diff --git a/SConstruct b/SConstruct index 240079f5190..f9fef1f1a49 100644 --- a/SConstruct +++ b/SConstruct @@ -54,8 +54,8 @@ if os.path.isdir (bs_globals.root_build_dir) == 0: os.makedirs (bs_globals.root_build_dir+os.sep+'source') # Blender version. -version='2.41' -shortversion = '241' # for wininst target -> nsis installer creation +version='2.40-alpha1' +shortversion = '240alpha1' # for wininst target -> nsis installer creation sdl_env = Environment (ENV = os.environ) freetype_env = Environment (ENV = os.environ) @@ -64,9 +64,10 @@ env = Environment (ENV = os.environ) if sys.platform == 'linux2' or sys.platform == 'linux-i386': use_international = 'true' use_gameengine = 'true' - use_openal = 'true' + use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'true' use_sumo = 'true' use_ode = 'false' use_bullet = 'true' @@ -95,6 +96,12 @@ if sys.platform == 'linux2' or sys.platform == 'linux-i386': png_lib = ['png'] png_libpath = ['/usr/lib'] png_include = ['/usr/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = ['/usr/lib'] @@ -152,11 +159,12 @@ if sys.platform == 'linux2' or sys.platform == 'linux-i386': elif sys.platform == 'darwin': use_international = 'true' - use_gameengine = 'true' + use_gameengine = 'false' use_openal = 'true' use_fmod = 'false' - use_openal = 'true' + use_openal = 'false' use_quicktime = 'true' + use_openexr = 'true' use_precomp = 'true' use_sumo = 'true' use_ode = 'false' @@ -176,7 +184,7 @@ elif sys.platform == 'darwin': fink_path = '/sw/' # TODO : try -mpowerpc -mpowerpc-gopt -mpowerpc-gfxopt optims # doing actual profiling - extra_flags = ['-pipe', '-fPIC', '-funsigned-char', '-mpowerpc', '-mtune=G5'] + extra_flags = ['-pipe', '-fPIC', '-funsigned-char', '-ffast-math', '-mpowerpc', '-mtune=G4'] # , '-malign-natural'] malign is causing problems with jpeg lib but worth a 1-2% speedup #'-force_cpusubtype_ALL', '-mpowerpc-gpopt', @@ -198,6 +206,12 @@ elif sys.platform == 'darwin': png_lib = ['libpng'] png_libpath = [darwin_precomp + 'png/lib'] png_include = [darwin_precomp + 'png/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/local/lib'] + openexr_include = ['/usr/local/include/OpenEXR'] # jpeg library information jpeg_lib = ['libjpeg'] jpeg_libpath = [darwin_precomp + 'jpeg/lib'] @@ -275,10 +289,11 @@ elif sys.platform == 'darwin': elif sys.platform == 'cygwin': use_international = 'false' - use_gameengine = 'true' - use_openal = 'true' + use_gameengine = 'false' + use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'true' use_sumo = 'false' use_ode = 'false' use_bullet = 'false' @@ -309,6 +324,12 @@ elif sys.platform == 'cygwin': png_lib = ['png'] png_libpath = ['#../lib/windows/png/lib'] png_include = ['#../lib/windows/png/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = ['#../lib/windows/jpeg/lib'] @@ -365,6 +386,7 @@ elif sys.platform == 'win32': use_openal = 'true' use_fmod = 'false' use_quicktime = 'true' + use_openexr = 'true' use_bullet = 'true' use_sumo = 'true' use_ode = 'false' @@ -417,6 +439,12 @@ elif sys.platform == 'win32': png_lib = ['libpng_st'] png_libpath = ['#../lib/windows/png/lib'] png_include = ['#../lib/windows/png/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['libjpeg'] jpeg_libpath = ['#../lib/windows/jpeg/lib'] @@ -477,6 +505,7 @@ elif string.find (sys.platform, 'sunos') != -1: use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'false' use_sumo = 'false' use_ode = 'false' use_bullet = 'false' @@ -505,6 +534,12 @@ elif string.find (sys.platform, 'sunos') != -1: png_lib = ['png'] png_libpath = [] png_include = [] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = [] @@ -561,6 +596,7 @@ elif string.find (sys.platform, 'irix') != -1: use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'false' use_sumo = 'false' use_ode = 'false' use_bullet = 'false' @@ -597,6 +633,12 @@ elif string.find (sys.platform, 'irix') != -1: png_lib = ['png'] png_libpath = [irix_precomp + '/png/lib'] png_include = [irix_precomp + '/png/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = [irix_precomp + '/jpeg/lib'] @@ -657,6 +699,7 @@ elif sys.platform=='openbsd3': use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'false' use_sumo = 'false' use_ode = 'false' use_bullet = 'false' @@ -684,6 +727,12 @@ elif sys.platform=='openbsd3': png_lib = ['png'] png_libpath = ['/usr/local/lib'] png_include = ['/usr/local/include/libpng'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = ['/usr/local/lib'] @@ -742,6 +791,7 @@ elif sys.platform=='freebsd4' or sys.platform=='freebsd5': use_openal = 'false' use_fmod = 'false' use_quicktime = 'false' + use_openexr = 'false' use_sumo = 'false' use_ode = 'false' use_bullet = 'false' @@ -769,6 +819,12 @@ elif sys.platform=='freebsd4' or sys.platform=='freebsd5': png_lib = ['png'] png_libpath = ['/usr/local/lib'] png_include = ['/usr/local/include'] + # OpenEXR library information + if use_openexr == 'true': + defines += ['WITH_OPENEXR'] + openexr_lib = ['Iex', 'Half', 'IlmImf', 'Imath'] + openexr_libpath = ['/usr/lib'] + openexr_include = ['/usr/include/OpenEXR'] # jpeg library information jpeg_lib = ['jpeg'] jpeg_libpath = ['/usr/local/lib'] @@ -870,6 +926,7 @@ else: config.write ("USE_OPENAL = %r\n"%(use_openal)) config.write ("USE_FMOD = %r\n"%(use_fmod)) config.write ("USE_QUICKTIME = %r\n"%(use_quicktime)) + config.write ("USE_OPENEXR = %r\n"%(use_openexr)) config.write ("USE_FLUIDSIM = %r\n"%(use_fluidsim)) config.write ("\n# Compiler information.\n") config.write ("HOST_CC = %r\n"%(env_dict['CC'])) @@ -896,6 +953,9 @@ else: config.write ("PNG_INCLUDE = %r\n"%(png_include)) config.write ("PNG_LIBPATH = %r\n"%(png_libpath)) config.write ("PNG_LIBRARY = %r\n"%(png_lib)) + config.write ("OPENEXR_INCLUDE = %r\n"%(openexr_include)) + config.write ("OPENEXR_LIBPATH = %r\n"%(openexr_libpath)) + config.write ("OPENEXR_LIBRARY = %r\n"%(openexr_lib)) config.write ("JPEG_INCLUDE = %r\n"%(jpeg_include)) config.write ("JPEG_LIBPATH = %r\n"%(jpeg_libpath)) config.write ("JPEG_LIBRARY = %r\n"%(jpeg_lib)) @@ -982,6 +1042,9 @@ user_options.AddOptions ( (BoolOption ('USE_QUICKTIME', 'Set to 1 to add support for QuickTime.', 'false')), + (BoolOption ('USE_OPENEXR', + 'Set to 1 to add support for OpenEXR.', + 'false')), (BoolOption ('USE_FLUIDSIM', # NT test new 'Set to 0 to disable compilation of fluid simulation library El\'Beem.', 'true')), @@ -1008,6 +1071,9 @@ user_options.AddOptions ( ('PNG_INCLUDE', 'Include directory for png header files.'), ('PNG_LIBPATH', 'Library path where the png library is located.'), ('PNG_LIBRARY', 'png library name.'), + ('OPENEXR_INCLUDE', 'Include directory for OpenEXR header files.'), + ('OPENEXR_LIBPATH', 'Library path where the OpenEXR libraries are located.'), + ('OPENEXR_LIBRARY', 'OpenEXR library names.'), ('JPEG_INCLUDE', 'Include directory for jpeg header files.'), ('JPEG_LIBPATH', 'Library path where the jpeg library is located.'), ('JPEG_LIBRARY', 'jpeg library name.'), diff --git a/bin/.blender/.Blanguages b/bin/.blender/.Blanguages index 76115a0b189..d9c6086b0e2 100644 --- a/bin/.blender/.Blanguages +++ b/bin/.blender/.Blanguages @@ -13,6 +13,4 @@ Brazilian Portuguese:pt_br Simplified Chinese:zh_CN Russian:ru_RU Croatian:hr_HR -Serbian:sr -Ukrainian:uk Polish:pl_PL diff --git a/extern/bFTGL/src/Makefile b/extern/bFTGL/src/Makefile index 3fa3e9139ab..064480fbd16 100644 --- a/extern/bFTGL/src/Makefile +++ b/extern/bFTGL/src/Makefile @@ -46,7 +46,6 @@ CCSRCS = FTBitmapGlyph.cpp FTCharmap.cpp FTContour.cpp FTExtrdGlyph.cpp \ include nan_compile.mk CPPFLAGS += -I../include -CPPFLAGS += -I/usr/X11R6/include CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2 install: all debug diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h new file mode 100644 index 00000000000..41009dcd110 --- /dev/null +++ b/extern/bullet/Bullet/NarrowPhaseCollision/CollisionMargin.h @@ -0,0 +1,11 @@ +#ifndef COLLISION_MARGIN_H +#define COLLISION_MARGIN_H + +//used by Gjk and some other algorithms + +#define CONVEX_DISTANCE_MARGIN 0.04f// 0.1f//;//0.01f + + + +#endif //COLLISION_MARGIN_H + diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index 98eed6bb104..28421b9f2e4 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -231,12 +231,8 @@ SND_OpenALDevice::SND_OpenALDevice() m_context = alcCreateContext(dev, NULL); if (m_context) { -#ifdef AL_VERSION_1_1 - alcMakeContextCurrent((ALCcontext*)m_context); -#else - alcMakeContextCurrent(m_context); -#endif - m_audio = true; + alcMakeContextCurrent((ALCcontext*)m_context); + m_audio = true; m_device = dev; #ifdef __linux__ /* @@ -343,11 +339,7 @@ SND_OpenALDevice::~SND_OpenALDevice() if (m_context) { MakeCurrent(); -#ifdef AL_VERSION_1_1 alcDestroyContext((ALCcontext*)m_context); -#else - alcDestroyContext(m_context); -#endif m_context = NULL; } @@ -418,7 +410,7 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, waveslot->SetFileSize(size); /* what was (our) buffer? */ - int buffer = waveslot->GetBuffer(); + buffer = waveslot->GetBuffer(); /* get some info out of the sample */ SND_GetSampleInfo((signed char*)memlocation, waveslot); @@ -427,14 +419,9 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, /* load the sample into openal */ #if defined(OUDE_OPENAL) || defined (__APPLE__) - alutLoadWAVMemory((char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate); // openal_2.12 + alutLoadWAVMemory((ALbyte *)memlocation, &sampleformat, &data, &numberofsamples, &samplerate); // openal_2.12 #else -#ifdef AL_VERSION_1_1 - alutLoadWAVMemory((ALbyte*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+ -#else - alutLoadWAVMemory((signed char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+ - -#endif + alutLoadWAVMemory((ALbyte *)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+ #endif /* put it in the buffer */ alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); diff --git a/intern/bmfont/intern/BMF_BitmapFont.cpp b/intern/bmfont/intern/BMF_BitmapFont.cpp index 7997a94344b..bbba2c978dd 100644 --- a/intern/bmfont/intern/BMF_BitmapFont.cpp +++ b/intern/bmfont/intern/BMF_BitmapFont.cpp @@ -59,86 +59,6 @@ #include "BMF_BitmapFont.h" -#ifdef __APPLE__ -#include - -static int needs_nvidia_rasterpos_workaround(void) -{ - static int well_is_it= -1; - - if (well_is_it==-1) - { - well_is_it= (strncmp((char *)glGetString(GL_RENDERER), "NVIDIA GeForce 6800", 18) == 0); - if ( well_is_it != 0) - { - const GLubyte* vers = glGetString(GL_VERSION); - const GLubyte* v = vers; - int major = 0, minor = 0, sub = 0; - - //advance to the '-' - while ((*v != 0) && (*v!='-')) - v++; - - if (*v == '-') - { - int i = 0; - v++; - - while ((v[i] <= '9') && (v[i] >= '0')) - { - major *=10; - major += v[i]-'0'; - i++; - } - - if (v[i] == '.') - { - i++; - while ((v[i] <= '9') && (v[i] >= '0')) - { - minor *=10; - minor += v[i]-'0'; - i++; - } - } - else - major = -1; - - if (v[i] == '.') - { - i++; - while ((v[i] <= '9') && (v[i] >= '0')) - { - sub *=10; - sub += v[i]-'0'; - i++; - } - } - else - minor = -1; - } - - //OS X 10.4.3 is the first version that contained the fix for this problem - // and the 6800's driver version in it is 1.4.16. So anything after that - // doesn't need the workaround - - if ( (major == -1) || (minor == -1)) - //If anything went wrong don't do the workaround - // - well_is_it = 0; - else if ( (major <= 1) && (minor <= 4) && (sub < 16)) - well_is_it = 1; - else - well_is_it = 0; - } - } - - return well_is_it; -} - - -#endif - BMF_BitmapFont::BMF_BitmapFont(BMF_FontData* fontData) : m_fontData(fontData) { @@ -154,19 +74,7 @@ void BMF_BitmapFont::DrawString(char* str) GLint alignment; unsigned char c; -#ifdef __APPLE__ - GLint vp[4]; // hack stuff - GLubyte nullm = 0; // hack stuff - - if(needs_nvidia_rasterpos_workaround()) { // was is_a_really_crappy_nvidia_card() - glGetIntegerv(GL_VIEWPORT, vp); // hack stuff - - glBitmap(1, 1, 0, 0, -vp[0], vp[1], &nullm); - - } - #endif - - glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); + glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); while ( (c = (unsigned char) *str++) ) { diff --git a/intern/boolop/intern/BOP_Face2Face.cpp b/intern/boolop/intern/BOP_Face2Face.cpp index bdd3637a598..08928935f33 100644 --- a/intern/boolop/intern/BOP_Face2Face.cpp +++ b/intern/boolop/intern/BOP_Face2Face.cpp @@ -146,7 +146,7 @@ void BOP_mergeVertexs(BOP_Mesh *mesh, unsigned int firstFace); * @param facesB set of faces from object B */ void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) -{ +{ for(unsigned int idxFaceA=0;idxFaceAsize();idxFaceA++) { BOP_Face *faceA = (*facesA)[idxFaceA]; MT_Plane3 planeA = faceA->getPlane(); @@ -160,28 +160,28 @@ void BOP_Face2Face(BOP_Mesh *mesh, BOP_Faces *facesA, BOP_Faces *facesB) idxFaceBsize() && (faceA->getTAG() != BROKEN) && (faceA->getTAG() != PHANTOM);) { BOP_Face *faceB = (*facesB)[idxFaceB]; if ((faceB->getTAG() != BROKEN) && (faceB->getTAG() != PHANTOM)) { - BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(), - mesh->getVertex(faceB->getVertex(1))->getPoint(), - mesh->getVertex(faceB->getVertex(2))->getPoint()); - if (boxA.intersect(boxB)) { + BOP_BBox boxB(mesh->getVertex(faceB->getVertex(0))->getPoint(), + mesh->getVertex(faceB->getVertex(1))->getPoint(), + mesh->getVertex(faceB->getVertex(2))->getPoint()); + if (boxA.intersect(boxB)) { - MT_Plane3 planeB = faceB->getPlane(); - if (BOP_containsPoint(planeB,p1) && - BOP_containsPoint(planeB,p2) && - BOP_containsPoint(planeB,p3)) { - if (BOP_orientation(planeB,planeA)>0) { - BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false); - } - } - else { - BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB); - } - } + MT_Plane3 planeB = faceB->getPlane(); + if (BOP_containsPoint(planeB,p1) && + BOP_containsPoint(planeB,p2) && + BOP_containsPoint(planeB,p3)) { + if (BOP_orientation(planeB,planeA)>0) { + BOP_intersectCoplanarFaces(mesh,facesB,faceA,faceB,false); + } + } + else { + BOP_intersectNonCoplanarFaces(mesh,facesA,facesB,faceA,faceB); + } + } } if (faceB->getTAG()==BROKEN){ - facesB->erase(facesB->begin()+idxFaceB); + facesB->erase(facesB->begin()+idxFaceB); }else - idxFaceB++; + idxFaceB++; } } diff --git a/intern/boolop/intern/BOP_Interface.cpp b/intern/boolop/intern/BOP_Interface.cpp index 1ef394963ac..02945340d55 100644 --- a/intern/boolop/intern/BOP_Interface.cpp +++ b/intern/boolop/intern/BOP_Interface.cpp @@ -92,9 +92,9 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType, CSG_VertexIteratorDescriptor obBVertices, CSG_InterpolateUserFaceVertexDataFunc interpFunc) { -#ifdef DEBUG + #ifdef DEBUG cout << "BEGIN BOP_performBooleanOperation" << endl; -#endif + #endif // Set invert flags depending on boolean operation type: // INTERSECTION: A^B = and(A,B) @@ -121,9 +121,6 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType, // Add B-mesh into C-mesh BOP_addMesh(&meshC, &meshBFacesId, &materials, obBProps, obBFaces, obBVertices, invertMeshB); - if (!meshC.isClosedMesh()) - return BOP_NO_SOLID; - // Perform the intersection boolean operation. BoolOpState result = BOP_intersectionBoolOp(&meshC, &meshAFacesId, &meshBFacesId, invertMeshA, invertMeshB); @@ -131,9 +128,9 @@ BoolOpState BOP_performBooleanOperation(BoolOpType opType, // Invert the output mesh if is required *outputMesh = BOP_exportMesh(&meshC, &materials, outputProps, invertMeshC); -#ifdef DEBUG + #ifdef DEBUG cout << "END BOP_performBooleanOperation" << endl; -#endif + #endif return result; } @@ -154,13 +151,13 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC, bool invertMeshA, bool invertMeshB) { -#ifdef DEBUG + #ifdef DEBUG BOP_Chrono chrono; float t = 0.0f; float c = 0.0f; chrono.start(); cout << "---" << endl; -#endif + #endif // Create BSPs trees for mesh A & B BOP_BSPTree bspA; @@ -171,10 +168,10 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC, bspB.addMesh(meshC, *facesB); bspB.computeBox(); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Create BSP " << c << endl; -#endif + #endif unsigned int numVertices = meshC->getNumVertexs(); @@ -187,54 +184,54 @@ BoolOpState BOP_intersectionBoolOp(BOP_Mesh* meshC, if ((0.25*facesB->size()) > bspA.getDeep()) BOP_meshFilter(meshC, facesB, &bspA); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "mesh Filter " << c << endl; -#endif + #endif // Face 2 Face BOP_Face2Face(meshC,facesA,facesB); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Face2Face " << c << endl; -#endif + #endif // BSP classification BOP_meshClassify(meshC,facesA,&bspB); BOP_meshClassify(meshC,facesB,&bspA); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Classification " << c << endl; -#endif + #endif // Process overlapped faces BOP_removeOverlappedFaces(meshC,facesA,facesB); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Remove overlap " << c << endl; -#endif + #endif // Sew two meshes BOP_sew(meshC,facesA,facesB); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Sew " << c << endl; -#endif + #endif // Merge faces BOP_Merge::getInstance().mergeFaces(meshC,numVertices); -#ifdef DEBUG + #ifdef DEBUG c = chrono.stamp(); t += c; cout << "Merge faces " << c << endl; cout << "Total " << t << endl; // Test integrity meshC->testMesh(); -#endif + #endif return BOP_OK; } diff --git a/intern/boolop/intern/BOP_Mesh.cpp b/intern/boolop/intern/BOP_Mesh.cpp index a7e7ef61e43..24d5b3fb6a9 100644 --- a/intern/boolop/intern/BOP_Mesh.cpp +++ b/intern/boolop/intern/BOP_Mesh.cpp @@ -553,23 +553,6 @@ BOP_Index BOP_Mesh::replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex) return newIndex; } -bool BOP_Mesh::isClosedMesh() -{ - for(unsigned int i=0; igetFaces(); - unsigned int count = 0; - const BOP_IT_Indexs facesEnd = faces.end(); - for(BOP_IT_Indexs it = faces.begin();it!=facesEnd;it++) { - if (m_faces[*it]->getTAG()!=BROKEN) - count++; - } - - if ((count%2)!=0) return false; - } - - return true; -} /** *************************************************************************** diff --git a/intern/boolop/intern/BOP_Mesh.h b/intern/boolop/intern/BOP_Mesh.h index adc92c91559..6751df7c4e7 100644 --- a/intern/boolop/intern/BOP_Mesh.h +++ b/intern/boolop/intern/BOP_Mesh.h @@ -82,7 +82,6 @@ public: unsigned int getNumVertexs(BOP_TAG tag); unsigned int getNumFaces(BOP_TAG tag); BOP_Index replaceVertexIndex(BOP_Index oldIndex, BOP_Index newIndex); - bool isClosedMesh(); // Debug functions void print(); diff --git a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h index 77ba076885f..453e6e20ea7 100755 --- a/intern/bsp/intern/BSP_CSGMesh_CFIterator.h +++ b/intern/bsp/intern/BSP_CSGMesh_CFIterator.h @@ -178,6 +178,7 @@ BSP_CSGMesh_FaceIt_Fill( // assume CSG_IteratorPtr is of the correct type. BSP_CSGMesh_FaceIt * face_it = (BSP_CSGMesh_FaceIt *)it; // essentially iterating through a triangle fan here. + const int tri_index = face_it->face_triangle; if (face_it->pos->m_verts.size()>3) { // QUAD diff --git a/intern/bsp/intern/CSG_BooleanOps.cpp b/intern/bsp/intern/CSG_BooleanOps.cpp index 9ea0ef60be5..6c9fecd88e1 100755 --- a/intern/bsp/intern/CSG_BooleanOps.cpp +++ b/intern/bsp/intern/CSG_BooleanOps.cpp @@ -33,6 +33,10 @@ * Implementation of external api for CSG part of BSP lib interface. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "../extern/CSG_BooleanOps.h" #include "BSP_CSGMesh_CFIterator.h" #include "BSP_CSGMeshBuilder.h" @@ -43,7 +47,7 @@ #include "../../boolop/extern/BOP_Interface.h" #include using namespace std; -#include "BSP_MeshPrimitives.h" +#include "BSP_MeshPrimitives.h"; struct BSP_MeshInfo { BSP_CSGMesh *output_mesh; @@ -99,20 +103,22 @@ CSG_DescibeOperands( /** * Compute the boolean operation, UNION, INTERSECION or DIFFERENCE */ -int + int CSG_PerformBooleanOperation( - CSG_BooleanOperation *operation, - CSG_OperationType op_type, - CSG_FaceIteratorDescriptor obAFaces, - CSG_VertexIteratorDescriptor obAVertices, - CSG_FaceIteratorDescriptor obBFaces, - CSG_VertexIteratorDescriptor obBVertices, - CSG_InterpolateUserFaceVertexDataFunc interp_func + CSG_BooleanOperation *operation, + CSG_OperationType op_type, + CSG_FaceIteratorDescriptor obAFaces, + CSG_VertexIteratorDescriptor obAVertices, + CSG_FaceIteratorDescriptor obBFaces, + CSG_VertexIteratorDescriptor obBVertices, + CSG_InterpolateUserFaceVertexDataFunc interp_func ){ if (operation == NULL) return 0; BSP_MeshInfo * mesh_info = static_cast(operation->CSG_info); if (mesh_info == NULL) return 0; + bool success = 1; + obAFaces.Reset(obAFaces.it); obBFaces.Reset(obBFaces.it); obAVertices.Reset(obAVertices.it); @@ -122,39 +128,33 @@ CSG_PerformBooleanOperation( switch( op_type ) { case e_csg_union: - boolType = BOP_UNION; - break; + boolType = BOP_UNION; + break; case e_csg_difference: - boolType = BOP_DIFFERENCE; - break; + boolType = BOP_DIFFERENCE; + break; default: - boolType = BOP_INTERSECTION; - break; + boolType = BOP_INTERSECTION; + break; } - BoolOpState boolOpResult; try { - boolOpResult= BOP_performBooleanOperation( boolType, - mesh_info->output_descriptor, - (BSP_CSGMesh**) &(mesh_info->output_mesh), - mesh_info->obB_descriptor, - obBFaces, - obBVertices, - mesh_info->obA_descriptor, - obAFaces, - obAVertices, - interp_func ); + BOP_performBooleanOperation( boolType, + mesh_info->output_descriptor, + (BSP_CSGMesh**) &(mesh_info->output_mesh), + mesh_info->obB_descriptor, + obBFaces, + obBVertices, + mesh_info->obA_descriptor, + obAFaces, + obAVertices, + interp_func ); } catch(...) { return 0; } - switch (boolOpResult) { - case BOP_OK: return 1; - case BOP_NO_SOLID: return -2; - case BOP_ERROR: return 0; - default: return 1; - } + return success; } int diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript index 5d30b58a982..3ef20b9be3a 100644 --- a/intern/elbeem/SConscript +++ b/intern/elbeem/SConscript @@ -10,8 +10,6 @@ elbeem_env.Append(CPPDEFINES= [('ELBEEM_BLENDER',1)] ); if use_fluidsim=='false': # print "El'Beem Fluid Simulation Disabled..." # debug elbeem_env.Append (CPPPATH = user_options_dict['PNG_INCLUDE']) - elbeem_env.Append (CPPPATH = user_options_dict['SDL_INCLUDE']) - elbeem_env.Append(CPPDEFINES= 'ELBEEM_DUMMIES'); # dummy interface build Sources = [ "intern/utilities.cpp", diff --git a/intern/elbeem/intern/blenderdummy.cpp b/intern/elbeem/intern/blenderdummy.cpp index 3111c9359dd..4d672dee528 100644 --- a/intern/elbeem/intern/blenderdummy.cpp +++ b/intern/elbeem/intern/blenderdummy.cpp @@ -9,30 +9,11 @@ * *****************************************************************************/ -#ifdef ELBEEM_DUMMIES - #include -#include "ntl_vector3dim.h" extern "C" int performElbeemSimulation(char *cfgfilename) { - return 1; // dummy + return 1; }; -// dummies from intern/elbeem/intern/solver_interface.cpp -// for utilities.cpp - -void initGridSizes(int &sizex, int &sizey, int &sizez, - ntlVec3Gfx &geoStart, ntlVec3Gfx &geoEnd, - int mMaxRefine, bool parallel) -{ - // dummy -} - -void calculateMemreqEstimate( int resx,int resy,int resz, int refine, - double *reqret, string *reqstr) { - *reqret = 0.0; // dummy -} - -#endif // ELBEEM_DUMMIES diff --git a/intern/elbeem/intern/cfglexer.cpp b/intern/elbeem/intern/cfglexer.cpp index 0bc9d96b5b2..472c6929451 100644 --- a/intern/elbeem/intern/cfglexer.cpp +++ b/intern/elbeem/intern/cfglexer.cpp @@ -430,16 +430,16 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, - 1, 7, 8, 1, 9, 10, 11, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 13, 14, 1, - 15, 1, 1, 1, 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, 34, - 1, 16, 1, 1, 17, 1, 18, 19, 20, 21, + 1, 7, 1, 1, 8, 9, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 12, 13, 1, + 14, 1, 1, 1, 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, 33, + 1, 15, 1, 1, 16, 1, 17, 18, 19, 20, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 34, 43, 1, 44, 1, 1, 1, 1, 1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 33, 42, 1, 43, 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, @@ -456,103 +456,103 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[45] = +static yyconst flex_int32_t yy_meta[44] = { 0, - 1, 2, 3, 4, 1, 1, 1, 5, 5, 6, - 5, 6, 5, 2, 1, 5, 6, 6, 6, 6, + 1, 2, 3, 4, 1, 1, 1, 5, 6, 5, + 6, 5, 2, 1, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 1, 1 + 6, 1, 1 } ; -static yyconst flex_int16_t yy_base[575] = +static yyconst flex_int16_t yy_base[576] = { 0, - 0, 0, 44, 0, 87, 130, 713, 714, 95, 714, - 102, 0, 0, 84, 700, 96, 90, 85, 91, 92, - 86, 83, 122, 689, 82, 85, 101, 111, 133, 118, - 137, 128, 125, 677, 136, 124, 166, 167, 173, 0, - 174, 0, 704, 177, 173, 714, 181, 185, 188, 191, - 192, 703, 0, 695, 187, 694, 714, 0, 188, 668, - 685, 175, 670, 665, 681, 180, 659, 167, 178, 190, - 192, 678, 676, 668, 667, 657, 655, 200, 661, 653, - 659, 666, 657, 182, 653, 657, 656, 658, 661, 652, - 714, 660, 649, 191, 638, 205, 661, 199, 660, 641, + 0, 0, 43, 86, 128, 170, 704, 705, 60, 705, + 63, 0, 0, 43, 692, 53, 50, 47, 53, 78, + 47, 39, 87, 681, 43, 82, 54, 80, 117, 92, + 93, 112, 116, 669, 99, 123, 138, 149, 152, 0, + 141, 0, 695, 156, 101, 705, 157, 160, 163, 175, + 180, 694, 0, 687, 176, 686, 705, 0, 177, 660, + 677, 153, 662, 657, 673, 101, 651, 161, 46, 175, + 178, 670, 668, 660, 659, 649, 647, 186, 653, 645, + 651, 658, 649, 168, 645, 649, 648, 650, 653, 644, + 705, 652, 641, 174, 630, 192, 653, 131, 652, 633, - 208, 643, 636, 639, 637, 231, 235, 236, 240, 0, - 241, 0, 667, 666, 245, 0, 246, 714, 0, 644, - 643, 229, 642, 645, 631, 637, 633, 632, 714, 625, - 625, 628, 626, 620, 631, 627, 632, 714, 621, 617, - 630, 625, 608, 619, 612, 617, 624, 609, 619, 615, - 620, 606, 605, 617, 222, 608, 714, 611, 605, 604, - 592, 607, 595, 609, 595, 608, 596, 606, 606, 603, - 589, 586, 591, 599, 598, 597, 596, 580, 590, 252, - 576, 592, 578, 575, 593, 590, 583, 584, 586, 575, - 569, 567, 229, 585, 578, 570, 578, 561, 566, 575, + 198, 635, 628, 631, 629, 214, 219, 222, 226, 0, + 227, 0, 658, 657, 230, 0, 235, 705, 0, 636, + 635, 146, 634, 637, 623, 629, 625, 624, 705, 617, + 617, 620, 618, 612, 623, 619, 624, 705, 613, 609, + 622, 617, 600, 611, 604, 609, 616, 601, 611, 607, + 612, 598, 597, 609, 206, 600, 705, 603, 597, 596, + 584, 599, 587, 601, 587, 600, 588, 598, 598, 595, + 581, 578, 583, 591, 590, 589, 588, 572, 582, 238, + 568, 584, 570, 567, 585, 582, 575, 576, 578, 567, + 561, 559, 183, 577, 570, 562, 570, 553, 558, 567, - 227, 575, 714, 573, 563, 571, 557, 553, 553, 571, - 553, 569, 554, 714, 553, 562, 551, 714, 558, 557, - 556, 542, 543, 551, 558, 553, 545, 541, 534, 536, - 533, 539, 532, 537, 714, 714, 546, 543, 545, 541, - 531, 543, 542, 530, 521, 538, 521, 533, 714, 529, - 527, 714, 517, 516, 239, 528, 529, 512, 521, 714, - 514, 527, 515, 507, 520, 504, 503, 504, 714, 501, - 511, 494, 500, 505, 498, 511, 502, 714, 498, 503, - 510, 488, 506, 490, 486, 483, 493, 499, 714, 488, - 244, 501, 714, 477, 488, 714, 479, 485, 479, 487, + 216, 567, 705, 565, 555, 563, 549, 545, 545, 563, + 545, 561, 546, 705, 545, 554, 543, 705, 550, 549, + 548, 534, 535, 543, 550, 545, 537, 533, 526, 528, + 525, 531, 524, 529, 705, 705, 538, 535, 537, 533, + 523, 535, 534, 522, 513, 530, 513, 525, 705, 521, + 519, 705, 509, 508, 221, 520, 521, 504, 513, 705, + 506, 519, 507, 499, 512, 496, 495, 496, 705, 493, + 503, 486, 492, 497, 490, 503, 494, 705, 490, 495, + 502, 480, 498, 482, 478, 475, 485, 491, 705, 480, + 193, 493, 705, 469, 480, 705, 471, 477, 471, 479, - 714, 474, 479, 475, 491, 488, 714, 485, 484, 473, - 478, 486, 465, 479, 469, 478, 468, 478, 468, 466, - 459, 714, 470, 714, 474, 470, 714, 448, 452, 466, - 469, 455, 453, 464, 461, 456, 461, 443, 449, 460, - 714, 456, 249, 458, 434, 714, 452, 444, 450, 434, - 452, 432, 430, 449, 445, 245, 436, 425, 442, 421, - 443, 425, 714, 422, 436, 435, 426, 429, 714, 412, - 435, 423, 429, 426, 423, 419, 410, 714, 415, 419, - 408, 412, 424, 415, 422, 404, 416, 416, 399, 400, - 252, 714, 408, 238, 714, 397, 410, 400, 393, 397, + 705, 466, 471, 467, 483, 480, 705, 477, 476, 465, + 470, 478, 457, 471, 461, 470, 460, 470, 460, 458, + 451, 705, 462, 705, 466, 462, 705, 440, 444, 458, + 461, 447, 445, 456, 453, 448, 453, 435, 441, 452, + 705, 448, 221, 450, 426, 705, 444, 436, 442, 426, + 444, 424, 422, 441, 437, 227, 428, 417, 434, 413, + 435, 417, 705, 414, 428, 427, 418, 421, 705, 404, + 427, 415, 421, 418, 415, 411, 402, 705, 407, 411, + 400, 404, 416, 407, 414, 396, 408, 408, 391, 392, + 227, 705, 400, 219, 705, 389, 402, 392, 385, 389, - 393, 402, 246, 407, 403, 402, 401, 385, 395, 714, - 714, 714, 714, 387, 714, 399, 714, 385, 385, 396, - 714, 378, 714, 383, 388, 391, 373, 378, 376, 714, - 714, 382, 387, 384, 383, 369, 379, 714, 376, 714, - 365, 379, 362, 358, 362, 364, 377, 359, 363, 363, - 714, 362, 353, 369, 714, 366, 350, 355, 363, 349, - 359, 364, 359, 344, 348, 359, 340, 344, 344, 341, - 347, 347, 341, 714, 714, 335, 333, 350, 330, 333, - 343, 714, 714, 714, 329, 714, 714, 338, 326, 325, - 714, 714, 339, 318, 321, 714, 331, 330, 326, 334, + 385, 394, 231, 399, 395, 394, 393, 377, 387, 705, + 705, 705, 705, 379, 705, 391, 705, 377, 377, 388, + 705, 370, 705, 375, 380, 383, 365, 370, 368, 705, + 705, 374, 379, 376, 375, 361, 371, 705, 368, 705, + 357, 371, 354, 350, 354, 356, 369, 351, 355, 355, + 705, 354, 345, 361, 705, 358, 342, 347, 355, 341, + 351, 356, 351, 336, 340, 351, 332, 336, 336, 333, + 339, 339, 333, 705, 705, 327, 325, 342, 322, 325, + 335, 705, 705, 705, 321, 705, 705, 330, 318, 317, + 705, 705, 331, 310, 313, 705, 323, 322, 318, 326, - 316, 334, 314, 328, 714, 714, 328, 316, 714, 316, - 320, 714, 714, 714, 313, 714, 318, 325, 303, 714, - 319, 315, 305, 714, 714, 261, 299, 300, 300, 278, - 297, 277, 290, 714, 714, 287, 280, 268, 256, 254, - 252, 252, 251, 714, 714, 256, 248, 231, 714, 228, - 197, 714, 714, 207, 167, 149, 714, 150, 106, 714, - 714, 101, 714, 714, 714, 294, 297, 303, 89, 309, - 315, 321, 327, 333 + 308, 326, 306, 320, 705, 705, 320, 308, 705, 308, + 312, 705, 705, 705, 305, 705, 310, 317, 295, 705, + 311, 307, 300, 705, 705, 236, 299, 305, 309, 287, + 306, 289, 302, 705, 705, 299, 296, 296, 281, 274, + 267, 264, 263, 705, 705, 269, 258, 261, 705, 267, + 250, 705, 705, 245, 225, 222, 705, 212, 166, 705, + 705, 155, 705, 705, 705, 268, 274, 277, 283, 113, + 289, 295, 301, 307, 313 } ; -static yyconst flex_int16_t yy_def[575] = +static yyconst flex_int16_t yy_def[576] = { 0, - 565, 1, 565, 3, 566, 566, 565, 565, 565, 565, - 565, 567, 568, 565, 565, 565, 565, 565, 565, 565, + 565, 1, 566, 566, 567, 567, 565, 565, 565, 565, + 565, 568, 569, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 565, 565, 565, 565, 565, 565, 565, 565, 565, 569, - 565, 570, 571, 572, 570, 565, 570, 570, 565, 565, - 565, 567, 568, 565, 565, 565, 565, 573, 565, 565, + 565, 565, 565, 565, 565, 565, 565, 565, 565, 570, + 565, 571, 572, 573, 571, 565, 571, 571, 565, 565, + 565, 568, 569, 565, 565, 565, 565, 574, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 565, 565, 565, 565, 565, 565, 565, 565, 565, 569, - 565, 570, 571, 571, 572, 570, 574, 565, 573, 565, + 565, 565, 565, 565, 565, 565, 565, 565, 565, 570, + 565, 571, 572, 572, 573, 571, 575, 565, 574, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 565, 565, 565, 565, 565, 565, 565, 565, 565, 574, + 565, 565, 565, 565, 565, 565, 565, 565, 565, 575, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, @@ -596,177 +596,175 @@ static yyconst flex_int16_t yy_def[575] = 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 0, 565, 565, 565, 565, 565, - 565, 565, 565, 565 + 565, 565, 565, 565, 565 } ; -static yyconst flex_int16_t yy_nxt[759] = +static yyconst flex_int16_t yy_nxt[749] = { 0, - 8, 9, 10, 11, 12, 13, 8, 8, 14, 15, - 16, 17, 8, 8, 8, 8, 8, 18, 19, 20, - 21, 22, 23, 24, 8, 25, 8, 8, 26, 27, - 28, 29, 30, 8, 31, 32, 33, 34, 35, 8, - 8, 8, 36, 37, 8, 38, 10, 39, 8, 13, - 8, 8, 8, 40, 16, 40, 8, 8, 41, 8, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 36, 37, 9, 10, - 11, 43, 44, 54, 110, 55, 49, 45, 49, 54, + 8, 9, 10, 11, 12, 13, 8, 14, 15, 16, + 17, 8, 8, 8, 8, 8, 18, 19, 20, 21, + 22, 23, 24, 8, 25, 8, 8, 26, 27, 28, + 29, 30, 8, 31, 32, 33, 34, 35, 8, 8, + 8, 36, 37, 8, 38, 10, 39, 8, 13, 8, + 8, 54, 16, 55, 8, 8, 41, 8, 54, 57, + 59, 49, 58, 49, 49, 60, 49, 70, 72, 65, + 84, 71, 80, 132, 133, 61, 62, 81, 85, 73, + 66, 63, 64, 67, 36, 37, 8, 38, 10, 39, + 8, 13, 8, 8, 68, 16, 86, 8, 8, 41, - 46, 59, 57, 49, 60, 49, 58, 70, 65, 68, - 82, 71, 80, 72, 61, 62, 83, 81, 84, 66, - 63, 64, 67, 69, 73, 106, 85, 106, 86, 47, - 48, 9, 10, 11, 43, 44, 564, 50, 51, 74, - 45, 563, 93, 46, 50, 51, 100, 75, 87, 94, - 76, 88, 97, 77, 95, 89, 78, 104, 96, 101, - 98, 105, 90, 91, 99, 92, 102, 107, 108, 107, - 108, 562, 47, 48, 108, 111, 108, 111, 53, 116, - 53, 109, 106, 117, 106, 561, 107, 109, 107, 49, - 53, 49, 106, 107, 106, 107, 54, 54, 55, 59, + 8, 50, 51, 74, 50, 51, 82, 116, 69, 95, + 117, 75, 83, 96, 76, 93, 87, 77, 110, 104, + 78, 127, 94, 105, 106, 128, 106, 36, 37, 9, + 10, 11, 43, 44, 88, 97, 100, 45, 89, 107, + 46, 107, 111, 98, 111, 90, 91, 99, 92, 101, + 108, 169, 108, 108, 170, 108, 102, 53, 106, 53, + 106, 107, 109, 107, 49, 109, 49, 183, 53, 47, + 48, 9, 10, 11, 43, 44, 106, 122, 106, 45, + 184, 107, 46, 107, 54, 54, 55, 59, 123, 564, + 50, 51, 134, 50, 51, 130, 135, 131, 136, 137, - 122, 127, 130, 560, 131, 128, 132, 133, 134, 50, - 51, 123, 135, 136, 137, 50, 51, 144, 151, 161, - 169, 145, 152, 170, 164, 173, 162, 165, 559, 174, - 50, 51, 106, 558, 106, 166, 107, 108, 107, 108, - 167, 111, 111, 111, 111, 175, 53, 119, 53, 119, - 109, 183, 557, 119, 215, 119, 261, 262, 53, 119, - 216, 343, 556, 252, 184, 119, 253, 309, 310, 388, - 401, 311, 435, 438, 439, 447, 344, 402, 50, 51, - 403, 537, 448, 555, 554, 389, 553, 552, 436, 551, - 550, 549, 548, 538, 42, 42, 42, 42, 42, 42, + 563, 161, 144, 151, 50, 51, 145, 152, 162, 343, + 164, 47, 48, 165, 173, 106, 252, 106, 174, 253, + 107, 166, 107, 108, 344, 108, 167, 111, 111, 111, + 111, 53, 562, 53, 175, 109, 119, 215, 119, 119, + 388, 119, 53, 216, 261, 262, 435, 119, 309, 310, + 119, 401, 311, 438, 439, 537, 389, 561, 402, 447, + 560, 403, 436, 50, 51, 559, 448, 538, 40, 40, + 40, 40, 40, 40, 42, 42, 42, 42, 42, 42, + 52, 52, 52, 53, 53, 558, 53, 53, 53, 112, + 557, 556, 555, 112, 112, 113, 554, 553, 552, 113, - 52, 52, 52, 53, 53, 547, 53, 53, 53, 112, - 546, 545, 544, 112, 112, 113, 543, 542, 541, 113, - 113, 115, 115, 540, 115, 115, 115, 119, 119, 539, - 119, 119, 119, 180, 180, 536, 180, 180, 180, 535, - 534, 533, 532, 531, 530, 529, 528, 527, 526, 525, - 524, 523, 522, 521, 520, 519, 518, 517, 516, 515, - 514, 513, 512, 511, 510, 509, 508, 507, 506, 505, - 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, - 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, - 484, 483, 482, 481, 480, 479, 478, 477, 476, 475, + 113, 115, 115, 551, 115, 115, 115, 119, 119, 550, + 119, 119, 119, 180, 180, 549, 180, 180, 180, 548, + 547, 546, 545, 544, 543, 542, 541, 540, 539, 536, + 535, 534, 533, 532, 531, 530, 529, 528, 527, 526, + 525, 524, 523, 522, 521, 520, 519, 518, 517, 516, + 515, 514, 513, 512, 511, 510, 509, 508, 507, 506, + 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, + 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, + 485, 484, 483, 482, 481, 480, 479, 478, 477, 476, + 475, 474, 473, 472, 471, 470, 469, 468, 467, 466, - 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, - 464, 463, 462, 461, 460, 459, 458, 457, 456, 455, - 454, 453, 452, 451, 450, 449, 446, 445, 444, 443, - 442, 441, 440, 437, 434, 433, 432, 431, 430, 429, - 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, - 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, - 408, 407, 406, 405, 404, 400, 399, 398, 397, 396, - 395, 394, 393, 392, 391, 390, 387, 386, 385, 384, - 383, 382, 381, 380, 379, 378, 377, 376, 375, 374, - 373, 372, 371, 370, 369, 368, 367, 366, 365, 364, + 465, 464, 463, 462, 461, 460, 459, 458, 457, 456, + 455, 454, 453, 452, 451, 450, 449, 446, 445, 444, + 443, 442, 441, 440, 437, 434, 433, 432, 431, 430, + 429, 428, 427, 426, 425, 424, 423, 422, 421, 420, + 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, + 409, 408, 407, 406, 405, 404, 400, 399, 398, 397, + 396, 395, 394, 393, 392, 391, 390, 387, 386, 385, + 384, 383, 382, 381, 380, 379, 378, 377, 376, 375, + 374, 373, 372, 371, 370, 369, 368, 367, 366, 365, + 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, - 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, - 353, 352, 351, 350, 349, 348, 347, 346, 345, 342, - 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, - 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, - 321, 320, 319, 318, 317, 316, 315, 314, 313, 312, - 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, - 298, 297, 296, 295, 294, 293, 292, 291, 290, 289, - 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, - 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, - 268, 267, 266, 265, 264, 263, 260, 259, 258, 257, + 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, + 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, + 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, + 322, 321, 320, 319, 318, 317, 316, 315, 314, 313, + 312, 308, 307, 306, 305, 304, 303, 302, 301, 300, + 299, 298, 297, 296, 295, 294, 293, 292, 291, 290, + 289, 288, 287, 286, 285, 284, 283, 282, 281, 280, + 279, 278, 277, 276, 275, 274, 273, 272, 271, 270, + 269, 268, 267, 266, 265, 264, 263, 260, 259, 258, + 257, 256, 255, 254, 251, 250, 249, 248, 247, 246, - 256, 255, 254, 251, 250, 249, 248, 247, 246, 245, - 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, - 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, - 224, 223, 222, 221, 220, 219, 218, 217, 214, 213, - 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, - 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, - 192, 191, 190, 189, 188, 187, 186, 185, 182, 181, - 114, 114, 179, 178, 177, 176, 172, 171, 168, 163, - 160, 159, 158, 157, 156, 155, 154, 153, 150, 149, - 148, 147, 146, 143, 142, 141, 140, 139, 138, 129, + 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, + 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, + 225, 224, 223, 222, 221, 220, 219, 218, 217, 214, + 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, + 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, + 193, 192, 191, 190, 189, 188, 187, 186, 185, 182, + 181, 114, 114, 179, 178, 177, 176, 172, 171, 168, + 163, 160, 159, 158, 157, 156, 155, 154, 153, 150, + 149, 148, 147, 146, 143, 142, 141, 140, 139, 138, + 129, 126, 125, 124, 121, 120, 56, 56, 118, 114, - 126, 125, 124, 121, 120, 56, 56, 118, 114, 103, - 79, 56, 565, 7, 565, 565, 565, 565, 565, 565, + 103, 79, 56, 565, 7, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565 } ; -static yyconst flex_int16_t yy_chk[759] = +static yyconst flex_int16_t yy_chk[749] = { 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, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, - 5, 5, 5, 14, 569, 14, 9, 5, 9, 17, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 14, 3, 14, 3, 3, 3, 3, 17, 16, + 17, 9, 16, 9, 11, 18, 11, 21, 22, 19, + 27, 21, 25, 69, 69, 18, 18, 25, 27, 22, + 19, 18, 18, 19, 3, 3, 4, 4, 4, 4, + 4, 4, 4, 4, 20, 4, 28, 4, 4, 4, - 5, 17, 16, 11, 18, 11, 16, 21, 19, 20, - 26, 21, 25, 22, 18, 18, 26, 25, 27, 19, - 18, 18, 19, 20, 22, 36, 27, 36, 28, 5, - 5, 6, 6, 6, 6, 6, 562, 9, 9, 23, - 6, 559, 30, 6, 11, 11, 33, 23, 28, 30, - 23, 29, 32, 23, 31, 29, 23, 35, 31, 33, - 32, 35, 29, 29, 32, 29, 33, 37, 38, 37, - 38, 558, 6, 6, 39, 41, 39, 41, 44, 45, - 44, 38, 47, 45, 47, 556, 48, 39, 48, 49, - 44, 49, 50, 51, 50, 51, 55, 59, 55, 59, + 4, 9, 9, 23, 11, 11, 26, 45, 20, 31, + 45, 23, 26, 31, 23, 30, 28, 23, 570, 35, + 23, 66, 30, 35, 36, 66, 36, 4, 4, 5, + 5, 5, 5, 5, 29, 32, 33, 5, 29, 37, + 5, 37, 41, 32, 41, 29, 29, 32, 29, 33, + 38, 98, 38, 39, 98, 39, 33, 44, 47, 44, + 47, 48, 38, 48, 49, 39, 49, 122, 44, 5, + 5, 6, 6, 6, 6, 6, 50, 62, 50, 6, + 122, 51, 6, 51, 55, 59, 55, 59, 62, 562, + 38, 38, 70, 39, 39, 68, 70, 68, 71, 71, - 62, 66, 68, 555, 68, 66, 69, 69, 70, 38, - 38, 62, 70, 71, 71, 39, 39, 78, 84, 94, - 98, 78, 84, 98, 96, 101, 94, 96, 554, 101, - 49, 49, 106, 551, 106, 96, 107, 108, 107, 108, - 96, 109, 111, 109, 111, 101, 115, 117, 115, 117, - 108, 122, 550, 180, 155, 180, 201, 201, 115, 117, - 155, 291, 548, 193, 122, 180, 193, 255, 255, 343, - 356, 255, 391, 394, 394, 403, 291, 356, 108, 108, - 356, 526, 403, 547, 546, 343, 543, 542, 391, 541, - 540, 539, 538, 526, 566, 566, 566, 566, 566, 566, + 559, 94, 78, 84, 49, 49, 78, 84, 94, 291, + 96, 6, 6, 96, 101, 106, 193, 106, 101, 193, + 107, 96, 107, 108, 291, 108, 96, 109, 111, 109, + 111, 115, 558, 115, 101, 108, 117, 155, 117, 180, + 343, 180, 115, 155, 201, 201, 391, 117, 255, 255, + 180, 356, 255, 394, 394, 526, 343, 556, 356, 403, + 555, 356, 391, 108, 108, 554, 403, 526, 566, 566, + 566, 566, 566, 566, 567, 567, 567, 567, 567, 567, + 568, 568, 568, 569, 569, 551, 569, 569, 569, 571, + 550, 548, 547, 571, 571, 572, 546, 543, 542, 572, - 567, 567, 567, 568, 568, 537, 568, 568, 568, 570, - 536, 533, 532, 570, 570, 571, 531, 530, 529, 571, - 571, 572, 572, 528, 572, 572, 572, 573, 573, 527, - 573, 573, 573, 574, 574, 523, 574, 574, 574, 522, - 521, 519, 518, 517, 515, 511, 510, 508, 507, 504, - 503, 502, 501, 500, 499, 498, 497, 495, 494, 493, - 490, 489, 488, 485, 481, 480, 479, 478, 477, 476, - 473, 472, 471, 470, 469, 468, 467, 466, 465, 464, - 463, 462, 461, 460, 459, 458, 457, 456, 454, 453, - 452, 450, 449, 448, 447, 446, 445, 444, 443, 442, + 572, 573, 573, 541, 573, 573, 573, 574, 574, 540, + 574, 574, 574, 575, 575, 539, 575, 575, 575, 538, + 537, 536, 533, 532, 531, 530, 529, 528, 527, 523, + 522, 521, 519, 518, 517, 515, 511, 510, 508, 507, + 504, 503, 502, 501, 500, 499, 498, 497, 495, 494, + 493, 490, 489, 488, 485, 481, 480, 479, 478, 477, + 476, 473, 472, 471, 470, 469, 468, 467, 466, 465, + 464, 463, 462, 461, 460, 459, 458, 457, 456, 454, + 453, 452, 450, 449, 448, 447, 446, 445, 444, 443, + 442, 441, 439, 437, 436, 435, 434, 433, 432, 429, - 441, 439, 437, 436, 435, 434, 433, 432, 429, 428, - 427, 426, 425, 424, 422, 420, 419, 418, 416, 414, - 409, 408, 407, 406, 405, 404, 402, 401, 400, 399, - 398, 397, 396, 393, 390, 389, 388, 387, 386, 385, - 384, 383, 382, 381, 380, 379, 377, 376, 375, 374, - 373, 372, 371, 370, 368, 367, 366, 365, 364, 362, - 361, 360, 359, 358, 357, 355, 354, 353, 352, 351, - 350, 349, 348, 347, 345, 344, 342, 340, 339, 338, - 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, - 326, 325, 323, 321, 320, 319, 318, 317, 316, 315, + 428, 427, 426, 425, 424, 422, 420, 419, 418, 416, + 414, 409, 408, 407, 406, 405, 404, 402, 401, 400, + 399, 398, 397, 396, 393, 390, 389, 388, 387, 386, + 385, 384, 383, 382, 381, 380, 379, 377, 376, 375, + 374, 373, 372, 371, 370, 368, 367, 366, 365, 364, + 362, 361, 360, 359, 358, 357, 355, 354, 353, 352, + 351, 350, 349, 348, 347, 345, 344, 342, 340, 339, + 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, + 328, 326, 325, 323, 321, 320, 319, 318, 317, 316, + 315, 314, 313, 312, 311, 310, 309, 308, 306, 305, - 314, 313, 312, 311, 310, 309, 308, 306, 305, 304, - 303, 302, 300, 299, 298, 297, 295, 294, 292, 290, - 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, - 277, 276, 275, 274, 273, 272, 271, 270, 268, 267, - 266, 265, 264, 263, 262, 261, 259, 258, 257, 256, - 254, 253, 251, 250, 248, 247, 246, 245, 244, 243, - 242, 241, 240, 239, 238, 237, 234, 233, 232, 231, - 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, - 220, 219, 217, 216, 215, 213, 212, 211, 210, 209, - 208, 207, 206, 205, 204, 202, 200, 199, 198, 197, + 304, 303, 302, 300, 299, 298, 297, 295, 294, 292, + 290, 288, 287, 286, 285, 284, 283, 282, 281, 280, + 279, 277, 276, 275, 274, 273, 272, 271, 270, 268, + 267, 266, 265, 264, 263, 262, 261, 259, 258, 257, + 256, 254, 253, 251, 250, 248, 247, 246, 245, 244, + 243, 242, 241, 240, 239, 238, 237, 234, 233, 232, + 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, + 221, 220, 219, 217, 216, 215, 213, 212, 211, 210, + 209, 208, 207, 206, 205, 204, 202, 200, 199, 198, + 197, 196, 195, 194, 192, 191, 190, 189, 188, 187, - 196, 195, 194, 192, 191, 190, 189, 188, 187, 186, - 185, 184, 183, 182, 181, 179, 178, 177, 176, 175, - 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, - 164, 163, 162, 161, 160, 159, 158, 156, 154, 153, - 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, - 142, 141, 140, 139, 137, 136, 135, 134, 133, 132, - 131, 130, 128, 127, 126, 125, 124, 123, 121, 120, - 114, 113, 105, 104, 103, 102, 100, 99, 97, 95, - 93, 92, 90, 89, 88, 87, 86, 85, 83, 82, - 81, 80, 79, 77, 76, 75, 74, 73, 72, 67, + 186, 185, 184, 183, 182, 181, 179, 178, 177, 176, + 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, + 165, 164, 163, 162, 161, 160, 159, 158, 156, 154, + 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, + 143, 142, 141, 140, 139, 137, 136, 135, 134, 133, + 132, 131, 130, 128, 127, 126, 125, 124, 123, 121, + 120, 114, 113, 105, 104, 103, 102, 100, 99, 97, + 95, 93, 92, 90, 89, 88, 87, 86, 85, 83, + 82, 81, 80, 79, 77, 76, 75, 74, 73, 72, + 67, 65, 64, 63, 61, 60, 56, 54, 52, 43, - 65, 64, 63, 61, 60, 56, 54, 52, 43, 34, - 24, 15, 7, 565, 565, 565, 565, 565, 565, 565, + 34, 24, 15, 7, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, 565, @@ -802,11 +800,10 @@ char *yy_text; /* this header file is automatically generated by bison * and includes all token definitions, as well as yy_lval */ #if ELBEEM_BLENDER==1 -// for blender the headers have to be .h #include "cfgparser.h" -#else +#else // ELBEEM_BLENDER==1 #include "cfgparser.hpp" -#endif +#endif // ELBEEM_BLENDER==1 #include "utilities.h" #include @@ -828,7 +825,7 @@ extern "C" int yy_wrap (void ) { return 1; } * rules start */ /*----------------------------------------------------------------------------*/ -#line 832 "" +#line 829 "" #define INITIAL 0 #define ATTR 1 @@ -981,11 +978,11 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 55 "src/cfglexer.ll" +#line 54 "src/cfglexer.ll" -#line 989 "" +#line 986 "" if ( (yy_init) ) { @@ -1066,25 +1063,25 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 58 "src/cfglexer.ll" +#line 57 "src/cfglexer.ll" { return KW_PAROPEN; } YY_BREAK case 2: YY_RULE_SETUP -#line 59 "src/cfglexer.ll" +#line 58 "src/cfglexer.ll" { BEGIN(INITIAL); // '}' always closes scopes return KW_PARCLOSE; } YY_BREAK case 3: YY_RULE_SETUP -#line 62 "src/cfglexer.ll" +#line 61 "src/cfglexer.ll" { BEGIN(ATTRVALUE); return KW_EQUALS; } YY_BREAK case 4: YY_RULE_SETUP -#line 65 "src/cfglexer.ll" +#line 64 "src/cfglexer.ll" { /* attribute name = normal string */ strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 ); yy_lval.charValue = charBuffer; @@ -1094,7 +1091,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 71 "src/cfglexer.ll" +#line 70 "src/cfglexer.ll" { /* quoted string! attribute name = normal string */ strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 ); /* get rid of " " */ @@ -1105,7 +1102,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 78 "src/cfglexer.ll" +#line 77 "src/cfglexer.ll" { /* ends at newline or ';' */ strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 ); yy_lval.charValue = charBuffer; @@ -1113,433 +1110,433 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 82 "src/cfglexer.ll" +#line 81 "src/cfglexer.ll" { /* return end token... */ BEGIN(ATTR); return KW_ATTREND; } YY_BREAK case 8: YY_RULE_SETUP -#line 87 "src/cfglexer.ll" +#line 86 "src/cfglexer.ll" { return KW_LBMSIM; } YY_BREAK case 9: YY_RULE_SETUP -#line 88 "src/cfglexer.ll" +#line 87 "src/cfglexer.ll" { return KW_COMPARELBM; } YY_BREAK case 10: YY_RULE_SETUP -#line 89 "src/cfglexer.ll" +#line 88 "src/cfglexer.ll" { return KW_DEBUGMODE; } YY_BREAK case 11: YY_RULE_SETUP -#line 90 "src/cfglexer.ll" +#line 89 "src/cfglexer.ll" { return KW_DEBUGLEVEL; } YY_BREAK case 12: YY_RULE_SETUP -#line 91 "src/cfglexer.ll" +#line 90 "src/cfglexer.ll" { return KW_RAYTRACING; } YY_BREAK case 13: YY_RULE_SETUP -#line 94 "src/cfglexer.ll" +#line 93 "src/cfglexer.ll" { return KW_RESOLUTION; } YY_BREAK case 14: YY_RULE_SETUP -#line 95 "src/cfglexer.ll" +#line 94 "src/cfglexer.ll" { return KW_ANTIALIAS; } YY_BREAK case 15: YY_RULE_SETUP -#line 96 "src/cfglexer.ll" +#line 95 "src/cfglexer.ll" { return KW_EYEPOINT; } YY_BREAK case 16: YY_RULE_SETUP -#line 97 "src/cfglexer.ll" +#line 96 "src/cfglexer.ll" { return KW_LOOKAT ; } YY_BREAK case 17: YY_RULE_SETUP -#line 98 "src/cfglexer.ll" +#line 97 "src/cfglexer.ll" { return KW_UPVEC ; } YY_BREAK case 18: YY_RULE_SETUP -#line 99 "src/cfglexer.ll" +#line 98 "src/cfglexer.ll" { return KW_FOVY; } YY_BREAK case 19: YY_RULE_SETUP -#line 100 "src/cfglexer.ll" +#line 99 "src/cfglexer.ll" { return KW_ASPECT ; } YY_BREAK case 20: YY_RULE_SETUP -#line 101 "src/cfglexer.ll" +#line 100 "src/cfglexer.ll" { return KW_AMBIENCE; } YY_BREAK case 21: YY_RULE_SETUP -#line 102 "src/cfglexer.ll" +#line 101 "src/cfglexer.ll" { return KW_BACKGROUND; } YY_BREAK case 22: YY_RULE_SETUP -#line 103 "src/cfglexer.ll" +#line 102 "src/cfglexer.ll" { return KW_ANISTART; } YY_BREAK case 23: YY_RULE_SETUP -#line 104 "src/cfglexer.ll" +#line 103 "src/cfglexer.ll" { return KW_ANIFRAMES; } YY_BREAK case 24: YY_RULE_SETUP -#line 105 "src/cfglexer.ll" +#line 104 "src/cfglexer.ll" { return KW_ANIFRAMETIME; } YY_BREAK case 25: YY_RULE_SETUP -#line 106 "src/cfglexer.ll" +#line 105 "src/cfglexer.ll" { return KW_FRAMESKIP; } YY_BREAK case 26: YY_RULE_SETUP -#line 107 "src/cfglexer.ll" +#line 106 "src/cfglexer.ll" { return KW_FILENAME; } YY_BREAK case 27: YY_RULE_SETUP -#line 108 "src/cfglexer.ll" +#line 107 "src/cfglexer.ll" { return KW_PMCAUSTICS; } YY_BREAK case 28: YY_RULE_SETUP -#line 109 "src/cfglexer.ll" +#line 108 "src/cfglexer.ll" { return KW_CAUSTICDIST; } YY_BREAK case 29: YY_RULE_SETUP -#line 110 "src/cfglexer.ll" +#line 109 "src/cfglexer.ll" { return KW_CAUSTICPHOT; } YY_BREAK case 30: YY_RULE_SETUP -#line 111 "src/cfglexer.ll" +#line 110 "src/cfglexer.ll" { return KW_SHADOWMAPBIAS; } YY_BREAK case 31: YY_RULE_SETUP -#line 112 "src/cfglexer.ll" +#line 111 "src/cfglexer.ll" { return KW_MAXRAYDEPTH; } YY_BREAK case 32: YY_RULE_SETUP -#line 113 "src/cfglexer.ll" +#line 112 "src/cfglexer.ll" { return KW_TREEMAXDEPTH; } YY_BREAK case 33: YY_RULE_SETUP -#line 114 "src/cfglexer.ll" +#line 113 "src/cfglexer.ll" { return KW_TREEMAXTRIANGLES; } YY_BREAK case 34: YY_RULE_SETUP -#line 115 "src/cfglexer.ll" +#line 114 "src/cfglexer.ll" { return KW_DEBUGPIXEL; } YY_BREAK case 35: YY_RULE_SETUP -#line 116 "src/cfglexer.ll" +#line 115 "src/cfglexer.ll" { return KW_TESTMODE; } YY_BREAK case 36: YY_RULE_SETUP -#line 117 "src/cfglexer.ll" +#line 116 "src/cfglexer.ll" { return KW_OPENGLATTR; } YY_BREAK case 37: YY_RULE_SETUP -#line 118 "src/cfglexer.ll" +#line 117 "src/cfglexer.ll" { return KW_BLENDERATTR; } YY_BREAK case 38: YY_RULE_SETUP -#line 120 "src/cfglexer.ll" +#line 119 "src/cfglexer.ll" { return KW_OBJATTR; /* assign attr to obj */ } YY_BREAK case 39: YY_RULE_SETUP -#line 121 "src/cfglexer.ll" +#line 120 "src/cfglexer.ll" { BEGIN(ATTR); return KW_ATTRIBUTE; /* global attr list */ } YY_BREAK case 40: YY_RULE_SETUP -#line 122 "src/cfglexer.ll" +#line 121 "src/cfglexer.ll" { BEGIN(ATTR); return KW_DEFINEATTR; /* obj defines new attrs */ } YY_BREAK case 41: YY_RULE_SETUP -#line 123 "src/cfglexer.ll" +#line 122 "src/cfglexer.ll" { BEGIN(ATTR); return KW_DEFINEATTR; } YY_BREAK case 42: YY_RULE_SETUP -#line 124 "src/cfglexer.ll" +#line 123 "src/cfglexer.ll" { BEGIN(ATTR); return KW_DEFINEATTR; } YY_BREAK case 43: YY_RULE_SETUP -#line 126 "src/cfglexer.ll" +#line 125 "src/cfglexer.ll" { return KW_GEOMETRY; } YY_BREAK case 44: YY_RULE_SETUP -#line 127 "src/cfglexer.ll" +#line 126 "src/cfglexer.ll" { return KW_TYPE; } YY_BREAK case 45: YY_RULE_SETUP -#line 128 "src/cfglexer.ll" +#line 127 "src/cfglexer.ll" { return KW_GEOTYPE_BOX; } YY_BREAK case 46: YY_RULE_SETUP -#line 129 "src/cfglexer.ll" +#line 128 "src/cfglexer.ll" { return KW_GEOTYPE_SPHERE; } YY_BREAK case 47: YY_RULE_SETUP -#line 130 "src/cfglexer.ll" +#line 129 "src/cfglexer.ll" { return KW_GEOTYPE_OBJMODEL; } YY_BREAK case 48: YY_RULE_SETUP -#line 131 "src/cfglexer.ll" +#line 130 "src/cfglexer.ll" { return KW_CASTSHADOWS; } YY_BREAK case 49: YY_RULE_SETUP -#line 132 "src/cfglexer.ll" +#line 131 "src/cfglexer.ll" { return KW_RECEIVESHADOWS ; } YY_BREAK case 50: YY_RULE_SETUP -#line 133 "src/cfglexer.ll" +#line 132 "src/cfglexer.ll" { return KW_VISIBLE; } YY_BREAK case 51: YY_RULE_SETUP -#line 134 "src/cfglexer.ll" +#line 133 "src/cfglexer.ll" { return KW_BOX_START; } YY_BREAK case 52: YY_RULE_SETUP -#line 135 "src/cfglexer.ll" +#line 134 "src/cfglexer.ll" { return KW_BOX_END; } YY_BREAK case 53: YY_RULE_SETUP -#line 136 "src/cfglexer.ll" +#line 135 "src/cfglexer.ll" { return KW_POLY ; } YY_BREAK case 54: YY_RULE_SETUP -#line 137 "src/cfglexer.ll" +#line 136 "src/cfglexer.ll" { return KW_POLY ; } YY_BREAK case 55: YY_RULE_SETUP -#line 138 "src/cfglexer.ll" +#line 137 "src/cfglexer.ll" { return KW_NUMVERTICES; } YY_BREAK case 56: YY_RULE_SETUP -#line 139 "src/cfglexer.ll" +#line 138 "src/cfglexer.ll" { return KW_VERTEX; } YY_BREAK case 57: YY_RULE_SETUP -#line 140 "src/cfglexer.ll" +#line 139 "src/cfglexer.ll" { return KW_NUMPOLYGONS; } YY_BREAK case 58: YY_RULE_SETUP -#line 141 "src/cfglexer.ll" +#line 140 "src/cfglexer.ll" { return KW_ISOSURF; } YY_BREAK case 59: YY_RULE_SETUP -#line 142 "src/cfglexer.ll" +#line 141 "src/cfglexer.ll" { return KW_FILEMODE; } YY_BREAK case 60: YY_RULE_SETUP -#line 143 "src/cfglexer.ll" +#line 142 "src/cfglexer.ll" { return KW_INVERT; } YY_BREAK case 61: YY_RULE_SETUP -#line 145 "src/cfglexer.ll" +#line 144 "src/cfglexer.ll" { return KW_MATERIAL; } YY_BREAK case 62: YY_RULE_SETUP -#line 146 "src/cfglexer.ll" +#line 145 "src/cfglexer.ll" { return KW_MATTYPE_PHONG; } YY_BREAK case 63: YY_RULE_SETUP -#line 147 "src/cfglexer.ll" +#line 146 "src/cfglexer.ll" { return KW_MATTYPE_BLINN; } YY_BREAK case 64: YY_RULE_SETUP -#line 148 "src/cfglexer.ll" +#line 147 "src/cfglexer.ll" { return KW_NAME; } YY_BREAK case 65: YY_RULE_SETUP -#line 149 "src/cfglexer.ll" +#line 148 "src/cfglexer.ll" { return KW_AMBIENT; } YY_BREAK case 66: YY_RULE_SETUP -#line 150 "src/cfglexer.ll" +#line 149 "src/cfglexer.ll" { return KW_DIFFUSE; } YY_BREAK case 67: YY_RULE_SETUP -#line 151 "src/cfglexer.ll" +#line 150 "src/cfglexer.ll" { return KW_SPECULAR; } YY_BREAK case 68: YY_RULE_SETUP -#line 152 "src/cfglexer.ll" +#line 151 "src/cfglexer.ll" { return KW_MIRROR; } YY_BREAK case 69: YY_RULE_SETUP -#line 153 "src/cfglexer.ll" +#line 152 "src/cfglexer.ll" { return KW_TRANSPARENCE; } YY_BREAK case 70: YY_RULE_SETUP -#line 154 "src/cfglexer.ll" +#line 153 "src/cfglexer.ll" { return KW_REFRACINDEX; } YY_BREAK case 71: YY_RULE_SETUP -#line 155 "src/cfglexer.ll" +#line 154 "src/cfglexer.ll" { return KW_TRANSADDITIVE; } YY_BREAK case 72: YY_RULE_SETUP -#line 156 "src/cfglexer.ll" +#line 155 "src/cfglexer.ll" { return KW_TRANSATTCOL; } YY_BREAK case 73: YY_RULE_SETUP -#line 157 "src/cfglexer.ll" +#line 156 "src/cfglexer.ll" { return KW_FRESNEL; } YY_BREAK case 74: YY_RULE_SETUP -#line 158 "src/cfglexer.ll" +#line 157 "src/cfglexer.ll" { return KW_FRESNEL; } YY_BREAK case 75: YY_RULE_SETUP -#line 160 "src/cfglexer.ll" +#line 159 "src/cfglexer.ll" { return KW_LIGHT; } YY_BREAK case 76: YY_RULE_SETUP -#line 161 "src/cfglexer.ll" +#line 160 "src/cfglexer.ll" { return KW_LIGHT_OMNI; } YY_BREAK case 77: YY_RULE_SETUP -#line 162 "src/cfglexer.ll" +#line 161 "src/cfglexer.ll" { return KW_ACTIVE; } YY_BREAK case 78: YY_RULE_SETUP -#line 163 "src/cfglexer.ll" +#line 162 "src/cfglexer.ll" { return KW_COLOUR; } YY_BREAK case 79: YY_RULE_SETUP -#line 164 "src/cfglexer.ll" +#line 163 "src/cfglexer.ll" { return KW_COLOUR; } YY_BREAK case 80: YY_RULE_SETUP -#line 165 "src/cfglexer.ll" +#line 164 "src/cfglexer.ll" { return KW_POSITION; } YY_BREAK case 81: YY_RULE_SETUP -#line 166 "src/cfglexer.ll" +#line 165 "src/cfglexer.ll" { return KW_CAUSTICPHOTONS; } YY_BREAK case 82: YY_RULE_SETUP -#line 167 "src/cfglexer.ll" +#line 166 "src/cfglexer.ll" { return KW_CAUSTICSTRENGTH; } YY_BREAK case 83: YY_RULE_SETUP -#line 168 "src/cfglexer.ll" +#line 167 "src/cfglexer.ll" { return KW_SHADOWMAP; } YY_BREAK case 84: YY_RULE_SETUP -#line 169 "src/cfglexer.ll" +#line 168 "src/cfglexer.ll" { return KW_CAUSTICSMAP; } YY_BREAK case 85: YY_RULE_SETUP -#line 171 "src/cfglexer.ll" +#line 170 "src/cfglexer.ll" { yy_lval.intValue = 1; return DT_INTEGER; } YY_BREAK case 86: YY_RULE_SETUP -#line 172 "src/cfglexer.ll" +#line 171 "src/cfglexer.ll" { yy_lval.intValue = 0; return DT_INTEGER; } YY_BREAK case 87: YY_RULE_SETUP -#line 173 "src/cfglexer.ll" +#line 172 "src/cfglexer.ll" { yy_lval.intValue = 1; return DT_INTEGER; } YY_BREAK case 88: YY_RULE_SETUP -#line 174 "src/cfglexer.ll" +#line 173 "src/cfglexer.ll" { yy_lval.intValue = 0; return DT_INTEGER; } YY_BREAK case 89: YY_RULE_SETUP -#line 177 "src/cfglexer.ll" +#line 176 "src/cfglexer.ll" { // integer number yy_lval.intValue = atoi( yy_text ); return DT_INTEGER; } YY_BREAK case 90: YY_RULE_SETUP -#line 181 "src/cfglexer.ll" +#line 180 "src/cfglexer.ll" { // floating point number yy_lval.floatValue = atof( yy_text ); return DT_FLOAT; } YY_BREAK case 91: YY_RULE_SETUP -#line 185 "src/cfglexer.ll" +#line 184 "src/cfglexer.ll" { /* normal character strings, now also for paths/filenames */ strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 ); /* get rid of " " */ @@ -1550,17 +1547,17 @@ YY_RULE_SETUP YY_BREAK case 92: YY_RULE_SETUP -#line 193 "src/cfglexer.ll" +#line 192 "src/cfglexer.ll" { /* one line comment */ } YY_BREAK case 93: YY_RULE_SETUP -#line 194 "src/cfglexer.ll" +#line 193 "src/cfglexer.ll" { /* one line comment */ } YY_BREAK case 94: YY_RULE_SETUP -#line 195 "src/cfglexer.ll" +#line 194 "src/cfglexer.ll" { /* multiline comment */ register int c; for ( ; ; ) { @@ -1586,26 +1583,26 @@ YY_RULE_SETUP case 95: /* rule 95 can match eol */ YY_RULE_SETUP -#line 219 "src/cfglexer.ll" +#line 218 "src/cfglexer.ll" { // count line numbers lineCount++; } YY_BREAK case 96: YY_RULE_SETUP -#line 222 "src/cfglexer.ll" +#line 221 "src/cfglexer.ll" { /* do nothing by default... */ } YY_BREAK case 97: YY_RULE_SETUP -#line 224 "src/cfglexer.ll" +#line 223 "src/cfglexer.ll" { /*errorOut( "cfgLexer, Line "<" +#line 1606 "" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(ATTR): case YY_STATE_EOF(ATTRVALUE): @@ -2570,4 +2567,4 @@ void yy_free (void * ptr ) #undef YY_DECL_IS_OURS #undef YY_DECL #endif -#line 227 "src/cfglexer.ll" +#line 226 "src/cfglexer.ll" diff --git a/intern/elbeem/make/msvc_7_0/elbeem.vcproj b/intern/elbeem/make/msvc_7_0/elbeem.vcproj index f2c44512338..afd4c345ccd 100644 --- a/intern/elbeem/make/msvc_7_0/elbeem.vcproj +++ b/intern/elbeem/make/msvc_7_0/elbeem.vcproj @@ -273,9 +273,6 @@ ECHO Done - - @@ -285,18 +282,6 @@ ECHO Done - - - - - - - - @@ -311,9 +296,6 @@ ECHO Done - - @@ -368,9 +350,6 @@ ECHO Done - - @@ -380,18 +359,6 @@ ECHO Done - - - - - - - - diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h index fa2f788823f..61a2b83011b 100644 --- a/intern/ghost/GHOST_ITimerTask.h +++ b/intern/ghost/GHOST_ITimerTask.h @@ -67,19 +67,19 @@ public: * Returns the timer callback. * @return The timer callback. */ - virtual GHOST_TimerProcPtr getTimerProc() const = 0; + inline virtual GHOST_TimerProcPtr getTimerProc() const = 0; /** * Changes the timer callback. * @param timerProc The timer callback. */ - virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0; + inline virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0; /** * Returns the timer user data. * @return The timer user data. */ - virtual GHOST_TUserDataPtr getUserData() const = 0; + inline virtual GHOST_TUserDataPtr getUserData() const = 0; /** * Changes the time user data. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 903d1e4498d..bd15df3dba8 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -79,7 +79,7 @@ public: * Returns the type of drawing context used in this window. * @return The current type of drawing context. */ - virtual GHOST_TDrawingContextType getDrawingContextType() = 0; + inline virtual GHOST_TDrawingContextType getDrawingContextType() = 0; /** * Tries to install a rendering context in this window. @@ -193,7 +193,7 @@ public: * Returns the window user data. * @return The window user data. */ - virtual GHOST_TUserDataPtr getUserData() const = 0; + inline virtual GHOST_TUserDataPtr getUserData() const = 0; /** * Changes the window user data. diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp index ee76349eded..d1caadab219 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.cpp +++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp @@ -655,7 +655,6 @@ OSStatus GHOST_SystemCarbon::handleWindowEvent(EventRef event) case kEventWindowActivated: m_windowManager->setActiveWindow(window); window->loadCursor(window->getCursorVisibility(), window->getCursorShape()); - window->updateDrawingContext(); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) ); break; case kEventWindowDeactivated: @@ -664,7 +663,6 @@ OSStatus GHOST_SystemCarbon::handleWindowEvent(EventRef event) break; case kEventWindowUpdate: //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n"); - window->updateDrawingContext(); pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) ); break; case kEventWindowBoundsChanged: diff --git a/intern/iksolver/intern/IK_Solver.cpp b/intern/iksolver/intern/IK_Solver.cpp index 919eeb739ce..23960a9550b 100644 --- a/intern/iksolver/intern/IK_Solver.cpp +++ b/intern/iksolver/intern/IK_Solver.cpp @@ -39,14 +39,11 @@ #include using namespace std; -class IK_QSolver { -public: - IK_QSolver() {}; - +typedef struct { IK_QJacobianSolver solver; IK_QSegment *root; std::list tasks; -}; +} IK_QSolver; IK_QSegment *CreateSegment(int flag, bool translate) { diff --git a/intern/iksolver/intern/TNT/cmat.h b/intern/iksolver/intern/TNT/cmat.h index c6d701b30fc..46eb1100475 100644 --- a/intern/iksolver/intern/TNT/cmat.h +++ b/intern/iksolver/intern/TNT/cmat.h @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef TNT_USE_REGIONS #include "region2d.h" #endif @@ -203,7 +204,19 @@ class Matrix copy(v); } + Matrix(Subscript M, Subscript N, const char *s) + { + initialize(M,N); + std::istrstream ins(s); + Subscript i, j; + + for (i=0; i> row_[i][j]; + } + + // destructor // ~Matrix() diff --git a/intern/iksolver/intern/TNT/fmat.h b/intern/iksolver/intern/TNT/fmat.h index daba50c993f..eb5531815eb 100644 --- a/intern/iksolver/intern/TNT/fmat.h +++ b/intern/iksolver/intern/TNT/fmat.h @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef TNT_USE_REGIONS #include "region2d.h" #endif @@ -197,6 +198,18 @@ class Fortran_Matrix } + Fortran_Matrix(Subscript M, Subscript N, char *s) + { + initialize(M,N); + std::istrstream ins(s); + + Subscript i, j; + + for (i=1; i<=M; i++) + for (j=1; j<=N; j++) + ins >> (*this)(i,j); + } + // destructor ~Fortran_Matrix() { diff --git a/intern/iksolver/intern/TNT/fspvec.h b/intern/iksolver/intern/TNT/fspvec.h index 1fafccdfe93..7ebba6f882d 100644 --- a/intern/iksolver/intern/TNT/fspvec.h +++ b/intern/iksolver/intern/TNT/fspvec.h @@ -39,6 +39,7 @@ #include #include #include +#include using namespace std; diff --git a/intern/iksolver/intern/TNT/vec.h b/intern/iksolver/intern/TNT/vec.h index 1729d83ca10..d4f7c2f4021 100644 --- a/intern/iksolver/intern/TNT/vec.h +++ b/intern/iksolver/intern/TNT/vec.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace TNT { @@ -185,6 +186,17 @@ class Vector copy(v); } + Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0) + { + initialize(N); + std::istrstream ins(s); + + Subscript i; + + for (i=0; i> v_[i]; + } + // methods // diff --git a/intern/iksolver/intern/TNT/vecadaptor.h b/intern/iksolver/intern/TNT/vecadaptor.h index ef2e66f19e0..fc5930c1b4f 100644 --- a/intern/iksolver/intern/TNT/vecadaptor.h +++ b/intern/iksolver/intern/TNT/vecadaptor.h @@ -33,6 +33,7 @@ #include #include +#include #include #include "subscript.h" @@ -116,6 +117,15 @@ class Vector_Adaptor } + Vector_Adaptor(Subscript N, /*const*/ char *s) : v_(N) + { + istrstream ins(s); + for (Subscript i=0; i> v_[i] ; + + vm1_ = ( v_.size() > 0 ? &(v_[0]) -1 : NULL); + }; + Vector_Adaptor(Subscript N, const T& value = T()) : v_(N) { for (Subscript i=0; i Project_Dep_Name MoTo End Project Dependency Begin Project Dependency - Project_Dep_Name OpenALSoundSystem - End Project Dependency - Begin Project Dependency Project_Dep_Name SoundSystem End Project Dependency Begin Project Dependency @@ -59,6 +56,9 @@ Package=<4> Begin Project Dependency Project_Dep_Name boolop End Project Dependency + Begin Project Dependency + Project_Dep_Name OpenALSoundSystem + End Project Dependency }}} ############################################################################### diff --git a/intern/opennl/extern/ONL_opennl.h b/intern/opennl/extern/ONL_opennl.h index 128f1b137bc..345cf0dc717 100644 --- a/intern/opennl/extern/ONL_opennl.h +++ b/intern/opennl/extern/ONL_opennl.h @@ -89,10 +89,6 @@ typedef void* NLContext; #define NL_SYMMETRIC 0x106 #define NL_ERROR 0x108 -/* Enable / Disable */ - -#define NL_NORMALIZE_ROWS 0x400 - /* Row parameters */ #define NL_RIGHT_HAND_SIDE 0x500 @@ -142,7 +138,9 @@ void nlRightHandSideAdd(NLuint index, NLfloat value); /* Solve */ -NLboolean nlSolve(void); +void nlPrintMatrix(void); +NLboolean nlSolve(); +NLboolean nlSolveAdvanced(NLint *permutation, NLboolean solveAgain); #ifdef __cplusplus } diff --git a/intern/opennl/intern/opennl.c b/intern/opennl/intern/opennl.c index 7773582e027..c5518731c6b 100644 --- a/intern/opennl/intern/opennl.c +++ b/intern/opennl/intern/opennl.c @@ -24,13 +24,13 @@ * * Contact: Bruno Levy * - * levy@loria.fr + * levy@loria.fr * - * ISA Project - * LORIA, INRIA Lorraine, - * Campus Scientifique, BP 239 - * 54506 VANDOEUVRE LES NANCY CEDEX - * FRANCE + * ISA Project + * LORIA, INRIA Lorraine, + * Campus Scientifique, BP 239 + * 54506 VANDOEUVRE LES NANCY CEDEX + * FRANCE * * Note that the GNU General Public License does not permit incorporating * the Software into proprietary programs. @@ -58,51 +58,51 @@ static void __nl_assertion_failed(char* cond, char* file, int line) { - fprintf( - stderr, - "OpenNL assertion failed: %s, file:%s, line:%d\n", - cond,file,line - ); - abort(); + fprintf( + stderr, + "OpenNL assertion failed: %s, file:%s, line:%d\n", + cond,file,line + ); + abort(); } static void __nl_range_assertion_failed( - float x, float min_val, float max_val, char* file, int line + float x, float min_val, float max_val, char* file, int line ) { - fprintf( - stderr, - "OpenNL range assertion failed: %f in [ %f ... %f ], file:%s, line:%d\n", - x, min_val, max_val, file,line - ); - abort(); + fprintf( + stderr, + "OpenNL range assertion failed: %f in [ %f ... %f ], file:%s, line:%d\n", + x, min_val, max_val, file,line + ); + abort(); } static void __nl_should_not_have_reached(char* file, int line) { - fprintf( - stderr, - "OpenNL should not have reached this point: file:%s, line:%d\n", - file,line - ); - abort(); + fprintf( + stderr, + "OpenNL should not have reached this point: file:%s, line:%d\n", + file,line + ); + abort(); } -#define __nl_assert(x) { \ - if(!(x)) { \ - __nl_assertion_failed(#x,__FILE__, __LINE__); \ - } \ +#define __nl_assert(x) { \ + if(!(x)) { \ + __nl_assertion_failed(#x,__FILE__, __LINE__); \ + } \ } -#define __nl_range_assert(x,min_val,max_val) { \ - if(((x) < (min_val)) || ((x) > (max_val))) { \ - __nl_range_assertion_failed(x, min_val, max_val, \ - __FILE__, __LINE__ \ - ); \ - } \ +#define __nl_range_assert(x,min_val,max_val) { \ + if(((x) < (min_val)) || ((x) > (max_val))) { \ + __nl_range_assertion_failed(x, min_val, max_val, \ + __FILE__, __LINE__ \ + ); \ + } \ } -#define __nl_assert_not_reached { \ - __nl_should_not_have_reached(__FILE__, __LINE__); \ +#define __nl_assert_not_reached { \ + __nl_should_not_have_reached(__FILE__, __LINE__); \ } #ifdef NL_DEBUG @@ -135,301 +135,301 @@ static void __nl_should_not_have_reached(char* file, int line) { /************************************************************************************/ /* memory management */ -#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) -#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T))) +#define __NL_NEW(T) (T*)(calloc(1, sizeof(T))) +#define __NL_NEW_ARRAY(T,NB) (T*)(calloc((NB),sizeof(T))) #define __NL_RENEW_ARRAY(T,x,NB) (T*)(realloc(x,(NB)*sizeof(T))) -#define __NL_DELETE(x) free(x); x = NULL -#define __NL_DELETE_ARRAY(x) free(x); x = NULL +#define __NL_DELETE(x) free(x); x = NULL +#define __NL_DELETE_ARRAY(x) free(x); x = NULL -#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) +#define __NL_CLEAR(T, x) memset(x, 0, sizeof(T)) #define __NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (NB)*sizeof(T)) /************************************************************************************/ /* Dynamic arrays for sparse row/columns */ typedef struct { - NLuint index; - NLfloat value; + NLuint index; + NLfloat value; } __NLCoeff; typedef struct { - NLuint size; - NLuint capacity; - __NLCoeff* coeff; + NLuint size; + NLuint capacity; + __NLCoeff* coeff; } __NLRowColumn; static void __nlRowColumnConstruct(__NLRowColumn* c) { - c->size = 0; - c->capacity = 0; - c->coeff = NULL; + c->size = 0; + c->capacity = 0; + c->coeff = NULL; } static void __nlRowColumnDestroy(__NLRowColumn* c) { - __NL_DELETE_ARRAY(c->coeff); + __NL_DELETE_ARRAY(c->coeff); #ifdef NL_PARANOID - __NL_CLEAR(__NLRowColumn, c); + __NL_CLEAR(__NLRowColumn, c); #endif } static void __nlRowColumnGrow(__NLRowColumn* c) { - if(c->capacity != 0) { - c->capacity = 2 * c->capacity; - c->coeff = __NL_RENEW_ARRAY(__NLCoeff, c->coeff, c->capacity); - } else { - c->capacity = 4; - c->coeff = __NL_NEW_ARRAY(__NLCoeff, c->capacity); - } + if(c->capacity != 0) { + c->capacity = 2 * c->capacity; + c->coeff = __NL_RENEW_ARRAY(__NLCoeff, c->coeff, c->capacity); + } else { + c->capacity = 4; + c->coeff = __NL_NEW_ARRAY(__NLCoeff, c->capacity); + } } static void __nlRowColumnAdd(__NLRowColumn* c, NLint index, NLfloat value) { - NLuint i; - for(i=0; isize; i++) { - if(c->coeff[i].index == (NLuint)index) { - c->coeff[i].value += value; - return; - } - } - if(c->size == c->capacity) { - __nlRowColumnGrow(c); - } - c->coeff[c->size].index = index; - c->coeff[c->size].value = value; - c->size++; + NLuint i; + for(i=0; isize; i++) { + if(c->coeff[i].index == (NLuint)index) { + c->coeff[i].value += value; + return; + } + } + if(c->size == c->capacity) { + __nlRowColumnGrow(c); + } + c->coeff[c->size].index = index; + c->coeff[c->size].value = value; + c->size++; } /* Does not check whether the index already exists */ static void __nlRowColumnAppend(__NLRowColumn* c, NLint index, NLfloat value) { - if(c->size == c->capacity) { - __nlRowColumnGrow(c); - } - c->coeff[c->size].index = index; - c->coeff[c->size].value = value; - c->size++; + if(c->size == c->capacity) { + __nlRowColumnGrow(c); + } + c->coeff[c->size].index = index; + c->coeff[c->size].value = value; + c->size++; } static void __nlRowColumnZero(__NLRowColumn* c) { - c->size = 0; + c->size = 0; } static void __nlRowColumnClear(__NLRowColumn* c) { - c->size = 0; - c->capacity = 0; - __NL_DELETE_ARRAY(c->coeff); + c->size = 0; + c->capacity = 0; + __NL_DELETE_ARRAY(c->coeff); } /************************************************************************************/ /* SparseMatrix data structure */ -#define __NL_ROWS 1 +#define __NL_ROWS 1 #define __NL_COLUMNS 2 #define __NL_SYMMETRIC 4 typedef struct { - NLuint m; - NLuint n; - NLuint diag_size; - NLenum storage; - __NLRowColumn* row; - __NLRowColumn* column; - NLfloat* diag; + NLuint m; + NLuint n; + NLuint diag_size; + NLenum storage; + __NLRowColumn* row; + __NLRowColumn* column; + NLfloat* diag; } __NLSparseMatrix; static void __nlSparseMatrixConstruct( - __NLSparseMatrix* M, NLuint m, NLuint n, NLenum storage + __NLSparseMatrix* M, NLuint m, NLuint n, NLenum storage ) { - NLuint i; - M->m = m; - M->n = n; - M->storage = storage; - if(storage & __NL_ROWS) { - M->row = __NL_NEW_ARRAY(__NLRowColumn, m); - for(i=0; irow[i])); - } - } else { - M->row = NULL; - } + NLuint i; + M->m = m; + M->n = n; + M->storage = storage; + if(storage & __NL_ROWS) { + M->row = __NL_NEW_ARRAY(__NLRowColumn, m); + for(i=0; irow[i])); + } + } else { + M->row = NULL; + } - if(storage & __NL_COLUMNS) { - M->column = __NL_NEW_ARRAY(__NLRowColumn, n); - for(i=0; icolumn[i])); - } - } else { - M->column = NULL; - } + if(storage & __NL_COLUMNS) { + M->column = __NL_NEW_ARRAY(__NLRowColumn, n); + for(i=0; icolumn[i])); + } + } else { + M->column = NULL; + } - M->diag_size = MIN(m,n); - M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size); + M->diag_size = MIN(m,n); + M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size); } static void __nlSparseMatrixDestroy(__NLSparseMatrix* M) { - NLuint i; - __NL_DELETE_ARRAY(M->diag); - if(M->storage & __NL_ROWS) { - for(i=0; im; i++) { - __nlRowColumnDestroy(&(M->row[i])); - } - __NL_DELETE_ARRAY(M->row); - } - if(M->storage & __NL_COLUMNS) { - for(i=0; in; i++) { - __nlRowColumnDestroy(&(M->column[i])); - } - __NL_DELETE_ARRAY(M->column); - } + NLuint i; + __NL_DELETE_ARRAY(M->diag); + if(M->storage & __NL_ROWS) { + for(i=0; im; i++) { + __nlRowColumnDestroy(&(M->row[i])); + } + __NL_DELETE_ARRAY(M->row); + } + if(M->storage & __NL_COLUMNS) { + for(i=0; in; i++) { + __nlRowColumnDestroy(&(M->column[i])); + } + __NL_DELETE_ARRAY(M->column); + } #ifdef NL_PARANOID - __NL_CLEAR(__NLSparseMatrix,M); + __NL_CLEAR(__NLSparseMatrix,M); #endif } static void __nlSparseMatrixAdd( - __NLSparseMatrix* M, NLuint i, NLuint j, NLfloat value + __NLSparseMatrix* M, NLuint i, NLuint j, NLfloat value ) { - __nl_parano_range_assert(i, 0, M->m - 1); - __nl_parano_range_assert(j, 0, M->n - 1); - if((M->storage & __NL_SYMMETRIC) && (j > i)) { - return; - } - if(i == j) { - M->diag[i] += value; - } - if(M->storage & __NL_ROWS) { - __nlRowColumnAdd(&(M->row[i]), j, value); - } - if(M->storage & __NL_COLUMNS) { - __nlRowColumnAdd(&(M->column[j]), i, value); - } + __nl_parano_range_assert(i, 0, M->m - 1); + __nl_parano_range_assert(j, 0, M->n - 1); + if((M->storage & __NL_SYMMETRIC) && (j > i)) { + return; + } + if(i == j) { + M->diag[i] += value; + } + if(M->storage & __NL_ROWS) { + __nlRowColumnAdd(&(M->row[i]), j, value); + } + if(M->storage & __NL_COLUMNS) { + __nlRowColumnAdd(&(M->column[j]), i, value); + } } static void __nlSparseMatrixClear( __NLSparseMatrix* M) { - NLuint i; - if(M->storage & __NL_ROWS) { - for(i=0; im; i++) { - __nlRowColumnClear(&(M->row[i])); - } - } - if(M->storage & __NL_COLUMNS) { - for(i=0; in; i++) { - __nlRowColumnClear(&(M->column[i])); - } - } - __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size); + NLuint i; + if(M->storage & __NL_ROWS) { + for(i=0; im; i++) { + __nlRowColumnClear(&(M->row[i])); + } + } + if(M->storage & __NL_COLUMNS) { + for(i=0; in; i++) { + __nlRowColumnClear(&(M->column[i])); + } + } + __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size); } /* Returns the number of non-zero coefficients */ static NLuint __nlSparseMatrixNNZ( __NLSparseMatrix* M) { - NLuint nnz = 0; - NLuint i; - if(M->storage & __NL_ROWS) { - for(i = 0; im; i++) { - nnz += M->row[i].size; - } - } else if (M->storage & __NL_COLUMNS) { - for(i = 0; in; i++) { - nnz += M->column[i].size; - } - } else { - __nl_assert_not_reached; - } - return nnz; + NLuint nnz = 0; + NLuint i; + if(M->storage & __NL_ROWS) { + for(i = 0; im; i++) { + nnz += M->row[i].size; + } + } else if (M->storage & __NL_COLUMNS) { + for(i = 0; in; i++) { + nnz += M->column[i].size; + } + } else { + __nl_assert_not_reached; + } + return nnz; } /************************************************************************************/ /* SparseMatrix x Vector routines, internal helper routines */ static void __nlSparseMatrix_mult_rows_symmetric( - __NLSparseMatrix* A, NLfloat* x, NLfloat* y + __NLSparseMatrix* A, NLfloat* x, NLfloat* y ) { - NLuint m = A->m; - NLuint i,ij; - __NLRowColumn* Ri = NULL; - __NLCoeff* c = NULL; - for(i=0; irow[i]); - for(ij=0; ijsize; ij++) { - c = &(Ri->coeff[ij]); - y[i] += c->value * x[c->index]; - if(i != c->index) { - y[c->index] += c->value * x[i]; - } - } - } + NLuint m = A->m; + NLuint i,ij; + __NLRowColumn* Ri = NULL; + __NLCoeff* c = NULL; + for(i=0; irow[i]); + for(ij=0; ijsize; ij++) { + c = &(Ri->coeff[ij]); + y[i] += c->value * x[c->index]; + if(i != c->index) { + y[c->index] += c->value * x[i]; + } + } + } } static void __nlSparseMatrix_mult_rows( - __NLSparseMatrix* A, NLfloat* x, NLfloat* y + __NLSparseMatrix* A, NLfloat* x, NLfloat* y ) { - NLuint m = A->m; - NLuint i,ij; - __NLRowColumn* Ri = NULL; - __NLCoeff* c = NULL; - for(i=0; irow[i]); - for(ij=0; ijsize; ij++) { - c = &(Ri->coeff[ij]); - y[i] += c->value * x[c->index]; - } - } + NLuint m = A->m; + NLuint i,ij; + __NLRowColumn* Ri = NULL; + __NLCoeff* c = NULL; + for(i=0; irow[i]); + for(ij=0; ijsize; ij++) { + c = &(Ri->coeff[ij]); + y[i] += c->value * x[c->index]; + } + } } static void __nlSparseMatrix_mult_cols_symmetric( - __NLSparseMatrix* A, NLfloat* x, NLfloat* y + __NLSparseMatrix* A, NLfloat* x, NLfloat* y ) { - NLuint n = A->n; - NLuint j,ii; - __NLRowColumn* Cj = NULL; - __NLCoeff* c = NULL; - for(j=0; jcolumn[j]); - for(ii=0; iisize; ii++) { - c = &(Cj->coeff[ii]); - y[c->index] += c->value * x[j]; - if(j != c->index) { - y[j] += c->value * x[c->index]; - } - } - } + NLuint n = A->n; + NLuint j,ii; + __NLRowColumn* Cj = NULL; + __NLCoeff* c = NULL; + for(j=0; jcolumn[j]); + for(ii=0; iisize; ii++) { + c = &(Cj->coeff[ii]); + y[c->index] += c->value * x[j]; + if(j != c->index) { + y[j] += c->value * x[c->index]; + } + } + } } static void __nlSparseMatrix_mult_cols( - __NLSparseMatrix* A, NLfloat* x, NLfloat* y + __NLSparseMatrix* A, NLfloat* x, NLfloat* y ) { - NLuint n = A->n; - NLuint j,ii; - __NLRowColumn* Cj = NULL; - __NLCoeff* c = NULL; - __NL_CLEAR_ARRAY(NLfloat, y, A->m); - for(j=0; jcolumn[j]); - for(ii=0; iisize; ii++) { - c = &(Cj->coeff[ii]); - y[c->index] += c->value * x[j]; - } - } + NLuint n = A->n; + NLuint j,ii; + __NLRowColumn* Cj = NULL; + __NLCoeff* c = NULL; + __NL_CLEAR_ARRAY(NLfloat, y, A->m); + for(j=0; jcolumn[j]); + for(ii=0; iisize; ii++) { + c = &(Cj->coeff[ii]); + y[c->index] += c->value * x[j]; + } + } } /************************************************************************************/ /* SparseMatrix x Vector routines, main driver routine */ static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLfloat* x, NLfloat* y) { - if(A->storage & __NL_ROWS) { - if(A->storage & __NL_SYMMETRIC) { - __nlSparseMatrix_mult_rows_symmetric(A, x, y); - } else { - __nlSparseMatrix_mult_rows(A, x, y); - } - } else { - if(A->storage & __NL_SYMMETRIC) { - __nlSparseMatrix_mult_cols_symmetric(A, x, y); - } else { - __nlSparseMatrix_mult_cols(A, x, y); - } - } + if(A->storage & __NL_ROWS) { + if(A->storage & __NL_SYMMETRIC) { + __nlSparseMatrix_mult_rows_symmetric(A, x, y); + } else { + __nlSparseMatrix_mult_rows(A, x, y); + } + } else { + if(A->storage & __NL_SYMMETRIC) { + __nlSparseMatrix_mult_cols_symmetric(A, x, y); + } else { + __nlSparseMatrix_mult_cols(A, x, y); + } + } } /************************************************************************************/ @@ -438,513 +438,467 @@ static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLfloat* x, NLfloat* y) { typedef void(*__NLMatrixFunc)(float* x, float* y); typedef struct { - NLfloat value; - NLboolean locked; - NLuint index; + NLfloat value; + NLboolean locked; + NLuint index; } __NLVariable; -#define __NL_STATE_INITIAL 0 -#define __NL_STATE_SYSTEM 1 -#define __NL_STATE_MATRIX 2 -#define __NL_STATE_ROW 3 -#define __NL_STATE_MATRIX_CONSTRUCTED 4 -#define __NL_STATE_SYSTEM_CONSTRUCTED 5 -#define __NL_STATE_SOLVED 6 +#define __NL_STATE_INITIAL 0 +#define __NL_STATE_SYSTEM 1 +#define __NL_STATE_MATRIX 2 +#define __NL_STATE_ROW 3 +#define __NL_STATE_MATRIX_CONSTRUCTED 4 +#define __NL_STATE_SYSTEM_CONSTRUCTED 5 +#define __NL_STATE_SYSTEM_SOLVED 7 typedef struct { - NLenum state; - __NLVariable* variable; - NLuint n; - __NLSparseMatrix M; - __NLRowColumn af; - __NLRowColumn al; - __NLRowColumn xl; - NLfloat* x; - NLfloat* b; - NLfloat right_hand_side; - NLfloat row_scaling; - NLuint nb_variables; - NLuint current_row; - NLboolean least_squares; - NLboolean symmetric; - NLboolean normalize_rows; - NLboolean alloc_M; - NLboolean alloc_af; - NLboolean alloc_al; - NLboolean alloc_xl; - NLboolean alloc_variable; - NLboolean alloc_x; - NLboolean alloc_b; - NLfloat error; - __NLMatrixFunc matrix_vector_prod; + NLenum state; + __NLVariable* variable; + NLuint n; + __NLSparseMatrix M; + __NLRowColumn af; + __NLRowColumn al; + NLfloat* x; + NLfloat* b; + NLfloat right_hand_side; + NLuint nb_variables; + NLuint current_row; + NLboolean least_squares; + NLboolean symmetric; + NLboolean solve_again; + NLboolean alloc_M; + NLboolean alloc_af; + NLboolean alloc_al; + NLboolean alloc_variable; + NLboolean alloc_x; + NLboolean alloc_b; + NLfloat error; + __NLMatrixFunc matrix_vector_prod; + + struct __NLSuperLUContext { + NLboolean alloc_slu; + SuperMatrix L, U; + NLint *perm_c, *perm_r; + SuperLUStat_t stat; + } slu; } __NLContext; static __NLContext* __nlCurrentContext = NULL; static void __nlMatrixVectorProd_default(NLfloat* x, NLfloat* y) { - __nlSparseMatrixMult(&(__nlCurrentContext->M), x, y); + __nlSparseMatrixMult(&(__nlCurrentContext->M), x, y); } NLContext nlNewContext(void) { - __NLContext* result = __NL_NEW(__NLContext); - result->state = __NL_STATE_INITIAL; - result->row_scaling = 1.0; - result->right_hand_side = 0.0; - result->matrix_vector_prod = __nlMatrixVectorProd_default; - nlMakeCurrent(result); - return result; + __NLContext* result = __NL_NEW(__NLContext); + result->state = __NL_STATE_INITIAL; + result->right_hand_side = 0.0; + result->matrix_vector_prod = __nlMatrixVectorProd_default; + nlMakeCurrent(result); + return result; } +static void __nlFree_SUPERLU(__NLContext *context); + void nlDeleteContext(NLContext context_in) { - __NLContext* context = (__NLContext*)(context_in); - if(__nlCurrentContext == context) { - __nlCurrentContext = NULL; - } - if(context->alloc_M) { - __nlSparseMatrixDestroy(&context->M); - } - if(context->alloc_af) { - __nlRowColumnDestroy(&context->af); - } - if(context->alloc_al) { - __nlRowColumnDestroy(&context->al); - } - if(context->alloc_xl) { - __nlRowColumnDestroy(&context->xl); - } - if(context->alloc_variable) { - __NL_DELETE_ARRAY(context->variable); - } - if(context->alloc_x) { - __NL_DELETE_ARRAY(context->x); - } - if(context->alloc_b) { - __NL_DELETE_ARRAY(context->b); - } + __NLContext* context = (__NLContext*)(context_in); + if(__nlCurrentContext == context) { + __nlCurrentContext = NULL; + } + if(context->alloc_M) { + __nlSparseMatrixDestroy(&context->M); + } + if(context->alloc_af) { + __nlRowColumnDestroy(&context->af); + } + if(context->alloc_al) { + __nlRowColumnDestroy(&context->al); + } + if(context->alloc_variable) { + __NL_DELETE_ARRAY(context->variable); + } + if(context->alloc_x) { + __NL_DELETE_ARRAY(context->x); + } + if(context->alloc_b) { + __NL_DELETE_ARRAY(context->b); + } + if (context->slu.alloc_slu) { + __nlFree_SUPERLU(context); + } #ifdef NL_PARANOID - __NL_CLEAR(__NLContext, context); + __NL_CLEAR(__NLContext, context); #endif - __NL_DELETE(context); + __NL_DELETE(context); } void nlMakeCurrent(NLContext context) { - __nlCurrentContext = (__NLContext*)(context); + __nlCurrentContext = (__NLContext*)(context); } NLContext nlGetCurrent(void) { - return __nlCurrentContext; + return __nlCurrentContext; } static void __nlCheckState(NLenum state) { - __nl_assert(__nlCurrentContext->state == state); + __nl_assert(__nlCurrentContext->state == state); } static void __nlTransition(NLenum from_state, NLenum to_state) { - __nlCheckState(from_state); - __nlCurrentContext->state = to_state; + __nlCheckState(from_state); + __nlCurrentContext->state = to_state; } /************************************************************************************/ /* Get/Set parameters */ void nlSolverParameterf(NLenum pname, NLfloat param) { - __nlCheckState(__NL_STATE_INITIAL); - switch(pname) { - case NL_NB_VARIABLES: { - __nl_assert(param > 0); - __nlCurrentContext->nb_variables = (NLuint)param; - } break; - case NL_LEAST_SQUARES: { - __nlCurrentContext->least_squares = (NLboolean)param; - } break; - case NL_SYMMETRIC: { - __nlCurrentContext->symmetric = (NLboolean)param; - } - default: { - __nl_assert_not_reached; - } break; - } + __nlCheckState(__NL_STATE_INITIAL); + switch(pname) { + case NL_NB_VARIABLES: { + __nl_assert(param > 0); + __nlCurrentContext->nb_variables = (NLuint)param; + } break; + case NL_LEAST_SQUARES: { + __nlCurrentContext->least_squares = (NLboolean)param; + } break; + case NL_SYMMETRIC: { + __nlCurrentContext->symmetric = (NLboolean)param; + } + default: { + __nl_assert_not_reached; + } break; + } } void nlSolverParameteri(NLenum pname, NLint param) { - __nlCheckState(__NL_STATE_INITIAL); - switch(pname) { - case NL_NB_VARIABLES: { - __nl_assert(param > 0); - __nlCurrentContext->nb_variables = (NLuint)param; - } break; - case NL_LEAST_SQUARES: { - __nlCurrentContext->least_squares = (NLboolean)param; - } break; - case NL_SYMMETRIC: { - __nlCurrentContext->symmetric = (NLboolean)param; - } - default: { - __nl_assert_not_reached; - } break; - } + __nlCheckState(__NL_STATE_INITIAL); + switch(pname) { + case NL_NB_VARIABLES: { + __nl_assert(param > 0); + __nlCurrentContext->nb_variables = (NLuint)param; + } break; + case NL_LEAST_SQUARES: { + __nlCurrentContext->least_squares = (NLboolean)param; + } break; + case NL_SYMMETRIC: { + __nlCurrentContext->symmetric = (NLboolean)param; + } + default: { + __nl_assert_not_reached; + } break; + } } void nlRowParameterf(NLenum pname, NLfloat param) { - __nlCheckState(__NL_STATE_MATRIX); - switch(pname) { - case NL_RIGHT_HAND_SIDE: { - __nlCurrentContext->right_hand_side = param; - } break; - case NL_ROW_SCALING: { - __nlCurrentContext->row_scaling = param; - } break; - } + __nlCheckState(__NL_STATE_MATRIX); + switch(pname) { + case NL_RIGHT_HAND_SIDE: { + __nlCurrentContext->right_hand_side = param; + } break; + } } void nlRowParameteri(NLenum pname, NLint param) { - __nlCheckState(__NL_STATE_MATRIX); - switch(pname) { - case NL_RIGHT_HAND_SIDE: { - __nlCurrentContext->right_hand_side = (NLfloat)param; - } break; - case NL_ROW_SCALING: { - __nlCurrentContext->row_scaling = (NLfloat)param; - } break; - } + __nlCheckState(__NL_STATE_MATRIX); + switch(pname) { + case NL_RIGHT_HAND_SIDE: { + __nlCurrentContext->right_hand_side = (NLfloat)param; + } break; + } } void nlGetBooleanv(NLenum pname, NLboolean* params) { - switch(pname) { - case NL_LEAST_SQUARES: { - *params = __nlCurrentContext->least_squares; - } break; - case NL_SYMMETRIC: { - *params = __nlCurrentContext->symmetric; - } break; - default: { - __nl_assert_not_reached; - } break; - } + switch(pname) { + case NL_LEAST_SQUARES: { + *params = __nlCurrentContext->least_squares; + } break; + case NL_SYMMETRIC: { + *params = __nlCurrentContext->symmetric; + } break; + default: { + __nl_assert_not_reached; + } break; + } } void nlGetFloatv(NLenum pname, NLfloat* params) { - switch(pname) { - case NL_NB_VARIABLES: { - *params = (NLfloat)(__nlCurrentContext->nb_variables); - } break; - case NL_LEAST_SQUARES: { - *params = (NLfloat)(__nlCurrentContext->least_squares); - } break; - case NL_SYMMETRIC: { - *params = (NLfloat)(__nlCurrentContext->symmetric); - } break; - case NL_ERROR: { - *params = (NLfloat)(__nlCurrentContext->error); - } break; - default: { - __nl_assert_not_reached; - } break; - } + switch(pname) { + case NL_NB_VARIABLES: { + *params = (NLfloat)(__nlCurrentContext->nb_variables); + } break; + case NL_LEAST_SQUARES: { + *params = (NLfloat)(__nlCurrentContext->least_squares); + } break; + case NL_SYMMETRIC: { + *params = (NLfloat)(__nlCurrentContext->symmetric); + } break; + case NL_ERROR: { + *params = (NLfloat)(__nlCurrentContext->error); + } break; + default: { + __nl_assert_not_reached; + } break; + } } void nlGetIntergerv(NLenum pname, NLint* params) { - switch(pname) { - case NL_NB_VARIABLES: { - *params = (NLint)(__nlCurrentContext->nb_variables); - } break; - case NL_LEAST_SQUARES: { - *params = (NLint)(__nlCurrentContext->least_squares); - } break; - case NL_SYMMETRIC: { - *params = (NLint)(__nlCurrentContext->symmetric); - } break; - default: { - __nl_assert_not_reached; - } break; - } + switch(pname) { + case NL_NB_VARIABLES: { + *params = (NLint)(__nlCurrentContext->nb_variables); + } break; + case NL_LEAST_SQUARES: { + *params = (NLint)(__nlCurrentContext->least_squares); + } break; + case NL_SYMMETRIC: { + *params = (NLint)(__nlCurrentContext->symmetric); + } break; + default: { + __nl_assert_not_reached; + } break; + } } /************************************************************************************/ /* Enable / Disable */ void nlEnable(NLenum pname) { - switch(pname) { - case NL_NORMALIZE_ROWS: { - __nl_assert(__nlCurrentContext->state != __NL_STATE_ROW); - __nlCurrentContext->normalize_rows = NL_TRUE; - } break; - default: { - __nl_assert_not_reached; - } - } + switch(pname) { + default: { + __nl_assert_not_reached; + } + } } void nlDisable(NLenum pname) { - switch(pname) { - case NL_NORMALIZE_ROWS: { - __nl_assert(__nlCurrentContext->state != __NL_STATE_ROW); - __nlCurrentContext->normalize_rows = NL_FALSE; - } break; - default: { - __nl_assert_not_reached; - } - } + switch(pname) { + default: { + __nl_assert_not_reached; + } + } } NLboolean nlIsEnabled(NLenum pname) { - switch(pname) { - case NL_NORMALIZE_ROWS: { - return __nlCurrentContext->normalize_rows; - } break; - default: { - __nl_assert_not_reached; - } - } - return NL_FALSE; + switch(pname) { + default: { + __nl_assert_not_reached; + } + } + return NL_FALSE; } /************************************************************************************/ /* Get/Set Lock/Unlock variables */ void nlSetVariable(NLuint index, NLfloat value) { - __nlCheckState(__NL_STATE_SYSTEM); - __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); - __nlCurrentContext->variable[index].value = value; + __nlCheckState(__NL_STATE_SYSTEM); + __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); + __nlCurrentContext->variable[index].value = value; } NLfloat nlGetVariable(NLuint index) { - __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL); - __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); - return __nlCurrentContext->variable[index].value; + __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL); + __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); + return __nlCurrentContext->variable[index].value; } void nlLockVariable(NLuint index) { - __nlCheckState(__NL_STATE_SYSTEM); - __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); - __nlCurrentContext->variable[index].locked = NL_TRUE; + __nlCheckState(__NL_STATE_SYSTEM); + __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); + __nlCurrentContext->variable[index].locked = NL_TRUE; } void nlUnlockVariable(NLuint index) { - __nlCheckState(__NL_STATE_SYSTEM); - __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); - __nlCurrentContext->variable[index].locked = NL_FALSE; + __nlCheckState(__NL_STATE_SYSTEM); + __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); + __nlCurrentContext->variable[index].locked = NL_FALSE; } NLboolean nlVariableIsLocked(NLuint index) { - __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL); - __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); - return __nlCurrentContext->variable[index].locked; + __nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL); + __nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1); + return __nlCurrentContext->variable[index].locked; } /************************************************************************************/ /* System construction */ static void __nlVariablesToVector() { - NLuint i; - __nl_assert(__nlCurrentContext->alloc_x); - __nl_assert(__nlCurrentContext->alloc_variable); - for(i=0; i<__nlCurrentContext->nb_variables; i++) { - __NLVariable* v = &(__nlCurrentContext->variable[i]); - if(!v->locked) { - __nl_assert(v->index < __nlCurrentContext->n); - __nlCurrentContext->x[v->index] = v->value; - } - } + NLuint i; + __nl_assert(__nlCurrentContext->alloc_x); + __nl_assert(__nlCurrentContext->alloc_variable); + for(i=0; i<__nlCurrentContext->nb_variables; i++) { + __NLVariable* v = &(__nlCurrentContext->variable[i]); + if(!v->locked) { + __nl_assert(v->index < __nlCurrentContext->n); + __nlCurrentContext->x[v->index] = v->value; + } + } } static void __nlVectorToVariables() { - NLuint i; - __nl_assert(__nlCurrentContext->alloc_x); - __nl_assert(__nlCurrentContext->alloc_variable); - for(i=0; i<__nlCurrentContext->nb_variables; i++) { - __NLVariable* v = &(__nlCurrentContext->variable[i]); - if(!v->locked) { - __nl_assert(v->index < __nlCurrentContext->n); - v->value = __nlCurrentContext->x[v->index]; - } - } + NLuint i; + __nl_assert(__nlCurrentContext->alloc_x); + __nl_assert(__nlCurrentContext->alloc_variable); + for(i=0; i<__nlCurrentContext->nb_variables; i++) { + __NLVariable* v = &(__nlCurrentContext->variable[i]); + if(!v->locked) { + __nl_assert(v->index < __nlCurrentContext->n); + v->value = __nlCurrentContext->x[v->index]; + } + } } - static void __nlBeginSystem() { - __nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM); - __nl_assert(__nlCurrentContext->nb_variables > 0); - __nlCurrentContext->variable = __NL_NEW_ARRAY( - __NLVariable, __nlCurrentContext->nb_variables - ); - __nlCurrentContext->alloc_variable = NL_TRUE; + __nl_assert(__nlCurrentContext->nb_variables > 0); + + if (__nlCurrentContext->solve_again) + __nlTransition(__NL_STATE_SYSTEM_SOLVED, __NL_STATE_SYSTEM); + else { + __nlTransition(__NL_STATE_INITIAL, __NL_STATE_SYSTEM); + + __nlCurrentContext->variable = __NL_NEW_ARRAY( + __NLVariable, __nlCurrentContext->nb_variables + ); + __nlCurrentContext->alloc_variable = NL_TRUE; + } } static void __nlEndSystem() { - __nlTransition(__NL_STATE_MATRIX_CONSTRUCTED, __NL_STATE_SYSTEM_CONSTRUCTED); + __nlTransition(__NL_STATE_MATRIX_CONSTRUCTED, __NL_STATE_SYSTEM_CONSTRUCTED); } static void __nlBeginMatrix() { - NLuint i; - NLuint n = 0; - NLenum storage = __NL_ROWS; + NLuint i; + NLuint n = 0; + NLenum storage = __NL_ROWS; - __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX); + __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX); - for(i=0; i<__nlCurrentContext->nb_variables; i++) { - if(!__nlCurrentContext->variable[i].locked) { - __nlCurrentContext->variable[i].index = n; - n++; - } else { - __nlCurrentContext->variable[i].index = ~0; - } - } + if (!__nlCurrentContext->solve_again) { + for(i=0; i<__nlCurrentContext->nb_variables; i++) { + if(!__nlCurrentContext->variable[i].locked) + __nlCurrentContext->variable[i].index = n++; + else + __nlCurrentContext->variable[i].index = ~0; + } - __nlCurrentContext->n = n; + __nlCurrentContext->n = n; - /* a least squares problem results in a symmetric matrix */ - if(__nlCurrentContext->least_squares) { - __nlCurrentContext->symmetric = NL_TRUE; - } + /* a least squares problem results in a symmetric matrix */ + if(__nlCurrentContext->least_squares) + __nlCurrentContext->symmetric = NL_TRUE; - if(__nlCurrentContext->symmetric) { - storage = (storage | __NL_SYMMETRIC); - } + if(__nlCurrentContext->symmetric) + storage = (storage | __NL_SYMMETRIC); - /* SuperLU storage does not support symmetric storage */ - storage = (storage & ~__NL_SYMMETRIC); + /* SuperLU storage does not support symmetric storage */ + storage = (storage & ~__NL_SYMMETRIC); - __nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage); - __nlCurrentContext->alloc_M = NL_TRUE; + __nlSparseMatrixConstruct(&__nlCurrentContext->M, n, n, storage); + __nlCurrentContext->alloc_M = NL_TRUE; - __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n); - __nlCurrentContext->alloc_x = NL_TRUE; - - __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n); - __nlCurrentContext->alloc_b = NL_TRUE; + __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n); + __nlCurrentContext->alloc_x = NL_TRUE; + + __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n); + __nlCurrentContext->alloc_b = NL_TRUE; + } + else { + /* need to recompute b only, A is not constructed anymore */ + __NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, __nlCurrentContext->n); + } - __nlVariablesToVector(); + __nlVariablesToVector(); - __nlRowColumnConstruct(&__nlCurrentContext->af); - __nlCurrentContext->alloc_af = NL_TRUE; - __nlRowColumnConstruct(&__nlCurrentContext->al); - __nlCurrentContext->alloc_al = NL_TRUE; - __nlRowColumnConstruct(&__nlCurrentContext->xl); - __nlCurrentContext->alloc_xl = NL_TRUE; + __nlRowColumnConstruct(&__nlCurrentContext->af); + __nlCurrentContext->alloc_af = NL_TRUE; + __nlRowColumnConstruct(&__nlCurrentContext->al); + __nlCurrentContext->alloc_al = NL_TRUE; - __nlCurrentContext->current_row = 0; + __nlCurrentContext->current_row = 0; } static void __nlEndMatrix() { - __nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED); - - __nlRowColumnDestroy(&__nlCurrentContext->af); - __nlCurrentContext->alloc_af = NL_FALSE; - __nlRowColumnDestroy(&__nlCurrentContext->al); - __nlCurrentContext->alloc_al = NL_FALSE; - __nlRowColumnDestroy(&__nlCurrentContext->xl); - __nlCurrentContext->alloc_al = NL_FALSE; - + __nlTransition(__NL_STATE_MATRIX, __NL_STATE_MATRIX_CONSTRUCTED); + + __nlRowColumnDestroy(&__nlCurrentContext->af); + __nlCurrentContext->alloc_af = NL_FALSE; + __nlRowColumnDestroy(&__nlCurrentContext->al); + __nlCurrentContext->alloc_al = NL_FALSE; + #if 0 - if(!__nlCurrentContext->least_squares) { - __nl_assert( - __nlCurrentContext->current_row == - __nlCurrentContext->n - ); - } + if(!__nlCurrentContext->least_squares) { + __nl_assert( + __nlCurrentContext->current_row == + __nlCurrentContext->n + ); + } #endif } static void __nlBeginRow() { - __nlTransition(__NL_STATE_MATRIX, __NL_STATE_ROW); - __nlRowColumnZero(&__nlCurrentContext->af); - __nlRowColumnZero(&__nlCurrentContext->al); - __nlRowColumnZero(&__nlCurrentContext->xl); -} - -static void __nlScaleRow(NLfloat s) { - __NLRowColumn* af = &__nlCurrentContext->af; - __NLRowColumn* al = &__nlCurrentContext->al; - NLuint nf = af->size; - NLuint nl = al->size; - NLuint i; - for(i=0; icoeff[i].value *= s; - } - for(i=0; icoeff[i].value *= s; - } - __nlCurrentContext->right_hand_side *= s; -} - -static void __nlNormalizeRow(NLfloat weight) { - __NLRowColumn* af = &__nlCurrentContext->af; - __NLRowColumn* al = &__nlCurrentContext->al; - NLuint nf = af->size; - NLuint nl = al->size; - NLuint i; - NLfloat norm = 0.0; - for(i=0; icoeff[i].value * af->coeff[i].value; - } - for(i=0; icoeff[i].value * al->coeff[i].value; - } - norm = sqrt(norm); - __nlScaleRow(weight / norm); + __nlTransition(__NL_STATE_MATRIX, __NL_STATE_ROW); + __nlRowColumnZero(&__nlCurrentContext->af); + __nlRowColumnZero(&__nlCurrentContext->al); } static void __nlEndRow() { - __NLRowColumn* af = &__nlCurrentContext->af; - __NLRowColumn* al = &__nlCurrentContext->al; - __NLRowColumn* xl = &__nlCurrentContext->xl; - __NLSparseMatrix* M = &__nlCurrentContext->M; - NLfloat* b = __nlCurrentContext->b; - NLuint nf = af->size; - NLuint nl = al->size; - NLuint current_row = __nlCurrentContext->current_row; - NLuint i; - NLuint j; - NLfloat S; - __nlTransition(__NL_STATE_ROW, __NL_STATE_MATRIX); + __NLRowColumn* af = &__nlCurrentContext->af; + __NLRowColumn* al = &__nlCurrentContext->al; + __NLSparseMatrix* M = &__nlCurrentContext->M; + NLfloat* b = __nlCurrentContext->b; + NLuint nf = af->size; + NLuint nl = al->size; + NLuint current_row = __nlCurrentContext->current_row; + NLuint i; + NLuint j; + NLfloat S; + __nlTransition(__NL_STATE_ROW, __NL_STATE_MATRIX); - if(__nlCurrentContext->normalize_rows) { - __nlNormalizeRow(__nlCurrentContext->row_scaling); - } else { - __nlScaleRow(__nlCurrentContext->row_scaling); - } + if(__nlCurrentContext->least_squares) { + if (!__nlCurrentContext->solve_again) { + for(i=0; icoeff[i].index, af->coeff[j].index, + af->coeff[i].value * af->coeff[j].value + ); + } + } + } - if(__nlCurrentContext->least_squares) { - for(i=0; icoeff[i].index, af->coeff[j].index, - af->coeff[i].value * af->coeff[j].value - ); - } - } - S = -__nlCurrentContext->right_hand_side; - for(j=0; jcoeff[j].value * xl->coeff[j].value; - } - for(i=0; icoeff[i].index ] -= af->coeff[i].value * S; - } - } else { - for(i=0; icoeff[i].index, af->coeff[i].value - ); - } - b[current_row] = -__nlCurrentContext->right_hand_side; - for(i=0; icoeff[i].value * xl->coeff[i].value; - } - } - __nlCurrentContext->current_row++; - __nlCurrentContext->right_hand_side = 0.0; - __nlCurrentContext->row_scaling = 1.0; + S = -__nlCurrentContext->right_hand_side; + for(j=0; jcoeff[j].value; + + for(i=0; icoeff[i].index ] -= af->coeff[i].value * S; + } else { + if (!__nlCurrentContext->solve_again) { + for(i=0; icoeff[i].index, af->coeff[i].value + ); + } + } + b[current_row] = -__nlCurrentContext->right_hand_side; + for(i=0; icoeff[i].value; + } + } + __nlCurrentContext->current_row++; + __nlCurrentContext->right_hand_side = 0.0; } void nlMatrixAdd(NLuint row, NLuint col, NLfloat value) { - __NLSparseMatrix* M = &__nlCurrentContext->M; - __nlCheckState(__NL_STATE_MATRIX); - __nl_range_assert(row, 0, __nlCurrentContext->n - 1); - __nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1); + __NLSparseMatrix* M = &__nlCurrentContext->M; + __nlCheckState(__NL_STATE_MATRIX); + __nl_range_assert(row, 0, __nlCurrentContext->n - 1); + __nl_range_assert(col, 0, __nlCurrentContext->nb_variables - 1); __nl_assert(!__nlCurrentContext->least_squares); __nlSparseMatrixAdd(M, row, col, value); @@ -952,226 +906,264 @@ void nlMatrixAdd(NLuint row, NLuint col, NLfloat value) void nlRightHandSideAdd(NLuint index, NLfloat value) { - NLfloat* b = __nlCurrentContext->b; + NLfloat* b = __nlCurrentContext->b; - __nlCheckState(__NL_STATE_MATRIX); - __nl_range_assert(index, 0, __nlCurrentContext->n - 1); + __nlCheckState(__NL_STATE_MATRIX); + __nl_range_assert(index, 0, __nlCurrentContext->n - 1); __nl_assert(!__nlCurrentContext->least_squares); b[index] += value; } void nlCoefficient(NLuint index, NLfloat value) { - __NLVariable* v; + __NLVariable* v; unsigned int zero= 0; - __nlCheckState(__NL_STATE_ROW); - __nl_range_assert(index, zero, __nlCurrentContext->nb_variables - 1); - v = &(__nlCurrentContext->variable[index]); - if(v->locked) { - __nlRowColumnAppend(&(__nlCurrentContext->al), 0, value); - __nlRowColumnAppend(&(__nlCurrentContext->xl), 0, v->value); - } else { - __nlRowColumnAppend(&(__nlCurrentContext->af), v->index, value); - } + __nlCheckState(__NL_STATE_ROW); + __nl_range_assert(index, zero, __nlCurrentContext->nb_variables - 1); + v = &(__nlCurrentContext->variable[index]); + if(v->locked) + __nlRowColumnAppend(&(__nlCurrentContext->al), 0, value*v->value); + else + __nlRowColumnAppend(&(__nlCurrentContext->af), v->index, value); } void nlBegin(NLenum prim) { - switch(prim) { - case NL_SYSTEM: { - __nlBeginSystem(); - } break; - case NL_MATRIX: { - __nlBeginMatrix(); - } break; - case NL_ROW: { - __nlBeginRow(); - } break; - default: { - __nl_assert_not_reached; - } - } + switch(prim) { + case NL_SYSTEM: { + __nlBeginSystem(); + } break; + case NL_MATRIX: { + __nlBeginMatrix(); + } break; + case NL_ROW: { + __nlBeginRow(); + } break; + default: { + __nl_assert_not_reached; + } + } } void nlEnd(NLenum prim) { - switch(prim) { - case NL_SYSTEM: { - __nlEndSystem(); - } break; - case NL_MATRIX: { - __nlEndMatrix(); - } break; - case NL_ROW: { - __nlEndRow(); - } break; - default: { - __nl_assert_not_reached; - } - } + switch(prim) { + case NL_SYSTEM: { + __nlEndSystem(); + } break; + case NL_MATRIX: { + __nlEndMatrix(); + } break; + case NL_ROW: { + __nlEndRow(); + } break; + default: { + __nl_assert_not_reached; + } + } } /************************************************************************/ /* SuperLU wrapper */ -/* Note: SuperLU is difficult to call, but it is worth it. */ +/* Note: SuperLU is difficult to call, but it is worth it. */ /* Here is a driver inspired by A. Sheffer's "cow flattener". */ -static NLboolean __nlSolve_SUPERLU( NLboolean do_perm) { +static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) { - /* OpenNL Context */ - __NLSparseMatrix* M = &(__nlCurrentContext->M); - NLfloat* b = __nlCurrentContext->b; - NLfloat* x = __nlCurrentContext->x; + /* OpenNL Context */ + __NLSparseMatrix* M = &(context->M); + NLuint n = context->n; + NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */ - /* Compressed Row Storage matrix representation */ - NLuint n = __nlCurrentContext->n; - NLuint nnz = __nlSparseMatrixNNZ(M); /* Number of Non-Zero coeffs */ - NLint* xa = __NL_NEW_ARRAY(NLint, n+1); - NLfloat* rhs = __NL_NEW_ARRAY(NLfloat, n); - NLfloat* a = __NL_NEW_ARRAY(NLfloat, nnz); - NLint* asub = __NL_NEW_ARRAY(NLint, nnz); + /* Compressed Row Storage matrix representation */ + NLint *xa = __NL_NEW_ARRAY(NLint, n+1); + NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n); + NLfloat *a = __NL_NEW_ARRAY(NLfloat, nnz); + NLint *asub = __NL_NEW_ARRAY(NLint, nnz); + NLint *etree = __NL_NEW_ARRAY(NLint, n); - /* Permutation vector */ - NLint* perm_r = __NL_NEW_ARRAY(NLint, n); - NLint* perm = __NL_NEW_ARRAY(NLint, n); + /* SuperLU variables */ + SuperMatrix At, AtP; + NLint info, panel_size, relax; + superlu_options_t options; - /* SuperLU variables */ - SuperMatrix A, B; /* System */ - SuperMatrix L, U; /* Inverse of A */ - NLint info; /* status code */ - DNformat *vals = NULL; /* access to result */ - float *rvals = NULL; /* access to result */ + /* Temporary variables */ + __NLRowColumn* Ri = NULL; + NLuint i, jj, count; + + __nl_assert(!(M->storage & __NL_SYMMETRIC)); + __nl_assert(M->storage & __NL_ROWS); + __nl_assert(M->m == M->n); + + /* Convert M to compressed column format */ + for(i=0, count=0; irow + i; + xa[i] = count; - /* SuperLU options and stats */ - superlu_options_t options; - SuperLUStat_t stat; + for(jj=0; jjsize; jj++, count++) { + a[count] = Ri->coeff[jj].value; + asub[count] = Ri->coeff[jj].index; + } + } + xa[n] = nnz; + /* Free M, don't need it anymore at this point */ + __nlSparseMatrixClear(M); - /* Temporary variables */ - __NLRowColumn* Ri = NULL; - NLuint i,jj,count; - - __nl_assert(!(M->storage & __NL_SYMMETRIC)); - __nl_assert(M->storage & __NL_ROWS); - __nl_assert(M->m == M->n); - - - /* - * Step 1: convert matrix M into SuperLU compressed column - * representation. - * ------------------------------------------------------- - */ + /* Create superlu A matrix transposed */ + sCreate_CompCol_Matrix( + &At, n, n, nnz, a, asub, xa, + SLU_NC, /* Colum wise, no supernode */ + SLU_S, /* floats */ + SLU_GE /* general storage */ + ); - count = 0; - for(i=0; irow[i]); - xa[i] = count; - for(jj=0; jjsize; jj++) { - a[count] = Ri->coeff[jj].value; - asub[count] = Ri->coeff[jj].index; - count++; - } - } - xa[n] = nnz; + /* Set superlu options */ + set_default_options(&options); + options.ColPerm = MY_PERMC; + options.Fact = DOFACT; - /* Save memory for SuperLU */ - __nlSparseMatrixClear(M); + StatInit(&(context->slu.stat)); + panel_size = sp_ienv(1); /* sp_ienv give us the defaults */ + relax = sp_ienv(2); - /* - * Rem: symmetric storage does not seem to work with - * SuperLU ... (->deactivated in main SLS::Solver driver) - */ - sCreate_CompCol_Matrix( - &A, n, n, nnz, a, asub, xa, - SLU_NR, /* Row_wise, no supernode */ - SLU_S, /* floats */ - SLU_GE /* general storage */ - ); + /* Compute permutation and permuted matrix */ + context->slu.perm_r = __NL_NEW_ARRAY(NLint, n); + context->slu.perm_c = __NL_NEW_ARRAY(NLint, n); - /* Step 2: create vector */ - sCreate_Dense_Matrix( - &B, n, 1, b, n, - SLU_DN, /* Fortran-type column-wise storage */ - SLU_S, /* floats */ - SLU_GE /* general */ - ); - + if ((permutation == NULL) || (*permutation == -1)) { + get_perm_c(3, &At, context->slu.perm_c); - /* Step 3: get permutation matrix - * ------------------------------ - * com_perm: 0 -> no re-ordering - * 1 -> re-ordering for A^t.A - * 2 -> re-ordering for A^t+A - * 3 -> approximate minimum degree ordering - */ - get_perm_c(do_perm ? 3 : 0, &A, perm); + if (permutation) + memcpy(permutation, context->slu.perm_c, sizeof(NLint)*n); + } + else + memcpy(context->slu.perm_c, permutation, sizeof(NLint)*n); - /* Step 4: call SuperLU main routine - * --------------------------------- - */ + sp_preorder(&options, &At, context->slu.perm_c, etree, &AtP); - set_default_options(&options); - options.ColPerm = MY_PERMC; - StatInit(&stat); + /* Decompose into L and U */ + sgstrf(&options, &AtP, relax, panel_size, + etree, NULL, 0, context->slu.perm_c, context->slu.perm_r, + &(context->slu.L), &(context->slu.U), &(context->slu.stat), &info); - sgssv(&options, &A, perm, perm_r, &L, &U, &B, &stat, &info); + /* Cleanup */ - /* Step 5: get the solution - * ------------------------ - * Fortran-type column-wise storage - */ - vals = (DNformat*)B.Store; - rvals = (float*)(vals->nzval); - if(info == 0) { - for(i = 0; i < n; i++){ - x[i] = rvals[i]; - } - } + Destroy_SuperMatrix_Store(&At); + Destroy_SuperMatrix_Store(&AtP); - /* Step 6: cleanup - * --------------- - */ + __NL_DELETE_ARRAY(etree); + __NL_DELETE_ARRAY(xa); + __NL_DELETE_ARRAY(rhs); + __NL_DELETE_ARRAY(a); + __NL_DELETE_ARRAY(asub); - /* - * For these two ones, only the "store" structure - * needs to be deallocated (the arrays have been allocated - * by us). - */ - Destroy_SuperMatrix_Store(&A); - Destroy_SuperMatrix_Store(&B); + context->slu.alloc_slu = NL_TRUE; - - /* - * These ones need to be fully deallocated (they have been - * allocated by SuperLU). - */ - Destroy_SuperNode_Matrix(&L); - Destroy_CompCol_Matrix(&U); - - StatFree(&stat); - - __NL_DELETE_ARRAY(xa); - __NL_DELETE_ARRAY(rhs); - __NL_DELETE_ARRAY(a); - __NL_DELETE_ARRAY(asub); - __NL_DELETE_ARRAY(perm_r); - __NL_DELETE_ARRAY(perm); - - return (info == 0); + return (info == 0); } +static NLboolean __nlInvert_SUPERLU(__NLContext *context) { + + /* OpenNL Context */ + NLfloat* b = context->b; + NLfloat* x = context->x; + NLuint n = context->n; + + /* SuperLU variables */ + SuperMatrix B; + NLint info; + + /* Create superlu array for B */ + sCreate_Dense_Matrix( + &B, n, 1, b, n, + SLU_DN, /* Fortran-type column-wise storage */ + SLU_S, /* floats */ + SLU_GE /* general */ + ); + + /* Forward/Back substitution to compute x */ + sgstrs(TRANS, &(context->slu.L), &(context->slu.U), + context->slu.perm_c, context->slu.perm_r, &B, + &(context->slu.stat), &info); + + if(info == 0) + memcpy(x, ((DNformat*)B.Store)->nzval, sizeof(*x)*n); + + Destroy_SuperMatrix_Store(&B); + + return (info == 0); +} + +static void __nlFree_SUPERLU(__NLContext *context) { + + Destroy_SuperNode_Matrix(&(context->slu.L)); + Destroy_CompCol_Matrix(&(context->slu.U)); + + StatFree(&(context->slu.stat)); + + __NL_DELETE_ARRAY(context->slu.perm_r); + __NL_DELETE_ARRAY(context->slu.perm_c); + + context->slu.alloc_slu = NL_FALSE; +} + +void nlPrintMatrix(void) { + __NLSparseMatrix* M = &(__nlCurrentContext->M); + float *b = __nlCurrentContext->b; + NLuint i, jj, k; + NLuint n = __nlCurrentContext->n; + __NLRowColumn* Ri = NULL; + float *value = malloc(sizeof(*value)*n); + + printf("A:\n"); + for(i=0; irow[i]); + + memset(value, 0.0, sizeof(*value)*n); + for(jj=0; jjsize; jj++) + value[Ri->coeff[jj].index] = Ri->coeff[jj].value; + + for (k = 0; ksolve_again) + result = __nlFactorize_SUPERLU(__nlCurrentContext, permutation); - return result; + if (result) { + result = __nlInvert_SUPERLU(__nlCurrentContext); + + if (result) { + __nlVectorToVariables(); + + if (solveAgain) + __nlCurrentContext->solve_again = NL_TRUE; + + __nlTransition(__NL_STATE_SYSTEM_CONSTRUCTED, __NL_STATE_SYSTEM_SOLVED); + } + } + + return result; +} + +NLboolean nlSolve() { + return nlSolveAdvanced(NULL, NL_FALSE); } diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp index c3f88b446b2..0586907d7c5 100644 --- a/intern/string/intern/STR_String.cpp +++ b/intern/string/intern/STR_String.cpp @@ -40,9 +40,12 @@ #include #include #include -#include #include "STR_String.h" +#ifdef HAVE_CONFIG_H +#include +#endif + /*------------------------------------------------------------------------------------------------- Construction / destruction -------------------------------------------------------------------------------------------------*/ @@ -540,10 +543,15 @@ STR_String& STR_String::Lower() STR_String& STR_String::Capitalize() { assertd(pData != NULL); +#ifdef WIN32 + if (Len>0) pData[0] = toupper(pData[0]); + if (Len>1) _strlwr(pData+1); +#else if (Len > 0) pData[0] = (pData[0] >= 'A' && pData[0] <= 'A')?pData[0]+'a'-'A':pData[0]; for (int i=1;i= 'a' && pData[i] <= 'z')?pData[i]+'A'-'a':pData[i]; +#endif return *this; } diff --git a/po/Makefile b/po/Makefile index cf151627dcd..f9980369818 100644 --- a/po/Makefile +++ b/po/Makefile @@ -36,7 +36,7 @@ SOURCEDIR = blender/po include nan_definitions.mk -LINGUAS = ca cs de es fr it ja nl pl pt_br sr sv uk +LINGUAS = ca cs de es fr it ja nl sv ifeq ($(OS), darwin) DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/$@/LC_MESSAGES/ else diff --git a/projectfiles/blender/BPY_python/BPY_python.dsp b/projectfiles/blender/BPY_python/BPY_python.dsp index d2b64cab934..22648fef088 100644 --- a/projectfiles/blender/BPY_python/BPY_python.dsp +++ b/projectfiles/blender/BPY_python/BPY_python.dsp @@ -40,6 +40,7 @@ RSC=rc.exe # PROP Output_Dir "..\..\..\obj\windows\blender\bpython" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\bpython" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # 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 "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\source\blender\misc" /I "..\..\..\lib\windows\guardedalloc\include" /I "..\..\source\blender\blenlib" /I "..\..\source\kernel\gen_messaging" /I "..\..\source\blender\include" /I "..\..\source\blender" /I "..\..\source\blender\makesdna" /I "..\..\source\blender\blenkernel" /I "..\..\source\blender\blenloader" /I "..\..\source\blender\bpython\include" /I "..\..\source\blender\imbuf" /I "..\..\source\blender\render\extern\include" /I "..\..\source\blender\radiosity\extern\include" /I "..\..\source\kernel\gen_system" /I "..\..\source\blender\renderconverter\\" /I "..\..\source\blender\renderui\\" /I "..\..\source\blender\python" /I "../../../../lib/windows/bsp/include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\bpython\include" /I "../../../source/gameengine\SoundSystem\\" /I "../../../../lib/windows/iksolver/include" /I "..\..\..\source\blender\python" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /J /FD /c @@ -64,6 +65,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\bpython\debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\bpython\debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /w /W0 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\img" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\source\blender\misc" /I "..\..\..\lib\windows\guardedalloc\include" /I "..\..\source\blender\blenlib" /I "..\..\source\kernel\gen_messaging" /I "..\..\source\blender\include" /I "..\..\source\blender" /I "..\..\source\blender\makesdna" /I "..\..\source\blender\blenkernel" /I "..\..\source\blender\blenloader" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\source\blender\bpython\include" /I "..\..\source\blender\imbuf" /I "..\..\source\blender\render\extern\include" /I "..\..\source\kernel\gen_system" /I "..\..\source\blender\renderconverter\\" /I "..\..\source\blender\renderui\\" /I "..\..\source\blender\python" /I "../../../../lib/windows/bsp/include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\bpython\include" /I "../../../source/gameengine\SoundSystem\\" /I "../../../../lib/windows/iksolver/include" /I "..\..\..\source\blender\python" /D "WIN32" /D "_MBCS" /D "_LIB" /U "_DEBUG" /YX /J /FD /GZ /c @@ -187,10 +189,6 @@ SOURCE=..\..\..\source\blender\python\api2_2x\Library.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\python\api2_2x\Pose.c -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\python\api2_2x\logic.c # End Source File # Begin Source File @@ -243,6 +241,10 @@ SOURCE=..\..\..\source\blender\python\api2_2x\point.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\python\api2_2x\Pose.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\python\api2_2x\quat.c # End Source File # Begin Source File diff --git a/projectfiles/blender/blender.dsw b/projectfiles/blender/blender.dsw index 4e8ae8775ce..8cfab4da860 100644 --- a/projectfiles/blender/blender.dsw +++ b/projectfiles/blender/blender.dsw @@ -660,18 +660,6 @@ Package=<4> Project_Dep_Name gen_messaging End Project Dependency Begin Project Dependency - Project_Dep_Name KX_blenderhook - End Project Dependency - Begin Project Dependency - Project_Dep_Name KX_converter - End Project Dependency - Begin Project Dependency - Project_Dep_Name KX_ketsji - End Project Dependency - Begin Project Dependency - Project_Dep_Name KX_network - End Project Dependency - Begin Project Dependency Project_Dep_Name NG_loopbacknetwork End Project Dependency Begin Project Dependency @@ -693,9 +681,6 @@ Package=<4> Project_Dep_Name SYS_system End Project Dependency Begin Project Dependency - Project_Dep_Name BRE_renderconverter - End Project Dependency - Begin Project Dependency Project_Dep_Name BL_src_pub End Project Dependency Begin Project Dependency diff --git a/projectfiles/blender/blenkernel/BKE_blenkernel.dsp b/projectfiles/blender/blenkernel/BKE_blenkernel.dsp index 262d6d835d5..e884117ce3e 100644 --- a/projectfiles/blender/blenkernel/BKE_blenkernel.dsp +++ b/projectfiles/blender/blenkernel/BKE_blenkernel.dsp @@ -42,6 +42,7 @@ RSC=rc.exe # PROP Output_Dir "..\..\..\obj\windows\blender\blenkernel" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenkernel" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # 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 "..\..\..\..\lib\windows\decimation\include" /I "../../../../lib/windows/zlib/include" /I "..\..\..\intern\elbeem\extern" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenlib" /I "../../../source/gameengine\SoundSystem\\" /I "../../../../lib/windows/iksolver/include" /I "../../../../lib/windows/bsp/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_FREETYPE2" /D "USE_CCGSUBSURFLIB" /YX /J /FD /c @@ -66,6 +67,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenkernel\debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenkernel\debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\decimation\include" /I "../../../../lib/windows/zlib/include" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenlib" /I "../../../source/gameengine\SoundSystem\\" /I "../../../../lib/windows/iksolver/include" /I "../../../../lib/windows/bsp/include" /I "..\..\..\intern\elbeem\extern" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_FREETYPE2" /YX /J /FD /GZ /c @@ -90,6 +92,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenkernel\mtdll_debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenkernel\mtdll_debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /Gm /GX /ZI /Od /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\gameengine\soundsystem" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\gameengine\soundsystem\snd_blenderwavecache" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /GZ /c # SUBTRACT BASE CPP /WX @@ -116,6 +119,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenkernel\mtdll" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenkernel\mtdll" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /GX /O2 /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\gameengine\soundsystem" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\gameengine\soundsystem\snd_blenderwavecache" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c # ADD CPP /nologo /MD /GX /O2 /I "..\..\..\source\gameengine\soundsystem" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\gameengine\soundsystem\snd_blenderwavecache" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenlib" /I "../../../source/gameengine\SoundSystem\\" /I "../../../../lib/windows/iksolver/include" /I "../../../../lib/windows/bsp/include" /I "..\..\..\intern\elbeem\extern" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c @@ -165,6 +169,10 @@ SOURCE=..\..\..\source\blender\blenkernel\intern\CCGSubSurf.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\blenkernel\intern\colortools.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\blenkernel\intern\constraint.c # End Source File # Begin Source File @@ -205,6 +213,10 @@ SOURCE=..\..\..\source\blender\blenkernel\intern\group.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\blenkernel\intern\icons.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\blenkernel\intern\image.c # End Source File # Begin Source File @@ -245,6 +257,18 @@ SOURCE=..\..\..\source\blender\blenkernel\intern\nla.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\blenkernel\intern\node.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\source\blender\blenkernel\intern\node_composit.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\source\blender\blenkernel\intern\node_shaders.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\blenkernel\intern\object.c # End Source File # Begin Source File diff --git a/projectfiles/blender/blenlib/BLI_blenlib.dsp b/projectfiles/blender/blenlib/BLI_blenlib.dsp index 59bbd3b37d4..8505d17eb7f 100644 --- a/projectfiles/blender/blenlib/BLI_blenlib.dsp +++ b/projectfiles/blender/blenlib/BLI_blenlib.dsp @@ -42,6 +42,7 @@ RSC=rc.exe # PROP Output_Dir "..\..\..\obj\windows\blender\blenlib" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenlib" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # 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 "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\..\lib\windows\freetype\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /I "../../../../lib/windows/zlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_FREETYPE2" /J /FD /c @@ -66,6 +67,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenlib\debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenlib\debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\..\lib\windows\freetype\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /I "../../../../lib/windows/zlib/include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_FREETYPE2" /J /FD /GZ /c @@ -90,6 +92,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenlib\mtdll_debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenlib\mtdll_debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /Gm /GX /ZI /Od /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /GZ /c # ADD CPP /nologo /MDd /Gm /GX /ZI /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /GZ /c @@ -114,6 +117,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\blenlib\mtdll" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\blenlib\mtdll" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /GX /O2 /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c # ADD CPP /nologo /MD /GX /O2 /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\makesdna" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c @@ -179,6 +183,10 @@ SOURCE=..\..\..\source\blender\blenlib\intern\gsqueue.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\blenlib\intern\jitter.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\blenlib\intern\matrixops.c # End Source File # Begin Source File diff --git a/projectfiles/blender/imbuf/BL_imbuf.dsp b/projectfiles/blender/imbuf/BL_imbuf.dsp index b6134b5d805..f152db2096e 100644 --- a/projectfiles/blender/imbuf/BL_imbuf.dsp +++ b/projectfiles/blender/imbuf/BL_imbuf.dsp @@ -70,7 +70,7 @@ LIB32=link.exe -lib MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\source\blender\imbuf\intern" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\include" /I "..\..\..\..\lib\windows\jpeg\include" /I "..\..\..\..\lib\windows\zlib\include" /I "..\..\..\..\lib\windows\png\include" /I "..\..\..\source\blender\makesdna" /I "..\..\..\..\lib\windows\tiff\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /FD /I /GZ "..\..\..\source\blender\imbuf" /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\source\blender\imbuf\intern" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\avi" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\include" /I "..\..\..\..\lib\windows\jpeg\include" /I "..\..\..\..\lib\windows\zlib\include" /I "..\..\..\..\lib\windows\png\include" /I "..\..\..\source\blender\makesdna" /I "..\..\..\..\lib\windows\tiff\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /FD /I /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe diff --git a/projectfiles/blender/radiosity/BRA_radiosity.dsp b/projectfiles/blender/radiosity/BRA_radiosity.dsp index 502bedb5229..be9e33e311f 100644 --- a/projectfiles/blender/radiosity/BRA_radiosity.dsp +++ b/projectfiles/blender/radiosity/BRA_radiosity.dsp @@ -41,8 +41,9 @@ RSC=rc.exe # PROP Intermediate_Dir "..\..\..\obj\windows\blender\radiosity" # PROP Target_Dir "" LINK32=link.exe -lib +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 "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\makesdna" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\render\intern\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -65,8 +66,9 @@ LIB32=link.exe -lib # PROP Intermediate_Dir "..\..\..\obj\windows\blender\radiosity\debug" # PROP Target_Dir "" LINK32=link.exe -lib +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 /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\makesdna" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\render\intern\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /GZ /c # SUBTRACT CPP /Fr # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" diff --git a/projectfiles/blender/render/BRE_render.dsp b/projectfiles/blender/render/BRE_render.dsp index 5530e8ee563..edec8a86291 100644 --- a/projectfiles/blender/render/BRE_render.dsp +++ b/projectfiles/blender/render/BRE_render.dsp @@ -40,6 +40,7 @@ RSC=rc.exe # PROP Output_Dir "..\..\..\obj\windows\blender\render" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\render" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # 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 "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\..\lib\windows\sdl\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\kernel\gen_messaging" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\kernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\intern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender" /I "..\..\..\source\blender\yafray" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /J /FD /c @@ -64,6 +65,7 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\render\debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\render\debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\..\lib\windows\sdl\include" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\kernel\gen_messaging" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\misc" /I "..\..\..\source\kernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\intern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender" /I "..\..\..\source\blender\yafray" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "WITH_QUICKTIME" /YX /J /FD /GZ /c @@ -87,6 +89,10 @@ LIB32=link.exe -lib # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=..\..\..\source\blender\render\intern\source\convertblender.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\render\intern\source\edgeRender.c # End Source File # Begin Source File @@ -95,10 +101,6 @@ SOURCE=..\..\..\source\blender\render\intern\source\envmap.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\source\errorHandler.c -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\source\gammaCorrectionTables.c # End Source File # Begin Source File @@ -111,7 +113,7 @@ SOURCE=..\..\..\source\blender\render\intern\source\initrender.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\source\jitter.c +SOURCE=..\..\..\source\blender\render\intern\source\pipeline.c # End Source File # Begin Source File @@ -127,10 +129,6 @@ SOURCE=..\..\..\source\blender\render\intern\source\ray.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\source\RE_callbacks.c -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\source\rendercore.c # End Source File # Begin Source File @@ -139,14 +137,6 @@ SOURCE=..\..\..\source\blender\render\intern\source\renderdatabase.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\source\renderHelp.c -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\source\renderPreAndPost.c -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\source\shadbuf.c # End Source File # Begin Source File @@ -155,20 +145,8 @@ SOURCE=..\..\..\source\blender\render\intern\source\texture.c # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\source\vanillaRenderPipe.c -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\source\zblur.c -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\source\zbuf.c # End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\source\zbufferdatastruct.c -# End Source File # End Group # Begin Group "Header Files" @@ -183,10 +161,6 @@ SOURCE=..\..\..\source\blender\render\intern\include\envmap.h # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\include\errorHandler.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\include\gammaCorrectionTables.h # End Source File # Begin Source File @@ -195,14 +169,6 @@ SOURCE=..\..\..\source\blender\render\intern\include\initrender.h # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\include\jitter.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\outerRenderLoop.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\include\pixelblending.h # End Source File # Begin Source File @@ -211,22 +177,10 @@ SOURCE=..\..\..\source\blender\render\intern\include\pixelshading.h # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\include\RE_callbacks.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\include\rendercore.h # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\include\renderHelp.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\renderPreAndPost.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\include\shadbuf.h # End Source File # Begin Source File @@ -235,28 +189,8 @@ SOURCE=..\..\..\source\blender\render\intern\include\texture.h # End Source File # Begin Source File -SOURCE=..\..\..\source\blender\render\intern\include\vanillaRenderPipe.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\vanillaRenderPipe_types.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\blender\render\intern\include\zbuf.h # End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\zbuf_types.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\zbufferdatastruct.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\blender\render\intern\include\zbufferdatastruct_types.h -# End Source File # End Group # End Target # End Project diff --git a/projectfiles/blender/src/BL_src.dsp b/projectfiles/blender/src/BL_src.dsp index 670b929f52d..1a004d4ec44 100644 --- a/projectfiles/blender/src/BL_src.dsp +++ b/projectfiles/blender/src/BL_src.dsp @@ -40,9 +40,10 @@ RSC=rc.exe # PROP Output_Dir "..\..\..\obj\windows\blender\src" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\src" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # 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 "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "GAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /FR /J /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "GAMEBLENDERx" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /FR /J /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -64,9 +65,10 @@ LIB32=link.exe -lib # PROP Output_Dir "..\..\..\obj\windows\blender\src\debug" # PROP Intermediate_Dir "..\..\..\obj\windows\blender\src\debug" # PROP Target_Dir "" +MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "GAMEBLENDER" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /U "_DEBUG" /J /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\..\lib\windows\sdl\include\\" /I "..\..\..\source\blender\img" /I "..\..\..\source\blender\renderui" /I "..\..\..\..\lib\windows\soundsystem\include\\" /I "..\..\..\..\lib\windows\python\include\python2.0\\" /I "..\..\..\..\lib\windows\bmfont\include" /I "..\..\..\source\blender\ftfont" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\blender\renderconverter" /I "..\..\..\source\blender\verify" /I "..\..\..\source\blender\readstreamglue" /I "..\..\..\source\gameengine\soundsystem\snd_openal" /I "..\..\..\source\blender\imbuf" /I "..\..\..\source\blender\blenloader" /I "..\..\..\source\blender\quicktime" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\blenlib" /I "..\..\..\source\blender\misc" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\radiosity\extern\include" /I "..\..\..\source\blender\render\extern\include" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\gameengine\network" /I "..\..\..\..\lib\windows\decimation\include" /I "..\..\..\source\blender\blenpluginapi\\" /I "..\..\..\..\lib\windows\blenkey\include" /I "..\..\..\..\lib\windows\ghost\include" /I "..\..\..\..\lib\windows\bsp\include" /I "..\..\..\..\lib\windows\opennl\include" /I "..\..\..\intern\elbeem\extern" /D "WIN32" /D "_MBCS" /D "_LIB" /D "_CONSOLE" /D "GAMEBLENDERx" /D "WITH_QUICKTIME" /D "INTERNATIONAL" /U "_DEBUG" /J /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -187,6 +189,10 @@ SOURCE=..\..\..\source\blender\src\drawnla.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\drawnode.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\drawobject.c # End Source File # Begin Source File @@ -319,6 +325,10 @@ SOURCE=..\..\..\source\blender\src\editnla.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\editnode.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\editobject.c # End Source File # Begin Source File @@ -403,6 +413,10 @@ SOURCE=..\..\..\source\blender\src\header_nla.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\header_node.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\header_oops.c # End Source File # Begin Source File @@ -451,6 +465,10 @@ SOURCE=..\..\..\source\blender\src\interface_draw.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\interface_icons.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\interface_panel.c # End Source File # Begin Source File @@ -487,6 +505,10 @@ SOURCE=..\..\..\source\blender\src\outliner.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\parametrizer.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\playanim.c # End Source File # Begin Source File @@ -499,6 +521,10 @@ SOURCE=..\..\..\source\blender\src\poseobject.c # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\preview.blend.c +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\src\previewrender.c # End Source File # Begin Source File @@ -955,6 +981,14 @@ SOURCE=..\..\..\source\blender\include\editmesh.h # End Source File # Begin Source File +SOURCE=..\..\..\source\blender\src\parametrizer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\source\blender\src\parametrizer_intern.h +# End Source File +# Begin Source File + SOURCE=..\..\..\source\blender\include\transform.h # End Source File # Begin Source File diff --git a/projectfiles/gameengine/ketsji/KX_ketsji.dsp b/projectfiles/gameengine/ketsji/KX_ketsji.dsp index ea57ffd95b9..c4496e7edde 100644 --- a/projectfiles/gameengine/ketsji/KX_ketsji.dsp +++ b/projectfiles/gameengine/ketsji/KX_ketsji.dsp @@ -45,7 +45,7 @@ RSC=rc.exe MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "..\..\..\source\gameengine\physics\common\dummy" /I "..\..\..\extern\solid" /I "..\..\..\..\lib\windows\string\include" /I "..\..\..\..\lib\windows\moto\include" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\..\lib\windows\soundsystem\include" /I "..\..\..\source\gameengine\rasterizer" /I "..\..\..\source\gameengine\scenegraph" /I "..\..\..\source\gameengine\gamelogic" /I "..\..\..\source\gameengine\expressions" /I "..\..\..\source\sumo\include" /I "..\..\..\source\sumo\fuzzics\include" /I "..\..\..\source\gameengine\network" /I "..\..\..\source\gameengine\Converter" /I "..\..\..\source\gameengine\ketsji\kxnetwork" /I "..\..\..\source\gameengine\physics" /I "..\..\..\source\gameengine\physics\common" /I "..\..\..\source\gameengine\physics\dummy" /I "..\..\..\source\gameengine\physics\sumo" /I "..\..\..\source\gameengine\physics\sumo\fuzzics\include" /I "..\..\..\source\gameengine\physics\sumo\include" /I "..\..\..\source\gameengine\physics\BlOde" /I "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\gameengine\physics\bullet" /I "..\..\..\extern\bullet\linearmath" /I "..\..\..\extern\bullet\Bulletdynamics" /I "..\..\..\extern\bullet\Bullet" /I "..\..\..\source\gameengine/Rasterizer/RAS_OpenGLRasterizer" /I "..\..\..\source\blender\blenlib" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "EXP_PYTHON_EMBEDDING" /D "USE_SUMO_SOLID" /YX /J /FD /c +# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "..\..\..\source\gameengine\physics\common\dummy" /I "..\..\..\extern\solid" /I "..\..\..\..\lib\windows\string\include" /I "..\..\..\..\lib\windows\moto\include" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\..\lib\windows\soundsystem\include" /I "..\..\..\source\gameengine\rasterizer" /I "..\..\..\source\gameengine\scenegraph" /I "..\..\..\source\gameengine\gamelogic" /I "..\..\..\source\gameengine\expressions" /I "..\..\..\source\sumo\include" /I "..\..\..\source\sumo\fuzzics\include" /I "..\..\..\source\gameengine\network" /I "..\..\..\source\gameengine\Converter" /I "..\..\..\source\gameengine\ketsji\kxnetwork" /I "..\..\..\source\gameengine\physics" /I "..\..\..\source\gameengine\physics\common" /I "..\..\..\source\gameengine\physics\dummy" /I "..\..\..\source\gameengine\physics\sumo" /I "..\..\..\source\gameengine\physics\sumo\fuzzics\include" /I "..\..\..\source\gameengine\physics\sumo\include" /I "..\..\..\source\gameengine\physics\BlOde" /I "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\gameengine\physics\bullet" /I "..\..\..\extern\bullet\linearmath" /I "..\..\..\extern\bullet\Bulletdynamics" /I "..\..\..\extern\bullet\Bullet" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "EXP_PYTHON_EMBEDDING" /D "USE_SUMO_SOLID" /YX /J /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -70,7 +70,7 @@ LIB32=link.exe -lib MTL=midl.exe LINK32=link.exe -lib # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\source\gameengine\physics\common\dummy" /I "..\..\..\extern\solid" /I "..\..\..\..\lib\windows\string\include" /I "..\..\..\..\lib\windows\moto\include" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\..\lib\windows\soundsystem\include" /I "..\..\..\source\gameengine\rasterizer" /I "..\..\..\source\gameengine\scenegraph" /I "..\..\..\source\gameengine\gamelogic" /I "..\..\..\source\gameengine\expressions" /I "..\..\..\source\sumo\include" /I "..\..\..\source\sumo\fuzzics\include" /I "..\..\..\source\gameengine\network" /I "..\..\..\source\gameengine\Converter" /I "..\..\..\source\gameengine\ketsji\kxnetwork" /I "..\..\..\source\gameengine\physics" /I "..\..\..\source\gameengine\physics\common" /I "..\..\..\source\gameengine\physics\dummy" /I "..\..\..\source\gameengine\physics\sumo" /I "..\..\..\source\gameengine\physics\sumo\fuzzics\include" /I "..\..\..\source\gameengine\physics\sumo\include" /I "..\..\..\source\gameengine\physics\BlOde" /I "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\gameengine\physics\bullet" /I "..\..\..\extern\bullet\linearmath" /I "..\..\..\extern\bullet\Bulletdynamics" /I "..\..\..\extern\bullet\Bullet" /I "..\..\..\source\gameengine/Rasterizer/RAS_OpenGLRasterizer" /I "..\..\..\source\blender\blenlib" /D "JANCODEPANCO" /D "WIN32" /D "_MBCS" /D "_LIB" /D "EXP_PYTHON_EMBEDDING" /D "USE_SUMO_SOLID" /U "_DEBUG" /YX /J /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /Zi /Od /I "..\..\..\source\gameengine\physics\common\dummy" /I "..\..\..\extern\solid" /I "..\..\..\..\lib\windows\string\include" /I "..\..\..\..\lib\windows\moto\include" /I "..\..\..\source\kernel\gen_system" /I "..\..\..\..\lib\windows\soundsystem\include" /I "..\..\..\source\gameengine\rasterizer" /I "..\..\..\source\gameengine\scenegraph" /I "..\..\..\source\gameengine\gamelogic" /I "..\..\..\source\gameengine\expressions" /I "..\..\..\source\sumo\include" /I "..\..\..\source\sumo\fuzzics\include" /I "..\..\..\source\gameengine\network" /I "..\..\..\source\gameengine\Converter" /I "..\..\..\source\gameengine\ketsji\kxnetwork" /I "..\..\..\source\gameengine\physics" /I "..\..\..\source\gameengine\physics\common" /I "..\..\..\source\gameengine\physics\dummy" /I "..\..\..\source\gameengine\physics\sumo" /I "..\..\..\source\gameengine\physics\sumo\fuzzics\include" /I "..\..\..\source\gameengine\physics\sumo\include" /I "..\..\..\source\gameengine\physics\BlOde" /I "..\..\..\..\lib\windows\python\include\python2.4" /I "..\..\..\source\blender\python" /I "..\..\..\source\blender\blenkernel" /I "..\..\..\source\blender\makesdna" /I "..\..\..\source\blender\include" /I "..\..\..\source\blender\imbuf" /I "..\..\..\..\lib\windows\guardedalloc\include" /I "..\..\..\source\gameengine\physics\bullet" /I "..\..\..\extern\bullet\linearmath" /I "..\..\..\extern\bullet\Bulletdynamics" /I "..\..\..\extern\bullet\Bullet" /D "JANCODEPANCO" /D "WIN32" /D "_MBCS" /D "_LIB" /D "EXP_PYTHON_EMBEDDING" /D "USE_SUMO_SOLID" /U "_DEBUG" /YX /J /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -267,22 +267,6 @@ SOURCE=..\..\..\source\gameengine\Ketsji\KX_ScalingInterpolator.cpp # End Group # Begin Source File -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Material.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Shader.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Texture.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\KX_BlenderMaterial.cpp -# End Source File -# Begin Source File - SOURCE=..\..\..\source\gameengine\Ketsji\KX_BulletPhysicsController.cpp # End Source File # Begin Source File @@ -319,10 +303,6 @@ SOURCE=..\..\..\source\gameengine\Ketsji\KX_Light.cpp # End Source File # Begin Source File -SOURCE=..\..\..\source\gameengine\Ketsji\KX_MaterialIpoController.cpp -# End Source File -# Begin Source File - SOURCE=..\..\..\source\gameengine\Ketsji\KX_MeshProxy.cpp # End Source File # Begin Source File @@ -535,22 +515,6 @@ SOURCE=..\..\..\source\gameengine\Ketsji\KX_ScalingInterpolator.h # End Group # Begin Source File -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Material.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Shader.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\BL_Texture.h -# End Source File -# Begin Source File - -SOURCE=..\..\..\source\gameengine\Ketsji\KX_BlenderMaterial.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\gameengine\Ketsji\KX_BulletPhysicsController.h # End Source File # Begin Source File @@ -599,10 +563,6 @@ SOURCE=..\..\..\source\gameengine\Ketsji\KX_Light.h # End Source File # Begin Source File -SOURCE=..\..\..\source\gameengine\Ketsji\KX_MaterialIpoController.h -# End Source File -# Begin Source File - SOURCE=..\..\..\source\gameengine\Ketsji\KX_MeshProxy.h # End Source File # Begin Source File diff --git a/projectfiles_vc7/blender/BPY_python/BPY_python.vcproj b/projectfiles_vc7/blender/BPY_python/BPY_python.vcproj index 4a8dbce56d6..4f7a5ec6271 100644 --- a/projectfiles_vc7/blender/BPY_python/BPY_python.vcproj +++ b/projectfiles_vc7/blender/BPY_python/BPY_python.vcproj @@ -190,9 +190,6 @@ - - @@ -360,9 +357,6 @@ - - diff --git a/projectfiles_vc7/blender/blender.sln b/projectfiles_vc7/blender/blender.sln index 2522bc2c805..f7a327a9fc3 100644 --- a/projectfiles_vc7/blender/blender.sln +++ b/projectfiles_vc7/blender/blender.sln @@ -117,6 +117,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GP_axctl", "..\gameengine\g {09222F5E-1625-4FF3-A89A-384D16875EE5} = {09222F5E-1625-4FF3-A89A-384D16875EE5} {E013786A-9575-4F34-81B2-33290357EE87} = {E013786A-9575-4F34-81B2-33290357EE87} {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292} + {EC405272-28E3-4840-AAC2-53D6DE4E163D} = {EC405272-28E3-4840-AAC2-53D6DE4E163D} {6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC} {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} {F90BD995-FFA4-4B18-81E8-FA4322C939E8} = {F90BD995-FFA4-4B18-81E8-FA4322C939E8} @@ -151,6 +152,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GP_ghost", "..\gameengine\g {09222F5E-1625-4FF3-A89A-384D16875EE5} = {09222F5E-1625-4FF3-A89A-384D16875EE5} {E013786A-9575-4F34-81B2-33290357EE87} = {E013786A-9575-4F34-81B2-33290357EE87} {415BFD6E-64CF-422B-AF88-C07F040A7292} = {415BFD6E-64CF-422B-AF88-C07F040A7292} + {EC405272-28E3-4840-AAC2-53D6DE4E163D} = {EC405272-28E3-4840-AAC2-53D6DE4E163D} {6B801390-5F95-4F07-81A7-97FBA046AACC} = {6B801390-5F95-4F07-81A7-97FBA046AACC} {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} = {CAE37E91-6570-43AC-A4B4-7A37A4B0FC94} {F90BD995-FFA4-4B18-81E8-FA4322C939E8} = {F90BD995-FFA4-4B18-81E8-FA4322C939E8} @@ -193,6 +195,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PHY_Dummy", "..\GAMEENGINE\ ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PHY_Ode", "..\gameengine\physics\PHY_Physics\PHY_Ode\PHY_Ode.vcproj", "{EC405272-28E3-4840-AAC2-53D6DE4E163D}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PHY_Physics", "..\gameengine\physics\PHY_Physics\PHY_Physics.vcproj", "{E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}" ProjectSection(ProjectDependencies) = postProject EndProjectSection @@ -523,6 +529,16 @@ Global {3648FB9A-C36F-43AB-AED0-1F1361E67FC7}.BlenderPlayer Debug.Build.0 = BlenderPlayer Debug|Win32 {3648FB9A-C36F-43AB-AED0-1F1361E67FC7}.BlenderPlayer Release.ActiveCfg = BlenderPlayer Release|Win32 {3648FB9A-C36F-43AB-AED0-1F1361E67FC7}.BlenderPlayer Release.Build.0 = BlenderPlayer Release|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.3D Plugin Release.Build.0 = 3D Plugin Release|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.Blender Debug.ActiveCfg = BlenderPlayer Debug|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.Blender Release.ActiveCfg = BlenderPlayer Release|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.BlenderPlayer Debug.ActiveCfg = BlenderPlayer Debug|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.BlenderPlayer Debug.Build.0 = BlenderPlayer Debug|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.BlenderPlayer Release.ActiveCfg = BlenderPlayer Release|Win32 + {EC405272-28E3-4840-AAC2-53D6DE4E163D}.BlenderPlayer Release.Build.0 = BlenderPlayer Release|Win32 {E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}.3D Plugin Debug.ActiveCfg = 3D Plugin Debug|Win32 {E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}.3D Plugin Debug.Build.0 = 3D Plugin Debug|Win32 {E109F1A5-FDD3-4F56-A1C4-96867EEA4C5B}.3D Plugin Release.ActiveCfg = 3D Plugin Release|Win32 diff --git a/projectfiles_vc7/blender/blender.vcproj b/projectfiles_vc7/blender/blender.vcproj index e8a8580bb59..7da591109f5 100644 --- a/projectfiles_vc7/blender/blender.vcproj +++ b/projectfiles_vc7/blender/blender.vcproj @@ -63,7 +63,6 @@ ECHO Copying required 3rd party dlls... XCOPY /Y ..\..\..\lib\windows\python\lib\python24.dll ..\..\bin XCOPY /Y ..\..\..\lib\windows\gettext\lib\*.dll ..\..\bin XCOPY /Y ..\..\..\lib\windows\sdl\lib\*.dll ..\..\bin -XCOPY /Y ..\..\..\lib\windows\tiff\lib\libtiff.dll ..\..\bin ECHO Copying language folder ECHO Done "/> @@ -141,7 +140,6 @@ XCOPY /Y ..\..\..\lib\windows\gettext\lib\*.dll ..\..\bin\debug XCOPY /Y ..\..\..\lib\windows\sdl\lib\*.dll ..\..\bin\debug XCOPY /Y ..\..\..\lib\windows\python\lib\python24_d.dll ..\..\bin\debug XCOPY /Y ..\..\..\lib\windows\CRTL\lib\msvcrtd.dll ..\..\bin\debug -XCOPY /Y ..\..\..\lib\windows\tiff\lib\libtiff.dll ..\..\bin\debug ECHO Copying language folder IF NOT EXIST ..\..\bin\debug\.blender MKDIR ..\..\bin\debug\.blender XCOPY /Y ..\..\bin\.blender ..\..\bin\debug\.blender /E diff --git a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj index 2ce865373dc..c608b3044ea 100644 --- a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj +++ b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj @@ -21,7 +21,7 @@ - - @@ -414,9 +411,6 @@ - - @@ -427,9 +421,6 @@ - - @@ -487,9 +478,6 @@ - - diff --git a/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj b/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj index 546be9d5991..ed4caf5c095 100644 --- a/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj +++ b/projectfiles_vc7/blender/makesdna/DNA_makesdna.vcproj @@ -488,9 +488,6 @@ DNA_makesdna.exe dna.c - - diff --git a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj index 9cf9b018a6f..2cbf21a5efe 100644 --- a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj +++ b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj @@ -21,7 +21,7 @@ - - - - - - - - @@ -371,15 +359,15 @@ - - + + @@ -529,18 +517,6 @@ - - - - - - - - @@ -577,9 +553,6 @@ - - diff --git a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj index 7b965fa771c..082f502f5c0 100644 --- a/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj +++ b/projectfiles_vc7/gameengine/physics/PHY_Physics/PHY_Bullet/PHY_Bullet.vcproj @@ -19,7 +19,7 @@ - - - - diff --git a/release/Makefile b/release/Makefile index 8a2bb114275..31a7f04dbb0 100644 --- a/release/Makefile +++ b/release/Makefile @@ -55,7 +55,14 @@ all: ifeq ($(CPU),alpha) @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \ COMPRESS="gzip -f --best" EXT2=".gz" - else + endif + ifeq ($(CPU),i386) + @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \ + COMPRESS="gzip -f --best" EXT2=".gz" + @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \ + COMPRESS="gzip -f --best" EXT2=".gz" + endif + ifeq ($(CPU),powerpc) @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \ COMPRESS="gzip -f --best" EXT2=".gz" @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \ @@ -89,7 +96,6 @@ install: package @#echo "****> Install text" @cp text/blender.html $(DISTDIR) @cp text/*.txt $(DISTDIR) - @cp text/*.pdf $(DISTDIR) @echo "----> Make Config dir .blender" @mkdir -p $(CONFDIR) @# possible overruling .txt text documents diff --git a/release/VERSION b/release/VERSION index d920eceb604..eeab995e801 100644 --- a/release/VERSION +++ b/release/VERSION @@ -1 +1 @@ -2.41 +2.40-alpha1 diff --git a/release/datafiles/blenderbuttons b/release/datafiles/blenderbuttons index e34f3d8fecc..4946acd4b78 100644 Binary files a/release/datafiles/blenderbuttons and b/release/datafiles/blenderbuttons differ diff --git a/release/scripts/Apply_def.py b/release/scripts/Apply_def.py index f0e3c029b50..bdcae3744ec 100644 --- a/release/scripts/Apply_def.py +++ b/release/scripts/Apply_def.py @@ -54,55 +54,49 @@ directly manipulate or export its data. # # ***** END GPL LICENCE BLOCK ***** - import Blender Blender.Window.EditMode(0) -NAME_LENGTH = 19 -PREFIX = "_def" -PREFIX_LENGTH = len(PREFIX) - ob_list = Blender.Object.GetSelected() - -for ob in ob_list: - ob.sel = 0 - -used_names = [ob.name for ob in Blender.Object.Get()] -used_names.extend(Blender.NMesh.GetNames()) - -deformedList = [] for ob in ob_list: if ob.getType() == "Mesh": name = ob.getName() - new_name = "%s_def" % name[:NAME_LENGTH-PREFIX_LENGTH] + new_name = name + "_deformed" num = 0 new_mesh = Blender.NMesh.GetRawFromObject(name) - while new_name in used_names: - new_name = "%s_def.%.3i" % (name[:NAME_LENGTH-(PREFIX_LENGTH+PREFIX_LENGTH)], num) + mesh = Blender.NMesh.GetRaw(new_name) + while mesh: num += 1 - - used_names.append(new_name) - + new_name = name + "_deformed." + "%03i" % num + mesh = Blender.NMesh.GetRaw(new_name) new_ob = Blender.NMesh.PutRaw(new_mesh, new_name) new_ob.setMatrix(ob.getMatrix()) + try: + new_ob = Blender.Object.Get(new_name) + while 1: + num += 1 + new_name = name + "_deformed." + "%03i" % num + new_ob = Blender.Object.Get(new_name) + except: + pass new_ob.setName(new_name) - deformedList.append(new_ob) - - # Vert groups. + ob_mesh = ob.getData() new_ob_mesh = new_ob.getData() - - for vgroupname in ob_mesh.getVertGroupNames(): - new_ob_mesh.addVertGroup(vgroupname) - if len(ob_mesh.verts) == len(new_ob_mesh.verts): - vlist = ob_mesh.getVertsFromGroup(vgroupname, True) - try: - for vpair in vlist: - new_ob_mesh.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], 'add') - except: - pass -for ob in deformedList: - ob.sel = 1 -deformedList[0].sel = 1 # Keep the same object active. \ No newline at end of file + # If SubSurf is off on the original, copy the vertex weight + if not ob_mesh.getMode() & Blender.NMesh.Modes['SUBSURF']: + for vgroupname in ob_mesh.getVertGroupNames(): + vlist = ob_mesh.getVertsFromGroup(vgroupname, True) + new_ob_mesh.addVertGroup(vgroupname) + for vpair in vlist: + new_ob_mesh.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], 'add') + # If it's on, just add the vertex groups + else: + for vgroupname in ob_mesh.getVertGroupNames(): + new_ob_mesh.addVertGroup(vgroupname) + + new_ob_mesh.update() + +Blender.Window.EditMode(1) diff --git a/release/scripts/Axiscopy.py b/release/scripts/Axiscopy.py index a6fa2e8b627..0a9a411ef08 100644 --- a/release/scripts/Axiscopy.py +++ b/release/scripts/Axiscopy.py @@ -2,7 +2,7 @@ """ Registration info for Blender menus: <- these words are ignored Name: 'Axis Orientation Copy' -Blender: 239 +Blender: 233 Group: 'Object' Tip: 'Copy the axis orientation of the active object to all selected mesh objects' """ @@ -10,7 +10,7 @@ Tip: 'Copy the axis orientation of the active object to all selected mesh object __author__ = "A Vanpoucke (xand)" __url__ = ("blender", "elysiun", "French Blender support forum, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "2 17/12/05" +__version__ = "1.1 11/05/04" __bpydoc__ = """\ This script copies the axis orientation -- X, Y and Z rotations -- of the @@ -75,7 +75,7 @@ from Blender.Mathutils import * def applyTransform(mesh,mat): for v in mesh.verts: - vec = v.co*mat + vec = VecMultMat(v.co,mat) v.co[0], v.co[1], v.co[2] = vec[0], vec[1], vec[2] @@ -87,13 +87,13 @@ lenob=len(oblist) error = 0 for o in oblist[1:]: if o.getType() != "Mesh": - Draw.PupMenu("Error: selected objects must be meshes") + Draw.PupMenu("ERROR%t|Selected objects must be meshes") error = 1 if not error: if lenob<2: - Draw.PupMenu("Error: you must select at least 2 objects") - else : + Draw.PupMenu("ERROR%t|You must select at least 2 objects") + else : source=oblist[0] nsource=source.name texte="Copy axis orientation from: " + nsource + " ?%t|OK" @@ -102,9 +102,9 @@ if not error: for cible in oblist[1:]: if source.rot!=cible.rot: - rotcible=cible.mat.rotationPart().toEuler().toMatrix() - rotsource=source.mat.rotationPart().toEuler().toMatrix() - rotsourcet = Matrix(rotsource) + rotcible=cible.mat.toEuler().toMatrix() + rotsource=source.mat.toEuler().toMatrix() + rotsourcet = CopyMat(rotsource) rotsourcet.invert() mat=rotcible*rotsourcet ncible=cible.name diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py index 0bb436ac86a..bfe6ccbdc88 100644 --- a/release/scripts/DirectX8Exporter.py +++ b/release/scripts/DirectX8Exporter.py @@ -1,16 +1,17 @@ #!BPY """ Registration info for Blender menus: -Name: 'DirectX(.x)...' -Blender: 240 +Name: 'DirectX8(.x)...' +Blender: 239 Group: 'Export' Submenu: 'Export all the scene' export Submenu: 'Export selected obj' exportsel -Tip: 'Export to DirectX text file format format.' +Tip: 'Export to DirectX8 text file format format.' """ + __author__ = "Arben (Ben) Omari" __url__ = ("blender", "elysiun", "Author's site, http://www.omariben.too.it") -__version__ = "2.0" +__version__ = "1.0" __bpydoc__ = """\ This script exports a Blender mesh with armature to DirectX 8's text file @@ -20,8 +21,8 @@ Notes:
Check author's site or the elYsiun forum for a new beta version of the DX exporter. """ -# DirectXExporter.py version 2.0 -# Copyright (C) 2006 Arben OMARI -- omariarben@everyday.com +# DirectX8Exporter.py version 1.0 +# Copyright (C) 2003 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 @@ -41,17 +42,10 @@ DX exporter. import Blender from Blender import Types, Object, NMesh, Material,Armature from Blender.Mathutils import * -import math -global mat_flip,index_list,space,bone_list,mat_dict -bone_list =[] +global new_bon,mat_flip,index_list index_list = [] -mat_dict = {} -space = 0 -ANIM = 1 -NORMAL = 1 -TEXCOORDS = 1 -TEXTURE = 1 +new_bon = {} mat_flip = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]) @@ -70,7 +64,6 @@ class xExport: #Select Scene objects #*********************************************** def SelectObjs(self): - global chld_obj print "exporting..." self.writeHeader() for obj in Object.Get(): @@ -161,117 +154,115 @@ class xExport: #Export Root Bone #*********************************************** def writeRootBone(self,am_ob,child_obj): - global mat_flip,space,root_bon,mat_ob - arms = am_ob.getData() - self.writeArmFrames(mat_flip, "RootFrame") - for bon in arms.bones.values(): - if bon.hasParent(): - pass - else: - root_bon = bon - space += 1 - mat_rb = self.writeCombineMatrix(root_bon) - mat_r = mat_rb #* am_ob.matrixLocal - name_r = root_bon.name - name_f = name_r.replace(".","") - self.writeArmFrames(mat_r, name_f) - bon_c = self.findChildrens(root_bon) - self.writeChildren(bon_c) - self.file.write(" }\n") - self.exportMeshArm(arms,am_ob,child_obj) + global new_bon,mat_flip + space = 0 + arm = am_ob.getData() + Blender.Set('curframe',1) + mat_ob = mat_flip * am_ob.matrixWorld + self.writeArmFrames(mat_ob, "RootFrame", 0) + root_bon = arm.getBones() + mat_r = self.writeCombineMatrix(root_bon[0]) + name_r = root_bon[0].getName() + new_bon[name_r] = len(root_bon[0].getChildren()) + self.writeArmFrames(mat_r, name_r, 1) + self.writeListOfChildrens(root_bon[0],2,arm) + self.file.write("}\n") + self.exportMeshArm(arm,am_ob,child_obj) + + #*********************************************** + #Export Children Bones + #*********************************************** + def writeListOfChildrens(self,bon,space,arm): + global new_bon + bon_c = bon.getChildren() + Blender.Set('curframe',1) + for n in range(len(bon_c)): + name_h = bon_c[n].getName() + chi_h = bon_c[n].getChildren() + new_bon[name_h] = len(chi_h) + + if bon_c == [] : + self.CloseBrackets(bon, new_bon, space, arm.getBones()[0]) + + for nch in range(len(bon_c)): + mat = self.writeCombineMatrix(bon_c[nch]) + name_ch = bon_c[nch].getName() + self.writeArmFrames(mat, name_ch,space) + self.findChildrens(bon_c[nch],space,arm) + #*********************************************** #Create Children structure #*********************************************** - def writeBon(self,bon): - global space - mat_r = self.writeCombineMatrix(bon) - name_r = bon.name - name_f = name_r.replace(".","") - self.writeArmFrames(mat_r, name_f) - - - def findChildrens(self,bon): - bon_c = bon.children - return bon_c - - - 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 + def CloseBrackets(self, bon, new_bon, space, root_bon): tab = " " - self.file.write("%s" % (tab * space)) + self.file.write("%s" % (tab * (space -1))) self.file.write("}\n") - + while bon.hasParent(): + if new_bon[bon.getName()] == 0: + pare = bon.getParent() + name_p = pare.getName() + if new_bon[name_p] > 0: + new_bon[name_p] = new_bon[name_p] - 1 + if new_bon[name_p] == 0 and pare != root_bon: + self.file.write("%s" % (tab * (space-2))) + self.file.write("}\n") + space = space - 1 + bon = pare + else: + break + #*********************************************** + #Create Children structure + #*********************************************** + def findChildrens(self,bon_c,space,arm): + bon_cc = bon_c + space += 1 + self.writeListOfChildrens(bon_cc,space,arm) + + #*********************************************** #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_b.invert() + Blender.Set('curframe',1) + mat_b = bon.getRestMatrix() + mat_b.invert() return mat_b + + #*********************************************** #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 + Blender.Set('curframe',1) + mat_b = bon.getRestMatrix() if bon.hasParent(): - pare = bon.parent - pos_p = pose.bones[pare.name] - mat_p = pos_p.poseMatrix - - else: + pare = bon.getParent() + mat_p = pare.getRestMatrix() + else : mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) mat_p.invert() - mat_f = mat_b * mat_p - - return mat_f + mat_rb = mat_b * mat_p + return mat_rb + #*********************************************** #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 + def writeCombineAnimMatrix(self,bon): + + mat_b = bon.getRestMatrix() if bon.hasParent(): - pare = bon.parent - pos_p = pose.bones[pare.name] - mat_p = pos_p.poseMatrix - - else: + pare = bon.getParent() + mat_p = pare.getRestMatrix() + else : mat_p = Matrix([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]) mat_p.invert() - mat_f = mat_b * mat_p - - return mat_f + mat_rb = mat_b * mat_p + return mat_rb #********************************************************************************************************************************************* @@ -280,23 +271,16 @@ class xExport: #*********************************************** def writeSkinWeights(self, arm, mesh): global index_list - v_dict = {} + Blender.Set('curframe',1) self.file.write(" XSkinMeshHeader {\n") max_infl = 0 - #this part supply the missing getVertexInfluences(index) - for v in index_list: - v_dict[v] = [] - for bo in arm.bones.values() : - name = bo.name - + for bo in arm.getBones() : + name = bo.getName() try : vertx_list = mesh.getVertsFromGroup(name,1) - for vn in vertx_list: - v_dict[vn[0]].append(name) - #--------------------------------------------------- for inde in vertx_list : - vert_infl = v_dict[inde[0]] + vert_infl = mesh.getVertexInfluences(inde[0]) ln_infl = len(vert_infl) if ln_infl > max_infl : max_infl = ln_infl @@ -304,21 +288,20 @@ class xExport: 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(" %s; \n" % (max_infl)) + self.file.write(" %s; \n" % (max_infl * 3)) + self.file.write(" %s; \n" % (len(arm.getBones()))) self.file.write(" }\n") - for bo in arm.bones.values() : + for bo in arm.getBones() : bo_list = [] weight_list = [] - name = bo.name - f_name = name.replace(".","") + name = bo.getName() try : vert_list = mesh.getVertsFromGroup(name,1) le = 0 for indx in vert_list: - ver_infl = v_dict[indx[0]] + ver_infl = mesh.getVertexInfluences(indx[0]) len_infl = float(len(ver_infl)) infl = 1 / len_infl i = -1 @@ -331,27 +314,28 @@ class xExport: self.file.write(" SkinWeights {\n") - self.file.write(' "%s"; \n' % (f_name)) - self.file.write(' %d; \n' % (le)) + self.file.write(' "%s"; \n' % (name)) + self.file.write(' %s; \n' % (le)) count = 0 for ind in bo_list : count += 1 if count == len(bo_list): - self.file.write(" %d; \n" % (ind)) + self.file.write(" %s; \n" % (ind)) else : - self.file.write(" %d, \n" % (ind)) + self.file.write(" %s, \n" % (ind)) cou = 0 for wegh in weight_list : cou += 1 if cou == len(weight_list): - self.file.write(" %f; \n" % (round(wegh,6))) + self.file.write(" %s; \n" % (round(wegh,6))) else : - self.file.write(" %f, \n" % (round(wegh,6))) + self.file.write(" %s, \n" % (round(wegh,6))) matx = self.writeMatrixOffset(bo) - self.writeOffsFrames(matx, name) + + self.writeOffsFrames(matx, name, 1) except : pass self.file.write(" }\n") @@ -360,8 +344,7 @@ class xExport: #*********************************************** # Write Matrices #*********************************************** - def writeArmFrames(self, matx, name): - global space + def writeArmFrames(self, matx, name, space): tab = " " self.file.write("%s" % (tab * space)) self.file.write("Frame ") @@ -369,16 +352,16 @@ class xExport: self.file.write("%s" % (tab * space)) self.file.write(" FrameTransformMatrix {\n") self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f,\n" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s;;\n" % (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6))) self.file.write("%s" % (tab * space)) self.file.write(" }\n") @@ -386,20 +369,19 @@ class xExport: #*********************************************** # Write Matrices #*********************************************** - def writeOffsFrames(self, matx, name): - space = 1 + def writeOffsFrames(self, matx, name, space): tab = " " self.file.write("%s" % (tab * space)) - self.file.write(" %f,%f,%f,%f,\n" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s,\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" % + self.file.write(" %s,%s,%s,%s;;\n" % (round(matx[3][0],4),round(matx[3][1],4),round(matx[3][2],4),round(matx[3][3],6))) self.file.write("%s" % (tab * space)) self.file.write(" }\n") @@ -463,8 +445,7 @@ template SkinWeights {\n\ mat_ob.invert() mat = mat_arm * mat_ob mat.invert() - name_f = name.name.replace(".","") - self.writeArmFrames(mat, name_f) + self.writeArmFrames(mat, name.name, 1) mesh = NMesh.GetRawFromObject(name.name) self.file.write("Mesh {\n") numface=len(mesh.faces) @@ -480,8 +461,8 @@ template SkinWeights {\n\ 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]) - f_vec_vert = vec_vert * mat - self.file.write("%f; %f; %f;" % (round(f_vec_vert[0],4), round(f_vec_vert[1],4), round(f_vec_vert[2],4))) + f_vec_vert = VecMultMat(vec_vert, mat) + self.file.write("%s; %s; %s;" % (f_vec_vert[0], f_vec_vert[1], f_vec_vert[2])) if counter == numface : if n == len(face.v)-1 : self.file.write(";\n") @@ -524,8 +505,7 @@ template SkinWeights {\n\ global index_list #ROTATION mat_ob = mat_flip * name.matrixWorld - name_f = name.name.replace(".","") - self.writeArmFrames(mat_ob, name_f) + self.writeArmFrames(mat_ob, name.name, 0) self.file.write("Mesh {\n") numface=len(mesh.faces) @@ -609,9 +589,10 @@ template SkinWeights {\n\ ##MATERIAL NAME for mat in Material.Get(): self.file.write(" Material") - name_m = mat.name - name_f = name_m.replace(".","") - self.file.write(" %s "% (name_f)) + for a in range(0,len(mat.name)): + if mat.name[a] == ".": + print "WARNING:the material " + mat.name + " contains '.' within.Many viewers may refuse to read the exported file" + self.file.write(" %s "% (mat.name)) self.file.write("{\n") self.file.write(" %s; %s; %s;" % (mat.R, mat.G, mat.B)) self.file.write("%s;;\n" % (mat.alpha)) @@ -628,7 +609,7 @@ template SkinWeights {\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(" TextureFilename {\n") self.file.write(' "%s" ;'% (mat)) self.file.write(" }\n") self.file.write(" }\n") @@ -730,45 +711,47 @@ template SkinWeights {\n\ - - + #*********************************************** #WRITE ANIMATION KEYS #*********************************************** def writeAnimation(self,arm_ob): - global mat_dict arm = arm_ob.getData() act_list = arm_ob.getAction() ip = act_list.getAllChannelIpos() - for bon in arm.bones.values() : + for bon in arm.getBones() : point_list = [] - name = bon.name - name_f = name.replace(".", "") 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) - + point_list.pop(0) + + self.file.write(" Animation { \n") - self.file.write(" {%s}\n" %(name_f)) + self.file.write(" {%s}\n" %(bon.getName())) self.file.write(" AnimationKey { \n") self.file.write(" 4;\n") - self.file.write(" %s; \n" % (len(point_list))) + self.file.write(" %s; \n" % (len(point_list)+1)) + + self.file.write(" %s;" % (1)) + self.file.write("16;") + mat = self.writeCombineMatrix(bon) + self.writeFrames(mat) + self.file.write(",\n") for fr in point_list: - mat = self.writeAnimCombineMatrix(bon,fr) - self.file.write(" %s;" % (fr)) self.file.write("16;") + Blender.Set('curframe',fr) - self.writeFrames(mat) + mat_new = self.writeCombineAnimMatrix(bon) + self.writeFrames(mat_new) if fr == point_list[len(point_list)-1]: self.file.write(";\n") @@ -881,8 +864,8 @@ arg = __script__['arg'] if arg == 'exportsel': fname = Blender.sys.makename(ext = ".x") - Blender.Window.FileSelector(my_callback_sel, "Export DirectX", fname) + Blender.Window.FileSelector(my_callback_sel, "Export DirectX8", fname) else: fname = Blender.sys.makename(ext = ".x") - Blender.Window.FileSelector(my_callback, "Export DirectX", fname) - \ No newline at end of file + Blender.Window.FileSelector(my_callback, "Export DirectX8", fname) + diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py index ea9ba239003..b9b7b8e5ae6 100644 --- a/release/scripts/ac3d_export.py +++ b/release/scripts/ac3d_export.py @@ -202,8 +202,7 @@ def transform_verts(verts, m): vecs = [] for v in verts: vec = Mathutils.Vector([v[0],v[1],v[2], 1]) - #vecs.append(Mathutils.VecMultMat(vec, m)) - vecs.append(vec*m) + vecs.append(Mathutils.VecMultMat(vec, m)) return vecs # --- diff --git a/release/scripts/ac3d_import.py b/release/scripts/ac3d_import.py index 4dcde65fb4a..d2505022adf 100644 --- a/release/scripts/ac3d_import.py +++ b/release/scripts/ac3d_import.py @@ -10,7 +10,7 @@ Tip: 'Import an AC3D (.ac) file.' __author__ = "Willian P. Germano" __url__ = ("blender", "elysiun", "AC3D's homepage, http://www.ac3d.org", "PLib 3d gaming lib, http://plib.sf.net") -__version__ = "2.36a 2005-12-04" +__version__ = "2.36 2005-04-14" __bpydoc__ = """\ This script imports AC3D models into Blender. @@ -43,9 +43,9 @@ users can configure (see config options above). # $Id$ # # -------------------------------------------------------------------------- -# AC3DImport version 2.36a Dec 04, 2005 +# AC3DImport version 2.36 Apr 14, 2005 # Program versions: Blender 2.36+ and AC3Db files (means version 0xb) -# changed: fixed a bug: error on 1 vertex "closed" polylines +# changed: updated to use the Scripts Config Editor facilities # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -366,7 +366,7 @@ class AC3DImport: faces.append(cut) face = face[1:] - if flaglow == 1 and faces: + if flaglow == 1: face = [faces[-1][-1], faces[0][0]] faces.append(face) @@ -498,9 +498,7 @@ class AC3DImport: for vi in range(len(f)): bface.v.append(mesh.verts[f[vi][0]]) bface.uv.append((f[vi][1][0], f[vi][1][1])) - #mesh.faces.append(bface) - # quick hack, will switch from NMesh to Mesh later: - if len(bface.v) > 1: mesh.addFace(bface) + mesh.faces.append(bface) mesh.mode = 0 object = Blender.NMesh.PutRaw(mesh) diff --git a/release/scripts/batch_name_edit.py b/release/scripts/batch_name_edit.py new file mode 100644 index 00000000000..75d2294aa68 --- /dev/null +++ b/release/scripts/batch_name_edit.py @@ -0,0 +1,131 @@ +#!BPY + +""" +Name: 'Batch Object Name Edit' +Blender: 232 +Group: 'Object' +Tooltip: 'Apply the chosen rule to rename all selected objects at once.' +""" + +__author__ = "Campbell Barton" +__url__ = ("blender", "elysiun") +__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 * + +def main(): + def new(): + newname = Draw.PupStrInput('Name: ', '', 32) + if newname == None: return + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = newname + + def replace(): + replace = Draw.PupStrInput('Replace: ', '', 32) + if replace == None: return + with = Draw.PupStrInput('With: ', '', 32) + if with == None: return + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = ob.name.replace(replace, with) + + # Use pythons replace, its better. + ''' + if replace in ob.name: + chIdx = ob.name.index(replace) + + # Remove the offending word and replace it with - 'with' + ob.name = ob.name[ :chIdx] + with + ob.name[chIdx + len(replace):] + ''' + + + def prefix(): + prefix = Draw.PupStrInput('prefix: ', '', 32) + + if prefix == None: return + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = prefix + ob.name + + + def suffix(): + suffix = Draw.PupStrInput('Suffix: ', '', 32) + if suffix == None: return + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = ob.name + suffix + + def truncate_start(): + truncate = Draw.PupIntInput('Truncate Start: ', 0, 0, 31) + if truncate != None: + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = ob.name[truncate: ] + + def truncate_end(): + truncate = Draw.PupIntInput('Truncate End: ', 0, 0, 31) + if truncate == None: return + Window.WaitCursor(1) + for ob in Object.GetSelected(): + ob.name = ob.name[ :-truncate] + + + name = "Selected Object Names%t|New Name|Replace Text|Add Prefix|Add Suffix|Truncate Start|Truncate End" + result = Draw.PupMenu(name) + + if result == -1: + pass + elif result == 1: + new() + elif result == 2: + replace() + elif result == 3: + prefix() + elif result == 4: + suffix() + elif result == 5: + truncate_start() + elif result == 6: + truncate_end() + + Window.WaitCursor(0) + +main() diff --git a/release/scripts/bevel_center.py b/release/scripts/bevel_center.py index 1e3fb3c78d7..6025cef7f0e 100644 --- a/release/scripts/bevel_center.py +++ b/release/scripts/bevel_center.py @@ -2,21 +2,21 @@ """ Registration info for Blender menus Name: 'Bevel Center' -Blender: 240 +Blender: 236 Group: 'Mesh' -Tip: 'Bevel selected faces, edges, and vertices' +Tip: 'Bevel selected vertices' """ -__author__ = "Loic BERTHE" +__author__ = "Loic Berthe" __url__ = ("blender", "elysiun") -__version__ = "2.0" +__version__ = "1.0" __bpydoc__ = """\ -This script implements vertex and edges bevelling in Blender. +This script implements vertex bevelling in Blender. Usage: -Select the mesh you want to work on, enter Edit Mode and select the edges +Select the mesh you want to work on, enter Edit Mode and select the vertices 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 @@ -24,295 +24,358 @@ 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. +recursiveness and use the "Recursive" button. Notes:
- You can undo and redo your steps just like with normal mesh operations in + You can undo and redo your steps just like with normal mesh operations in Blender. """ +# $Id$ +# ###################################################################### -# Bevel Center v2.0 for Blender - -# This script lets you bevel the selected vertices or edges and control the +# Bevel Center v1 for Blender +# +# This script lets you bevel the selected vertices and control the # thickness of the bevel - -# (c) 2004-2006 Loïc Berthe (loic+blender@lilotux.net) +# +# (c) 2004 Loïc Berthe (loic.berthe@lilotux.net) # released under Blender Artistic License - +# ###################################################################### import Blender -from Blender import NMesh, Window, Scene +from Blender import NMesh, Window from Blender.Draw import * -from Blender.Mathutils import * from Blender.BGL import * +from math import pi, sin, sqrt + ###################################################################### -# Functions to handle the global structures of the script NF, NE and NC -# which contain informations about faces and corners to be created +# Functions to handle the global structures of the script NV, NE and NC +# which contain informations about the vertices, faces and corners to be +# created -global E_selected -E_selected = NMesh.EdgeFlags['SELECT'] +class Dir: + def __init__(self, co): + self.co = co -def make_sel_vert(*co): - vi= NMesh.Vert(*co) - v.sel = 1 +def add_to_NV(old,co,new): + dir = Dir(co) + # + if old in NV.keys(): + NV[old][dir] = new + else: + NV[old] = {dir:new} + +def is_in_NV(old,co): + if old in NV.keys(): + for dir in NV[old]: + if dir.co == co : return NV[old][dir] + # + return False + +def add_to_NE(old, new): + ind1 = old[0].index + ind2 = old[1].index + if ind1 > ind2: + new.reverse() + ind1,ind2 = ind2,ind1 + id = str(ind1)+"_"+str(ind2) + if id in NE.keys(): + [NE[id].append(v) for v in new] + else: + NE[id] = new + +def add_to_NC(old,edge): + if old in NC.keys(): + NC[old].append(edge) + else: + NC[old] = [edge] + +###################################################################### +# Geometric functions + +def norm(vec): + n = sqrt(vec[0]**2+vec[1]**2+vec[2]**2) + return [vec[0]/n,vec[1]/n,vec[2]/n] + +def parall_coord(old, dir): + co = old.co + vec = [0.0,0.0,0.0] + nco = [0.0,0.0,0.0] + # + if len(dir) == 1: + for i in range(3): vec[i] = dir[0].co[i] - co[i] + vec = norm(vec) + # + elif len(dir) == 2: + vec1 = [0.0,0.0,0.0] + vec2 = [0.0,0.0,0.0] + for i in range(3): + vec1[i] = dir[0].co[i] - co[i] + vec2[i] = dir[1].co[i] - co[i] + vec1 = norm(vec1) + vec2 = norm(vec2) + for i in range(3) : vec[i] = vec1[i]+vec2[i] + # + for i in range(3): nco[i] = co[i] + dist.val*vec[i] + return (nco,vec) + +def get_vert(old, dir): + """ Look in NV if a vertice corresponding to the vertex old and the + direction dir already exists, and create one otherwise""" + (nco, vec) = parall_coord(old, dir) + v = is_in_NV(old,vec) + if v: return v + # + v = NMesh.Vert(nco[0],nco[1],nco[2]) + v.sel = 1 me.verts.append(v) + add_to_NV(old,vec,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): - if old in NV.keys(): NV[old][dir] = new - else: 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() - 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] + +###################################################################### +# Functions to create the differents faces - # 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 +def make_NF(): + """ Analyse the mesh, sort the faces containing selected vertices and + create a liste NF : NF = [[flag, vertlist, old_face]]. Flag describes the + topology of the face.""" + # 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 + v_sel = [x.sel for x in V] + nb_sel = sum(v_sel) + if nb_sel == 0 : + pass + else: + nb_v = len(V) + # + if nb_v == 4: + # + if nb_sel == 4: + NF.append([1,V,f]) + # + elif nb_sel == 3: + if v_sel == [0,1,1,1]: V = [V[1],V[2],V[3],V[0]] + elif v_sel == [1,0,1,1]: V = [V[2],V[3],V[0],V[1]] + elif v_sel == [1,1,0,1]: V = [V[3],V[0],V[1],V[2]] + NF.append([2,V,f]) + # + elif nb_sel == 2: + if v_sel == [1,0,1,0] or v_sel == [0,1,0,1]: + if v_sel == [0,1,0,1]: V = [V[1],V[2],V[3],V[0]] + NF.append([5,[V[0],V[1],V[3]],f]) + NF.append([5,[V[2],V[1],V[3]]]) + else: + if v_sel == [0,1,1,0]: V = [V[1],V[2],V[3],V[0]] + elif v_sel == [0,0,1,1]: V = [V[2],V[3],V[0],V[1]] + elif v_sel == [1,0,0,1]: V = [V[3],V[0],V[1],V[2]] + NF.append([3,V,f]) + # + else: + if v_sel == [0,1,0,0]: V = [V[1],V[2],V[3],V[0]] + elif v_sel == [0,0,1,0]: V = [V[2],V[3],V[0],V[1]] + elif v_sel == [0,0,0,1]: V = [V[3],V[0],V[1],V[2]] + NF.append([4,V,f]) + # + elif nb_v == 3: + # + if nb_sel == 3: + NF.append([6,V,f]) + # + elif nb_sel == 2: + if v_sel == [0,1,1]: V = [V[1],V[2],V[0]] + elif v_sel == [1,0,1]: V = [V[2],V[0],V[1]] + NF.append([7,V,f]) + # + else: + if v_sel == [0,1,0]: V = [V[1],V[2],V[0]] + elif v_sel == [0,0,1]: V = [V[2],V[0],V[1]] + NF.append([5,V,f]) - 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_faces(): + """ Make the new faces according to NF """ + # + for N in NF: + cas = N[0] + V = N[1] + # + if cas < 6: + new_v = [0,0,0,0] + if cas == 1: # v_sel = [1,1,1,1] + for i in range(-1,3): + new_v[i] = get_vert(V[i],[V[i-1],V[i+1]]) + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + for i in range(-1,3): + add_to_NE([V[i],V[i+1]],[new_v[i],new_v[i+1]]) + # + elif cas == 2: # v_sel = [1,1,1,0] + new_v[0] = get_vert(V[0],[V[3]]) + new_v[1] = get_vert(V[1],[V[0],V[2]]) + new_v[2] = get_vert(V[2],[V[3]]) + new_v[3] = V[3] + # + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + # + add_to_NE([V[0],V[1]],[new_v[0],new_v[1]]) + add_to_NE([V[1],V[2]],[new_v[1],new_v[2]]) + # + elif cas == 3: # v_sel = [1,1,0,0] + new_v[0] = get_vert(V[0],[V[3]]) + new_v[1] = get_vert(V[1],[V[2]]) + new_v[2] = V[2] + new_v[3] = V[3] + # + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + # + add_to_NE([V[0],V[1]],[new_v[0],new_v[1]]) + # + elif cas == 4: # v_sel = [1,0,0,0] + new_v[0] = get_vert(V[0],[V[3]]) + new_v[1] = get_vert(V[0],[V[1]]) + new_v[2] = V[1] + new_v[3] = V[3] + # + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + # + add_to_NC(V[0], new_v[0:2]) + # + new_v[0] = V[1] + new_v[1] = V[2] + new_v[2] = V[3] + # + new_f = NMesh.Face(new_v[:3]) + me.faces.append(new_f) + # + else: # v_sel = [1,0,0] + new_v[0] = get_vert(V[0],[V[2]]) + new_v[1] = get_vert(V[0],[V[1]]) + new_v[2] = V[1] + new_v[3] = V[2] + # + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + # + add_to_NC(V[0], new_v[0:2]) + # + else: + new_v = [0,0,0] + # + if cas == 6: # v_sel = [1,1,1] + for i in range(-1,2): + new_v[i] = get_vert(V[i],[V[i-1],V[i+1]]) + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + for i in range(-1,2): + add_to_NE([V[i],V[i+1]],[new_v[i],new_v[i+1]]) + # + elif cas == 7: # v_sel = [1,1,0] + new_v[0] = get_vert(V[0],[V[2]]) + new_v[1] = get_vert(V[1],[V[2]]) + new_v[2] = V[2] + # + new_f = NMesh.Face(new_v) + me.faces.append(new_f) + add_to_NE([V[0],V[1]],[new_v[0],new_v[1]]) 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 - - for v in oldv : NV_ext.add(v) - - else: - make_sel_face(new[0] + new[1][::-1]) - - me.findEdge(*new[0]).flag |= E_selected - me.findEdge(*new[1]).flag |= E_selected + # + for l in NE.values(): + if len(l) == 4: + f = NMesh.Face([l[0],l[1],l[3],l[2]]) + me.faces.append(f) def make_corners(): - """ Make the faces corresponding to corners """ - + """ Make the faces corresponding to selected corners """ + # for v in NV.keys(): V = NV[v].values() - nV = len(V) - - if nV == 1: pass - - elif nV == 2 : - if v in NV_ext: - make_sel_face(V+[v]) - me.findEdge(*V).flag |= E_selected - + nb_v = len(V) + # + if nb_v < 3: + pass + # + elif nb_v == 3: + new_f = NMesh.Face(V) + me.faces.append(new_f) + # else: - if nV == 3 and v not in NV_ext : 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 range(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.keys(): 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 range(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 range(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 + # We need to know which are the edges around the corner. + # First, we look for the quads surrounding the corner. + q = [NE[id] for id in NE.keys() if str(v.index) in id.split('_')] + # + # We will put the associated edges in the list eed + is_in_v = lambda x:x in V + eed = [filter(is_in_v, l) for l in q] + # + # We will add the edges coming from faces where only one vertice is selected. + # They are stocked in NC. + if v in NC.keys(): + eed = eed+NC[v] + b = eed.pop() + # b will contain the sorted list of vertices + # + while eed: + for l in eed: + if l[0] == b[-1]: + b.append(l[1]) + eed.remove(l) + break + elif l[1] == b[-1]: + b.append(l[0]) + eed.remove(l) + break + # Now we can create the faces + if nb_v == 4: + new_f = NMesh.Face(b[:4]) + me.faces.append(new_f) + # + else: + co = [0.0, 0.0,0.0] + vec = [0.0, 0.0,0.0] + for x in V: + co[0] += x[0] + co[1] += x[1] + co[2] += x[2] + # + for dir in NV[v]: + vec[0] += dir.co[0] + vec[1] += dir.co[1] + vec[2] += dir.co[2] + # + co = [x/nb_v for x in co] + vec = [x/nb_v for x in vec] + center = NMesh.Vert(co[0],co[1],co[2]) + center.sel = 1 + me.verts.append(center) + add_to_NV(v,vec,center) + # + for k in range(nb_v): + new_f = NMesh.Face([center, b[k], b[k+1]]) + me.faces.append(new_f) + # def clear_old(): """ Erase old faces and vertices """ - - for f in old_faces: me.removeFace(f) - + for F in NF: + if len(F) == 3: + me.faces.remove(F[2]) + # for v in NV.keys(): - if v not in NV_ext : me.verts.remove(v) - - for e in me.edges: - if e.flag & E_selected : - e.v1.sel = 1 - e.v2.sel = 1 - + me.verts.remove(v) ###################################################################### # Interface - +# global dist - +NV = {} dist = Create(0.2) left = Create(0.0) right = Create(1.0) @@ -330,79 +393,83 @@ def draw(): global EVENT_NOEVENT, EVENT_BEVEL, EVENT_UPDATE, EVENT_RECURS, EVENT_EXIT glClear(GL_COLOR_BUFFER_BIT) - Button("Bevel",EVENT_BEVEL,10,100,280,25) - left=Number('', EVENT_NOEVENT,10,70,45, 20,left.val,0,right.val,'Set the minimum of the slider') - right = Number("",EVENT_NOEVENT,245,70,45,20,right.val,left.val,200,"Set the maximum 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") - glRasterPos2d(8,40) + Button("Bevel",EVENT_BEVEL,10,100,300,25) + left=Number('', EVENT_NOEVENT,10,70,50, 20,left.val,0,right.val,'Set the minimum of the slider') + right = Number("",EVENT_NOEVENT,260,70,50,20,right.val,left.val,200,"Set the maximum of the slider") + dist=Slider("Thickness ",EVENT_UPDATE,65,70,190,20,dist.val,left.val,right.val,0,"Thickness of the bevel, can be changed even after bevelling") + glRasterPos2d(10,40) Text('To finish, you can use recursive bevel to smooth it') - 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) + num=Number('', EVENT_NOEVENT,10,10,50, 16,num.val,1,100,'Recursion level') + Button("Recursive",EVENT_RECURS,65,10,100,16) + Button("Exit",EVENT_EXIT,230,10,80,20) def event(evt, val): - if ((evt == QKEY or evt == ESCKEY) and not val): Exit() + 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() + 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 - - scn = Scene.GetCurrent() - ob = scn.getActiveObject() - if ob == None or ob.getType() != 'Mesh': - Draw.PupMenu('ERROR%t|Select a mesh object.') - return - - Window.WaitCursor(1) # Change the Cursor - - is_editmode = Window.EditMode() + global me,NF,NV,NE,NC, old_dist + # + is_editmode = Window.EditMode() if is_editmode: Window.EditMode(0) - - me = ob.getData() - + objects = Blender.Object.GetSelected() + bev_obj = objects[0] + if bev_obj.getType() != "Mesh": + PupMenu("ERROR: active object must be a mesh") + return + me = NMesh.GetRaw(bev_obj.getData(name_only = True)) + # + NF = [] NV = {} - NV_ext = set() NE = {} NC = {} - old_faces = [] - + # + make_NF() make_faces() make_edges() make_corners() clear_old() - + # old_dist = dist.val - + # 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 + global dist, old_dist, NV + if not NV: 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.keys(): for dir in NV[old_v].keys(): for i in range(3): - NV[old_v][dir].co[i] += fac*dir[i] - + NV[old_v][dir].co[i] += fac*dir.co[i] + # me.update(1) if is_editmode: Window.EditMode(1) Blender.Redraw() @@ -410,23 +477,24 @@ def bevel_update(): 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 range(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() + +# vim:set ts=4 sw=4: diff --git a/release/scripts/bpymodules/meshtools.py b/release/scripts/bpymodules/meshtools.py index bf875abf43c..4ddf6035e59 100644 --- a/release/scripts/bpymodules/meshtools.py +++ b/release/scripts/bpymodules/meshtools.py @@ -5,28 +5,12 @@ # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | September 28, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | # +---------------------------------------------------------+ # | 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 @@ -51,16 +35,7 @@ def append_faces(mesh, faces, facesuv, uvcoords): for i in range(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 + if numfaceverts <= 4: # This face is a triangle or quad face = Blender.NMesh.Face() for j in range(numfaceverts): index = faces[i][j] diff --git a/release/scripts/bpymodules/svg2obj.py b/release/scripts/bpymodules/svg2obj.py index 2ee133a00ee..98c6a489b0c 100644 --- a/release/scripts/bpymodules/svg2obj.py +++ b/release/scripts/bpymodules/svg2obj.py @@ -1,41 +1,8 @@ -# -*- coding: latin-1 -*- """ -SVG 2 OBJ translater, 0.4.7 -Copyright (c) jm soler juillet/novembre 2004-janvier 2006, -# --------------------------------------------------------------- - released under GNU Licence - for the Blender 2.40 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 -# --------------------------------------------------------------- - +SVG 2 OBJ translater, 0.3.3 +(c) jm soler juillet/novembre 2004-juin 2005, +# released under Blender Artistic Licence + for the Blender 2.37/36/35/34/33 Python Scripts Bundle. #--------------------------------------------------------------------------- # Page officielle : # http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm @@ -73,14 +40,10 @@ Yet done: 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 : courbe_vers_a, V : ligne_tracee_v, @@ -121,70 +84,19 @@ Changelog: 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 filtre_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.3.3 : - controle du contenu des transformation de type matrix + 0.3.4 : - restructuration de la lecture des donnes paths (19/06/05) ================================================================================== ==================================================================================""" SHARP_IMPORT=0 SCALE=1 -scale_=1 -DEBUG = 0#print +scale=1 +DEBUG =0 #print DEVELOPPEMENT=0 import sys -from math import cos,sin,tan, atan2, pi, ceil -PI=pi +from math import cos,sin,tan import Blender from Blender import Mathutils BLversion=Blender.Get('version') @@ -227,69 +139,27 @@ os.split=split os.join=join def filtreFICHIER(nom): - """ - Function filtreFICHIER - - in : string nom , filename - out : string t , if correct filecontaint - - 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().find('.SVGZ')!=-1: - 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 - # ---------- + f=open(nom,'rU') + t=f.read() + f.close() - # ----------------- - # pre-format ... - # ----------------- - # -------------------- - # 0.4.4 '\r','' --> '\r',' ' - # '\n','' --> '\n',' ' - #-------------------- - t=t.replace('\r',' ') - t=t.replace('\n',' ') - t=t.replace('svg:','') + t=t.replace('\r','') + t=t.replace('\n','') if t.upper().find('=233: Blender.Load(dir+nom+'OOO.obj', 1) BO=Blender.Object.Get() @@ -365,7 +231,7 @@ def Open_GEOfile(dir,nom): BO[-1].RotZ=3.1416 BO[-1].RotX=3.1416/2.0 - if scale_==1: + if scale==1: BO[-1].LocY+=BOUNDINGBOX['rec'][3] else: BO[-1].LocY+=BOUNDINGBOX['rec'][3]/SCALE @@ -376,14 +242,14 @@ def Open_GEOfile(dir,nom): print "Not yet implemented" def create_GEOtext(courbes): - global SCALE, B, BOUNDINGBOX,scale_ - + global SCALE, B, BOUNDINGBOX,scale r=BOUNDINGBOX['rec'] - if scale_==1: + + if scale==1: SCALE=1.0 - elif scale_==2: + elif scale==2: SCALE=r[2]-r[0] - elif scale_==3: + elif scale==3: SCALE=r[3]-r[1] t=[] @@ -418,535 +284,211 @@ def save_GEOfile(dir,nom,t): f.writelines(t) f.close() -#-------------------- -# 0.4.5 : for blender cvs 2.38 .... -#-------------------- -def createCURVES(courbes): - global SCALE, B, BOUNDINGBOX,scale_ - from Blender import Curve, Object, Scene, BezTriple - 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] - - [o.select(0) for o in Object.Get()] - for I in courbes.ITEM: - c = Curve.New() - # ---------- - # 0.4.7 - # ---------- - c.setResolu(24) - scene = Scene.getCurrent() - ob = Object.New('Curve') - ob.link(c) - scene.link(ob) - ob.select(1) - bzn=0 - #for b in courbes.ITEM[I].beziers_knot: - for k2 in range(0,len(courbes.ITEM[I].beziers_knot)): - bz=ajustement(courbes.ITEM[I].beziers_knot[k2], SCALE) - #bz=k1 - if bzn==0: - cp1 = bz[4],bz[5],0.0 , bz[0],bz[1],0.0, bz[2],bz[3],0.0, - beztriple1 = BezTriple.New(cp1) - bez = c.appendNurb(beztriple1) - - bzn = 1 - else: - cp2 = bz[4],bz[5],0.0 , bz[0],bz[1],0.0, bz[2],bz[3],0.0 - beztriple2 = BezTriple.New(cp2) - bez.append(beztriple2) - - if courbes.ITEM[I].flagUV[0]==1 : - #-------------------- - # 0.4.6 : cyclic flag ... - #-------------------- - bez.flagU += 1 - +def filtre_DATA(c,D,n): + global DEBUG,TAGcourbe + #print 'c',c,'D',D,'n',n + l=[] + if len(c[0])==1 and D[c[1]+1].find(',')!=-1: + for n2 in range(1,n+1): + ld=D[c[1]+n2].split(',') + for l_ in ld: + l.append(l_) + + elif len(c[0])==1 and D[c[1]+2][0] not in TAGcourbe: + for n2 in range(1,n*2+1): + l.append(D[c[1]+n2]) + if DEBUG==1 : print l + return l #===================================================================== #===== SVG format : DEBUT ========================= #===================================================================== -#-------------------- -# 0.4.2 -#-------------------- -OTHERSSHAPES=['rect','line', 'polyline', 'polygon','circle','ellipse'] -#-------------------- -# 0.4.2 -#-------------------- -def rect(prp): - D=[] - if 'x' not in prp.keys(): x=0.0 - else : x=float(prp['x']) - if 'y' not in prp.keys(): y=0.0 - else : y=float(prp['y']) - - height=float(prp['height']) - width=float(prp['width']) - - """ - normal rect +def contruit_SYMETRIC(l): + L=[float(l[0]), float(l[1]), + float(l[2]),float(l[3])] + X=L[0]-(L[2]-L[0]) + Y=L[1]-(L[3]-L[1]) + l =[l[0],l[1],"%4s"%X,"%4s"%Y,l[2],l[3]] + return l - x,y - h1 - *----------* - | | - | | - | | - *----------* v1 - h2 - """ - if 'rx' not in prp.keys() or 'rx' not in prp.keys(): - exec """D=['M','%s','%s','h','%s','v','%s','h','%s','z']"""%(x,y,width,height,-width) - else : - rx=float(prp['rx']) - if 'ry' not in prp.keys() : - ry=float(prp['rx']) - else : ry=float(prp['ry']) - if 'rx' in prp.keys() and prp['rx']<0.0: rx*=-1 - if 'ry' in prp.keys() and prp['ry']<0.0: ry*=-1 - - """ - rounded corner - - x,y M h1 - ---*----------* - / \ - / \ - v2 * * c1 - | | - | | - | | - c3 * * v2 - \ / - \ / - *----------* - h2 c2 - """ - exec """D=['M','%s','%s', - 'h','%s', - 'c','%s','%s','%s','%s','%s','%s', - 'v','%s', - 'c','%s','%s','%s','%s','%s','%s', - 'h','%s', - 'c','%s','%s','%s','%s','%s','%s', - 'v','%s', - 'c','%s','%s','%s','%s','%s','%s', - 'z']"""%(x+rx,y, - width-2*rx, - rx,0.0,rx,ry,rx,ry, - height-ry, - 0.0,ry,-rx,ry,-rx,ry, - -width+2*rx, - -rx,0.0,-rx,-ry,-rx,-ry, - -height+ry, - 0.0,0.0,0.0,-ry,rx,-ry - ) - - return D - -#-------------------- -# 0.4.2 -#-------------------- -def circle(prp): - if 'cx' not in prp.keys(): cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp.keys(): cy=0.0 - else : cy =float(prp['cy']) - r = float(prp['r']) - exec """D=['M','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'Z']"""%( - cx,cy+r, - cx-r,cy+r*0.552, cx-0.552*r,cy+r, cx,cy+r, - cx+r*0.552,cy+r, cx+r,cy+r*0.552, cx+r,cy, - cx+r,cy-r*0.552, cx+r*0.552,cy-r, cx,cy-r, - cx-r*0.552,cy-r, cx-r,cy-r*0.552, cx-r,cy - ) - return D - -#-------------------- -# 0.4.2 -#-------------------- -def ellipse(prp): - if 'cx' not in prp.keys(): cx=0.0 - else : cx =float(prp['cx']) - if 'cy' not in prp.keys(): cy=0.0 - else : cy =float(prp['cy']) - ry = float(prp['rx']) - rx = float(prp['ry']) - - exec """D=['M','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'C','%s','%s','%s','%s','%s','%s', - 'Z']"""%( - cx,cy+rx, - cx-ry,cy+rx*0.552, cx-0.552*ry,cy+rx, cx,cy+rx, - cx+ry*0.552,cy+rx, cx+ry,cy+rx*0.552, cx+ry,cy, - cx+ry,cy-rx*0.552, cx+ry*0.552,cy-rx, cx,cy-rx, - cx-ry*0.552,cy-rx, cx-ry,cy-rx*0.552, cx-ry,cy - ) - return D -#-------------------- -# 0.4.2 -#-------------------- -def line(prp): - exec """D=['M','%s','%s', - 'L','%s','%s']"""%(prp['x1'],prp['y1'], prp['x2'],prp['y2']) - return D -#-------------------- -# 0.4.2 -#-------------------- -def polyline(prp): - if 'points' in prp.keys(): - #print prp['points'] - points=prp['points'].split(' ') - #print points - np=0 - for p in points: - if p!='': - p=p.split(',') - if np==0: - exec "D=['M','%s','%s']"%(p[0],p[1]) - np+=1 - else: - exec """D.append('L');D.append('%s');D.append('%s')"""%(p[0],p[1]) - #print D - return D - else: - return [] - -#-------------------- -# 0.4.2 -#-------------------- -def polygon(prp): - D=polyline(prp) - if D!=[]: - D.append('Z') - return D - - -#-------------------- -# 0.3.9 -#-------------------- -def calc_arc (cpx,cpy, rx, ry, ang, fa , fs , x, y) : - 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 - pl=px/(rx**2.0)+py/(ry**2.0 ) - if pl>1.0: - pl=pl**0.5;rx*=pl;ry*=pl - x0=(cos(ang)/rx)*cpx+(sin(ang)/rx)*cpy - y0=(-sin(ang)/ry)*cpx+(cos(ang)/ry)*cpy - x1=(cos(ang)/rx)*x+(sin(ang)/rx)*y - y1=(-sin(ang)/ry)*x+(cos(ang)/ ry)*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 range(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 courbe_vers_a(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=[0,0] - 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] ) - - if DEBUG == 1 : print POINTS - - 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=[0,0] - B.tag=c[0] - BP=courbes.ITEM[n0].beziers_knot[-1] - BP.co[2]=B.co[2] - BP.co[3]=B.co[3] - courbes.ITEM[n0].beziers_knot.append(B) - - BP=courbes.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - - CP=[l[5], l[6]] - return courbes,n0,CP - -def mouvement_vers(c, D, n0,CP, proprietes): +def mouvement_vers(c, D, n0,CP): global DEBUG,TAGcourbe + #print 'c',c,'D[c[1]+1]',D[c[1]+1] - #l=filtre_DATA(c,D,2) - l=[float(D[c[1]+1]),float(D[c[1]+2])] - - if c[0]=='m': - l=[l[0]+CP[0], - l[1] + CP[1]] - + l=filtre_DATA(c,D,1) + #print 'l',l if n0 in courbes.ITEM.keys(): n0+=1 - + # + # CP=[l[0],l[1]] + #else: + # CP=[l[0],l[1]] CP=[l[0],l[1]] + courbes.ITEM[n0]=ITEM() courbes.ITEM[n0].Origine=[l[0],l[1]] - proprietes['n'].append(n0) - #print 'prop et item',proprietes['n'], courbes.ITEM.keys() - B=Bez() B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]] B.ha=[0,0] - B.tag=c[0] - courbes.ITEM[n0].beziers_knot.append(B) - if DEBUG==1: print courbes.ITEM[n0], CP + courbes.ITEM[n0].beziers_knot.append(B) + if DEBUG==1: print courbes.ITEM[n0], CP + return courbes,n0,CP def boucle_z(c,D,n0,CP): #Z,z #print c, 'close' - #print courbes.ITEM[n0].beziers_knot - courbes.ITEM[n0].flagUV[0]=1 - #print 'len(courbes.ITEM[n0].beziers_knot)',len(courbes.ITEM[n0].beziers_knot) - 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 in ['c','C','s','S']: - BP.co[2]=BP0.co[2] #4-5 point prec - BP.co[3]=BP0.co[3] - del courbes.ITEM[n0].beziers_knot[0] - else: - del courbes.ITEM[n0] - - n0-=1 + courbes.ITEM[n0].flagUV[0]=1 return courbes,n0,CP - -def courbe_vers_q(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]] + +def courbe_vers_s(c,D,n0,CP): #S,s + l=filtre_DATA(c,D,2) + if c[0]=='s': + l=["%4s"%(float(l[0])+float(CP[0])), + "%4s"%(float(l[1])+float(CP[1])), + "%4s"%(float(l[2])+float(CP[0])), + "%4s"%(float(l[3])+float(CP[1]))] + l=contruit_SYMETRIC(l) B=Bez() - B.co=[l[2], l[3], l[2], l[3], l[0], l[1]] #plus toucher au 2-3 + B.co=[l[4],l[5],l[2],l[3],l[0],l[1]] #plus toucher au 2-3 B.ha=[0,0] - B.tag=c[0] - BP=courbes.ITEM[n0].beziers_knot[-1] - BP.co[2]=BP.co[0] - BP.co[3]=BP.co[1] - courbes.ITEM[n0].beziers_knot.append(B) - if DEBUG==1: print B.co,BP.co - - 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 - courbe_vers_q(c, D, n0,CP) - return courbes,n0,CP - -def courbe_vers_t(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=[0,0] - B.tag=c[0] BP=courbes.ITEM[n0].beziers_knot[-1] - - l0=contruit_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] + BP.co[2]=l[2] #4-5 point prec + BP.co[3]=l[3] courbes.ITEM[n0].beziers_knot.append(B) if DEBUG==1: print B.co,BP.co + CP=[l[4],l[5]] - CP=[l[0],l[1]] - if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=4 - courbe_vers_t(c, D, n0,CP) + if len(D)c[1]+5 and D[c[1]+5] not in TAGcourbe : - c[1]+=4 - courbe_vers_c(c, D, n0,CP) - return courbes,n0,CP +def courbe_vers_t(c,D,n0,CP): #T + return courbes,n0,CP def courbe_vers_c(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])] + + l=filtre_DATA(c,D,3) + + print '\n','l',l, 'c',c,'CP', CP + 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]] + l=["%4s"%(float(l[0])+float(CP[0])), + "%4s"%(float(l[1])+float(CP[1])), + "%4s"%(float(l[2])+float(CP[0])), + "%4s"%(float(l[3])+float(CP[1])), + "%4s"%(float(l[4])+float(CP[0])), + "%4s"%(float(l[5])+float(CP[1]))] + + #print l + B=Bez() B.co=[l[4], l[5], - l[4], - l[5], + l[0], + l[1], l[2], l[3]] #plus toucher au 2-3 + B.ha=[0,0] - B.tag=c[0] + BP=courbes.ITEM[n0].beziers_knot[-1] + BP.co[2]=l[0] BP.co[3]=l[1] + courbes.ITEM[n0].beziers_knot.append(B) if DEBUG==1: print B.co,BP.co + CP=[l[4],l[5]] - if len(D)>c[1]+7 and D[c[1]+7] not in TAGcourbe : - c[1]+=6 + if DEBUG==1: + pass #print 'D[c[1]]', D[c[1]], c + #print D + if len(D)c[1]+3 and D[c[1]+3] not in TAGcourbe : - c[1]+=2 + + CP=[l[0],l[1]] + + if len(D) ',CP[0] + #print 'D :',D,' \n CP :', CP if c[0]=='h': - l=[float(D[c[1]+1])+float(CP[0]),CP[1]] + l=["%4s"%(float(D[c[1]+1])+float(CP[0])),"%4s"%float(CP[1])] else: - l=[float(D[c[1]+1]),CP[1]] + l=["%4s"%float(D[c[1]+1]),"%4s"%float(CP[1])] B=Bez() B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] B.ha=[0,0] - B.tag=c[0] - BP=courbes.ITEM[n0].beziers_knot[-1] - if BP.tag in ['c','C','s','S','m','M']: - BP.co[2]=B.co[4] - BP.co[3]=B.co[5] courbes.ITEM[n0].beziers_knot.append(B) + CP=[l[0],l[1]] + #print 'CP', CP return courbes,n0,CP -def ligne_tracee_v(c,D,n0,CP): #V, v +def ligne_tracee_v(c,D,n0,CP): #V, v + #l=filtre_DATA(c,D,0) + if c[0]=='v': - l=[CP[0], float(D[c[1]+1])+CP[1]] + l=["%4s"%float(CP[0]), + "%4s"%(float(D[c[1]+1])+float(CP[1]))] + #print '|',c[0],'|', len(c[0]) ,' --> ',CP else: - l=[CP[0], float(D[c[1]+1])] + l=["%4s"%float(CP[0]), + "%4s"%float(D[c[1]+1])] + #print '|',c[0],'|', len(c[0]) ,' --> ',CP + B=Bez() B.co=[l[0],l[1],l[0],l[1],l[0],l[1]] B.ha=[0,0] - B.tag=c[0] - BP=courbes.ITEM[n0].beziers_knot[-1] - if BP.tag in ['c','C','s','S','m','M']: - BP.co[2]=B.co[4] - BP.co[3]=B.co[5] courbes.ITEM[n0].beziers_knot.append(B) + CP=[l[0],l[1]] + #print 'CP', CP + return courbes,n0,CP + +def boucle_tracee_z(c,D,n0,CP): #Z + #print c + #CP=[] return courbes,n0,CP Actions= { "C" : courbe_vers_c, @@ -975,8 +517,81 @@ Actions= { "C" : courbe_vers_c, TAGcourbe=Actions.keys() TAGtransform=['M','L','C','S','H','V','T','Q'] tagTRANSFORM=0 - + +def get_content(val,t0): + t=t0[:] + if t.find(' '+val+'="')!=-1: + t=t[t.find(' '+val+'="')+len(' '+val+'="'):] + val=t[:t.find('"')] + t=t[t.find('"'):] + return t0,val + else: + return t0,0 + +def get_tag(val,t): + t=t[t.find('<'+val):] + val=t[:t.find('>')+1] + t=t[t.find('>')+1:] + if DEBUG==3 : print t[:10], val + return t,val + +def get_data(val,t): + t=t[t.find('<'+val):] + val=t[:t.find('')] + t=t[t.find('')+3+len(val):] + if DEBUG==3 : print t[:10], val + return t,val + +def get_val(val,t): + d="" + #print t + for l in t: + if l.find(val+'="')!=-1: + #print 'l', l + # 0.2.7 : - correction for inskape 0.40 cvs SVG + l=l.replace('>','') + # 0.2.7 : -- end + d=l[l[:-1].rfind('"')+1:-1] + #print 'd', d + for nn in d: + if '0123456789.'.find(nn)==-1: + d=d.replace(nn,"") + #print d + d=float(d) + break + #else: + # print l + d=0.0 + return d + + + +def get_BOUNDBOX(BOUNDINGBOX,SVG,viewbox): + if viewbox==0: + h=get_val('height',SVG) + if DEBUG==1 : print 'h : ',h + w=get_val('width',SVG) + if DEBUG==1 : print 'w :',w + BOUNDINGBOX['rec']=[0.0,0.0,w,h] + r=BOUNDINGBOX['rec'] + BOUNDINGBOX['coef']=w/h + else: + viewbox=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.2.8 : - correction for inskape 0.40 cvs SVG +def repack_DATA2(DATA): + for d in Actions.keys(): + DATA=DATA.replace(d,d+' ') + return DATA + + def wash_DATA(ndata): + print 'ndata', ndata, len(ndata) if ndata!='': while ndata[0]==' ': ndata=ndata[1:] @@ -984,21 +599,17 @@ def wash_DATA(ndata): ndata=ndata[:-1] if ndata[0]==',':ndata=ndata[1:] if ndata[-1]==',':ndata=ndata[:-1] - #-------------------- - # 0.4.0 : 'e' - #-------------------- - if ndata.find('-')!=-1 and ndata[ndata.find('-')-1] not in [' ', ',', 'e']: + if ndata.find('-')!=-1 and ndata[ndata.find('-')-1] not in [' ',' ']: ndata=ndata.replace('-',',-') ndata=ndata.replace(',,',',') ndata=ndata.replace(' ',',') ndata=ndata.split(',') for n in ndata : - if n=='' : ndata.remove(n) + if n=='' : ndata.remove(n) return ndata - -#-------------------- -# 0.3.4 : - reading data rewrittten -#-------------------- + + +# 0.3.4 : - restructuration de la lecture des donnes paths def list_DATA(DATA): """ cette fonction doit retourner une liste proposant @@ -1007,304 +618,238 @@ def list_DATA(DATA): Par exemple : d="'M0,14.0 z" devient ['M','0.0','14.0','z'] """ + while DATA.count(' ')!=0 : + DATA=DATA.replace(' ',' ') + tagplace=[] + DATA=DATA.replace('\n','') + for d in Actions.keys(): b1=0 b2=len(DATA) while DATA.find(d,b1,b2)!=-1 : + #print d, b1 tagplace.append(DATA.find(d,b1,b2)) b1=DATA.find(d,b1,b2)+1 tagplace.sort() tpn=range(len(tagplace)-1) - #-------------------- - # 0.3.5 :: short data,only one tag - #-------------------- - if len(tagplace)-1>0: - DATA2=[] - for t in tpn: - 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) - for n in ndata : DATA2.append(n) - 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:-1] + DATA2=[] + + for t in tpn: + + DATA2.append(DATA[tagplace[t]:tagplace[t]+1]) + print DATA2[-1] + + ndata=DATA[tagplace[t]+1:tagplace[t+1]] + if DATA2[-1] not in ['z','Z'] : ndata=wash_DATA(ndata) for n in ndata : DATA2.append(n) - 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) - for n in ndata : DATA2.append(n) + + DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1]) + + print DATA2[-1] + + if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1: + ndata=DATA[tagplace[t+1]+1:-1] + ndata=wash_DATA(ndata) + for n in ndata : DATA2.append(n) + return DATA2 + # 0.3 -def translate(tx=None,ty=None): +def translate(tx,ty): return [1, 0, tx], [0, 1, ty],[0,0,1] + # 0.3.2 -def scale(sx=None,sy=None): - if sy==None: sy=sx +def scale(sx,sy): return [sx, 0, 0], [0, sy, 0],[0,0,1] -# 0.4.1 : transslate a in radians +# 0.3.2 def rotate(a): - return [cos(a*3.1416/90.0), -sin(a*3.1416/90.0), 0], [sin(a*3.1416/90.0), cos(a*3.1416/90.0),0],[0,0,1] + return [cos(a), -sin(a), 0], [sin(a), cos(a),0],[0,0,1] # 0.3.2 def skewX(a): return [1, tan(a), 0], [0, 1, 0],[0,0,1] -# 0.4.1 -def skewY(a): +# 0.3.2 +def skewX(a): return [1, 0, 0], [tan(a), 1 , 0],[0,0,1] # 0.3.2 def matrix(a,b,c,d,e,f): - return [a,c,e],[b,d,f],[0,0,1] + return [a,b,e],[c,d,f],[0,0,1] -# 0.4.2 : rewritten -def control_CONTAINT(txt): +# 0.3.3 +def controle_CONTENU(val,t): """ - les descriptions de transformation peuvent être seules ou plusieurs et - les séparateurs peuvent avoir été oubliés + une matrice peut s'ecrire : matrix(a,b,c,d,e,f) ou matrix(a b c d e f) """ - 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(' ',' ') - t2=t2.replace(' ',',') - if t2.find('e'): - t3=t2.split(',') - t2='' - for t in t3 : - t=str(float(t)) - t2=str(t3).replace(']','').replace('[','').replace('\'','') - if val=='rotate' : - t3=t2.split(',') - if len(t3)==3: - tlist.append('translate('+t3[1]+','+t3[2]+')') - tlist.append('rotate('+t3[0]+')') - tlist.append('translate(-'+t3[1]+',-'+t3[2]+')') - else: - tlist.append(val+'('+t2+')') - t0=t1+1 - return tlist - -# 0.4.1 : apply transform stack -def courbe_TRANSFORM(Courbe,proprietes): - # 1/ deplier le STACK - # créer une matrice pour chaque transformation - ST=[] - #print proprietes['stack'] - for st in proprietes['stack'] : - if st and type(st)==list: - for t in st: - exec "a,b,c=%s;T=Mathutils.Matrix(a,b,c)"%control_CONTAINT(t)[0] - ST.append(T) - elif st : - exec "a,b,c=%s;T=Mathutils.Matrix(a,b,c)"%control_CONTAINT(st)[0] - ST.append(T) - if 'transform' in proprietes.keys(): - for trans in control_CONTAINT(proprietes['transform']): - exec """a,b,c=%s;T=Mathutils.Matrix(a,b,c)"""%trans - ST.append(T) - #print ST - ST.reverse() - for n in proprietes['n']: - if n in Courbe.keys(): - for bez0 in Courbe[n].beziers_knot: - bez=bez0.co - for b in [0,2,4]: - for t in ST: - v=Mathutils.Vector([bez[b],bez[b+1],1.0]) - #v=Mathutils.MatMultVec(t, v) - v=t * v - bez[b]=v[0] - bez[b+1]=v[1] - -def filtre(d): - for nn in d: - if '0123456789.'.find(nn)==-1: - d=d.replace(nn,"") - return d - -def get_BOUNDBOX(BOUNDINGBOX,SVG): - if 'viewbox' not in SVG.keys(): - h=float(filtre(SVG['height'])) - if DEBUG==1 : print 'h : ',h - w=float(filtre(SVG['width'])) - if DEBUG==1 : print 'w :',w - BOUNDINGBOX['rec']=[0.0,0.0,w,h] - r=BOUNDINGBOX['rec'] - BOUNDINGBOX['coef']=w/h + if val.find('matrix') and t.find(val+'(')!=-1 and t.find(val+',')==-1: + t0=t[t.find(val+'(')+len(val+'('):] + t0=t0[:t0.find(')')] + val=t0[:] + while val.find(' ')!=-1: + val=val.replace(' ',' ') + val=val.replace(' ',',') + t=t.replace(t0,val) + return val 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 + return -1 + +# 0.3 +def get_TRANSFORM(STRING): + STRING,TRANSFORM=get_content('transform',STRING) + #print 'TRANSFORM 1 :', TRANSFORM + for t in ['translate','scale','rotate','matrix','skewX','skewY'] : + if TRANSFORM.find(t)!=-1 and TRANSFORM.count('(')==1: + #print 'TRANSFORM 2 :', TRANSFORM + print ' getcontent ', t,' ',controle_CONTENU(t,TRANSFORM) + exec "a,b,c=%s;T=Mathutils.Matrix(a,b,c)"%TRANSFORM + return T + +# 0.3 +def G_move(l,a,t): + if a==0: + v=Mathutils.Vector([float(l[0]),float(l[1]),1.0]) + v=Mathutils.MatMultVec(t, v) + return str(v[0]),str(v[1]) + else : + #print 'l', l ,'t', t, 'a', a + l=l.split(',') + v=Mathutils.Vector([float(l[0]),float(l[1]),1.0]) + v=Mathutils.MatMultVec(t, v) + return str(v[0])+','+str(v[1]) + +# 0.3 +def transform_DATA(D1,TRANSFORM): + for cell in range(len(D1)): + if D1[cell] in TAGtransform: + if D1[cell+1].find(',')==-1: + if D1[cell] in ['C', 'S','Q', 'M','L','T',]: #2 valeurs + D1[cell+1],D1[cell+2]=G_move([D1[cell+1],D1[cell+2]],0,TRANSFORM) + if D1[cell] in ['C', 'S','Q'] : + D1[cell+3],D1[cell+4]=G_move([D1[cell+3],D1[cell+4]],0,TRANSFORM) + if D1[cell] in ['C']: + D1[cell+5],D1[cell+6]=G_move([D1[cell+5],D1[cell+6]],0,TRANSFORM) + else : + if D1[cell] == 'C': #6 valeurs + D1[cell+1]=G_move(D1[cell+1],-1,TRANSFORM) + D1[cell+2]=G_move(D1[cell+2],-1,TRANSFORM) + D1[cell+3]=G_move(D1[cell+3],-1,TRANSFORM) + elif D1[cell] in ['M','L','T']: #2 valeurs + D1[cell+1]=G_move(D1[cell+1],-1,TRANSFORM) + elif D1[cell] == ['S','Q']: #4 valeurs + D1[cell+1]=G_move(D1[cell+1],-1,TRANSFORM) + D1[cell+2]=G_move(D1[cell+2],-1,TRANSFORM) + if D1[cell] == 'H': #1 valeurs x + n=0 + D1[cell+1]=G_move(D1[cell+1],0,TRANSFORM) + elif D1[cell] == 'V': #1 valeurs y + n=0 + D1[cell+1]=G_move(D1[cell+1],1,TRANSFORM) + return D1 + +def format_PATH(t,TRANSFORM): + global tagTRANSFORM + + t,PATH=get_tag('path',t) + + if PATH.find(' transform="')!=-1: + TRANSFORM2=get_TRANSFORM(PATH) + # 0.3.3 + TRANSFORM=TRANSFORM*TRANSFORM2 + #TRANSFORM[1]+=TRANSFORM2[1] + tagTRANSFORM+=1 + + if PATH.find(' id="')!=-1: + PATH,ID=get_content('id',PATH) + #print 'ident = ', ID + + if PATH.find(' STROKE="')!=-1: + PATH,ID=get_content('stroke',PATH) + #print 'path stroke = ', ID + + if PATH.find(' stroke-width="')!=-1: + PATH,ID=get_content('stroke-width',PATH) + #print 'path stroke-width = ', ID + + if PATH.find(' d="')!=-1: + PATH,D=get_content('d',PATH) + D=list_DATA(D) + + if tagTRANSFORM in [1,2] : D=transform_DATA(D,TRANSFORM) + return t,D + -# 0.4.1 : attributs ex : 'id=', 'transform=', 'd=' ... -def collecte_ATTRIBUTS(data): - data=data.replace(' ',' ') - 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': - exec "ELEM[id]=\"\"\"%s\"\"\""%(data[t0+2:t2].replace('\\','/')) - else: - exec "ELEM[id]=[%s,%s]"%(t0+2,t2) - ct=data.count('="',t2) - return ELEM -# -------------------------------------------- -# 0.4.1 : to avoid to use sax and ths xml -# tools of the complete python -# -------------------------------------------- -def contruit_HIERARCHIE(t): - global CP, courbes, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - 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 t.find('-1: - balise=BALISES[-1] - else: - balise=BALISES[-2] - if balise=='E' or balise=='O': - proprietes=collecte_ATTRIBUTS(t[t0:t1+ouvrante]) - if balise=='O' and 'transform' in proprietes.keys(): - 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: - exec "D=%s(proprietes)"% proprietes['TYPE'] - if len(D)>0: - cursor=0 - proprietes['n']=[] - for cell in D: - if DEBUG==2 : print 'cell : ',cell ,' --' - if len(cell)>=1 and cell[0] in TAGcourbe: - prop='' - if cell[0] in ['m','M']: - prop=',proprietes' - exec """courbes,n0,CP=Actions[cell]([cell,cursor], D, n0,CP%s)"""%prop - cursor+=1 - if TRANSFORM>0 or 'transform' in proprietes.keys() : - courbe_TRANSFORM(courbes.ITEM,proprietes) - elif proprietes['TYPE'] in ['svg'] : - BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,proprietes) - else: - #-------------------- - # 0.4.4 - #-------------------- - break - t1+=1 - t0=t1 def scan_FILE(nom): - global CP, courbes, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM + global CP, courbes, SCALE, DEBUG, BOUNDINGBOX, scale, tagTRANSFORM dir,name=split(nom) name=name.split('.') + n0=0 result=0 + t=filtreFICHIER(nom) + if t!='false': - Blender.Window.EditMode(0) if not SHARP_IMPORT: warning = "Select Size : %t| As is %x1 | Scale on Height %x2| Scale on Width %x3" - scale_ = Blender.Draw.PupMenu(warning) - # 0.4.1 : to avoid to use sax and the xml - # tools of the complete python - contruit_HIERARCHIE(t) - 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] + scale = Blender.Draw.PupMenu(warning) + npat=0 + l=0 + do=0 + t,SVG=get_tag('svg',t) + + SVG,viewbox=get_content('viewBox',SVG) + + SVG=SVG.split(' ') + if DEBUG==1 : print SVG + if viewbox==0: + BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,SVG,0) + else: + BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,SVG,viewbox) + + while t.find('0 and CVS==2: + if courbes.number_of_items>0: if len(PATTERN.keys() )>0: if DEBUG == 3 : print len(PATTERN.keys() ) t=create_GEOtext(courbes) save_GEOfile(dir,name[0],t) Open_GEOfile(dir,name[0]) - - elif courbes.number_of_items>0 and CVS==1 : - #-------------------- - # 0.4.5 - #-------------------- - createCURVES(courbes) - else: - pass + pass def ajustement(v,s): @@ -1323,4 +868,4 @@ def fonctionSELECT(nom): scan_FILE(nom) if __name__=='__main__': - Blender.Window.FileSelector (fonctionSELECT, 'SELECT a .SVG FILE') \ No newline at end of file + Blender.Window.FileSelector (fonctionSELECT, 'SELECT a .SVG FILE') diff --git a/release/scripts/bvh2arm.py b/release/scripts/bvh2arm.py index e4430cdad96..ec04f59d60f 100644 --- a/release/scripts/bvh2arm.py +++ b/release/scripts/bvh2arm.py @@ -1,60 +1,40 @@ #!BPY """ -Name: 'Empties to Armature' -Blender: 241 +Name: 'BVH Empties to Armature' +Blender: 237 Group: 'Animation' -Tooltip: 'Create Armature from a parented-empties chain' +Tooltip: 'Create Armature from Empties created by BVH importer' """ -__author__ = " Jean-Baptiste PERIN (jb_perin(at)yahoo.fr) with valuable help from Vincent BILLET " +__author__ = " Jean-Baptiste PERIN (jb_perin(at)yahoo.fr)" __url__ = ("blender", "elysiun", -"BVH 2 ARMATURE, http://perso.wanadoo.fr/jb.perin/", +"BVH 2 ARMATURE, http://www.zoo-logique.org/3D.Blender/index.php3?zoo=dld&rep=zip ", "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "2.42" +__version__ = "2.2" -__bpydoc__ = """ BVH2ARM.py +__bpydoc__ = """ BVH2ARM.py v2.2 Script for generating armature on BVH empties. -This script generates an armature upon an empty-made parented chain, -and make the armature follow the empties - +This script generates an armature and make bones +follow empties created by Blender BVH import script. + Usage:
- Import a bvh in Blender (File->Import->BVH);
- - Rotate some empties to match your model and insert Rot key for them.
- - Select the root empty of the hierarchical chain.
- - Launch this script ;
+ - Launch this script (Alt-P);
- Set up variables:
- "hipbonename": the name of the main bone (automatically set to the selected empty).
+ "hipbonename": the name of the main bone;
"startframe": the first frame of your anim;
"endframe": the last frame of your anim;
- "decimation": the frequency (in number of frame) to which the armature's pos is updated;
-- Press "Create Armature". -Notes:
-- The start frame configuration is used as the rest pose for the armature.
-- If the armature already exists when script is launched, the current armature is re-used. + "decimation": the frequency (in number of frame) to which the armature is updated;
+ "scale" to size the created armature.
+ - Press "Create Armature". """ -# -------------------------------------------------------------------------- -# BVH2ARM.py -# -------------------------------------------------------------------------- -# ***** 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 ***** -# -------------------------------------------------------------------------- + +#---------------------------------------------- +# (c) Jean-Baptiste PERIN june 2005, released under Blender Artistic Licence +# for the Blender 2.34-2.36 Python Scripts Bundle. +#---------------------------------------------- @@ -70,9 +50,6 @@ dicEmptyChild={} dicBoneRestInvEmpRest={} dicEmpRestInvBoneRest={} restFrame = 1 -bonerest={} -emprest={} -emp2bone={} ######################################################################## # @@ -134,8 +111,8 @@ def getEmpty(name): p = o return p -##def getChild(emp, emp_list): -## return dicEmptyChild[emp.getName()] +def getChild(emp, emp_list): + return dicEmptyChild[emp.getName()] ######### @@ -229,6 +206,32 @@ def GetOrCreateCurve(ipo, curvename): # ######################################################################## +def computeRootQuat2(empty, bone): + + M1=dicBoneRestInvEmpRest[bone.getName()].rotationPart() + M2=dicEmpRestInvBoneRest[bone.getName()].rotationPart() + emprot = empty.getMatrix('worldspace').rotationPart() + emprot.transpose() + mat = M1*emprot*M2 + mat.transpose() + return (mat.toQuat()) + + #emprest = dicEmptiesRestMatrix[empty.getName()].rotationPart() + #invemprest= dicEmptiesRestMatrix[empty.getName()].rotationPart() + ##invemprest= emprest + ##invemprest.invert() + ##invemprest= dicEmptiesInvRestMatrix[empty.getName()].rotationPart() + #emprot = empty.getMatrix('worldspace').rotationPart() + #bonerest = dicBoneRestMatrix[bone.getName()].rotationPart() + #invbonerest = dicBoneRestMatrix[bone.getName()].rotationPart() + #invbonerest.invert() + #T2=emprot*invemprest + #T2.transpose() + #mat = bonerest*invemprest*T2*emprest*invbonerest + #mat.transpose() + #return (mat.toQuat()) + + ######### @@ -236,6 +239,27 @@ def GetOrCreateCurve(ipo, curvename): # in : # out : ######### +def computeRootPos(empty, bone): + vec = computeScaledPos(empty.getMatrix('worldspace').translationPart()) - dicBoneRestMatrix[bone.getName()].translationPart() + mat = dicBoneRestMatrix[bone.getName()].rotationPart() + vec2 = Mathutils.MatMultVec (mat, vec) + return vec2 + + +def computeRelativePos(empty,bone): + vec = computeScaledPos(empty.getMatrix('worldspace').translationPart()) - dicBoneRestMatrix[bone.getName()].translationPart() + rootempty = getEmpty(hipbonename) + vec3 = computeScaledPos(rootempty.getMatrix('worldspace').translationPart()) + mat = dicBoneRestMatrix[bone.getName()].rotationPart() + vec2 = Mathutils.MatMultVec (mat, vec-vec3) + return vec2 + + + ######### +# Cette fonction +# in : +# out : +######### def computeScaledPos(vec): global scalef vec2 = Mathutils.Vector([vec[0]*scalef, vec[1]*scalef, vec[2]*scalef]) @@ -253,28 +277,31 @@ def computeScaledPos(vec): # out : ######### def createBone (armature, empty, bone, empties): - global bonerest, emprest children = getChildren(empty, empties) - if len(children) != 0: - for ch in children: + for ch in children: if len(children) >= 2: bonename = empty.getName()[1:len(empty.getName())]+'_'+ch.getName()[1:len(ch.getName())] else : bonename = empty.getName()[1:len(empty.getName())] - print "creating Bone %s"%(bonename) - b=Blender.Armature.Editbone() - b.head = (computeScaledPos(empty.getMatrix('worldspace').translationPart())) - b.tail = (computeScaledPos(ch.getMatrix('worldspace').translationPart())) - b.parent = bone - # armature.makeEditable() should already be editable???? - armature.bones[bonename] = b - #print b.matrix - bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4() - emprest[empty.getName()]=Blender.Mathutils.Matrix(empty.getMatrix('localspace')).resize4x4() - #M = Blender.Mathutils.Matrix(emprest[empty.getName()]) - #emp2bone[bonename] = Blender.Mathutils.Matrix(M.invert().rotationPart()*bonerest[bonename].rotationPart()).resize4x4() - #print emp2bone[bonename].rotationPart().toEuler() - dicBone[b.name]=b + b=Blender.Armature.Bone.New(bonename) + b.setHead(computeScaledPos(empty.getMatrix('worldspace').translationPart())) + b.setTail(computeScaledPos(ch.getMatrix('worldspace').translationPart())) + #b.setParent(bone) + matrice = empty.getMatrix('worldspace') + invmatrice = empty.getMatrix('worldspace') + invmatrice.invert() + invmatricet=empty.getMatrix('worldspace') + invmatricet.invert() + invmatricet.transpose() + dicEmptiesRestMatrix[empty.getName()] = matrice + dicEmptiesInvRestMatrix[empty.getName()] = invmatrice + armature.addBone(b) + invbonerest=b.getRestMatrix() + invbonerest.invert() + dicBoneRestMatrix[b.getName()] = b.getRestMatrix() + dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet + dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest + dicBone[b.getName()]=b createBone(armature, ch, b, empties) ######### @@ -283,12 +310,13 @@ def createBone (armature, empty, bone, empties): # out : ######### def f_createBone (armData, empty, bone, empties): - bones = armData.bones.values() + bones = armData.getBones() + def getBone(bonename): bone = None for b in bones: #print b.getName() - if b.name == bonename: + if b.getName() == bonename: bone = b return bone @@ -300,41 +328,56 @@ def f_createBone (armData, empty, bone, empties): bonename = empty.getName()[1:len(empty.getName())] #b=Blender.Armature.Bone.New(bonename) b=getBone(bonename) - b.head = (computeScaledPos(empty.getMatrix('worldspace').translationPart())) - b.tail = (computeScaledPos(ch.getMatrix('worldspace').translationPart())) - b.parent = bone - bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4() - emprest[empty.getName()]=Blender.Mathutils.Matrix(empty.getMatrix('localspace')).resize4x4() - dicBone[b.name]=b + #b.setHead(empty.getMatrix('worldspace').translationPart()) + #b.setTail(ch.getMatrix('worldspace').translationPart()) + #b.setParent(bone) + matrice = empty.getMatrix('worldspace') + invmatrice = empty.getMatrix('worldspace') + invmatrice.invert() + invmatricet=empty.getMatrix('worldspace') + invmatricet.invert() + invmatricet.transpose() + dicEmptiesRestMatrix[empty.getName()] = matrice + dicEmptiesInvRestMatrix[empty.getName()] = invmatrice + #armature.addBone(b) + invbonerest=b.getRestMatrix() + invbonerest.invert() + dicBoneRestMatrix[b.getName()] = b.getRestMatrix() + dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet + dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest + dicBone[b.getName()]=b #print "Ajout de ", b.getName()," au dictionnaire" f_createBone(armData, ch, b, empties) + ######### # Cette fonction fabrique une arma # in : # out : ######### -def createArmature (armObj, rootEmpty, empties): - global bonerest, emprest - armData=Blender.Armature.Armature('monArmature') +def createArmature (rootEmpty, empties): + armData=Blender.Armature.New('monArmature') children = getChildren(rootEmpty, empties) - armObj.link(armData) - armData.makeEditable() for ch in children: - b=Blender.Armature.Editbone() - bonename = rootEmpty.getName()[1:len(rootEmpty.getName())] + ch.getName()[1:len(ch.getName())] - print "creating Bone %s"%(bonename) - - #print b, dir([b]) - b.head=(computeScaledPos(rootEmpty.getMatrix('worldspace').translationPart())) - b.tail=(computeScaledPos(ch.getMatrix('worldspace').translationPart())) - - bonerest[bonename]=Blender.Mathutils.Matrix(b.matrix).resize4x4() - emprest[rootEmpty.getName()]=Blender.Mathutils.Matrix(rootEmpty.getMatrix('localspace')).resize4x4() - armData.bones[bonename] = b - dicBone[b.name]=b + b=Blender.Armature.Bone.New(rootEmpty.getName()[1:len(rootEmpty.getName())] + ch.getName()[1:len(ch.getName())]) + b.setHead(computeScaledPos(rootEmpty.getMatrix('worldspace').translationPart())) + b.setTail(computeScaledPos(ch.getMatrix('worldspace').translationPart())) + armData.addBone(b) + matrice = ch.getMatrix('worldspace') + invmatrice = ch.getMatrix('worldspace') + invmatrice.invert() + invmatricet=ch.getMatrix('worldspace') + invmatricet.invert() + invmatricet.transpose() + dicEmptiesRestMatrix[rootEmpty.getName()] = matrice + dicEmptiesInvRestMatrix[rootEmpty.getName()] = invmatrice + invbonerest=b.getRestMatrix() + invbonerest.invert() + dicBoneRestMatrix[b.getName()] = b.getRestMatrix() + dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet + dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest + dicBone[b.getName()]=b createBone(armData, ch, b, empties) - armData.update() return armData @@ -345,27 +388,37 @@ def createArmature (armObj, rootEmpty, empties): # out : ######### def f_createArmature (rootEmpty, empties, armData): - armData.makeEditable() - bones = armData.bones.values() + bones = armData.getBones() def getBone(bonename): bone = None for b in bones: #print b.getName() - if b.name == bonename: + if b.getName() == bonename: bone = b return bone children = getChildren(rootEmpty, empties) for ch in children: b=getBone(rootEmpty.getName()[1:len(rootEmpty.getName())] + ch.getName()[1:len(ch.getName())]) - dicBone[b.name]=b + matrice = ch.getMatrix('worldspace') + invmatrice = ch.getMatrix('worldspace') + invmatrice.invert() + invmatricet=ch.getMatrix('worldspace') + invmatricet.invert() + invmatricet.transpose() + dicEmptiesRestMatrix[rootEmpty.getName()] = matrice + dicEmptiesInvRestMatrix[rootEmpty.getName()] = invmatrice + invbonerest=b.getRestMatrix() + invbonerest.invert() + dicBoneRestMatrix[b.getName()] = b.getRestMatrix() + dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet + dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest + dicBone[b.getName()]=b #print "Ajout de ", b.getName()," au dictionnaire" - bonerest[b.name]=Blender.Mathutils.Matrix(b.matrix).resize4x4() - emprest[rootEmpty.getName()]=Blender.Mathutils.Matrix(rootEmpty.getMatrix('localspace')).resize4x4() + f_createBone(armData, ch, b, empties) - armData.update() ######### @@ -373,34 +426,20 @@ def f_createArmature (rootEmpty, empties, armData): # in : # out : ######### -def moveBones(larmature, empty, empties): - #print "move bones" - global bonerest, emprest +def moveBones(armature, empty, empties): children = dicEmptyChild[empty.getName()] - thepose = larmature.getPose() for ch in children: if len(children) >= 2: bonename = empty.getName()[1:len(empty.getName())]+'_'+ch.getName()[1:len(ch.getName())] else : bonename = empty.getName()[1:len(empty.getName())] - thebone = thepose.bones[bonename] - trMatrix = empty.getMatrix('localspace') - bonerestmat = Blender.Mathutils.Matrix(bonerest[bonename]) - invbonerestmat = Blender.Mathutils.Matrix(bonerest[bonename]) - invbonerestmat.invert() - trMatrix[3][0] = 0.0 - trMatrix[3][1] = 0.0 - trMatrix[3][2] = 0.0 - invemprestmat = Blender.Mathutils.Matrix(emprest[empty.getName()].rotationPart()).resize4x4() - invemprestmat.invert() - emprestmat = Blender.Mathutils.Matrix(emprest[empty.getName()].rotationPart()).resize4x4() - thebone.localMatrix = bonerestmat* invemprestmat *trMatrix * invbonerestmat - thepose.update() - thebone.insertKey(larmature, Blender.Get('curframe'), [Blender.Object.Pose.ROT, Blender.Object.Pose.LOC]) - thepose.update() - chch = dicEmptyChild[ch.getName()] + bone = dicBone[bonename] + #bone.setLoc(computeRootPos(empty,bone)) + bone.setLoc(computeRelativePos(empty,bone)) + bone.setQuat(computeRootQuat2(empty,bone)) + chch = dicEmptyChild[ch.getName()] if len(chch) >= 1: - moveBones(larmature, ch, empties) + moveBones(armature, ch, empties) ######### @@ -408,20 +447,26 @@ def moveBones(larmature, empty, empties): # in : # out : ######### -def moveArmature (larmature, empties): - global bonerest, emprest - #print "move armature" - thepose = larmature.getPose() - #armature.makeEditable() +def moveArmature (armature, empties): root = Blender.Object.Get(hipbonename) children = dicEmptyChild[hipbonename] for ch in children: b=dicBone[hipbonename[1:len(hipbonename)] + ch.getName()[1:len(ch.getName())]] - - moveBones(larmature, ch, empties) - #armature.update() + #b.setLoc(computeRootPos(root, b)) + b.setLoc([0.0, 0.0, 0.0]) + b.setQuat(computeRootQuat2(root, b)) + moveBones(armature, ch, empties) +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) ######################################################################## @@ -467,7 +512,7 @@ def Main(): lesEmpties = getEmpties() #print dicEmptyChild - print "creating armature" + #armData = createArmature(em0, lesEmpties) objects = Blender.Object.Get() if 'OBArmature' in map(names,objects): @@ -478,16 +523,15 @@ def Main(): #print armData.getBones() f_createArmature(em0, lesEmpties, armData) else: + armData= createArmature(em0, lesEmpties) armObj=Blender.Object.New('Armature', 'OBArmature') - armData= createArmature(armObj, em0, lesEmpties) - #armObj.link(armData) + armObj.link(armData) scn = Blender.Scene.getCurrent() scn.link (armObj) print 'OBArmature'+' was created' #return myobj - print emprest - armData.drawType = Blender.Armature.STICK + ##----------- ## Creation de l'ipo de l'armature ##----------- @@ -496,11 +540,7 @@ def Main(): curvX = GetOrCreateCurve(lipo, 'LocX') curvY = GetOrCreateCurve(lipo, 'LocY') curvZ = GetOrCreateCurve(lipo, 'LocZ') - curvrX = GetOrCreateCurve(lipo, 'RotX') - curvrY = GetOrCreateCurve(lipo, 'RotY') - curvrZ = GetOrCreateCurve(lipo, 'RotZ') - print "animating armature" #armData.drawAxes(1) #armData.drawNames(1) @@ -509,16 +549,13 @@ def Main(): Blender.Redraw() - action = Blender.Armature.NLA.NewAction() - action.setActive(armObj) - - - ##----------- ## Enregistrement de la position de l'armature ##----------- - bones = armData.bones.values() + bones = armData.getBones() + for bo in bones: + bo.setPose([Blender.Armature.Bone.ROT, Blender.Armature.Bone.LOC]) curvX.addBezier((Blender.Get("curframe"), getEmpty(hipbonename).getMatrix('worldspace').translationPart()[0]*scalef)) curvY.addBezier((Blender.Get("curframe"), getEmpty(hipbonename).getMatrix('worldspace').translationPart()[1]*scalef)) @@ -529,12 +566,6 @@ def Main(): curvY.setExtrapolation('Constant') curvZ.setInterpolation('Linear') curvZ.setExtrapolation('Constant') - curvrX.setInterpolation('Linear') - curvrX.setExtrapolation('Constant') - curvrY.setInterpolation('Linear') - curvrY.setExtrapolation('Constant') - curvrZ.setInterpolation('Linear') - curvrZ.setExtrapolation('Constant') Blender.Redraw() @@ -545,19 +576,18 @@ def Main(): ## Positionnement des os ##----------- - moveArmature(armObj, lesEmpties) + moveArmature(armData, lesEmpties) ##----------- ## Enregistrement de la position de l'armature ##----------- + for bo in bones: + bo.setPose([Blender.Armature.Bone.ROT, Blender.Armature.Bone.LOC]) curvX.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[0])*scalef)) curvY.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[1])*scalef)) curvZ.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').translationPart()[2])*scalef)) - curvrX.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[0])*scalef/10)) - curvrY.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[1])*scalef/10)) - curvrZ.addBezier((Blender.Get("curframe"), (getEmpty(hipbonename).getMatrix('worldspace').rotationPart().toEuler()[2])*scalef/10)) ##----------- ## Passage a la frame suivante @@ -566,12 +596,6 @@ def Main(): print num_frame Blender.Set("curframe", num_frame) - curvX.Recalc() - curvY.Recalc() - curvZ.Recalc() - curvrX.Recalc() - curvrY.Recalc() - curvrZ.Recalc() Blender.Set("curframe",startframe) Blender.Redraw() @@ -603,35 +627,26 @@ def button_event(evt): global endframe, startframe, insertionframe, hipbonename, framedecimation , scalef if evt==1: startframe = SFrame2.val - insertionframe = 100 #IFrame.val + insertionframe = IFrame.val endframe = EFrame.val hipbonename = HBName.val framedecimation = FrameDecimation.val - scalef= 1.0 #eval(str(ScaleF.val)) + scalef= eval(str(ScaleF.val)) #print "scalef = ", scalef if startframe>=endframe: Msg = 'Start frame must be lower than End frame' - error_txt = "Error|Start frame must be lower than End frame" - Blender.Draw.PupMenu(error_txt) else: ob = getEmpty(hipbonename) if (ob!=None): if ob.getParent()!=None: Msg = 'Empty '+hipbonename+ ' is not a root bone.' - error_txt = "Error|Empty %s is not a root bone"%hipbonename - Blender.Draw.PupMenu(error_txt) else: if (0.0 > scalef): Msg = 'Scale factor must be greater than 0' - error_txt = "Error|Scale factor must be greater than 0" - Blender.Draw.PupMenu(error_txt) else: #Blender.Draw.Exit() Main() - #Main() else: - error_txt = "Error|Empty %s not found"%hipbonename - Blender.Draw.PupMenu(error_txt) Msg = 'Empty '+ hipbonename+ ' not found' #Blender.Draw.Redraw(1) @@ -640,9 +655,6 @@ def button_event(evt): ob = getEmpty(hipbonename) if (ob!=None): if ob.getParent()!=None: - error_txt = "Error|Empty %s is not a root bone"%hipbonename - Blender.Draw.PupMenu(error_txt) - Msg = 'Empty '+hipbonename+ ' is not a root bone.' else: #Blender.Draw.Exit() @@ -659,17 +671,15 @@ def GUI(): Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT) Blender.BGL.glColor3f(1,1,1) Blender.BGL.glRasterPos2i(20,200) - selobj = Blender.Object.GetSelected() - if len(selobj) == 1 and type (selobj[0]) == Blender.Types.ObjectType: - hipname = selobj[0].getName() - else: - hipname = '_Hips' - Blender.Draw.Text ("BVH 2 ARMATURE v%s by %s"%(__version__, __author__), 'normal') - HBName = Blender.Draw.String("HipBoneName: ", 0, 20, 175, 250, 20, hipname, 100) + Blender.Draw.Text ("BVH 2 ARMATURE v2.2 by Jean-Baptiste PERIN", 'normal') + HBName = Blender.Draw.String("HipBoneName: ", 0, 20, 175, 250, 20, '_Hips', 100) SFrame2 = Blender.Draw.Number("Startframe: ", 0, 20, 150, 250, 20, 1, 1,3000,"Start frame of anim") EFrame = Blender.Draw.Number("Endframe: ", 0, 20, 125, 250, 20, Blender.Get("endframe"), 1,3000,"Last frame of anim") - FrameDecimation = Blender.Draw.Number("FrameDecimation: ", 0, 20, 75, 250, 20,1, 1,10,'number of frame to skip between two action keys') + #IFrame = Blender.Draw.Number("Insertionframe: ", 0, 20, 100, 250, 20, Blender.Get("staframe"), 1,3000,"") + FrameDecimation = Blender.Draw.Number("FrameDecimation: ", 0, 20, 75, 250, 20,5, 1,10,'number of frame to skip between two action keys') + ScaleF = Blender.Draw.Number("Scale: ", 0, 20, 50, 250, 20, 1.0, 0.0, 10.0, 'Scale Factor') Blender.Draw.Toggle("Create Armature", 1, 20, 10, 100, 20, 0, "Create Armature") + #Blender.Draw.Toggle("Remove Empties", 2, 200, 10, 100, 20, 0, "Remove Empties") Blender.BGL.glRasterPos2i(20,40) Blender.Draw.Text (Msg, 'normal') diff --git a/release/scripts/bvh_export.py b/release/scripts/bvh_export.py index 7c6ac4c7e36..84425626cee 100644 --- a/release/scripts/bvh_export.py +++ b/release/scripts/bvh_export.py @@ -9,7 +9,7 @@ Tip: 'Export a (.bvh) motion capture file' __author__ = "Campbell Barton" __url__ = ("blender", "elysiun") -__version__ = "1.1 12/16/05" +__version__ = "1.0 03/30/04" __bpydoc__ = """\ This script exports animation data to BVH motion capture file format. @@ -30,11 +30,12 @@ Notes:
# BVH Export script 1.0 by Campbell Barton # # Copyright MetaVR 30/03/2004, # # if you have any questions about this script # -# email me cbarton@metavr.com # +# email me ideasman@linuxmail.org # +# # #===============================================# # -------------------------------------------------------------------------- -# BVH Export v1.1 by Campbell Barton (AKA Ideasman) +# BVH Export v0.9 by Campbell Barton (AKA Ideasman) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -45,12 +46,12 @@ Notes:
# # This program is distributed in the hope 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 ***** # -------------------------------------------------------------------------- @@ -58,328 +59,348 @@ Notes:
import Blender from Blender import Scene, Object import math -time = Blender.sys.time from math import * # Get the current scene. scn = Scene.GetCurrent() context = scn.getRenderingContext() -frameRate = 1.0/context.framesPerSec() # 0.04 = 25fps -scale = 1.0 +frameRate = 0.3333 # 0.04 = 25fps +scale = 1 -indent = '\t' # 2 space indent per object +indent = ' ' # 2 space indent per object prefixDelimiter = '_' # Vars used in eular rotation funtcion RAD_TO_DEG = 180.0/3.14159265359 -DEG_TO_RAD = math.pi/180.0 + #====================================================# # Search for children of this object and return them # #====================================================# def getChildren(parent): - children = [] # We'll assume none. - for child in Object.Get(): - if child.parent == parent: - children.append( child ) - return children + children = [] # We'll assume none. + for child in Object.Get(): + if child.getParent() == Object.Get(parent): + children.append( child.getName() ) + return children #====================================================# -# MESSY BUT WORKS: Make a string that shows the # -# hierarchy as a list and then eval it # +# MESSY BUT WORKS: Make a string that shows the # +# hierarchy as a list and then eval it # #====================================================# def getHierarchy(root, hierarchy): - hierarchy = '%s["%s",' % (hierarchy, root.name) - for child in getChildren(root): - hierarchy = getHierarchy(child, hierarchy) - hierarchy = '%s],' % hierarchy - return hierarchy + hierarchy = hierarchy + '["' + root + '",' + for child in getChildren(root): + hierarchy = getHierarchy(child, hierarchy) + hierarchy += '],' + return hierarchy #====================================================# -# Strips the prefix off the name before writing # +# Strips the prefix off the name before writing # #====================================================# def stripName(name): # name is a string - - # WARNING!!! Special case for a custom RIG for output - # for MetaVR's HPX compatable RIG. - # print 'stripname', name[0:10] - if name.lower().startswith('transform('): - name = name[10:].split(prefixDelimiter)[0] - return name.split('_')[0] - + + # WARNING!!! Special case for a custom RIG for output + # for MetaVR's HPX compatable RIG. + print 'stripname', name[0:10] + if name[0:10] == 'Transform(': + name = name[10:] + while name[-1] != ')': + name = name[0:-1] + print name + name = name[:-1] + + + return name[1+name.find(prefixDelimiter): ] + + +#====================================================# +# Return a 6 deciaml point floating point value # +# as a string that dosent have any python chars # +#====================================================# +def saneFloat(float): + #return '%(float)b' % vars() # 6 fp as house.hqx + return str('%f' % float) + ' ' + + #====================================================# # Recieves an object name, gets all the data for that# # node from blender and returns it for formatting # # and writing to a file. # #====================================================# -def getNodeData(nodeOb): - ob = nodeOb - obipo = ob.getIpo() - # Get real location - offset = [o*scale for o in ob.getLocation()] - - #=========================# - # Test for X/Y/Z IPO's # - #=========================# - - # IF we dont have an IPO then dont check the curves. - # This was added to catch end nodes that never have an IPO, only an offset. - - # DUMMY channels xloc, yloc, zloc, xrot, yrot, zrot - # [, , , , , ] - channels = [0,0,0,0,0,0] # xloc,yloc,zloc,xrot,yrot,zrot - if obipo != None: # Do have an IPO, checkout which curves are in use. - # Assume the rot's/loc's dont exist until they proven they do. - if obipo.getCurve('LocX') != None: - channels[0] = 1 - if obipo.getCurve('LocY') != None: - channels[1] = 1 - if obipo.getCurve('LocZ') != None: - channels[2] = 1 - - # Now for the rotations, Because of the conversion of rotation coords - # if there is one rotation er need to store all 3 - if obipo.getCurve('RotX') != None or \ - obipo.getCurve('RotY') != None or \ - obipo.getCurve('RotZ') != None: - channels[3] = channels[4] = channels[5] = 1 - #print ob, channels - return offset, channels +def getNodeData(nodeName): + Object.Get(nodeName) + # Get real location + offset = Object.Get(nodeName).getLocation() + offset = (offset[0]*scale, offset[1]*scale, offset[2]*scale,) + + #=========================# + # Test for X/Y/Z IPO's # + #=========================# + obipo = Object.Get(nodeName).getIpo() + + # IF we dont have an IPO then dont check the curves. + # This was added to catch end nodes that never have an IPO, only an offset. + if obipo == None: + xloc=yloc=zloc=xrot=yrot=zrot = 0 + + else: # Do have an IPO, checkout which curves are in use. + # Assume the rot's/loc's exist until proven they dont + xloc=yloc=zloc=xrot=yrot=zrot = 1 + if obipo.getCurve('LocX') == None: + xloc = 0 + if obipo.getCurve('LocY') == None: + yloc = 0 + if obipo.getCurve('LocZ') == None: + zloc = 0 + + # Now for the rotations, Because of the conversion of rotation coords + # if there is one rotation er need to store all 3 + if obipo.getCurve('RotX') == None and \ + obipo.getCurve('RotY') == None and \ + obipo.getCurve('RotZ') == None: + xrot=yrot=zrot = 0 + + # DUMMY channels xloc, yloc, zloc, xrot, yrot, zrot + # [, , , , , ] + channels = [xloc, yloc, zloc, xrot, yrot, zrot] + + return offset, channels #====================================================# -# Writes the BVH hierarchy to a file # +# Return the BVH hierarchy to a file from a list # # hierarchy: is a list of the empty hierarcht # +# bvhHierarchy: a string, in the bvh format to write # # level: how many levels we are down the tree, # # ...used for indenting # # Also gathers channelList , so we know the order to # -# write the motiondata in # +# write the motiondata in # #====================================================# -def hierarchy2bvh(file, hierarchy, level, channelList, nodeObjectList): - nodeName = hierarchy[0] - ob = Object.Get(nodeName) - ''' - obipo = ob.getIpo() - if obipo != None: - obcurves = obipo.getCurves() - else: - obcurves = None - ''' - #============# - # JOINT NAME # - #============# - file.write(level * indent) - if level == 0: - # Add object to nodeObjectList - #nodeObjectList.append( (ob, obipo, obcurves) ) - nodeObjectList.append( ob ) - file.write( 'ROOT %s\n' % stripName(nodeName) ) - # If this is the last object in the list then we - # dont bother withwriting its real name, use "End Site" instead - elif len(hierarchy) == 1: - file.write( 'End Site\n' ) - # Ok This is a normal joint - else: - # Add object to nodeObjectList - #nodeObjectList.append((ob, obipo, obcurves)) - nodeObjectList.append( ob ) - file.write( 'JOINT %s\n' % stripName(nodeName) ) - #================# - # END JOINT NAME # - #================# - - # Indent again, this line is just for the brackets - file.write( '%s{\n' % (level * indent) ) +def hierarchy2bvh(hierarchy, bvhHierarchy, level, channelList, nodeObjectList): + nodeName = hierarchy[0] + + # Add object to nodeObjectList + nodeObjectList.append(Object.Get(nodeName)) + + #============# + # JOINT NAME # + #============# + bvhHierarchy += level * indent + if level == 0: + # Add object to nodeObjectList + nodeObjectList.append(Object.Get(nodeName)) + bvhHierarchy+= 'ROOT ' + bvhHierarchy += stripName(nodeName) + '\n' + # If this is the last object in the list then we + # dont bother withwriting its real name, use "End Site" instead + elif len(hierarchy) == 1: + bvhHierarchy+= 'End Site\n' + # Ok This is a normal joint + else: + # Add object to nodeObjectList + nodeObjectList.append(Object.Get(nodeName)) + bvhHierarchy+= 'JOINT ' + bvhHierarchy += stripName(nodeName) + '\n' + #================# + # END JOINT NAME # + #================# - # Indent - level += 1 - - #================================================# - # Data for writing to a file offset and channels # - #================================================# - offset, channels = getNodeData(ob) - - #============# - # Offset # - #============# - file.write( '%sOFFSET %.6f %.6f %.6f\n' %\ - (level*indent, scale*offset[0], scale*offset[1], scale*offset[2]) ) - - #============# - # Channels # - #============# - if len(hierarchy) != 1: - # Channels, remember who is where so when we write motiondata - file.write('%sCHANNELS %i ' % (level*indent, len([c for c in channels if c ==1]) )) - if channels[0]: - file.write('Xposition ') - channelList.append([len(nodeObjectList)-1, 0]) - if channels[1]: - file.write('Yposition ') - channelList.append([len(nodeObjectList)-1, 1]) - if channels[2]: - file.write('Zposition ') - channelList.append([len(nodeObjectList)-1, 2]) - if channels[5]: - file.write('Zrotation ') - channelList.append([len(nodeObjectList)-1, 5]) - if channels[3]: - file.write('Xrotation ') - channelList.append([len(nodeObjectList)-1, 3]) - if channels[4]: - file.write('Yrotation ') - channelList.append([len(nodeObjectList)-1, 4]) - file.write('\n') + # Indent again, this line is just for the brackets + bvhHierarchy += level * indent + '{' + '\n' - # Loop through children if any and run this function (recursively) - for hierarchyIdx in range(len(hierarchy)-1): - level = hierarchy2bvh(file, hierarchy[hierarchyIdx+1], level, channelList, nodeObjectList) - # Unindent - level -= 1 - file.write('%s}\n' % (level * indent)) - - return level + # Indent + level += 1 + + #================================================# + # Data for writing to a file offset and channels # + #================================================# + offset, channels = getNodeData(nodeName) + + #============# + # Offset # + #============# + bvhHierarchy += level * indent + 'OFFSET ' + saneFloat(scale * offset[0]) + ' ' + saneFloat(scale * offset[1]) + ' ' + saneFloat(scale * offset[2]) + '\n' + + #============# + # Channels # + #============# + if len(hierarchy) != 1: + # Channels, remember who is where so when we write motiondata + bvhHierarchy += level * indent + 'CHANNELS ' + # Count the channels + chCount = 0 + for chn in channels: + chCount += chn + bvhHierarchy += str(chCount) + ' ' + if channels[0]: + bvhHierarchy += 'Xposition ' + channelList.append([len(nodeObjectList)-1, 0]) + if channels[1]: + bvhHierarchy += 'Yposition ' + channelList.append([len(nodeObjectList)-1, 1]) + if channels[2]: + bvhHierarchy += 'Zposition ' + channelList.append([len(nodeObjectList)-1, 2]) + if channels[5]: + bvhHierarchy += 'Zrotation ' + channelList.append([len(nodeObjectList)-1, 5]) + if channels[3]: + bvhHierarchy += 'Xrotation ' + channelList.append([len(nodeObjectList)-1, 3]) + if channels[4]: + bvhHierarchy += 'Yrotation ' + channelList.append([len(nodeObjectList)-1, 4]) + + bvhHierarchy += '\n' + + # Loop through children if any and run this function (recursively) + for hierarchyIdx in range(len(hierarchy)-1): + bvhHierarchy, level, channelList, nodeObjectList = hierarchy2bvh(hierarchy[hierarchyIdx+1], bvhHierarchy, level, channelList, nodeObjectList) + # Unindent + level -= 1 + bvhHierarchy += level * indent + '}' + '\n' + + return bvhHierarchy, level, channelList, nodeObjectList # added by Ben Batt 30/3/2004 to make the exported rotations correct def ZYXToZXY(x, y, z): - ''' - Converts a set of Euler rotations (x, y, z) (which are intended to be - applied in z, y, x order, into a set which are intended to be applied in - z, x, y order (the order expected by .bvh files) - ''' - A,B = cos(x),sin(x) - C,D = cos(y),sin(y) - E,F = cos(z),sin(z) + ''' + Converts a set of Euler rotations (x, y, z) (which are intended to be + applied in z, y, x order) into a set which are intended to be applied in + z, x, y order (the order expected by .bvh files) + ''' + A,B = cos(x),sin(x) + C,D = cos(y),sin(y) + E,F = cos(z),sin(z) - x = asin(-B*C) - y = atan2(D, A*C) - z = atan2(-B*D*E + A*F, B*D*F + A*E) + x = asin(-B*C) + y = atan2(D, A*C) + z = atan2(-B*D*E + A*F, B*D*F + A*E) - # this seems to be necessary - not sure why (right/left-handed coordinates?) - # x = -x # x is negative, see below. - return -x*RAD_TO_DEG, y*RAD_TO_DEG, z*RAD_TO_DEG + # this seems to be necessary - not sure why (right/left-handed coordinates?) + x = -x + return x*RAD_TO_DEG, y*RAD_TO_DEG, z*RAD_TO_DEG -''' # UNUSED, JUST GET OBJECT LOC/ROT -def getIpoLocation(object, obipo, curves, frame): - x = y = z = rx = ry = rz =0 - if obipo: - for i in range(obipo.getNcurves()): - if curves[i].getName() =='LocX': - x = obipo.EvaluateCurveOn(i,frame) - elif curves[i].getName() =='LocY': - y = obipo.EvaluateCurveOn(i,frame) - elif curves[i].getName() =='LocZ': - z = obipo.EvaluateCurveOn(i,frame) - elif curves[i].getName() =='RotX': - rx = obipo.EvaluateCurveOn(i,frame) - elif curves[i].getName() =='RotY': - ry = obipo.EvaluateCurveOn(i,frame) - elif curves[i].getName() =='RotZ': - rz = obipo.EvaluateCurveOn(i,frame) - return x, y, z, rx*10*DEG_TO_RAD, ry*10*DEG_TO_RAD, rz*10*DEG_TO_RAD -''' + +def getIpoLocation(object, frame): + x = y = z = 0 + obipo = object.getIpo() + for i in range(object.getIpo().getNcurves()): + if obipo.getCurves()[i].getName() =='LocX': + x = object.getIpo().EvaluateCurveOn(i,frame) + elif obipo.getCurves()[i].getName() =='LocY': + y = object.getIpo().EvaluateCurveOn(i,frame) + elif obipo.getCurves()[i].getName() =='LocZ': + z = object.getIpo().EvaluateCurveOn(i,frame) + return x, y, z + #====================================================# # Return the BVH motion for the spesified frame # # hierarchy: is a list of the empty hierarcht # +# bvhHierarchy: a string, in the bvh format to write # # level: how many levels we are down the tree, # # ...used for indenting # #====================================================# -def motion2bvh(file, frame, chennelList, nodeObjectList): - for chIdx in chennelList: - #ob, obipo, obcurves = nodeObjectList[chIdx[0]] - ob = nodeObjectList[chIdx[0]] - chType = chIdx[1] - - # Get object rotation - x, y, z = ob.getEuler() - - # Convert the rotation from ZYX order to ZXY order - x, y, z = ZYXToZXY(x, y, z) - - # Location - xloc, yloc, zloc = ob.matrixLocal[3][:3] - - # Using regular Locations stuffs upIPO locations stuffs up - # Get IPO locations instead - #xloc, yloc, zloc, x, y, z = getIpoLocation(ob, obipo, obcurves, frame) - # Convert the rotation from ZYX order to ZXY order - #x, y, z = ZYXToZXY(x, y, z) - - - # WARNING non standard Location - # xloc, zloc, yloc = -xloc, yloc, zloc - - if chType == 0: - file.write('%.6f ' % (scale * xloc)) - if chType == 1: - file.write('%.6f ' % (scale * yloc)) - if chType == 2: - file.write('%.6f ' % (scale * zloc)) - if chType == 3: - file.write('%.6f ' % x) - if chType == 4: - file.write('%.6f ' % y) - if chType == 5: - file.write('%.6f ' % z) - file.write('\n') - +def motion2bvh(frame, chennelList, nodeObjectList): + + motionData = '' # We'll append the frames to the string. + + for chIdx in chennelList: + ob = nodeObjectList[chIdx[0]] + chType = chIdx[1] + + # Get object rotation + x, y, z = ob.getEuler() + + # Convert the rotation from ZYX order to ZXY order + x, y, z = ZYXToZXY(x, y, z) + + + # Using regular Locations stuffs upIPO locations stuffs up + # Get IPO locations instead + xloc, yloc, zloc = getIpoLocation(ob, frame) + + # WARNING non standard Location + xloc, zloc, yloc = -xloc, yloc, zloc + + + if chType == 0: + motionData += saneFloat(scale * (xloc)) + if chType == 1: + motionData += saneFloat(scale * (yloc)) + if chType == 2: + motionData += saneFloat(scale * (zloc)) + if chType == 3: + motionData += saneFloat(x) + if chType == 4: + motionData += saneFloat(y) + if chType == 5: + motionData += saneFloat(z) + + motionData += ' ' + + motionData += '\n' + return motionData def saveBVH(filename): - t = time() - if not filename.lower().endswith('.bvh'): - filename += '.bvh' # for safety - - # Here we store a serialized list of blender objects as they appier - # in the hierarchy, this is refred to when writing motiondata - nodeObjectList = [] - - # In this list we store a 2 values for each node - # 1) An index pointing to a blender object - # in objectList - # 2) The type if channel x/y/z rot:x/y/z - Use 0-5 to indicate this - chennelList = [] - - print '\nBVH 1.1 by Campbell Barton (Ideasman) - cbarton@metavr.com' - - # Get the active object and recursively traverse its kids to build - # the BVH hierarchy, then eval the string to make a hierarchy list. - hierarchy = eval(getHierarchy(scn.getActiveObject(),''))[0] # somhow this returns a tuple with one list in it. - - # Put all data in the file we have selected file. - file = open(filename, "w") - file.write('HIERARCHY\n') # all bvh files have this on the first line - - # Write the whole hirarchy to a list - level = 0 # Indenting level, start with no indent - level = hierarchy2bvh(file, hierarchy, level, chennelList, nodeObjectList) - - #====================================================# - # MOTION: Loop through the frames ande write out # - # the motion data for each # - #====================================================# - # Do some basic motion file header stuff - file.write( 'MOTION\n' ) - file.write( 'Frames: %i\n' % ( 1 + context.endFrame() - context.startFrame() ) ) - file.write( 'Frame Time: %.6f\n' % frameRate ) - - frames = range(context.startFrame()+1, context.endFrame()+1) - print 'exporting %i of motion...' % len(frames) - - for frame in frames: - context.currentFrame(frame) - scn.update(1) # Update locations so we can write the new locations. This is the SLOW part. - # Blender.Window.RedrawAll() # Debugging. - - motion2bvh(file, frame, chennelList, nodeObjectList) # Write the motion to a file. - - file.write('\n') # newline - file.close() - print '...Done in %.4f seconds.' % (time()-t) - + + if filename.find('.bvh', -4) <= 0: filename += '.bvh' # for safety + + # Here we store a serialized list of blender objects as they appier + # in the hierarchy, this is refred to when writing motiondata + nodeObjectList = [] + + # In this list we store a 2 values for each node + # 1) An index pointing to a blender object + # in objectList + # 2) The type if channel x/y/z rot:x/y/z - Use 0-5 to indicate this + chennelList = [] + + print '' + print 'BVH 1.0 by Campbell Barton (Ideasman) - ideasman@linuxmail.org' + + # Get the active object and recursively traverse its kids to build + # the BVH hierarchy, then eval the string to make a hierarchy list. + hierarchy = eval(getHierarchy(Object.GetSelected()[0].getName(),''))[0] # somhow this returns a tuple with one list in it. + + # Put all data in the file we have selected file. + file = open(filename, "w") + file.write('HIERARCHY\n') # all bvh files have this on the first line + + # Write the whole hirarchy to a list + bvhHierarchy, level, chennelList, nodeObjectList = hierarchy2bvh(hierarchy, '', 0, chennelList, nodeObjectList) + file.write( bvhHierarchy ) # Rwite the var fileBlock to the output. + bvhHierarchy = None # Save a tit bit of memory + + #====================================================# + # MOTION: Loop through the frames ande write out # + # the motion data for each # + #====================================================# + # Do some basic motion file header stuff + file.write('MOTION\n') + file.write( 'Frames: ' + str(1 + context.endFrame() - context.startFrame()) + '\n' ) + file.write( 'Frame Time: ' + saneFloat(frameRate) + '\n' ) + + #print 'WARNING- exact frames might be stuffed up- inclusive whatever, do some tests later on.' + frames = range(context.startFrame(), context.endFrame()+1) + print 'exporting ' + str(len(frames)) + ' of motion...' + + for frame in frames: + context.currentFrame(frame) + scn.update(1) # Update locations so we can write the new locations + #Blender.Window.RedrawAll() # causes crash + + file.write( motion2bvh(frame, chennelList, nodeObjectList) ) + + file.write('\n') # newline + file.close() + print 'done' + Blender.Window.FileSelector(saveBVH, 'Export BVH') diff --git a/release/scripts/bvh_import.py b/release/scripts/bvh_import.py index 05f40f018dc..17ce01c0cab 100644 --- a/release/scripts/bvh_import.py +++ b/release/scripts/bvh_import.py @@ -2,14 +2,14 @@ """ Name: 'Motion Capture (.bvh)...' -Blender: 239 +Blender: 236 Group: 'Import' Tip: 'Import a (.bvh) motion capture file' """ __author__ = "Campbell Barton" -__url__ = ("blender", "elysiun") -__version__ = "1.0.4 05/12/04" +__url__ = ("blender", "elysiun", "http://jmsoler.free.fr/util/blenderfile/py/bvh_import.py") +__version__ = "1.0.2 04/12/28" __bpydoc__ = """\ This script imports BVH motion capture data to Blender. @@ -21,52 +21,32 @@ Missing:
Known issues:
Notes:
- Jean-Michel Soler improved importer to support Poser 3.01 files;
- Jean-Baptiste Perin wrote a script to create an armature out of the + Jean-Michel Soler improved importer to support Poser 3.01 files;
+ Jean-Baptiste Perin wrote a script to create an armature out of the Empties created by this importer, it's in the Scripts window -> Scripts -> Animation menu. """ # $Id$ # -#===============================================# -# BVH Import script 1.05 patched by Campbell # -# Modified to use Mathutils for matrix math, # -# Fixed possible joint naming bug, # -# Imports BVH's with bad EOF gracefully # -# Fixed duplicate joint names, make them unique # -# Use \r as well as \n for newlines # -# Added suppot for nodes with 0 motion channels # -# Rotation IPOs never cross more then 180d # -# fixes sub frame tweening and time scaling # -# 5x overall speedup. # -# 06/12/2005, # -#===============================================# - -#===============================================# -# BVH Import script 1.04 patched by jms # -# Small modif for blender 2.40 # -# 04/12/2005, # -#===============================================# - #===============================================# # BVH Import script 1.03 patched by Campbell # # Small optimizations and scale input # -# 01/01/2005, # +# 01/01/2005, # #===============================================# #===============================================# # BVH Import script 1.02 patched by Jm Soler # -# to the Poser 3.01 bvh file # -# 28/12/2004, # +# to the Poser 3.01 bvh file # +# 28/12/2004, # #===============================================# #===============================================# # BVH Import script 1.0 by Campbell Barton # # 25/03/2004, euler rotation code taken from # # Reevan Mckay's BVH import script v1.1 # -# if you have any questions about this scrip. # -# email me cbarton@metavr.com # +# if you have any questions about this script # +# email me ideasman@linuxmail.org # #===============================================# #===============================================# @@ -77,7 +57,7 @@ Empties created by this importer, it's in the Scripts window -> Scripts -> Anima #===============================================# # -------------------------------------------------------------------------- -# BVH Import v1.05 by Campbell Barton (AKA Ideasman) +# BVH Import v0.9 by Campbell Barton (AKA Ideasman) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -88,410 +68,457 @@ Empties created by this importer, it's in the Scripts window -> Scripts -> Anima # # This program is distributed in the hope 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 string +import math import Blender from Blender import Window, Object, Scene, Ipo, Draw from Blender.Scene import Render -# Attempt to load psyco, speed things up -try: - import psyco - psyco.full() - print 'using psyco to speed up BVH importing' -except: - #print 'psyco is not present on this system' - pass +# # PSYCO IS CRASHING ON MY SYSTEM +# # Attempt to load psyco, speed things up +# try: +# print 'using psyco to speed up BVH importing' +# import psyco +# psyco.full() +# +# except: +# print 'psyco is not present on this system' + +# Default scale +scale = 0.01 + +# Update as we load? +debug = 0 + +# Get the current scene. +scn = Scene.GetCurrent() +context = scn.getRenderingContext() + +# Here we store the Ipo curves in the order they load. +channelCurves = [] + +# Object list +# We need this so we can loop through the objects and edit there IPO's +# Chenging there rotation to EULER rotation +objectList = [] + +def getScale(): + return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3) + +def MAT(m): + if len(m) == 3: + return Blender.Mathutils.Matrix(m[0], m[1], m[2]) + elif len(m) == 4: + return Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3]) -def main(): - global scale - scale = None - - # Update as we load? - debug = 0 - - def getScale(): - return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3) - - - #===============================================# - # MAIN FUNCTION - All things are done from here # - #===============================================# - def loadBVH(filename): - global scale - print '\nBVH Importer 1.05 by Campbell Barton (Ideasman) - cbarton@metavr.com' - - objectCurveMapping = {} - objectNameMapping = {} - objectMotiondataMapping = {} - - # Here we store the Ipo curves in the order they load. - channelCurves = [] - - # Object list - # We need this so we can loop through the objects and edit there IPO's - # Chenging there rotation to EULER rotation - objectList = [] - - if scale == None: - tempscale = getScale() - if tempscale: - scale = tempscale - else: - scale = 0.01 - - Window.WaitCursor(1) - # Unique names, dont reuse any of these names. - uniqueObNames = [ob.name for ob in Object.Get()] - - - # FUNCTIONS ====================================# - def getUniqueObName(name): - i = 0 - newname = name[:min(len(name), 12)] # Concatinate to 12 chars - while newname in uniqueObNames: - newname = name + str(i) - i+=1 - return newname - - # Change the order rotation is applied. - RotationMatrix = Blender.Mathutils.RotationMatrix - MATRIX_IDENTITY_3x3 = Blender.Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]) - def eulerRotate(x,y,z): - x,y,z = x%360,y%360,z%360 # Clamp all values between 0 and 360, values outside this raise an error. - xmat = RotationMatrix(x,3,'x') - ymat = RotationMatrix(y,3,'y') - zmat = RotationMatrix(z,3,'z') - # Standard BVH multiplication order, apply the rotation in the order Z,X,Y - return (ymat*(xmat * (zmat * MATRIX_IDENTITY_3x3))).toEuler() - +#===============================================# +# eulerRotation: converts X, Y, Z rotation # +# to eular Rotation. This entire function # +# is copied from Reevan Mckay's BVH script # +#===============================================# +# Vars used in eular rotation funtcion +DEG_TO_RAD = math.pi/180.0 +RAD_TO_DEG = 180.0/math.pi +PI=3.14159 - currentFrame = 1 # Set the initial frame to import all data to. - - #===============================================# - # makeJoint: Here we use the node data # - # from the BVA file to create an empty # - #===============================================# - BVH2BLEND_TX_NAME = {'Xposition':'LocX','Yposition':'LocY','Zposition':'LocZ','Xrotation':'RotX','Yrotation':'RotY','Zrotation':'RotZ'} - def makeJoint(name, parent, offset, channels): - ob = Object.New('Empty', name) # New object, ob is shorter and nicer to use. - - objectNameMapping[name] = ob - scn.link(ob) # place the object in the current scene - ob.sel = 1 - - # Make me a child of another empty. - # Vale of None will make the empty a root node (no parent) - if parent[-1]: # != None - obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here. - obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast. - - # Offset Empty from BVH's initial joint location. - ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) - - # Add Ipo's for necessary channels - newIpo = Ipo.New('Object', name) - ob.setIpo(newIpo) - obname = ob.name - for channelType in channels: - channelType = BVH2BLEND_TX_NAME[channelType] - curve = newIpo.addCurve(channelType) - curve.setInterpolation('Linear') - objectCurveMapping[(obname, channelType)] = curve - - # Add to object list - objectList.append(ob) - - # Redraw if debugging - if debug: Blender.Redraw() - - - #===============================================# - # makeEnd: Here we make an end node # - # This is needed when adding the last bone # - #===============================================# - def makeEnd(parent, offset): - new_name = parent[-1] + '_end' - ob = Object.New('Empty', new_name) # New object, ob is shorter and nicer to use. - objectNameMapping[new_name] = ob - scn.link(ob) - ob.sel = 1 - - # Dont check for a parent, an end node MUST have a parent - obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here. - obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast. - - # Offset Empty - ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) - - # Redraw if debugging - if debug: Blender.Redraw() - # END FUNCTION DEFINITIONS ====================================# - - - - - time1 = Blender.sys.time() - - # Get the current scene. - scn = Scene.GetCurrent() - #context = scn.getRenderingContext() - - # DeSelect All - for ob in scn.getChildren(): - ob.sel = 0 - - # File loading stuff - # Open the file for importing - file = open(filename, 'r') - - # Seperate into a list of lists, each line a list of words. - lines = file.readlines() - # Non standard carrage returns? - if len(lines) == 1: - lines = lines[0].split('\r') - - # Split by whitespace. - lines =[ll for ll in [ [w for w in l.split() if w != '\n' ] for l in lines] if ll] - # End file loading code - - - - # Create Hirachy as empties - if lines[0][0] == 'HIERARCHY': - print 'Importing the BVH Hierarchy for:', filename - else: - return 'ERROR: This is not a BVH file' - - # A liniar list of ancestors to keep track of a single objects heratage - # at any one time, this is appended and removed, dosent store tree- just a liniar list. - # ZERO is a place holder that means we are a root node. (no parents) - parent = [None] - - #channelList, sync with objectList: [[channelType1, channelType2...], [channelType1, channelType2...)] - channelList = [] - channelIndex = -1 - - lineIdx = 0 # An index for the file. - while lineIdx < len(lines) -1: - #... - if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT': - - # Join spaces into 1 word with underscores joining it. - if len(lines[lineIdx]) > 2: - lines[lineIdx][1] = '_'.join(lines[lineIdx][1:]) - lines[lineIdx] = 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 = getUniqueObName(lines[lineIdx][1]) - uniqueObNames.append(name) - - print '%snode: %s, parent: %s' % (len(parent) * ' ', name, parent[-1]) - - lineIdx += 2 # Incriment to the next line (Offset) - offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(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. - newChannel = [-1, -1, -1, -1, -1, -1] - for channel in lines[lineIdx][2:]: - channelIndex += 1 # So the index points to the right channel - if channel == 'Xposition': - newChannel[0] = channelIndex - elif channel == 'Yposition': - newChannel[1] = channelIndex - elif channel == 'Zposition': - newChannel[2] = channelIndex - elif channel == 'Xrotation': - newChannel[3] = channelIndex - elif channel == 'Yrotation': - newChannel[4] = channelIndex - elif channel == 'Zrotation': - newChannel[5] = channelIndex - - channelList.append(newChannel) - - channels = lines[lineIdx][2:] - - # Call funtion that uses the gatrhered data to make an empty. - makeJoint(name, parent, offset, channels) - - # If we have another child then we can call ourselves a parent, else - parent.append(name) - - # Account for an end node - if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name after 'End Site' but we will ignore it. - lineIdx += 2 # Incriment to the next line (Offset) - offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) ) - makeEnd(parent, offset) - - # Just so we can remove the Parents in a uniform way- End end never has kids - # so this is a placeholder - parent.append(None) - - if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == '}': # == ['}'] - parent.pop() # Remove the last item - - #=============================================# - # BVH Structure loaded, Now import motion # - #=============================================# - if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == 'MOTION': - print '\nImporting motion data' - lineIdx += 3 # Set the cursor to the first frame - - #=============================================# - # Add a ZERO keyframe, this keeps the rig # - # so when we export we know where all the # - # joints start from # - #=============================================# - - for obIdx, ob in enumerate(objectList): - obname = ob.name - if channelList[obIdx][0] != -1: - objectCurveMapping[obname, 'LocX'].addBezier((currentFrame,0)) - objectMotiondataMapping[obname, 'LocX'] = [] - if channelList[obIdx][1] != -1: - objectCurveMapping[obname, 'LocY'].addBezier((currentFrame,0)) - objectMotiondataMapping[obname, 'LocY'] = [] - if channelList[obIdx][2] != -1: - objectCurveMapping[obname, 'LocZ'].addBezier((currentFrame,0)) - objectMotiondataMapping[obname, 'LocZ'] = [] - if\ - channelList[obIdx][3] != -1 or\ - channelList[obIdx][4] != -1 or\ - channelList[obIdx][5] != -1: - objectMotiondataMapping[obname, 'RotX'] = [] - objectMotiondataMapping[obname, 'RotY'] = [] - objectMotiondataMapping[obname, 'RotZ'] = [] - - #=============================================# - # Loop through frames, each line a frame # - #=============================================# - MOTION_DATA_LINE_LEN = len(lines[lineIdx]) - while lineIdx < len(lines): - line = lines[lineIdx] - if MOTION_DATA_LINE_LEN != len(line): - print 'ERROR: Incomplete motion data on line %i, finishing import.' % lineIdx - break - - # Exit loop if we are past the motiondata. - # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS' - # I dont know what they do and I dont care, they'll be ignored here. - if len(line) < len(objectList): - print '...ending on unknown tags' - break - - - currentFrame += 1 # Incriment to next frame - - #=============================================# - # Import motion data and assign it to an IPO # - #=============================================# - line.append(0.0) # Use this as a dummy var for objects that dont have a loc/rotate channel. - - if debug: Blender.Redraw() - for obIdx, ob in enumerate(objectList): - obname = ob.name - obChannel = channelList[obIdx] - if channelList[obIdx][0] != -1: - objectMotiondataMapping[obname, 'LocX'].append((currentFrame, scale * float( line[obChannel[0]] ))) - - if channelList[obIdx][1] != -1: - objectMotiondataMapping[obname, 'LocY'].append((currentFrame, scale * float( line[obChannel[1]] ))) +def eulerRotate(x,y,z): + #================================= + def RVMatMult3 (mat1,mat2): + #================================= + mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]] + for i in range(3): + for k in range(3): + for j in range(3): + mat3[i][k]=mat3[i][k]+mat1[i][j]*mat2[j][k] + return mat3 + + + #================================= + def RVAxisAngleToMat3 (rot4): + # Takes a direction vector and + # a rotation (in rads) and + # returns the rotation matrix. + # Graphics Gems I p. 466: + #================================= + mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]] + if math.fabs(rot4[3])>0.01: + s=math.sin(rot4[3]) + c=math.cos(rot4[3]) + t=1.0-math.cos(rot4[3]) + else: + s=rot4[3] + c=1.0 + t=0.0 - if channelList[obIdx][2] != -1: - objectMotiondataMapping[obname, 'LocZ'].append((currentFrame, scale * float( line[obChannel[2]] ))) - - if obChannel[3] != -1 or obChannel[4] != -1 or obChannel[5] != -1: - x, y, z = eulerRotate(float( line[obChannel[3]] ), float( line[obChannel[4]] ), float( line[obChannel[5]] )) - x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d - motionMappingRotX = objectMotiondataMapping[obname, 'RotX'] - motionMappingRotY = objectMotiondataMapping[obname, 'RotY'] - motionMappingRotZ = objectMotiondataMapping[obname, 'RotZ'] - - # 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. - if len(motionMappingRotX) > 1: - while (motionMappingRotX[-1][1] - x) > 18: x+=36 - while (motionMappingRotX[-1][1] - x) < -18: x-=36 - - while (motionMappingRotY[-1][1] - y) > 18: y+=36 - while (motionMappingRotY[-1][1] - y) < -18: y-=36 - - while (motionMappingRotZ[-1][1] - z) > 18: z+=36 - while (motionMappingRotZ[-1][1] - z) < -18: z-=36 - - motionMappingRotX.append((currentFrame, x)) - motionMappingRotY.append((currentFrame, y)) - motionMappingRotZ.append((currentFrame, z)) - # Done importing motion data # - - lineIdx += 1 - - #=======================================# - # Now Write the motion to the IPO's # - #=======================================# - for key, motion_data in objectMotiondataMapping.iteritems(): - - # Strip the motion data where all the points have the same falue. - i = len(motion_data) -2 - while i > 0 and len(motion_data) > 2: - if motion_data[i][1] == motion_data[i-1][1] == motion_data[i+1][1]: - motion_data.pop(i) - i-=1 - # Done stripping. - - obname, tx_type = key - curve = objectCurveMapping[obname, tx_type] - for point_data in motion_data: - curve.addBezier( point_data ) - # Imported motion to an IPO - - # No point in looking further, when this loop is done - # There is nothine else left to do - break - - # Main file loop - lineIdx += 1 - - print 'bvh import time for %i frames: %.6f' % (currentFrame, Blender.sys.time() - time1) - Window.RedrawAll() - Window.WaitCursor(0) - - Blender.Window.FileSelector(loadBVH, "Import BVH") - - #=============# - # TESTING # - #=============# - ''' - #loadBVH('/metavr/mocap/bvh/boxer.bvh') - #loadBVH('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF - #loadBVH('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings. - #loadBVH('/metavr/mocap/bvh/walk4.bvh') # 0 channels - scale = 0.01 - import os - DIR = '/metavr/mocap/bvh/' - for f in os.listdir(DIR): - if f.endswith('.bvh'): - s = Scene.New(f) - s.makeCurrent() - loadBVH(DIR + f) - ''' -if __name__ == '__main__': - main() \ No newline at end of file + x=rot4[0]; y=rot4[1]; z=rot4[2] + + mat3[0][0]=t*x*x+c + mat3[0][1]=t*x*y+s*z + mat3[0][2]=t*x*z-s*y + + mat3[1][0]=t*x*y-s*z + mat3[1][1]=t*y*y+c + mat3[1][2]=t*y*z+s*x + + mat3[2][0]=t*x*z+s*y + mat3[2][1]=t*y*z-s*x + mat3[2][2]=t*z*z+c + + return mat3 + + eul = [x,y,z] + + for jj in range(3): + while eul[jj] < 0: + eul[jj] = eul[jj] + 360.0 + while eul[jj] >= 360.0: + eul[jj] = eul[jj] - 360.0 + + eul[0] = eul[0]*DEG_TO_RAD + eul[1] = eul[1]*DEG_TO_RAD + eul[2] = eul[2]*DEG_TO_RAD + + xmat=RVAxisAngleToMat3([1,0,0,eul[0]]) + ymat=RVAxisAngleToMat3([0,1,0,eul[1]]) + zmat=RVAxisAngleToMat3([0,0,1,eul[2]]) + + mat=[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]] + + # Standard BVH multiplication order + mat=RVMatMult3 (zmat,mat) + mat=RVMatMult3 (xmat,mat) + mat=RVMatMult3 (ymat,mat) + + + ''' + # Screwy Animation Master BVH multiplcation order + mat=RVMatMult3 (ymat,mat) + mat=RVMatMult3 (xmat,mat) + mat=RVMatMult3 (zmat,mat) + ''' + mat = MAT(mat) + + eul = mat.toEuler() + x =- eul[0]/-10 + y =- eul[1]/-10 + z =- eul[2]/-10 + + return x, y, z # Returm euler roration values. + + + +#===============================================# +# makeJoint: Here we use the node data # +# from the BVA file to create an empty # +#===============================================# +def makeJoint(name, parent, prefix, offset, channels): + global scale + # Make Empty, with the prefix in front of the name + ob = Object.New('Empty', prefix + name) # New object, ob is shorter and nicer to use. + scn.link(ob) # place the object in the current scene + + # Offset Empty + ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) + + # Make me a child of another empty. + # Vale of None will make the empty a root node (no parent) + if parent[-1] != None: + obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here. + obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast. + + # Add Ipo's for necessary channels + newIpo = Ipo.New('Object', prefix + name) + ob.setIpo(newIpo) + for channelType in channels: + if channelType == 'Xposition': + newIpo.addCurve('LocX') + newIpo.getCurve('LocX').setInterpolation('Linear') + if channelType == 'Yposition': + newIpo.addCurve('LocY') + newIpo.getCurve('LocY').setInterpolation('Linear') + if channelType == 'Zposition': + newIpo.addCurve('LocZ') + newIpo.getCurve('LocZ').setInterpolation('Linear') + + if channelType == 'Zrotation': + newIpo.addCurve('RotZ') + newIpo.getCurve('RotZ').setInterpolation('Linear') + if channelType == 'Yrotation': + newIpo.addCurve('RotY') + newIpo.getCurve('RotY').setInterpolation('Linear') + if channelType == 'Xrotation': + newIpo.addCurve('RotX') + newIpo.getCurve('RotX').setInterpolation('Linear') + + # Add to object list + objectList.append(ob) + + # Redraw if debugging + if debug: Blender.Redraw() + + +#===============================================# +# makeEnd: Here we make an end node # +# This is needed when adding the last bone # +#===============================================# +def makeEnd(parent, prefix, offset): + # Make Empty, with the prefix in front of the name, end nodes have no name so call it its parents name+'_end' + ob = Object.New('Empty', prefix + parent[-1] + '_end') # New object, ob is shorter and nicer to use. + scn.link(ob) + + # Dont check for a parent, an end node MUST have a parent + obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here. + obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast. + + # Offset Empty + ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) + + # Redraw if debugging + if debug: Blender.Redraw() + + + + +#===============================================# +# MAIN FUNCTION - All things are done from here # +#===============================================# +def loadBVH(filename): + global scale + print '' + print 'BVH Importer 1.0 by Campbell Barton (Ideasman) - ideasman@linuxmail.org' + alpha='abcdefghijklmnopqrstuvewxyz' + ALPHA=alpha+alpha.upper() + ALPHA+=' 0123456789+-{}. ' + time1 = Blender.sys.time() + tmpScale = getScale() + if tmpScale != None: + scale = tmpScale + + # File loading stuff + # Open the file for importing + file = open(filename, 'r') + fileData = file.readlines() + # Make a list of lines + lines = [] + for fileLine in fileData: + fileLine=fileLine.replace('..','.') + newLine = string.split(fileLine) + if newLine != []: + t=[] + for n in newLine: + for n0 in n: + if n0 not in ALPHA: + n=n.replace(n0,'') + t.append(n) + lines.append(t) + + + del fileData + # End file loading code + + # Call object names with this prefix, mainly for scenes with multiple BVH's - Can imagine most partr names are the same + # So in future + #prefix = str(len(lines)) + '_' + + prefix = '_' + + # Create Hirachy as empties + if lines[0][0] == 'HIERARCHY': + print 'Importing the BVH Hierarchy for:', filename + else: + return 'ERROR: This is not a BVH file' + + # A liniar list of ancestors to keep track of a single objects heratage + # at any one time, this is appended and removed, dosent store tree- just a liniar list. + # ZERO is a place holder that means we are a root node. (no parents) + parent = [None] + + #channelList [(, [channelType1, channelType2...]), (, [channelType1, channelType2...)] + channelList = [] + channelIndex = -1 + + + + lineIdx = 1 # An index for the file. + while lineIdx < len(lines) -1: + #... + if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT': + if lines[lineIdx][0] == 'JOINT' and len(lines[lineIdx])>2: + for j in range(2,len(lines[lineIdx])) : + lines[lineIdx][1]+='_'+lines[lineIdx][j] + + # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.?? + + print len(parent) * ' ' + 'node:',lines[lineIdx][1],' parent:',parent[-1] + print lineIdx + name = lines[lineIdx][1] + print name,lines[lineIdx+1],lines[lineIdx+2] + lineIdx += 2 # Incriment to the next line (Offset) + offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) ) + lineIdx += 1 # Incriment to the next line (Channels) + + # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation] + # newChannel has Indecies to the motiondata, + # -1 refers to the last value that will be added on loading at a value of zero + # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value. + newChannel = [-1, -1, -1, -1, -1, -1] + for channel in lines[lineIdx][2:]: + channelIndex += 1 # So the index points to the right channel + if channel == 'Xposition': + newChannel[0] = channelIndex + elif channel == 'Yposition': + newChannel[1] = channelIndex + elif channel == 'Zposition': + newChannel[2] = channelIndex + elif channel == 'Xrotation': + newChannel[3] = channelIndex + elif channel == 'Yrotation': + newChannel[4] = channelIndex + elif channel == 'Zrotation': + newChannel[5] = channelIndex + + channelList.append(newChannel) + + channels = lines[lineIdx][2:] + + # Call funtion that uses the gatrhered data to make an empty. + makeJoint(name, parent, prefix, offset, channels) + + # If we have another child then we can call ourselves a parent, else + parent.append(name) + + # Account for an end node + if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name afetr 'End Site' but we will ignore it. + lineIdx += 2 # Incriment to the next line (Offset) + offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) ) + makeEnd(parent, prefix, offset) + + # Just so we can remove the Parents in a uniform way- End end never has kids + # so this is a placeholder + parent.append(None) + + if lines[lineIdx] == ['}']: + parent = parent[:-1] # Remove the last item + + + #=============================================# + # BVH Structure loaded, Now import motion # + #=============================================# + if lines[lineIdx] == ['MOTION']: + print '\nImporting motion data' + lineIdx += 3 # Set the cursor to the forst frame + + #=============================================# + # Loop through frames, each line a frame # + #=============================================# + currentFrame = 1 + print 'frames: ', + + + #=============================================# + # Add a ZERO keyframe, this keeps the rig # + # so when we export we know where all the # + # joints start from # + #=============================================# + obIdx = 0 + while obIdx < len(objectList) -1: + if channelList[obIdx][0] != -1: + objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame,0)) + if channelList[obIdx][1] != -1: + objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame,0)) + if channelList[obIdx][2] != -1: + objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame,0)) + if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1': + objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame,0)) + objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame,0)) + objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame,0)) + obIdx += 1 + + while lineIdx < len(lines): + + # Exit loop if we are past the motiondata. + # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS' + # I dont know what they do and I dont care, they'll be ignored here. + if len(lines[lineIdx]) < len(objectList): + print '...ending on unknown tags' + break + + + currentFrame += 1 # Incriment to next frame + + #=============================================# + # Import motion data and assign it to an IPO # + #=============================================# + lines[lineIdx].append('0') # Use this as a dummy var for objects that dont have a rotate channel. + obIdx = 0 + if debug: Blender.Redraw() + while obIdx < len(objectList) -1: + if channelList[obIdx][0] != -1: + VAL0=lines[lineIdx][channelList[obIdx][0]] + if VAL0.find('.')==-1: + VAL0=VAL0[:len(VAL0)-6]+'.'+VAL0[-6:] + objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame, scale * float(VAL0))) + + if channelList[obIdx][1] != -1: + VAL1=lines[lineIdx][channelList[obIdx][1]] + if VAL1.find('.')==-1: + VAL1=VAL1[:len(VAL1)-6]+'.'+VAL1[-6:] + objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame, scale * float(VAL1))) + + if channelList[obIdx][2] != -1: + VAL2=lines[lineIdx][channelList[obIdx][2]] + if VAL2.find('.')==-1: + VAL2=VAL2[:len(VAL2)-6]+'.'+VAL2[-6:] + objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame, scale * float(VAL2))) + + if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1': + VAL3=lines[lineIdx][channelList[obIdx][3]] + if VAL3.find('.')==-1: + VAL3=VAL3[:len(VAL3)-6]+'.'+VAL3[-6:] + + VAL4=lines[lineIdx][channelList[obIdx][4]] + if VAL4.find('.')==-1: + VAL4=VAL4[:len(VAL4)-6]+'.'+VAL4[-6:] + + VAL5=lines[lineIdx][channelList[obIdx][5]] + if VAL5.find('.')==-1: + VAL5=VAL5[:len(VAL5)-6]+'.'+VAL5[-6:] + + x, y, z = eulerRotate(float(VAL3), float(VAL4), float(VAL5)) + + objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame, x)) + objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame, y)) + objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame, z)) + + obIdx += 1 + # Done importing motion data # + + # lines[lineIdx] = None # Scrap old motion data, save some memory? + lineIdx += 1 + # We have finished now + print currentFrame, 'done.' + + # No point in looking further, when this loop is done + # There is nothine else left to do + print 'Imported ', currentFrame, ' frames' + break + + # Main file loop + lineIdx += 1 + print "bvh import time: ", Blender.sys.time() - time1 + +Blender.Window.FileSelector(loadBVH, "Import BVH") diff --git a/release/scripts/clean_mesh.py b/release/scripts/clean_mesh.py new file mode 100644 index 00000000000..d7e20daa27f --- /dev/null +++ b/release/scripts/clean_mesh.py @@ -0,0 +1,213 @@ +#!BPY + +""" +Name: 'Clean Mesh' +Blender: 234 +Group: 'Mesh' +Tooltip: 'Clean unused data from all selected meshes' +""" + +__author__ = "Campbell Barton" +__url__ = ("blender", "elysiun") +__version__ = "1.1 04/25/04" + +__bpydoc__ = """\ +This script cleans specific data from all selected meshes. + +Usage: + +Select the meshes to be cleaned and run this script. A pop-up will ask +you what you want to remove: + +- Free standing vertices;
+- Edges that are not part of any face;
+- Edges below a threshold length;
+- Faces below a threshold area;
+- All of the above. + +After choosing one of the above alternatives, if your choice requires a +threshold value you'll be prompted with a number pop-up to set it. +""" + + +# $Id$ +# +# -------------------------------------------------------------------------- +# Mesh Cleaner 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 2004/04/25 - ideasman@linuxmail.org + +import Blender +from Blender import * +from math import sqrt + +time1 = Blender.sys.time() + +VRemNum = ERemNum = FRemNum = 0 # Remember for statistics + + +#================# +# Math functions # +#================# +def compare(f1, f2, limit): + if f1 + limit > f2 and f1 - limit < f2: + return 1 + return 0 + +def measure(v1, v2): + return Mathutils.Vector([v1[0]-v2[0], v1[1] - v2[1], v1[2] - v2[2]]).length + +def triArea2D(v1, v2, v3): + e1 = measure(v1, v2) + e2 = measure(v2, v3) + e3 = measure(v3, v1) + p = e1+e2+e3 + return 0.25 * sqrt(p*(p-2*e1)*(p-2*e2)*(p-2*e3)) + + +#=============================# +# Blender functions/shortcuts # +#=============================# +def error(str): + Draw.PupMenu('ERROR%t|'+str) + +def getLimit(text): + return Draw.PupFloatInput(text, 0.001, 0.0, 1.0, 0.1, 3) + +def faceArea(f): + if len(f.v) == 4: + return triArea2D(f.v[0].co, f.v[1].co, f.v[2].co) + triArea2D(f.v[0].co, f.v[2].co, f.v[3].co) + elif len(f.v) == 3: + return triArea2D(f.v[0].co, f.v[1].co, f.v[2].co) + + + +#================# +# Mesh functions # +#================# +def delFreeVert(mesh): + global VRemNum + usedList = eval('[' + ('False,' * len(mesh.verts) )+ ']') + # Now tag verts that areused + for f in mesh.faces: + for v in f.v: + usedList[mesh.verts.index(v)] = True + vIdx = 0 + for bool in usedList: + if bool == False: + mesh.verts.pop(vIdx) + vIdx -= 1 + VRemNum += 1 + vIdx += 1 + mesh.update() + + +def delEdge(mesh): + global ERemNum + fIdx = 0 + while fIdx < len(mesh.faces): + if len(mesh.faces[fIdx].v) == 2: + mesh.faces.pop(fIdx) + ERemNum += 1 + fIdx -= 1 + fIdx +=1 + mesh.update() + +def delEdgeLen(mesh, limit): + global ERemNum + fIdx = 0 + while fIdx < len(mesh.faces): + if len(mesh.faces[fIdx].v) == 2: + if measure(mesh.faces[fIdx].v[0].co, mesh.faces[fIdx].v[1].co) <= limit: + mesh.faces(fIdx) + ERemNum += 1 + fIdx -= 1 + fIdx +=1 + mesh.update() + +def delFaceArea(mesh, limit): + global FRemNum + fIdx = 0 + while fIdx < len(mesh.faces): + if len(mesh.faces[fIdx].v) > 2: + if faceArea(mesh.faces[fIdx]) <= limit: + mesh.faces.pop(fIdx) + FRemNum += 1 + fIdx -= 1 + fIdx +=1 + mesh.update() + + +#====================# +# Make a mesh list # +#====================# + +is_editmode = Window.EditMode() +if is_editmode: Window.EditMode(0) + +meshList = [] +if len(Object.GetSelected()) > 0: + for ob in Object.GetSelected(): + if ob.getType() == 'Mesh': + meshList.append(ob.getData()) + + +#====================================# +# Popup menu to select the functions # +#====================================# +if len(meshList) == 0: + error('no meshes in selection') +else: + method = Draw.PupMenu(\ + 'Clean Mesh, Remove...%t|\ + Verts: free standing|\ + Edges: not in a face|\ + Edges: below a length|\ + Faces: below an area|%l|\ + All of the above|') + + if method >= 3: + limit = getLimit('threshold: ') + + if method != -1: + for mesh in meshList: + if method == 1: + delFreeVert(mesh) + elif method == 2: + delEdge(mesh) + elif method == 3: + delEdgeLen(mesh, limit) + elif method == 4: + delFaceArea(mesh, limit) + elif method == 6: # All of them + delFaceArea(mesh, limit) + delEdge(mesh) + delFreeVert(mesh) + + mesh.update(0) + Redraw() +print 'mesh cleanup time',Blender.sys.time() - time1 +if is_editmode: Window.EditMode(1) + +if method != -1: + Draw.PupMenu('Removed from ' + str(len(meshList)) +' Mesh(es)%t|' + 'Verts:' + str(VRemNum) + ' Edges:' + str(ERemNum) + ' Faces:' + str(FRemNum)) diff --git a/release/scripts/console.py b/release/scripts/console.py index c5d2eb5568e..4ce58e06e10 100644 --- a/release/scripts/console.py +++ b/release/scripts/console.py @@ -29,26 +29,6 @@ Usage:
__author__ = "Campbell Barton AKA Ideasman" __url__ = ["http://members.iinet.net.au/~cpbarton/ideasman/", "blender", "elysiun"] -# -------------------------------------------------------------------------- -# ***** 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 * import sys as python_sys @@ -152,7 +132,7 @@ def unzip(list): this function will fail """ - if not list: return () + if len(list) == 0: return () l = [] for t in range(len(list[0])): l.append(map( lambda x,t=t: x[t], list )) @@ -233,7 +213,7 @@ def rdir(dirString, depth=0): # Dont bother with this data. continue - if type(dirItem) != types.StringType: + if type(dirItem) != type('str'): print dirItem, type(dirItem) if dirItem not in COLLECTED_VAR_NAMES.keys(): @@ -249,17 +229,17 @@ def rdir(dirString, depth=0): #print type(dirItem) #if type(dirData) == types.ClassType or \ # type(dirData) == types.ModuleType: - type_dirData = type(dirData) - if type_dirData != types.StringType and\ - type_dirData != types.DictType and\ - type_dirData != types.DictionaryType and\ - type_dirData != types.FloatType and\ - type_dirData != types.IntType and\ - type_dirData != types.NoneType and\ - type_dirData != types.StringTypes and\ - type_dirData != types.TypeType and\ - type_dirData != types.TupleType and\ - type_dirData != types.BuiltinFunctionType: + + if type(dirData) != types.StringType and\ + type(dirData) != types.DictType and\ + type(dirData) != types.DictionaryType and\ + type(dirData) != types.FloatType and\ + type(dirData) != types.IntType and\ + type(dirData) != types.NoneType and\ + type(dirData) != types.StringTypes and\ + type(dirData) != types.TypeType and\ + type(dirData) != types.TupleType and\ + type(dirData) != types.BuiltinFunctionType: # print type(dirData), dirItem # Dont loop up dirs for strings ints etc. if dirItem not in dirStringSplit: @@ -539,17 +519,16 @@ def handle_event(evt, val): menuList.sort() choice = PupMenuLess( # Menu for the user to choose the autocompleate - 'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text + 'Choices (Shift for Whole 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: # Only paste in the Short name + cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:])) else: # print 'NO EDITVAR' @@ -560,8 +539,11 @@ def handle_event(evt, val): # 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 + if evt == Draw.MOUSEX: # AVOID TOO MANY REDRAWS. + return + elif evt == Draw.MOUSEY: + return + global cursor @@ -823,4 +805,4 @@ cmdBuffer.append(cmdLine(' ', 0, 0)) def main(): Draw.Register(draw_gui, handle_event, handle_button_event) -main() \ No newline at end of file +main() diff --git a/release/scripts/hotkeys.py b/release/scripts/hotkeys.py index 843664edb05..d56951959c3 100644 --- a/release/scripts/hotkeys.py +++ b/release/scripts/hotkeys.py @@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)" __url__ = ("blender", "elysiun", "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__ = "12/18/2005" +__version__ = "10/04/2005" __bpydoc__ = """\ This script is a reference about all hotkeys and mouse actions in Blender. @@ -26,9 +26,10 @@ Notes:
""" +# $Id$ #------------------------ # Hotkeys script -# jm soler (2003-->12/2005) +# jm soler (2003-->10/2004) # ----------------------- # Page officielle : # http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_hotkeyscript.htm @@ -74,17 +75,16 @@ hotkeys={ ['Ctrl-,', 'Set Median Point rotation scaling pivot'], ['.', 'Set 3D cursor as rotation scaling pivot'], ['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-ù)'], +['~', 'Display all layers (German keys: ö)'], +['Shift-~', 'Display all/previous layers (German keys: Shift-ö)'], ['Space', 'Popup menu'], ['Space', '3D View: camera selected + fly mode, accept'], -['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'], -['Ctrl-TAB', 'ARMATURE : Enter/exit Pose Mode'], -['Shift-TAB', 'EDIT MODE : Enter Object Mode'], +['Ctrl-TAB', 'Enter/exit Pose Mode'], +['Shift-TAB', 'Enter Object Mode'], ['Ctrl-Open menu /', ''], ['Ctrl-Load Image', 'Opens a thumbnail browser instead of file browser for images'] ], @@ -97,25 +97,20 @@ hotkeys={ ['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 transformation ( if there is a problem with small step adjustment, first select the axe or axes with LBM alone)'], ['MMB', 'Rotate'], ['Ctrl-MMB', 'Zoom view'], ['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', 'Edit Mode: Select edge'], ['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)'], +['Drag+Ctrl+Shift', 'Small step adjustment'], +['Drag+Shift', 'Fine adjustment'], ['LMB', 'Confirm transformation'], ['MMB', 'Toggle optional transform feature'], ['RMB', 'Abort transformation'] @@ -123,36 +118,33 @@ hotkeys={ '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'], +['F10', 'Render Window'], +['F11', 'Recall the last rendered image'], +['F12', 'Render current Scene'], +['Ctrl-Shift-F12', 'NLA Editor'], +['Shift-F1', 'Library Data Select'], +['Shift-F2', 'Export DXF'], +['Shift-F4', 'Object manager Data Select '], +['Shift-F5', '3D Window'], +['Shift-F6', 'IPO Window'], +['Shift-F7', 'Buttons Window'], +['Shift-F8', 'Video Sequencer 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'] +['Ctrl-F2', 'Save/export in vrml 1.0 format' ], +['Ctrl-F3', 'Save image : dump 3d view'], +['Ctrl-Shift-F3', 'Save image : dump screen'] ], 'Numbers ':[ @@ -160,10 +152,7 @@ hotkeys={ ['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'], -['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'], +['Shift-ALT-...', 'Toggle layer 11..12..20'] ], 'Numpad ':[ @@ -178,10 +167,9 @@ hotkeys={ ['Numpad +', 'In 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 INS', 'Set Camera view'], +['Ctrl-Numpad INS', 'Set active object as camera'], +['Alt-Numbad INS', 'Restore old camera'], ['Numpad 1', 'Front view'], ['Ctrl-Numpad 1', 'Back view'], ['Numpad 3', 'Right view'], @@ -191,9 +179,7 @@ hotkeys={ ['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'] ], @@ -221,7 +207,6 @@ hotkeys={ ['Alt-Up', 'Blender in Fullscreen mode'], ['Ctrl-Left', 'Previous screen'], ['Ctrl-Right', 'Next screen'], -['Ctrl-Alt-C', 'Object Mode : Add Constraint'], ['Ctrl-Down', 'Maximize window toggle'], ['Ctrl-Up', 'Maximize window toggle'], ['Shift-Arrow', 'Toggle first frame/ last frame'] @@ -283,12 +268,6 @@ hotkeys={ ['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'] ], @@ -308,7 +287,6 @@ hotkeys={ ['Alt-G', 'Clear location'], ['Shift-ALT-G', 'Remove selected objects from group'], ['Ctrl-G', 'Add selected objects to group'], -['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Grab Mode'], ['Shift-G', 'Selected Group menu'] ], @@ -317,11 +295,11 @@ hotkeys={ ['H', 'Curves: Set handle type'], ['H', 'Action editor: Handle type aligned'], ['H', 'Action editor: Handle type free'], -['Alt-H', 'Edit Mode : Show Hidden vertices/faces'], +['Alt-H', '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 .'] +['Shift-H', 'Edit Mode, Hide deselected vertices/faces'], +['Ctrl-H', 'Edit Mode, Add a hook on selected points or show the hook menu .'] ], "I":[ @@ -351,7 +329,7 @@ hotkeys={ "L":[ ['L', 'Make local menu'], -['L', 'Edit Mode: Select linked vertices (near mouse pointer)'], +['L', 'Edit mode: Select linked vertices (near mouse pointer)'], ['L', 'OOPS window: Select linked objects'], ['L', 'UV Face Select: Select linked faces'], ['Ctrl-L', 'Make links menu (for instance : to scene...)'], @@ -375,7 +353,7 @@ hotkeys={ ['N', 'OOPS window: Rename object/linked objects'] , ['Ctrl-N', 'Armature: Recalculate bone roll angles'] , ['Ctrl-N', 'Edit Mode: Recalculate normals to outside'] , -['Ctrl-Shift-N', 'Edit Mode: Recalculate normals to inside'] ], +['Ctrl-ALT-N', 'Edit Mode: Recalculate normals to inside'] ], "O":[ ['O', 'Edit Mode/UV Image Editor: Toggle proportional vertex editing'], @@ -387,7 +365,6 @@ hotkeys={ "P":[ ['P', 'Object Mode: Start realtime engine'], ['P', 'Edit mode: Seperate vertices to new object'], -['shift-P', 'Edit mode: Push-Pull'], ['P', 'UV Image Editor: Pin UVs'], ['Alt-P', 'Clear parent relationship'], ['Alt-P', 'UV Image Editor: Unpin UVs'], @@ -410,7 +387,6 @@ hotkeys={ ['RZZ', "Rotate around object's local Z axis"], ['Alt-R', 'Clear object rotation'], ['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'] ], @@ -424,11 +400,8 @@ hotkeys={ ['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)'] , -['Ctrl-Shift-S', 'Edit mode: To Sphere'] , -['Ctrl-Alt-Shift-S', 'Edit mode: Shear'] , ['Alt-S', 'Clear object size'] , ['Ctrl-S', 'Edit mode: Shear'] , -['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Size Mode'], ['Shift-S', 'Cursor/Grid snap menu'] ], "T":[ @@ -445,18 +418,18 @@ hotkeys={ "U":[ ['U', 'Make single user menu (for import completly linked object to another scene for instance) '] , ['U', '3D View: Make Single user Menu'] , +['U', 'Edit Mode: Reload object data from before entering Edit Mode'] , ['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']], +['Alt-U', 'Edit Mode: Undo Menu'] ], "V":[ ['V', 'Curves/Nurbs: Vector handle'], -['V', 'Edit Mode : Rip selected vertices'], ['V', 'Vertexpaint mode'], ['V', 'UV Image Editor: Stitch UVs'], -['V', 'Action editor: Vector'], +['V', 'Action editor: Vector'], ['Alt-V', "Scale object to match image texture's aspect ratio"], ['Shift-V', 'Edit mode: Align view to selected vertices'], ['Shift-V', 'UV Image Editor: Limited Stitch UVs popup'], @@ -464,37 +437,13 @@ hotkeys={ ], "W":[ -['W', 'Edit Mode: Specials menu'], -['W', 'Edit Mode: Specials menu, ARMATURE 1 Subdivide'], -['W', 'Edit Mode: Specials menu, ARMATURE 2 Flip Left-Right Name'], -['W', 'Edit Mode: Specials menu, CURVE 1 Subdivide'], -['W', 'Edit Mode: Specials menu, CURVE 2 Swich Direction'], -['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', 'Object Mode: Boolean operations menu'], +['W', 'Edit mode: Specials menu'], ['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'] , +['Ctrl-W', 'Nurbs: Switch direction'] , ['Shift-W', 'Warp/bend selected vertices around cursor'], ['alt-W', 'Export in videoscape format'] ], @@ -507,15 +456,13 @@ hotkeys={ ], "Y":[ -['Y', 'Edit Mode & Mesh : Split selected vertices/faces from the rest'], -['Ctrl-Y', 'Object Mode : Redo'], -], +['Y', 'Mesh: Split selected vertices/faces from the rest'] ], "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)'], -['Ctrl-Z', 'Object Mode : Undo'], +['Ctrl-Z', 'Switch 3d draw type : shaded (see also D)'], ['Shift-Z', 'Switch 3d draw type : shaded / wireframe (see also D)'], ]}]} @@ -551,15 +498,12 @@ def searchfor(SEARCHLINE): #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 @@ -625,7 +569,6 @@ def draw(): listed=hot.index(k) l=0 size[3]=size[3]-4 - if hot[listed]!='Letters ' and hot[listed]!='Search ' : size[3]=size[3]-8 SCROLL=size[3]/21 @@ -651,19 +594,17 @@ def draw(): glRasterPos2f(4+8*15, size[3]-(58+21*l)) Text(' : '+n[1]) l+=1 - elif hot[listed]=='Search ' : r=[0,size[3]-70, size[2], size[3]-44] trace_rectangle4(r,c2) SEARCHLINE=String(' ', LINE, 42, size[3]-68,200,18,SEARCHLINE.val, 256,'') if len(FINDED)>0: - LEN=len(FINDED) - size[3]=size[3]-8 - SCROLL=size[3]/21 - END=-1 - - if SCROLL < len(FINDED): + LEN=len(FINDED) + size[3]=size[3]-8 + SCROLL=size[3]/21 + END=-1 + if SCROLL < len(FINDED): Button('/\\',up,4,size[3]+8,20,14,'Scroll up') Button('\\/',down,4,size[3]-8,20,14,'Scroll down') if (SCROLL+UP) %s" % (pp, pplist[pp]), where) self.pprint ("]") # end def plist def pdict(self, pdict, where = _NO): self.pprint ("dict:{", where) - for pp in pdict.iterkeys(): + for pp in pdict.keys(): self.pprint ("[%s] -> %s" % (pp, pdict[pp]), where) self.pprint ("}") # end def pdict @@ -180,12 +135,12 @@ class dotext: def pprint(self, parg, where = _NO): if parg == None: self.pstring("_None_", where) - elif type(parg) == type_list: + elif type(parg) == type ([]): self.plist(parg, where) - elif type(parg) == type_dict: + elif type(parg) == type ({}): self.pdict(parg, where) else: - self.pstring(safestring(str(parg)), where) + self.pstring(parg, where) # end def pprint def logcon(self, parg): @@ -197,13 +152,6 @@ tobj=dotext(textname) #uncomment the following line to log all messages on both console and logfile #tobj=dotext(textname,dotext.CON) -def rlcopy(ll): - if type(ll) != type_list: - return ll - if ll == []: - return [] - cpy = [rlcopy(ii) for ii in ll] - return cpy # =========================================================== # === Main read functions =================================== @@ -224,9 +172,7 @@ def read(filename): start = time.clock() 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 === - + # === LWO header === form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12)) if (form_type == "LWOB"): read_lwob(file, filename) @@ -247,8 +193,6 @@ def read(filename): tobj.pprint ("#####################################################################") tobj.logcon (message) tobj.logcon ("#####################################################################") - if editmode: Blender.Window.EditMode(1) # optional, just being nice - # enddef read @@ -290,7 +234,6 @@ def read_lwo2(file, filename, typ="LWO2"): dir_part = Blender.sys.dirname(filename) fname_part = Blender.sys.basename(filename) - ask_weird = 1 #first initialization of data structures defaultname = os.path.splitext(fname_part)[0] @@ -299,63 +242,17 @@ def read_lwo2(file, filename, typ="LWO2"): 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 + #5 - polytag_dict = {TAG} #tag to polygon 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 + #7 - uvcoords_dict = {name} #uvmap coordinates (mixed mode per face/per vertex) + #8 - facesuv_dict = {name} #uvmap coordinates associations poly -> uv tuples - #pass 1: look in advance for materials - tobj.logcon ("#####################################################################") - tobj.logcon ("Starting Pass 1: hold on tight") - tobj.logcon ("#####################################################################") - while 1: - try: - lwochunk = chunk.Chunk(file) - except EOFError: - break - tobj.pprint(" ") - if lwochunk.chunkname == "TAGS": # Tags - tobj.pprint("---- TAGS") - tag_list.extend(read_tags(lwochunk)) - elif lwochunk.chunkname == "SURF": # surfaces - tobj.pprint("---- SURF") - surf_list.append(read_surfs(lwochunk, surf_list, tag_list)) - elif lwochunk.chunkname == "CLIP": # texture images - tobj.pprint("---- CLIP") - clip_list.append(read_clip(lwochunk, dir_part)) - tobj.pprint("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: - tobj.logcon("---- %s: Maybe file corrupted. Terminated by user" % lwochunk.chunkname) - return - ask_weird = 0 - tobj.pprint("---- %s: skipping (maybe later)" % lwochunk.chunkname) - lwochunk.skip() - - #add default material for orphaned faces, if any - surf_list.append({'NAME': "_Orphans", 'g_MAT': Blender.Material.New("_Orphans")}) - - #pass 2: effectively generate objects - tobj.logcon ("#####################################################################") - tobj.logcon ("Pass 2: now for the hard part") - tobj.logcon ("#####################################################################") - file.seek(0) - # === LWO header === - form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12)) - if (form_type != "LWO2"): - tobj.logcon ("??? Inconsistent file type: %s" %form_type) - return while 1: try: lwochunk = chunk.Chunk(file) @@ -366,69 +263,81 @@ def read_lwo2(file, filename, typ="LWO2"): tobj.pprint("---- LAYR") objname = read_layr(lwochunk) tobj.pprint(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 + if object_list == None: + object_list = [[objname, {}, [], [], {}, {}, 0, {}, {}]] + else: + object_list.append([objname, {}, [], [], {}, {}, 0, {}, {}]) + object_index += 1 elif lwochunk.chunkname == "PNTS": # Verts tobj.pprint("---- PNTS") verts = read_verts(lwochunk) - objspec_list[2] = verts + object_list[object_index][2] = verts elif lwochunk.chunkname == "VMAP": # MAPS (UV) tobj.pprint("---- VMAP") - #objspec_list[7] = read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk) - read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk) + object_list[object_index][7], object_list[object_index][8] = read_vmap(object_list[object_index][7], object_list[object_index][8], object_list[object_index][3], len(object_list[object_index][2]), lwochunk) elif lwochunk.chunkname == "VMAD": # MAPS (UV) per-face tobj.pprint("---- 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) + object_list[object_index][7], object_list[object_index][8] = read_vmad(object_list[object_index][7], object_list[object_index][8], object_list[object_index][3], len(object_list[object_index][2]), lwochunk) elif lwochunk.chunkname == "POLS": # Faces v6.0 tobj.pprint("-------- 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 + if object_list[object_index][3] != []: + object_list.append([object_list[object_index][0], #update name + {}, #init + copy.deepcopy(object_list[object_index][2]), #same vertexes + [], #no faces + {}, #no need to copy - filled at runtime + {}, #polygon tagging will follow + flag, #patch flag + copy.deepcopy(object_list[object_index][7]), #same uvcoords + {}]) #no uv mapping object_index += 1 #end if already has a face list - objspec_list[3] = faces - objname = objspec_list[0] + #update uv coords mapping if VMAP already encountered + for uvname in object_list[object_index][7]: + tobj.pprint("updating uv to face mapping for %s" % uvname) + object_list[object_index][8][uvname] = copy.deepcopy(faces) + object_list[object_index][3] = faces + objname = object_list[object_index][0] if objname == None: objname = defaultname #end if processing a valid poly type + elif lwochunk.chunkname == "TAGS": # Tags + tobj.pprint("---- TAGS") + tag_list.extend(read_tags(lwochunk)) elif lwochunk.chunkname == "PTAG": # PTags tobj.pprint("---- PTAG") polytag_dict = read_ptags(lwochunk, tag_list) - for kk, ii in polytag_dict.iteritems(): objspec_list[5][kk] = ii + for kk in polytag_dict.keys(): object_list[object_index][5][kk] = polytag_dict[kk] + elif lwochunk.chunkname == "SURF": # surfaces + tobj.pprint("---- SURF") + surf_list.append(read_surfs(lwochunk, surf_list, tag_list)) + elif lwochunk.chunkname == "CLIP": # texture images + tobj.pprint("---- CLIP") + clip_list.append(read_clip(lwochunk)) + tobj.pprint("read total %s clips" % len(clip_list)) else: # Misc Chunks - tobj.pprint("---- %s: skipping (definitely!)" % lwochunk.chunkname) + tobj.pprint("---- %s: skipping" % lwochunk.chunkname) lwochunk.skip() #uncomment here to log data structure as it is built #tobj.pprint(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 - tobj.pprint ("\n#####################################################################") - tobj.pprint("Found %d objects:" % object_index) + tobj.pprint("Found %d objects:" % len(object_list)) tobj.pprint ("#####################################################################") + for objspec_list in object_list: + tobj.pprint ("\n#===================================================================#") + tobj.pprint("Processing Object: %s" % objspec_list[0]) + tobj.pprint ("#===================================================================#") + objspec_list[3], objspec_list[5], objspec_list[8] = recalc_faces(objspec_list[2], objspec_list[3], objspec_list[5], objspec_list[8]) #recalculate faces, polytag_dict and uv_mapping get rid of faces fanning + + create_objects(objspec_list) + + if surf_list != []: + create_material(clip_list, surf_list, objspec_list, dir_part) #give it all the object + return # enddef read_lwo2 @@ -449,8 +358,8 @@ def read_verts(lwochunk): numverts = lwochunk.chunksize/12 #$verts = [] verts = [None] * numverts - for i in xrange(numverts): - if not i%1000 and my_meshtools.show_progress: + for i in range(numverts): + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts") x, y, z = struct.unpack(">fff", data.read(12)) verts[i] = (x, z, y) @@ -497,18 +406,13 @@ def read_faces_5(lwochunk): faces = [] i = 0 while i < lwochunk.chunksize: - if not i%1000 and my_meshtools.show_progress: + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces") - - ''' facev = [] numfaceverts, = struct.unpack(">H", data.read(2)) - for j in xrange(numfaceverts): + for j in range(numfaceverts): index, = struct.unpack(">H", data.read(2)) facev.append(index) - ''' - 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)) @@ -538,42 +442,46 @@ def read_vx(data): # ====================== # === Read uvmapping === # ====================== -def read_vmap(uvcoords_dict, maxvertnum, lwochunk): +def read_vmap(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk): if maxvertnum == 0: tobj.pprint ("Found VMAP but no vertexes to map!") - return uvcoords_dict + return uvcoords_dict, facesuv_dict data = cStringIO.StringIO(lwochunk.read()) map_type = data.read(4) if map_type != "TXUV": tobj.pprint ("Reading VMAP: No Texture UV map Were Found. Map Type: %s" % map_type) - return uvcoords_dict + return uvcoords_dict, facesuv_dict dimension, = struct.unpack(">H", data.read(2)) name, i = read_name(data) #i initialized with string lenght + zeros tobj.pprint ("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 - 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 + #my_uv_list = [None] * maxvertnum + my_uv_list = [(0.0, 0.0)] * maxvertnum #more safe to have some default coordinates to associate in any case? + while (i < lwochunk.chunksize - 6): #4+2 header bytes already read vertnum, vnum_size = read_vx(data) u, v = struct.unpack(">ff", data.read(8)) if vertnum >= maxvertnum: tobj.pprint ("Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum) else: - my_uv_dict[vertnum] = (u, v) + my_uv_list[vertnum] = (u, v) i += 8 + vnum_size #end loop on uv pairs - uvcoords_dict[name] = my_uv_dict + uvcoords_dict[name] = my_uv_list #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 + if faces == []: + tobj.pprint ("no faces read yet! delaying uv to face assignments") + facesuv_dict[name] = [] + else: + #deepcopy so we could modify it without actually modify faces + tobj.pprint ("faces already present: proceeding with assignments") + facesuv_dict[name] = copy.deepcopy(faces) + return uvcoords_dict, facesuv_dict + # ======================== # === Read uvmapping 2 === # ======================== -def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk): +def read_vmad(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk): + maxfacenum = len(faces) if maxvertnum == 0 or maxfacenum == 0: tobj.pprint ("Found VMAD but no vertexes to map!") return uvcoords_dict, facesuv_dict @@ -585,13 +493,14 @@ def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk): dimension, = struct.unpack(">H", data.read(2)) name, i = read_name(data) #i initialized with string lenght + zeros tobj.pprint ("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? + if uvcoords_dict.has_key(name): + my_uv_list = uvcoords_dict[name] #update existing + my_facesuv_list = facesuv_dict[name] + else: + my_uv_list = [(0.0, 0.0)] * maxvertnum #start a brand new: this could be made more smart + my_facesuv_list = copy.deepcopy(faces) #end variable initialization + lastindex = len(my_uv_list) - 1 while (i < lwochunk.chunksize - 6): #4+2 header bytes already read vertnum, vnum_size = read_vx(data) i += vnum_size @@ -601,15 +510,18 @@ def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk): if polynum >= maxfacenum or vertnum >= maxvertnum: tobj.pprint ("Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum) else: - my_uv_dict[newindex] = (u, v) - my_facesuv_list.append([polynum, vertnum, newindex]) - newindex += 1 + my_uv_list.append( (u,v) ) + newindex = len(my_uv_list) - 1 + for vi in range(len(my_facesuv_list[polynum])): #polynum starting from 1 or from 0? + if my_facesuv_list[polynum][vi] == vertnum: + my_facesuv_list[polynum][vi] = newindex + #end loop on current face vertexes i += 8 #end loop on uv pairs - uvcoords_dict[name] = my_uv_dict + uvcoords_dict[name] = my_uv_list facesuv_dict[name] = my_facesuv_list - tobj.pprint ("updated %d vertexes data" % (newindex-maxvertnum-10)) - return + tobj.pprint ("updated %d vertexes data" % (newindex-lastindex)) + return uvcoords_dict, facesuv_dict # ================= @@ -646,7 +558,7 @@ def read_ptags(lwochunk, tag_list): ptag_dict = {} i = 0 while(i < lwochunk.chunksize-4): #4 bytes polygon type already read - if not i%1000 and my_meshtools.show_progress: + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading PTAGS") poln, poln_size = read_vx(data) i += poln_size @@ -656,12 +568,11 @@ def read_ptags(lwochunk, tag_list): return {} i += 2 tag_key = tag_list[tag_index] - try: #if ptag_dict.has_key(tag_key): - ptag_dict[tag_list[tag_index]].append(poln) - except: #else: + if not(ptag_dict.has_key(tag_key)): ptag_dict[tag_list[tag_index]] = [poln] - - for i in ptag_dict.iterkeys(): + else: + ptag_dict[tag_list[tag_index]].append(poln) + for i in ptag_dict.keys(): tobj.pprint ("read %d polygons belonging to TAG %s" % (len(ptag_dict[i]), i)) return ptag_dict @@ -670,9 +581,7 @@ def read_ptags(lwochunk, tag_list): # ================== # === 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 +def read_clip(lwochunk): clip_dict = {} data = cStringIO.StringIO(lwochunk.read()) image_index, = struct.unpack(">L", data.read(4)) @@ -707,30 +616,11 @@ def read_clip(lwochunk, dir_part): n, = struct.unpack(">H", data.read(2)) clip_dict['NEGA'] = n else: # Misc Chunks - tobj.pprint("-------- CLIP:%s: skipping" % subchunkname) + tobj.pprint("-------- SURF:%s: skipping" % subchunkname) discard = data.read(subchunklen) i = i + 6 + subchunklen #end loop on surf chunks tobj.pprint("read image:%s" % clip_dict) - if clip_dict.has_key('XREF'): - tobj.pprint("Cross-reference: no image pre-allocated.") - return clip_dict - #look for images - img = load_image("",clip_dict['NAME']) - if img == None: - tobj.pprint ( "***No image %s found: trying LWO file subdir" % clip_dict['NAME']) - img = load_image(dir_part,clip_dict['BASENAME']) - if img == None: - tobj.pprint ( "***No image %s found in directory %s: trying Images subdir" % (clip_dict['BASENAME'], dir_part)) - img = load_image(dir_part+Blender.sys.sep+"Images",clip_dict['BASENAME']) - if img == None: - tobj.pprint ( "***No image %s found: trying alternate Images subdir" % clip_dict['BASENAME']) - img = load_image(dir_part+Blender.sys.sep+".."+Blender.sys.sep+"Images",clip_dict['BASENAME']) - if img == None: - tobj.pprint ( "***No image %s found: giving up" % clip_dict['BASENAME']) - #lucky we are: we have an image - tobj.pprint ("Image pre-allocated.") - clip_dict['g_IMG'] = img return clip_dict @@ -754,7 +644,7 @@ def read_surfblok(subchunkdata): tobj.pprint ("---------- IMAP") ordinal, i = read_name(data) my_dict['ORD'] = ordinal - #my_dict['g_ORD'] = -1 + 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)) @@ -990,32 +880,27 @@ def read_surfs(lwochunk, surf_list, tag_list): rr, uvname = read_surfblok(data.read(subchunklen)) #paranoia setting: preventing adding an empty dict if rr != {}: - try: - my_dict['BLOK'].append(rr) - except: + if not(my_dict.has_key('BLOK')): my_dict['BLOK'] = [rr] - + else: + my_dict['BLOK'].append(rr) if uvname != "": my_dict['UVNAME'] = uvname #theoretically there could be a number of them: only one used per surf - if not(my_dict.has_key('g_IMAG')) and (rr.has_key('CHAN')) and (rr.has_key('OPAC')) and (rr.has_key('IMAG')): - 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 tobj.pprint("-------- 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'] = Blender.Material.New(my_dict['NAME']) - tobj.pprint("-> Material pre-allocated.") + if my_dict.has_key('BLOK'): + my_dict['BLOK'].reverse() return my_dict + + + + # =========================================================== # === Generation Routines =================================== # =========================================================== @@ -1037,7 +922,7 @@ def find_ear(normal, list_dict, verts, face): mla = 1 mlb = 2 - for c in xrange(nv): + for c in range(nv): a = (c+1) % nv; b = (a+1) % nv if list_dict['P'][a] > 0.0: #we have to start from a convex vertex @@ -1049,7 +934,7 @@ def find_ear(normal, list_dict, verts, face): #tobj.pprint (" ok, this one passed") concave = 0 concave_inside = 0 - for xx in xrange(nv): #looking for concave vertex + for xx in range(nv): #looking for concave vertex if (list_dict['P'][xx] <= 0.0) and (xx != b) and (xx != c): #cannot be a: it's convex #ok, found concave vertex concave = 1 @@ -1124,12 +1009,12 @@ def reduce_face(verts, face): vi = face[mvi] list_dict['D'][mvi] = dist_vector(verts[vi_hiend], verts[vi]) #list of cross products - normals evaluated into vertexes - for vi in xrange(nv): + for vi in range(nv): list_dict['X'][vi] = Blender.Mathutils.CrossVecs(list_dict['D'][vi], list_dict['D'][vi-1]) my_face_normal = Blender.Mathutils.Vector([list_dict['X'][0][0], list_dict['X'][0][1], list_dict['X'][0][2]]) #list of dot products list_dict['P'][0] = 1.0 - for vi in xrange(1, nv): + for vi in range(1, nv): list_dict['P'][vi] = Blender.Mathutils.DotVecs(my_face_normal, list_dict['X'][vi]) #is there at least one concave vertex? #one_concave = reduce(lambda x, y: (x) or (y<=0.0), list_dict['P'], 0) @@ -1179,37 +1064,63 @@ def reduce_face(verts, face): # ========================= # === 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 - -def get_newindex(polygon_list, vertnum): - # extract from the polygon list the new index associated to a vertex - if polygon_list == []: - return -1 - for elem in polygon_list: - if elem[1] == vertnum: - return elem[2] - #tobj.pprint("WARNING: expected vertex %s for polygon %s. Polygon_list dump follows" % (vertnum, polygon_list[0][0])) - #tobj.pprint(polygon_list) - return -1 - -def get_surf(surf_list, cur_tag): - for elem in surf_list: - if elem['NAME'] == cur_tag: - return elem - return {} +# --------- this do the standard face + ptag_dict + uv-map recalc +def recalc_faces(verts, faces, polytag_dict, facesuv_dict): + # init local face list + my_faces = [] + # init local uvface dict + my_facesuv = {} + for uvname in facesuv_dict: + my_facesuv[uvname] = [] + replaced_faces_dict = {} + j = 0 + if len(faces)==0: + return faces, polytag_dict, facesuv_dict + for i in range(len(faces)): + # i = index that spans on original faces + # j = index that spans on new faces + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Recalculating faces") + numfaceverts=len(faces[i]) + if numfaceverts < 4: #This face is a triangle or quad: more strict - it has to be a triangle + my_faces.append(faces[i]) #ok, leave it alone .... + for uvname in facesuv_dict: + my_facesuv[uvname].append(facesuv_dict[uvname][i]) + replaced_faces_dict[i] = [j] #.... but change the nuber order of the face + j += 1 + else: # Reduce n-sided convex polygon. + meta_faces = reduce_face(verts, faces[i]) # Indices of triangles. + this_faces = [] # list of triangles poly replacing original face + this_faces_index = [] + for mf in meta_faces: + ll = len(mf) + if ll == 3: #triangle + this_faces.append([faces[i][mf[0]], faces[i][mf[1]], faces[i][mf[2]]]) + else: #quads + this_faces.append([faces[i][mf[0]], faces[i][mf[1]], faces[i][mf[2]], faces[i][mf[3]]]) + for uvname in facesuv_dict: + if ll == 3: #triangle + my_facesuv[uvname].append([facesuv_dict[uvname][i][mf[0]], facesuv_dict[uvname][i][mf[1]], facesuv_dict[uvname][i][mf[2]]]) + else: #quads + my_facesuv[uvname].append([facesuv_dict[uvname][i][mf[0]], facesuv_dict[uvname][i][mf[1]], facesuv_dict[uvname][i][mf[2]], facesuv_dict[uvname][i][mf[3]]]) + this_faces_index.append(j) + j +=1 + my_faces.extend(this_faces) + replaced_faces_dict[i] = this_faces_index #face i substituted by this list of faces + #endif on face vertex number + #end loop on every face + #now we have the new faces list and a dictionary replacement. + #going for polygon tagging + my_ptag_dict = {} + for tag in polytag_dict: #for every tag group + my_ptag_dict[tag] = [] #rebuild a new entry + for poly in polytag_dict[tag]: #take every element of old face list + my_ptag_dict[tag].extend(replaced_faces_dict[poly]) #substitutes the element of new face list + return my_faces, my_ptag_dict, my_facesuv - -# ========================================== -# === Revert list (keeping first vertex) === -# ========================================== +# ======================================== +# === Revert list keeping first vertex === +# ======================================== def revert (llist): #different flavors: the reverse one is the one that works better #rhead = [llist[0]] @@ -1217,202 +1128,59 @@ def revert (llist): #rhead.extend(rtail) #return rhead #-------------- - rhead=rlcopy(llist) + rhead=copy.deepcopy(llist) rhead.reverse() return rhead #-------------- #return llist - # ==================================== # === Modified Create Blender Mesh === # ==================================== -def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not_used_faces): +def my_create_mesh(complete_vertlist, complete_facelist, 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 + vertex_map = [-1] * len(complete_vertlist) cur_ptag_faces = [] - cur_ptag_faces_indexes = [] - maxface = len(complete_facelist) for ff in current_facelist: - if ff >= maxface: - tobj.logcon("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) + cur_ptag_faces.append(cur_face) if not_used_faces != []: not_used_faces[ff] = -1 - for vv in cur_face: vertex_map[vv] = 1 + for vv in cur_face: + vertex_map[vv] = 1 + #end loop on vertex on this face #end loop on faces - store_edge = 0 - msh = Blender.NMesh.GetRaw() - # Name the Object + mesh = Blender.NMesh.GetRaw() + + #append vertexes + jj = 0 + for i in range(len(complete_vertlist)): + if vertex_map[i] == 1: + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(complete_vertlist), "Generating Verts") + x, y, z = complete_vertlist[i] + mesh.verts.append(Blender.NMesh.Vert(x, y, z)) + vertex_map[i] = jj + jj += 1 + #end sweep over vertexes + + #append faces + for i in range(len(cur_ptag_faces)): + if not i%100 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(cur_ptag_faces), "Generating Faces") + face = Blender.NMesh.Face() + rev_face = revert(cur_ptag_faces[i]) + for vi in rev_face: + #for vi in cur_ptag_faces[i]: + index = vertex_map[vi] + face.v.append(mesh.verts[index]) + #end sweep over vertexes + mesh.faces.append(face) + #end sweep over faces + if not my_meshtools.overwrite_mesh_name: objname = my_meshtools.versioned_name(objname) - Blender.NMesh.PutRaw(msh, objname) # Name the Mesh + Blender.NMesh.PutRaw(mesh, objname) # Name the Mesh obj = Blender.Object.GetSelected()[0] - obj.name=objname - # Associate material and mesh properties => from create materials - msh = obj.getData() - mat_index = len(msh.getMaterials(1)) - mat = None - if surf.has_key('g_MAT'): - mat = surf['g_MAT'] - msh.addMaterial(mat) - msh.mode |= Blender.NMesh.Modes.AUTOSMOOTH #smooth it anyway - if surf.has_key('SMAN'): - #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 - s = int(surf['SMAN']/3.1415926535897932384626433832795*180.0) #lwo in radians - blender in degrees - if msh.getMaxSmoothAngle() < s: msh.setMaxSmoothAngle(s) - - img = None - if surf.has_key('g_IMAG'): - ima = lookup_imag(clip_list, surf['g_IMAG']) - if ima != None: - img = ima['g_IMG'] - - #uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])) and (img != None)) - uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME']))) - - if uv_flag: #assign uv-data; settings at mesh level - msh.hasFaceUV(1) - msh.update(1) - - tobj.pprint ("\n#===================================================================#") - tobj.pprint("Processing Object: %s" % objname) - tobj.pprint ("#===================================================================#") - - jj = 0 - vertlen = len(vertex_map) - maxvert = len(complete_vertlist) - for i in vertex_map.iterkeys(): - if not jj%1000 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/vertlen, "Generating Verts") - if i >= maxvert: - tobj.logcon("Non existent vertex addressed: Giving up with this object") - return obj, not_used_faces #return the created object - x, y, z = complete_vertlist[i] - msh.verts.append(Blender.NMesh.Vert(x, y, z)) - vertex_map[i] = jj - jj += 1 - #end sweep over vertexes - - ALPHA_FACE_MODE = (surf.has_key('TRAN') and mat.getAlpha()<1.0) - #append faces - jj = 0 - for i in cur_ptag_faces_indexes: - if not jj%1000 and my_meshtools.show_progress: Blender.Window.DrawProgressBar(float(jj)/len(cur_ptag_faces_indexes), "Generating Faces") - cur_face = complete_facelist[i] - numfaceverts = len(cur_face) - vmad_list = [] #empty VMAD in any case - if uv_flag: #settings at original face level - if facesuv_dict.has_key(surf['UVNAME']): #yes = has VMAD; no = has VMAP only - vmad_list = get_uvface(facesuv_dict[surf['UVNAME']],i) #this for VMAD - - if numfaceverts == 2: - #This is not a face is an edge - store_edge = 1 - if msh.edges == None: #first run - msh.addEdgeData() - #rev_face = revert(cur_face) - i1 = vertex_map[cur_face[1]] - i2 = vertex_map[cur_face[0]] - ee = msh.addEdge(msh.verts[i1],msh.verts[i2]) - ee.flag |= Blender.NMesh.EdgeFlags.EDGEDRAW - ee.flag |= Blender.NMesh.EdgeFlags.EDGERENDER - - elif numfaceverts == 3: - #This face is a triangle skip face reduction - face = Blender.NMesh.Face() - msh.faces.append(face) - # Associate face properties => from create materials - if mat != None: face.materialIndex = mat_index - face.smooth = 1 #smooth it anyway - - #rev_face = revert(cur_face) - rev_face = [cur_face[2], cur_face[1], cur_face[0]] - - for vi in rev_face: - index = vertex_map[vi] - face.v.append(msh.verts[index]) - - if uv_flag: - ni = get_newindex(vmad_list, vi) - if ni > -1: - uv_index = ni - else: #VMAP - uses the same criteria as face - uv_index = vi - try: #if uvcoords_dict[surf['UVNAME']].has_key(uv_index): - uv_tuple = uvcoords_dict[surf['UVNAME']][uv_index] - except: #else: - uv_tuple = (0,0) - face.uv.append(uv_tuple) - - if uv_flag and img != None: - face.mode |= Blender.NMesh.FaceModes['TEX'] - face.image = img - face.mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway - face.transp = Blender.NMesh.FaceTranspModes['SOLID'] - face.flag = Blender.NMesh.FaceTranspModes['SOLID'] - #if surf.has_key('SIDE'): - # msh.faces[f].mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway - if ALPHA_FACE_MODE: - face.transp = Blender.NMesh.FaceTranspModes['ALPHA'] - - elif numfaceverts > 3: - #Reduce all the faces with more than 3 vertexes (& test if the quad is concave .....) - - meta_faces = reduce_face(complete_vertlist, cur_face) # Indices of triangles. - for mf in meta_faces: - face = Blender.NMesh.Face() - msh.faces.append(face) - - if len(mf) == 3: #triangle - #rev_face = revert([cur_face[mf[0]], cur_face[mf[1]], cur_face[mf[2]]]) - rev_face = [cur_face[mf[2]], cur_face[mf[1]], cur_face[mf[0]]] - else: #quads - #rev_face = revert([cur_face[mf[0]], cur_face[mf[1]], cur_face[mf[2]], cur_face[mf[3]]]) - rev_face = [cur_face[mf[3]], cur_face[mf[2]], cur_face[mf[1]], cur_face[mf[0]]] - - # Associate face properties => from create materials - if mat != None: face.materialIndex = mat_index - face.smooth = 1 #smooth it anyway - - for vi in rev_face: - index = vertex_map[vi] - face.v.append(msh.verts[index]) - - if uv_flag: - ni = get_newindex(vmad_list, vi) - if ni > -1: - uv_index = ni - else: #VMAP - uses the same criteria as face - uv_index = vi - try: #if uvcoords_dict[surf['UVNAME']].has_key(uv_index): - uv_tuple = uvcoords_dict[surf['UVNAME']][uv_index] - except: #else: - uv_tuple = (0,0) - face.uv.append(uv_tuple) - - if uv_flag and img != None: - face.mode |= Blender.NMesh.FaceModes['TEX'] - face.image = img - face.mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway - face.transp = Blender.NMesh.FaceTranspModes['SOLID'] - face.flag = Blender.NMesh.FaceTranspModes['SOLID'] - #if surf.has_key('SIDE'): - # msh.faces[f].mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway - if ALPHA_FACE_MODE: - face.transp = Blender.NMesh.FaceTranspModes['ALPHA'] - - jj += 1 - - if not(uv_flag): #clear eventual UV data - msh.hasFaceUV(0) - msh.update(1,store_edge) + obj.name=objname # Name the Object Blender.Redraw() return obj, not_used_faces #return the created object @@ -1423,12 +1191,8 @@ def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not def set_subsurf(obj): msh = obj.getData() msh.setSubDivLevels([2, 2]) - #does not work any more in 2.40 alpha 2 - #msh.mode |= Blender.NMesh.Modes.SUBSURF - if msh.edges != None: - msh.update(1,1) - else: - msh.update(1) + msh.mode |= Blender.NMesh.Modes.SUBSURF + msh.update(1) obj.makeDisplayList() return @@ -1448,7 +1212,7 @@ def obj_size_pos(obj): # ========================= # === Create the object === # ========================= -def create_objects(clip_list, objspec_list, surf_list): +def create_objects(objspec_list): nf = len(objspec_list[3]) not_used_faces = range(nf) ptag_dict = objspec_list[5] @@ -1459,36 +1223,33 @@ def create_objects(clip_list, objspec_list, surf_list): endchar = "" if (objspec_list[6] == 1): middlechar = endchar = "#" - for cur_tag in ptag_dict.iterkeys(): + for cur_tag in ptag_dict.keys(): if ptag_dict[cur_tag] != []: - cur_surf = get_surf(surf_list, cur_tag) - cur_obj, not_used_faces= my_create_mesh(clip_list, cur_surf, objspec_list, ptag_dict[cur_tag], objspec_list[0][:9]+middlechar+cur_tag[:9], not_used_faces) - #does not work any more in 2.40 alpha 2 - #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: + cur_obj, not_used_faces= my_create_mesh(objspec_list[2], objspec_list[3], ptag_dict[cur_tag], objspec_list[0][:9]+middlechar+cur_tag[:9], not_used_faces) if objspec_list[6] == 1: set_subsurf(cur_obj) - obj_dict["_Orphans"] = cur_obj - obj_dim_dict["_Orphans"] = obj_size_pos(cur_obj) + 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 + for ff in range(nf): + tt = nf-1-ff #reverse order + if not_used_faces[tt] == -1: + not_used_faces.pop(tt) + #end sweep on unused face list + if not_used_faces != []: + cur_obj, not_used_faces = my_create_mesh(objspec_list[2], objspec_list[3], not_used_faces, objspec_list[0][:9]+middlechar+"lone", []) + #my_meshtools.create_mesh(objspec_list[2], not_used_faces, "_unk") #vert, faces, name + #cur_obj = Blender.Object.GetSelected()[0] + if objspec_list[6] == 1: + set_subsurf(cur_obj) + obj_dict["lone"] = cur_obj + obj_dim_dict["lone"] = obj_size_pos(cur_obj) + obj_list.append(cur_obj) objspec_list[1] = obj_dict objspec_list[4] = obj_dim_dict - scene = Blender.Scene.GetCurrent () # get the current scene + scene = Blender.Scene.getCurrent () # get the current scene ob = Blender.Object.New ('Empty', objspec_list[0]+endchar) # make empty object scene.link (ob) # link the object into the scene ob.makeParent(obj_list, 1, 0) # set the root for created objects (no inverse, update scene hyerarchy (slow)) @@ -1543,7 +1304,7 @@ def lookup_imag(clip_list,ima_id): # =================================================== # === Create and assign image mapping to material === # =================================================== -def create_blok(surf, mat, clip_list, obj_size, obj_pos): +def create_blok(surf, mat, clip_list, dir_part, obj_size, obj_pos): def output_size_ofs(size, pos, blok): #just automate repetitive task @@ -1590,10 +1351,21 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos): if ima == None: tobj.pprint ( "***Block index image not within CLIP list? Quitting Block") break #safety check (paranoia setting) - img = ima['g_IMG'] + #look for images + img = load_image("",ima['NAME']) if img == None: - tobj.pprint ("***Failed to pre-allocate image %s found: giving up" % ima['BASENAME']) + tobj.pprint ( "***No image %s found: trying LWO file subdir" % ima['NAME']) + img = load_image(dir_part,ima['BASENAME']) + if img == None: + tobj.pprint ( "***No image %s found in directory %s: trying Images subdir" % (ima['BASENAME'], dir_part)) + img = load_image(dir_part+Blender.sys.sep+"Images",ima['BASENAME']) + if img == None: + tobj.pprint ( "***No image %s found: trying alternate Images subdir" % ima['BASENAME']) + img = load_image(dir_part+Blender.sys.sep+".."+Blender.sys.sep+"Images",ima['BASENAME']) + if img == None: + tobj.pprint ( "***No image %s found: giving up" % ima['BASENAME']) break + #lucky we are: we have an image tname = str(ima['ID']) if blok.has_key('CHAN'): tname = tname + "+" + blok['CHAN'] @@ -1634,6 +1406,8 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos): if blok.has_key('CHAN'): if blok['CHAN'] == 'COLR': tobj.pprint ("!!!Set Texture -> MapTo -> Col = %.3f" % set_dvar) + if set_blendmode == 0: + surf['g_IM'] = img #do not set anything, just save image object for later assignment if blok['CHAN'] == 'BUMP': mapflag = Blender.Texture.MapTo.NOR tobj.pprint ("!!!Set Texture -> MapTo -> Nor = %.3f" % set_dvar) @@ -1688,22 +1462,21 @@ def create_blok(surf, mat, clip_list, obj_size, obj_pos): # ======================================== # === 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): +#def create_material(surf_list, ptag_dict, obj, clip_list, uv_dict, dir_part): +def create_material(clip_list, surf_list, objspec, dir_part): if (surf_list == []) or (objspec[5] == {}) or (objspec[1] == {}): - tobj.pprint( "something getting wrong in update_material: dump follows ...") tobj.pprint( surf_list) tobj.pprint( objspec[5]) tobj.pprint( objspec[1]) + tobj.pprint( "something getting wrong in create_material ...") 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['NAME'] in ptag_dict.iterkeys()): + if (surf['NAME'] in ptag_dict.keys()): tobj.pprint ("#-------------------------------------------------------------------#") tobj.pprint ("Processing surface (material): %s" % surf['NAME']) tobj.pprint ("#-------------------------------------------------------------------#") @@ -1714,13 +1487,7 @@ def update_material(clip_list, objspec, surf_list): obj_size = obj_dim_dict[surf['NAME']][0] obj_pos = obj_dim_dict[surf['NAME']][1] tobj.pprint(surf) - #uncomment this if material pre-allocated by read_surf - mat = surf['g_MAT'] - if mat == None: - tobj.pprint ("Sorry, no pre-allocated material to update. Giving up for %s." % surf['NAME']) - break - #mat = Blender.Material.New(surf['NAME']) - #surf['g_MAT'] = mat + mat = Blender.Material.New(surf['NAME']) if surf.has_key('COLR'): mat.rgbCol = surf['COLR'] if surf.has_key('LUMI'): @@ -1733,12 +1500,8 @@ def update_material(clip_list, objspec, surf_list): mat.setRef(surf['DIFF']) #lwo [0.0, 1.0] - blender [0.0, 1.0] if surf.has_key('REFL'): mat.setRayMirr(surf['REFL']) #lwo [0.0, 1.0] - blender [0.0, 1.0] - #mat.setMode('RAYMIRROR') NO! this will reset all the other modes - #mat.mode |= Blender.Material.Modes.RAYMIRROR No more usable? - mm = mat.getMode() - mm |= Blender.Material.Modes.RAYMIRROR - mm &= 327679 #4FFFF this is implementation dependent - mat.setMode(mm) + #mat.setMode('RAYMIRROR') + mat.mode |= Blender.Material.Modes.RAYMIRROR #WARNING translucency not implemented yet check 2.36 API #if surf.has_key('TRNL'): # @@ -1749,27 +1512,55 @@ def update_material(clip_list, objspec, surf_list): mat.setHardness(glo) if surf.has_key('TRAN'): mat.setAlpha(1.0-surf['TRAN']) #lwo [0.0, 1.0] - blender [1.0, 0.0] - #mat.mode |= Blender.Material.Modes.RAYTRANSP - mm = mat.getMode() - mm |= Blender.Material.Modes.RAYTRANSP - mm &= 327679 #4FFFF this is implementation dependent - mat.setMode(mm) + mat.mode |= Blender.Material.Modes.RAYTRANSP if surf.has_key('RIND'): 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] - #mat.mode |= Blender.Material.Modes.RAYTRANSP - mm = mat.getMode() - mm |= Blender.Material.Modes.RAYTRANSP - mm &= 327679 #4FFFF this is implementation dependent - mat.setMode(mm) + mat.mode |= Blender.Material.Modes.RAYTRANSP if surf.has_key('BLOK') and surf['BLOK'] != []: #update the material according to texture. - create_blok(surf, mat, clip_list, obj_size, obj_pos) + create_blok(surf, mat, clip_list, dir_part, obj_size, obj_pos) #finished setting up the material - #end if exist SURF - #end loop on materials (SURFs) + #associate material to mesh + msh = cur_obj.getData() + mat_index = len(msh.getMaterials(1)) + msh.addMaterial(mat) + msh.mode |= Blender.NMesh.Modes.AUTOSMOOTH #smooth it anyway + msh.update(1) + for f in range(len(msh.faces)): + msh.faces[f].materialIndex = mat_index + msh.faces[f].smooth = 1 #smooth it anyway + msh.faces[f].mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway + msh.faces[f].transp = Blender.NMesh.FaceTranspModes['SOLID'] + msh.faces[f].flag = Blender.NMesh.FaceTranspModes['SOLID'] + if surf.has_key('SMAN'): + #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 + s = int(surf['SMAN']/3.1415926535897932384626433832795*180.0) #lwo in radians - blender in degrees + if msh.getMaxSmoothAngle() < s: msh.setMaxSmoothAngle(s) + #if surf.has_key('SIDE'): + # msh.faces[f].mode |= Blender.NMesh.FaceModes.TWOSIDE #set it anyway + if surf.has_key('TRAN') and mat.getAlpha()<1.0: + msh.faces[f].transp = Blender.NMesh.FaceTranspModes['ALPHA'] + if surf.has_key('UVNAME') and facesuv_dict.has_key(surf['UVNAME']): + #assign uv-data + msh.hasFaceUV(1) + #WARNING every block could have its own uvmap set of coordinate. take only the first one + facesuv_list = facesuv_dict[surf['UVNAME']] + #print "facesuv_list: ",f , facelist[f] + rev_face = revert(facesuv_list[facelist[f]]) + for vi in rev_face: + msh.faces[f].uv.append(uvcoords_dict[surf['UVNAME']][vi]) + if surf.has_key('g_IM'): + msh.faces[f].mode |= Blender.NMesh.FaceModes['TEX'] + msh.faces[f].image = surf['g_IM'] + #end loop over faces + msh.update(1) + mat_index += 1 + #end if exist faces ib this object belonging to surf + #end loop on surfaces return @@ -1787,13 +1578,13 @@ def read_faces_6(lwochunk): if polygon_type == 'PTCH': subsurf = 1 i = 0 while(i < lwochunk.chunksize-4): - if not i%1000 and my_meshtools.show_progress: + if not i%100 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): + for j in range(numfaceverts): index, index_size = read_vx(data) i += index_size facev.append(index) @@ -1811,4 +1602,3 @@ def fs_callback(filename): read(filename) Blender.Window.FileSelector(fs_callback, "Import LWO") - diff --git a/release/scripts/nendo_export.py b/release/scripts/nendo_export.py index ff9600769d0..830c4303f56 100644 --- a/release/scripts/nendo_export.py +++ b/release/scripts/nendo_export.py @@ -53,27 +53,12 @@ field. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | September 25, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Nendo File Format (*.nendo) | # +---------------------------------------------------------+ -# ***** 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, meshtools import struct, time, sys, os diff --git a/release/scripts/nendo_import.py b/release/scripts/nendo_import.py index e34101ad1e1..e7f3071bd99 100644 --- a/release/scripts/nendo_import.py +++ b/release/scripts/nendo_import.py @@ -48,27 +48,12 @@ edges during the course of modeling. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | September 25, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Nendo File Format (*.nendo) | # +---------------------------------------------------------+ -# ***** 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, meshtools import struct, time, sys, os diff --git a/release/scripts/obj_export.py b/release/scripts/obj_export.py index b57343e36dc..c220d66b709 100644 --- a/release/scripts/obj_export.py +++ b/release/scripts/obj_export.py @@ -21,7 +21,7 @@ Run this script from "File->Export" menu to export all meshes. # -------------------------------------------------------------------------- -# OBJ Export v1.0 by Campbell Barton (AKA Ideasman) +# OBJ Export v0.9b by Campbell Barton (AKA Ideasman) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -42,18 +42,12 @@ Run this script from "File->Export" menu to export all meshes. # ***** END GPL LICENCE BLOCK ***** # -------------------------------------------------------------------------- +#==================================================# +# New name based on old with a different extension # +#==================================================# +def newFName(ext): + return Get('filename')[: -len(Get('filename').split('.', -1)[-1]) ] + ext -import Blender -from Blender import Mesh, Scene, Window, sys, Image, Draw - -# 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: @@ -61,53 +55,10 @@ def fixName(name): else: return name.replace(' ', '_') -# Used to add the scene name into the filename without using odd chars -def saneFilechars(name): - for ch in ' /\\~!@#$%^&*()+=[];\':",./<>?\t\r\n': - name = name.replace(ch, '_') - return name -def sortPair(a,b): - return min(a,b), max(a,b) -def getMeshFromObject(object, name=None, mesh=None): - if mesh: - mesh.verts = None # Clear the mesh - else: - if not name: - mesh = Mesh.New() - else: - mesh = Mesh.New(name) - - - type = object.getType() - dataname = object.getData(1) - - try: - mesh.getFromObject(object.name) - except: - return None - - if type == 'Mesh': - tempMe = Mesh.Get( dataname ) - mesh.materials = tempMe.materials - mesh.degr = tempMe.degr - mesh.mode = tempMe.mode - else: - try: - # Will only work for curves!! - # Text- no material access in python interface. - # Surf- no python interface - # MBall- no material access in python interface. - - data = object.getData() - materials = data.getMaterials() - mesh.materials = materials - print 'assigning materials for non mesh' - except: - print 'Cant assign materials to', type - - return mesh + +from Blender import * global MTL_DICT @@ -115,17 +66,17 @@ global MTL_DICT # (material.name, image.name):matname_imagename # matname_imagename has gaps removed. MTL_DICT = {} -def write_mtl(filename): +def save_mtl(filename): global MTL_DICT - world = Blender.World.GetCurrent() + world = World.GetCurrent() if world: worldAmb = world.getAmb() else: worldAmb = (0,0,0) # Default value file = open(filename, "w") - file.write('# Blender MTL File: %s\n' % Blender.Get('filename').split('\\')[-1].split('/')[-1]) + file.write('# Blender MTL File: %s\n' % 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 in MTL_DICT.iteritems(): @@ -145,7 +96,7 @@ def write_mtl(filename): file.write('illum 2\n') # light normaly else: - mat = Blender.Material.Get(key[0]) + mat = Material.Get(key[0]) file.write('Ns %s\n' % round((mat.getHardness()-1) * 1.9607843137254901 ) ) # Hardness, convert blenders 1-511 to MTL's file.write('Ka %s %s %s\n' % tuple([round(c*mat.getAmb(), 6) for c in worldAmb]) ) # Ambient, uses mirror colour, file.write('Kd %s %s %s\n' % tuple([round(c*mat.getRef(), 6) for c in mat.getRGBCol()]) ) # Diffuse @@ -154,7 +105,7 @@ def write_mtl(filename): file.write('d %s\n' % round(mat.getAlpha(), 6)) # 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']: + if mat.getMode() & Material.Modes['SHADELESS']: file.write('illum 0\n') # ignore lighting elif mat.getSpec() == 0: file.write('illum 1\n') # no specular. @@ -169,7 +120,7 @@ def write_mtl(filename): elif key[0] != None: # 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: + if mtex and mtex.tex.type == Texture.Types.IMAGE: try: filename = mtex.tex.image.filename.split('\\')[-1].split('/')[-1] file.write('map_Kd %s\n' % filename) # Diffuse mapping image @@ -182,84 +133,24 @@ def write_mtl(filename): 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, imagename in MTL_DICT.iterkeys(): # Only use image name - if imagename != None: - uniqueImages[imagename] = None # Should use sets here. wait until Python 2.4 is default. - - # Now copy images - copyCount = 0 - - for imageName in uniqueImages.iterkeys(): - print imageName - bImage = Image.Get(imageName) - 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_UV=True, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False,\ -EXPORT_APPLY_MODIFIERS=True, EXPORT_BLEN_OBS=True,\ -EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=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. - ''' - print 'OBJ Export path: "%s"' % filename +def save_obj(filename): global MTL_DICT - temp_mesh_name = '~tmp-mesh' + time1 = sys.time() scn = Scene.GetCurrent() file = open(filename, "w") # Write Header - file.write('# Blender v%s OBJ File: %s\n' % (Blender.Get('version'), Blender.Get('filename').split('/')[-1].split('\\')[-1] )) - file.write('# www.blender3d.org\n') + file.write('# Blender OBJ File: %s\n' % (Get('filename').split('/')[-1].split('\\')[-1] )) + file.write('# www.blender.org\n') # Tell the obj file what material file to use. mtlfilename = '%s.mtl' % '.'.join(filename.split('.')[:-1]) file.write('mtllib %s\n' % ( mtlfilename.split('\\')[-1].split('/')[-1] )) - - # Get the container mesh. - if EXPORT_APPLY_MODIFIERS: - 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) - del meshName - del tempMesh - - - + # Initialize totals, these are updated each object totverts = totuvco = totno = 1 @@ -267,61 +158,28 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): globalNormals = {} # Get all meshs - for ob in objects: + for ob in scn.getChildren(): + #for ob in Object.GetSelected(): + try: + # Will work for non meshes now! :) + m = NMesh.GetRawFromObject(ob.name) + except: + continue - # Will work for non meshes now! :) - if EXPORT_APPLY_MODIFIERS or ob.getType() != 'Mesh': - m = getMeshFromObject(ob, temp_mesh_name, containerMesh) - if not m: - continue - - # We have a valid mesh - if m and EXPORT_APPLY_MODIFIERS and EXPORT_TRI: - # Add a dummy object to it. - oldmode = Mesh.Mode() - Mesh.Mode(Mesh.SelectModes['FACE']) - quadcount = 0 - for f in m.faces: - if len(f.v) == 4: - f.sel = 1 - quadcount +=1 - - if quadcount: - tempob = Blender.Object.New('Mesh') - tempob.link(m) - scn.link(tempob) - m.quadToTriangle(0) # more=0 shortest length - oldmode = Mesh.Mode(oldmode) - scn.unlink(tempob) - Mesh.Mode(oldmode) - - else: # We are a mesh. get the data. - m = ob.getData(mesh=1) + faces = [ f for f in m.faces if len(f) > 2 ] - faces = [ f for f in m.faces ] - if EXPORT_EDGES: - edges = [ ed for ed in m.edges ] - else: - edges = [] - - if not (len(faces)+len(edges)): # Make sure there is somthing to write + if not faces: # Make sure there is somthing to write continue # dont bother with this mesh. m.transform(ob.matrix) # # Crash Blender #materials = m.getMaterials(1) # 1 == will return None in the list. - materials = m.materials + materials = m.getMaterials() + - materialNames = [] 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. + materialNames = map(lambda mat: mat.name, materials) # Bug Blender, dosent account for null materials, still broken. else: materialNames = [] @@ -332,62 +190,52 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): # Sort by Material, then images # so we dont over context switch in the obj file. - if m.faceUV and EXPORT_UV: - faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, b.smooth))) - else: - faces.sort(lambda a,b: cmp((a.mat, a.smooth), (b.mat, b.smooth))) + faces.sort(lambda a,b: cmp((a.mat, a.image, a.smooth), (b.mat, b.image, 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: - obnamestring = '%s_%s' % (fixName(ob.name), fixName(ob.getData(1))) - 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) - + file.write('o %s_%s\n' % (fixName(ob.name), fixName(m.name))) # Write Object name # Vert for v in m.verts: file.write('v %.6f %.6f %.6f\n' % tuple(v.co)) # UV - if m.faceUV and EXPORT_UV: + if m.hasFaceUV(): for f in faces: for uvKey in f.uv: - uvKey = tuple(uvKey) if not globalUVCoords.has_key(uvKey): globalUVCoords[uvKey] = totuvco totuvco +=1 file.write('vt %.6f %.6f 0.0\n' % uvKey) # NORMAL, Smooth/Non smoothed. - if EXPORT_NORMALS: - for f in faces: - if f.smooth: - for v in f.v: - noKey = tuple(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 = tuple(f.no) + + for f in faces: + if f.smooth: + for v in f.v: + noKey = tuple(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 = tuple(f.no) + if not globalNormals.has_key( noKey ): + globalNormals[noKey] = totno + totno +=1 + file.write('vn %.6f %.6f %.6f\n' % noKey) uvIdx = 0 for f in faces: # MAKE KEY - if EXPORT_UV and m.faceUV and f.image: # Object is always true. + if f.image: # Object is always true. key = materialNames[f.mat], f.image.name else: key = materialNames[f.mat], None # No image, use None instead. @@ -395,34 +243,31 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): # 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. - matstring = '(null)' - file.write('usemtl (null)\n') # mat, image - - else: - try: # Faster to try then 2x dict lookups. - # We have the material, just need to write the context switch, - matstring = MTL_DICT[key] - - - except KeyError: - # 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: - matstring = MTL_DICT[key] ='%s' % fixName(key[0]) - else: - matstring = MTL_DICT[key] = '%s_%s' % (fixName(key[0]), fixName(key[1])) + elif key[0] == None and key[1] == None: + # Write a null material, since we know the context has changed. + file.write('usemtl (null)\n') # mat, image - if EXPORT_GROUP_BY_MAT: - file.write('g %s_%s_%s\n' % (fixName(ob.name), fixName(ob.getData(1)), matstring) ) # can be mat_image or (null) - file.write('usemtl %s\n' % matstring) # can be mat_image or (null) + else: + try: # Faster to try then 2x dict lookups. + + # We have the material, just need to write the context switch, + file.write('usemtl %s\n' % MTL_DICT[key]) # mat, image + + except KeyError: + # 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: + tmp_matname = MTL_DICT[key] ='%s' % fixName(key[0]) + file.write('usemtl %s\n' % tmp_matname) # mat, image + + else: + tmp_matname = MTL_DICT[key] = '%s_%s' % (fixName(key[0]), fixName(key[1])) + file.write('usemtl %s\n' % tmp_matname) # mat, image contextMat = key @@ -434,198 +279,57 @@ EXPORT_GROUP_BY_OB=False, EXPORT_GROUP_BY_MAT=False): contextSmooth = f.smooth file.write('f') - if m.faceUV and EXPORT_UV: - 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,\ - globalUVCoords[ tuple(f.uv[vi]) ],\ - globalNormals[ tuple(v.no) ])) # vert, uv, normal - else: # No smoothing, face normals - no = globalNormals[ tuple(f.no) ] - for vi, v in enumerate(f.v): - file.write( ' %d/%d/%d' % (\ - v.index+totverts,\ - globalUVCoords[ tuple(f.uv[vi]) ],\ - no)) # vert, uv, normal - - else: # No Normals + if m.hasFaceUV(): + if f.smooth: # Smoothed, use vertex normals for vi, v in enumerate(f.v): - file.write( ' %d/%d' % (\ + file.write( ' %d/%d/%d' % (\ v.index+totverts,\ - globalUVCoords[ tuple(f.uv[vi])])) # vert, uv - - + globalUVCoords[ f.uv[vi] ],\ + globalNormals[ tuple(v.no) ])) # vert, uv, normal + else: # No smoothing, face normals + no = globalNormals[ tuple(f.no) ] + for vi, v in enumerate(f.v): + file.write( ' %d/%d/%d' % (\ + v.index+totverts,\ + globalUVCoords[ f.uv[vi] ],\ + no)) # vert, uv, normal + 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[ tuple(v.no) ])) - else: # No smoothing, face normals - no = globalNormals[ tuple(f.no) ] - for v in f.v: - file.write( ' %d//%d' % (\ - v.index+totverts,\ - no)) - else: # No Normals + if f.smooth: # Smoothed, use vertex normals for v in f.v: - file.write( ' %d' % (\ - v.index+totverts)) + file.write( ' %d//%d' % (\ + v.index+totverts,\ + globalNormals[ tuple(v.no) ])) + else: # No smoothing, face normals + no = globalNormals[ tuple(f.no) ] + for v in f.v: + file.write( ' %d//%d' % (\ + v.index+totverts,\ + no)) file.write('\n') - # Write edges. - if EXPORT_EDGES: - edgeUsers = {} - for f in faces: - for i in xrange(len(f.v)): - faceEdgeVKey = sortPair(f.v[i].index, f.v[i-1].index) - - # We dont realy need to keep count. Just that a face uses it - # so dont export. - edgeUsers[faceEdgeVKey] = 1 - - for ed in edges: - edgeVKey = sortPair(ed.v1.index, ed.v2.index) - if not edgeUsers.has_key(edgeVKey): # No users? Write the edge. - file.write('f %d %d\n' % (edgeVKey[0]+totverts, edgeVKey[1]+totverts)) - # Make the indicies global rather then per mesh totverts += len(m.verts) 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) - + save_mtl(mtlfilename) + print "obj export time: %.2f" % (sys.time() - time1) -def write_ui(filename): - - for s in Window.GetScreenInfo(): - Window.QHandle(s['id']) - - EXPORT_APPLY_MODIFIERS = Draw.Create(1) - EXPORT_TRI = Draw.Create(0) - EXPORT_EDGES = Draw.Create(0) - EXPORT_NORMALS = 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(1) - EXPORT_GROUP_BY_OB = Draw.Create(0) - EXPORT_GROUP_BY_MAT = Draw.Create(0) - - - # Get USER Options - pup_block = [\ - ('Mesh Options...'),\ - ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object. May break vert order for morph targets.'),\ - ('Triangulate', EXPORT_TRI, 'Triangulate quads (Depends on "Apply Modifiers").'),\ - ('Edges', EXPORT_EDGES, 'Edges not connected to faces.'),\ - ('Normals', EXPORT_NORMALS, 'Export vertex normal data (Ignored on import).'),\ - ('UVs', EXPORT_UV, 'Export texface UV coords.'),\ - ('Materials', EXPORT_MTL, 'Write a seperate MTL file with the OBJ.'),\ - ('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 seperate OBJ file.'),\ - ('Animation', EXPORT_ANIMATION, 'Each frame as a numbered OBJ file.'),\ - ('Copy Images', EXPORT_COPY_IMAGES, 'Copy image files to the export directory, never overwrite.'),\ - ('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 - - Window.WaitCursor(1) - - EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val - EXPORT_TRI = EXPORT_TRI.val - EXPORT_EDGES = EXPORT_EDGES.val - EXPORT_NORMALS = EXPORT_NORMALS.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 - - - - 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' % saneFilechars(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(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 = Blender.Object.GetSelected() # Export Context - else: - export_objects = scn.getChildren() - - # EXPORT THE FILE. - write(''.join(context_name), export_objects,\ - EXPORT_TRI, EXPORT_EDGES, EXPORT_NORMALS,\ - EXPORT_UV, EXPORT_MTL, EXPORT_COPY_IMAGES,\ - EXPORT_APPLY_MODIFIERS,\ - EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT) - - Blender.Set('curframe', orig_frame) - - # Restore old active scene. - orig_scene.makeCurrent() - Window.WaitCursor(0) +Window.FileSelector(save_obj, 'Export Wavefront OBJ', newFName('obj')) +''' +TIME = sys.time() +import os +OBJDIR = '/obj_out/' +for scn in Scene.Get(): + scn.makeCurrent() + obj = OBJDIR + scn.name + print obj + save_obj(obj) -if __name__ == '__main__': - Window.FileSelector(write_ui, 'Export Wavefront OBJ', sys.makename(ext='.obj')) +print "TOTAL EXPORT TIME: ", sys.time() - TIME +''' diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py index f2bcaf853e7..d8788f6d042 100644 --- a/release/scripts/obj_import.py +++ b/release/scripts/obj_import.py @@ -269,6 +269,8 @@ def comprehansiveImageLoad(imagePath, filePath): break return img + + # No go. print '\t\tImage Not Found "%s"' % imagePath return None @@ -276,6 +278,22 @@ def comprehansiveImageLoad(imagePath, filePath): + + + + + + + + + + + + + + + + #==================================================================================# # This function sets textures defined in .mtl file # @@ -359,7 +377,9 @@ def load_mtl(dir, mtl_file, meshDict, materialDict): l = fileLines[lIdx].split() # Detect a line that will be ignored - if len(l) == 0 or l[0].startswith('#'): + if len(l) == 0: + pass + elif l[0] == '#' or len(l) == 0: pass elif l[0] == 'newmtl': currentMat = getMat('_'.join(l[1:]), materialDict) # Material should alredy exist. @@ -408,27 +428,30 @@ def load_mtl(dir, mtl_file, meshDict, materialDict): # Returns unique name of object/mesh (preserve overwriting existing meshes) # #===========================================================================# def getUniqueName(name): - newName = name[:19] # 19 chars is the longest name. + newName = name uniqueInt = 0 - while newName in getUniqueName.uniqueNames: - newName = '%s.%.3i' % (name[:15], uniqueInt) - uniqueInt +=1 - getUniqueName.uniqueNames.append(newName) - return newName -getUniqueName.uniqueNames = [] + while 1: + try: + ob = Object.Get(newName) + # Okay, this is working, so lets make a new name + newName = '%s.%d' % (name, uniqueInt) + uniqueInt +=1 + except AttributeError: + if newName not in NMesh.GetNames(): + return newName + else: + newName = '%s.%d' % (name, uniqueInt) + uniqueInt +=1 #==================================================================================# # This loads data from .obj file # #==================================================================================# -def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): +def load_obj(file): print '\nImporting OBJ file: "%s"' % file time1 = sys.time() - getUniqueName.uniqueNames.extend( [ob.name for ob in Object.Get()] ) - getUniqueName.uniqueNames.extend( NMesh.GetNames() ) - # Deselect all objects in the scene. # do this first so we dont have to bother, with objects we import for ob in Scene.GetCurrent().getChildren(): @@ -444,9 +467,9 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): DIR = stripFile(file) tempFile = open(file, 'r') - fileLines = tempFile.readlines() + fileLines = tempFile.readlines() tempFile.close() - del tempFile + uvMapList = [] # store tuple uv pairs here # This dummy vert makes life a whole lot easier- @@ -466,10 +489,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): currentMat = nullMat # Use this mat. currentImg = None # Null image is a string, otherwise this should be set to an image object.\ - if IMPORT_SMOOTH_ALL: - currentSmooth = True - else: - currentSmooth = False + currentSmooth = False # Store a list of unnamed names currentUnnamedGroupIdx = 1 @@ -483,36 +503,63 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): #==================================================================================# # Load all verts first (texture verts too) # #==================================================================================# - + nonVertFileLines = [] + smoothingGroups = {} + materialDict = {} # Store all imported materials as unique dict, names are key + lIdx = 0 print '\tfile length: %d' % len(fileLines) - # Ignore normals and comments. - fileLines = [lsplit for l in fileLines if not l.startswith('vn') if not l.startswith('#') for lsplit in (l.split(),) if lsplit] - Vert = NMesh.Vert - vertList = [Vert(float(l[1]), float(l[2]), float(l[3]) ) for l in fileLines if l[0] == 'v'] - uvMapList = [(float(l[1]), float(l[2])) for l in fileLines if l[0] == 'vt'] - smoothingGroups = dict([('_'.join(l[1:]), None) for l in fileLines if l[0] == 's' ]) - materialDict = dict([('_'.join(l[1:]), None) for l in fileLines if l[0] == 'usemtl']) # Store all imported materials as unique dict, names are key - print '\tvert:%i texverts:%i smoothgroups:%i materials:%s' % (len(vertList), len(uvMapList), len(smoothingGroups), len(materialDict)) + while lIdx < len(fileLines): + # Ignore vert normals + if fileLines[lIdx].startswith('vn'): + lIdx+=1 + continue + + # Dont Bother splitting empty or comment lines. + if len(fileLines[lIdx]) == 0 or\ + fileLines[lIdx][0] == '\n' or\ + fileLines[lIdx][0] == '#': + pass + + else: + fileLines[lIdx] = fileLines[lIdx].split() + l = fileLines[lIdx] + + # Splitting may + if len(l) == 0: + pass + # Verts + elif l[0] == 'v': + vertList.append( NMesh.Vert(float(l[1]), float(l[2]), float(l[3]) ) ) + + # UV COORDINATE + elif l[0] == 'vt': + uvMapList.append( (float(l[1]), float(l[2])) ) + + # Smoothing groups, make a list of unique. + elif l[0] == 's': + if len(l) > 1: + smoothingGroups['_'.join(l[1:])] = None # Can we assign something more usefull? cant use sets yet + + # Keep Smoothing group line + nonVertFileLines.append(l) + + # Smoothing groups, make a list of unique. + elif l[0] == 'usemtl': + if len(l) > 1: + materialDict['_'.join(l[1:])] = None # Can we assign something more usefull? cant use sets yet + + # Keep Smoothing group line + nonVertFileLines.append(l) + + else: + nonVertFileLines.append(l) + lIdx+=1 - # Replace filelines, Excluding v excludes "v ", "vn " and "vt " - # Remove any variables we may have created. - try: del _dummy - except: pass - try: del _x - except: pass - try: del _y - except: pass - try: del _z - except: pass - try: del lsplit - except: pass - del Vert - - # With negative values this is used a lot. make faster access. - len_uvMapList = len(uvMapList) - len_vertList = len(vertList) + del fileLines + fileLines = nonVertFileLines + del nonVertFileLines # Only want unique keys anyway smoothingGroups['(null)'] = None # Make sure we have at least 1. @@ -525,7 +572,7 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): # Make a list of all unused vert indicies that we can copy from - VERT_USED_LIST = [0]*len_vertList + VERT_USED_LIST = [0]*len(vertList) # Here we store a boolean list of which verts are used or not # no we know weather to add them to the current mesh @@ -537,9 +584,9 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): # We ignore it when naming the object. currentObjectName = 'unnamed_obj_0' # If we cant get one, use this - #meshDict = {} # The 3 variables below are stored in a tuple within this dict for each mesh + meshDict = {} # The 3 variables below are stored in a tuple within this dict for each mesh currentMesh = NMesh.GetRaw() # The NMesh representation of the OBJ group/Object - #currentUsedVertList = {} # A Dict of smooth groups, each smooth group has a list of used verts and they are generated on demand so as to save memory. + currentUsedVertList = {} # A Dict of smooth groups, each smooth group has a list of used verts and they are generated on demand so as to save memory. currentMaterialMeshMapping = {} # Used to store material indicies so we dont have to search the mesh for materials every time. # Every mesh has a null smooth group, this is used if there are no smooth groups in the OBJ file. @@ -548,13 +595,14 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): # For direct accsess to the Current Meshes, Current Smooth Groups- Used verts. # This is of course context based and changes on the fly. - # Set the initial '(null)' Smooth group, every mesh has one. currentUsedVertListSmoothGroup = VERT_USED_LIST[:] - currentUsedVertList= {currentSmoothGroup: currentUsedVertListSmoothGroup } + + # Set the initial '(null)' Smooth group, every mesh has one. + currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup # 0:NMesh, 1:SmoothGroups[UsedVerts[0,0,0,0]], 2:materialMapping['matname':matIndexForThisNMesh] - meshDict = {currentObjectName: (currentMesh, currentUsedVertList, currentMaterialMeshMapping) } + meshDict[currentObjectName] = (currentMesh, currentUsedVertList, currentMaterialMeshMapping) # Only show the bad uv error once badObjUvs = 0 @@ -563,23 +611,20 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): #currentMesh.verts.append(vertList[0]) # So we can sync with OBJ indicies where 1 is the first item. - if len_uvMapList > 1: + if len(uvMapList) > 1: currentMesh.hasFaceUV(1) # Turn UV's on if we have ANY texture coords in this obj file. #==================================================================================# # Load all faces into objects, main loop # #==================================================================================# - #lIdx = 0 + lIdx = 0 # Face and Object loading LOOP - #while lIdx < len(fileLines): - # l = fileLines[lIdx] - #for lIdx - for l in fileLines: - if len(l) == 0: - continue + while lIdx < len(fileLines): + l = fileLines[lIdx] + # FACE - elif l[0] == 'f': + if l[0] == 'f': # Make a face with the correct material. # Add material to mesh @@ -601,19 +646,15 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): vtIdxLs = [] - fHasUV = len_uvMapList # Assume the face has a UV until it sho it dosent, if there are no UV coords then this will start as 0. + fHasUV = len(uvMapList) # Assume the face has a UV until it sho it dosent, if there are no UV coords then this will start as 0. for v in l[1:]: # OBJ files can have // or / to seperate vert/texVert/normal # this is a bit of a pain but we must deal with it. objVert = v.split('/') # Vert Index - OBJ supports negative index assignment (like python) - index = int(objVert[0])-1 - # Account for negative indicies. - if index < 0: - index = len_vertList+index+1 - vIdxLs.append(index) + vIdxLs.append(int(objVert[0])-1) if fHasUV: # UV index = 0 # Dummy var @@ -621,17 +662,15 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): index = vIdxLs[-1] elif objVert[1]: # != '' # Its possible that theres no texture vert just he vert and normal eg 1//2 index = int(objVert[1])-1 - if index < 0: - index = len_uvMapList+index+1 - - if len_uvMapList > index: + + if len(uvMapList) > index: vtIdxLs.append(index) # Seperate UV coords else: # BAD FILE, I have found this so I account for it. # INVALID UV COORD # Could ignore this- only happens with 1 in 1000 files. badObjFaceTexCo +=1 - vtIdxLs.append(1) + vtIdxLs.append(0) fHasUV = 0 @@ -639,26 +678,12 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): # The OBJ file would have to be corrupt or badly written for thi to happen # but account for it anyway. if len(vtIdxLs) > 0: - if vtIdxLs[-1] > len_uvMapList: + if vtIdxLs[-1] > len(uvMapList): fHasUV = 0 badObjUvs +=1 # ERROR, Cont # Quads only, we could import quads using the method below but it polite to import a quad as a quad. - #print lIdx, len(vIdxLs), len(currentUsedVertListSmoothGroup) - #print fileLines[lIdx] - if len(vIdxLs) == 2: - if IMPORT_EDGES: - # Edge - for i in (0,1): - if currentUsedVertListSmoothGroup[vIdxLs[i]] == 0: - faceQuadVList[i] = vertList[vIdxLs[i]] - currentMesh.verts.append(faceQuadVList[i]) - currentUsedVertListSmoothGroup[vIdxLs[i]] = len(currentMesh.verts)-1 - else: - faceQuadVList[i] = currentMesh.verts[currentUsedVertListSmoothGroup[vIdxLs[i]]] - - currentMesh.addEdge(faceQuadVList[0], faceQuadVList[1]) - elif len(vIdxLs) == 4: + if len(vIdxLs) == 4: # Have found some files where wach face references the same vert # - This causes a bug and stopts the import so lets check here @@ -726,20 +751,22 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): if len(l) == 1: currentSmooth = True currentSmoothGroup = '(null)' + try: + currentUsedVertListSmoothGroup = currentUsedVertList[currentSmoothGroup] + except KeyError: + currentUsedVertListSmoothGroup = VERT_USED_LIST[:] + currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup + else: - if l[1] == 'off': # We all have a null group so dont need to try, will try anyway to avoid code duplication. - if not IMPORT_SMOOTH_ALL: - currentSmooth = False + if l[1] == 'off': + currentSmooth = False currentSmoothGroup = '(null)' + # We all have a null group so dont need to try + currentUsedVertListSmoothGroup = currentUsedVertList['(null)'] else: currentSmooth = True currentSmoothGroup = '_'.join(l[1:]) - try: - currentUsedVertListSmoothGroup = currentUsedVertList[currentSmoothGroup] - except KeyError: - currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup = VERT_USED_LIST[:] - - + # OBJECT / GROUP elif l[0] == 'o' or l[0] == 'g': @@ -756,10 +783,10 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): else: # No name given # Make a new empty name if l[0] == 'g': # Make a blank group name - currentObjectName = 'unnamed_grp_%.4d' % currentUnnamedGroupIdx + currentObjectName = 'unnamed_grp_%d' % currentUnnamedGroupIdx currentUnnamedGroupIdx +=1 else: # is an object. - currentObjectName = 'unnamed_ob_%.4d' % currentUnnamedObjectIdx + currentObjectName = 'unnamed_ob_%d' % currentUnnamedObjectIdx currentUnnamedObjectIdx +=1 @@ -774,10 +801,11 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): currentUsedVertList = {} # Sg is a string - ########currentSmoothGroup = '(null)' # From examplesm changing the g/o shouldent change the smooth group. - currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup = VERT_USED_LIST[:] - + currentSmoothGroup = '(null)' + currentUsedVertListSmoothGroup = VERT_USED_LIST[:] + currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup currentMaterialMeshMapping = {} + meshDict[currentObjectName] = (currentMesh, currentUsedVertList, currentMaterialMeshMapping) currentMesh.hasFaceUV(1) contextMeshMatIdx = -1 @@ -794,13 +822,8 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): contextMeshMatIdx -1 # For new meshes switch smoothing groups to null - ########currentSmoothGroup = '(null)' # From examplesm changing the g/o shouldent change the smooth group. - try: - currentUsedVertListSmoothGroup = currentUsedVertList[currentSmoothGroup] - except: - currentUsedVertList[currentSmoothGroup] = currentUsedVertListSmoothGroup = VERT_USED_LIST[:] - - + currentSmoothGroup = '(null)' + currentUsedVertListSmoothGroup = currentUsedVertList[currentSmoothGroup] # MATERIAL elif l[0] == 'usemtl': @@ -836,12 +859,11 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): # MATERIAL FILE elif l[0] == 'mtllib': mtl_fileName.append(' '.join(l[1:]) ) # SHOULD SUPPORT MULTIPLE MTL? - #lIdx+=1 + lIdx+=1 # Applies material properties to materials alredy on the mesh as well as Textures. - if IMPORT_MTL: - for mtl in mtl_fileName: - load_mtl(DIR, mtl, meshDict, materialDict) + for mtl in mtl_fileName: + load_mtl(DIR, mtl, meshDict, materialDict) importedObjects = [] @@ -872,78 +894,45 @@ def load_obj(file, IMPORT_MTL=1, IMPORT_EDGES=1, IMPORT_SMOOTH_ALL=0): print "obj import time: ", sys.time() - time1 - -def load_obj_ui(file): - IMPORT_MTL = Draw.Create(1) - IMPORT_DIR = Draw.Create(0) - IMPORT_NEW_SCENE = Draw.Create(0) - IMPORT_EDGES = Draw.Create(1) - IMPORT_SMOOTH_ALL = Draw.Create(0) +# Batch directory loading. +def load_obj_dir(obj_dir): - - # Get USER Options - pup_block = [\ - ('Material (*.mtl)', IMPORT_MTL, 'Imports material settings and images from the obj\'s .mtl file'),\ - ('All *.obj\'s in dir', IMPORT_DIR, 'Import all obj files in this dir (avoid overlapping data with "Create scene")'),\ - ('Create scene', IMPORT_NEW_SCENE, 'Imports each obj into its own scene, named from the file'),\ - 'Geometry...',\ - ('Edges', IMPORT_EDGES, 'Import faces with 2 verts as in edge'),\ - ('Smooths all faces', IMPORT_SMOOTH_ALL, 'Smooth all faces even if they are not in a smoothing group'),\ - ] - - if not os: - pup_block.pop(1) # Make sure this is the IMPORT_DIR option that requires OS - - if not Draw.PupBlock('Import...', pup_block): - return - - Window.WaitCursor(1) - Window.DrawProgressBar(0, '') + # Strip file + obj_dir = stripFile(obj_dir) time = sys.time() - IMPORT_MTL = IMPORT_MTL.val - IMPORT_DIR = IMPORT_DIR.val - IMPORT_NEW_SCENE = IMPORT_NEW_SCENE.val - IMPORT_EDGES = IMPORT_EDGES.val - IMPORT_SMOOTH_ALL = IMPORT_SMOOTH_ALL.val + objFiles = [f for f in os.listdir(obj_dir) if f.lower().endswith('obj')] - #orig_scene = Scene.GetCurrent() - - obj_dir = stripFile(file) - if IMPORT_DIR: - obj_files = [(obj_dir,f) for f in os.listdir(obj_dir) if f.lower().endswith('obj')] - else: - obj_files = [(obj_dir,stripPath(file))] - - obj_len = len(obj_files) + Window.DrawProgressBar(0, '') count = 0 - for d, f in obj_files: - count+= 1 - if not sys.exists(d+f): - print 'Error: "%s%s" does not exist' % (d,f) - else: - if IMPORT_NEW_SCENE: - scn = Scene.New('.'.join(f.split('.')[0:-1])) - scn.makeCurrent() - - - Window.DrawProgressBar((float(count)/obj_len) - 0.01, '%s: %i of %i' % (f, count, obj_len)) - load_obj(d+f, IMPORT_MTL, IMPORT_EDGES, IMPORT_SMOOTH_ALL) - - - #orig_scene.makeCurrent() # We can leave them in there new scene. + obj_len = len(objFiles) + for obj in objFiles: + count+=1 + + newScn = Scene.New(obj) + newScn.makeCurrent() + + Window.DrawProgressBar((float(count)/obj_len) - 0.01, '%s: %i of %i' % (obj, count, obj_len)) + + load_obj(obj_dir + obj) + Window.DrawProgressBar(1, '') - Window.WaitCursor(0) - - if count > 1: - print 'Total obj import "%s" dir: %.2f' % (obj_dir, sys.time() - time) - + print 'Total obj import "%s" dir: %.2f' % (obj_dir, sys.time() - time) + def main(): - Window.FileSelector(load_obj_ui, 'Import a Wavefront OBJ') - - + TEXT_IMPORT = 'Import a Wavefront OBJ' + TEXT_BATCH_IMPORT = 'Import *.obj to Scenes' + + if Window.GetKeyQualifiers() & Window.Qual.SHIFT: + if not os: + Draw.PupMenu('Module "os" not found, needed for batch load, using normal selector.') + Window.FileSelector(load_obj, TEXT_IMPORT) + else: + Window.FileSelector(load_obj_dir, TEXT_BATCH_IMPORT) + else: + Window.FileSelector(load_obj, TEXT_IMPORT) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/release/scripts/off_export.py b/release/scripts/off_export.py index 53bd9ef6a6f..8465720478f 100644 --- a/release/scripts/off_export.py +++ b/release/scripts/off_export.py @@ -28,34 +28,17 @@ Notes:
Only exports a single selected mesh. """ -# $Id: -# # +---------------------------------------------------------+ # | Copyright (c) 2002 Anthony D'Agostino | # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | February 3, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Object File Format (*.off) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/off_import.py b/release/scripts/off_import.py index 452a91ffc5f..cbaab483154 100644 --- a/release/scripts/off_import.py +++ b/release/scripts/off_import.py @@ -29,34 +29,18 @@ Notes:
UV Coordinate support has been added. """ -# $Id: -# + # +---------------------------------------------------------+ # | Copyright (c) 2002 Anthony D'Agostino | # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | February 3, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Object File Format (*.off) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/radiosity_export.py b/release/scripts/radiosity_export.py index 43ec7d9838c..4f7766c3dd5 100644 --- a/release/scripts/radiosity_export.py +++ b/release/scripts/radiosity_export.py @@ -46,27 +46,12 @@ specular highlights to the vertex colors. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | April 11, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Radiosity File Format (*.radio) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/radiosity_import.py b/release/scripts/radiosity_import.py index d2d45568b99..704a87becf5 100644 --- a/release/scripts/radiosity_import.py +++ b/release/scripts/radiosity_import.py @@ -31,27 +31,12 @@ file to open. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | April 11, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Radiosity File Format (*.radio) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/raw_export.py b/release/scripts/raw_export.py index b8469adc5f4..f52f0404e19 100644 --- a/release/scripts/raw_export.py +++ b/release/scripts/raw_export.py @@ -25,6 +25,7 @@ Usage:
Select meshes to be exported and run this script from "File->Export" menu. """ + # $Id$ # # +---------------------------------------------------------+ @@ -32,27 +33,12 @@ Usage:
# | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | April 28, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write RAW Triangle File Format (*.raw) | # +---------------------------------------------------------+ -# ***** 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, meshtools import sys #import time diff --git a/release/scripts/raw_import.py b/release/scripts/raw_import.py index a452bb4b40e..c793791664f 100644 --- a/release/scripts/raw_import.py +++ b/release/scripts/raw_import.py @@ -38,27 +38,12 @@ tolerance. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | April 28, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write RAW Triangle File Format (*.raw) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/save_theme.py b/release/scripts/save_theme.py index 936c12a46f8..79205c0d478 100644 --- a/release/scripts/save_theme.py +++ b/release/scripts/save_theme.py @@ -2,14 +2,14 @@ """ Name: 'Save Current Theme...' -Blender: 240 +Blender: 237 Group: 'Export' -Tooltip: 'Save current theme as a BPython script' +Tooltip: 'Save current theme as a bpython script' """ __author__ = "Willian P. Germano" __url__ = ("blender", "elysiun") -__version__ = "2.41 2006/01/16" +__version__ = "2.37 2005/06/06" __bpydoc__ = """\ This script saves the current Theme in Blender as a Blender Python script. @@ -39,32 +39,15 @@ some information on it before sharing it with others. # $Id$ # # -------------------------------------------------------------------------- -# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig com br +# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br # -------------------------------------------------------------------------- +# Released under the Blender Artistic License (BAL): +# http://download.blender.org/documentation/html/x21254.html +# # The scripts generated by this script are put under Public Domain by # default, but you are free to edit the ones you generate with this script # and change their license to another one of your choice. # -------------------------------------------------------------------------- -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# Copyright (C) 2005: 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.Window import Theme, FileSelector @@ -87,13 +70,13 @@ def write_theme(filename): # \"\"\" # Name: '%s' -# Blender: 241 +# Blender: 237 # Group: 'Themes' # Tooltip: 'Change current theme' # \"\"\" __%s__ = "????" -__%s__ = "2.41" +__%s__ = "2.37" __%s__ = ["blender"] __%s__ = \"\"\"\\ You can edit this section to write something about your script that can diff --git a/release/scripts/skin.py b/release/scripts/skin.py index c319de31915..adf49b1af7b 100644 --- a/release/scripts/skin.py +++ b/release/scripts/skin.py @@ -483,9 +483,7 @@ def main(): if choice == 1 and len(edgeOrderedList) > 2: # Loop skin2EdgeLoops(edgeOrderedList[0], edgeOrderedList[-1], me, ob, 0) - print '\nArray done in %.4f sec.' % (sys.time()-time1) me.update(1, 1, 0) if is_editmode: Window.EditMode(1) -if __name__ == '__main__': - main() +main() diff --git a/release/scripts/slp_import.py b/release/scripts/slp_import.py index 4944c34045d..246f84ec02b 100644 --- a/release/scripts/slp_import.py +++ b/release/scripts/slp_import.py @@ -36,27 +36,12 @@ tolerance. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | May 3, 2004 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write SLP Triangle File Format (*.slp) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/tex2uvbaker.py b/release/scripts/tex2uvbaker.py index 2a25a3d8516..0324d9c0290 100644 --- a/release/scripts/tex2uvbaker.py +++ b/release/scripts/tex2uvbaker.py @@ -2,7 +2,7 @@ """ Registration info for Blender menus: Name: 'Texture Baker' -Blender: 239 +Blender: 236 Group: 'UV' Tooltip: 'Procedural to uvmapped texture baker' """ @@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)" __url__ = ("blender", "elysiun", "Official Page, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_mesh3d2uv2d_en.htm", "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender") -__version__ = "0.3.2 2005/12/28" +__version__ = "0.3.1 2005/10/21" __bpydoc__ = """\ This script "bakes" Blender procedural materials (including textures): it saves @@ -49,10 +49,6 @@ Notes:
# # Released under Blender Artistic Licence # -# 0.3.2 -# blender 2.40 update to deal with the new shape -# key system . -# # 0.3.1 # stupid bug correction # @@ -437,85 +433,6 @@ def REST_Shadeless(SHADEDict): # release : 0.2.6 , 2005/05/29 , end #----------------------------------- - -#----------------------------------- -# release : 0.3.2 , 2005/12/28 , 13h00 -#----------------------------------- -def Blender240update(MESH2,FRAME): - """ -# --------------------------- -# Function Blender240update -# -# IN : MESH2 a mesh data bloc -# FRAME , the animation frame limit -# -# ADD : an ipo curve to the shape key -# named "Key 1" -# -# OUT : nothing -# --------------------------- - """ - # --------------------------- - # recuperation des clef de morphing pour ce mesh - # --------------------------- - key = MESH2.getKey() - # --------------------------- - # recuperation de l'Ipo - # --------------------------- - ipo = key.ipo - # --------------------------- - # si l'ipo n'existe pas on la cree - # --------------------------- - if ipo == None: - noipo = Blender.Ipo.New("Key","keyipo") - key.ipo = noipo - # --------------------------- - # raccourci de l'expression - # --------------------------- - ipo = key.ipo - # --------------------------- - # identification de la clef de morphing - # --------------------------- - keyidentity = "Key 1" - # --------------------------- - # recuperation de la courbe correspondante - # c'est toujours la courbe 0 - # --------------------------- - ipocurve = ipo.getCurve(0) - # --------------------------- - # si la courbe n'existe pas (normalement, elle n'existe pas mais - # on gère le risque pour faciliter une eventuelle récupération de - # cette fonction dans un autre script ou pour les cas , certe peu - # probable, ou blender viendrait a etre modifie pour les ajouter - # automatiquement ) on la cree ... - # --------------------------- - if ipocurve == None: - ipocurve = ipo.addCurve(keyidentity) - # --------------------------- - # On applique l'attribut d'inetrpolation qui permet d'avoir - # une ligne droite - # --------------------------- - ipocurve.setInterpolation("Linear") - # --------------------------- - # On retire tous les sommets qui pourraient se trouver sur la - # courbe (dans l'état actuel, cette opération est une sécurité - # superflue ) . - # --------------------------- - while len(ipocurve.getPoints()) > 0: - ipocurve.delBezier(0) - ipocurve.recalc() - # --------------------------- - # On ajouter les sommets necessaires ... - # --------------------------- - ipocurve.addBezier((-1,1)) - # --------------------------- - # ... ce dernire n'est peut-être pas absolument obligatoire . - # --------------------------- - ipocurve.addBezier((FRAME+1,1)) -#----------------------------------- -# release : 0.3.2 , 2005/12/28 , end -#----------------------------------- - def Mesh2UVCoord (LIMIT): """ # --------------------------- @@ -527,7 +444,7 @@ def Mesh2UVCoord (LIMIT): """ global PUTRAW, FRAME, SCENELAYERS - try: + try : MESH3D = Object.GetSelected()[0] if MESH3D.getType() == 'Mesh': MESH = MESH3D.getData() @@ -537,8 +454,7 @@ def Mesh2UVCoord (LIMIT): CurSCENE=Blender.Scene.getCurrent() except: NewOBJECT, CurSCENE = GET_newobject('Mesh','UVOBJECT') - MESH2 = NewOBJECT.getData() - MESH2.edges=[] + MESH2 = NewOBJECT.getData() NewOBJECT.layers=[RENDERLAYER] MESH2.faces=[] @@ -569,12 +485,13 @@ def Mesh2UVCoord (LIMIT): NewOBJECT.setLocation (OBJPOS, OBJPOS, 0.0) NewOBJECT.setEuler (0.0, 0.0, 0.0) + MESH2.removeAllKeys() MESH2.update() MESH2.insertKey (1, 'absolute') MESH2.update() - + for f in MESH2.faces: for v in f.v: for n in [0,1]: @@ -589,14 +506,6 @@ def Mesh2UVCoord (LIMIT): MESH2.insertKey (FRAME, 'absolute') MESH2.update() - #----------------------------------- - # release : 0.3.2 , 2005/12/28 , 13h00 - #----------------------------------- - Blender240update(MESH2,FRAME) - #----------------------------------- - # release : 0.3.2 , 2005/12/28 , end - #----------------------------------- - imagename = 'uvtext' name = "CHANGE IMAGE NAME ? %t | Replace it | No replace | Script help" @@ -642,4 +551,4 @@ def Mesh2UVCoord (LIMIT): result = Draw.PupMenu(name) print 'problem : no object selected or not mesh' -Mesh2UVCoord(LIMIT) \ No newline at end of file +Mesh2UVCoord(LIMIT) diff --git a/release/scripts/truespace_export.py b/release/scripts/truespace_export.py index a9f1688ae46..af9aa2a5a23 100644 --- a/release/scripts/truespace_export.py +++ b/release/scripts/truespace_export.py @@ -49,6 +49,7 @@ For Cameras: The matrix here gets a little confusing, and I'm not sure of how to handle it. """ + # $Id$ # # +---------------------------------------------------------+ @@ -56,27 +57,12 @@ how to handle it. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | June 12, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Caligari trueSpace File Format (*.cob) | # +---------------------------------------------------------+ -# ***** 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, meshtools import struct, os, cStringIO, time diff --git a/release/scripts/truespace_import.py b/release/scripts/truespace_import.py index ff655e1614c..40326612f3f 100644 --- a/release/scripts/truespace_import.py +++ b/release/scripts/truespace_import.py @@ -62,27 +62,12 @@ how to handle it. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | June 12, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Caligari trueSpace File Format (*.cob) | # +---------------------------------------------------------+ -# ***** 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, meshtools import struct, chunk, os, cStringIO, time diff --git a/release/scripts/uv_export.py b/release/scripts/uv_export.py index bf02c323f61..78d173d88fb 100644 --- a/release/scripts/uv_export.py +++ b/release/scripts/uv_export.py @@ -9,7 +9,7 @@ Tooltip: 'Export the UV face layout of the selected object to a .TGA file' __author__ = "Martin 'theeth' Poirier" __url__ = ("http://www.blender.org", "http://www.elysiun.com") -__version__ = "1.4" +__version__ = "1.3a" __bpydoc__ = """\ This script exports the UV face layout of the selected mesh object to @@ -26,9 +26,8 @@ There are more options to configure, like setting export path, if image should use object's name and more. Notes:
- Jean-Michel Soler (jms) wrote TGA functions used by this script.
- Zaz added the default path code and Selected Face option.
- Macouno fixed a rounding error in the step calculations
+ Jean-Michel Soler (jms) wrote TGA functions used by this script. + Zaz added the default path code and Selected Face option. """ @@ -63,22 +62,19 @@ Notes:
# Communicate problems and errors on: # http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender # -------------------------- -# Version 1.1 +# Version 1.1 # Clear a bug that crashed the script when UV coords overlapped in the same faces # -------------------------- -# Version 1.2 +# Version 1.2 # Now with option to use the object's name as filename # -------------------------- -# Version 1.3 Updates by Zaz from Elysiun.com +# Version 1.3 Updates by Zaz from Elysiun.com # Default path is now the directory of the last saved .blend # New options: Work on selected face only & Scale image when face wraps # -------------------------- -# Version 1.3a +# Version 1.3a # Corrected a minor typo and added the tga extension to both export call # -------------------------- -# Version 1.4 Updates by Macouno from Elysiun.com -# Fixed rounding error that can cause breaks in lines. -# -------------------------- import Blender from math import * @@ -138,42 +134,42 @@ def bevent(evt): UV_Export(bSize.val, bWSize.val, bFile.val + ".tga") def Buffer(height=16, width=16, profondeur=3,rvb=255 ): - """ - reserve l'espace memoire necessaire - """ - p=[rvb] - b=p*height*width*profondeur - return b + """ + reserve l'espace memoire necessaire + """ + p=[rvb] + b=p*height*width*profondeur + return b def write_tgafile(loc2,bitmap,width,height,profondeur): - f=open(loc2,'wb') + f=open(loc2,'wb') - Origine_en_haut_a_gauche=32 - Origine_en_bas_a_gauche=0 + Origine_en_haut_a_gauche=32 + Origine_en_bas_a_gauche=0 - Data_Type_2=2 - RVB=profondeur*8 - RVBA=32 - entete0=[] - for t in range(18): - entete0.append(chr(0)) + Data_Type_2=2 + RVB=profondeur*8 + RVBA=32 + entete0=[] + for t in range(18): + entete0.append(chr(0)) - entete0[2]=chr(Data_Type_2) - entete0[13]=chr(width/256) - entete0[12]=chr(width % 256) - entete0[15]=chr(height/256) - entete0[14]=chr(height % 256) - entete0[16]=chr(RVB) - entete0[17]=chr(Origine_en_bas_a_gauche) + entete0[2]=chr(Data_Type_2) + entete0[13]=chr(width/256) + entete0[12]=chr(width % 256) + entete0[15]=chr(height/256) + entete0[14]=chr(height % 256) + entete0[16]=chr(RVB) + entete0[17]=chr(Origine_en_bas_a_gauche) - #Origine_en_haut_a_gauche + #Origine_en_haut_a_gauche - for t in entete0: - f.write(t) + for t in entete0: + f.write(t) - for t in bitmap: - f.write(chr(t)) - f.close() + for t in bitmap: + f.write(chr(t)) + f.close() def UV_Export(size, wsize, file): obj = Blender.Object.GetSelected() @@ -242,12 +238,11 @@ def UV_Export(size, wsize, file): co2 = f[index + 1] else: co2 = f[0] - - step = int(ceil(size*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2))) + step = int(size*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2)) if step: - for t in range(step): - x = int(floor((co1[0] + t*(co2[0]-co1[0])/step) * size)) - y = int(floor((co1[1] + t*(co2[1]-co1[1])/step) * size)) + for t in range(step + 1): + x = int((co1[0] + t*(co2[0]-co1[0])/step) * size) + y = int((co1[1] + t*(co2[1]-co1[1])/step) * size) if bWrap.val: x = x % wrapSize @@ -256,17 +251,16 @@ def UV_Export(size, wsize, file): x = int ((x - minx) * scale) y = int ((y - miny) * scale) - co = x * 3 + y * 3 * size; - + co = x * 3 + y * 3 * size img[co] = 0 img[co+1] = 0 - img[co+2] = 0 + img[co+2] = 255 if wsize > 1: for x in range(-1*wsize + 1,wsize): for y in range(-1*wsize,wsize): img[co + 3 * x + y * 3 * size] = 0 img[co + 3 * x + y * 3 * size +1] = 0 - img[co + 3 * x + y * 3 * size +2] = 0 + img[co + 3 * x + y * 3 * size +2] = 255 for v in f: x = int(v[0] * size) @@ -282,7 +276,8 @@ def UV_Export(size, wsize, file): co = x * 3 + y * 3 * size img[co] = 0 img[co+1] = 0 - img[co+2] = 255 + img[co+2] = 0 + write_tgafile(file,img,size,size,3) diff --git a/release/scripts/videoscape_export.py b/release/scripts/videoscape_export.py index 49160e8b48d..37905239496 100644 --- a/release/scripts/videoscape_export.py +++ b/release/scripts/videoscape_export.py @@ -43,6 +43,7 @@ specular highlights to the vertex colors. 5. The Videoscape format also allows vertex colors to be specified. """ + # $Id$ # # +---------------------------------------------------------+ @@ -50,27 +51,12 @@ specular highlights to the vertex colors. # | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | June 5, 2001 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Write Videoscape File Format (*.obj NOT WAVEFRONT OBJ) | # +---------------------------------------------------------+ -# ***** 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, meshtools #import time diff --git a/release/scripts/vrml97_export.py b/release/scripts/vrml97_export.py index 41201d45315..3b7751c5fec 100644 --- a/release/scripts/vrml97_export.py +++ b/release/scripts/vrml97_export.py @@ -4,7 +4,6 @@ Name: 'VRML97 (.wrl)...' Blender: 235 Group: 'Export' Submenu: 'All Objects...' all -Submenu: 'All Objects compressed...' comp Submenu: 'Selected Objects...' selected Tooltip: 'Export to VRML97 file (.wrl)' """ @@ -13,8 +12,8 @@ __author__ = ("Rick Kimball", "Ken Miller", "Steve Matthews", "Bart") __url__ = ["blender", "elysiun", "Author's (Rick) homepage, http://kimballsoftware.com/blender", "Author's (Bart) homepage, http://www.neeneenee.de/vrml"] -__email__ = ["Bart, bart:neeneenee*de"] -__version__ = "2006/01/17" +__version__ = "2005/06/03" + __bpydoc__ = """\ This script exports to VRML97 format. @@ -38,6 +37,8 @@ for each texture);
# # ***** BEGIN GPL LICENSE BLOCK ***** # +# Copyright (C) 2003,2004: Rick Kimball rick@vrmlworld.net +# # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 @@ -60,7 +61,7 @@ for each texture);
#################################### import Blender -from Blender import Object, NMesh, Lamp, Draw, BGL, Image, Text, sys, Mathutils +from Blender import Object, NMesh, Lamp, Draw, BGL, Image, Text from Blender.Scene import Render try: from os.path import exists, join @@ -79,9 +80,15 @@ world = Blender.World.Get() worldmat = Blender.Texture.Get() filename = Blender.Get('filename') _safeOverwrite = True -extension = '' +radD=math.pi/180.0 ARG='' +def rad2deg(v): + return round(v*180.0/math.pi,4) + +def deg2rad(v): + return (v*math.pi)/180.0; + class DrawTypes: """Object DrawTypes enum values BOUNDS - draw only the bounding box of the object @@ -154,12 +161,11 @@ class VRML2Export: ########################################################## def writeHeader(self): - bfile = sys.expandpath(Blender.Get('filename')) self.file.write("#VRML V2.0 utf8\n\n") self.file.write("# This file was authored with Blender (http://www.blender.org/)\n") self.file.write("# Blender version %s\n" % Blender.Get('version')) - self.file.write("# Blender file %s\n" % sys.basename(bfile)) - self.file.write("# Exported using VRML97 exporter v1.55 (2006/01/17)\n\n") + self.file.write("# Blender file %s\n" % filename) + self.file.write("# Exported using VRML97 exporter v1.50 (2005/06/03)\n\n") def writeInline(self): inlines = Blender.Scene.Get() @@ -199,8 +205,9 @@ class VRML2Export: def writeViewpoint(self, thisObj): context = scene.getRenderingContext() ratio = float(context.imageSizeY())/float(context.imageSizeX()) - lens = (360* (math.atan(ratio *16 / thisObj.data.getLens()) / math.pi))*(math.pi/180) - lens = min(lens, math.pi) + lens = (360* (math.atan(ratio *16 / thisObj.data.getLens()) / 3.141593))*(3.141593/180) + if lens > 3.14: + lens = 3.14 # get the camera location, subtract 90 degress from X to orient like VRML does loc = self.rotatePointForVRML(thisObj.loc) rot = [thisObj.RotX - 1.57, thisObj.RotY, thisObj.RotZ] @@ -264,8 +271,8 @@ class VRML2Export: ambientIntensity = 0 # compute cutoff and beamwidth - intensity=min(lamp.energy/1.75,1.0) - beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; + intensity=min(lamp.energy/1.5,1.0) + beamWidth=deg2rad(lamp.spotSize)*.37; cutOffAngle=beamWidth*1.3 (dx,dy,dz)=self.computeDirection(object) @@ -296,7 +303,7 @@ class VRML2Export: ambi = 0 ambientIntensity = 0 - intensity=min(lamp.energy/1.75,1.0) + intensity=min(lamp.energy/1.5, 1.0) (dx,dy,dz)=self.computeDirection(object) self.writeIndented("DEF %s DirectionalLight {\n" % self.cleanStr(object.name),1) self.writeIndented("ambientIntensity %s\n" % (round(ambientIntensity,self.cp))) @@ -315,7 +322,7 @@ class VRML2Export: ambientIntensity = 0 om = object.getMatrix() location=self.rotVertex(om, (0,0,0)); - intensity=min(lamp.energy/1.75,1.0) + intensity=min(lamp.energy/1.5,1.0) radius = lamp.dist self.writeIndented("DEF %s PointLight {\n" % self.cleanStr(object.name),1) self.writeIndented("ambientIntensity %s\n" % (round(ambientIntensity,self.cp))) @@ -339,10 +346,28 @@ class VRML2Export: 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 createDef(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 secureName(self, name): name = name + str(self.nodeID) - self.nodeID += 1 + self.nodeID=self.nodeID+1 if len(name) <= 3: newname = "_" + str(self.nodeID) return "%s" % (newname) @@ -360,14 +385,13 @@ class VRML2Export: return "%s" % (newname) def writeIndexedFaceSet(self, object, normals = 0): + imageMap={} # set of used images sided={} # 'one':cnt , 'two':cnt vColors={} # 'multi':1 meshName = self.cleanStr(object.name) mesh=object.getData() meshME = self.cleanStr(mesh.name) - if len(mesh.faces) == 0: - return for face in mesh.faces: if face.mode & Blender.NMesh.FaceModes['HALO'] and self.halonode == 0: self.writeIndented("Billboard {\n",1) @@ -413,22 +437,23 @@ class VRML2Export: issmooth=0 if len(maters) > 0 or mesh.hasFaceUV(): - self.writeIndented("appearance Appearance {\n", 1) - # right now this script can only handle a single material per mesh. - if len(maters) >= 1: - mat=Blender.Material.Get(maters[0].name) - matFlags = mat.getMode() - if not matFlags & Blender.Material.Modes['TEXFACE']: - self.writeMaterial(mat, self.cleanStr(maters[0].name,'')) - if len(maters) > 1: - print "Warning: mesh named %s has multiple materials" % meshName - print "Warning: only one material per object handled" + self.writeIndented("appearance Appearance {\n", 1) + + # right now this script can only handle a single material per mesh. + if len(maters) >= 1: + mat=Blender.Material.Get(maters[0].name) + self.writeMaterial(mat, self.cleanStr(maters[0].name,'')) + if len(maters) > 1: + print "Warning: mesh named %s has multiple materials" % meshName + print "Warning: only one material per object handled" + else: + self.writeIndented("material NULL\n") #-- textures if mesh.hasFaceUV(): for face in mesh.faces: if (hasImageTexture == 0) and (face.image): - self.writeImageTexture(face.image.name, face.image.filename) + self.writeImageTexture(face.image.name) hasImageTexture=1 # keep track of face texture if self.tilenode == 1: self.writeIndented("textureTransform TextureTransform { scale %s %s }\n" % (face.image.xrep, face.image.yrep)) @@ -476,7 +501,7 @@ class VRML2Export: if face.smooth: issmooth=1 if issmooth==1 and self.wire == 0: - creaseAngle=(mesh.getMaxSmoothAngle())*(math.pi/180.0) + creaseAngle=(mesh.getMaxSmoothAngle())*radD self.writeIndented("creaseAngle %s\n" % (round(creaseAngle,self.cp))) #--- output vertexColors @@ -611,27 +636,22 @@ class VRML2Export: self.matNames[matName]=1 - ambient = mat.amb/3 + ambient = mat.amb/2 diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] if len(world) > 0: ambi = world[0].getAmb() - ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 + ambi0, ambi1, ambi2 = ambi[0], ambi[1], ambi[2] else: + ambi = 0 ambi0, ambi1, ambi2 = 0, 0, 0 - emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 + emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/4, (diffuseG*mat.emit+ambi1)/4, (diffuseB*mat.emit+ambi2)/4 - shininess = mat.hard/512.0 - specR = (mat.specCol[0]+0.001)/(1.25/(mat.getSpec()+0.001)) - specG = (mat.specCol[1]+0.001)/(1.25/(mat.getSpec()+0.001)) - specB = (mat.specCol[2]+0.001)/(1.25/(mat.getSpec()+0.001)) + shininess = mat.hard/255.0 + specR = (mat.specCol[0]+0.001)/(1.05/(mat.getSpec()+0.001)) + specG = (mat.specCol[1]+0.001)/(1.05/(mat.getSpec()+0.001)) + specB = (mat.specCol[2]+0.001)/(1.05/(mat.getSpec()+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("material DEF MA_%s Material {\n" % matName, 1) self.writeIndented("diffuseColor %s %s %s\n" % (round(diffuseR,self.cp), round(diffuseG,self.cp), round(diffuseB,self.cp))) self.writeIndented("ambientIntensity %s\n" % (round(ambient,self.cp))) @@ -641,14 +661,14 @@ class VRML2Export: self.writeIndented("transparency %s\n" % (round(transp,self.cp))) self.writeIndented("}\n",-1) - def writeImageTexture(self, name, filename): + def writeImageTexture(self, name): if self.texNames.has_key(name): self.writeIndented("texture USE %s\n" % self.cleanStr(name)) self.texNames[name] += 1 return else: self.writeIndented("texture DEF %s ImageTexture {\n" % self.cleanStr(name), 1) - self.writeIndented("url \"%s\"\n" % name.split("\\")[-1].split("/")[-1]) + self.writeIndented("url \"%s\"\n" % name) self.writeIndented("}\n",-1) self.texNames[name] = 1 @@ -667,7 +687,7 @@ class VRML2Export: if worldname in self.namesStandard: self.writeIndented("Background {\n",1) else: - self.writeIndented("DEF %s Background {\n" % self.secureName(worldname),1) + self.writeIndented("DEF %s Background {\n" % self.createDef(worldname),1) # No Skytype - just Hor color if blending == 0: self.writeIndented("groundColor %s %s %s\n" % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp))) @@ -936,8 +956,11 @@ class VRML2Export: def writeIndented(self, s, inc=0): if inc < 1: self.indentLevel = self.indentLevel + inc - - self.file.write( self.indentLevel*"\t" + s) + + spaces="" + for x in xrange(self.indentLevel): + spaces = spaces + "\t" + self.file.write(spaces + s) if inc > 0: self.indentLevel = self.indentLevel + inc @@ -993,9 +1016,7 @@ def select_file(filename): if(result != 1): return - if not filename.endswith(extension): - filename += extension - + if filename.find('.wrl', -4) < 0: filename += '.wrl' wrlexport=VRML2Export(filename) wrlexport.export(scene, world, worldmat) @@ -1005,7 +1026,7 @@ def createWRLPath(): if filename.find('.') != -1: filename = filename.split('.')[0] - filename += extension + filename += ".wrl" print filename return filename @@ -1020,14 +1041,8 @@ except: print "older version" if Blender.Get('version') < 235: - print "Warning: VRML97 export failed, wrong blender version!" - print " You aren't running blender version 2.35 or greater" - print " download a newer version from http://blender3d.org/" + print "Warning: VRML97 export failed, wrong blender version!" + print " You aren't running blender version 2.35 or greater" + print " download a newer version from http://blender3d.org/" else: - if ARG == 'comp': - extension=".wrz" - from gzip import * - else: - extension=".wrl" - Blender.Window.FileSelector(select_file,"Export VRML97",createWRLPath()) - + Blender.Window.FileSelector(select_file,"Export VRML97",createWRLPath()) diff --git a/release/scripts/wings_export.py b/release/scripts/wings_export.py index 8477f9e076a..c262f3faabd 100644 --- a/release/scripts/wings_export.py +++ b/release/scripts/wings_export.py @@ -50,27 +50,12 @@ Notes:
# | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | Feb 19, 2002 | +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ # | Read and write Wings3D File Format (*.wings) | # +---------------------------------------------------------+ -# ***** 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, meshtools import struct, time, sys, os, zlib, cStringIO diff --git a/release/scripts/wings_import.py b/release/scripts/wings_import.py index 8bba6f52de7..70f124b3bac 100644 --- a/release/scripts/wings_import.py +++ b/release/scripts/wings_import.py @@ -11,7 +11,7 @@ __author__ = "Anthony D'Agostino (Scorpius)" __url__ = ("blender", "elysiun", "Author's homepage, http://www.redrival.com/scorpius", "Wings 3D, http://www.wings3d.com") -__version__ = "Update on version from IOSuite 0.5" +__version__ = "Part of IOSuite 0.5" __bpydoc__ = """\ This script imports Wings3D files to Blender. @@ -37,8 +37,7 @@ fanning algorithm. Convex polygons (i.e., shaped like the letter "U") require a different algorithm, and will be triagulated incorrectly. Notes:
- Last tested with Wings 3D 0.98.25 & Blender 2.35a.
- This version has improvements made by Adam Saltsman (AdamAtomic) and Toastie. + Last tested with Wings 3D 0.98.25 & Blender 2.35a. """ # $Id$ @@ -48,29 +47,15 @@ Notes:
# | http://www.redrival.com/scorpius | # | scorpius@netzero.com | # | Feb 19, 2002 | - -# ***** 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 ***** - +# | Released under the Blender Artistic Licence (BAL) | +# | Import Export Suite v0.5 | +# +---------------------------------------------------------+ +# | Read and write Wings3D File Format (*.wings) | +# +---------------------------------------------------------+ import Blender, meshtools import struct, time, sys, os, zlib, cStringIO - + # ============================================== # === Read The 'Header' Common To All Chunks === # ============================================== @@ -94,28 +79,26 @@ def read_mode(data): # === Read Hard Edges === # ======================= def read_hardedges(data): - hardedge_table = {} # hard edges table tag = data.read(1) if tag == '\x6A': - return hardedge_table # There are no hard edges + return # There are no hard edges elif tag == '\x6B': numhardedges, = struct.unpack(">H", data.read(2)) - #print "numhardedges:", numhardedges + print "numhardedges:", numhardedges for i in range(numhardedges): - hardedge_table[i] = struct.unpack(">B", data.read(1))[0] + data.read(1) elif tag == '\x6C': numhardedges, = struct.unpack(">L", data.read(4)) - #print "numhardedges:", numhardedges + print "numhardedges:", numhardedges for i in range(numhardedges): misc = data.read(1) if misc == '\x61': # next value is stored as a byte - hardedge_table[i] = struct.unpack(">B", data.read(1))[0] + data.read(1) elif misc == '\x62': # next value is stored as a long - hardedge_table[i] = struct.unpack(">L", data.read(4))[0] + data.read(4) data.read(1) # 6A else: print tag - return hardedge_table # ================== # === Read Edges === @@ -151,7 +134,6 @@ def read_edges(data): # === Read Faces === # ================== def read_faces(data): - mat_table = {} #list of faces and material names misc, numfaces = struct.unpack(">BL", data.read(5)) for i in range(numfaces): if not i%100 and meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces") @@ -159,10 +141,10 @@ def read_faces(data): data.read(4) read_chunkheader(data) misc, namelen = struct.unpack(">BH", data.read(3)) - mat_table[i] = data.read(namelen) - data.read(1) # 6A? + materialname = data.read(namelen) + data.read(1) data.read(1) # 6A - return mat_table + return numfaces # ================== # === Read Verts === @@ -187,10 +169,8 @@ def make_face_table(edge_table): # For Wings for i in range(len(edge_table)): Lf = edge_table[i][2] Rf = edge_table[i][3] - if Lf >= 0: - face_table[Lf] = i - if Rf >= 0: - face_table[Rf] = i + face_table[Lf] = i + face_table[Rf] = i return face_table # ======================= @@ -218,17 +198,14 @@ def make_faces(edge_table): # For Wings if i == edge_table[current_edge][3]: next_edge = edge_table[current_edge][7] # Right successor edge next_vert = edge_table[current_edge][0] - elif i == edge_table[current_edge][2]: + else: next_edge = edge_table[current_edge][5] # Left successor edge next_vert = edge_table[current_edge][1] - else: - break face_verts.append(next_vert) current_edge = next_edge if current_edge == face_table[i]: break - if len(face_verts) > 0: - face_verts.reverse() - faces.append(face_verts) + face_verts.reverse() + faces.append(face_verts) return faces # ======================= @@ -246,7 +223,7 @@ def dump_wings(filename): file.close() data = zlib.decompress(data) if dsize != len(data): print "ERROR: uncompressed size does not match." - data = cStringIO.StringIO(data) + data = cStringIO.StringIO(data) print "header:", header print read_chunkheader(data) # === wings chunk === data.read(4) # misc bytes @@ -259,10 +236,9 @@ def dump_wings(filename): objname = data.read(namelen) print read_chunkheader(data) # === winged chunk === edge_table = read_edges(data) - mat_table = read_faces(data) - numfaces = len(mat_table) + numfaces = read_faces(data) verts = read_verts(data) - hardedge_table = read_hardedges(data) + read_hardedges(data) face_table = {} # contains an incident edge vert_table = {} # contains an incident edge @@ -279,26 +255,25 @@ def dump_wings(filename): print print "Ä"*79 print "edge_table:" - #pprint.pprint(edge_table) + pprint.pprint(edge_table) #for i in range(len(edge_table)): print "%2d" % (i), edge_table[i] print print "face_table:" - #pprint.pprint(face_table) + pprint.pprint(face_table) #for i in range(len(face_table)): print "%2d %2d" % (i, face_table[i]) print print "vert_table:" - #pprint.pprint(vert_table) + pprint.pprint(vert_table) #for i in range(len(vert_table)): print "%2d %2d" % (i, vert_table[i]) file.close() end = time.clock() print '\a\r', - sys.stderr.write("\nDone in %.2f %s\a\r" % (end-start, "seconds")) + sys.stderr.write("\nDone in %.2f %s" % (end-start, "seconds")) # ========================= # === Read Wings Format === # ========================= def read(filename): - start = time.clock() file = open(filename, "rb") header = file.read(15) @@ -324,113 +299,9 @@ def read(filename): objname = data.read(namelen) read_chunkheader(data) # winged chunk edge_table = read_edges(data) - mat_table = read_faces(data) - numfaces = len(mat_table) + numfaces = read_faces(data) verts = read_verts(data) - hardedge_table = read_hardedges(data) - - # Manually split hard edges - # TODO: Handle the case where there are 2+ edges on a face - duped = {} - processed = [] - cleanup = [] - oldedgecount = len(edge_table) - for i in range(len(verts)): - duped[i] = -1 - for j in range(len(hardedge_table)): - hardedge = hardedge_table[j] - oldedge = edge_table[hardedge] - newedge = [] # Copy old edge into a new list - for k in range(len(oldedge)): - newedge.append(oldedge[k]) - - # Duplicate start vert if not duped already - sv = newedge[0] - if duped[sv] == -1: - verts.append(verts[sv]) - duped[sv] = len(verts)-1 - newedge[0] = duped[sv] - - # Duplicate end vert if not duped already - ev = newedge[1] - if duped[ev] == -1: - verts.append(verts[ev]) - duped[ev] = len(verts)-1 - newedge[1] = duped[ev] - - # Decide which way to cut the edge - flip = 0 - for v in range(len(processed)): - if processed[v][0] == oldedge[0]: - flip = 1 - elif processed[v][1] == oldedge[1]: - flip = 1 - if flip == 0: - of = 3 - oe1 = 6 - oe2 = 7 - nf = 2 - ne1 = 4 - ne2 = 5 - else: - of = 2 - oe1 = 4 - oe2 = 5 - nf = 3 - ne1 = 6 - ne2 = 7 - - # Fix up side-specific edge fields - oldedge[of] = -1 - oldedge[oe1] = -1 - oldedge[oe2] = -1 - newedge[nf] = -1 - newedge[ne1] = -1 - newedge[ne2] = -1 - - # Store new edge's neighbors for cleanup later - cleanup.append(edge_table[newedge[oe1]]) - cleanup.append(edge_table[newedge[oe2]]) - - #DEBUG - # Sv Ev | Lf Rf | Lp Ls | Rp Rs - #print "Old Edge:",hardedge,oldedge - #print "New Edge:",len(edge_table),newedge - - # Add this new edge to the edge table - edge_table[len(edge_table)] = newedge - if flip == 0: - processed.append(oldedge) # mark it off as processed - - # Cycle through cleanup list and fix it up - for c in range(len(cleanup)): - cleanupedge = cleanup[c] - - # Fix up their verts in case they were duped - sv = cleanupedge[0] - if sv < len(duped): - if duped[sv] >= 0: - cleanupedge[0] = duped[sv] - ev = cleanupedge[1] - if ev < len(duped): - if duped[ev] >= 0: - cleanupedge[1] = duped[ev] - - # Fix up edge info (in case a hard edge was replaced with a new one) - edgecount = c/2 - hardedge = hardedge_table[edgecount] # look up what edge we were replacing - newedgenum = oldedgecount+edgecount # calculate new edge's index - if cleanupedge[4] == hardedge: - cleanupedge[4] = newedgenum - if cleanupedge[5] == hardedge: - cleanupedge[5] = newedgenum - if cleanupedge[6] == hardedge: - cleanupedge[6] = newedgenum - if cleanupedge[7] == hardedge: - cleanupedge[7] = newedgenum - - #for i in range(len(edge_table)): print "%2d" % (i), edge_table[i] - + read_hardedges(data) read_mode(data) faces = make_faces(edge_table) message += "%s %8s %8s %8s\n" % (objname.ljust(15), len(faces), len(edge_table), len(verts)) diff --git a/release/scripts/x3d_export.py b/release/scripts/x3d_export.py index 9239db6ab9e..322af5eac25 100644 --- a/release/scripts/x3d_export.py +++ b/release/scripts/x3d_export.py @@ -4,15 +4,16 @@ Name: 'X3D Extensible 3D (.x3d)...' Blender: 235 Group: 'Export' Submenu: 'All Objects...' all -Submenu: 'All Objects compressed...' comp Submenu: 'Selected Objects...' selected Tooltip: 'Export to Extensible 3D file (.x3d)' """ __author__ = ("Bart") -__email__ = ["Bart, bart:neeneenee*de"] __url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"] -__version__ = "2006/01/17" +__version__ = "2005/06/06" + + + __bpydoc__ = """\ This script exports to X3D format. @@ -36,6 +37,8 @@ for each texture);
# # ***** BEGIN GPL LICENSE BLOCK ***** # +# Copyright (C) 2003,2004: 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 @@ -58,7 +61,7 @@ for each texture);
#################################### import Blender -from Blender import Object, NMesh, Lamp, Draw, BGL, Image, Text, sys, Mathutils +from Blender import Object, NMesh, Lamp, Draw, BGL, Image, Text from Blender.Scene import Render try: from os.path import exists, join @@ -77,8 +80,14 @@ world = Blender.World.Get() worldmat = Blender.Texture.Get() filename = Blender.Get('filename') _safeOverwrite = True +radD=math.pi/180.0 ARG='' -extension = '' + +def rad2deg(v): + return round(v*180.0/math.pi,4) + +def deg2rad(v): + return (v*math.pi)/180.0; class DrawTypes: """Object DrawTypes enum values @@ -168,14 +177,13 @@ class VRML2Export: ########################################################## def writeHeader(self): - bfile = sys.expandpath(Blender.Get('filename')) 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" % filename) self.file.write("\t\n" % Blender.Get('version')) - self.file.write("\t\n") + self.file.write("\t\n") self.file.write("\n") self.file.write("\n") @@ -216,8 +224,9 @@ class VRML2Export: def writeViewpoint(self, thisObj): context = scene.getRenderingContext() ratio = float(context.imageSizeY())/float(context.imageSizeX()) - lens = (360* (math.atan(ratio *16 / thisObj.data.getLens()) / math.pi))*(math.pi/180) - lens = min(lens, math.pi) + lens = (360* (math.atan(ratio *16 / thisObj.data.getLens()) / 3.141593))*(3.141593/180) + if lens > 3.14: + lens = 3.14 # get the camera location, subtract 90 degress from X to orient like X3D does loc = self.rotatePointForVRML(thisObj.loc) rot = [thisObj.RotX - 1.57, thisObj.RotY, thisObj.RotZ] @@ -274,8 +283,8 @@ class VRML2Export: ambientIntensity = 0 # compute cutoff and beamwidth - intensity=min(lamp.energy/1.75,1.0) - beamWidth=((lamp.spotSize*math.pi)/180.0)*.37; + intensity=min(lamp.energy/1.5,1.0) + beamWidth=deg2rad(lamp.spotSize)*.37; cutOffAngle=beamWidth*1.3 (dx,dy,dz)=self.computeDirection(object) @@ -305,7 +314,7 @@ class VRML2Export: ambi = 0 ambientIntensity = 0 - intensity=min(lamp.energy/1.75,1.0) + intensity=min(lamp.energy/1.5, 1.0) (dx,dy,dz)=self.computeDirection(object) self.file.write("\n",-1) self.writeIndented("\n") + def createDef(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 secureName(self, name): name = name + str(self.nodeID) @@ -366,14 +393,13 @@ class VRML2Export: return "%s" % (newname) def writeIndexedFaceSet(self, object, normals = 0): + imageMap={} # set of used images sided={} # 'one':cnt , 'two':cnt vColors={} # 'multi':1 meshName = self.cleanStr(object.name) mesh=object.getData() meshME = self.cleanStr(mesh.name) - if len(mesh.faces) == 0: - return for face in mesh.faces: if face.mode & Blender.NMesh.FaceModes['HALO'] and self.halonode == 0: self.writeIndented("\n",1) @@ -410,16 +436,17 @@ class VRML2Export: issmooth=0 if len(maters) > 0 or mesh.hasFaceUV(): - self.writeIndented("\n", 1) - # right now this script can only handle a single material per mesh. - if len(maters) >= 1: - mat=Blender.Material.Get(maters[0].name) - matFlags = mat.getMode() - if not matFlags & Blender.Material.Modes['TEXFACE']: - self.writeMaterial(mat, self.cleanStr(maters[0].name,'')) - if len(maters) > 1: - print "Warning: mesh named %s has multiple materials" % meshName - print "Warning: only one material per object handled" + self.writeIndented("\n", 1) + + # right now this script can only handle a single material per mesh. + if len(maters) >= 1: + mat=Blender.Material.Get(maters[0].name) + self.writeMaterial(mat, self.cleanStr(maters[0].name,'')) + if len(maters) > 1: + print "Warning: mesh named %s has multiple materials" % meshName + print "Warning: only one material per object handled" + else: + self.writeIndented("\n") #-- textures if mesh.hasFaceUV(): @@ -462,7 +489,7 @@ class VRML2Export: if face.smooth: issmooth=1 if issmooth==1 and self.wire == 0: - creaseAngle=(mesh.getMaxSmoothAngle())*(math.pi/180.0) + creaseAngle=(mesh.getMaxSmoothAngle())*radD self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp))) #--- output vertexColors @@ -613,27 +640,22 @@ class VRML2Export: self.matNames[matName]=1 - ambient = mat.amb/3 + ambient = mat.amb/2 diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2] if len(world) > 0: ambi = world[0].getAmb() - ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2 + ambi0, ambi1, ambi2 = ambi[0], ambi[1], ambi[2] else: + ambi = 0 ambi0, ambi1, ambi2 = 0, 0, 0 - emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2 + emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/4, (diffuseG*mat.emit+ambi1)/4, (diffuseB*mat.emit+ambi2)/4 - shininess = mat.hard/512.0 - specR = (mat.specCol[0]+0.001)/(1.25/(mat.getSpec()+0.001)) - specG = (mat.specCol[1]+0.001)/(1.25/(mat.getSpec()+0.001)) - specB = (mat.specCol[2]+0.001)/(1.25/(mat.getSpec()+0.001)) + shininess = mat.hard/255.0 + specR = (mat.specCol[0]+0.001)/(1.05/(mat.getSpec()+0.001)) + specG = (mat.specCol[1]+0.001)/(1.05/(mat.getSpec()+0.001)) + specB = (mat.specCol[2]+0.001)/(1.05/(mat.getSpec()+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(" #include "AVI_avi.h" #include "endian.h" +#include "avi_intern.h" #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) #define WORDS_BIGENDIAN @@ -165,7 +166,7 @@ void awrite (AviMovie *movie, void *datain, int block, int size, FILE *fp, int t #ifdef WORDS_BIGENDIAN void *data; - data = malloc (size); + data = MEM_mallocN (size, "avi endian"); memcpy (data, datain, size); @@ -208,7 +209,7 @@ void awrite (AviMovie *movie, void *datain, int block, int size, FILE *fp, int t break; } - free (data); + MEM_freeN (data); #else /* WORDS_BIGENDIAN */ fwrite (datain, block, size, fp); #endif /* WORDS_BIGENDIAN */ diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index eec23b91b9e..1e62dacc158 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -47,6 +47,7 @@ struct MVert; struct Object; +struct TFace; struct EditMesh; struct DispListMesh; struct ModifierData; @@ -143,7 +144,7 @@ struct DerivedMesh { /* Draw all faces uses TFace * o Drawing options too complicated to enumerate, look at code. */ - void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(TFace *tf, int matnr)); + void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tf, int matnr)); /* Draw mapped faces (no color, or texture) * o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index b6e0aded1b8..9abd73d7bef 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -111,7 +111,7 @@ struct bAction *copy_action(struct bAction *src); /** * Some kind of bounding box operation on the action. */ -void calc_action_range(const struct bAction *act, float *start, float *end); +void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden); /** * Set the pose channels from the given action. @@ -132,6 +132,9 @@ struct bActionChannel *get_action_channel(struct bAction *act, const char *name */ struct bActionChannel *verify_action_channel(struct bAction *act, const char *name); + /* baking */ +struct bAction *bake_obIPO_to_action(struct Object *ob); + /* exported for game engine */ void blend_poses(struct bPose *dst, struct bPose *src, float srcweight, short mode); void extract_pose_from_pose(struct bPose *pose, const struct bPose *src); diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index 16e8b5652aa..69fb83aac30 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -39,15 +39,18 @@ struct Object; struct PartEff; struct Scene; +typedef struct DupliObject { + struct DupliObject *next, *prev; + struct Object *ob; + float mat[4][4], omat[4][4]; +} 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); -void frames_duplilist(struct Object *ob); -void vertex_duplilist(struct Scene *sce, struct Object *par); -void particle_duplilist(struct Scene *sce, struct Object *par, struct PartEff *paf); -void free_duplilist(void); -void make_duplilist(struct Scene *sce, struct Object *ob); + +ListBase *object_duplilist(struct Scene *sce, struct Object *ob); int count_duplilist(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index 905b6d3bf74..1bc02a02ea6 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -75,25 +75,6 @@ void error(char *str, ...); /* anim.c */ extern struct ListBase editNurb; -/* displist.c */ -#include "DNA_world_types.h" /* for render_types */ -#include "render_types.h" -extern struct RE_Render R; -float Blinn_Spec(float *n, float *l, float *v, float a, float b, int); -float Phong_Spec(float *, float *, float *, int, int); -float CookTorr_Spec(float *n, float *l, float *v, int hard, int); -float Toon_Spec(float *n, float *l, float *v, float a, float b, int); -float WardIso_Spec(float *n, float *l, float *v, float a, int); - -float Toon_Diff(float *n, float *l, float *v, float a, float b); -float OrenNayar_Diff(float *n, float *l, float *v, float rough); -float Minnaert_Diff(float nl, float *n, float *v, float a); - -void add_to_diffuse(float *, ShadeInput *, float, float, float, float); -void ramp_diffuse_result(float *diff, ShadeInput *shi); -void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec); -void ramp_spec_result(float *, float *, float *, ShadeInput *); - void mainqenter (unsigned short event, short val); void waitcursor(int); void allqueue(unsigned short event, short val); @@ -102,9 +83,6 @@ void allqueue(unsigned short event, short val); struct Material; extern struct Material defmaterial; -/* effect.c */ -void RE_jitterate1(float *jit1, float *jit2, int num, float rad1); -void RE_jitterate2(float *jit1, float *jit2, int num, float rad2); /* exotic.c */ void load_editMesh(void); @@ -118,7 +96,6 @@ int saveover(char *str); /* image.c */ #include "DNA_image_types.h" void free_realtime_image(Image *ima); // has to become a callback, opengl stuff -void RE_make_existing_file(char *name); // from render, but these funcs should be moved anyway /* ipo.c */ void copy_view3d_lock(short val); // was a hack, to make scene layer ipo's possible @@ -128,11 +105,12 @@ void allspace(unsigned short event, short val) ; #define OOPS_TEST 2 /* mball.c */ -extern ListBase editelems; +extern struct ListBase editelems; /* object.c */ -void BPY_free_scriptlink(ScriptLink *slink); -void BPY_copy_scriptlink(ScriptLink *scriptlink); +struct ScriptLink; +void BPY_free_scriptlink(struct ScriptLink *slink); +void BPY_copy_scriptlink(struct ScriptLink *scriptlink); float *give_cursor(void); // become a callback or argument void exit_posemode(int freedata); @@ -148,22 +126,7 @@ void free_editing(struct Editing *ed); // scenes and sequences problem... void BPY_do_all_scripts (short int event); int BPY_call_importloader(char *name); -/* texture.c */ -#define FLO 128 -#define INT 96 -struct EnvMap; -struct Tex; -void do_material_tex(ShadeInput *shi); -void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, - float *tg, float *tb, float *ta); -void init_render_textures(void); -void end_render_textures(void); - -void RE_free_envmap(struct EnvMap *env); -void RE_free_envmapdata(struct EnvMap *env); -struct EnvMap *RE_copy_envmap(struct EnvMap *env); -int RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt); extern char texstr[20][12]; /* buttons.c */ diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h new file mode 100644 index 00000000000..a9d38162824 --- /dev/null +++ b/source/blender/blenkernel/BKE_colortools.h @@ -0,0 +1,60 @@ +/** + * $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): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef BKE_COLORTOOLS_H +#define BKE_COLORTOOLS_H + +struct CurveMapping; +struct CurveMap; +struct Image; +struct rctf; + +struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy); +void curvemapping_free(struct CurveMapping *cumap); +struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap); +void curvemapping_set_black_white(struct CurveMapping *cumap, float *black, float *white); + +void curvemap_remove(struct CurveMap *cuma, int flag); +void curvemap_insert(struct CurveMap *cuma, float x, float y); +void curvemap_reset(struct CurveMap *cuma, struct rctf *clipr); +void curvemap_sethandle(struct CurveMap *cuma, int type); + +void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles); + + /* single curve, no table check */ +float curvemap_evaluateF(struct CurveMap *cuma, float value); + /* single curve, with table check */ +float curvemapping_evaluateF(struct CurveMapping *cumap, int cur, float value); +void curvemapping_evaluate3F(struct CurveMapping *cumap, float *vecout, const float *vecin); +void curvemapping_evaluateRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin); +void curvemapping_evaluate_premulRGBF(struct CurveMapping *cumap, float *vecout, const float *vecin); +void curvemapping_do_image(struct CurveMapping *cumap, struct Image *ima); +void curvemapping_premultiply(struct CurveMapping *cumap, int restore); +int curvemapping_RGBA_does_something(struct CurveMapping *cumap); +#endif + diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 5dd820d5a79..294f61e54bd 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -109,5 +109,5 @@ void DAG_scene_flush_update(struct Scene *sce, unsigned int lay); void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag); void DAG_pose_sort(struct Object *ob); - + #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 2dcf4bfe1be..05a1cfc5376 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -75,6 +75,7 @@ if( (cyclv) && a==sizev-1) { \ /* prototypes */ +struct Base; struct Object; struct Curve; struct ListBase; @@ -144,7 +145,7 @@ extern void makeDispListMesh(struct Object *ob); extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender); extern void makeDispListCurveTypes(struct Object *ob, int forOrco); extern void makeDispListMBall(struct Object *ob); -extern void shadeDispList(struct Object *ob); +extern void shadeDispList(struct Base *base); void freefastshade(void); void imagestodisplist(void); void reshadeall_displist(void); diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index c68d4b8b10e..5585735e0b5 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -34,14 +34,26 @@ #ifndef BKE_EFFECT_H #define BKE_EFFECT_H +#include "DNA_object_types.h" + struct Effect; struct ListBase; -struct Object; struct PartEff; -struct MTex; -struct Mesh; -struct WaveEff; struct Particle; +struct Group; + +typedef struct pEffectorCache { + struct pEffectorCache *next, *prev; + Object *ob; + + /* precalculated variables */ + float oldloc[3], oldspeed[3]; + float scale, time_scale; + float guide_dist; + + Object obcopy; /* for restoring transformation data */ +} pEffectorCache; + struct Effect *add_effect(int type); void free_effect(struct Effect *eff); @@ -57,7 +69,7 @@ void build_particle_system(struct Object *ob); /* particle deflector */ #define PE_WIND_AS_SPEED 0x00000001 -struct ListBase *pdInitEffectors(struct Object *ob); +struct ListBase *pdInitEffectors(struct Object *obsrc, struct Group *group); void pdEndEffectors(struct ListBase *lb); void pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags); diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 00a994672be..05621a4d9b2 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -41,6 +41,13 @@ struct Object; struct Curve; struct objfnt; +struct chartrans { + float xof, yof; + float rot; + short linenr,charnr; + char dobreak; +}; + typedef struct SelBox { float x, y, w, h; } SelBox; @@ -55,7 +62,7 @@ struct VFont *load_vfont(char *name); struct chartrans *text_to_curve(struct Object *ob, int mode); int style_to_sel(int style, int toggle); int mat_to_sel(void); -void font_duplilist(struct Object *par); + int getselection(int *start, int *end); void chtoutf8(unsigned long c, char *o); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index c5afa9a1980..f078fd14753 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -96,7 +96,7 @@ typedef struct Global { short afbreek, moving; short qual, background; short winpos, displaymode; /* used to be in Render */ - + short rendering; /* to indicate render is busy, prevent renderwindow events etc */ /** * The current version of Blender. */ @@ -124,7 +124,7 @@ typedef struct Global { struct VFont *selfont; struct ListBase ttfdata; - /* libtiff flag */ + /* libtiff flag used to determine if shared library loaded for libtiff*/ int have_libtiff; /* this variable is written to / read from FileGlobal->fileflags */ diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 265d16579c2..2a14c2f6ed5 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -35,26 +35,23 @@ #define BKE_GROUP_H struct Group; -struct GroupKey; struct GroupObject; -struct ObjectKey; struct Object; +struct bAction; -void free_object_key(struct ObjectKey *ok); -void free_group_object(struct GroupObject *go); -void free_group(struct Group *group); +void free_group_object(struct GroupObject *go); +void free_group(struct Group *group); +void unlink_group(struct Group *group); struct Group *add_group(void); -void object_to_obkey(struct Object *ob, struct ObjectKey *ok); -void obkey_to_object(struct ObjectKey *ok, struct Object *ob); -void add_object_key(struct GroupObject *go, struct GroupKey *gk); -void add_to_group(struct Group *group, struct Object *ob); -void rem_from_group(struct Group *group, struct Object *ob); -void add_group_key(struct Group *group); -void set_object_key(struct Object *ob, struct ObjectKey *ok); -void set_group_key(struct Group *group); +void add_to_group(struct Group *group, struct Object *ob); +void rem_from_group(struct Group *group, struct Object *ob); struct Group *find_group(struct Object *ob); -void set_group_key_name(struct Group *group, char *name); -void set_group_key_frame(struct Group *group, float frame); +int object_in_group(struct Object *ob, struct Group *group); + +void group_tag_recalc(struct Group *group); +void group_handle_recalc_and_update(struct Object *parent, struct Group *group); +struct Object *group_get_member_with_action(struct Group *group, struct bAction *act); +void group_relink_nla_objects(struct Object *ob); #endif diff --git a/source/blender/render/intern/include/zbuf_types.h b/source/blender/blenkernel/BKE_icons.h similarity index 57% rename from source/blender/render/intern/include/zbuf_types.h rename to source/blender/blenkernel/BKE_icons.h index b5ad9c75902..315c7dc7a53 100644 --- a/source/blender/render/intern/include/zbuf_types.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -1,7 +1,4 @@ -/* - * zbuf_types.h - * type definitions used (and maybe exported) by zbuf.c. - * +/** * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -29,47 +26,50 @@ * The Original Code is: all of this file. * * Contributor(s): none yet. - * + * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifndef ZBUF_TYPES_H -#define ZBUF_TYPES_H +#ifndef BKE_ICONS_H +#define BKE_ICONS_H -#ifdef __cplusplus -extern "C" { -#endif +/* + Resizable Icons for Blender +*/ -#define ABUFPART 64 +typedef void (*DrawInfoFreeFP) (void *drawinfo); -/** - * Primitive data structure for zbuffering. One struct - * stores data for 4 entries. - */ -typedef struct APixstr { - unsigned short mask[4]; /* jitter mask */ - int z[4]; /* distance */ - int p[4]; /* index */ - struct APixstr *next; -} APixstr; - - -typedef struct APixstrMain +struct Icon { - struct APixstr *ps; - struct APixstrMain *next; -} APixstrMain; + void *drawinfo; + void *obj; + short type; + short changed; + DrawInfoFreeFP drawinfo_free; +}; + +typedef struct Icon Icon; + +void BKE_icons_init(int first_dyn_id); + +/* return icon id for library object or create new icon if not found */ +int BKE_icon_getid(struct ID* id); + +/* retrieve icon for id */ +struct Icon* BKE_icon_get(int icon_id); + +/* set icon for id if not already defined */ +/* used for inserting the internal icons */ +void BKE_icon_set(int icon_id, struct Icon* icon); + +/* remove icon and free date if library object becomes invalid */ +void BKE_icon_delete(struct ID* id); + +/* report changes - icon needs to be recalculated */ +void BKE_icon_changed(int icon_id); + +/* free all icons */ +void BKE_icons_free(); -typedef struct { - float *vert; - float hoco[4]; - int clip; -} VertBucket; - -#ifdef __cplusplus -} -#endif - -#endif /* ZBUF_TYPES_H */ - +#endif /* BKE_ICONS_H */ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 1ae5552104c..250b6dc762f 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -49,8 +49,10 @@ struct Image *add_image(char *name); void free_unused_animimages(void); struct Image *new_image(int width, int height, char *name, short uvtestgrid); -void makepicstring(char *string, int frame); -void addImageExtension(char *string); +int BKE_write_ibuf(struct ImBuf *ibuf, char *name, int imtype, int subimtype, int quality); +void BKE_makepicstring(char *string, int frame); +void BKE_add_image_extension(char *string, int imtype); +int BKE_imtype_is_movie(int imtype); struct anim *openanim(char * name, int flags); void ima_ibuf_is_nul(struct Tex *tex, struct Image *ima); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 8ec6f013ef9..ac438ec95bd 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -41,13 +41,13 @@ struct ID; struct Main; struct Library; -void *alloc_libblock(struct ListBase *lb, short type, char *name); +void *alloc_libblock(struct ListBase *lb, short type, const char *name); void *copy_libblock(void *rt); void id_lib_extern(struct ID *id); void id_us_plus(struct ID *id); -int new_id(struct ListBase *lb, struct ID *id, char *name); +int new_id(struct ListBase *lb, struct ID *id, const char *name); struct ListBase *wich_libbase(struct Main *mainlib, short type); int set_listbasepointers(struct Main *main, struct ListBase **lb); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 9a37f91a023..1512ea28d4a 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -72,8 +72,9 @@ typedef struct Main { ListBase text; ListBase sound; ListBase group; - ListBase armature; /* NLA */ - ListBase action; /* NLA */ + ListBase armature; + ListBase action; + ListBase nodetree; } Main; diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index fcdbed10ffa..a9609f88c98 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -42,25 +42,32 @@ struct Material; struct ID; struct Object; +void init_def_material(void); void free_material(struct Material *sc); void test_object_materials(struct ID *id); void init_material(struct Material *ma); struct Material *add_material(char *name); struct Material *copy_material(struct Material *ma); void make_local_material(struct Material *ma); + struct Material ***give_matarar(struct Object *ob); short *give_totcolp(struct Object *ob); struct Material *give_current_material(struct Object *ob, int act); 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); -void init_render_material(struct Material *ma); -void init_render_materials(void); -void end_render_material(struct Material *ma); + +void init_render_material(struct Material *, int, float *); +void init_render_materials(int, float *); +void end_render_material(struct Material *); void end_render_materials(void); -void automatname(struct Material *ma); + +void automatname(struct Material *); void delete_material_index(void); +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_node.h b/source/blender/blenkernel/BKE_node.h new file mode 100644 index 00000000000..f289de038d6 --- /dev/null +++ b/source/blender/blenkernel/BKE_node.h @@ -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. 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): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_NODE_H +#define BKE_NODE_H + +struct bNodeTree; +struct bNode; +struct bNodeLink; +struct bNodeSocket; +struct bNodeStack; +struct uiBlock; +struct rctf; +struct ListBase; +struct RenderData; + +#define SOCK_IN 1 +#define SOCK_OUT 2 + +/* ************** NODE TYPE DEFINITIONS ***** */ + +typedef struct bNodeSocketType { + int type, limit; + char *name; + float val1, val2, val3, val4; /* default alloc value for inputs */ + float min, max; /* default range for inputs */ + + /* after this line is used internal only */ + struct bNodeSocket *sock; /* used during verify_types */ + struct bNodeSocket *internsock; /* group nodes, the internal socket counterpart */ + int own_index; /* verify group nodes */ + +} bNodeSocketType; + +typedef struct bNodeType { + int type; + char *name; + float width, minwidth, maxwidth; + short nclass, flag; + + bNodeSocketType *inputs, *outputs; + + char storagename[64]; /* struct name for DNA */ + + void (*execfunc)(void *data, struct bNode *, struct bNodeStack **, struct bNodeStack **); + + /* after this line is set on startup of blender */ + int (*butfunc)(struct uiBlock *, struct bNodeTree *, struct bNode *, struct rctf *); + +} bNodeType; + +/* nodetype->nclass, also for themes */ +#define NODE_CLASS_INPUT 0 +#define NODE_CLASS_OUTPUT 1 +#define NODE_CLASS_GENERATOR 2 +#define NODE_CLASS_OPERATOR 3 +#define NODE_CLASS_GROUP 4 +#define NODE_CLASS_FILE 5 + +/* ************** GENERIC API, TREES *************** */ + +void ntreeVerifyTypes(struct bNodeTree *ntree); + +struct bNodeTree *ntreeAddTree(int type); +void ntreeInitTypes(struct bNodeTree *ntree); +void ntreeMakeOwnType(struct bNodeTree *ntree); +void ntreeFreeTree(struct bNodeTree *ntree); +struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree, int internal_select); + +void ntreeSocketUseFlags(struct bNodeTree *ntree); + +void ntreeSolveOrder(struct bNodeTree *ntree); + +void ntreeBeginExecTree(struct bNodeTree *ntree); +void ntreeExecTree(struct bNodeTree *ntree, void *callerdata, int thread); +void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews); +void ntreeEndExecTree(struct bNodeTree *ntree); + +void ntreeInitPreview(struct bNodeTree *, int xsize, int ysize); + +/* ************** GENERIC API, NODES *************** */ + +void nodeVerifyType(struct bNodeTree *ntree, struct bNode *node); + +void nodeAddToPreview(struct bNode *, float *, int, int); + +struct bNode *nodeAddNodeType(struct bNodeTree *ntree, int type, struct bNodeTree *ngroup); +void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node); +struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node); + +struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock); +void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); + +struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to); +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); +void nodeClearActiveID(struct bNodeTree *ntree, short idtype); + +void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node); + +/* ************** Groups ****************** */ + +struct bNode *nodeMakeGroupFromSelected(struct bNodeTree *ntree); +int nodeGroupUnGroup(struct bNodeTree *ntree, struct bNode *gnode); + +void nodeVerifyGroup(struct bNodeTree *ngroup); +void nodeGroupSocketUseFlags(struct bNodeTree *ngroup); + +/* ************** COMMON NODES *************** */ + +#define NODE_GROUP 2 + +extern bNodeType node_group_typeinfo; + + +/* ************** SHADER NODES *************** */ + +struct ShadeInput; +struct ShadeResult; + +/* note: types are needed to restore callbacks, don't change values */ +#define SH_NODE_OUTPUT 1 + +#define SH_NODE_MATERIAL 100 +#define SH_NODE_RGB 101 +#define SH_NODE_VALUE 102 +#define SH_NODE_MIX_RGB 103 +#define SH_NODE_VALTORGB 104 +#define SH_NODE_RGBTOBW 105 +#define SH_NODE_TEXTURE 106 +#define SH_NODE_NORMAL 107 +#define SH_NODE_GEOMETRY 108 +#define SH_NODE_MAPPING 109 +#define SH_NODE_CURVE_VEC 110 +#define SH_NODE_CURVE_RGB 111 + +/* custom defines: options for Material node */ +#define SH_NODE_MAT_DIFF 1 +#define SH_NODE_MAT_SPEC 2 +#define SH_NODE_MAT_NEG 4 + +/* the type definitions array */ +extern bNodeType *node_all_shaders[]; + +/* API */ + +void ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr); +int ntreeShaderGetTexco(struct bNodeTree *ntree, int osa); +void nodeShaderSynchronizeID(struct bNode *node, int copyto); + + /* switch material render loop */ +void set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *)); + +/* ************** COMPOSIT NODES *************** */ + +/* note: types are needed to restore callbacks, don't change values */ +#define CMP_NODE_VIEWER 201 +#define CMP_NODE_RGB 202 +#define CMP_NODE_VALUE 203 +#define CMP_NODE_MIX_RGB 204 +#define CMP_NODE_VALTORGB 205 +#define CMP_NODE_RGBTOBW 206 +#define CMP_NODE_NORMAL 207 +#define CMP_NODE_CURVE_VEC 208 +#define CMP_NODE_CURVE_RGB 209 +#define CMP_NODE_ALPHAOVER 210 +#define CMP_NODE_BLUR 211 +#define CMP_NODE_FILTER 212 +#define CMP_NODE_MAP_VALUE 213 +#define CMP_NODE_TIME 214 + +#define CMP_NODE_IMAGE 220 +#define CMP_NODE_R_RESULT 221 +#define CMP_NODE_COMPOSITE 222 +#define CMP_NODE_OUTPUT_FILE 223 + + +/* filter types */ +#define CMP_FILT_SOFT 0 +#define CMP_FILT_SHARP 1 +#define CMP_FILT_LAPLACE 2 +#define CMP_FILT_SOBEL 3 +#define CMP_FILT_PREWITT 4 +#define CMP_FILT_KIRSCH 5 +#define CMP_FILT_SHADOW 6 + + +/* the type definitions array */ +extern bNodeType *node_all_composit[]; + +/* API */ +struct CompBuf; +int ntreeCompositNeedsRender(struct bNodeTree *ntree); +void ntreeCompositTagRender(struct bNodeTree *ntree); + +void free_compbuf(struct CompBuf *cbuf); /* internal...*/ + +#endif + diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 2e4e4917de2..d0f70907e5c 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -73,7 +73,7 @@ void base_init_from_view3d(struct Base *base, struct View3D *v3d); struct Object *copy_object(struct Object *ob); void expand_local_object(struct Object *ob); void make_local_object(struct Object *ob); -void set_mblur_offs(int blur); +void set_mblur_offs(float blur); void disable_speed_curve(int val); float bsystem_time(struct Object *ob, struct Object *par, float cfra, float ofs); void object_to_mat3(struct Object *ob, float mat[][3]); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 1313ad251e7..a7e2839d20c 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -53,6 +53,7 @@ struct QuicktimeCodecData; } +#define SETLOOPER(s, b) sce= s, b= s->base.first; b; b= (b->next?b->next:s->set?(s=s->set)->base.first:NULL) void free_avicodecdata(struct AviCodecData *acd); @@ -60,7 +61,7 @@ void free_qtcodecdata(struct QuicktimeCodecData *acd); void free_scene(struct Scene *me); struct Scene *add_scene(char *name); -int object_in_scene(struct Object *ob, struct Scene *sce); +struct Base *object_in_scene(struct Object *ob, struct Scene *sce); void set_scene_bg(struct Scene *sce); void set_scene_name(char *name); @@ -74,5 +75,7 @@ void scene_select_base(struct Scene *sce, struct Base *selbase); void scene_update_for_newframe(struct Scene *sce, unsigned int lay); +void scene_add_render_layer(struct Scene *sce); + #endif diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 23c31564a66..a34ef43cab7 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -40,6 +40,8 @@ struct PluginTex; struct LampRen; struct ColorBand; struct HaloRen; +struct TexMapping; +struct EnvMap; /* in ColorBand struct */ #define MAXCOLORBAND 16 @@ -50,7 +52,7 @@ int test_dlerr(const char *name, const char *symbol); void open_plugin_tex(struct PluginTex *pit); struct PluginTex *add_plugin_tex(char *str); void free_plugin_tex(struct PluginTex *pit); -struct ColorBand *add_colorband(void); +struct ColorBand *add_colorband(int rangetype); int do_colorband(struct ColorBand *coba, float in, float out[4]); void default_tex(struct Tex *tex); struct Tex *add_texture(char *name); @@ -61,5 +63,15 @@ void make_local_texture(struct Tex *tex); void autotexname(struct Tex *tex); struct Tex *give_current_texture(struct Object *ob, int act); +struct TexMapping *add_mapping(void); +void init_mapping(struct TexMapping *texmap); + + +void BKE_free_envmapdata(struct EnvMap *env); +void BKE_free_envmap(struct EnvMap *env); +struct EnvMap *BKE_add_envmap(void); +struct EnvMap *BKE_copy_envmap(struct EnvMap *env); + + #endif diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index a18a43fb7b8..f784973708d 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -1,5 +1,3 @@ -/* util defines -- might go away ?*/ - /* $Id$ @@ -58,11 +56,6 @@ #define ELEM7(a, b, c, d, e, f, g, h) ( ELEM3(a, b, c, d) || ELEM4(a, e, f, g, h) ) #define ELEM8(a, b, c, d, e, f, g, h, i) ( ELEM4(a, b, c, d, e) || ELEM4(a, f, g, h, i) ) -/* pointer magic, only to be used for the max 16 Gig mem period */ -/* note that int is signed! */ -#define POINTER_TO_INT(poin) (int)( ((long)(poin))>>3 ) -#define INT_TO_POINTER(int) (void *)( ((long)(int))<<3 ) - /* string compare */ #define STREQ(str, a) ( strcmp((str), (a))==0 ) #define STREQ2(str, a, b) ( STREQ(str, a) || STREQ(str, b) ) @@ -108,6 +101,7 @@ #define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} #define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} +#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 INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h index cedff61f2dd..b51eaff420c 100644 --- a/source/blender/blenkernel/BKE_world.h +++ b/source/blender/blenkernel/BKE_world.h @@ -40,7 +40,6 @@ void free_world(struct World *sc); struct World *add_world(char *name); struct World *copy_world(struct World *wrld); void make_local_world(struct World *wrld); -void init_render_world(void); #endif diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h index f63342ea047..af442600c6b 100644 --- a/source/blender/blenkernel/BKE_writeavi.h +++ b/source/blender/blenkernel/BKE_writeavi.h @@ -37,10 +37,26 @@ extern "C" { #endif -void start_avi(void); +/* generic blender movie support, could move to own module */ + +typedef struct bMovieHandle { + void (*start_movie)(RenderData *rd, int rectx, int recty); + void (*append_movie)(int frame, int *pixels, int rectx, int recty); + void (*end_movie)(void); +} bMovieHandle; + +bMovieHandle *BKE_get_movie_handle(int imtype); + + +/* ************** */ + +struct RenderData; +void start_avi(struct RenderData *rd, int rectx, int recty); void end_avi(void); -void append_avi(int frame); -void makeavistring(char *string); +void append_avi(int frame, int *pixels, int rectx, int recty); +void makeavistring (struct RenderData *rd, char *string); + + #ifdef __cplusplus } diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index d279fc4a7d7..8a5fd47388f 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -8,6 +8,7 @@ source_files = ['intern/constraint.c', 'intern/depsgraph.c', 'intern/DerivedMesh.c', 'intern/group.c', + 'intern/icons.c', 'intern/material.c', 'intern/sca.c', 'intern/world.c', @@ -43,6 +44,10 @@ source_files = ['intern/constraint.c', 'intern/library.c', 'intern/property.c', 'intern/softbody.c', + 'intern/node.c', + 'intern/node_shaders.c', + 'intern/node_composit.c', + 'intern/colortools.c', 'intern/texture.c'] blenkernel_env.Append (CPPPATH = ['.', @@ -56,6 +61,7 @@ blenkernel_env.Append (CPPPATH = ['.', '../../../intern/decimation/extern', '../imbuf', '../avi', + '../quicktime', '#/intern/elbeem/extern', '#/intern/iksolver/extern', '../blenloader']) diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 457c6a2d7e5..f8c44730bdf 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -102,36 +102,11 @@ void error(char *str, ...){} /* anim.c */ ListBase editNurb; -/* displist.c */ -#include "DNA_world_types.h" /* for render_types */ -#include "render_types.h" -struct RE_Render R; - -float Phong_Spec(float *n, float *l, float *v, int hard, int tangent){return 0;} -float Blinn_Spec(float *n, float *l, float *v, float a, float b, int tangent){return 0;} -float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent){return 0;} -float Toon_Spec(float *n, float *l, float *v, float a, float b, int tangent){return 0;} -float WardIso_Spec(float *n, float *l, float *v, float a, int tangent){return 0;} - -float Toon_Diff(float *n, float *l, float *v, float a, float b){return 0;} -float OrenNayar_Diff(float *n, float *l, float *v, float rough){return 0;} -float Minnaert_Diff(float nl, float *n, float *v, float a){return 0;} - -void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b){} -void ramp_diffuse_result(float *diff, ShadeInput *shi){} -void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec){} -void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi){} - - void waitcursor(int val){} void allqueue(unsigned short event, short val){} #define REDRAWVIEW3D 0x4010 Material defmaterial; -/* effect.c */ -void RE_jitterate1(float *jit1, float *jit2, int num, float rad1){} -void RE_jitterate2(float *jit1, float *jit2, int num, float rad2){} - /* exotic.c */ void load_editMesh(void){} void make_editMesh(void){} @@ -142,7 +117,6 @@ int saveover(char *str){ return 0;} /* image.c */ #include "DNA_image_types.h" void free_realtime_image(Image *ima){} // has to become a callback, opengl stuff -void RE_make_existing_file(char *name){} // from render, but these funcs should be moved anyway /* ipo.c */ void copy_view3d_lock(short val){} // was a hack, to make scene layer ipo's possible @@ -201,21 +175,7 @@ int BPY_call_importloader(char *name) /* texture.c */ #define FLO 128 #define INT 96 - /* struct EnvMap; */ - /* struct Tex; */ -void do_material_tex(ShadeInput *shi){} -void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){} -void init_render_textures(void){} -void end_render_textures(void){} - -void RE_free_envmap(struct EnvMap *env){} -struct EnvMap *RE_copy_envmap(struct EnvMap *env){ return env;} -void RE_free_envmapdata(struct EnvMap *env){} - -int RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt){ - return 0; -} char texstr[20][12]; /* buttons.c */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 61db603d647..1a26b52a0aa 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1823,8 +1823,6 @@ static void mesh_build_data(Object *ob) Mesh *me = ob->data; float min[3], max[3]; - if(ob->flag&OB_FROMDUPLI) return; - clear_mesh_caches(ob); if(ob!=G.obedit) { diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 9207023f9a5..c173051e862 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -83,3 +83,11 @@ ifeq ($(WITH_FREETYPE2), true) CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2 endif +ifeq ($(WITH_OPENEXR), true) + CPPFLAGS += -DWITH_OPENEXR +endif + +ifeq ($(WITH_QUICKTIME), true) + CPPFLAGS += -I../../quicktime + CPPFLAGS += -DWITH_QUICKTIME +endif diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 38a07f246dc..642ce855383 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -66,7 +66,6 @@ #include "BLI_blenlib.h" #include "nla.h" -#include "render.h" /* *********************** NOTE ON POSE AND ACTION ********************** @@ -83,6 +82,38 @@ /* ***************** Library data level operations on action ************** */ +static void make_local_action_channels(bAction *act) +{ + bActionChannel *chan; + bConstraintChannel *conchan; + + for (chan=act->chanbase.first; chan; chan=chan->next) { + if(chan->ipo) { + if(chan->ipo->id.us==1) { + chan->ipo->id.lib= NULL; + chan->ipo->id.flag= LIB_LOCAL; + new_id(0, (ID *)chan->ipo, 0); + } + else { + chan->ipo= copy_ipo(chan->ipo); + } + } + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) { + if(conchan->ipo) { + if(conchan->ipo->id.us==1) { + conchan->ipo->id.lib= NULL; + conchan->ipo->id.flag= LIB_LOCAL; + new_id(0, (ID *)conchan->ipo, 0); + } + else { + conchan->ipo= copy_ipo(conchan->ipo); + } + } + } + } + +} + void make_local_action(bAction *act) { Object *ob; @@ -93,6 +124,7 @@ void make_local_action(bAction *act) if(act->id.us==1) { act->id.lib= 0; act->id.flag= LIB_LOCAL; + make_local_action_channels(act); new_id(0, (ID *)act, 0); return; } @@ -109,6 +141,7 @@ void make_local_action(bAction *act) if(local && lib==0) { act->id.lib= 0; act->id.flag= LIB_LOCAL; + make_local_action_channels(act); new_id(0, (ID *)act, 0); } else if(local && lib) { @@ -204,7 +237,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name) /* If not, create it and add it */ chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); - strcpy (chan->name, name); + strncpy (chan->name, name, 31); /* init vars to prevent mat errors */ chan->quat[0] = 1.0F; chan->size[0] = chan->size[1] = chan->size[2] = 1.0F; @@ -346,7 +379,7 @@ bActionChannel *verify_action_channel(bAction *act, const char *name) if(chan==NULL) { if (!chan) { chan = MEM_callocN (sizeof(bActionChannel), "actionChannel"); - strcpy (chan->name, name); + strncpy (chan->name, name, 31); BLI_addtail (&act->chanbase, chan); } } @@ -427,7 +460,7 @@ void blend_poses(bPose *dst, bPose *src, float srcweight, short mode) } -void calc_action_range(const bAction *act, float *start, float *end) +void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden) { const bActionChannel *chan; const bConstraintChannel *conchan; @@ -437,18 +470,9 @@ void calc_action_range(const bAction *act, float *start, float *end) if(act) { for (chan=act->chanbase.first; chan; chan=chan->next) { - if(chan->ipo) { - for (icu=chan->ipo->curve.first; icu; icu=icu->next) { - if(icu->totvert) { - min= MIN2 (min, icu->bezt[0].vec[1][0]); - max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); - foundvert=1; - } - } - } - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) { - if(conchan->ipo) { - for (icu=conchan->ipo->curve.first; icu; icu=icu->next) { + if(incl_hidden || (chan->flag & ACHAN_HIDDEN)==0) { + if(chan->ipo) { + for (icu=chan->ipo->curve.first; icu; icu=icu->next) { if(icu->totvert) { min= MIN2 (min, icu->bezt[0].vec[1][0]); max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); @@ -456,6 +480,17 @@ void calc_action_range(const bAction *act, float *start, float *end) } } } + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) { + if(conchan->ipo) { + for (icu=conchan->ipo->curve.first; icu; icu=icu->next) { + if(icu->totvert) { + min= MIN2 (min, icu->bezt[0].vec[1][0]); + max= MAX2 (max, icu->bezt[icu->totvert-1].vec[1][0]); + foundvert=1; + } + } + } + } } } } @@ -719,9 +754,9 @@ static float nla_time(float cfra, float unit) extern float bluroffs; // bad construct, borrowed from object.c for now /* 2nd field */ - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_FIELDSTILL); else cfra+= 0.5f*unit; - } +// if(R.flag & R_SEC_FIELD) { +// if(R.r.mode & R_FIELDSTILL); else cfra+= 0.5f*unit; +// } /* motion blur */ cfra+= unit*bluroffs; @@ -769,11 +804,14 @@ static float stridechannel_frame(Object *ob, bActionStrip *strip, Path *path, fl if(foundvert && miny!=maxy) { float stridelen= fabs(maxy-miny), striptime; - float actiondist, pdist, pdistNewNormalized; + float actiondist, pdist, pdistNewNormalized, offs; float vec1[4], vec2[4], dir[3]; + /* internal cycling, actoffs is in frames */ + offs= stridelen*strip->actoffs/(maxx-minx); + /* amount path moves object */ - pdist = (float)fmod (pathdist, stridelen); + pdist = (float)fmod (pathdist+offs, stridelen); striptime= pdist/stridelen; /* amount stride bone moves */ @@ -801,6 +839,26 @@ static float stridechannel_frame(Object *ob, bActionStrip *strip, Path *path, fl return 0.0f; } +/* simple case for now; only the curve path with constraint value > 0.5 */ +/* blending we might do later... */ +static Object *get_parent_path(Object *ob) +{ + bConstraint *con; + + if(ob->parent && ob->parent->type==OB_CURVE) + return ob->parent; + + for (con = ob->constraints.first; con; con=con->next) { + if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) { + if(con->enforce>0.5f) { + bFollowPathConstraint *data= con->data; + return data->tar; + } + } + } + return NULL; +} + /* ************** do the action ************ */ static void do_nla(Object *ob, int blocktype) @@ -808,9 +866,10 @@ static void do_nla(Object *ob, int blocktype) bPose *tpose= NULL; Key *key= NULL; ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL}; - bActionStrip *strip; + bActionStrip *strip, *striplast=NULL, *stripfirst=NULL; float striptime, frametime, length, actlength; float blendfac, stripframe; + float scene_cfra= G.scene->r.cfra; int doit, dostride; if(blocktype==ID_AR) { @@ -821,6 +880,32 @@ static void do_nla(Object *ob, int blocktype) key= ob_get_key(ob); } + /* check on extend to left or right, when no strip is hit by 'cfra' */ + for (strip=ob->nlastrips.first; strip; strip=strip->next) { + /* escape loop on a hit */ + if( scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f) /* note 0.1 comes back below */ + break; + if(scene_cfra < strip->start) { + if(stripfirst==NULL) + stripfirst= strip; + else if(stripfirst->start > strip->start) + stripfirst= strip; + } + else if(scene_cfra > strip->end) { + if(striplast==NULL) + striplast= strip; + else if(striplast->end < strip->end) + striplast= strip; + } + } + if(strip==NULL) { /* extend */ + if(stripfirst) + scene_cfra= stripfirst->start; + else if(striplast) + scene_cfra= striplast->end; + } + + /* and now go over all strips */ for (strip=ob->nlastrips.first; strip; strip=strip->next){ doit=dostride= 0; @@ -829,82 +914,88 @@ static void do_nla(Object *ob, int blocktype) /* Determine if the current frame is within the strip's range */ length = strip->end-strip->start; actlength = strip->actend-strip->actstart; - striptime = (G.scene->r.cfra-(strip->start)) / length; - stripframe = (G.scene->r.cfra-(strip->start)) ; - + striptime = (scene_cfra-(strip->start)) / length; + stripframe = (scene_cfra-(strip->start)) ; + if (striptime>=0.0){ if(blocktype==ID_AR) rest_pose(tpose); - /* Handle path */ - if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){ - if (ob->parent && ob->parent->type==OB_CURVE){ - Curve *cu = ob->parent->data; - float ctime, pdist; + /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ + if (striptime < 1.0f + 0.1f/length) { + + /* Handle path */ + if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype==ID_AR) && (ob->ipoflag & OB_DISABLE_PATH)==0){ + Object *parent= get_parent_path(ob); - if (cu->flag & CU_PATH){ - /* Ensure we have a valid path */ - if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(ob->parent, 0); - if(cu->path) { - - /* Find the position on the path */ - ctime= bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0); - - if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { - ctime /= cu->pathlen; - CLAMP(ctime, 0.0, 1.0); - } - pdist = ctime*cu->path->totdist; - - if(tpose && strip->stridechannel[0]) { - striptime= stridechannel_frame(ob->parent, strip, cu->path, pdist, tpose->stride_offset); - } - else { - if (strip->stridelen) { - striptime = pdist / strip->stridelen; - striptime = (float)fmod (striptime, 1.0); + if (parent) { + Curve *cu = parent->data; + float ctime, pdist; + + if (cu->flag & CU_PATH){ + /* Ensure we have a valid path */ + if(cu->path==NULL || cu->path->data==NULL) makeDispListCurveTypes(parent, 0); + if(cu->path) { + + /* Find the position on the path */ + ctime= bsystem_time(ob, parent, scene_cfra, 0.0); + + if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) { + ctime /= cu->pathlen; + CLAMP(ctime, 0.0, 1.0); } - else - striptime = 0; + pdist = ctime*cu->path->totdist; + + if(tpose && strip->stridechannel[0]) { + striptime= stridechannel_frame(parent, strip, cu->path, pdist, tpose->stride_offset); + } + else { + if (strip->stridelen) { + striptime = pdist / strip->stridelen; + striptime = (float)fmod (striptime+strip->actoffs, 1.0); + } + else + striptime = 0; + } + + frametime = (striptime * actlength) + strip->actstart; + frametime= bsystem_time(ob, 0, frametime, 0.0); + + if(blocktype==ID_AR) { + extract_pose_from_action (tpose, strip->act, frametime); + } + else if(blocktype==ID_OB) { + extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); + } + doit=dostride= 1; } - - frametime = (striptime * actlength) + strip->actstart; - frametime= bsystem_time(ob, 0, frametime, 0.0); - - if(blocktype==ID_AR) { - extract_pose_from_action (tpose, strip->act, frametime); - } - else if(blocktype==ID_OB) { - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); - if(key) - extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); - } - doit=dostride= 1; } } } - } - /* Handle repeat, we add 0.1 frame extra to make sure the last frame is included */ - else if (striptime < 1.0f + 0.1f/length) { - - /* Mod to repeat */ - if(strip->repeat!=1.0f) { - striptime*= strip->repeat; - striptime = (float)fmod (striptime, 1.0f + 0.1f/length); - } - - frametime = (striptime * actlength) + strip->actstart; - frametime= nla_time(frametime, (float)strip->repeat); + /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */ + else { - if(blocktype==ID_AR) - extract_pose_from_action (tpose, strip->act, frametime); - else if(blocktype==ID_OB) { - extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); - if(key) - extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); - } - doit=1; + /* Mod to repeat */ + if(strip->repeat!=1.0f) { + striptime*= strip->repeat; + striptime = (float)fmod (striptime, 1.0f + 0.1f/length); + } + + frametime = (striptime * actlength) + strip->actstart; + frametime= nla_time(frametime, (float)strip->repeat); + + if(blocktype==ID_AR) + extract_pose_from_action (tpose, strip->act, frametime); + else if(blocktype==ID_OB) { + extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime); + if(key) + extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime); + } + doit=1; + } } /* Handle extend */ else{ @@ -930,10 +1021,10 @@ static void do_nla(Object *ob, int blocktype) if (doit){ /* Handle blendin */ - if (strip->blendin>0.0 && stripframe<=strip->blendin && G.scene->r.cfra>=strip->start){ + if (strip->blendin>0.0 && stripframe<=strip->blendin && scene_cfra>=strip->start){ blendfac = stripframe/strip->blendin; } - else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && G.scene->r.cfra<=strip->end){ + else if (strip->blendout>0.0 && stripframe>=(length-strip->blendout) && scene_cfra<=strip->end){ blendfac = (length-stripframe)/(strip->blendout); } else @@ -998,6 +1089,7 @@ void do_all_pose_actions(Object *ob) void do_all_object_actions(Object *ob) { if(ob==NULL) return; + if(ob->dup_group) return; /* prevent conflicts, might add smarter check later */ /* Do local action */ if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) { @@ -1021,3 +1113,4 @@ void do_all_object_actions(Object *ob) } } + diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index b8178dd98cd..5700be0fcbc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -40,25 +40,29 @@ #include "BLI_arithb.h" #include "DNA_listBase.h" -#include "DNA_object_types.h" #include "DNA_curve_types.h" -#include "DNA_key_types.h" -#include "DNA_view3d_types.h" #include "DNA_effect_types.h" +#include "DNA_group_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_view3d_types.h" +#include "DNA_vfont_types.h" -#include "BKE_DerivedMesh.h" -#include "BKE_global.h" -#include "BKE_utildefines.h" #include "BKE_anim.h" -#include "BKE_ipo.h" -#include "BKE_object.h" +#include "BKE_DerivedMesh.h" #include "BKE_displist.h" -#include "BKE_key.h" -#include "BKE_font.h" #include "BKE_effect.h" +#include "BKE_font.h" +#include "BKE_group.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_key.h" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" #include "BKE_bad_level_calls.h" @@ -271,32 +275,40 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK return 1; } -static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par) +/* ****************** DUPLICATOR ************** */ + +static void new_dupli_object(ListBase *lb, Object *ob, float mat[][4]) { - Object *newob; - - newob= MEM_mallocN(sizeof(Object), "newobj dupli"); - - memcpy(newob, ob, sizeof(Object)); - newob->flag |= OB_FROMDUPLI; - newob->id.newid= (ID *)par; /* store duplicator */ - - /* only basis-ball gets displist */ - if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL; - - if(ob!=par) { // dupliverts, particle - newob->parent= NULL; - newob->track= NULL; - } - BLI_addtail(lb, newob); - - return newob; + DupliObject *dob= MEM_mallocN(sizeof(DupliObject), "dupliobject"); + BLI_addtail(lb, dob); + dob->ob= ob; + Mat4CpyMat4(dob->mat, mat); + Mat4CpyMat4(dob->omat, ob->obmat); } -void frames_duplilist(Object *ob) +static void group_duplilist(ListBase *lb, Object *ob) +{ + GroupObject *go; + float mat[4][4]; + + if(ob->dup_group==NULL) return; + + /* handles animated groups, and */ + /* we need to check update for objects that are not in scene... */ + group_handle_recalc_and_update(ob, ob->dup_group); + + for(go= ob->dup_group->gobject.first; go; go= go->next) { + if(go->ob!=ob) { + Mat4MulMat4(mat, go->ob->obmat, ob->obmat); + new_dupli_object(lb, go->ob, mat); + } + } +} + +static void frames_duplilist(ListBase *lb, Object *ob) { extern int enable_cu_speed; /* object.c */ - Object *newob, copyob; + Object copyob; int cfrao, ok; cfrao= G.scene->r.cfra; @@ -315,10 +327,9 @@ void frames_duplilist(Object *ob) else ok= 0; } if(ok) { - newob= new_dupli_object(&duplilist, ob, ob); - - do_ob_ipo(newob); - where_is_object_time(newob, (float)G.scene->r.cfra); + do_ob_ipo(ob); + where_is_object_time(ob, (float)G.scene->r.cfra); + new_dupli_object(lb, ob, ob->obmat); } } @@ -328,6 +339,7 @@ void frames_duplilist(Object *ob) } struct vertexDupliData { + ListBase *lb; float pmat[4][4]; Object *ob, *par; }; @@ -335,16 +347,15 @@ struct vertexDupliData { static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { struct vertexDupliData *vdd= userData; - Object *newob; - float vec[3], *q2, mat[3][3], tmat[4][4]; + float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4]; VECCOPY(vec, co); Mat4MulVecfl(vdd->pmat, vec); VecSubf(vec, vec, vdd->pmat[3]); VecAddf(vec, vec, vdd->ob->obmat[3]); - newob= new_dupli_object(&duplilist, vdd->ob, vdd->par); - VECCOPY(newob->obmat[3], vec); + Mat4CpyMat4(obmat, vdd->ob->obmat); + VECCOPY(obmat[3], vec); if(vdd->par->transflag & OB_DUPLIROT) { @@ -353,13 +364,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, obmat); + Mat4MulMat43(obmat, tmat, mat); } - + new_dupli_object(vdd->lb, vdd->ob, obmat); } -void vertex_duplilist(Scene *sce, Object *par) +static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) { Object *ob; Base *base; @@ -389,6 +400,7 @@ void vertex_duplilist(Scene *sce, Object *par) struct vertexDupliData vdd; ob= base->object; + vdd.lb= lb; vdd.ob= ob; vdd.par= par; Mat4CpyMat4(vdd.pmat, pmat); @@ -420,10 +432,9 @@ void vertex_duplilist(Scene *sce, Object *par) dm->release(dm); } - -void particle_duplilist(Scene *sce, Object *par, PartEff *paf) +static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf) { - Object *ob, *newob; + Object *ob, copyob; Base *base; Particle *pa; float ctime, vec1[3]; @@ -439,21 +450,20 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf) } ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0); - + lay= G.scene->lay; - base= sce->base.first; - while(base) { - + for(base= sce->base.first; base; base= base->next) { if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) { ob= base->object->parent; while(ob) { if(ob==par) { ob= base->object; + /* temp copy, to have ipos etc to work OK */ + copyob= *ob; - pa= paf->keys; - for(a=0; atotpart; a++, pa+=paf->totkey) { + for(a=0, pa= paf->keys; atotpart; a++, pa+=paf->totkey) { if(paf->flag & PAF_STATIC) { float mtime; @@ -462,13 +472,12 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf) mtime= pa->time+pa->lifetime; for(ctime= pa->time; ctimestaticstep) { - newob= new_dupli_object(&duplilist, ob, par); /* make sure hair grows until the end.. */ if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime; /* to give ipos in object correct offset */ - where_is_object_time(newob, ctime-pa->time); + where_is_object_time(ob, ctime-pa->time); where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec Mat4MulVecfl(par->obmat, vec); @@ -481,11 +490,12 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf) q2= vectoquat(vec1, ob->trackflag, ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, ob->obmat); + Mat4MulMat43(ob->obmat, tmat, mat); } - VECCOPY(newob->obmat[3], vec); + VECCOPY(ob->obmat[3], vec); + new_dupli_object(lb, ob, ob->obmat); } } else { // non static particles @@ -494,10 +504,9 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf) if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue; //if(ctime < pa->time+pa->lifetime) { - newob= new_dupli_object(&duplilist, ob, par); /* to give ipos in object correct offset */ - where_is_object_time(newob, ctime-pa->time); + where_is_object_time(ob, ctime-pa->time); where_is_particle(paf, pa, ctime, vec); if(paf->stype==PAF_VECT) { @@ -507,54 +516,129 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf) q2= vectoquat(vec1, ob->trackflag, ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, ob->obmat); + Mat4MulMat43(ob->obmat, tmat, mat); } - VECCOPY(newob->obmat[3], vec); + VECCOPY(ob->obmat[3], vec); + new_dupli_object(lb, ob, ob->obmat); } } + /* temp copy, to have ipos etc to work OK */ + *ob= copyob; + break; } ob= ob->parent; } } - base= base->next; } } - -void free_duplilist() +static Object *find_family_object(Object **obar, char *family, char ch) { Object *ob; + int flen; - while( (ob= duplilist.first) ) { - BLI_remlink(&duplilist, ob); - MEM_freeN(ob); + if( obar[ch] ) return obar[ch]; + + flen= strlen(family); + + ob= G.main->object.first; + while(ob) { + if( ob->id.name[flen+2]==ch ) { + if( strncmp(ob->id.name+2, family, flen)==0 ) break; + } + ob= ob->id.next; } + obar[ch]= ob; + + return ob; } -void make_duplilist(Scene *sce, Object *ob) -{ - PartEff *paf; +static void font_duplilist(ListBase *lb, Object *par) +{ + Object *ob, *obar[256]; + Curve *cu; + struct chartrans *ct, *chartransdata; + float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; + int slen, a; + + Mat4CpyMat4(pmat, par->obmat); + + /* in par the family name is stored, use this to find the other objects */ + + chartransdata= text_to_curve(par, FO_DUPLI); + if(chartransdata==0) return; + + memset(obar, 0, 256*sizeof(void *)); + + cu= par->data; + slen= strlen(cu->str); + fsize= cu->fsize; + xof= cu->xof; + yof= cu->yof; + + ct= chartransdata; + + for(a=0; afamily, cu->str[a]); + if(ob) { + vec[0]= fsize*(ct->xof - xof); + vec[1]= fsize*(ct->yof - yof); + vec[2]= 0.0; + + Mat4MulVecfl(pmat, vec); + + Mat4CpyMat4(obmat, par->obmat); + VECCOPY(obmat[3], vec); + + new_dupli_object(lb, ob, obmat); + } + + } + + MEM_freeN(chartransdata); +} + +/* ***************************** */ + +ListBase *object_duplilist(Scene *sce, Object *ob) +{ + static ListBase duplilist={NULL, NULL}; + + if(duplilist.first) { + printf("wrong call to object_duplilist\n"); + return &duplilist; + } + duplilist.first= duplilist.last= NULL; + if(ob->transflag & OB_DUPLI) { if(ob->transflag & OB_DUPLIVERTS) { if(ob->type==OB_MESH) { if(ob->transflag & OB_DUPLIVERTS) { - if( (paf=give_parteff(ob)) ) particle_duplilist(sce, ob, paf); - else vertex_duplilist(sce, ob); + PartEff *paf; + if( (paf=give_parteff(ob)) ) particle_duplilist(&duplilist, sce, ob, paf); + else vertex_duplilist(&duplilist, sce, ob); } } else if(ob->type==OB_FONT) { - font_duplilist(ob); + font_duplilist(&duplilist, ob); } } - else if(ob->transflag & OB_DUPLIFRAMES) frames_duplilist(ob); + else if(ob->transflag & OB_DUPLIFRAMES) + frames_duplilist(&duplilist, ob); + else if(ob->transflag & OB_DUPLIGROUP) + group_duplilist(&duplilist, ob); } + + return &duplilist; } + int count_duplilist(Object *ob) { if(ob->transflag & OB_DUPLI) { diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 4cdd1b71c30..f5d8edef167 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -84,6 +84,7 @@ bArmature *add_armature() arm= alloc_libblock (&G.main->armature, ID_AR, "Armature"); arm->deformflag = ARM_DEF_VGROUP|ARM_DEF_ENVELOPE; + arm->layer= 1; return arm; } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 23c36b9573a..992139a5120 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -1,4 +1,3 @@ - /* blender.c jan 94 MIXED MODEL * * common help functions and data @@ -34,10 +33,6 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifdef HAVE_CONFIG_H -#include -#endif - #ifndef WIN32 #include // for read close #include // for MAXPATHLEN @@ -51,11 +46,13 @@ #include // for open #include "MEM_guardedalloc.h" + #include "DNA_listBase.h" #include "DNA_sdna_types.h" #include "DNA_userdef_types.h" #include "DNA_object_types.h" #include "DNA_curve_types.h" +#include "DNA_scene_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -233,10 +230,6 @@ static void clear_global(void) free_main(G.main); /* free all lib data */ freefastshade(); /* othwerwise old lamp settings stay active */ - - /* prevent hanging vars */ - R.backbuf= 0; - /* force all queues to be left */ winqueue_break= 1; @@ -275,7 +268,6 @@ static void clean_paths(Main *main) Sequence *seq; Strip *strip; - while(image) { BLI_clean(image->name); image= image->id.next; @@ -469,7 +461,7 @@ int BKE_read_file_from_memfile(MemFile *memfile) if (!G.background) waitcursor(1); - bfd= BLO_read_from_memfile(memfile, &bre); + bfd= BLO_read_from_memfile(G.sce, memfile, &bre); if (bfd) { setup_app_data(bfd, ""); } else { diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c new file mode 100644 index 00000000000..ce0db15603f --- /dev/null +++ b/source/blender/blenkernel/intern/colortools.c @@ -0,0 +1,617 @@ +/* + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_color_types.h" +#include "DNA_curve_types.h" +#include "DNA_image_types.h" +#include "DNA_texture_types.h" + +#include "BKE_colortools.h" +#include "BKE_curve.h" +#include "BKE_global.h" +#include "BKE_ipo.h" +#include "BKE_main.h" +#include "BKE_utildefines.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +/* ********************************* color curve ********************* */ + +/* ***************** operations on full struct ************* */ + +CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy) +{ + CurveMapping *cumap; + int a; + + cumap= MEM_callocN(sizeof(CurveMapping), "new curvemap"); + cumap->flag= CUMA_DO_CLIP; + if(tot==4) cumap->cur= 3; /* rhms, hack for 'col' curve? */ + + BLI_init_rctf(&cumap->curr, minx, maxx, miny, maxy); + cumap->clipr= cumap->curr; + + cumap->white[0]= cumap->white[1]= cumap->white[2]= 1.0f; + cumap->bwmul[0]= cumap->bwmul[1]= cumap->bwmul[2]= 1.0f; + + for(a=0; acm[a].totpoint= 2; + cumap->cm[a].curve= MEM_callocN(2*sizeof(CurveMapPoint), "curve points"); + + cumap->cm[a].curve[0].x= minx; + cumap->cm[a].curve[0].y= miny; + cumap->cm[a].curve[1].x= maxx; + cumap->cm[a].curve[1].y= maxy; + } + return cumap; +} + +void curvemapping_free(CurveMapping *cumap) +{ + int a; + + if(cumap) { + for(a=0; acm[a].curve) MEM_freeN(cumap->cm[a].curve); + if(cumap->cm[a].table) MEM_freeN(cumap->cm[a].table); + } + MEM_freeN(cumap); + } +} + +CurveMapping *curvemapping_copy(CurveMapping *cumap) +{ + int a; + + if(cumap) { + CurveMapping *cumapn= MEM_dupallocN(cumap); + for(a=0; acm[a].curve) + cumapn->cm[a].curve= MEM_dupallocN(cumap->cm[a].curve); + if(cumap->cm[a].table) + cumapn->cm[a].table= MEM_dupallocN(cumap->cm[a].table); + } + return cumapn; + } + return NULL; +} + +void curvemapping_set_black_white(CurveMapping *cumap, float *black, float *white) +{ + int a; + + if(white) + VECCOPY(cumap->white, white); + if(black) + VECCOPY(cumap->black, black); + + for(a=0; a<3; a++) { + if(cumap->white[a]==cumap->black[a]) + cumap->bwmul[a]= 0.0f; + else + cumap->bwmul[a]= 1.0f/(cumap->white[a] - cumap->black[a]); + } +} + +/* ***************** operations on single curve ************* */ +/* ********** NOTE: requires curvemapping_changed() call after ******** */ + +/* removes with flag set */ +void curvemap_remove(CurveMap *cuma, int flag) +{ + CurveMapPoint *cmp= MEM_mallocN((cuma->totpoint)*sizeof(CurveMapPoint), "curve points"); + int a, b, removed=0; + + /* well, lets keep the two outer points! */ + cmp[0]= cuma->curve[0]; + for(a=1, b=1; atotpoint-1; a++) { + if(!(cuma->curve[a].flag & flag)) { + cmp[b]= cuma->curve[a]; + b++; + } + else removed++; + } + cmp[b]= cuma->curve[a]; + + MEM_freeN(cuma->curve); + cuma->curve= cmp; + cuma->totpoint -= removed; +} + +void curvemap_insert(CurveMap *cuma, float x, float y) +{ + CurveMapPoint *cmp= MEM_callocN((cuma->totpoint+1)*sizeof(CurveMapPoint), "curve points"); + int a; + + memcpy(cmp, cuma->curve, (cuma->totpoint)*sizeof(CurveMapPoint)); + MEM_freeN(cuma->curve); + cuma->curve= cmp; + + cuma->curve[cuma->totpoint].x= x; + cuma->curve[cuma->totpoint].y= y; + cuma->curve[cuma->totpoint].flag = CUMA_SELECT; + for(a=0; atotpoint; a++, cmp++) + cmp->flag= 0; + cuma->totpoint++; +} + +void curvemap_reset(CurveMap *cuma, rctf *clipr) +{ + cuma->totpoint= 2; + + cuma->curve[0].x= clipr->xmin; + cuma->curve[0].y= clipr->ymin; + cuma->curve[0].flag= 0; + cuma->curve[1].x= clipr->xmax; + cuma->curve[1].y= clipr->ymax; + cuma->curve[1].flag= 0; + + if(cuma->table) { + MEM_freeN(cuma->table); + cuma->table= NULL; + } +} + +/* if type==1: vector, else auto */ +void curvemap_sethandle(CurveMap *cuma, int type) +{ + int a; + + for(a=0; atotpoint; a++) { + if(cuma->curve[a].flag & CUMA_SELECT) { + if(type) cuma->curve[a].flag |= CUMA_VECTOR; + else cuma->curve[a].flag &= ~CUMA_VECTOR; + } + } +} + +/* *********************** Making the tables and display ************** */ + +/* reduced copy of garbled calchandleNurb() code in curve.c */ +static void calchandle_curvemap(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode) +{ + float *p1,*p2,*p3,pt[3]; + float dx1,dy1, dx,dy, vx,vy, len,len1,len2; + + if(bezt->h1==0 && bezt->h2==0) return; + + p2= bezt->vec[1]; + + if(prev==NULL) { + p3= next->vec[1]; + pt[0]= 2*p2[0]- p3[0]; + pt[1]= 2*p2[1]- p3[1]; + p1= pt; + } + else p1= prev->vec[1]; + + if(next==NULL) { + p1= prev->vec[1]; + pt[0]= 2*p2[0]- p1[0]; + pt[1]= 2*p2[1]- p1[1]; + p3= pt; + } + else p3= next->vec[1]; + + dx= p2[0]- p1[0]; + dy= p2[1]- p1[1]; + + len1= (float)sqrt(dx*dx+dy*dy); + + dx1= p3[0]- p2[0]; + dy1= p3[1]- p2[1]; + + len2= (float)sqrt(dx1*dx1+dy1*dy1); + + if(len1==0.0f) len1=1.0f; + if(len2==0.0f) len2=1.0f; + + if(bezt->h1==HD_AUTO || bezt->h2==HD_AUTO) { /* auto */ + vx= dx1/len2 + dx/len1; + vy= dy1/len2 + dy/len1; + + len= 2.5614f*(float)sqrt(vx*vx + vy*vy); + if(len!=0.0f) { + + if(bezt->h1==HD_AUTO) { + len1/=len; + *(p2-3)= *p2-vx*len1; + *(p2-2)= *(p2+1)-vy*len1; + } + if(bezt->h2==HD_AUTO) { + len2/=len; + *(p2+3)= *p2+vx*len2; + *(p2+4)= *(p2+1)+vy*len2; + } + } + } + + if(bezt->h1==HD_VECT) { /* vector */ + dx/=3.0; + dy/=3.0; + *(p2-3)= *p2-dx; + *(p2-2)= *(p2+1)-dy; + } + if(bezt->h2==HD_VECT) { + dx1/=3.0; + dy1/=3.0; + *(p2+3)= *p2+dx1; + *(p2+4)= *(p2+1)+dy1; + } +} + +/* only creates a table for a single channel in CurveMapping */ +static void curvemap_make_table(CurveMap *cuma, rctf *clipr) +{ + CurveMapPoint *cmp= cuma->curve; + BezTriple *bezt; + float *fp, *allpoints, curf, range; + int a, totpoint; + + if(cuma->curve==NULL) return; + + /* default rect also is table range */ + cuma->mintable= clipr->xmin; + cuma->maxtable= clipr->xmax; + + /* hrmf... we now rely on blender ipo beziers, these are more advanced */ + bezt= MEM_callocN(cuma->totpoint*sizeof(BezTriple), "beztarr"); + + for(a=0; atotpoint; a++) { + cuma->mintable= MIN2(cuma->mintable, cmp[a].x); + cuma->maxtable= MAX2(cuma->maxtable, cmp[a].x); + bezt[a].vec[1][0]= cmp[a].x; + bezt[a].vec[1][1]= cmp[a].y; + if(cmp[a].flag & CUMA_VECTOR) + bezt[a].h1= bezt[a].h2= HD_VECT; + else + bezt[a].h1= bezt[a].h2= HD_AUTO; + } + + for(a=0; atotpoint; a++) { + if(a==0) + calchandle_curvemap(bezt, NULL, bezt+1, 0); + else if(a==cuma->totpoint-1) + calchandle_curvemap(bezt+a, bezt+a-1, NULL, 0); + else + calchandle_curvemap(bezt+a, bezt+a-1, bezt+a+1, 0); + } + + /* first and last handle need correction, instead of pointing to center of next/prev, + we let it point to the closest handle */ + if(cuma->totpoint>2) { + float hlen, nlen, vec[3]; + + if(bezt[0].h2==HD_AUTO) { + + hlen= VecLenf(bezt[0].vec[1], bezt[0].vec[2]); /* original handle length */ + /* clip handle point */ + VECCOPY(vec, bezt[1].vec[0]); + if(vec[0] < bezt[0].vec[1][0]) + vec[0]= bezt[0].vec[1][0]; + + VecSubf(vec, vec, bezt[0].vec[1]); + nlen= VecLength(vec); + if(nlen>FLT_EPSILON) { + VecMulf(vec, hlen/nlen); + VecAddf(bezt[0].vec[2], vec, bezt[0].vec[1]); + } + } + a= cuma->totpoint-1; + if(bezt[a].h2==HD_AUTO) { + + hlen= VecLenf(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */ + /* clip handle point */ + VECCOPY(vec, bezt[a-1].vec[2]); + if(vec[0] > bezt[a].vec[1][0]) + vec[0]= bezt[a].vec[1][0]; + + VecSubf(vec, vec, bezt[a].vec[1]); + nlen= VecLength(vec); + if(nlen>FLT_EPSILON) { + VecMulf(vec, hlen/nlen); + VecAddf(bezt[a].vec[0], vec, bezt[a].vec[1]); + } + } + } + /* make the bezier curve */ + if(cuma->table) + MEM_freeN(cuma->table); + totpoint= (cuma->totpoint-1)*CM_RESOL; + fp= allpoints= MEM_mallocN(totpoint*2*sizeof(float), "table"); + + 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); + } + + MEM_freeN(bezt); + + range= CM_TABLEDIV*(cuma->maxtable - cuma->mintable); + cuma->range= 1.0f/range; + + /* now make a table with CM_TABLE equal x distances */ + fp= allpoints; + cmp= MEM_callocN((CM_TABLE+1)*sizeof(CurveMapPoint), "dist table"); + cmp[0].x= cuma->mintable; + cmp[0].y= allpoints[1]; + + for(a=1; amintable + range*(float)a; + cmp[a].x= curf; + + /* get the first x coordinate larger than curf */ + while(curf >= fp[0] && fp!=allpoints-2) { + fp+=2; + } + if(fp==allpoints-2) + cmp[a].y= fp[1]; + else { + float fac1= fp[0] - fp[-2]; + float fac2= fp[0] - curf; + if(fac1 > FLT_EPSILON) + fac1= fac2/fac1; + else + fac1= 0.0f; + cmp[a].y= fac1*fp[-1] + (1.0f-fac1)*fp[1]; + } + } + cmp[CM_TABLE].x= cuma->maxtable; + cmp[CM_TABLE].y= allpoints[2*totpoint-1]; + + MEM_freeN(allpoints); + cuma->table= cmp; +} + +/* call when you do images etc, needs restore too. also verifies tables */ +void curvemapping_premultiply(CurveMapping *cumap, int restore) +{ + static CurveMapPoint *table[3]= {NULL, NULL, NULL}; + int a; + + if(restore) { + for(a=0; a<3; a++) { + MEM_freeN(cumap->cm[a].table); + cumap->cm[a].table= table[a]; + } + } + else { + /* verify and copy */ + for(a=0; a<3; a++) { + if(cumap->cm[a].table==NULL) + curvemap_make_table(cumap->cm+a, &cumap->clipr); + table[a]= cumap->cm[a].table; + cumap->cm[a].table= MEM_dupallocN(cumap->cm[a].table); + } + + if(cumap->cm[3].table==NULL) + curvemap_make_table(cumap->cm+3, &cumap->clipr); + + /* premul */ + for(a=0; a<3; a++) { + int b; + for(b=0; b<=CM_TABLE; b++) { + cumap->cm[a].table[b].y= curvemap_evaluateF(cumap->cm+3, cumap->cm[a].table[b].y); + } + } + } +} + +static int sort_curvepoints(const void *a1, const void *a2) +{ + const struct CurveMapPoint *x1=a1, *x2=a2; + + if( x1->x > x2->x ) return 1; + else if( x1->x < x2->x) return -1; + return 0; +} + +/* ************************ more CurveMapping calls *************** */ + +/* note; only does current curvemap! */ +void curvemapping_changed(CurveMapping *cumap, int rem_doubles) +{ + CurveMap *cuma= cumap->cm+cumap->cur; + CurveMapPoint *cmp= cuma->curve; + rctf *clipr= &cumap->clipr; + float thresh= 0.01f*(clipr->xmax - clipr->xmin); + float dx, dy; + int a; + + /* clamp with clip */ + if(cumap->flag & CUMA_DO_CLIP) { + for(a=0; atotpoint; a++) { + if(cmp[a].x < clipr->xmin) + cmp[a].x= clipr->xmin; + else if(cmp[a].x > clipr->xmax) + cmp[a].x= clipr->xmax; + if(cmp[a].y < clipr->ymin) + cmp[a].y= clipr->ymin; + else if(cmp[a].y > clipr->ymax) + cmp[a].y= clipr->ymax; + } + } + + qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); + + /* remove doubles, threshold set on 1% of default range */ + if(rem_doubles && cuma->totpoint>2) { + for(a=0; atotpoint-1; a++) { + dx= cmp[a].x - cmp[a+1].x; + dy= cmp[a].y - cmp[a+1].y; + if( sqrt(dx*dx + dy*dy) < thresh ) { + if(a==0) { + cmp[a+1].flag|= 2; + if(cmp[a+1].flag & CUMA_SELECT) + cmp[a].flag |= CUMA_SELECT; + } + else { + cmp[a].flag|= 2; + if(cmp[a].flag & CUMA_SELECT) + cmp[a+1].flag |= CUMA_SELECT; + } + break; /* we assume 1 deletion per edit is ok */ + } + } + if(a != cuma->totpoint-1) + curvemap_remove(cuma, 2); + } + curvemap_make_table(cuma, clipr); +} + +/* table should be verified */ +float curvemap_evaluateF(CurveMap *cuma, float value) +{ + float fi; + int i; + + /* index in table */ + fi= (value-cuma->mintable)*cuma->range; + i= (int)fi; + if(i<0) return cuma->table[0].y; + if(i>=CM_TABLE) return cuma->table[CM_TABLE].y; + + fi= fi-(float)i; + return (1.0f-fi)*cuma->table[i].y + (fi)*cuma->table[i+1].y; +} + +/* works with curve 'cur' */ +float curvemapping_evaluateF(CurveMapping *cumap, int cur, float value) +{ + CurveMap *cuma= cumap->cm+cur; + + /* allocate or bail out */ + if(cuma->table==NULL) { + curvemap_make_table(cuma, &cumap->clipr); + if(cuma->table==NULL) + return value; + } + return curvemap_evaluateF(cuma, value); +} + +/* vector case */ +void curvemapping_evaluate3F(CurveMapping *cumap, float *vecout, const float *vecin) +{ + vecout[0]= curvemapping_evaluateF(cumap, 0, vecin[0]); + vecout[1]= curvemapping_evaluateF(cumap, 1, vecin[1]); + vecout[2]= curvemapping_evaluateF(cumap, 2, vecin[2]); +} + +/* RGB case, no black/white points, no premult */ +void curvemapping_evaluateRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +{ + vecout[0]= curvemapping_evaluateF(cumap, 0, curvemapping_evaluateF(cumap, 3, vecin[0])); + vecout[1]= curvemapping_evaluateF(cumap, 1, curvemapping_evaluateF(cumap, 3, vecin[1])); + vecout[2]= curvemapping_evaluateF(cumap, 2, curvemapping_evaluateF(cumap, 3, vecin[2])); +} + + +/* RGB with black/white points and premult. tables are checked */ +void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const float *vecin) +{ + float fac; + + fac= (vecin[0] - cumap->black[0])*cumap->bwmul[0]; + vecout[0]= curvemap_evaluateF(cumap->cm, fac); + + fac= (vecin[1] - cumap->black[1])*cumap->bwmul[1]; + vecout[1]= curvemap_evaluateF(cumap->cm+1, fac); + + fac= (vecin[2] - cumap->black[2])*cumap->bwmul[2]; + vecout[2]= curvemap_evaluateF(cumap->cm+2, fac); +} + +#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val)) + +void curvemapping_do_image(CurveMapping *cumap, Image *ima) +{ + int pixel; + + if(ima==NULL || ima->ibuf==NULL) + return; + if(ima->ibuf->rect_float==NULL) + IMB_float_from_rect(ima->ibuf); + else if(ima->ibuf->rect==NULL) + imb_addrectImBuf(ima->ibuf); + + curvemapping_premultiply(cumap, 0); + + if(ima->ibuf->rect_float && ima->ibuf->rect) { + float *pixf= ima->ibuf->rect_float; + float col[3]; + char *pixc= (char *)ima->ibuf->rect; + + for(pixel= ima->ibuf->x*ima->ibuf->y; pixel>0; pixel--, pixf+=4, pixc+=4) { + curvemapping_evaluate_premulRGBF(cumap, col, pixf); + pixc[0]= FTOCHAR(col[0]); + pixc[1]= FTOCHAR(col[1]); + pixc[2]= FTOCHAR(col[2]); + pixc[3]= FTOCHAR(pixf[3]); + } + } + + curvemapping_premultiply(cumap, 1); +} + +int curvemapping_RGBA_does_something(CurveMapping *cumap) +{ + int a; + + if(cumap->black[0]!=0.0f) return 1; + if(cumap->black[1]!=0.0f) return 1; + if(cumap->black[2]!=0.0f) return 1; + if(cumap->white[0]!=1.0f) return 1; + if(cumap->white[1]!=1.0f) return 1; + if(cumap->white[2]!=1.0f) return 1; + + for(a=0; acm[a].curve) { + if(cumap->cm[a].totpoint!=2) return 1; + + if(cumap->cm[a].curve[0].x != 0.0f) return 1; + if(cumap->cm[a].curve[0].y != 0.0f) return 1; + if(cumap->cm[a].curve[1].x != 1.0f) return 1; + if(cumap->cm[a].curve[1].y != 1.0f) return 1; + } + } + return 0; +} + diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 223c27923f8..7458a0230dd 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -53,6 +53,7 @@ #include "BKE_armature.h" #include "BKE_blender.h" #include "BKE_constraint.h" +#include "BKE_displist.h" #include "BKE_object.h" #include "BKE_ipo.h" #include "BKE_global.h" @@ -959,6 +960,9 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own /* note; when creating constraints that follow path, the curve gets the CU_PATH set now, currently for paths to work it needs to go through the bevlist/displist system (ton) */ + + if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */ + makeDispListCurveTypes(data->tar, 0); if(cu->path && cu->path->data) { curvetime= bsystem_time(data->tar, data->tar->parent, (float)ctime, 0.0) - data->offset; diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 7f5f6fbaddf..9a4a8f62600 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -46,6 +46,7 @@ #include "DNA_curve_types.h" #include "DNA_ID.h" #include "DNA_effect_types.h" +#include "DNA_group_types.h" #include "DNA_lattice_types.h" #include "DNA_key_types.h" #include "DNA_mesh_types.h" @@ -65,6 +66,7 @@ #include "BKE_effect.h" #include "BKE_global.h" #include "BKE_key.h" +#include "BKE_main.h" #include "BKE_mball.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -310,110 +312,90 @@ static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int } } -struct DagForest *build_dag(struct Scene *sce, short mask) +static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask) { - Base *base; - Object *ob; bConstraint *con; DagNode * node; DagNode * node2; DagNode * node3; - DagNode * scenenode; - DagForest *dag; - DagAdjList *itA; Key *key; - - dag = sce->theDag; - sce->dagisvalid=1; - if ( dag) - free_forest( dag ); - else { - dag = dag_init(); - sce->theDag = dag; + int addtoroot= 1; + + node = dag_get_node(dag, ob); + + if ((ob->data) && (mask&DAG_RL_DATA)) { + node2 = dag_get_node(dag,ob->data); + dag_add_relation(dag,node,node2,DAG_RL_DATA); + node2->first_ancestor = ob; + node2->ancestor_count += 1; } - /* add base node for scene. scene is always the first node in DAG */ - scenenode = dag_add_node(dag, sce); - - for(base = sce->base.first; base; base= base->next) { - int addtoroot = 1; - ob= (Object *) base->object; - - node = dag_get_node(dag,ob); - - if ((ob->data) && (mask&DAG_RL_DATA)) { - node2 = dag_get_node(dag,ob->data); - dag_add_relation(dag,node,node2,DAG_RL_DATA); - node2->first_ancestor = ob; - node2->ancestor_count += 1; - } - - if (ob->type == OB_ARMATURE) { - if (ob->pose){ - bPoseChannel *pchan; - bConstraint *con; - Object * target; - char *subtarget; - - for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ - for (con = pchan->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { + if (ob->type == OB_ARMATURE) { + if (ob->pose){ + bPoseChannel *pchan; + bConstraint *con; + Object * target; + char *subtarget; + + for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){ + for (con = pchan->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + + target = get_constraint_target(con, &subtarget); + if (target!=ob) { + // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name); + node3 = dag_get_node(dag, target); + + if(subtarget && subtarget[0]) + dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA); + else + dag_add_relation(dag,node3,node, DAG_RL_OB_DATA); - target = get_constraint_target(con, &subtarget); - if (target!=ob) { - // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name); - node3 = dag_get_node(dag, target); - - if(subtarget && subtarget[0]) - dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA); - else - dag_add_relation(dag,node3,node, DAG_RL_OB_DATA); - - } } } } } } - - /* driver dependencies */ - if(ob->ipo) - dag_add_driver_relation(ob->ipo, dag, node, 0); - - key= ob_get_key(ob); - if(key && key->ipo) - dag_add_driver_relation(key->ipo, dag, node, 1); - - if(ob->action) { - bActionChannel *chan; - for (chan = ob->action->chanbase.first; chan; chan=chan->next){ - if(chan->ipo) - dag_add_driver_relation(chan->ipo, dag, node, 1); - } + } + + /* driver dependencies */ + if(ob->ipo) + dag_add_driver_relation(ob->ipo, dag, node, 0); + + key= ob_get_key(ob); + if(key && key->ipo) + dag_add_driver_relation(key->ipo, dag, node, 1); + + if(ob->action) { + bActionChannel *chan; + for (chan = ob->action->chanbase.first; chan; chan=chan->next){ + if(chan->ipo) + dag_add_driver_relation(chan->ipo, dag, node, 1); } - if(ob->nlastrips.first) { - bActionStrip *strip; - bActionChannel *chan; - for(strip= ob->nlastrips.first; strip; strip= strip->next) { - if(strip->act && strip->act!=ob->action) - for (chan = strip->act->chanbase.first; chan; chan=chan->next) - if(chan->ipo) - dag_add_driver_relation(chan->ipo, dag, node, 1); - } + } + if(ob->nlastrips.first) { + bActionStrip *strip; + bActionChannel *chan; + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->act && strip->act!=ob->action) + for (chan = strip->act->chanbase.first; chan; chan=chan->next) + if(chan->ipo) + dag_add_driver_relation(chan->ipo, dag, node, 1); } - if (ob->modifiers.first) { - ModifierData *md; - - for(md=ob->modifiers.first; md; md=md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); - - if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node); - } - } - if (ob->parent) { - node2 = dag_get_node(dag,ob->parent); + } + if (ob->modifiers.first) { + ModifierData *md; + + for(md=ob->modifiers.first; md; md=md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); - switch(ob->partype) { + if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node); + } + } + if (ob->parent) { + node2 = dag_get_node(dag,ob->parent); + + switch(ob->partype) { case PARSKEL: dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB); break; @@ -430,89 +412,149 @@ struct DagForest *build_dag(struct Scene *sce, short mask) else dag_add_relation(dag,node2,node,DAG_RL_OB_OB); } - else - dag_add_relation(dag,node2,node,DAG_RL_OB_OB); - } - addtoroot = 0; + else + dag_add_relation(dag,node2,node,DAG_RL_OB_OB); } - if (ob->track) { - node2 = dag_get_node(dag,ob->track); - dag_add_relation(dag,node2,node,DAG_RL_OB_OB); - addtoroot = 0; - } - - if (ob->type==OB_MBALL) { - Object *mom= find_basis_mball(ob); - if(mom!=ob) { - node2 = dag_get_node(dag, mom); - dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children! + addtoroot = 0; + } + if (ob->track) { + node2 = dag_get_node(dag,ob->track); + dag_add_relation(dag,node2,node,DAG_RL_OB_OB); + addtoroot = 0; + } + + if (ob->transflag & OB_DUPLI) { + if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) { + GroupObject *go; + for(go= ob->dup_group->gobject.first; go; go= go->next) { + if(go->ob) { + node2 = dag_get_node(dag, go->ob); + /* node2 changes node1, this keeps animations updated in groups?? not logical? */ + dag_add_relation(dag, node2, node, DAG_RL_OB_OB); + } } } - else if (ob->type==OB_CURVE) { - Curve *cu= ob->data; - if(cu->bevobj) { - node2 = dag_get_node(dag, cu->bevobj); - dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } - if(cu->taperobj) { - node2 = dag_get_node(dag, cu->taperobj); - dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } + } + + if (ob->type==OB_MBALL) { + Object *mom= find_basis_mball(ob); + if(mom!=ob) { + node2 = dag_get_node(dag, mom); + dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); // mom depends on children! } - else if(ob->type==OB_FONT) { - Curve *cu= ob->data; - if(cu->textoncurve) { - node2 = dag_get_node(dag, cu->textoncurve); - dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - } + } + else if (ob->type==OB_CURVE) { + Curve *cu= ob->data; + if(cu->bevobj) { + node2 = dag_get_node(dag, cu->bevobj); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); } - else if(ob->type==OB_MESH) { - PartEff *paf= give_parteff(ob); - if(paf) { - Base *base1; - - /* ob location depends on itself */ - if((paf->flag & PAF_STATIC)==0) - dag_add_relation(dag, node, node, DAG_RL_OB_DATA); - - /* force fields, warning for loop inside loop... */ - for(base1 = G.scene->base.first; base1; base1= base1->next) { - if( (base1->lay & base->lay) && base1->object->pd) { - Object *ob1= base1->object; - PartDeflect *pd= ob1->pd; + if(cu->taperobj) { + node2 = dag_get_node(dag, cu->taperobj); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } + } + else if(ob->type==OB_FONT) { + Curve *cu= ob->data; + if(cu->textoncurve) { + node2 = dag_get_node(dag, cu->textoncurve); + dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + } + } + else if(ob->type==OB_MESH) { + PartEff *paf= give_parteff(ob); + if(paf) { + ListBase *listb; + pEffectorCache *ec; + + /* ob location depends on itself */ + if((paf->flag & PAF_STATIC)==0) + dag_add_relation(dag, node, node, DAG_RL_OB_DATA); + + listb= pdInitEffectors(ob, paf->group); /* note, makes copy... */ + if(listb) { + for(ec= listb->first; ec; ec= ec->next) { + Object *ob1= ec->ob; + PartDeflect *pd= ob1->pd; - if(pd->forcefield) { - node2 = dag_get_node(dag, ob1); - if(pd->forcefield==PFIELD_GUIDE) - dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); - else - dag_add_relation(dag, node2, node, DAG_RL_OB_DATA); - } + if(pd->forcefield) { + node2 = dag_get_node(dag, ob1); + if(pd->forcefield==PFIELD_GUIDE) + dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA); + else + dag_add_relation(dag, node2, node, DAG_RL_OB_DATA); } } + + pdEndEffectors(listb); /* restores copy... */ } } - - for (con = ob->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - char *str; - Object *obt= get_constraint_target(con, &str); - - node2 = dag_get_node(dag, obt); - if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) + } + + for (con = ob->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + char *str; + Object *obt= get_constraint_target(con, &str); + + node2 = dag_get_node(dag, obt); + if(con->type==CONSTRAINT_TYPE_FOLLOWPATH) + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB); + else { + if(obt->type==OB_ARMATURE && str[0]) dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB); - else { - if(obt->type==OB_ARMATURE && str[0]) - dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB); - else - dag_add_relation(dag, node2, node, DAG_RL_OB_OB); - } - addtoroot = 0; + else + dag_add_relation(dag, node2, node, DAG_RL_OB_OB); } + addtoroot = 0; } + } + + if (addtoroot == 1 ) + dag_add_relation(dag,scenenode,node,DAG_RL_SCENE); +} + +struct DagForest *build_dag(struct Scene *sce, short mask) +{ + Base *base; + Object *ob; + Group *group; + GroupObject *go; + DagNode *node; + DagNode *scenenode; + DagForest *dag; + DagAdjList *itA; + + dag = sce->theDag; + sce->dagisvalid=1; + if ( dag) + free_forest( dag ); + else { + dag = dag_init(); + sce->theDag = dag; + } + + /* add base node for scene. scene is always the first node in DAG */ + scenenode = dag_add_node(dag, sce); + + /* add current scene objects */ + for(base = sce->base.first; base; base= base->next) { + ob= base->object; - if (addtoroot == 1 ) - dag_add_relation(dag,scenenode,node,DAG_RL_SCENE); + build_dag_object(dag, scenenode, ob, mask); + + /* handled in next loop */ + if(ob->dup_group) + ob->dup_group->id.flag |= LIB_DOIT; + } + + /* add groups used in current scene objects */ + for(group= G.main->group.first; group; group= group->id.next) { + if(group->id.flag & LIB_DOIT) { + for(go= group->gobject.first; go; go= go->next) { + build_dag_object(dag, scenenode, go->ob, mask); + } + group->id.flag &= ~LIB_DOIT; + } } /* Now all relations were built, but we need to solve 1 exceptional case; @@ -1314,10 +1356,12 @@ void DAG_scene_sort(struct Scene *sce) time++; base = sce->base.first; - while (base->object != node->ob) + while (base && base->object != node->ob) base = base->next; - BLI_remlink(&sce->base,base); - BLI_addhead(&tempbase,base); + if(base) { + BLI_remlink(&sce->base,base); + BLI_addhead(&tempbase,base); + } } } } @@ -1341,6 +1385,8 @@ void DAG_scene_sort(struct Scene *sce) printf(" %s\n", base->object->id.name); } } + /* temporal...? */ + G.scene->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */ } /* node was checked to have lasttime != curtime and is if type ID_OB */ @@ -1502,96 +1548,143 @@ static int exists_channel(Object *ob, char *name) return 0; } +static void dag_object_time_update_flags(Object *ob) +{ + + if(ob->ipo) ob->recalc |= OB_RECALC_OB; + else if(ob->constraints.first) { + bConstraint *con; + for (con = ob->constraints.first; con; con=con->next){ + if (constraint_has_target(con)) { + ob->recalc |= OB_RECALC_OB; + break; + } + } + } + else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB; + else if(ob->parent) { + /* motion path or bone child */ + if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB; + } + + if(ob->action || ob->nlastrips.first) { + /* since actions now are mixed, we set the recalcs on the safe side */ + ob->recalc |= OB_RECALC_OB; + if(ob->type==OB_ARMATURE) + ob->recalc |= OB_RECALC_DATA; + else if(exists_channel(ob, "Shape")) + ob->recalc |= OB_RECALC_DATA; + else if(ob->dup_group) { + bActionStrip *strip; + /* this case is for groups with nla, whilst nla target has no action or nla */ + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object) + strip->object->recalc |= OB_RECALC; + } + } + } + else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA; + else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; + else { + Mesh *me; + Curve *cu; + Lattice *lt; + + switch(ob->type) { + case OB_MESH: + me= ob->data; + if(me->key) { + if(!(ob->shapeflag & OB_SHAPE_LOCK)) { + ob->recalc |= OB_RECALC_DATA; + ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; + } + } + else if(ob->effect.first) { + Effect *eff= ob->effect.first; + PartEff *paf= give_parteff(ob); + + if(eff->type==EFF_WAVE) + ob->recalc |= OB_RECALC_DATA; + if(paf && paf->keys==NULL) + ob->recalc |= OB_RECALC_DATA; + } + if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) { + // fluidsimSettings might not be initialized during load... + if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) { + ob->recalc |= OB_RECALC_DATA; // NT + } + } + break; + case OB_CURVE: + case OB_SURF: + cu= ob->data; + if(cu->key) { + if(!(ob->shapeflag & OB_SHAPE_LOCK)) { + ob->recalc |= OB_RECALC_DATA; + ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; + } + } + break; + case OB_LATTICE: + lt= ob->data; + if(lt->key) { + if(!(ob->shapeflag & OB_SHAPE_LOCK)) { + ob->recalc |= OB_RECALC_DATA; + ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; + } + } + break; + case OB_MBALL: + if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA; + break; + } + } +} + /* flag all objects that need recalc, for changes in time for example */ void DAG_scene_update_flags(Scene *sce, unsigned int lay) { Base *base; Object *ob; + Group *group; + GroupObject *go; /* set ob flags where animated systems are */ for(base= sce->base.first; base; base= base->next) { + ob= base->object; /* now if DagNode were part of base, the node->lay could be checked... */ /* we do all now, since the scene_flush checks layers and clears recalc flags even */ - ob= base->object; + dag_object_time_update_flags(ob); - if(ob->ipo) ob->recalc |= OB_RECALC_OB; - else if(ob->constraints.first) { - bConstraint *con; - for (con = ob->constraints.first; con; con=con->next){ - if (constraint_has_target(con)) { - ob->recalc |= OB_RECALC_OB; - break; - } - } - } - else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB; - else if(ob->parent) { - if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB; - } + /* handled in next loop */ + if(ob->dup_group) + ob->dup_group->id.flag |= LIB_DOIT; - if(ob->action || ob->nlastrips.first) { - /* since actions now are mixed, we set the recalcs on the safe side */ - ob->recalc |= OB_RECALC_OB; - if(ob->type==OB_ARMATURE) - ob->recalc |= OB_RECALC_DATA; - else if(exists_channel(ob, "Shape")) - ob->recalc |= OB_RECALC_DATA; - - } - else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA; - else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA; - else { - Mesh *me; - Curve *cu; - Lattice *lt; - - switch(ob->type) { - case OB_MESH: - me= ob->data; - if(me->key) { - if(!(ob->shapeflag & OB_SHAPE_LOCK)) { - ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; - } - } - else if(ob->effect.first) { - Effect *eff= ob->effect.first; - if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA; - } - if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) { - // fluidsimSettings might not be initialized during load... - if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) { - ob->recalc |= OB_RECALC_DATA; // NT - } - } - break; - case OB_CURVE: - case OB_SURF: - cu= ob->data; - if(cu->key) { - if(!(ob->shapeflag & OB_SHAPE_LOCK)) { - ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; - } - } - break; - case OB_LATTICE: - lt= ob->data; - if(lt->key) { - if(!(ob->shapeflag & OB_SHAPE_LOCK)) { - ob->recalc |= OB_RECALC_DATA; - ob->shapeflag &= ~OB_SHAPE_TEMPLOCK; - } - } - break; - case OB_MBALL: - if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA; - break; + } + + /* we do groups each once */ + for(group= G.main->group.first; group; group= group->id.next) { + if(group->id.flag & LIB_DOIT) { + for(go= group->gobject.first; go; go= go->next) { + dag_object_time_update_flags(go->ob); } } } + DAG_scene_flush_update(sce, lay); + + /* and store the info in groubobject */ + for(group= G.main->group.first; group; group= group->id.next) { + if(group->id.flag & LIB_DOIT) { + for(go= group->gobject.first; go; go= go->next) { + go->recalc= go->ob->recalc; +// printf("ob %s recalc %d\n", go->ob->id.name, go->recalc); + } + group->id.flag &= ~LIB_DOIT; + } + } + } /* for depgraph updating, all layers visible in a screen */ diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 36d6c82b266..2e7f821abd7 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1,4 +1,3 @@ - /* displist.c * * @@ -33,10 +32,6 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include #include #include @@ -93,28 +88,10 @@ #include "BKE_modifier.h" #include "nla.h" /* For __NLA: Please do not remove yet */ -#include "render.h" -/***/ - -typedef struct _FastLamp FastLamp; -struct _FastLamp { - FastLamp *next; - - short type, mode, lay, rt; - float co[3]; - float vec[3]; - float dist, distkw, att1, att2, spotsi, spotbl, r, g, b; -}; - -/***/ - static void boundbox_displist(Object *ob); -static FastLamp *fastlamplist= NULL; -static float fviewmat[4][4]; - void displistmesh_free(DispListMesh *dlm) { // also check on mvert and mface, can be NULL after decimator (ton) @@ -288,357 +265,18 @@ void copy_displist(ListBase *lbn, ListBase *lb) } } -static void initfastshade(void) +void initfastshade(void) { - Base *base; - Scene *setscene; - Object *ob; - Lamp *la; - FastLamp *fl; - float mat[4][4]; - - init_render_world(); - - if(fastlamplist) return; - if(G.scene->camera==0) G.scene->camera= scene_find_camera(G.scene); - if(G.scene->camera==0) return; - - /* copied from 'roteerscene' (does that function still exist? (ton) */ - where_is_object(G.scene->camera); - Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); - Mat4Ortho(R.viewinv); - Mat4Invert(fviewmat, R.viewinv); - - /* initrendertexture(); */ - setscene = G.scene; - base= G.scene->base.first; - while(base) { - ob= base->object; - if( ob->type==OB_LAMP && (base->lay & G.scene->lay)) { - - Mat4MulMat4(mat, ob->obmat, fviewmat); - - la= ob->data; - fl= MEM_mallocN(sizeof(FastLamp), "initfastshade2"); - - fl->next= fastlamplist; - fastlamplist= fl; - - fl->type= la->type; - fl->mode= la->mode; - fl->lay= base->lay; - - fl->vec[0]= mat[2][0]; - fl->vec[1]= mat[2][1]; - fl->vec[2]= mat[2][2]; - Normalise(fl->vec); - - fl->co[0]= mat[3][0]; - fl->co[1]= mat[3][1]; - fl->co[2]= mat[3][2]; - - fl->dist= la->dist; - fl->distkw= fl->dist*fl->dist; - fl->att1= la->att1; - fl->att2= la->att2; - - fl->spotsi= (float)cos( M_PI*la->spotsize/360.0 ); - fl->spotbl= (1.0f-fl->spotsi)*la->spotblend; - - fl->r= la->energy*la->r; - fl->g= la->energy*la->g; - fl->b= la->energy*la->b; - } - - if(base->next==0 && setscene && setscene->set) {/*if(base->next==0 && G.scene->set && base==G.scene->base.last) {*/ - setscene = setscene->set; - base= setscene->base.first; /* base= G.scene->set->base.first;*/ - } else { - base= base->next; - } - } } void freefastshade() { - while (fastlamplist) { - FastLamp *fl= fastlamplist; - fastlamplist= fl->next; - - MEM_freeN(fl); - } } static void fastshade(float *co, float *nor, float *orco, Material *ma, char *col1, char *col2, char *vertcol) { - ShadeInput shi; - FastLamp *fl; - float i, t, inp, is, soft, lv[3], lampdist, ld; - float diff1[3], diff2[3]; - float isr1=0, isg1=0, isb1=0, isr=0, isg=0, isb=0; - int a, back; - - if(ma==0) return; - - shi.mat= ma; - shi.vlr= NULL; // have to do this! - - // copy all relevant material vars, note, keep this synced with render_types.h - memcpy(&shi.r, &shi.mat->r, 23*sizeof(float)); - // set special cases: - shi.har= shi.mat->har; - - shi.osatex= 0; // also prevents reading vlr - - VECCOPY(shi.vn, nor); - - if(ma->mode & MA_VERTEXCOLP) { - if(vertcol) { - shi.r= vertcol[3]/255.0; - shi.g= vertcol[2]/255.0; - shi.b= vertcol[1]/255.0; - } - } - - if(ma->texco) { - VECCOPY(shi.lo, orco); - - if(ma->texco & TEXCO_GLOB) { - VECCOPY(shi.gl, shi.lo); - } - if(ma->texco & TEXCO_WINDOW) { - VECCOPY(shi.winco, shi.lo); - } - if(ma->texco & TEXCO_STICKY) { - VECCOPY(shi.sticky, shi.lo); - } - if(ma->texco & TEXCO_UV) { - VECCOPY(shi.uv, shi.lo); - } - if(ma->texco & TEXCO_OBJECT) { - VECCOPY(shi.co, shi.lo); - } - if(ma->texco & TEXCO_NORM) { - VECCOPY(shi.orn, shi.vn); - } - if(ma->texco & TEXCO_REFL) { - - inp= 2.0*(shi.vn[2]); - shi.ref[0]= (inp*shi.vn[0]); - shi.ref[1]= (inp*shi.vn[1]); - shi.ref[2]= (-1.0+inp*shi.vn[2]); - } - - do_material_tex(&shi); - } - - if(ma->mode & MA_SHLESS) { - if(vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - float fac; - fac= vertcol[3]*shi.r; - col1[3]= fac>=1.0?255:(char)fac; - fac= vertcol[2]*shi.g; - col1[2]= fac>=1.0?255:(char)fac; - fac= vertcol[1]*shi.b; - col1[1]= fac>=1.0?255:(char)fac; - } - else { - int fac; - fac= (int) (255.0*shi.r); - col1[3]= fac>255?255:(char)fac; - fac= (int) (255.0*shi.g); - col1[2]= fac>255?255:(char)fac; - fac= (int) (255.0*shi.b); - col1[1]= fac>255?255:(char)fac; - } - if(col2) { - col2[3]= col1[3]; - col2[2]= col1[2]; - col2[1]= col1[1]; - } - return; - } - - if( vertcol && (ma->mode & (MA_VERTEXCOL+MA_VERTEXCOLP))== MA_VERTEXCOL ) { - diff1[0]= diff2[0]= shi.r*(shi.emit+vertcol[3]/255.0); - diff1[1]= diff2[1]= shi.g*(shi.emit+vertcol[2]/255.0); - diff1[2]= diff2[2]= shi.b*(shi.emit+vertcol[1]/255.0); - } - else { - diff1[0]= diff2[0]= shi.r*shi.emit; - diff1[1]= diff2[1]= shi.g*shi.emit; - diff1[2]= diff2[2]= shi.b*shi.emit; - } - - shi.view[0]= 0.0; - shi.view[1]= 0.0; - shi.view[2]= 1.0; - - Normalise(shi.view); - - for (fl= fastlamplist; fl; fl= fl->next) { - /* if(fl->mode & LA_LAYER) if((fl->lay & ma->lay)==0) continue; */ - - if(fl->type==LA_SUN || fl->type==LA_HEMI) { - VECCOPY(lv, fl->vec); - lampdist= 1.0; - } - else { - lv[0]= fl->co[0] - co[0]; - lv[1]= fl->co[1] - co[1]; - lv[2]= fl->co[2] - co[2]; - ld= sqrt(lv[0]*lv[0]+lv[1]*lv[1]+lv[2]*lv[2]); - lv[0]/=ld; - lv[1]/=ld; - lv[2]/=ld; - - if(fl->mode & LA_QUAD) { - t= 1.0; - if(fl->att1>0.0) - t= fl->dist/(fl->dist+fl->att1*ld); - if(fl->att2>0.0) - t*= fl->distkw/(fl->distkw+fl->att2*ld*ld); - - lampdist= t; - } - else { - lampdist= (fl->dist/(fl->dist+ld)); - } - - if(fl->mode & LA_SPHERE) { - t= fl->dist - ld; - if(t<0.0) continue; - - t/= fl->dist; - lampdist*= (t); - } - } - - if(fl->type==LA_SPOT) { - inp= lv[0]*fl->vec[0]+lv[1]*fl->vec[1]+lv[2]*fl->vec[2]; - if(inpspotsi) continue; - else { - t= inp-fl->spotsi; - i= 1.0; - soft= 1.0; - if(tspotbl && fl->spotbl!=0.0) { - /* soft area */ - i= t/fl->spotbl; - t= i*i; - soft= (3.0*t-2.0*t*i); - inp*= soft; - } - - lampdist*=inp; - } - } - - if(fl->mode & LA_NO_DIFF) is= 0.0; - else { - is= nor[0]*lv[0]+ nor[1]*lv[1]+ nor[2]*lv[2]; - - if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(nor, lv, shi.view, ma->roughness); - else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]); - else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, nor, shi.view, ma->darkness); - } - - back= 0; - if(is<0.0) { - back= 1; - is= -is; - } - inp= is*lampdist*shi.refl; - - if(back==0) { - add_to_diffuse(diff1, &shi, is, inp*fl->r, inp*fl->g, inp*fl->b); - //diff1[0]+= inp*fl->r; - //diff1[1]+= inp*fl->g; - //diff1[2]+= inp*fl->b; - } else if(col2) { - add_to_diffuse(diff2, &shi, is, inp*fl->r, inp*fl->g, inp*fl->b); - //diff2[0]+= inp*fl->r; - //diff2[1]+= inp*fl->g; - //diff2[2]+= inp*fl->b; - } - if(shi.spec!=0.0 && (fl->mode & LA_NO_SPEC)==0) { - float specfac; - - if(ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(nor, lv, shi.view, shi.har, 0); - else if(ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(nor, lv, shi.view, shi.har, 0); - else if(ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(nor, lv, shi.view, ma->refrac, (float)shi.har, 0); - else if(ma->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec(nor, lv, shi.view, ma->rms, 0); - else - specfac= Toon_Spec(nor, lv, shi.view, ma->param[2], ma->param[3], 0); - - if(specfac>0) { - t= specfac*shi.spec*lampdist; - if(back==0) { - if(ma->mode & MA_RAMP_SPEC) { - float spec[3]; - do_specular_ramp(&shi, specfac, t, spec); - isr+= t*(fl->r * spec[0]); - isg+= t*(fl->g * spec[1]); - isb+= t*(fl->b * spec[2]); - } - else { - isr+= t*(fl->r * shi.specr); - isg+= t*(fl->g * shi.specg); - isb+= t*(fl->b * shi.specb); - } - } - else if(col2) { - if(ma->mode & MA_RAMP_SPEC) { - float spec[3]; - do_specular_ramp(&shi, specfac, t, spec); - isr1+= t*(fl->r * spec[0]); - isg1+= t*(fl->g * spec[1]); - isb1+= t*(fl->b * spec[2]); - } - else { - isr1+= t*(fl->r * shi.specr); - isg1+= t*(fl->g * shi.specg); - isb1+= t*(fl->b * shi.specb); - } - } - } - } - - } - - if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff1, &shi); - if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, &shi); - - a= 256*(diff1[0] + shi.ambr +isr); - if(a>255) col1[3]= 255; - else col1[3]= a; - a= 256*(diff1[1] + shi.ambg +isg); - if(a>255) col1[2]= 255; - else col1[2]= a; - a= 256*(diff1[2] + shi.ambb +isb); - if(a>255) col1[1]= 255; - else col1[1]= a; - - if(col2) { - if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(diff2, &shi); - if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(&isr1, &isg1, &isb1, &shi); - - a= 256*(diff2[0] + shi.ambr +isr1); - if(a>255) col2[3]= 255; - else col2[3]= a; - a= 256*(diff2[1] + shi.ambg +isg1); - if(a>255) col2[2]= 255; - else col2[2]= a; - a= 256*(diff2[2] + shi.ambb +isb1); - if(a>255) col2[1]= 255; - else col2[1]= a; - } - } void addnormalsDispList(Object *ob, ListBase *lb) @@ -709,36 +347,6 @@ void addnormalsDispList(Object *ob, ListBase *lb) static void init_fastshade_for_ob(Object *ob, int *need_orco_r, float mat[4][4], float imat[3][3]) { - float tmat[4][4]; - int a; - - initfastshade(); - - Mat4MulMat4(mat, ob->obmat, fviewmat); - - Mat4Invert(tmat, mat); - Mat3CpyMat4(imat, tmat); - if(ob->transflag & OB_NEG_SCALE) Mat3MulFloat((float *)imat, -1.0); - - if (need_orco_r) *need_orco_r= 0; - for(a=0; atotcol; a++) { - Material *ma= give_current_material(ob, a+1); - if(ma) { - init_render_material(ma); - if(ma->texco & TEXCO_ORCO) { - if (need_orco_r) *need_orco_r= 1; - } - } - } -} -static void end_fastshade_for_ob(Object *ob) -{ - int a; - - for(a=0; atotcol; a++) { - Material *ma= give_current_material(ob, a+1); - if(ma) end_render_material(ma); - } } void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r, unsigned int **col2_r) @@ -841,7 +449,7 @@ void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r Mat4MulVecfl(mat, vec); fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol); } - } + } MEM_freeN(vnors); displistmesh_free(dlm); @@ -851,11 +459,12 @@ void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r if (dmNeedsFree) dm->release(dm); - end_fastshade_for_ob(ob); } -void shadeDispList(Object *ob) +/* has base pointer, to check for layer */ +void shadeDispList(Base *base) { + Object *ob= base->object; DispList *dl, *dlob; Material *ma = NULL; Curve *cu; @@ -864,8 +473,6 @@ void shadeDispList(Object *ob) unsigned int *col1; int a; - if(ob->flag & OB_FROMDUPLI) return; - dl = find_displist(&ob->disp, DL_VERTCOL); if (dl) { BLI_remlink(&ob->disp, dl); @@ -991,8 +598,6 @@ void shadeDispList(Object *ob) dl= dl->next; } } - - end_fastshade_for_ob(ob); } void reshadeall_displist(void) @@ -1002,16 +607,13 @@ void reshadeall_displist(void) freefastshade(); - base= G.scene->base.first; - while(base) { + for(base= G.scene->base.first; base; base= base->next) { + ob= base->object; + freedisplist(&ob->disp); if(base->lay & G.scene->lay) { - ob= base->object; - /* Metaballs have standard displist at the Object */ - if(ob->type==OB_MBALL) shadeDispList(ob); - else freedisplist(&ob->disp); + if(ob->type==OB_MBALL) shadeDispList(base); } - base= base->next; } } @@ -1244,7 +846,7 @@ void filldisplist(ListBase *dispbase, ListBase *to) f1+= 3; /* index number */ - eve->vn= (EditVert *)totvert; + eve->tmp.l = totvert; totvert++; eve= eve->next; @@ -1254,9 +856,9 @@ void filldisplist(ListBase *dispbase, ListBase *to) efa= fillfacebase.first; index= dlnew->index; while(efa) { - index[0]= (long)efa->v1->vn; - index[1]= (long)efa->v2->vn; - index[2]= (long)efa->v3->vn; + index[0]= (long)efa->v1->tmp.l; + index[1]= (long)efa->v2->tmp.l; + index[2]= (long)efa->v3->tmp.l; index+= 3; efa= efa->next; @@ -1404,7 +1006,7 @@ static float calc_taper(Object *taperobj, int cur, int tot) void makeDispListMBall(Object *ob) { - if(!ob || (ob->flag&OB_FROMDUPLI) || ob->type!=OB_MBALL) return; + if(!ob || ob->type!=OB_MBALL) return; freedisplist(&(ob->disp)); @@ -1591,9 +1193,9 @@ void makeDispListCurveTypes(Object *ob, int forOrco) { Curve *cu = ob->data; ListBase *dispbase; - - if((ob->flag&OB_FROMDUPLI) || !ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; - if(ob->flag & OB_FROMDUPLI) return; + + /* we do allow duplis... this is only displist on curve level */ + if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; freedisplist(&(ob->disp)); dispbase= &(cu->disp); @@ -1707,306 +1309,9 @@ void makeDispListCurveTypes(Object *ob, int forOrco) boundbox_displist(ob); } -/*******************************/ -/***** OUTLINE *****/ -/*******************************/ - -typedef struct Sample{ - short x, y; -} Sample; - -typedef struct Segment{ - /* coordinates */ - struct Segment * next, * prev; - float co[2]; -} Segment; - - - -static int dflt_in_out(struct ImBuf * ibuf, int x, int y) -{ - unsigned char * rect; - - if (ibuf == 0) return (0); - if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y || ibuf->rect == 0) return (-1); - - rect = (unsigned char *) (ibuf->rect + (y * ibuf->x) + x); - if (rect[0] > 0x81) return (1); - return(0); -} - - -static Sample * outline(struct ImBuf * ibuf, - int (*in_or_out)(struct ImBuf *, int, int)) -{ - static int dirs[8][2] = { - {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, - {1, 0}, {1, -1}, {0, -1}, {-1, -1} - }; - - int dir, x, y, in, i; - int count, sampcount; - int startx = 0, starty = 0; - Sample * samp, * oldsamp; - - /* input: - * 1 - image - * 2 - pointer to function that defines which pixel 'in' or 'out' is - */ - - if (ibuf == 0) return (0); - if (ibuf->rect == 0) return (0); - - if (in_or_out == 0) in_or_out = dflt_in_out; - in = in_or_out(ibuf, 0, 0); - - /* search for first transition, and continue from there */ - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - if (in_or_out(ibuf, x, y) != in) { - /* found first 'other' point !! */ - - if (x != startx) dir = 0; - else dir = 6; - - startx = x; starty = y; - count = 1; - sampcount = 2000; - samp = MEM_mallocN(sampcount * sizeof(Sample), "wire_samples"); - - do{ - samp[count].x = x; samp[count].y = y; - count++; - - if (count >= sampcount) { - oldsamp = samp; - samp = MEM_mallocN(2 * sampcount * sizeof(Sample), "wire_samples"); - memcpy(samp, oldsamp, sampcount * sizeof(Sample)); - sampcount *= 2; - MEM_freeN(oldsamp); - } - - i = 0; - while(in_or_out(ibuf, x + dirs[dir][0], y + dirs[dir][1]) == in) { - dir = (dir + 1) & 0x7; - if (i++ == 9) break; - } - - if (i >= 8) { - /* this has to be a loose point */ - break; - } - - x += dirs[dir][0]; - y += dirs[dir][1]; - dir = (dir - 3) & 0x7; - } while(x != startx || y != starty); - - if (i >= 8) { - /* patch for loose points */ - MEM_freeN(samp); - } else { - count = count - 1; - samp[0].x = count >> 16; - samp[0].y = count; - return(samp); - } - } - } - } - /* printf("no transition \n"); */ - return(0); -} - - - -/*******************************/ -/***** WIREFRAME *****/ -/*******************************/ - - -static float DistToLine2D(short *v1, short *v2, short *v3) /* using Hesse formula :NO LINE PIECE! */ -{ - float a[2],deler; - - a[0] = v2[1]-v3[1]; - a[1] = v3[0]-v2[0]; - deler = sqrt(a[0]*a[0]+a[1]*a[1]); - if(deler == 0.0) return 0; - - return fabs((v1[0]-v2[0])*a[0]+(v1[1]-v2[1])*a[1])/deler; - -} - -static float ComputeMaxShpError(Sample *samp, int first, int last, int *splitPoint) - /* samp: Array of digitized points */ - /* first, last: Indices defining region */ - /* splitpoint: Point of maximum error */ -{ - int i; - float maxDist; /* Maximum error */ - float dist; /* Current error */ - - *splitPoint = (last - first + 1) / 2; - maxDist = 0.0; - - for (i = first + 1; i < last; i++) { - dist = DistToLine2D((short *)(samp+i), (short *)(samp+first), (short *)(samp+last)); - - if (dist >= maxDist) { - maxDist = dist; - *splitPoint = i; - } - } - - return (maxDist); -} - - -static void FitPoly(Sample *samp, int first, int last, float shperr, ListBase *seglist) - /* Samp: Array of digitized points */ - /* first,last: Indices of first and last pts in region */ - /* spherr: User-defined error squared */ -{ - Segment * seg; /* Control points segment*/ - float maxError; /* Maximum fitting error */ - int splitPoint; /* Point to split point set at */ - int nPts; /* Number of points in subset */ - - nPts = last - first + 1; - - /* Use heuristic if region only has two points in it */ - - seg = MEM_mallocN(sizeof(Segment), "wure_segment"); - - seg->co[0] = samp[first].x; - seg->co[1] = samp[first].y; - - if (nPts == 2) { - BLI_addtail(seglist, seg); - return; - } - - maxError = ComputeMaxShpError(samp, first, last, &splitPoint); - if (maxError < shperr) { - BLI_addtail(seglist, seg); - return; - } - - /* Fitting failed -- split at max error point and fit recursively */ - - FitPoly(samp, first, splitPoint, shperr, seglist); - FitPoly(samp, splitPoint, last, shperr, seglist); - - MEM_freeN(seg); -} - - -static void ibuf2wire(ListBase * wireframe, struct ImBuf * ibuf) -{ - int count; - Sample * samp; - - /* first make a list of samples */ - - samp = outline(ibuf, 0); - if (samp == 0) return; - - count = (samp[0].x << 16) + samp[0].y; - if (count) FitPoly(samp, 1, count, 1.0, wireframe); /* was 3.0. Frank */ - - MEM_freeN(samp); -} - - - void imagestodisplist(void) { - Base *base; - Object *ob; - Material *ma; - Tex *tex; - Mesh *me; - ListBase _wireframe, *wireframe; - DispList *dl; - Segment *seg; - float *data, xfac, yfac, xsi, ysi, vec[3], dum; - int tot; - - _wireframe.first= 0; - _wireframe.last= 0; - wireframe = &_wireframe; - - init_render_textures(); - - base= G.scene->base.first; - while(base) { - if(( (base->flag & SELECT) && (base->lay & G.scene->lay) ) ) { - if( base->object->type==OB_MESH) { - ob= base->object; - me= ob->data; - - ma= give_current_material(ob, 1); - - if(ma && ma->mtex[0] && ma->mtex[0]->tex) { - tex= ma->mtex[0]->tex; - - /* this takes care of correct loading of new imbufs */ - externtex(ma->mtex[0], vec, &dum, &dum, &dum, &dum, &dum); - - if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) { - - ob->dtx |= OB_DRAWIMAGE; - - ibuf2wire(wireframe, tex->ima->ibuf); - - tot= 0; - seg = wireframe->first; - while (seg) { - tot++; - seg = seg->next; - } - - if(tot) { - float size[3]; - - freedisplist(&(ob->disp)); - - dl= MEM_callocN(sizeof(DispList), "makeDispListimage"); - dl->verts= MEM_callocN(3*sizeof(float)*tot, "dlverts"); - - BLI_addtail(&(ob->disp), dl); - dl->type= DL_POLY; - dl->parts= 1; - dl->nr= tot; - - xsi= 0.5*(tex->ima->ibuf->x); - ysi= 0.5*(tex->ima->ibuf->y); - - mesh_get_texspace(me, NULL, NULL, size); - xfac= size[0]/xsi; - yfac= size[1]/ysi; - - data= dl->verts; - seg = wireframe->first; - while (seg) { - data[0]= xfac*(seg->co[0]-xsi); - data[1]= yfac*(seg->co[1]-ysi); - data+= 3; - seg = seg->next; - } - BLI_freelistN(wireframe); - } - } - } - } - } - base= base->next; - } - - end_render_textures(); - - allqueue(REDRAWVIEW3D, 0); + /* removed */ } static void boundbox_displist(Object *ob) diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index acff6d80024..663fe02aaf0 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -36,22 +36,25 @@ #include #include "MEM_guardedalloc.h" -#include "DNA_listBase.h" + +#include "DNA_curve_types.h" #include "DNA_effect_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "DNA_group_types.h" +#include "DNA_ipo_types.h" +#include "DNA_key_types.h" +#include "DNA_lattice_types.h" +#include "DNA_listBase.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_material_types.h" -#include "DNA_curve_types.h" -#include "DNA_key_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" #include "DNA_texture_types.h" #include "DNA_scene_types.h" -#include "DNA_lattice_types.h" -#include "DNA_ipo_types.h" -#include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_jitter.h" #include "BLI_rand.h" #include "BKE_action.h" @@ -75,9 +78,10 @@ #include "BKE_screen.h" #include "BKE_utildefines.h" -#include "render.h" // externtex, bad level call (ton) #include "PIL_time.h" +#include "RE_render_ext.h" + /* temporal struct, used for reading return of mesh_get_mapped_verts_nors() */ typedef struct VeNoCo { float co[3], no[3]; @@ -314,54 +318,57 @@ static void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no) /* -------------------------- Effectors ------------------ */ -typedef struct pEffectorCache { - struct pEffectorCache *next, *prev; - struct Object *ob; - - /* precalculated variables */ - float oldloc[3], oldspeed[3]; - float scale, time_scale; - float guide_dist; - - Object obcopy; /* for restoring transformation data */ -} pEffectorCache; - - -/* returns ListBase handle with objects taking part in the effecting */ -ListBase *pdInitEffectors(Object *obsrc) +static void add_to_effectorcache(ListBase *lb, Object *ob, Object *obsrc) { - static ListBase listb={NULL, NULL}; pEffectorCache *ec; - unsigned int layer= obsrc->lay; - Base *base; - - for(base = G.scene->base.first; base; base= base->next) { - if( (base->lay & layer) && base->object->pd && base->object!=obsrc) { - Object *ob= base->object; - PartDeflect *pd= ob->pd; + 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(ob, 0); - if(cu->path && cu->path->data) { - ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); - ec->ob= ob; - BLI_addtail(&listb, ec); - } - } + 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(ob, 0); + if(cu->path && cu->path->data) { + ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); + ec->ob= ob; + BLI_addtail(lb, ec); } } - else if(pd->forcefield) { - ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); - ec->ob= ob; - BLI_addtail(&listb, ec); - } } } + else if(pd->forcefield) { + ec= MEM_callocN(sizeof(pEffectorCache), "effector cache"); + ec->ob= ob; + BLI_addtail(lb, ec); + } +} +/* returns ListBase handle with objects taking part in the effecting */ +ListBase *pdInitEffectors(Object *obsrc, Group *group) +{ + static ListBase listb={NULL, NULL}; + pEffectorCache *ec; + Base *base; + unsigned int layer= obsrc->lay; + + if(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, go->ob, obsrc); + } + } + } + else { + for(base = G.scene->base.first; base; base= base->next) { + if( (base->lay & layer) && base->object->pd && base->object!=obsrc) { + add_to_effectorcache(&listb, base->object, obsrc); + } + } + } + /* make a full copy */ for(ec= listb.first; ec; ec= ec->next) { ec->obcopy= *(ec->ob); @@ -1212,9 +1219,9 @@ static void init_mv_jit(float *jit, int num, int seed2) jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit"); for (i=0 ; i<4 ; i++) { - RE_jitterate1(jit, jit2, num, rad1); - RE_jitterate1(jit, jit2, num, rad1); - RE_jitterate2(jit, jit2, num, rad2); + BLI_jitterate1(jit, jit2, num, rad1); + BLI_jitterate1(jit, jit2, num, rad1); + BLI_jitterate2(jit, jit2, num, rad2); } MEM_freeN(jit2); rng_free(rng); @@ -1604,8 +1611,7 @@ void build_particle_system(Object *ob) if(me->totvert==0) return; if(ob==G.obedit) return; - - totpart= (R.flag & R_RENDERING)?paf->totpart:(paf->disp*paf->totpart)/100; + totpart= (G.rendering)?paf->totpart:(paf->disp*paf->totpart)/100; if(totpart==0) return; /* No returns after this line! */ @@ -1647,6 +1653,7 @@ void build_particle_system(Object *ob) /* matrix invert for static too */ Mat4Invert(ob->imat, ob->obmat); + Mat4CpyMat4(paf->imat, ob->imat); /* used for duplicators */ /* new random generator */ rng = rng_new(paf->seed); @@ -1663,7 +1670,7 @@ void build_particle_system(Object *ob) } /* get the effectors */ - effectorbase= pdInitEffectors(ob); + effectorbase= pdInitEffectors(ob, paf->group); /* init geometry, return is 6 x float * me->totvert in size */ vertexcosnos= (VeNoCo *)mesh_get_mapped_verts_nors(ob); diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index dd67f8f8179..f8e9587c415 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -2611,7 +2611,7 @@ static void write_videoscape_mesh(Object *ob, char *str) VECCOPY(co, eve->co); Mat4MulVecfl(ob->obmat, co); fprintf(fp, "%f %f %f\n", co[0], co[1], co[2] ); - eve->vn= (struct EditVert *)tot; + eve->tmp.l = tot; tot++; eve= eve->next; } @@ -2619,10 +2619,19 @@ static void write_videoscape_mesh(Object *ob, char *str) while(evl) { if(evl->v4==0) { - fprintf(fp, "3 %p %p %p 0x%x\n", evl->v1->vn, evl->v2->vn, evl->v3->vn, kleur[evl->mat_nr]); + fprintf(fp, "3 %ld %ld %ld 0x%x\n", + evl->v1->tmp.l, + evl->v2->tmp.l, + evl->v3->tmp.l, + kleur[evl->mat_nr]); } else { - fprintf(fp, "4 %p %p %p %p 0x%x\n", evl->v1->vn, evl->v2->vn, evl->v3->vn, evl->v4->vn, kleur[evl->mat_nr]); + fprintf(fp, "4 %ld %ld %ld %ld 0x%x\n", + evl->v1->tmp.l, + evl->v2->tmp.l, + evl->v3->tmp.l, + evl->v4->tmp.l, + kleur[evl->mat_nr]); } evl= evl->next; } diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 2ab13fe328a..b5ed7fb3688 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -73,13 +73,6 @@ struct SelBox *selboxes= NULL; -struct chartrans { - float xof, yof; - float rot; - short linenr,charnr; - char dobreak; -}; - /* UTF-8 <-> wchar transformations */ void chtoutf8(unsigned long c, char *o) @@ -1190,86 +1183,4 @@ struct chartrans *text_to_curve(Object *ob, int mode) return 0; } -/* ***************** DUPLI ***************** */ -static Object *find_family_object(Object **obar, char *family, char ch) -{ - Object *ob; - int flen; - - if( obar[ch] ) return obar[ch]; - - flen= strlen(family); - - ob= G.main->object.first; - while(ob) { - if( ob->id.name[flen+2]==ch ) { - if( strncmp(ob->id.name+2, family, flen)==0 ) break; - } - ob= ob->id.next; - } - - obar[ch]= ob; - - return ob; -} - - -void font_duplilist(Object *par) -{ - extern ListBase duplilist; - Object *ob, *newob, *obar[256]; - Curve *cu; - struct chartrans *ct, *chartransdata; - float vec[3], pmat[4][4], fsize, xof, yof; - int slen, a; - - Mat4CpyMat4(pmat, par->obmat); - - /* in par the family name is stored, use this to find the other objects */ - - chartransdata= text_to_curve(par, FO_DUPLI); - if(chartransdata==0) return; - - memset(obar, 0, 256*4); - - cu= par->data; - slen= strlen(cu->str); - fsize= cu->fsize; - xof= cu->xof; - yof= cu->yof; - - ct= chartransdata; - - for(a=0; afamily, cu->str[a]); - if(ob) { - /* not clear if this free line here is still needed */ - freedisplist(&ob->disp); - - vec[0]= fsize*(ct->xof - xof); - vec[1]= fsize*(ct->yof - yof); - vec[2]= 0.0; - - Mat4MulVecfl(pmat, vec); - - newob= MEM_mallocN(sizeof(Object), "newobj dupli"); - memcpy(newob, ob, sizeof(Object)); - newob->flag |= OB_FROMDUPLI; - newob->id.newid= (ID *)par; /* keep duplicator */ - newob->totcol= par->totcol; /* for give_current_material */ - - Mat4CpyMat4(newob->obmat, par->obmat); - VECCOPY(newob->obmat[3], vec); - - newob->parent= 0; - newob->track= 0; - - BLI_addtail(&duplilist, newob); - } - - } - - MEM_freeN(chartransdata); -} diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 65c4ed42e03..0dda754e4ce 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -1,19 +1,12 @@ -/* group.c sept 2000 - * - cleaned up mar-01 nzc - * - * - * ton roosendaal +/* * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -31,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -39,40 +32,31 @@ #include "MEM_guardedalloc.h" -#include "DNA_ID.h" +#include "DNA_action_types.h" +#include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_object_types.h" +#include "DNA_ID.h" #include "DNA_ipo_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_nla_types.h" +#include "DNA_scene_types.h" #include "BLI_blenlib.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_library.h" +#include "BKE_global.h" #include "BKE_group.h" -#include "BKE_object.h" #include "BKE_ipo.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_object.h" #ifdef HAVE_CONFIG_H #include #endif -void free_object_key(ObjectKey *ok) -{ - if(ok->ipo) ok->ipo->id.us--; - - MEM_freeN(ok); -} - void free_group_object(GroupObject *go) { - ObjectKey *ok; - - while(go->okey.first) { - ok= go->okey.first; - BLI_remlink(&go->okey, ok); - free_object_key(ok); - } MEM_freeN(go); } @@ -82,14 +66,42 @@ void free_group(Group *group) /* don't free group itself */ GroupObject *go; - BLI_freelistN(&group->gkey); - while(group->gobject.first) { go= group->gobject.first; BLI_remlink(&group->gobject, go); free_group_object(go); } +} + +void unlink_group(Group *group) +{ + Material *ma; + Object *ob; + for(ma= G.main->mat.first; ma; ma= ma->id.next) { + if(ma->group==group) + ma->group= NULL; + } + for(ob= G.main->object.first; ob; ob= ob->id.next) { + bActionStrip *strip; + PartEff *paf; + + if(ob->dup_group==group) { + ob->dup_group= NULL; + + /* duplicator strips use a group object, we remove it */ + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object) + strip->object= NULL; + } + } + for(paf= ob->effect.first; paf; paf= paf->next) { + if(paf->type==EFF_PARTICLE) { + if(paf->group) + paf->group= NULL; + } + } + } } Group *add_group() @@ -100,97 +112,16 @@ Group *add_group() return group; } -/* assumes 'ok' is unitialized */ -void object_to_obkey(Object *ob, ObjectKey *ok) -{ - ok->partype= ob->partype; - ok->par1= ob->par1; - ok->par2= ob->par2; - ok->par3= ob->par3; - - ok->parent= ob->parent; - ok->track= ob->track; - - ok->ipo= copy_ipo(ob->ipo); - - memcpy(ok->loc, ob->loc, 7*3*sizeof(float)); - memcpy(ok->quat, ob->quat, 2*4*sizeof(float)); - memcpy(ok->obmat, ob->obmat, 3*4*4*sizeof(float)); - - ok->lay= ob->lay; - ok->transflag= ob->transflag; - ok->trackflag= ob->transflag; - ok->upflag= ob->upflag; - ok->sf= ob->sf; - ok->ctime= ob->ctime; - - -} - -void obkey_to_object(ObjectKey *ok, Object *ob) -{ - ob->partype= ok->partype; - ob->par1= ok->par1; - ob->par2= ok->par2; - ob->par3= ok->par3; - - ob->parent= ok->parent; - ob->track= ok->track; - - /* pretty tricky, this makes ob->ipo blocks with users 'hanging around' */ - if(ob->ipo) { - free_libblock_us(&G.main->ipo, ob->ipo); - } - ob->ipo= copy_ipo(ok->ipo); - - memcpy(ob->loc, ok->loc, 7*3*sizeof(float)); - memcpy(ob->quat, ok->quat, 2*4*sizeof(float)); - memcpy(ob->obmat, ok->obmat, 3*4*4*sizeof(float)); - - ob->lay= ok->lay; - ob->transflag= ok->transflag; - ob->trackflag= ok->transflag; - ob->upflag= ok->upflag; - ob->sf= ok->sf; - ob->ctime= ok->ctime; -} - -/* current ob position */ -void add_object_key(GroupObject *go, GroupKey *gk) -{ - ObjectKey *ok; - - /* check if there already is a key */ - ok= go->okey.first; - while(ok) { - if(ok->gkey == gk) break; - ok= ok->next; - } - - if(ok) { - BLI_remlink(&go->okey, ok); - free_object_key(ok); - } - ok= MEM_mallocN(sizeof(ObjectKey), "objectkey"); - ok->gkey= gk; - - object_to_obkey(go->ob, ok); - - BLI_addtail(&go->okey, ok); - -} - /* external */ void add_to_group(Group *group, Object *ob) { GroupObject *go; - GroupKey *gk; + + if(group==NULL || ob==NULL) return; /* check if the object has been added already */ - go= group->gobject.first; - while(go) { + for(go= group->gobject.first; go; go= go->next) { if(go->ob==ob) return; - go= go->next; } go= MEM_callocN(sizeof(GroupObject), "groupobject"); @@ -198,18 +129,14 @@ void add_to_group(Group *group, Object *ob) go->ob= ob; - /* keys? */ - gk= group->gkey.first; - while(gk) { - add_object_key(go, gk); - gk= gk->next; - } } +/* also used for ob==NULL */ void rem_from_group(Group *group, Object *ob) { GroupObject *go, *gon; - ObjectKey *ok; + + if(group==NULL) return; go= group->gobject.first; while(go) { @@ -218,116 +145,179 @@ void rem_from_group(Group *group, Object *ob) BLI_remlink(&group->gobject, go); free_group_object(go); } - else { - ok= go->okey.first; - while(ok) { - if(ok->parent==ob) ok->parent= NULL; - if(ok->track==ob) ok->track= NULL; - ok= ok->next; - } - } go= gon; } } -void add_group_key(Group *group) +int object_in_group(Object *ob, Group *group) { GroupObject *go; - GroupKey *gk; - int nr=10; - extern char colname_array[][20]; /* material.c */ - - gk= group->gkey.first; - while(gk) { - nr++; - gk= gk->next; + + if(group==NULL || ob==NULL) return 0; + + for(go= group->gobject.first; go; go= go->next) { + if(go->ob==ob) + return 1; } - - gk= MEM_callocN(sizeof(GroupKey), "groupkey"); - BLI_addtail(&group->gkey, gk); - strcpy(gk->name, colname_array[ nr % 120 ]); - - go= group->gobject.first; - while(go) { - add_object_key(go, gk); - go= go->next; - } - - group->active= gk; -} - -void set_object_key(Object *ob, ObjectKey *ok) -{ - obkey_to_object(ok, ob); -} - -void set_group_key(Group *group) -{ - /* sets active */ - GroupObject *go; - ObjectKey *ok; - - if(group->active==NULL) return; - - go= group->gobject.first; - while(go) { - ok= go->okey.first; - while(ok) { - if(ok->gkey==group->active) { - set_object_key(go->ob, ok); - break; - } - ok= ok->next; - } - go= go->next; - } - + return 0; } Group *find_group(Object *ob) { Group *group= G.main->group.first; - GroupObject *go; while(group) { - - go= group->gobject.first; - while(go) { - if(go->ob==ob) return group; - go= go->next; - } + if(object_in_group(ob, group)) + return group; group= group->id.next; } return NULL; } -void set_group_key_name(Group *group, char *name) -{ - GroupKey *gk; - - if(group==NULL) return; - - gk= group->gkey.first; - while(gk) { - if(strcmp(name, gk->name)==0) break; - gk= gk->next; - } - - if(gk) { - group->active= gk; - set_group_key(group); - } -} - -void set_group_key_frame(Group *group, float frame) +void group_tag_recalc(Group *group) { GroupObject *go; if(group==NULL) return; - - go= group->gobject.first; - while(go) { - where_is_object_time(go->ob, frame); - go= go->next; + + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) + go->ob->recalc= OB_RECALC; } } + +/* only replaces object strips or action when parent nla instructs it */ +/* keep checking nla.c though, in case internal structure of strip changes */ +static void group_replaces_nla(Object *parent, Object *target, char mode) +{ + static ListBase nlastrips={NULL, NULL}; + static bAction *action= NULL; + static int done= 0; + bActionStrip *strip, *nstrip; + + if(mode=='s') { + + for(strip= parent->nlastrips.first; strip; strip= strip->next) { + if(strip->object==target) { + if(done==0) { + /* clear nla & action from object */ + nlastrips= target->nlastrips; + target->nlastrips.first= target->nlastrips.last= NULL; + action= target->action; + target->action= NULL; + target->nlaflag |= OB_NLA_OVERRIDE; + done= 1; + } + nstrip= MEM_dupallocN(strip); + BLI_addtail(&target->nlastrips, nstrip); + } + } + } + else if(mode=='e') { + if(done) { + BLI_freelistN(&target->nlastrips); + target->nlastrips= nlastrips; + target->action= action; + + nlastrips.first= nlastrips.last= NULL; /* not needed, but yah... :) */ + action= NULL; + done= 0; + } + } +} + + +/* puts all group members in local timing system, after this call +you can draw everything, leaves tags in objects to signal it needs further updating */ +void group_handle_recalc_and_update(Object *parent, Group *group) +{ + GroupObject *go; + + /* if animated group... */ + if(parent->sf != 0.0f || parent->nlastrips.first) { + int cfrao; + + /* switch to local time */ + cfrao= G.scene->r.cfra; + G.scene->r.cfra -= (int)parent->sf; + + /* we need a DAG per group... */ + for(go= group->gobject.first; go; go= go->next) { + if(go->ob && go->recalc) { + go->ob->recalc= go->recalc; + + group_replaces_nla(parent, go->ob, 's'); + object_handle_update(go->ob); + group_replaces_nla(parent, go->ob, 'e'); + + /* leave recalc tags in case group members are in normal scene */ + go->ob->recalc= go->recalc; + } + } + + /* restore */ + G.scene->r.cfra= cfrao; + } + else { + /* only do existing tags, as set by regular depsgraph */ + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) { + if(go->ob->recalc) { + object_handle_update(go->ob); + } + } + } + } +} + +Object *group_get_member_with_action(Group *group, bAction *act) +{ + GroupObject *go; + + if(group==NULL || act==NULL) return NULL; + + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) { + if(go->ob->action==act) + return go->ob; + if(go->ob->nlastrips.first) { + bActionStrip *strip; + + for(strip= go->ob->nlastrips.first; strip; strip= strip->next) { + if(strip->act==act) + return go->ob; + } + } + } + } + return NULL; +} + +/* if group has NLA, we try to map the used objects in NLA to group members */ +/* this assuming that object has received a new group link */ +void group_relink_nla_objects(Object *ob) +{ + Group *group; + GroupObject *go; + bActionStrip *strip; + + if(ob==NULL || ob->dup_group==NULL) return; + group= ob->dup_group; + + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object) { + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) { + if(strcmp(go->ob->id.name, strip->object->id.name)==0) + break; + } + } + if(go) + strip->object= go->ob; + else + strip->object= NULL; + } + + } +} + diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c new file mode 100644 index 00000000000..9617902e057 --- /dev/null +++ b/source/blender/blenkernel/intern/icons.c @@ -0,0 +1,196 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_ID.h" + +#include "BLI_ghash.h" + +#include "BKE_icons.h" + +#define GS(a) (*((short *)(a))) + +/* GLOBALS */ + +static GHash* gIcons = 0; + +static int gNextIconId = 1; + +static int gFirstIconId = 1; + + +static void icon_free(void *val) +{ + Icon* icon = val; + + if (icon) + { + if (icon->drawinfo_free) { + icon->drawinfo_free(icon->drawinfo); + } + else if (icon->drawinfo) { + MEM_freeN(icon->drawinfo); + } + MEM_freeN(icon); + } +} + +/* create an id for a new icon and make sure that ids from deleted icons get reused + after the integer number range is used up */ +static int get_next_free_id() +{ + int startId = gFirstIconId; + + /* if we haven't used up the int number range, we just return the next int */ + if (gNextIconId>=gFirstIconId) + return gNextIconId++; + + /* now we try to find the smallest icon id not stored in the gIcons hash */ + while (BLI_ghash_lookup(gIcons, (void *)startId) && startId>=gFirstIconId) + startId++; + + /* if we found a suitable one that isnt used yet, return it */ + if (startId>=gFirstIconId) + return startId; + + /* fail */ + return 0; +} + +void BKE_icons_init(int first_dyn_id) +{ + gNextIconId = first_dyn_id; + gFirstIconId = first_dyn_id; + + if (!gIcons) + gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp); +} + +void BKE_icons_free() +{ + BLI_ghash_free(gIcons, 0, icon_free); + gIcons = 0; +} + + +void BKE_icon_changed(int id) +{ + Icon* icon = 0; + + if (!id) return; + + icon = BLI_ghash_lookup(gIcons, (void *)id); + + if (icon) + { + icon->changed = 1; + } +} + +int BKE_icon_getid(struct ID* id) +{ + Icon* new_icon = 0; + + if (!id) + return 0; + + if (id->icon_id) + return id->icon_id; + + id->icon_id = get_next_free_id(); + + if (!id->icon_id){ + printf("BKE_icon_getid: Internal error - not enough IDs\n"); + return 0; + } + + new_icon = MEM_callocN(sizeof(Icon), "texicon"); + + new_icon->obj = id; + new_icon->type = GS(id->name); + + /* next two lines make sure image gets created */ + new_icon->drawinfo = 0; + new_icon->drawinfo_free = 0; + new_icon->changed = 1; + + BLI_ghash_insert(gIcons, (void *)id->icon_id, new_icon); + + return id->icon_id; +} + +Icon* BKE_icon_get(int icon_id) +{ + Icon* icon = 0; + + icon = BLI_ghash_lookup(gIcons, (void*)icon_id); + + if (!icon) { + printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id); + return 0; + } + + return icon; +} + +void BKE_icon_set(int icon_id, struct Icon* icon) +{ + Icon* old_icon = 0; + + old_icon = BLI_ghash_lookup(gIcons, (void*)icon_id); + + if (old_icon) + { + printf("BKE_icon_set: Internal error, icon already set: %d\n", icon_id); + return; + } + + BLI_ghash_insert(gIcons, (void *)icon_id, icon); +} + +void BKE_icon_delete(struct ID* id) +{ + + if (!id->icon_id) return; /* no icon defined for library object */ + + BLI_ghash_remove(gIcons, (void*)id->icon_id, 0, icon_free); + id->icon_id = 0; +} diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 9973adddabc..b37e787729e 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -51,6 +51,7 @@ #include "DNA_image_types.h" #include "DNA_texture_types.h" #include "DNA_packedFile_types.h" +#include "DNA_scene_types.h" #include "DNA_userdef_types.h" #include "BLI_blenlib.h" @@ -61,6 +62,7 @@ #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_icons.h" #include "BKE_image.h" #include "BKE_scene.h" #include "BKE_texture.h" @@ -103,6 +105,8 @@ void free_image(Image *ima) freePackedFile(ima->packedfile); ima->packedfile = NULL; } + BKE_icon_delete(&ima->id); + ima->id.icon_id = 0; } @@ -272,7 +276,127 @@ void free_unused_animimages() /* *********** READ AND WRITE ************** */ -void makepicstring(char *string, int frame) +int BKE_imtype_is_movie(int imtype) +{ + switch(imtype) { + case R_MOVIE: + case R_AVIRAW: + case R_AVIJPEG: + case R_AVICODEC: + case R_QUICKTIME: + return 1; + } + return 0; +} + +void BKE_add_image_extension(char *string, int imtype) +{ + char *extension=""; + + if(G.scene->r.imtype== R_IRIS) { + if(!BLI_testextensie(string, ".rgb")) + extension= ".rgb"; + } + else if(imtype==R_IRIZ) { + if(!BLI_testextensie(string, ".rgb")) + extension= ".rgb"; + } + else if(imtype==R_RADHDR) { + if(!BLI_testextensie(string, ".hdr")) + extension= ".hdr"; + } + else if(imtype==R_PNG) { + if(!BLI_testextensie(string, ".png")) + extension= ".png"; + } + else if(imtype==R_RAWTGA) { + if(!BLI_testextensie(string, ".tga")) + extension= ".tga"; + } + else if(ELEM5(imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { + if(!BLI_testextensie(string, ".jpg")) + extension= ".jpg"; + } + else if(imtype==R_BMP) { + if(!BLI_testextensie(string, ".bmp")) + extension= ".bmp"; + } + else if(G.have_libtiff && (imtype==R_TIFF)) { + if(!BLI_testextensie(string, ".tif")) + extension= ".tif"; + } +#ifdef WITH_OPENEXR + else if(imtype==R_OPENEXR) { + if(!BLI_testextensie(string, ".exr")) + extension= ".exr"; + } +#endif + else { /* targa default */ + if(!BLI_testextensie(string, ".tga")) + extension= ".tga"; + } + + strcat(string, extension); +} + + +int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quality) +{ + int ok; + + if(imtype==0); + else if(imtype== R_IRIS) ibuf->ftype= IMAGIC; + else if ((imtype==R_RADHDR)) { + ibuf->ftype= RADHDR; + } + else if ((imtype==R_PNG)) { + ibuf->ftype= PNG; + } + else if ((imtype==R_BMP)) { + ibuf->ftype= BMP; + } + else if ((G.have_libtiff) && (imtype==R_TIFF)) { + ibuf->ftype= TIF; + } +#ifdef WITH_OPENEXR + else if (imtype==R_OPENEXR) { + ibuf->ftype= OPENEXR; + if(subimtype & R_OPENEXR_HALF) + ibuf->ftype |= OPENEXR_HALF; + ibuf->ftype |= (quality & OPENEXR_COMPRESS); + + if(!(subimtype & R_OPENEXR_ZBUF)) + ibuf->zbuf_float = NULL; /* signal for exr saving */ + + } +#endif + else if (imtype==R_TARGA) { + ibuf->ftype= TGA; + } + else if(imtype==R_RAWTGA) { + ibuf->ftype= RAWTGA; + } + else if(imtype==R_HAMX) { + ibuf->ftype= AN_hamx; + } + else if ELEM(imtype, R_JPEG90, R_MOVIE) { + if(quality < 10) quality= 90; + ibuf->ftype= JPG|quality; + } + else ibuf->ftype= TGA; + + BLI_make_existing_file(name); + + ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); + if (ok == 0) { + perror(name); + } + + return(ok); +} + + +void BKE_makepicstring(char *string, int frame) { short i,len; char num[10], *extension; @@ -297,55 +421,10 @@ void makepicstring(char *string, int frame) strcat(string,num); if(G.scene->r.scemode & R_EXTENSION) - addImageExtension(string); + BKE_add_image_extension(string, G.scene->r.imtype); } -void addImageExtension(char *string) -{ - char *extension=""; - - if(G.scene->r.imtype== R_IRIS) { - if(!BLI_testextensie(string, ".rgb")) - extension= ".rgb"; - } - else if(G.scene->r.imtype==R_IRIZ) { - if(!BLI_testextensie(string, ".rgb")) - extension= ".rgb"; - } - else if(G.scene->r.imtype==R_RADHDR) { - if(!BLI_testextensie(string, ".hdr")) - extension= ".hdr"; - } - else if(G.scene->r.imtype==R_PNG) { - if(!BLI_testextensie(string, ".png")) - extension= ".png"; - } - else if(G.scene->r.imtype==R_TARGA) { - if(!BLI_testextensie(string, ".tga")) - extension= ".tga"; - } - else if(G.scene->r.imtype==R_RAWTGA) { - if(!BLI_testextensie(string, ".tga")) - extension= ".tga"; - } - else if(G.scene->r.imtype==R_JPEG90) { - if(!BLI_testextensie(string, ".jpg")) - extension= ".jpg"; - } - else if(G.scene->r.imtype==R_BMP) { - if(!BLI_testextensie(string, ".bmp")) - extension= ".bmp"; - } - else if(G.have_libtiff && (G.scene->r.imtype==R_TIFF)) { - if(!BLI_testextensie(string, ".tif")) - extension= ".tif"; - } - - strcat(string, extension); -} - - /* ******** IMAGE WRAPPING INIT ************* */ /* used by sequencer, texture */ @@ -447,13 +526,13 @@ static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */ tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0); ibuf->x *= 2; - /* These rectop calls are broken!!! I added a trailing 0 arg... */ - IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + + IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y); ibuf->x /= 2; - IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y); + IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y); IMB_freeImBuf(tbuf1); IMB_freeImBuf(tbuf2); @@ -475,13 +554,13 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */ tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0); ibuf->x *= 2; - /* These are brolenm as well... */ - IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + + IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y); ibuf->x /= 2; - IMB_rectop(ibuf, tbuf2, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(ibuf, tbuf1, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, tbuf2, 0, 0, 0, 0, tbuf2->x, tbuf2->y); + IMB_rectcpy(ibuf, tbuf1, 0, tbuf2->y, 0, 0, tbuf1->x, tbuf1->y); IMB_freeImBuf(tbuf1); IMB_freeImBuf(tbuf2); @@ -510,7 +589,6 @@ void ima_ibuf_is_nul(Tex *tex, Image *ima) if (ima->anim) { dur = IMB_anim_get_duration(ima->anim); - ima->lastquality= R.osa; fra= ima->lastframe-1; if(fra<0) fra = 0; @@ -535,8 +613,6 @@ void ima_ibuf_is_nul(Tex *tex, Image *ima) load_image(ima, IB_rect, G.sce, G.scene->r.cfra); if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf); - - ima->lastquality= R.osa; } if(ima->ibuf) { @@ -557,21 +633,18 @@ void ima_ibuf_is_nul(Tex *tex, Image *ima) } IMB_applycmap(ima->ibuf); - IMB_convert_rgba_to_abgr(ima->ibuf->x*ima->ibuf->y, ima->ibuf->rect); + IMB_convert_rgba_to_abgr(ima->ibuf); } converttopremul(ima->ibuf); } - if(R.osa) { - - if(tex->imaflag & TEX_ANTISCALE) { - IMB_clever_double(ima->ibuf); - IMB_antialias(ima->ibuf); - } - else if(tex->imaflag & TEX_ANTIALI) IMB_antialias(ima->ibuf); + if(tex->imaflag & TEX_ANTISCALE) { + IMB_clever_double(ima->ibuf); + IMB_antialias(ima->ibuf); } + else if(tex->imaflag & TEX_ANTIALI) IMB_antialias(ima->ibuf); } if(ima->ibuf) diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index dcb8532b232..b6b4f9a3bcb 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -57,6 +57,7 @@ #include "DNA_sound_types.h" #include "DNA_texture_types.h" #include "DNA_view3d_types.h" +#include "DNA_world_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -178,9 +179,9 @@ float frame_to_float(int cfra) /* see also bsystem_time in object.c */ float ctime; ctime= (float)cfra; - if(R.flag & R_SEC_FIELD) { - if((R.r.mode & R_FIELDSTILL)==0) ctime+= 0.5; - } +// if(R.flag & R_SEC_FIELD) { +// if((R.r.mode & R_FIELDSTILL)==0) ctime+= 0.5; +// } ctime+= bluroffs; ctime*= G.scene->r.framelen; @@ -1829,7 +1830,11 @@ void execute_action_ipo(bActionChannel *achan, bPoseChannel *pchan) IpoCurve *icu; for(icu= achan->ipo->curve.first; icu; icu= icu->next) { void *poin= get_pchan_ipo_poin(pchan, icu->adrcode); - if(poin) write_ipo_poin(poin, IPO_FLOAT, icu->curval); + if(poin) { + write_ipo_poin(poin, IPO_FLOAT, icu->curval); + //printf("execute_action_ipo wrote_ipo_poin: %f\n", icu->curval); + //printf("%s has poin %p value %f\n", achan->name, poin, icu->curval); + } } } } diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index a2e372f33d5..e0006c854cf 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -45,6 +45,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_action.h" #include "BKE_bad_level_calls.h" diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 28808bb900f..4680a44d836 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1,11 +1,6 @@ - -/* library.c - * - * Contains management of ID's and libraries - * allocate and free of all library data - * +/** * $Id$ - * + * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -34,6 +29,14 @@ * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ + +/* + * Contains management of ID's and libraries + * allocate and free of all library data + * + */ + + #include #include #include @@ -71,6 +74,7 @@ #include "DNA_armature_types.h" #include "DNA_action_types.h" #include "DNA_userdef_types.h" +#include "DNA_node_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -90,6 +94,7 @@ #include "BKE_text.h" #include "BKE_texture.h" #include "BKE_scene.h" +#include "BKE_icons.h" #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_key.h" @@ -99,9 +104,11 @@ #include "BKE_lattice.h" #include "BKE_armature.h" #include "BKE_action.h" +#include "BKE_node.h" + #include "BPI_script.h" -#define MAX_IDPUP 30 /* was 24 */ +#define MAX_IDPUP 60 /* was 24 */ #define MAX_LIBARRAY 100 /* was 30, warning: used it readfile.c too */ /* ************* general ************************ */ @@ -181,6 +188,8 @@ ListBase *wich_libbase(Main *mainlib, short type) return &(mainlib->armature); case ID_AC: return &(mainlib->action); + case ID_NT: + return &(mainlib->nodetree); } return 0; } @@ -220,12 +229,13 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[20]= &(main->text); lb[21]= &(main->sound); lb[22]= &(main->group); + lb[23]= &(main->nodetree); - lb[23]= samples; - lb[24]= &(main->script); - lb[25]= NULL; + lb[24]= samples; + lb[25]= &(main->script); + lb[26]= NULL; - return 25; + return 26; } /* *********** ALLOC AND FREE ***************** @@ -240,7 +250,7 @@ void *alloc_libblock(ListBase *lb, type, name) static ID *alloc_libblock_notest(short type) { - ID *id= 0; + ID *id= NULL; switch( type ) { case ID_SCE: @@ -318,19 +328,23 @@ static ID *alloc_libblock_notest(short type) case ID_AC: id = MEM_callocN(sizeof(bAction), "action"); break; + case ID_NT: + id = MEM_callocN(sizeof(bNodeTree), "action"); + break; } return id; } // used everywhere in blenkernel and text.c -void *alloc_libblock(ListBase *lb, short type, char *name) +void *alloc_libblock(ListBase *lb, short type, const char *name) { - ID *id= 0; + ID *id= NULL; id= alloc_libblock_notest(type); if(id) { BLI_addtail(lb, id); id->us= 1; + id->icon_id = 0; *( (short *)id->name )= type; new_id(lb, id, name); /* alphabetic insterion: is in new_id */ @@ -338,19 +352,13 @@ void *alloc_libblock(ListBase *lb, short type, char *name) return id; } -/* GS reads the memory pointed at in a specific ordering. There are, - * however two definitions for it. I have jotted them down here, both, - * but I think the first one is actually used. The thing is that - * big-endian systems might read this the wrong way round. OTOH, we - * constructed the IDs that are read out with this macro explicitly as - * well. I expect we'll sort it out soon... */ +/* 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))) -/* from misc_util: flip the bytes from x */ -/*#define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */ - // used everywhere in blenkernel and text.c void *copy_libblock(void *rt) { @@ -463,6 +471,9 @@ void free_libblock(ListBase *lb, void *idv) case ID_AC: free_action((bAction *)id); break; + case ID_NT: + ntreeFreeTree((bNodeTree *)id); + break; } BLI_remlink(lb, id); @@ -525,9 +536,10 @@ ID *find_id(char *type, char *name) /* type: "OB" or "MA" etc */ return 0; } -static void get_flags_for_id(ID *id, char *buf) { +static void get_flags_for_id(ID *id, char *buf) +{ int isfake= id->flag & LIB_FAKEUSER; - + int isnode=0; /* Writeout the flags for the entry, note there * is a small hack that writes 5 spaces instead * of 4 if no flags are displayed... this makes @@ -535,10 +547,15 @@ static void get_flags_for_id(ID *id, char *buf) { * to have that explicit, oh well - zr */ + if(GS(id->name)==ID_MA) + isnode= ((Material *)id)->use_nodes; + if (id->us<0) sprintf(buf, "-1W "); - else if (!id->lib && !isfake && id->us) + else if (!id->lib && !isfake && id->us && !isnode) sprintf(buf, " "); + else if(isnode) + sprintf(buf, "%c%cN%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' '); else sprintf(buf, "%c%c%c ", id->lib?'L':' ', isfake?'F':' ', (id->us==0)?'O':' '); } @@ -551,6 +568,7 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor if (nr && nids>MAX_IDPUP) { BLI_dynstr_append(pupds, "DataBrowse %x-2"); + *nr= -2; } else { ID *id; @@ -569,6 +587,21 @@ static void IDnames_to_dyn_pupstring(DynStr *pupds, ListBase *lb, ID *link, shor sprintf(buf, "%%x%d", i+1); BLI_dynstr_append(pupds, buf); + /* 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 */ + sprintf(buf, "%%i%d", BKE_icon_getid(id) ); + BLI_dynstr_append(pupds, buf); + break; + default: + break; + } + if(id->next) BLI_dynstr_append(pupds, "|"); } @@ -715,7 +748,7 @@ static void sort_alpha_id(ListBase *lb, ID *id) } -int new_id(ListBase *lb, ID *id, char *tname) +int new_id(ListBase *lb, ID *id, const char *tname) /* only for local blocks: external en indirect blocks already have a unique ID */ /* return 1: created a new name */ { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index d303a7ed5bd..b95c401808d 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -34,35 +34,49 @@ */ #include +#include + #include "MEM_guardedalloc.h" -#include "DNA_material_types.h" -#include "DNA_texture_types.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" #include "DNA_curve_types.h" +#include "DNA_material_types.h" +#include "DNA_mesh_types.h" #include "DNA_meta_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_texture_types.h" #include "BLI_blenlib.h" #include "BKE_bad_level_calls.h" -#include "BKE_utildefines.h" - -#include "BKE_global.h" -#include "BKE_main.h" - -#include "BKE_mesh.h" -#include "BKE_library.h" +#include "BKE_blender.h" #include "BKE_displist.h" +#include "BKE_global.h" +#include "BKE_icons.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_material.h" +#include "BKE_mesh.h" +#include "BKE_node.h" +#include "BKE_utildefines.h" #include "BPY_extern.h" +/* used in UI and render */ +Material defmaterial; + +/* called on startup, creator.c */ +void init_def_material(void) +{ + init_material(&defmaterial); +} + +/* not material itself */ void free_material(Material *ma) { - int a; MTex *mtex; + int a; BPY_free_scriptlink(&ma->scriptlink); @@ -74,6 +88,15 @@ void free_material(Material *ma) if(ma->ramp_col) MEM_freeN(ma->ramp_col); if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); + + BKE_icon_delete((struct ID*)ma); + ma->id.icon_id = 0; + + /* is no lib link block, but material extension */ + if(ma->nodetree) { + ntreeFreeTree(ma->nodetree); + MEM_freeN(ma->nodetree); + } } void init_material(Material *ma) @@ -115,9 +138,9 @@ void init_material(Material *ma) ma->rampfac_col= 1.0; ma->rampfac_spec= 1.0; - ma->pr_lamp= 3; // two lamps, is bits - - ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_TANGENT_STR; + ma->pr_lamp= 3; /* two lamps, is bits */ + + ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR; } Material *add_material(char *name) @@ -149,9 +172,14 @@ Material *copy_material(Material *ma) } BPY_copy_scriptlink(&ma->scriptlink); + if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col); if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec); + if(ma->nodetree) { + man->nodetree= ntreeCopyTree(ma->nodetree, 0); /* 0 == full new tree */ + } + return man; } @@ -245,6 +273,7 @@ void make_local_material(Material *ma) new_id(0, (ID *)ma, 0); } else if(local && lib) { + man= copy_material(ma); man->id.us= 0; @@ -534,8 +563,7 @@ void new_material_to_objectdata(Object *ob) ob->actcol= ob->totcol; } - -void init_render_material(Material *ma) +static void do_init_render_material(Material *ma, int osa, float *amb) { MTex *mtex; int a, needuv=0; @@ -551,77 +579,85 @@ void init_render_material(Material *ma) ma->texco |= mtex->texco; ma->mapto |= mtex->mapto; - if(R.osa) { + if(osa) { if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA; } - if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND)) needuv= 1; + if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1; else if(ma->texco & (TEXCO_GLOB|TEXCO_UV|TEXCO_OBJECT)) needuv= 1; else if(ma->texco & (TEXCO_LAVECTOR|TEXCO_VIEW|TEXCO_STICKY)) needuv= 1; - - if(mtex->object) mtex->object->flag |= OB_DO_IMAT; - } } - if(ma->mode & MA_ZTRA) { - /* if(ma->alpha==0.0 || ma->alpha==1.0) */ - if(R.flag & R_RENDERING) R.flag |= R_ZTRA; - } if(ma->mode & MA_RADIO) needuv= 1; if(ma->mode & (MA_VERTEXCOL|MA_VERTEXCOLP|MA_FACETEXTURE)) { needuv= 1; - if(R.osa) ma->texco |= TEXCO_OSA; /* for texfaces */ + if(osa) ma->texco |= TEXCO_OSA; /* for texfaces */ } if(needuv) ma->texco |= NEED_UV; // since the raytracer doesnt recalc O structs for each ray, we have to preset them all if(ma->mode & (MA_RAYMIRROR|MA_RAYTRANSP|MA_SHADOW_TRA)) { ma->texco |= NEED_UV|TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM; - if(R.osa) ma->texco |= TEXCO_OSA; + if(osa) ma->texco |= TEXCO_OSA; } - ma->ambr= ma->amb*R.wrld.ambr; - ma->ambg= ma->amb*R.wrld.ambg; - ma->ambb= ma->amb*R.wrld.ambb; + ma->ambr= ma->amb*amb[0]; + ma->ambg= ma->amb*amb[1]; + ma->ambb= ma->amb*amb[2]; + /* will become or-ed result of all node modes */ + ma->mode_l= ma->mode; } -void init_render_materials() +void init_render_material(Material *mat, int osa, float *amb) { - Material *ma; + do_init_render_material(mat, osa, amb); - ma= G.main->mat.first; - while(ma) { - if(ma->id.us) init_render_material(ma); - ma= ma->id.next; - } - -} - -void end_render_material(Material *ma) -{ - /* XXXX obsolete? check! */ - if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { - if( !(ma->mode & MA_HALO) ) { - ma->r= ma->g= ma->b= 1.0; + if(mat->nodetree && mat->use_nodes) { + bNode *node; + + for(node=mat->nodetree->nodes.first; node; node= node->next) { + if(node->id && GS(node->id->name)==ID_MA) { + Material *ma= (Material *)node->id; + if(ma!=mat) { + do_init_render_material(ma, osa, amb); + mat->texco |= ma->texco; + mat->mode_l |= ma->mode_l; + } + } } + /* parses the geom nodes */ + mat->texco |= ntreeShaderGetTexco(mat->nodetree, osa); + ntreeBeginExecTree(mat->nodetree); /* has internal flag to detect it only does it once */ } } -void end_render_materials() +void init_render_materials(int osa, float *amb) { Material *ma; - ma= G.main->mat.first; - while(ma) { - if(ma->id.us) end_render_material(ma); - ma= ma->id.next; - } - + /* two steps, first initialize, then or the flags for layers */ + for(ma= G.main->mat.first; ma; ma= ma->id.next) + if(ma->id.us) + init_render_material(ma, osa, amb); } +/* only needed for nodes now */ +void end_render_material(Material *mat) +{ + if(mat && mat->nodetree && mat->use_nodes) + ntreeEndExecTree(mat->nodetree); /* has internal flag to detect it only does it once */ +} + +void end_render_materials(void) +{ + Material *ma; + for(ma= G.main->mat.first; ma; ma= ma->id.next) + if(ma->id.us) + end_render_material(ma); +} /* ****************** */ @@ -756,3 +792,89 @@ void delete_material_index() freedisplist(&ob->disp); } } + + +/* r g b = current value, col = new value, fac==0 is no change */ +/* if g==NULL, it only does r channel */ +void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) +{ + float tmp, facm= 1.0-fac; + + switch (type) { + case MA_RAMP_BLEND: + *r = facm*(*r) + fac*col[0]; + if(g) { + *g = facm*(*g) + fac*col[1]; + *b = facm*(*b) + fac*col[2]; + } + break; + case MA_RAMP_ADD: + *r += fac*col[0]; + if(g) { + *g += fac*col[1]; + *b += fac*col[2]; + } + break; + case MA_RAMP_MULT: + *r *= (facm + fac*col[0]); + if(g) { + *g *= (facm + fac*col[1]); + *b *= (facm + fac*col[2]); + } + break; + case MA_RAMP_SCREEN: + *r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r); + if(g) { + *g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g); + *b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b); + } + break; + case MA_RAMP_SUB: + *r -= fac*col[0]; + if(g) { + *g -= fac*col[1]; + *b -= fac*col[2]; + } + break; + case MA_RAMP_DIV: + if(col[0]!=0.0) + *r = facm*(*r) + fac*(*r)/col[0]; + if(g) { + if(col[1]!=0.0) + *g = facm*(*g) + fac*(*g)/col[1]; + if(col[2]!=0.0) + *b = facm*(*b) + fac*(*b)/col[2]; + } + break; + case MA_RAMP_DIFF: + *r = facm*(*r) + fac*fabs(*r-col[0]); + if(g) { + *g = facm*(*g) + fac*fabs(*g-col[1]); + *b = facm*(*b) + fac*fabs(*b-col[2]); + } + 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; + case MA_RAMP_LIGHT: + 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; + } + +} + + diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index ea1608d8a18..9429183105b 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -30,8 +30,6 @@ * 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): Jiri Hnidek . * * ***** END GPL/BL DUAL LICENSE BLOCK ***** @@ -1106,7 +1104,6 @@ void vnormal (MB_POINT *point, PROCESS *p, MB_POINT *v) } if(FALSE) { - /* if(R.flag & R_RENDERING) { */ MB_POINT temp; delta*= 2.0; @@ -1437,11 +1434,12 @@ float init_meta(Object *ob) /* return totsize */ Object *bob; MetaBall *mb; MetaElem *ml; - float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], vec[3]; + float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], obmat[4][4], vec[3]; float temp1[4][4], temp2[4][4], temp3[4][4]; //max=0.0; int a, obnr, zero_size=0; char obname[32]; + Mat4CpyMat4(obmat, ob->obmat); /* to cope with duplicators from next_object */ Mat4Invert(obinv, ob->obmat); a= 0; @@ -1456,7 +1454,7 @@ float init_meta(Object *ob) /* return totsize */ zero_size= 0; ml= NULL; - if(bob==ob) { + if(bob==ob && (base->flag & OB_FROMDUPLI)==0) { mat= imat= 0; mb= ob->data; @@ -1471,7 +1469,6 @@ float init_meta(Object *ob) /* return totsize */ splitIDname(bob->id.name+2, name, &nr); if( strcmp(obname, name)==0 ) { mb= bob->data; - if(G.obedit && G.obedit->type==OB_MBALL && G.obedit->data==mb) ml= editelems.first; else ml= mb->elems.first; @@ -1535,7 +1532,7 @@ float init_meta(Object *ob) /* return totsize */ imat= new_pgn_element(4*4*sizeof(float)); /* mat is the matrix to transform from mball into the basis-mball */ - Mat4Invert(obinv, ob->obmat); + Mat4Invert(obinv, obmat); Mat4MulMat4(temp2, bob->obmat, obinv); /* MetaBall transformation */ Mat4MulMat4(mat, temp1, temp2); @@ -2002,7 +1999,7 @@ void metaball_polygonize(Object *ob) mb= ob->data; if(totelem==0) return; - if(!(R.flag & R_RENDERING) && (mb->flag==MB_UPDATE_NEVER)) return; + if(!(G.rendering) && (mb->flag==MB_UPDATE_NEVER)) return; if(G.moving && mb->flag==MB_UPDATE_FAST) return; freedisplist(&ob->disp); @@ -2029,7 +2026,7 @@ void metaball_polygonize(Object *ob) if(totelem > 1024) init_metaball_octal_tree(5); /* width is size per polygonize cube */ - if(R.flag & R_RENDERING) width= mb->rendersize; + if(G.rendering) width= mb->rendersize; else { width= mb->wiresize; if(G.moving && mb->flag==MB_UPDATE_HALFRES) width*= 2; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 5adde76accc..5fefc41f77c 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -46,6 +46,9 @@ #include #endif +/* NOTE: in group.c the strips get copied for group-nla override, this assumes + that strips are one single block, without additional data to be copied */ + void copy_actionstrip (bActionStrip **dst, bActionStrip **src){ bActionStrip *dstrip; bActionStrip *sstrip = *src; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c new file mode 100644 index 00000000000..3e99f83a8f6 --- /dev/null +++ b/source/blender/blenkernel/intern/node.c @@ -0,0 +1,1630 @@ +/** + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "DNA_ID.h" +#include "DNA_node_types.h" +#include "DNA_material_types.h" +#include "DNA_scene_types.h" + +#include "BKE_blender.h" +#include "BKE_colortools.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "MEM_guardedalloc.h" +#include "IMB_imbuf.h" + +/* not very important, but the stack solver likes to know a maximum */ +#define MAX_SOCKET 64 + +#pragma mark /* ************** Type stuff ********** */ + +static bNodeType *node_get_type(bNodeTree *ntree, int type, bNodeTree *ngroup) +{ + if(type==NODE_GROUP) { + if(ngroup && GS(ngroup->id.name)==ID_NT) { + return ngroup->owntype; + } + return NULL; + } + else { + bNodeType **typedefs= ntree->alltypes; + + while( *typedefs && (*typedefs)->type!=type) + typedefs++; + + return *typedefs; + } +} + +void ntreeInitTypes(bNodeTree *ntree) +{ + bNode *node, *next; + + if(ntree->type==NTREE_SHADER) + ntree->alltypes= node_all_shaders; + else if(ntree->type==NTREE_COMPOSIT) + ntree->alltypes= node_all_composit; + else { + ntree->alltypes= NULL; + printf("Error: no type definitions for nodes\n"); + } + + for(node= ntree->nodes.first; node; node= next) { + next= node->next; + node->typeinfo= node_get_type(ntree, node->type, (bNodeTree *)node->id); + if(node->typeinfo==NULL) { + printf("Error: Node type %s doesn't exist anymore, removed\n", node->name); + nodeFreeNode(ntree, node); + } + } + + ntree->init |= NTREE_TYPE_INIT; +} + +/* only used internal... we depend on type definitions! */ +static bNodeSocket *node_add_socket_type(ListBase *lb, bNodeSocketType *stype) +{ + bNodeSocket *sock= MEM_callocN(sizeof(bNodeSocket), "sock"); + + BLI_strncpy(sock->name, stype->name, NODE_MAXSTR); + if(stype->limit==0) sock->limit= 0xFFF; + else sock->limit= stype->limit; + sock->type= stype->type; + + sock->to_index= stype->own_index; + sock->tosock= stype->internsock; + + sock->ns.vec[0]= stype->val1; + sock->ns.vec[1]= stype->val2; + sock->ns.vec[2]= stype->val3; + sock->ns.vec[3]= stype->val4; + + if(lb) + BLI_addtail(lb, sock); + + return sock; +} + +static void node_rem_socket(bNodeTree *ntree, ListBase *lb, bNodeSocket *sock) +{ + bNodeLink *link, *next; + + for(link= ntree->links.first; link; link= next) { + next= link->next; + if(link->fromsock==sock || link->tosock==sock) { + nodeRemLink(ntree, link); + } + } + + BLI_remlink(lb, sock); + MEM_freeN(sock); +} + +static bNodeSocket *verify_socket(ListBase *lb, bNodeSocketType *stype) +{ + bNodeSocket *sock; + + for(sock= lb->first; sock; sock= sock->next) { + /* both indices are zero for non-groups, otherwise it's a unique index */ + if(sock->to_index==stype->own_index) + if(strncmp(sock->name, stype->name, NODE_MAXSTR)==0) + break; + } + if(sock) { + sock->type= stype->type; /* in future, read this from tydefs! */ + if(stype->limit==0) sock->limit= 0xFFF; + else sock->limit= stype->limit; + sock->tosock= stype->internsock; + + BLI_remlink(lb, sock); + + return sock; + } + else { + return node_add_socket_type(NULL, stype); + } +} + +static void verify_socket_list(bNodeTree *ntree, ListBase *lb, bNodeSocketType *stype_first) +{ + bNodeSocketType *stype; + + /* no inputs anymore? */ + if(stype_first==NULL) { + while(lb->first) + node_rem_socket(ntree, lb, lb->first); + } + else { + /* step by step compare */ + stype= stype_first; + while(stype->type != -1) { + stype->sock= verify_socket(lb, stype); + stype++; + } + /* leftovers are removed */ + while(lb->first) + node_rem_socket(ntree, lb, lb->first); + /* and we put back the verified sockets */ + stype= stype_first; + while(stype->type != -1) { + BLI_addtail(lb, stype->sock); + stype++; + } + } +} + +void nodeVerifyType(bNodeTree *ntree, bNode *node) +{ + bNodeType *ntype= node->typeinfo; + + if(ntype) { + /* might add some other verify stuff here */ + + verify_socket_list(ntree, &node->inputs, ntype->inputs); + verify_socket_list(ntree, &node->outputs, ntype->outputs); + } +} + +void ntreeVerifyTypes(bNodeTree *ntree) +{ + bNode *node; + + if((ntree->init & NTREE_TYPE_INIT)==0) + ntreeInitTypes(ntree); + + /* check inputs and outputs, and remove or insert them */ + for(node= ntree->nodes.first; node; node= node->next) + nodeVerifyType(ntree, node); + +} + +#pragma mark /* ************** Group stuff ********** */ + +bNodeType node_group_typeinfo= { + /* type code */ NODE_GROUP, + /* name */ "Group", + /* width+range */ 120, 60, 200, + /* class+opts */ NODE_CLASS_GROUP, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ NULL, + +}; + +/* tag internal sockets */ +static void group_tag_internal_sockets(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + /* clear intern tag, but check already for hidden sockets */ + for(node= ngroup->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->intern= sock->flag & SOCK_HIDDEN; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->intern= sock->flag & SOCK_HIDDEN; + } + /* set tag */ + for(link= ngroup->links.first; link; link= link->next) { + link->fromsock->intern= 1; + link->tosock->intern= 1; + } + + /* remove link pointer to external links (only happens on create group) */ + for(node= ngroup->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->intern==0) + sock->link= NULL; + } + + /* set all intern sockets to own_index zero, makes sure that later use won't mixup */ + for(node= ngroup->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->intern) + sock->own_index= 0; + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->intern) + sock->own_index= 0; + } +} + +/* after editing group, new sockets are zero */ +/* this routine ensures unique identifiers for zero sockets that are exposed */ +static void group_verify_own_indices(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock; + + for(node= ngroup->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->own_index==0 && sock->intern==0) + sock->own_index= ++(ngroup->cur_index); + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->own_index==0 && sock->intern==0) + sock->own_index= ++(ngroup->cur_index); + } +// printf("internal index %d\n", ngroup->cur_index); +} + + +/* nodetrees can be used as groups, so we need typeinfo structs generated */ +void ntreeMakeOwnType(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock; + int totin= 0, totout=0, a; + + /* tags socket when internal linked */ + group_tag_internal_sockets(ngroup); + + /* ensure all sockets have own unique id */ + group_verify_own_indices(ngroup); + + /* counting stats */ + for(node= ngroup->nodes.first; node; node= node->next) { + if(node->type==NODE_GROUP) + break; + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->intern==0) + totin++; + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->intern==0) + totout++; + } + /* debug: nodetrees in nodetrees not handled yet */ + if(node) { + printf("group in group, not supported yet\n"); + return; + } + + /* free own type struct */ + if(ngroup->owntype) { + if(ngroup->owntype->inputs) + MEM_freeN(ngroup->owntype->inputs); + if(ngroup->owntype->outputs) + MEM_freeN(ngroup->owntype->outputs); + MEM_freeN(ngroup->owntype); + } + + /* make own type struct */ + ngroup->owntype= MEM_mallocN(sizeof(bNodeType), "group type"); + *ngroup->owntype= node_group_typeinfo; + + /* input type arrays */ + if(totin) { + bNodeSocketType *stype; + bNodeSocketType *inputs= MEM_mallocN(sizeof(bNodeSocketType)*(totin+1), "bNodeSocketType"); + a= 0; + + for(node= ngroup->nodes.first; node; node= node->next) { + /* nodes are presumed fully verified, stype and socket list are in sync */ + stype= node->typeinfo->inputs; + for(sock= node->inputs.first; sock; sock= sock->next, stype++) { + if(sock->intern==0) { + /* debug only print */ + if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name); + + inputs[a]= *stype; + inputs[a].own_index= sock->own_index; + inputs[a].internsock= sock; + a++; + } + } + } + inputs[a].type= -1; /* terminator code */ + ngroup->owntype->inputs= inputs; + } + + /* output type arrays */ + if(totout) { + bNodeSocketType *stype; + bNodeSocketType *outputs= MEM_mallocN(sizeof(bNodeSocketType)*(totout+1), "bNodeSocketType"); + a= 0; + + for(node= ngroup->nodes.first; node; node= node->next) { + /* nodes are presumed fully verified, stype and socket list are in sync */ + stype= node->typeinfo->outputs; + for(sock= node->outputs.first; sock; sock= sock->next, stype++) { + if(sock->intern==0) { + /* debug only print */ + if(stype==NULL || stype->type==-1) printf("group verification error %s\n", ngroup->id.name); + + outputs[a]= *stype; + outputs[a].own_index= sock->own_index; + outputs[a].internsock= sock; + a++; + } + } + } + outputs[a].type= -1; /* terminator code */ + ngroup->owntype->outputs= outputs; + } + + /* voila, the nodetree has the full definition for generating group-node instances! */ +} + + +static bNodeSocket *groupnode_find_tosock(bNode *gnode, int index) +{ + bNodeSocket *sock; + + for(sock= gnode->inputs.first; sock; sock= sock->next) + if(sock->to_index==index) + return sock; + return NULL; +} + +static bNodeSocket *groupnode_find_fromsock(bNode *gnode, int index) +{ + bNodeSocket *sock; + + for(sock= gnode->outputs.first; sock; sock= sock->next) + if(sock->to_index==index) + return sock; + return NULL; +} + +bNode *nodeMakeGroupFromSelected(bNodeTree *ntree) +{ + bNodeLink *link, *linkn; + bNode *node, *gnode, *nextn; + bNodeTree *ngroup; + float min[2], max[2]; + int totnode=0; + + INIT_MINMAX2(min, max); + + /* is there something to group? also do some clearing */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->flag & NODE_SELECT) { + /* no groups in groups */ + if(node->type==NODE_GROUP) + return NULL; + DO_MINMAX2( (&node->locx), min, max); + totnode++; + } + node->done= 0; + } + if(totnode==0) return NULL; + + /* check if all connections are OK, no unselected node has both + inputs and outputs to a selection */ + for(link= ntree->links.first; link; link= link->next) { + if(link->fromnode->flag & NODE_SELECT) + link->tonode->done |= 1; + if(link->tonode->flag & NODE_SELECT) + link->fromnode->done |= 2; + } + + for(node= ntree->nodes.first; node; node= node->next) { + if((node->flag & NODE_SELECT)==0) + if(node->done==3) + break; + } + if(node) + return NULL; + + /* OK! new nodetree */ + ngroup= alloc_libblock(&G.main->nodetree, ID_NT, "NodeGroup"); + ngroup->type= ntree->type; + ngroup->alltypes= ntree->alltypes; + + /* move nodes over */ + for(node= ntree->nodes.first; node; node= nextn) { + nextn= node->next; + if(node->flag & NODE_SELECT) { + BLI_remlink(&ntree->nodes, node); + BLI_addtail(&ngroup->nodes, node); + node->locx-= 0.5f*(min[0]+max[0]); + node->locy-= 0.5f*(min[1]+max[1]); + } + } + + /* move links over */ + for(link= ntree->links.first; link; link= linkn) { + linkn= link->next; + if(link->fromnode->flag & link->tonode->flag & NODE_SELECT) { + BLI_remlink(&ntree->links, link); + BLI_addtail(&ngroup->links, link); + } + } + + /* now we can make own group typeinfo */ + ntreeMakeOwnType(ngroup); + + /* make group node */ + gnode= nodeAddNodeType(ntree, NODE_GROUP, ngroup); + gnode->locx= 0.5f*(min[0]+max[0]); + gnode->locy= 0.5f*(min[1]+max[1]); + + /* relink external sockets */ + for(link= ntree->links.first; link; link= link->next) { + if(link->tonode->flag & NODE_SELECT) { + link->tonode= gnode; + link->tosock= groupnode_find_tosock(gnode, link->tosock->own_index); + if(link->tosock==NULL) printf("Bad!\n"); + } + else if(link->fromnode->flag & NODE_SELECT) { + link->fromnode= gnode; + link->fromsock= groupnode_find_fromsock(gnode, link->fromsock->own_index); + if(link->fromsock==NULL) printf("Bad!\n"); + } + } + + return gnode; +} + +/* note: ungroup: group_indices zero! */ + +/* here's a nasty little one, need to check users... */ +/* should become callbackable... */ +void nodeVerifyGroup(bNodeTree *ngroup) +{ + + /* group changed, so we rebuild the type definition */ + ntreeMakeOwnType(ngroup); + + if(ngroup->type==NTREE_SHADER) { + Material *ma; + for(ma= G.main->mat.first; ma; ma= ma->id.next) { + if(ma->nodetree) { + bNode *node; + + /* find if group is in tree */ + for(node= ma->nodetree->nodes.first; node; node= node->next) + if(node->id == (ID *)ngroup) + break; + + if(node) { + /* set all type pointers OK */ + ntreeInitTypes(ma->nodetree); + + for(node= ma->nodetree->nodes.first; node; node= node->next) + if(node->id == (ID *)ngroup) + nodeVerifyType(ma->nodetree, node); + } + } + } + } + else if(ngroup->type==NTREE_COMPOSIT) { + Scene *sce; + for(sce= G.main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + + /* find if group is in tree */ + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->id == (ID *)ngroup) + break; + + if(node) { + /* set all type pointers OK */ + ntreeInitTypes(sce->nodetree); + + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->id == (ID *)ngroup) + nodeVerifyType(sce->nodetree, node); + } + } + } + } +} + +/* also to check all users of groups. Now only used in editor for hide/unhide */ +/* should become callbackable? */ +void nodeGroupSocketUseFlags(bNodeTree *ngroup) +{ + bNode *node; + bNodeSocket *sock; + + /* clear flags */ + for(node= ngroup->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_IN_USE; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_IN_USE; + } + + /* tag all thats in use */ + if(ngroup->type==NTREE_SHADER) { + Material *ma; + for(ma= G.main->mat.first; ma; ma= ma->id.next) { + if(ma->nodetree) { + for(node= ma->nodetree->nodes.first; node; node= node->next) { + if(node->id==(ID *)ngroup) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->link) + if(sock->tosock) + sock->tosock->flag |= SOCK_IN_USE; + for(sock= node->outputs.first; sock; sock= sock->next) + if(nodeCountSocketLinks(ma->nodetree, sock)) + if(sock->tosock) + sock->tosock->flag |= SOCK_IN_USE; + } + } + } + } + } + else if(ngroup->type==NTREE_COMPOSIT) { + Scene *sce; + for(sce= G.main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) { + for(node= sce->nodetree->nodes.first; node; node= node->next) { + if(node->id==(ID *)ngroup) { + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->link) + if(sock->tosock) + sock->tosock->flag |= SOCK_IN_USE; + for(sock= node->outputs.first; sock; sock= sock->next) + if(nodeCountSocketLinks(sce->nodetree, sock)) + if(sock->tosock) + sock->tosock->flag |= SOCK_IN_USE; + } + } + } + } + } +} + +static void find_node_with_socket(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex) +{ + bNode *node; + bNodeSocket *tsock; + int index; + + for(node= ntree->nodes.first; node; node= node->next) { + for(index=0, tsock= node->inputs.first; tsock; tsock= tsock->next, index++) + if(tsock==sock) + break; + if(tsock) + break; + for(index=0, tsock= node->outputs.first; tsock; tsock= tsock->next, index++) + if(tsock==sock) + break; + if(tsock) + break; + } + if(node) { + *nodep= node; + *sockindex= index; + } + else { + *nodep= NULL; + } +} + +/* returns 1 if its OK */ +int nodeGroupUnGroup(bNodeTree *ntree, bNode *gnode) +{ + bNodeLink *link, *linkn; + bNode *node, *nextn; + bNodeTree *ngroup, *wgroup; + int index; + + ngroup= (bNodeTree *)gnode->id; + if(ngroup==NULL) return 0; + + /* clear new pointers, set in copytree */ + for(node= ntree->nodes.first; node; node= node->next) + node->new= NULL; + + wgroup= ntreeCopyTree(ngroup, 0); + + /* add the nodes into the ntree */ + for(node= wgroup->nodes.first; node; node= nextn) { + nextn= node->next; + BLI_remlink(&wgroup->nodes, node); + BLI_addtail(&ntree->nodes, node); + node->locx+= gnode->locx; + node->locy+= gnode->locy; + node->flag |= NODE_SELECT; + } + /* and the internal links */ + for(link= wgroup->links.first; link; link= linkn) { + linkn= link->next; + BLI_remlink(&wgroup->links, link); + BLI_addtail(&ntree->links, link); + } + + /* restore links to and from the gnode */ + for(link= ntree->links.first; link; link= link->next) { + if(link->tonode==gnode) { + /* link->tosock->tosock is on the node we look for */ + find_node_with_socket(ngroup, link->tosock->tosock, &nextn, &index); + if(nextn==NULL) printf("wrong stuff!\n"); + else if(nextn->new==NULL) printf("wrong stuff too!\n"); + else { + link->tonode= nextn->new; + link->tosock= BLI_findlink(&link->tonode->inputs, index); + } + } + else if(link->fromnode==gnode) { + /* link->fromsock->tosock is on the node we look for */ + find_node_with_socket(ngroup, link->fromsock->tosock, &nextn, &index); + if(nextn==NULL) printf("1 wrong stuff!\n"); + else if(nextn->new==NULL) printf("1 wrong stuff too!\n"); + else { + link->fromnode= nextn->new; + link->fromsock= BLI_findlink(&link->fromnode->outputs, index); + } + } + } + + /* remove the gnode & work tree */ + ntreeFreeTree(wgroup); + MEM_freeN(wgroup); + + nodeFreeNode(ntree, gnode); + + return 1; +} + +#pragma mark /* ************** Add stuff ********** */ + +bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup) +{ + bNode *node; + bNodeType *ntype= node_get_type(ntree, type, ngroup); + bNodeSocketType *stype; + + node= MEM_callocN(sizeof(bNode), "new node"); + BLI_addtail(&ntree->nodes, node); + node->typeinfo= ntype; + + BLI_strncpy(node->name, ntype->name, NODE_MAXSTR); + node->type= ntype->type; + node->flag= NODE_SELECT|ntype->flag; + node->width= ntype->width; + node->miniwidth= 15.0f; /* small value only, allows print of first chars */ + + if(type==NODE_GROUP) + node->id= (ID *)ngroup; + + if(ntype->inputs) { + stype= ntype->inputs; + while(stype->type != -1) { + node_add_socket_type(&node->inputs, stype); + stype++; + } + } + if(ntype->outputs) { + stype= ntype->outputs; + while(stype->type != -1) { + node_add_socket_type(&node->outputs, stype); + stype++; + } + } + + /* need init handler later? */ + if(ntree->type==NTREE_SHADER) { + if(type==SH_NODE_MATERIAL) + node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC; + else if(type==SH_NODE_VALTORGB) + node->storage= add_colorband(1); + else if(type==SH_NODE_MAPPING) + node->storage= add_mapping(); + else if(type==SH_NODE_CURVE_VEC) + node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); + else if(type==SH_NODE_CURVE_RGB) + node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); + } + else if(ntree->type==NTREE_COMPOSIT) { + if(type==CMP_NODE_VALTORGB) + node->storage= add_colorband(1); + else if(type==CMP_NODE_CURVE_VEC) + node->storage= curvemapping_add(3, -1.0f, -1.0f, 1.0f, 1.0f); + else if(type==CMP_NODE_CURVE_RGB) + node->storage= curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); + else if(type==CMP_NODE_MAP_VALUE) + node->storage= add_mapping(); + } + + return node; +} + +/* keep socket listorder identical, for copying links */ +/* ntree is the target tree */ +bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node) +{ + bNode *nnode= MEM_callocN(sizeof(bNode), "dupli node"); + bNodeSocket *sock; + + *nnode= *node; + BLI_addtail(&ntree->nodes, nnode); + + duplicatelist(&nnode->inputs, &node->inputs); + for(sock= nnode->inputs.first; sock; sock= sock->next) + sock->own_index= 0; + + duplicatelist(&nnode->outputs, &node->outputs); + for(sock= nnode->outputs.first; sock; sock= sock->next) { + sock->own_index= 0; + sock->ns.data= NULL; + } + + if(nnode->id) + nnode->id->us++; + + if(nnode->storage) { + /* another candidate for handlerizing! */ + if(ntree->type==NTREE_SHADER) { + if(node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) + nnode->storage= curvemapping_copy(node->storage); + else + nnode->storage= MEM_dupallocN(nnode->storage); + } + else if(ntree->type==NTREE_COMPOSIT) { + if(node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB) + nnode->storage= curvemapping_copy(node->storage); + else + nnode->storage= MEM_dupallocN(nnode->storage); + } + else + nnode->storage= MEM_dupallocN(nnode->storage); + } + + node->new= nnode; + nnode->new= NULL; + nnode->preview= NULL; + + return nnode; +} + +bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock) +{ + bNodeLink *link= MEM_callocN(sizeof(bNodeLink), "link"); + + BLI_addtail(&ntree->links, link); + link->fromnode= fromnode; + link->fromsock= fromsock; + link->tonode= tonode; + link->tosock= tosock; + + return link; +} + +void nodeRemLink(bNodeTree *ntree, bNodeLink *link) +{ + BLI_remlink(&ntree->links, link); + if(link->tosock) + link->tosock->link= NULL; + MEM_freeN(link); +} + + +bNodeTree *ntreeAddTree(int type) +{ + bNodeTree *ntree= MEM_callocN(sizeof(bNodeTree), "new node tree"); + ntree->type= type; + + ntreeInitTypes(ntree); + return ntree; +} + +#pragma mark /* ************** Free stuff ********** */ + +/* goes over entire tree */ +static void node_unlink_node(bNodeTree *ntree, bNode *node) +{ + bNodeLink *link, *next; + bNodeSocket *sock; + ListBase *lb; + + for(link= ntree->links.first; link; link= next) { + next= link->next; + + if(link->fromnode==node) { + lb= &node->outputs; + NodeTagChanged(ntree, link->tonode); + } + else if(link->tonode==node) + lb= &node->inputs; + else + lb= NULL; + + if(lb) { + for(sock= lb->first; sock; sock= sock->next) { + if(link->fromsock==sock || link->tosock==sock) + break; + } + if(sock) { + nodeRemLink(ntree, link); + } + } + } +} + +static void composit_free_sockets(bNode *node) +{ + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->ns.data) + free_compbuf(sock->ns.data); + } +} + +void nodeFreeNode(bNodeTree *ntree, bNode *node) +{ + node_unlink_node(ntree, node); + BLI_remlink(&ntree->nodes, node); + + if(node->id) + node->id->us--; + + if(ntree->type==NTREE_COMPOSIT) + composit_free_sockets(node); + BLI_freelistN(&node->inputs); + BLI_freelistN(&node->outputs); + + if(node->preview) { + if(node->preview->rect) + MEM_freeN(node->preview->rect); + MEM_freeN(node->preview); + } + if(node->storage) { + /* could be handlerized at some point, now only 1 exception still */ + if(ntree->type==NTREE_SHADER) { + if(node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) + curvemapping_free(node->storage); + else + MEM_freeN(node->storage); + } + else if(ntree->type==NTREE_COMPOSIT) { + if(node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB) + curvemapping_free(node->storage); + else + MEM_freeN(node->storage); + } + else + MEM_freeN(node->storage); + } + MEM_freeN(node); +} + +/* do not free ntree itself here, free_libblock calls this function too */ +void ntreeFreeTree(bNodeTree *ntree) +{ + bNode *node, *next; + + if(ntree==NULL) return; + + BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */ + + for(node= ntree->nodes.first; node; node= next) { + next= node->next; + nodeFreeNode(ntree, node); + } + + if(ntree->owntype) { + if(ntree->owntype->inputs) + MEM_freeN(ntree->owntype->inputs); + if(ntree->owntype->outputs) + MEM_freeN(ntree->owntype->outputs); + MEM_freeN(ntree->owntype); + } +} + +bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select) +{ + bNodeTree *newtree; + bNode *node, *nnode, *last; + bNodeLink *link, *nlink; + bNodeSocket *sock; + int a; + + if(ntree==NULL) return NULL; + + if(internal_select==0) { + newtree= MEM_dupallocN(ntree); + newtree->nodes.first= newtree->nodes.last= NULL; + newtree->links.first= newtree->links.last= NULL; + } + else + newtree= ntree; + + last= ntree->nodes.last; + for(node= ntree->nodes.first; node; node= node->next) { + + node->new= NULL; + if(internal_select==0 || (node->flag & NODE_SELECT)) { + nnode= nodeCopyNode(newtree, node); /* sets node->new */ + if(internal_select) { + node->flag &= ~NODE_SELECT; + nnode->flag |= NODE_SELECT; + } + node->flag &= ~NODE_ACTIVE; + } + if(node==last) break; + } + + /* check for copying links */ + for(link= ntree->links.first; link; link= link->next) { + if(link->fromnode->new && link->tonode->new) { + nlink= nodeAddLink(newtree, link->fromnode->new, NULL, link->tonode->new, NULL); + /* sockets were copied in order */ + for(a=0, sock= link->fromnode->outputs.first; sock; sock= sock->next, a++) { + if(sock==link->fromsock) + break; + } + nlink->fromsock= BLI_findlink(&link->fromnode->new->outputs, a); + + for(a=0, sock= link->tonode->inputs.first; sock; sock= sock->next, a++) { + if(sock==link->tosock) + break; + } + nlink->tosock= BLI_findlink(&link->tonode->new->inputs, a); + } + } + + /* own type definition for group usage */ + if(internal_select==0) { + if(ntree->owntype) { + newtree->owntype= MEM_dupallocN(ntree->owntype); + if(ntree->owntype->inputs) + newtree->owntype->inputs= MEM_dupallocN(ntree->owntype->inputs); + if(ntree->owntype->outputs) + newtree->owntype->outputs= MEM_dupallocN(ntree->owntype->outputs); + } + } + return newtree; +} + +#pragma mark /* ************ find stuff *************** */ + +bNodeLink *nodeFindLink(bNodeTree *ntree, bNodeSocket *from, bNodeSocket *to) +{ + bNodeLink *link; + + for(link= ntree->links.first; link; link= link->next) { + if(link->fromsock==from && link->tosock==to) + return link; + if(link->fromsock==to && link->tosock==from) /* hrms? */ + return link; + } + return NULL; +} + +int nodeCountSocketLinks(bNodeTree *ntree, bNodeSocket *sock) +{ + bNodeLink *link; + int tot= 0; + + for(link= ntree->links.first; link; link= link->next) { + if(link->fromsock==sock || link->tosock==sock) + tot++; + } + return tot; +} + +bNode *nodeGetActive(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return NULL; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_ACTIVE) + break; + return node; +} + +/* two active flags, ID nodes have special flag for buttons display */ +bNode *nodeGetActiveID(bNodeTree *ntree, short idtype) +{ + bNode *node; + + if(ntree==NULL) return NULL; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->id && GS(node->id->name)==idtype) + if(node->flag & NODE_ACTIVE_ID) + break; + return node; +} + +/* two active flags, ID nodes have special flag for buttons display */ +void nodeClearActiveID(bNodeTree *ntree, short idtype) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->id && GS(node->id->name)==idtype) + node->flag &= ~NODE_ACTIVE_ID; +} + +/* two active flags, ID nodes have special flag for buttons display */ +void nodeSetActive(bNodeTree *ntree, bNode *node) +{ + bNode *tnode; + + /* make sure only one node is active, and only one per ID type */ + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { + tnode->flag &= ~NODE_ACTIVE; + + if(node->id && tnode->id) { + if(GS(node->id->name) == GS(tnode->id->name)) + tnode->flag &= ~NODE_ACTIVE_ID; + } + } + + node->flag |= NODE_ACTIVE; + if(node->id) + node->flag |= NODE_ACTIVE_ID; +} + +/* use flags are not persistant yet, groups might need different tagging, so we do it each time + when we need to get this info */ +void ntreeSocketUseFlags(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + /* clear flags */ + for(node= ntree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_IN_USE; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_IN_USE; + } + + /* tag all thats in use */ + for(link= ntree->links.first; link; link= link->next) { + link->fromsock->flag |= SOCK_IN_USE; + link->tosock->flag |= SOCK_IN_USE; + } +} + +#pragma mark /* ************** dependency stuff *********** */ + +/* node is guaranteed to be not checked before */ +static int node_recurs_check(bNode *node, bNode ***nsort, int level) +{ + bNode *fromnode; + bNodeSocket *sock; + int has_inputlinks= 0; + + node->done= 1; + level++; + + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link) { + has_inputlinks= 1; + fromnode= sock->link->fromnode; + if(fromnode->done==0) { + fromnode->level= node_recurs_check(fromnode, nsort, level); + } + } + } +// printf("node sort %s level %d\n", node->name, level); + **nsort= node; + (*nsort)++; + + if(has_inputlinks) + return level; + else + return 0xFFF; +} + +void ntreeSolveOrder(bNodeTree *ntree) +{ + bNode *node, **nodesort, **nsort; + bNodeSocket *sock; + bNodeLink *link; + int a, totnode=0; + + /* the solve-order is called on each tree change, so we should be sure no exec can be running */ + ntreeEndExecTree(ntree); + + /* set links pointers the input sockets, to find dependencies */ + /* first clear data */ + for(node= ntree->nodes.first; node; node= node->next) { + node->done= 0; + totnode++; + for(sock= node->inputs.first; sock; sock= sock->next) + sock->link= NULL; + } + if(totnode==0) + return; + + for(link= ntree->links.first; link; link= link->next) { + link->tosock->link= link; + } + + nsort= nodesort= MEM_callocN(totnode*sizeof(void *), "sorted node array"); + + /* recursive check */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->done==0) { + node->level= node_recurs_check(node, &nsort, 0); + } + } + + /* re-insert nodes in order, first a paranoia check */ + for(a=0; anodes.first= ntree->nodes.last= NULL; + for(a=0; anodes, nodesort[a]); + } + + MEM_freeN(nodesort); + + /* find the active outputs, might become tree type dependant handler */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + bNode *tnode; + int output= 0; + /* there is more types having output class, each one is checked */ + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { + if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { + if(tnode->type==node->type) { + if(tnode->flag & NODE_DO_OUTPUT) { + if(output>1) + tnode->flag &= ~NODE_DO_OUTPUT; + output++; + } + } + } + } + if(output==0) + node->flag |= NODE_DO_OUTPUT; + } + } + + /* here we could recursively set which nodes have to be done, + might be different for editor or for "real" use... */ +} + +/* should be callback! */ +void NodeTagChanged(bNodeTree *ntree, bNode *node) +{ + if(ntree->type==NTREE_COMPOSIT) { + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->ns.data) { + free_compbuf(sock->ns.data); + sock->ns.data= NULL; + } + } + node->need_exec= 1; + } +} + +#pragma mark /* *************** preview *********** */ + +/* if node->preview, then we assume the rect to exist */ + +static void nodeInitPreview(bNode *node, int xsize, int ysize) +{ + + if(node->preview==NULL) { + node->preview= MEM_callocN(sizeof(bNodePreview), "node preview"); + printf("added preview %s\n", node->name); + } + + /* node previews can get added with variable size this way */ + if(xsize==0 || ysize==0) + return; + + /* sanity checks & initialize */ + if(node->preview && node->preview->rect) { + if(node->preview->xsize!=xsize && node->preview->ysize!=ysize) { + MEM_freeN(node->preview->rect); + node->preview->rect= NULL; + } + } + + 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 ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize) +{ + bNode *node; + + if(ntree==NULL) + return; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->flag & NODE_PREVIEW) /* hrms, check for closed nodes? */ + nodeInitPreview(node, xsize, ysize); + if(node->type==NODE_GROUP && (node->flag & NODE_GROUP_EDIT)) + ntreeInitPreview((bNodeTree *)node->id, xsize, ysize); + } +} + +void nodeAddToPreview(bNode *node, float *col, int x, int y) +{ + bNodePreview *preview= node->preview; + if(preview) { + if(x>=0 && y>=0) { + if(xxsize && yysize) { + float *tar= preview->rect+ 4*((preview->xsize*y) + x); + QUATCOPY(tar, col); + } + else printf("prv out bound x y %d %d\n", x, y); + } + else printf("prv out bound x y %d %d\n", x, y); + } +} + + + +#pragma mark /* ******************* executing ************* */ + +/* see notes at ntreeBeginExecTree */ +static void group_node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out, bNodeStack **gin, bNodeStack **gout) +{ + bNodeSocket *sock; + + /* build pointer stack */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->intern) { + /* yep, intern can have link or is hidden socket */ + if(sock->link) + *(in++)= stack + sock->link->fromsock->stack_index; + else + *(in++)= &sock->ns; + } + else + *(in++)= gin[sock->stack_index_ext]; + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->intern) + *(out++)= stack + sock->stack_index; + else + *(out++)= gout[sock->stack_index_ext]; + } +} + +static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNodeStack **in, bNodeStack **out) +{ + bNode *node; + bNodeTree *ntree= (bNodeTree *)gnode->id; + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + + if(ntree==NULL) return; + + stack+= gnode->stack_index; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->execfunc) { + group_node_get_stack(node, stack, nsin, nsout, in, out); + node->typeinfo->execfunc(data, node, nsin, nsout); + } + } +} + +/* recursively called for groups */ +/* we set all trees on own local indices, but put a total counter + in the groups, so each instance of a group has own stack */ +static int ntree_begin_exec_tree(bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + int index= 0, index_in= 0, index_out= 0; + + if((ntree->init & NTREE_TYPE_INIT)==0) + ntreeInitTypes(ntree); + + /* create indices for stack, check preview */ + for(node= ntree->nodes.first; node; node= node->next) { + + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->intern==0) + sock->stack_index_ext= index_in++; + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + sock->stack_index= index++; + if(sock->intern==0) + sock->stack_index_ext= index_out++; + } + + if(node->type==NODE_GROUP) { + if(node->id) { + + node->stack_index= index; + index+= ntree_begin_exec_tree((bNodeTree *)node->id); + + /* copy internal data from internal nodes to own input sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->tosock) { + sock->ns= sock->tosock->ns; + } + } + } + } + } + + return index; +} + +/* copy socket compbufs to stack */ +static void composit_begin_exec(bNodeTree *ntree) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) { + bNodeSocket *sock; + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->ns.data) { + bNodeStack *ns= ntree->stack + sock->stack_index; + + ns->data= sock->ns.data; + sock->ns.data= NULL; + } + } + } +} + +/* copy stack compbufs to sockets */ +static void composit_end_exec(bNodeTree *ntree) +{ + extern void print_compbuf(char *str, struct CompBuf *cbuf); + bNode *node; + bNodeStack *ns; + int a; + + for(node= ntree->nodes.first; node; node= node->next) { + bNodeSocket *sock; + + for(sock= node->outputs.first; sock; sock= sock->next) { + ns= ntree->stack + sock->stack_index; + if(ns->data) { + sock->ns.data= ns->data; + ns->data= NULL; + } + } + node->need_exec= 0; + } + + for(ns= ntree->stack, a=0; astacksize; a++, ns++) { + if(ns->data) { + print_compbuf("error: buf hanging in stack", ns->data); + free_compbuf(ns->data); + } + } + +} + +/* stack indices make sure all nodes only write in allocated data, for making it thread safe */ +/* only root tree gets the stack, to enable instances to have own stack entries */ +/* only two threads now! */ +/* per tree (and per group) unique indices are created */ +/* the index_ext we need to be able to map from groups to the group-node own stack */ + +void ntreeBeginExecTree(bNodeTree *ntree) +{ + + /* goes recursive over all groups */ + ntree->stacksize= ntree_begin_exec_tree(ntree); + + if(ntree->stacksize) { + bNode *node; + bNodeStack *ns; + int a; + + /* allocate stack */ + ns=ntree->stack= MEM_callocN(ntree->stacksize*sizeof(bNodeStack), "node stack"); + + /* tag inputs, the get_stack() gives own socket stackdata if not in use */ + for(a=0; astacksize; a++, ns++) ns->hasinput= 1; + + /* tag used outputs, so we know when we can skip operations */ + /* hrms... groups... */ + for(node= ntree->nodes.first; node; node= node->next) { + bNodeSocket *sock; + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link) { + ns= ntree->stack + sock->link->fromsock->stack_index; + ns->hasoutput= 1; + } + } + } + if(ntree->type==NTREE_COMPOSIT) + composit_begin_exec(ntree); + else + ntree->stack1= MEM_dupallocN(ntree->stack); + } + + ntree->init |= NTREE_EXEC_INIT; +} + +void ntreeEndExecTree(bNodeTree *ntree) +{ + + if(ntree->init & NTREE_EXEC_INIT) { + + /* another callback candidate! */ + if(ntree->type==NTREE_COMPOSIT) + composit_end_exec(ntree); + + if(ntree->stack) + MEM_freeN(ntree->stack); + ntree->stack= NULL; + + if(ntree->stack1) + MEM_freeN(ntree->stack1); + ntree->stack1= NULL; + + ntree->init &= ~NTREE_EXEC_INIT; + } +} + +static void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock; + + /* build pointer stack */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link) + *(in++)= stack + sock->link->fromsock->stack_index; + else + *(in++)= &sock->ns; + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + *(out++)= stack + sock->stack_index; + } +} + +/* nodes are presorted, so exec is in order of list */ +void ntreeExecTree(bNodeTree *ntree, void *callerdata, int thread) +{ + bNode *node; + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *stack; + + /* only when initialized */ + if((ntree->init & NTREE_EXEC_INIT)==0) + ntreeBeginExecTree(ntree); + + if(thread) + stack= ntree->stack1; + else + stack= ntree->stack; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->execfunc) { + node_get_stack(node, stack, nsin, nsout); + node->typeinfo->execfunc(callerdata, node, nsin, nsout); + } + else if(node->type==NODE_GROUP && node->id) { + node_get_stack(node, stack, nsin, nsout); + node_group_execute(stack, callerdata, node, nsin, nsout); + } + } +} + +/* optimized tree execute test for compositing */ +void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview) +{ + bNode *node; + bNodeSocket *sock; + bNodeStack *nsin[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *nsout[MAX_SOCKET]; /* arbitrary... watch this */ + bNodeStack *stack; + int totnode; + + if(ntree==NULL) return; + + totnode= BLI_countlist(&ntree->nodes); + + if(do_preview) + ntreeInitPreview(ntree, 0, 0); + + ntreeBeginExecTree(ntree); + + stack= ntree->stack; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->execfunc) { + int a; + + node_get_stack(node, stack, nsin, nsout); + + /* test the inputs */ + for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { + /* is sock in use? */ + if(sock->link) { + if(nsin[a]->data==NULL || sock->link->fromnode->need_exec) { + node->need_exec= 1; + break; + } + } + } + + /* test the outputs */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->data==NULL && nsout[a]->hasoutput) { + node->need_exec= 1; + break; + } + } + if(node->need_exec) { + + /* free output buffers */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(nsout[a]->data) { + free_compbuf(nsout[a]->data); + nsout[a]->data= NULL; + } + } + if(ntree->timecursor) + ntree->timecursor(totnode); + + printf("exec node %s\n", node->name); + node->typeinfo->execfunc(rd, node, nsin, nsout); + } + } + else if(node->type==NODE_GROUP && node->id) { + node_get_stack(node, stack, nsin, nsout); + node_group_execute(stack, rd, node, nsin, nsout); + } + totnode--; + } + + + ntreeEndExecTree(ntree); + + free_unused_animimages(); + +} + diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c new file mode 100644 index 00000000000..bcb3e9e600d --- /dev/null +++ b/source/blender/blenkernel/intern/node_composite.c @@ -0,0 +1,1854 @@ +/** + * $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): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "DNA_ID.h" +#include "DNA_image_types.h" +#include "DNA_node_types.h" +#include "DNA_material_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_vec_types.h" + +#include "BKE_blender.h" +#include "BKE_colortools.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_node.h" +#include "BKE_material.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "MEM_guardedalloc.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "RE_pipeline.h" + +/* *************************** operations support *************************** */ + +/* general signal that's in output sockets, and goes over the wires */ +typedef struct CompBuf { + float *rect; + int x, y; + short type, malloc; + rcti disprect; /* cropped part of image */ + int xof, yof; /* relative to center of target image */ +} CompBuf; + +/* defines also used for pixel size */ +#define CB_RGBA 4 +#define CB_VAL 1 + +static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc) +{ + CompBuf *cbuf= MEM_callocN(sizeof(CompBuf), "compbuf"); + + cbuf->x= sizex; + cbuf->y= sizey; + cbuf->type= type; + if(alloc) { + if(cbuf->type==CB_RGBA) + cbuf->rect= MEM_mallocN(4*sizeof(float)*sizex*sizey, "compbuf RGBA rect"); + else + cbuf->rect= MEM_mallocN(sizeof(float)*sizex*sizey, "compbuf Fac rect"); + cbuf->malloc= 1; + } + cbuf->disprect.xmin= 0; + cbuf->disprect.ymin= 0; + cbuf->disprect.xmax= sizex; + cbuf->disprect.ymax= sizey; + + return cbuf; +} + +void free_compbuf(CompBuf *cbuf) +{ + if(cbuf->malloc && cbuf->rect) + MEM_freeN(cbuf->rect); + MEM_freeN(cbuf); +} + +void print_compbuf(char *str, CompBuf *cbuf) +{ + printf("Compbuf %s %d %d %p\n", str, cbuf->x, cbuf->y, cbuf->rect); + +} + + + +#if 0 +/* on first call, disprect should be initialized to 'out', then you can call this on all 'src' images */ +static void get_overlap_rct(CompBuf *out, CompBuf *src, rcti *disprect) +{ + rcti rect; + /* output center is considered (0,0) */ + + if(src==NULL) return; + + /* translate src into output space */ + rect= src->disprect; + BLI_translate_rcti(&rect, out->xof-src->xof, out->xof-src->xof); + /* intersect rect with current disprect */ + + BLI_isect_rcti(&rect, disprect, disprect); +} + +static void get_scanline_rcti(CompBuf *out, rcti *disprect, CompBuf *src, rcti *srcrect) +{ + int xof, yof; + + /* translate src into output space */ + xof= out->xof-src->xof; + yof= out->xof-src->xof; + + srcrect->xmin= disprect->xmin + xof; + srcrect->ymin= disprect->ymin + yof; + srcrect->xmax= disprect->xmax + xof; + srcrect->ymax= disprect->ymax + yof; +} +#endif + +/* Pixel-to-Pixel operation, 1 Image in, 1 out */ +static void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col, + void (*func)(bNode *, float *, float *)) +{ + float *outfp, *srcfp, *out_data, *src_data; + int outx, outy; + int srcx, srcy; + int out_pix, out_stride, src_stride, src_pix, x, y; + + outx= out->x; + outy= out->y; + out_pix= out->type; + out_stride= out->x; + out_data= out->rect; + + /* handle case when input is constant color */ + if(src_buf==NULL) { + srcx= outx; srcy= outy; + src_stride= 0; + src_pix= 0; + src_data= src_col; + } + else { + srcx= src_buf->x; + srcy= src_buf->y; + src_stride= srcx; + src_pix= src_buf->type; + src_data= src_buf->rect; + } + + outx= MIN2(outx, srcx); + outy= MIN2(outy, srcy); + + for(y=0; yx, outy= out->y; + int srcx, srcy, facx, facy; + int out_pix, src_stride, src_pix, fac_stride, fac_pix, x, y; + + out_pix= out->type; + + /* handle case when input is constant color */ + if(src_buf==NULL) { + srcx= outx; srcy= outy; + src_stride= 0; + src_pix= 0; + src_data= src_col; + } + else { + srcx= src_buf->x; + srcy= src_buf->y; + src_stride= srcx; + src_pix= src_buf->type; + src_data= src_buf->rect; + } + + /* factor buf or constant? */ + if(fac_buf==NULL) { + facx= outx; facy= outy; + fac_stride= 0; + fac_pix= 0; + fac_data= fac; + } + else { + facx= fac_buf->x; + facy= fac_buf->y; + fac_stride= facx; + fac_pix= fac_buf->type; + fac_data= fac_buf->rect; + } + + if(fac_data==NULL) { + printf("fac buffer error, node %s\n", node->name); + return; + } + + facx= MIN2(facx, srcx); + facy= MIN2(facy, srcy); + +#if 0 + if(src_buf) { + rcti disprect; + + disprect= out->disprect; + get_overlap_rct(out, src_buf, &disprect); + printf("%s\n", node->name); + printf("union %d %d %d %d\n", disprect.xmin,disprect.ymin,disprect.xmax,disprect.ymax); + } + /* new approach */ + outfp= out->rect_float + src.ymin*outx + ; + for(y=src.ymin; y=disp.ymin && y=disp.xmin && xrect; + for(y=0; yx, outy= out->y; + int src1x, src1y, src2x, src2y, facx, facy; + int src1_stride, src1_pix, src2_stride, src2_pix, fac_stride, fac_pix, x, y; + + /* handle case when input has constant color */ + if(src1_buf==NULL) { + src1x= outx; src1y= outy; + src1_stride= 0; + src1_pix= 0; + src1_data= src1_col; + } + else { + src1x= src1_buf->x; + src1y= src1_buf->y; + src1_stride= src1x; + src1_pix= src1_buf->type; + src1_data= src1_buf->rect; + } + + if(src2_buf==NULL) { + src2x= outx; src2y= outy; + src2_stride= 0; + src2_pix= 0; + src2_data= src2_col; + } + else { + src2x= src2_buf->x; + src2y= src2_buf->y; + src2_stride= src2x; + src2_pix= src2_buf->type; + src2_data= src2_buf->rect; + } + + /* factor buf or constant? */ + if(fac_buf==NULL) { + facx= outx; facy= outy; + fac_stride= 0; + fac_pix= 0; + fac_data= &fac; + } + else { + facx= fac_buf->x; + facy= fac_buf->y; + fac_stride= facx; + fac_pix= 1; + fac_data= fac_buf->rect; + } + + facx= MIN3(facx, src1x, src2x); + facy= MIN3(facy, src1y, src2y); + + outfp= out->rect; + for(y=0; yx, cbuf->y, CB_VAL, 1); + float *valf, *rectf; + int tot; + + valf= valbuf->rect; + rectf= cbuf->rect + 3; + for(tot= cbuf->x*cbuf->y; tot>0; tot--, valf++, rectf+=4) + *valf= *rectf; + + return valbuf; +} + +static void generate_preview(bNode *node, CompBuf *stackbuf) +{ + bNodePreview *preview= node->preview; + + if(preview) { + ImBuf *ibuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0, 0); /* empty */ + + if(stackbuf->x > stackbuf->y) { + preview->xsize= 140; + preview->ysize= (140*stackbuf->y)/stackbuf->x; + } + else { + preview->ysize= 140; + preview->xsize= (140*stackbuf->x)/stackbuf->y; + } + ibuf->rect_float= stackbuf->rect; + ibuf= IMB_scalefastImBuf(ibuf, preview->xsize, preview->ysize); + + /* this ensures free-imbuf does the right stuff */ + SWAP(float *, ibuf->rect_float, node->preview->rect); + + IMB_freeImBuf(ibuf); + } +} + +/* ******************************************************** */ +/* ********* Composit Node type definitions ***************** */ +/* ******************************************************** */ + +/* SocketType syntax: + socket type, max connections (0 is no limit), name, 4 values for default, 2 values for range */ + +/* Verification rule: If name changes, a saved socket and its links will be removed! Type changes are OK */ + +/* **************** VIEWER ******************** */ +static bNodeSocketType cmp_node_viewer_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_copy_rgba(bNode *node, float *out, float *in) +{ + QUATCOPY(out, in); +} +static void do_copy_value(bNode *node, float *out, float *in) +{ + out[0]= in[0]; +} +static void do_copy_a_rgba(bNode *node, float *out, float *in, float *fac) +{ + VECCOPY(out, in); + out[3]= *fac; +} + +static void node_composit_exec_viewer(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* image assigned to output */ + /* stack order input sockets: col, alpha, z */ + + if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + Image *ima= (Image *)node->id; + CompBuf *cbuf; + int rectx, recty; + + /* scene size? */ + if(1) { + RenderData *rd= data; + + /* re-create output, derive size from scene */ + rectx= (rd->size*rd->xsch)/100; + recty= (rd->size*rd->ysch)/100; + + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + ima->ibuf= IMB_allocImBuf(rectx, recty, 32, IB_rectfloat, 0); // do alloc + + cbuf= alloc_compbuf(rectx, recty, CB_RGBA, 0); // no alloc + cbuf->rect= ima->ibuf->rect_float; + + /* when no alpha, we can simply copy */ + if(in[1]->data==NULL) + composit1_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, do_copy_rgba); + else + composit2_pixel_processor(node, cbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba); + + if(in[2]->data) { + CompBuf *zbuf= alloc_compbuf(rectx, recty, CB_VAL, 0); + addzbuffloatImBuf(ima->ibuf); + zbuf->rect= ima->ibuf->zbuf_float; + composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value); + free_compbuf(zbuf); + } + + generate_preview(node, cbuf); + free_compbuf(cbuf); + } + else { /* test */ + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + ima->ibuf= IMB_allocImBuf(rectx, recty, 32, 0, 0); // do alloc + ima->ibuf->mall= IB_rectfloat; + cbuf= in[0]->data; + ima->ibuf->rect_float= cbuf->rect; + ima->ibuf->x= cbuf->x; + ima->ibuf->y= cbuf->y; + cbuf->rect= NULL; + } + + } /* lets make only previews when not done yet, so activating doesnt update */ + else if(in[0]->data && node->preview && node->preview->rect==NULL) + generate_preview(node, in[0]->data); +} + +static bNodeType cmp_node_viewer= { + /* type code */ CMP_NODE_VIEWER, + /* name */ "Viewer", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, + /* input sock */ cmp_node_viewer_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_viewer + +}; + +/* **************** COMPOSITE ******************** */ +static bNodeSocketType cmp_node_composite_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +/* applies to render pipeline */ +static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* image assigned to output */ + /* stack order input sockets: col, alpha, z */ + + if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */ + RenderData *rd= data; + if(rd->scemode & R_DOCOMP) { + RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + if(rr) { + CompBuf *outbuf, *zbuf=NULL; + + if(rr->rectf) + MEM_freeN(rr->rectf); + outbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 1); + + if(in[1]->data==NULL) + composit1_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, do_copy_rgba); + else + composit2_pixel_processor(node, outbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_copy_a_rgba); + + if(in[2]->data) { + if(rr->rectz) + MEM_freeN(rr->rectz); + zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 1); + composit1_pixel_processor(node, zbuf, in[2]->data, in[2]->vec, do_copy_value); + rr->rectz= zbuf->rect; + zbuf->malloc= 0; + free_compbuf(zbuf); + } + generate_preview(node, outbuf); + + /* we give outbuf to rr... */ + rr->rectf= outbuf->rect; + outbuf->malloc= 0; + free_compbuf(outbuf); + + return; + } + } + } + if(in[0]->data) + generate_preview(node, in[0]->data); +} + +static bNodeType cmp_node_composite= { + /* type code */ CMP_NODE_COMPOSITE, + /* name */ "Composite", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, + /* input sock */ cmp_node_composite_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_composite + +}; + +/* **************** OUTPUT FILE ******************** */ +static bNodeSocketType cmp_node_output_file_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + + +static void node_composit_exec_output_file(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* image assigned to output */ + /* stack order input sockets: col, alpha */ + + if(node->id && (node->flag & NODE_DO_OUTPUT)) { /* only one works on out */ + } + else if(in[0]->data) + generate_preview(node, in[0]->data); +} + +static bNodeType cmp_node_output_file= { + /* type code */ CMP_NODE_OUTPUT_FILE, + /* name */ "File Output", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_FILE, NODE_PREVIEW, + /* input sock */ cmp_node_output_file_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_composit_exec_output_file + +}; + +/* **************** IMAGE ******************** */ +static bNodeSocketType cmp_node_image_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static int calcimanr(int cfra, NodeImageAnim *nia) +{ + + if(nia->frames==0) return nia->nr; + + cfra= cfra - nia->sfra; + + /* cyclic */ + if(nia->cyclic) + cfra= (cfra % nia->frames); + else if(cfra>=nia->frames) + cfra= nia->frames-1; + else if(cfra<0) + cfra= 0; + + cfra+= nia->nr; + + if(cfra<1) cfra= 1; + + return cfra; +} + + +static void animated_image(bNode *node, int cfra) +{ + Image *ima; + NodeImageAnim *nia; + int imanr; + unsigned short numlen; + char name[FILE_MAXDIR+FILE_MAXFILE], head[FILE_MAXDIR+FILE_MAXFILE], tail[FILE_MAXDIR+FILE_MAXFILE]; + + ima= (Image *)node->id; + nia= node->storage; + + if(nia && nia->frames && ima && ima->name) { /* frames */ + strcpy(name, ima->name); + + imanr= calcimanr(cfra, nia); + if(imanr!=ima->lastframe) { + ima->lastframe= imanr; + + BLI_stringdec(name, head, tail, &numlen); + BLI_stringenc(name, head, tail, numlen, imanr); + + ima= add_image(name); + + if(ima) { + ima->flag |= IMA_FROMANIM; + if(node->id) node->id->us--; + node->id= (ID *)ima; + + ima->ok= 1; + } + } + } +} + + +static void node_composit_exec_image(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + RenderData *rd= data; + + /* image assigned to output */ + /* stack order input sockets: col, alpha */ + if(node->id) { + Image *ima; + CompBuf *stackbuf; + + /* animated image? */ + if(node->storage) + animated_image(node, rd->cfra); + + ima= (Image *)node->id; + + /* test if image is OK */ + if(ima->ok==0) return; + + if(ima->ibuf==NULL) { + + load_image(ima, IB_rect, G.sce, rd->cfra); /* G.sce is current .blend path */ + if(ima->ibuf==NULL) { + ima->ok= 0; + return; + } + } + if(ima->ibuf->rect_float==NULL) + IMB_float_from_rect(ima->ibuf); + + /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ + stackbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_RGBA, 0); + stackbuf->rect= ima->ibuf->rect_float; + + /* put ibuf on stack */ + out[0]->data= stackbuf; + + if(out[1]->hasoutput) + out[1]->data= alphabuf_from_rgbabuf(stackbuf); + + if(out[2]->hasoutput && ima->ibuf->zbuf_float) { + CompBuf *zbuf= alloc_compbuf(ima->ibuf->x, ima->ibuf->y, CB_VAL, 0); + zbuf->rect= ima->ibuf->zbuf_float; + out[2]->data= zbuf; + } + + generate_preview(node, stackbuf); + } +} + +/* uses node->storage to indicate animated image */ + +static bNodeType cmp_node_image= { + /* type code */ CMP_NODE_IMAGE, + /* name */ "Image", + /* width+range */ 120, 80, 300, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_image_out, + /* storage */ "NodeImageAnim", + /* execfunc */ node_composit_exec_image + +}; + +/* **************** RENDER RESULT ******************** */ +static bNodeSocketType cmp_node_rresult_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Z", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + + if(rr) { + RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1); + if(rl) { + CompBuf *stackbuf; + + /* we put render rect on stack, cbuf knows rect is from other ibuf when freed! */ + stackbuf= alloc_compbuf(rr->rectx, rr->recty, CB_RGBA, 0); + stackbuf->rect= rl->rectf; + + /* put on stack */ + out[0]->data= stackbuf; + + if(out[1]->hasoutput) + out[1]->data= alphabuf_from_rgbabuf(stackbuf); + if(out[2]->hasoutput && rl->rectz) { + CompBuf *zbuf= alloc_compbuf(rr->rectx, rr->recty, CB_VAL, 0); + zbuf->rect= rl->rectz; + out[2]->data= zbuf; + } + + generate_preview(node, stackbuf); + } + } +} + +/* custom1 = render layer in use */ +static bNodeType cmp_node_rresult= { + /* type code */ CMP_NODE_R_RESULT, + /* name */ "Render Result", + /* width+range */ 120, 80, 300, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_PREVIEW|NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_rresult_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rresult + +}; + +/* **************** NORMAL ******************** */ +static bNodeSocketType cmp_node_normal_in[]= { + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_normal_out[]= { + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +/* generates normal, does dot product */ +static void node_composit_exec_normal(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + /* stack order input: normal */ + /* stack order output: normal, value */ + + VECCOPY(out[0]->vec, sock->ns.vec); + /* render normals point inside... the widget points outside */ + out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); +} + +static bNodeType cmp_node_normal= { + /* type code */ CMP_NODE_NORMAL, + /* name */ "Normal", + /* width+range */ 100, 60, 200, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_normal_in, + /* output sock */ cmp_node_normal_out, + /* storage */ "", + /* execfunc */ node_composit_exec_normal + +}; + +/* **************** CURVE VEC ******************** */ +static bNodeSocketType cmp_node_curve_vec_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_curve_vec_out[]= { + { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_curve_vec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order input: vec */ + /* stack order output: vec */ + + curvemapping_evaluate_premulRGBF(node->storage, out[0]->vec, in[0]->vec); +} + +static bNodeType cmp_node_curve_vec= { + /* type code */ CMP_NODE_CURVE_VEC, + /* name */ "Vector Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_curve_vec_in, + /* output sock */ cmp_node_curve_vec_out, + /* storage */ "CurveMapping", + /* execfunc */ node_composit_exec_curve_vec + +}; + +/* **************** CURVE RGB ******************** */ +static bNodeSocketType cmp_node_curve_rgb_in[]= { + { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType cmp_node_curve_rgb_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_curves(bNode *node, float *out, float *in) +{ + curvemapping_evaluateRGBF(node->storage, out, in); + out[3]= in[3]; +} + +static void node_composit_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order input: vec */ + /* stack order output: vec */ + + if(out[0]->hasoutput==0) + return; + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + curvemapping_premultiply(node->storage, 0); + composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_curves); + curvemapping_premultiply(node->storage, 1); + + out[0]->data= stackbuf; + } + +} + +static bNodeType cmp_node_curve_rgb= { + /* type code */ CMP_NODE_CURVE_RGB, + /* name */ "RGB Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_curve_rgb_in, + /* output sock */ cmp_node_curve_rgb_out, + /* storage */ "CurveMapping", + /* execfunc */ node_composit_exec_curve_rgb + +}; + +/* **************** VALUE ******************** */ +static bNodeSocketType cmp_node_value_out[]= { + { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + + out[0]->vec[0]= sock->ns.vec[0]; +} + +static bNodeType cmp_node_value= { + /* type code */ CMP_NODE_VALUE, + /* name */ "Value", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_value_out, + /* storage */ "", + /* execfunc */ node_composit_exec_value + +}; + +/* **************** RGB ******************** */ +static bNodeSocketType cmp_node_rgb_out[]= { + { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_composit_exec_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + + VECCOPY(out[0]->vec, sock->ns.vec); +} + +static bNodeType cmp_node_rgb= { + /* type code */ CMP_NODE_RGB, + /* name */ "RGB", + /* width+range */ 100, 60, 140, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ cmp_node_rgb_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rgb + +}; + +/* **************** MIX RGB ******************** */ +static bNodeSocketType cmp_node_mix_rgb_in[]= { + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_mix_rgb_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_mix_rgb(bNode *node, float *out, float *in1, float *in2, float fac) +{ + float col[3]; + + VECCOPY(col, in1); + ramp_blend(node->custom1, col, col+1, col+2, fac, in2); + VECCOPY(out, col); + out[3]= in1[3]; +} + +static void node_composit_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: fac, Image, Image */ + /* stack order out: Image */ + float fac= in[0]->vec[0]; + + CLAMP(fac, 0.0f, 1.0f); + + /* input no image? then only color operation */ + if(in[1]->data==NULL && in[2]->data==NULL) { + do_mix_rgb(node, out[0]->vec, in[1]->vec, in[2]->vec, fac); + } + else { + /* make output size of first available input image */ + CompBuf *cbuf= in[1]->data?in[1]->data:in[2]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit3_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[2]->data, in[2]->vec, in[0]->data, fac, do_mix_rgb); + + out[0]->data= stackbuf; + } +} + +/* custom1 = mix type */ +static bNodeType cmp_node_mix_rgb= { + /* type code */ CMP_NODE_MIX_RGB, + /* name */ "Mix", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_mix_rgb_in, + /* output sock */ cmp_node_mix_rgb_out, + /* storage */ "", + /* execfunc */ node_composit_exec_mix_rgb + +}; + +/* **************** FILTER ******************** */ +static bNodeSocketType cmp_node_filter_in[]= { + { SOCK_VALUE, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_filter_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac) +{ + float *row1, *row2, *row3; + float *fp, f1, f2, mfac= 1.0f-fac; + int rowlen, x, y, c; + + rowlen= in->x; + + if(in->type==CB_RGBA) { + + for(y=2; yy; y++) { + /* setup rows */ + row1= in->rect + 4*(y-2)*rowlen; + row2= row1 + 4*rowlen; + row3= row2 + 4*rowlen; + fp= out->rect + 4*(y-1)*rowlen + 4; + + for(x=2; xx; + + if(in->type==CB_RGBA) { + + for(y=2; yy; y++) { + /* setup rows */ + row1= in->rect + 4*(y-2)*rowlen; + row2= row1 + 4*rowlen; + row3= row2 + 4*rowlen; + + fp= out->rect + 4*(y-1)*rowlen; + QUATCOPY(fp, row2); + fp+= 4; + + for(x=2; xdata) { + /* make output size of first available input image */ + CompBuf *cbuf= in[1]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + switch(node->custom1) { + case CMP_FILT_SOFT: + do_filter3(stackbuf, cbuf, soft, in[0]->vec[0]); + break; + case CMP_FILT_SHARP: + do_filter3(stackbuf, cbuf, sharp, in[0]->vec[0]); + break; + case CMP_FILT_LAPLACE: + do_filter3(stackbuf, cbuf, laplace, in[0]->vec[0]); + break; + case CMP_FILT_SOBEL: + do_filter_edge(stackbuf, cbuf, sobel, in[0]->vec[0]); + break; + case CMP_FILT_PREWITT: + do_filter_edge(stackbuf, cbuf, prewitt, in[0]->vec[0]); + break; + case CMP_FILT_KIRSCH: + do_filter_edge(stackbuf, cbuf, kirsch, in[0]->vec[0]); + break; + case CMP_FILT_SHADOW: + do_filter3(stackbuf, cbuf, shadow, in[0]->vec[0]); + break; + } + + out[0]->data= stackbuf; + } +} + +/* custom1 = filter type */ +static bNodeType cmp_node_filter= { + /* type code */ CMP_NODE_FILTER, + /* name */ "Filter", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_filter_in, + /* output sock */ cmp_node_filter_out, + /* storage */ "", + /* execfunc */ node_composit_exec_filter + +}; + + +/* **************** VALTORGB ******************** */ +static bNodeSocketType cmp_node_valtorgb_in[]= { + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_valtorgb_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_colorband_composit(bNode *node, float *out, float *in) +{ + do_colorband(node->storage, in[0], out); +} + +static void node_composit_exec_valtorgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: fac */ + /* stack order out: col, alpha */ + + if(node->storage) { + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + do_colorband(node->storage, in[0]->vec[0], out[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_colorband_composit); + + out[0]->data= stackbuf; + + if(out[1]->hasoutput) + out[1]->data= alphabuf_from_rgbabuf(stackbuf); + + } + } +} + +static bNodeType cmp_node_valtorgb= { + /* type code */ CMP_NODE_VALTORGB, + /* name */ "ColorRamp", + /* width+range */ 240, 200, 300, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_valtorgb_in, + /* output sock */ cmp_node_valtorgb_out, + /* storage */ "ColorBand", + /* execfunc */ node_composit_exec_valtorgb + +}; + + +/* **************** RGBTOBW ******************** */ +static bNodeSocketType cmp_node_rgbtobw_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_rgbtobw_out[]= { + { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_rgbtobw(bNode *node, float *out, float *in) +{ + out[0]= in[0]*0.35f + in[1]*0.45f + in[2]*0.2f; +} + +static void node_composit_exec_rgbtobw(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order out: bw */ + /* stack order in: col */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + out[0]->vec[0]= in[0]->vec[0]*0.35f + in[0]->vec[1]*0.45f + in[0]->vec[2]*0.2f; + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, NULL, do_rgbtobw); + + out[0]->data= stackbuf; + } +} + +static bNodeType cmp_node_rgbtobw= { + /* type code */ CMP_NODE_RGBTOBW, + /* name */ "RGB to BW", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, 0, + /* input sock */ cmp_node_rgbtobw_in, + /* output sock */ cmp_node_rgbtobw_out, + /* storage */ "", + /* execfunc */ node_composit_exec_rgbtobw + +}; + +/* **************** ALPHAOVER ******************** */ +static bNodeSocketType cmp_node_alphaover_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_alphaover_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_alphaover(bNode *node, float *out, float *src, float *dest) +{ + float mul= 1.0f - dest[3]; + + if(mul<=0.0f) { + QUATCOPY(out, dest); + } + else { + out[0]= (mul*src[0]) + dest[0]; + out[1]= (mul*src[1]) + dest[1]; + out[2]= (mul*src[2]) + dest[2]; + out[3]= (mul*src[3]) + dest[3]; + } +} + +static void node_composit_exec_alphaover(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: col col */ + /* stack order out: col */ + + /* input no image? then only color operation */ + if(in[0]->data==NULL) { + do_alphaover(node, out[0]->vec, in[0]->vec, in[1]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs + + composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_alphaover); + + out[0]->data= stackbuf; + } +} + +static bNodeType cmp_node_alphaover= { + /* type code */ CMP_NODE_ALPHAOVER, + /* name */ "AlphaOver", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, 0, + /* input sock */ cmp_node_alphaover_in, + /* output sock */ cmp_node_alphaover_out, + /* storage */ "", + /* execfunc */ node_composit_exec_alphaover + +}; + +/* **************** MAP VALUE ******************** */ +static bNodeSocketType cmp_node_map_value_in[]= { + { SOCK_VALUE, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_map_value_out[]= { + { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void do_map_value(bNode *node, float *out, float *src) +{ + TexMapping *texmap= node->storage; + + out[0]= (src[0] + texmap->loc[0])*texmap->size[0]; + if(texmap->flag & TEXMAP_CLIP_MIN) + if(out[0]min[0]) + out[0]= texmap->min[0]; + if(texmap->flag & TEXMAP_CLIP_MAX) + if(out[0]>texmap->max[0]) + out[0]= texmap->max[0]; +} + +static void node_composit_exec_map_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: col col */ + /* stack order out: col */ + + /* input no image? then only value operation */ + if(in[0]->data==NULL) { + do_map_value(node, out[0]->vec, in[0]->vec); + } + else { + /* make output size of input image */ + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); // allocs + + composit1_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, do_map_value); + + out[0]->data= stackbuf; + } +} + +static bNodeType cmp_node_map_value= { + /* type code */ CMP_NODE_MAP_VALUE, + /* name */ "Map Value", + /* width+range */ 100, 60, 150, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_map_value_in, + /* output sock */ cmp_node_map_value_out, + /* storage */ "TexMapping", + /* execfunc */ node_composit_exec_map_value + +}; + +/* **************** GAUSS BLUR ******************** */ +static bNodeSocketType cmp_node_blur_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_blur_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static float *make_gausstab(int rad) +{ + float *gausstab, sum, val; + int i, n; + + n = 2 * rad + 1; + + gausstab = (float *) MEM_mallocN(n * sizeof(float), "gauss"); + + sum = 0.0f; + for (i = -rad; i <= rad; i++) { + val = exp(-4.0*((float)i*i) / (float) (rad*rad)); + sum += val; + gausstab[i+rad] = val; + } + + sum= 1.0f/sum; + for(i=0; ix, imgy= img->y; + int x, y, pix= img->type; + int i, bigstep; + float *src, *dest; + + /* helper image */ + work= alloc_compbuf(imgx, imgy, img->type, 1); // allocs + + /* horizontal */ + rad = ceil(blurx); + if(rad>imgx/2) + rad= imgx/2; + else if(rad<1) + rad= 1; + + gausstab= make_gausstab(rad); + gausstabcent= gausstab+rad; + + for (y = 0; y < imgy; y++) { + float *srcd= img->rect + pix*(y*img->x); + + dest = work->rect + pix*(y * img->x); + + for (x = 0; x < imgx ; x++) { + int minr= x-rad<0?-x:-rad; + int maxr= x+rad>imgx?imgx-x:rad; + + src= srcd + pix*(x+minr); + + sum= gval = rval= bval= aval= 0.0f; + for (i= minr; i < maxr; i++) { + val= gausstabcent[i]; + sum+= val; + rval += val * (*src++); + if(pix==4) { + gval += val * (*src++); + bval += val * (*src++); + aval += val * (*src++); + } + } + sum= 1.0f/sum; + *dest++ = rval*sum; + if(pix==4) { + *dest++ = gval*sum; + *dest++ = bval*sum; + *dest++ = aval*sum; + } + } + } + + /* vertical */ + MEM_freeN(gausstab); + + rad = ceil(blury); + if(rad>imgy/2) + rad= imgy/2; + else if(rad<1) + rad= 1; + + gausstab= make_gausstab(rad); + gausstabcent= gausstab+rad; + + bigstep = pix*imgx; + for (x = 0; x < imgx; x++) { + float *srcd= work->rect + pix*x; + + dest = new->rect + pix*x; + + for (y = 0; y < imgy ; y++) { + int minr= y-rad<0?-y:-rad; + int maxr= y+rad>imgy?imgy-y:rad; + + src= srcd + bigstep*(y+minr); + + sum= gval = rval= bval= aval= 0.0f; + for (i= minr; i < maxr; i++) { + val= gausstabcent[i]; + sum+= val; + rval += val * src[0]; + if(pix==4) { + gval += val * src[1]; + bval += val * src[2]; + aval += val * src[3]; + } + src += bigstep; + } + sum= 1.0f/sum; + dest[0] = rval*sum; + if(pix==4) { + dest[1] = gval*sum; + dest[2] = bval*sum; + dest[3] = aval*sum; + } + dest+= bigstep; + } + } + + free_compbuf(work); + MEM_freeN(gausstab); +} + +/* reference has to be mapped 0-1, and equal in size */ +static void bloom_with_reference(CompBuf *new, CompBuf *img, CompBuf *ref, float blurx, float blury) +{ + CompBuf *wbuf; + register float val; + float radxf, radyf; + float **maintabs; + float *gausstabx, *gausstabcenty; + float *gausstaby, *gausstabcentx; + int radx, rady, imgx= img->x, imgy= img->y; + int x, y; + int i, j; + float *src, *dest, *wb; + + wbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + memset(wbuf->rect, sizeof(float)*imgx*imgy, 0); + + /* horizontal */ + radx = ceil(blurx); + if(radx>imgx/2) + radx= imgx/2; + else if(radx<1) + radx= 1; + + /* vertical */ + rady = ceil(blury); + if(rady>imgy/2) + rady= imgy/2; + else if(rady<1) + rady= 1; + + x= MAX2(radx, rady); + maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); + for(i= 0; irect; + src= img->rect; + + memset(new->rect, 4*imgx*imgy, 0); + + radxf= (float)radx; + radyf= (float)rady; + + for (y = 0; y < imgy; y++) { + for (x = 0; x < imgx ; x++, src+=4) {//, refd++) { + +// int refradx= (int)(refd[0]*radxf); +// int refrady= (int)(refd[0]*radyf); + + int refradx= (int)(radxf*0.3f*src[3]*(src[0]+src[1]+src[2])); + int refrady= (int)(radyf*0.3f*src[3]*(src[0]+src[1]+src[2])); + + if(refradx>radx) refradx= radx; + else if(refradx<1) refradx= 1; + if(refrady>rady) refrady= rady; + else if(refrady<1) refrady= 1; + + if(refradx==1 && refrady==1) { + wb= wbuf->rect + ( y*imgx + x); + dest= new->rect + 4*( y*imgx + x); + wb[0]+= 1.0f; + dest[0] += src[0]; + dest[1] += src[1]; + dest[2] += src[2]; + dest[3] += src[3]; + } + else { + int minxr= x-refradx<0?-x:-refradx; + int maxxr= x+refradx>imgx?imgx-x:refradx; + int minyr= y-refrady<0?-y:-refrady; + int maxyr= y+refrady>imgy?imgy-y:refrady; + + float *destd= new->rect + 4*( (y + minyr)*imgx + x + minxr); + float *wbufd= wbuf->rect + ( (y + minyr)*imgx + x + minxr); + + gausstabx= maintabs[refradx-1]; + gausstabcentx= gausstabx+refradx; + gausstaby= maintabs[refrady-1]; + gausstabcenty= gausstaby+refrady; + + for (i= minyr; i < maxyr; i++, destd+= 4*imgx, wbufd+= imgx) { + dest= destd; + wb= wbufd; + for (j= minxr; j < maxxr; j++, dest+=4, wb++) { + + val= gausstabcenty[i]*gausstabcentx[j]; + wb[0]+= val; + dest[0] += val * src[0]; + dest[1] += val * src[1]; + dest[2] += val * src[2]; + dest[3] += val * src[3]; + } + } + } + } + } + + x= imgx*imgy; + dest= new->rect; + wb= wbuf->rect; + while(x--) { + val= 1.0f/wb[0]; + dest[0]*= val; + dest[1]*= val; + dest[2]*= val; + dest[3]*= val; + wb++; + dest+= 4; + } + + free_compbuf(wbuf); + + x= MAX2(radx, rady); + for(i= 0; ix, imgy= img->y; + int x, y; + int i, j; + float *src, *dest, *refd, *blurd; + + /* trick is; we blur the reference image... but only works with clipped values*/ + blurbuf= alloc_compbuf(imgx, imgy, CB_VAL, 1); + blurd= blurbuf->rect; + refd= ref->rect; + for(x= imgx*imgy; x>0; x--, refd++, blurd++) { + if(refd[0]<0.0f) blurd[0]= 0.0f; + else if(refd[0]>1.0f) blurd[0]= 1.0f; + else blurd[0]= refd[0]; + } + + blur_single_image(blurbuf, blurbuf, blurx, blury); + + /* horizontal */ + radx = ceil(blurx); + if(radx>imgx/2) + radx= imgx/2; + else if(radx<1) + radx= 1; + + /* vertical */ + rady = ceil(blury); + if(rady>imgy/2) + rady= imgy/2; + else if(rady<1) + rady= 1; + + x= MAX2(radx, rady); + maintabs= MEM_mallocN(x*sizeof(void *), "gauss array"); + for(i= 0; irect; + dest= new->rect; + radxf= (float)radx; + radyf= (float)rady; + + for (y = 0; y < imgy; y++) { + for (x = 0; x < imgx ; x++, dest+=4, refd++) { + int refradx= (int)(refd[0]*radxf); + int refrady= (int)(refd[0]*radyf); + + if(refradx>radx) refradx= radx; + else if(refradx<1) refradx= 1; + if(refrady>rady) refrady= rady; + else if(refrady<1) refrady= 1; + + if(refradx==1 && refrady==1) { + src= img->rect + 4*( y*imgx + x); + QUATCOPY(dest, src); + } + else { + int minxr= x-refradx<0?-x:-refradx; + int maxxr= x+refradx>imgx?imgx-x:refradx; + int minyr= y-refrady<0?-y:-refrady; + int maxyr= y+refrady>imgy?imgy-y:refrady; + + float *srcd= img->rect + 4*( (y + minyr)*imgx + x + minxr); + + gausstabx= maintabs[refradx-1]; + gausstabcentx= gausstabx+refradx; + gausstaby= maintabs[refrady-1]; + gausstabcenty= gausstaby+refrady; + + sum= gval = rval= bval= aval= 0.0f; + + for (i= minyr; i < maxyr; i++, srcd+= 4*imgx) { + src= srcd; + for (j= minxr; j < maxxr; j++, src+=4) { + + val= gausstabcenty[i]*gausstabcentx[j]; + sum+= val; + rval += val * src[0]; + gval += val * src[1]; + bval += val * src[2]; + aval += val * src[3]; + } + } + sum= 1.0f/sum; + dest[0] = rval*sum; + dest[1] = gval*sum; + dest[2] = bval*sum; + dest[3] = aval*sum; + } + } + } + + free_compbuf(blurbuf); + + x= MAX2(radx, rady); + for(i= 0; idata; + + if(img==NULL || out[0]->hasoutput==0) + return; + + /* if fac input, we do it different */ + if(in[1]->data) { + + /* test fitness if reference */ + + /* make output size of input image */ + new= alloc_compbuf(img->x, img->y, CB_RGBA, 1); // allocs + + blur_with_reference(new, img, in[1]->data, (float)node->custom1, (float)node->custom2); + + out[0]->data= new; + } + else { + if(in[1]->vec[0]==0.0f) { + /* pass on image */ + new= alloc_compbuf(img->x, img->y, img->type, 0); + new->rect= img->rect; + } + else { + /* make output size of input image */ + new= alloc_compbuf(img->x, img->y, img->type, 1); // allocs + if(1) + blur_single_image(new, img, in[1]->vec[0]*(float)node->custom1, in[1]->vec[0]*(float)node->custom2); + else /* bloom experimental... */ + bloom_with_reference(new, img, NULL, in[1]->vec[0]*(float)node->custom1, in[1]->vec[0]*(float)node->custom2); + } + out[0]->data= new; + } +} + + +/* custom1 custom2 = blur filter size */ +static bNodeType cmp_node_blur= { + /* type code */ CMP_NODE_BLUR, + /* name */ "Blur", + /* width+range */ 120, 80, 200, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ cmp_node_blur_in, + /* output sock */ cmp_node_blur_out, + /* storage */ "", + /* execfunc */ node_composit_exec_blur + +}; + + +/* ****************** types array for all shaders ****************** */ + +bNodeType *node_all_composit[]= { + &node_group_typeinfo, + &cmp_node_viewer, + &cmp_node_composite, + &cmp_node_output_file, + &cmp_node_value, + &cmp_node_rgb, + &cmp_node_mix_rgb, + &cmp_node_filter, + &cmp_node_valtorgb, + &cmp_node_rgbtobw, + &cmp_node_normal, + &cmp_node_curve_vec, + &cmp_node_curve_rgb, + &cmp_node_image, + &cmp_node_rresult, + &cmp_node_alphaover, + &cmp_node_blur, + &cmp_node_map_value, + NULL +}; + +/* ******************* parse ************ */ + +/* helper call to detect if theres a render-result node */ +int ntreeCompositNeedsRender(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return 1; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_R_RESULT) + return 1; + } + return 0; +} + +void ntreeCompositTagRender(bNodeTree *ntree) +{ + bNode *node; + + if(ntree==NULL) return; + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_R_RESULT) + NodeTagChanged(ntree, node); + } +} + diff --git a/source/blender/blenkernel/intern/node_shaders.c b/source/blender/blenkernel/intern/node_shaders.c new file mode 100644 index 00000000000..4e65b36588c --- /dev/null +++ b/source/blender/blenkernel/intern/node_shaders.c @@ -0,0 +1,811 @@ +/** + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include + +#include "DNA_ID.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_texture_types.h" + +#include "BKE_blender.h" +#include "BKE_colortools.h" +#include "BKE_node.h" +#include "BKE_material.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "MEM_guardedalloc.h" + +#include "RE_shader_ext.h" /* <- ShadeInput Shaderesult TexResult */ + + +/* ********* exec data struct, remains internal *********** */ + +typedef struct ShaderCallData { + ShadeInput *shi; + ShadeResult *shr; +} ShaderCallData; + + +/* **************** call to switch lamploop for material node ************ */ + +static void (*node_shader_lamp_loop)(ShadeInput *, ShadeResult *); + +void set_node_shader_lamp_loop(void (*lamp_loop_func)(ShadeInput *, ShadeResult *)) +{ + node_shader_lamp_loop= lamp_loop_func; +} + + +/* ******************************************************** */ +/* ********* Shader Node type definitions ***************** */ +/* ******************************************************** */ + +/* SocketType syntax: + socket type, max connections (0 is no limit), name, 4 values for default, 2 values for range */ + +/* Verification rule: If name changes, a saved socket and its links will be removed! Type changes are OK */ + +/* **************** OUTPUT ******************** */ +static bNodeSocketType sh_node_output_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_output(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(data) { + ShadeInput *shi= ((ShaderCallData *)data)->shi; + float col[4]; + + /* stack order input sockets: col, alpha, normal */ + VECCOPY(col, in[0]->vec); + col[3]= in[1]->vec[0]; + + if(shi->do_preview) { + nodeAddToPreview(node, col, shi->xs, shi->ys); + node->lasty= shi->ys; + } + + if(node->flag & NODE_DO_OUTPUT) { + ShadeResult *shr= ((ShaderCallData *)data)->shr; + + VECCOPY(shr->diff, col); + col[0]= col[1]= col[2]= 0.0f; + VECCOPY(shr->spec, col); + shr->alpha= col[3]; + + // VECCOPY(shr->nor, in[3]->vec); + } + } +} + +static bNodeType sh_node_output= { + /* type code */ SH_NODE_OUTPUT, + /* name */ "Output", + /* width+range */ 80, 60, 200, + /* class+opts */ NODE_CLASS_OUTPUT, NODE_PREVIEW, + /* input sock */ sh_node_output_in, + /* output sock */ NULL, + /* storage */ "", + /* execfunc */ node_shader_exec_output + +}; + +/* **************** GEOMETRY ******************** */ + +/* output socket defines */ +#define GEOM_OUT_GLOB 0 +#define GEOM_OUT_LOCAL 1 +#define GEOM_OUT_VIEW 2 +#define GEOM_OUT_ORCO 3 +#define GEOM_OUT_UV 4 +#define GEOM_OUT_NORMAL 5 + +/* output socket type definition */ +static bNodeSocketType sh_node_geom_out[]= { + { SOCK_VECTOR, 0, "Global", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* btw; uses no limit */ + { SOCK_VECTOR, 0, "Local", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 0, "View", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 0, "Orco", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 0, "UV", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +/* node execute callback */ +static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(data) { + ShadeInput *shi= ((ShaderCallData *)data)->shi; + + /* out: global, local, view, orco, uv, normal */ + VECCOPY(out[GEOM_OUT_GLOB]->vec, shi->gl); + VECCOPY(out[GEOM_OUT_LOCAL]->vec, shi->co); + VECCOPY(out[GEOM_OUT_VIEW]->vec, shi->view); + VECCOPY(out[GEOM_OUT_ORCO]->vec, shi->lo); + VECCOPY(out[GEOM_OUT_UV]->vec, shi->uv); + VECCOPY(out[GEOM_OUT_NORMAL]->vec, shi->vno); + + if(shi->osatex) { + out[GEOM_OUT_GLOB]->data= shi->dxgl; + out[GEOM_OUT_GLOB]->datatype= NS_OSA_VECTORS; + out[GEOM_OUT_LOCAL]->data= shi->dxco; + out[GEOM_OUT_LOCAL]->datatype= NS_OSA_VECTORS; + out[GEOM_OUT_VIEW]->data= &shi->dxview; + out[GEOM_OUT_VIEW]->datatype= NS_OSA_VALUES; + out[GEOM_OUT_ORCO]->data= shi->dxlo; + out[GEOM_OUT_ORCO]->datatype= NS_OSA_VECTORS; + out[GEOM_OUT_UV]->data= shi->dxuv; + out[GEOM_OUT_UV]->datatype= NS_OSA_VECTORS; + out[GEOM_OUT_NORMAL]->data= shi->dxno; + out[GEOM_OUT_NORMAL]->datatype= NS_OSA_VECTORS; + } + } +} + +/* node type definition */ +static bNodeType sh_node_geom= { + /* type code */ SH_NODE_GEOMETRY, + /* name */ "Geometry", + /* width+range */ 60, 40, 100, + /* class+opts */ NODE_CLASS_INPUT, 0, + /* input sock */ NULL, + /* output sock */ sh_node_geom_out, + /* storage */ "", + /* execfunc */ node_shader_exec_geom + +}; + +/* **************** MATERIAL ******************** */ + +/* input socket defines */ +#define MAT_IN_COLOR 0 +#define MAT_IN_SPEC 1 +#define MAT_IN_REFL 2 +#define MAT_IN_NORMAL 3 + +static bNodeSocketType sh_node_material_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_RGBA, 1, "Spec", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VALUE, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +/* output socket defines */ +#define MAT_OUT_COLOR 0 +#define MAT_OUT_ALPHA 1 +#define MAT_OUT_NORMAL 2 + +static bNodeSocketType sh_node_material_out[]= { + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(data && node->id) { + ShadeResult shrnode; + ShadeInput *shi; + float col[4], *nor; + + shi= ((ShaderCallData *)data)->shi; + shi->mat= (Material *)node->id; + + /* copy all relevant material vars, note, keep this synced with render_types.h */ + memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); + shi->har= shi->mat->har; + + /* write values */ + if(in[MAT_IN_COLOR]->hasinput) + VECCOPY(&shi->r, in[MAT_IN_COLOR]->vec); + + if(in[MAT_IN_SPEC]->hasinput) + VECCOPY(&shi->specr, in[MAT_IN_SPEC]->vec); + + if(in[MAT_IN_REFL]->hasinput) + shi->mat->ref= in[MAT_IN_REFL]->vec[0]; + + /* retrieve normal */ + if(in[MAT_IN_NORMAL]->hasinput) { + nor= in[MAT_IN_NORMAL]->vec; + Normalise(nor); + } + else + nor= shi->vno; + + /* custom option to flip normal */ + if(node->custom1 & SH_NODE_MAT_NEG) { + shi->vn[0]= -nor[0]; + shi->vn[1]= -nor[1]; + shi->vn[2]= -nor[2]; + } + else { + VECCOPY(shi->vn, nor); + } + + node_shader_lamp_loop(shi, &shrnode); + + /* write to outputs */ + if(node->custom1 & SH_NODE_MAT_DIFF) { + VECCOPY(col, shrnode.diff); + if(node->custom1 & SH_NODE_MAT_SPEC) { + VecAddf(col, col, shrnode.spec); + } + } + else if(node->custom1 & SH_NODE_MAT_SPEC) { + VECCOPY(col, shrnode.spec); + } + else + col[0]= col[1]= col[2]= 0.0f; + + col[3]= shrnode.alpha; + + if(shi->do_preview) + nodeAddToPreview(node, col, shi->xs, shi->ys); + + VECCOPY(out[MAT_OUT_COLOR]->vec, col); + out[MAT_OUT_ALPHA]->vec[0]= shrnode.alpha; + + if(node->custom1 & SH_NODE_MAT_NEG) { + shi->vn[0]= -shi->vn[0]; + shi->vn[1]= -shi->vn[1]; + shi->vn[2]= -shi->vn[2]; + } + + VECCOPY(out[MAT_OUT_NORMAL]->vec, shi->vn); + + } +} + +static bNodeType sh_node_material= { + /* type code */ SH_NODE_MATERIAL, + /* name */ "Material", + /* width+range */ 120, 80, 240, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS|NODE_PREVIEW, + /* input sock */ sh_node_material_in, + /* output sock */ sh_node_material_out, + /* storage */ "", + /* execfunc */ node_shader_exec_material + +}; + +/* **************** TEXTURE ******************** */ +static bNodeSocketType sh_node_texture_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, /* no limit */ + { -1, 0, "" } +}; +static bNodeSocketType sh_node_texture_out[]= { + { SOCK_VALUE, 0, "Value", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA , 0, "Color", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(data && node->id) { + ShadeInput *shi= ((ShaderCallData *)data)->shi; + TexResult texres; + float *vec, nor[3]={0.0f, 0.0f, 0.0f}; + int retval; + + /* out: value, color, normal */ + + /* we should find out if a normal as output is needed, for now we do all */ + texres.nor= nor; + + if(in[0]->hasinput) { + vec= in[0]->vec; + + if(in[0]->datatype==NS_OSA_VECTORS) { + float *fp= in[0]->data; + retval= multitex((Tex *)node->id, vec, fp, fp+3, shi->osatex, &texres); + } + else if(in[0]->datatype==NS_OSA_VALUES) { + float *fp= in[0]->data; + float dxt[3], dyt[3]; + + dxt[0]= fp[0]; dxt[1]= dxt[2]= 0.0f; + dyt[0]= fp[1]; dyt[1]= dyt[2]= 0.0f; + retval= multitex((Tex *)node->id, vec, dxt, dyt, shi->osatex, &texres); + } + else + retval= multitex((Tex *)node->id, vec, NULL, NULL, 0, &texres); + } + else { /* only for previewrender, so we see stuff */ + vec= shi->lo; + retval= multitex((Tex *)node->id, vec, NULL, NULL, 0, &texres); + } + + /* stupid exception */ + if( ((Tex *)node->id)->type==TEX_STUCCI) { + texres.tin= 0.5f + 0.7f*texres.nor[0]; + CLAMP(texres.tin, 0.0f, 1.0f); + } + + /* intensity and color need some handling */ + if(texres.talpha) + out[0]->vec[0]= texres.ta; + else + out[0]->vec[0]= texres.tin; + + if((retval & TEX_RGB)==0) { + out[1]->vec[0]= out[0]->vec[0]; + out[1]->vec[1]= out[0]->vec[0]; + out[1]->vec[2]= out[0]->vec[0]; + out[1]->vec[3]= 1.0f; + } + else { + out[1]->vec[0]= texres.tr; + out[1]->vec[1]= texres.tg; + out[1]->vec[2]= texres.tb; + out[1]->vec[3]= 1.0f; + } + + VECCOPY(out[2]->vec, nor); + + if(shi->do_preview) + nodeAddToPreview(node, out[1]->vec, shi->xs, shi->ys); + + } +} + +static bNodeType sh_node_texture= { + /* type code */ SH_NODE_TEXTURE, + /* name */ "Texture", + /* width+range */ 120, 80, 240, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS|NODE_PREVIEW, + /* input sock */ sh_node_texture_in, + /* output sock */ sh_node_texture_out, + /* storage */ "", + /* execfunc */ node_shader_exec_texture + +}; + +/* **************** MAPPING ******************** */ +static bNodeSocketType sh_node_mapping_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType sh_node_mapping_out[]= { + { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +/* do the regular mapping options for blender textures */ +static void node_shader_exec_mapping(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + TexMapping *texmap= node->storage; + float *vec= out[0]->vec; + + /* stack order input: vector */ + /* stack order output: vector */ + VECCOPY(vec, in[0]->vec); + Mat4MulVecfl(texmap->mat, vec); + + if(texmap->flag & TEXMAP_CLIP_MIN) { + if(vec[0]min[0]) vec[0]= texmap->min[0]; + if(vec[1]min[1]) vec[1]= texmap->min[1]; + if(vec[2]min[2]) vec[2]= texmap->min[2]; + } + if(texmap->flag & TEXMAP_CLIP_MAX) { + if(vec[0]>texmap->max[0]) vec[0]= texmap->max[0]; + if(vec[1]>texmap->max[1]) vec[1]= texmap->max[1]; + if(vec[2]>texmap->max[2]) vec[2]= texmap->max[2]; + } +} + +static bNodeType sh_node_mapping= { + /* type code */ SH_NODE_MAPPING, + /* name */ "Mapping", + /* width+range */ 240, 160, 320, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_mapping_in, + /* output sock */ sh_node_mapping_out, + /* storage */ "TexMapping", + /* execfunc */ node_shader_exec_mapping + +}; + +/* **************** NORMAL ******************** */ +static bNodeSocketType sh_node_normal_in[]= { + { SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType sh_node_normal_out[]= { + { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { SOCK_VALUE, 0, "Dot", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +/* generates normal, does dot product */ +static void node_shader_exec_normal(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + /* stack order input: normal */ + /* stack order output: normal, value */ + + VECCOPY(out[0]->vec, sock->ns.vec); + /* render normals point inside... the widget points outside */ + out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); +} + +static bNodeType sh_node_normal= { + /* type code */ SH_NODE_NORMAL, + /* name */ "Normal", + /* width+range */ 100, 60, 200, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_normal_in, + /* output sock */ sh_node_normal_out, + /* storage */ "", + /* execfunc */ node_shader_exec_normal + +}; + +/* **************** CURVE VEC ******************** */ +static bNodeSocketType sh_node_curve_vec_in[]= { + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType sh_node_curve_vec_out[]= { + { SOCK_VECTOR, 0, "Vector", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_curve_vec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order input: vec */ + /* stack order output: vec */ + + curvemapping_evaluate3F(node->storage, out[0]->vec, in[0]->vec); +} + +static bNodeType sh_node_curve_vec= { + /* type code */ SH_NODE_CURVE_VEC, + /* name */ "Vector Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_curve_vec_in, + /* output sock */ sh_node_curve_vec_out, + /* storage */ "CurveMapping", + /* execfunc */ node_shader_exec_curve_vec + +}; + +/* **************** CURVE RGB ******************** */ +static bNodeSocketType sh_node_curve_rgb_in[]= { + { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketType sh_node_curve_rgb_out[]= { + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_curve_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order input: vec */ + /* stack order output: vec */ + + curvemapping_evaluateRGBF(node->storage, out[0]->vec, in[0]->vec); +} + +static bNodeType sh_node_curve_rgb= { + /* type code */ SH_NODE_CURVE_RGB, + /* name */ "RGB Curves", + /* width+range */ 200, 140, 320, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_curve_rgb_in, + /* output sock */ sh_node_curve_rgb_out, + /* storage */ "CurveMapping", + /* execfunc */ node_shader_exec_curve_rgb + +}; + +/* **************** VALUE ******************** */ +static bNodeSocketType sh_node_value_out[]= { + { SOCK_VALUE, 0, "Value", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_value(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + + out[0]->vec[0]= sock->ns.vec[0]; +} + +static bNodeType sh_node_value= { + /* type code */ SH_NODE_VALUE, + /* name */ "Value", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ sh_node_value_out, + /* storage */ "", + /* execfunc */ node_shader_exec_value + +}; + +/* **************** RGB ******************** */ +static bNodeSocketType sh_node_rgb_out[]= { + { SOCK_RGBA, 0, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + bNodeSocket *sock= node->outputs.first; + + VECCOPY(out[0]->vec, sock->ns.vec); +} + +static bNodeType sh_node_rgb= { + /* type code */ SH_NODE_RGB, + /* name */ "RGB", + /* width+range */ 100, 60, 140, + /* class+opts */ NODE_CLASS_GENERATOR, NODE_OPTIONS, + /* input sock */ NULL, + /* output sock */ sh_node_rgb_out, + /* storage */ "", + /* execfunc */ node_shader_exec_rgb + +}; + +/* **************** MIX RGB ******************** */ +static bNodeSocketType sh_node_mix_rgb_in[]= { + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Color1", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Color2", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType sh_node_mix_rgb_out[]= { + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_mix_rgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: fac, col1, col2 */ + /* stack order out: col */ + float col[3]; + float fac= in[0]->vec[0]; + + CLAMP(fac, 0.0f, 1.0f); + + VECCOPY(col, in[1]->vec); + ramp_blend(node->custom1, col, col+1, col+2, fac, in[2]->vec); + VECCOPY(out[0]->vec, col); +} + +static bNodeType sh_node_mix_rgb= { + /* type code */ SH_NODE_MIX_RGB, + /* name */ "Mix", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_mix_rgb_in, + /* output sock */ sh_node_mix_rgb_out, + /* storage */ "", + /* execfunc */ node_shader_exec_mix_rgb + +}; + + +/* **************** VALTORGB ******************** */ +static bNodeSocketType sh_node_valtorgb_in[]= { + { SOCK_VALUE, 1, "Fac", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType sh_node_valtorgb_out[]= { + { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static void node_shader_exec_valtorgb(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order in: fac */ + /* stack order out: col, alpha */ + + if(node->storage) { + do_colorband(node->storage, in[0]->vec[0], out[0]->vec); + out[1]->vec[0]= out[0]->vec[3]; + } +} + +static bNodeType sh_node_valtorgb= { + /* type code */ SH_NODE_VALTORGB, + /* name */ "ColorRamp", + /* width+range */ 240, 200, 300, + /* class+opts */ NODE_CLASS_OPERATOR, NODE_OPTIONS, + /* input sock */ sh_node_valtorgb_in, + /* output sock */ sh_node_valtorgb_out, + /* storage */ "ColorBand", + /* execfunc */ node_shader_exec_valtorgb + +}; + + +/* **************** RGBTOBW ******************** */ +static bNodeSocketType sh_node_rgbtobw_in[]= { + { SOCK_RGBA, 1, "Color", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; +static bNodeSocketType sh_node_rgbtobw_out[]= { + { SOCK_VALUE, 0, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + + +static void node_shader_exec_rgbtobw(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + /* stack order out: bw */ + /* stack order in: col */ + + out[0]->vec[0]= in[0]->vec[0]*0.35f + in[0]->vec[1]*0.45f + in[0]->vec[2]*0.2f; +} + +static bNodeType sh_node_rgbtobw= { + /* type code */ SH_NODE_RGBTOBW, + /* name */ "RGB to BW", + /* width+range */ 80, 40, 120, + /* class+opts */ NODE_CLASS_OPERATOR, 0, + /* input sock */ sh_node_rgbtobw_in, + /* output sock */ sh_node_rgbtobw_out, + /* storage */ "", + /* execfunc */ node_shader_exec_rgbtobw + +}; + + +/* ****************** types array for all shaders ****************** */ + +bNodeType *node_all_shaders[]= { + &node_group_typeinfo, + &sh_node_output, + &sh_node_material, + &sh_node_value, + &sh_node_rgb, + &sh_node_mix_rgb, + &sh_node_valtorgb, + &sh_node_rgbtobw, + &sh_node_texture, + &sh_node_normal, + &sh_node_geom, + &sh_node_mapping, + &sh_node_curve_vec, + &sh_node_curve_rgb, + NULL +}; + +/* ******************* execute and parse ************ */ + +void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) +{ + ShaderCallData scd; + + /* convert caller data to struct */ + scd.shi= shi; + scd.shr= shr; + + ntreeExecTree(ntree, &scd, shi->thread); /* threads */ +} + +/* go over all used Geometry and Texture nodes, and return a texco flag */ +int ntreeShaderGetTexco(bNodeTree *ntree, int osa) +{ + bNode *node; + bNodeSocket *sock; + int texco= 0, a; + + ntreeSocketUseFlags(ntree); + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->type==SH_NODE_TEXTURE) { + if(osa && node->id) { + Tex *tex= (Tex *)node->id; + if ELEM3(tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) texco |= TEXCO_OSA; + } + } + else if(node->type==SH_NODE_GEOMETRY) { + /* note; sockets always exist for the given type! */ + for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { + if(sock->flag & SOCK_IN_USE) { + switch(a) { + case GEOM_OUT_GLOB: + texco |= TEXCO_GLOB; break; + case GEOM_OUT_VIEW: + texco |= TEXCO_VIEW; break; + case GEOM_OUT_ORCO: + texco |= TEXCO_ORCO; break; + case GEOM_OUT_UV: + texco |= TEXCO_UV; break; + case GEOM_OUT_NORMAL: + texco |= TEXCO_NORM; break; + } + } + } + } + } + + return texco; +} + +/* nodes that use ID data get synced with local data */ +void nodeShaderSynchronizeID(bNode *node, int copyto) +{ + if(node->id==NULL) return; + + if(node->type==SH_NODE_MATERIAL) { + bNodeSocket *sock; + Material *ma= (Material *)node->id; + int a; + + /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ + for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(copyto) { + switch(a) { + case MAT_IN_COLOR: + VECCOPY(&ma->r, sock->ns.vec); break; + case MAT_IN_SPEC: + VECCOPY(&ma->specr, sock->ns.vec); break; + case MAT_IN_REFL: + ma->ref= sock->ns.vec[0]; break; + } + } + else { + switch(a) { + case MAT_IN_COLOR: + VECCOPY(sock->ns.vec, &ma->r); break; + case MAT_IN_SPEC: + VECCOPY(sock->ns.vec, &ma->specr); break; + case MAT_IN_REFL: + sock->ns.vec[0]= ma->ref; break; + } + } + } + } + } + +} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 957d76d786b..0b52c92f50e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -55,6 +55,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" +#include "DNA_nla_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_object_fluidsim.h" @@ -90,6 +91,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_group.h" +#include "BKE_icons.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -207,6 +209,7 @@ void free_object(Object *ob) ob->path= 0; if(ob->ipo) ob->ipo->id.us--; if(ob->action) ob->action->id.us--; + if(ob->dup_group) ob->dup_group->id.us--; if(ob->defbase.first) BLI_freelistN(&ob->defbase); if(ob->pose) { @@ -254,6 +257,7 @@ void unlink_object(Object *ob) Ipo *ipo; Group *group; bConstraint *con; + bActionStrip *strip; int a; char *str; @@ -301,6 +305,8 @@ void unlink_object(Object *ob) obt->recalc |= OB_RECALC_DATA; } } + if(pchan->custom==ob) + pchan->custom= NULL; } } @@ -312,6 +318,7 @@ void unlink_object(Object *ob) obt->recalc |= OB_RECALC_OB; } } + /* object is deflector or field */ if(ob->pd) { if(give_parteff(obt)) @@ -319,6 +326,12 @@ void unlink_object(Object *ob) else if(obt->soft) obt->recalc |= OB_RECALC_DATA; } + + /* strips */ + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object==ob) + strip->object= NULL; + } } obt= obt->id.next; } @@ -662,6 +675,9 @@ void free_lamp(Lamp *la) if(mtex) MEM_freeN(mtex); } la->ipo= 0; + + BKE_icon_delete(&la->id); + la->id.icon_id = 0; } void *add_wave() @@ -743,6 +759,8 @@ Object *add_object(int type) Mat4One(ob->obmat); ob->dt= OB_SHADED; if(U.flag & USER_MAT_ON_OB) ob->colbits= -1; + ob->empty_drawtype= OB_ARROWS; + ob->empty_drawsize= 1.0; if(type==OB_CAMERA || type==OB_LAMP) { ob->trackflag= OB_NEGZ; @@ -869,6 +887,8 @@ Object *copy_object(Object *ob) id_us_plus((ID *)obn->data); id_us_plus((ID *)obn->ipo); id_us_plus((ID *)obn->action); + id_us_plus((ID *)obn->dup_group); + for(a=0; atotcol; a++) id_us_plus((ID *)obn->mat[a]); obn->disp.first= obn->disp.last= NULL; @@ -888,6 +908,7 @@ Object *copy_object(Object *ob) void expand_local_object(Object *ob) { + bActionStrip *strip; int a; id_lib_extern((ID *)ob->action); @@ -897,6 +918,10 @@ void expand_local_object(Object *ob) for(a=0; atotcol; a++) { id_lib_extern((ID *)ob->mat[a]); } + for (strip=ob->nlastrips.first; strip; strip=strip->next) { + id_lib_extern((ID *)strip->act); + } + } void make_local_object(Object *ob) @@ -970,10 +995,10 @@ void make_local_object(Object *ob) float bluroffs= 0.0; int no_speed_curve= 0; -void set_mblur_offs(int blur) +/* ugly call from render */ +void set_mblur_offs(float blur) { - bluroffs= R.r.blurfac*((float)blur); - bluroffs/= (float)R.r.osa; + bluroffs= blur; } void disable_speed_curve(int val) @@ -987,19 +1012,14 @@ float bsystem_time(Object *ob, Object *par, float cfra, float ofs) /* returns float ( see frame_to_float in ipo.c) */ /* 2nd field */ - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_FIELDSTILL); else cfra+= .5; - } +// if(R.flag & R_SEC_FIELD) { +// if(R.r.mode & R_FIELDSTILL); else cfra+= .5; +// } + cfra+= bluroffs; - if(ob && (ob->flag & OB_FROMDUPLI)); - else { - /* motion blur */ - cfra+= bluroffs; - - /* global time */ - cfra*= G.scene->r.framelen; - } + /* global time */ + cfra*= G.scene->r.framelen; if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra); @@ -1081,7 +1101,7 @@ void ob_parcurve(Object *ob, Object *par, float mat[][4]) Mat4One(mat); cu= par->data; - if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file */ + if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */ makeDispListCurveTypes(par, 0); if(cu->path==NULL) return; @@ -1514,9 +1534,6 @@ void solve_tracking (Object *ob, float targetmat[][4]) void where_is_object(Object *ob) { - /* these have been mem copied */ - if(ob->flag & OB_FROMDUPLI) return; - where_is_object_time(ob, (float)G.scene->r.cfra); } diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index f0058ee6ad0..cb47c43da06 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -52,24 +52,19 @@ #include "DNA_sound_types.h" #include "DNA_vfont_types.h" #include "DNA_packedFile_types.h" - +#include "DNA_scene_types.h" #include "BLI_blenlib.h" #include "BKE_utildefines.h" -#include "BKE_bad_level_calls.h" - #include "BKE_global.h" #include "BKE_main.h" - #include "BKE_screen.h" - #include "BKE_sound.h" -//#include "sound.h" - #include "BKE_image.h" #include "BKE_font.h" #include "BKE_packedFile.h" +#include "BKE_bad_level_calls.h" /* <- waitcursor */ int seekPackedFile(PackedFile * pf, int offset, int whence) { @@ -309,7 +304,7 @@ int writePackedFile(char * filename, PackedFile *pf) } // make sure the path to the file exists... - RE_make_existing_file(name); + BLI_make_existing_file(name); file = open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666); if (file >= 0) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 53b4a09d89b..492c1b1c264 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -65,17 +65,19 @@ #include "BKE_constraint.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_object.h" #include "BKE_scene.h" #include "BKE_world.h" #include "BKE_utildefines.h" #include "BPY_extern.h" - +#include "BLI_arithb.h" #include "BLI_blenlib.h" #include "nla.h" @@ -112,6 +114,8 @@ void free_qtcodecdata(QuicktimeCodecData *qcd) } } +/* copy_scene moved to src/header_info.c... should be back */ + /* do not free scene itself */ void free_scene(Scene *sce) { @@ -142,6 +146,7 @@ void free_scene(Scene *sce) } BLI_freelistN(&sce->markers); + BLI_freelistN(&sce->r.layers); if(sce->toolsettings){ MEM_freeN(sce->toolsettings); @@ -152,6 +157,11 @@ void free_scene(Scene *sce) free_forest(sce->theDag); MEM_freeN(sce->theDag); } + + if(sce->nodetree) { + ntreeFreeTree(sce->nodetree); + MEM_freeN(sce->nodetree); + } } Scene *add_scene(char *name) @@ -171,8 +181,8 @@ Scene *add_scene(char *name) sce->r.ysch= 256; sce->r.xasp= 1; sce->r.yasp= 1; - sce->r.xparts= 1; - sce->r.yparts= 1; + sce->r.xparts= 4; + sce->r.yparts= 4; sce->r.size= 100; sce->r.planes= 24; sce->r.quality= 90; @@ -217,19 +227,21 @@ Scene *add_scene(char *name) BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f); sce->r.osa= 8; + scene_add_render_layer(sce); + return sce; } -int object_in_scene(Object *ob, Scene *sce) +Base *object_in_scene(Object *ob, Scene *sce) { Base *base; base= sce->base.first; while(base) { - if(base->object == ob) return 1; + if(base->object == ob) return base; base= base->next; } - return 0; + return NULL; } void set_scene_bg(Scene *sce) @@ -275,12 +287,11 @@ void set_scene_bg(Scene *sce) base->flag |= flag; ob->flag= base->flag; - ob->recalc= OB_RECALC; ob->ctime= -1234567.0; /* force ipo to be calculated later */ base= base->next; } - // full update + // full animation update scene_update_for_newframe(sce, sce->lay); /* do we need FRAMECHANGED in set_scene? */ @@ -306,23 +317,21 @@ void set_scene_name(char *name) */ int next_object(int val, Base **base, Object **ob) { - extern ListBase duplilist; - static Object *dupob; + static ListBase *duplilist= NULL; + static DupliObject *dupob; static int fase; int run_again=1; /* init */ if(val==0) { fase= F_START; - dupob= 0; + dupob= NULL; } else { /* run_again is set when a duplilist has been ended */ while(run_again) { run_again= 0; - - /* the first base */ if(fase==F_START) { @@ -357,30 +366,40 @@ int next_object(int val, Base **base, Object **ob) } } - if(*base == 0) fase= F_START; + if(*base == NULL) fase= F_START; else { if(fase!=F_DUPLI) { if( (*base)->object->transflag & OB_DUPLI) { - make_duplilist(G.scene, (*base)->object); - dupob= duplilist.first; + duplilist= object_duplilist(G.scene, (*base)->object); + + dupob= duplilist->first; } } /* handle dupli's */ if(dupob) { - *ob= dupob; + Mat4CpyMat4(dupob->ob->obmat, dupob->mat); + + (*base)->flag |= OB_FROMDUPLI; + *ob= dupob->ob; fase= F_DUPLI; - dupob= dupob->id.next; + dupob= dupob->next; } else if(fase==F_DUPLI) { fase= F_SCENE; - free_duplilist(); + (*base)->flag &= ~OB_FROMDUPLI; + + for(dupob= duplilist->first; dupob; dupob= dupob->next) { + Mat4CpyMat4(dupob->ob->obmat, dupob->omat); + } + + BLI_freelistN(duplilist); + duplilist= NULL; run_again= 1; } - } } } @@ -465,3 +484,20 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay) setcount++; } } + +/* return default layer, also used to patch old files */ +void scene_add_render_layer(Scene *sce) +{ + SceneRenderLayer *srl; + int tot= 1 + BLI_countlist(&sce->r.layers); + + srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer"); + sprintf(srl->name, "%d RenderLayer", tot); + BLI_addtail(&sce->r.layers, srl); + + /* note, this is also in render, pipeline.c, to make layer when scenedata doesnt have it */ + srl->lay= (1<<20) -1; + srl->layflag= 0x7FFF; /* solid ztra halo strand */ + srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z; +} + diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 5b98a3bf794..d81c0e94944 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -546,7 +546,7 @@ static void softbody_calc_forces(Object *ob, float forcetime) /* check! */ do_deflector= is_there_deflection(ob->lay); - do_effector= pdInitEffectors(ob); + do_effector= pdInitEffectors(ob, NULL); iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */ bproot= sb->bpoint; /* need this for proper spring addressing */ diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index ea0134470f1..2633bbd2779 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -39,6 +39,7 @@ #include "BLI_blenlib.h" +#include "DNA_scene_types.h" #include "DNA_text_types.h" #include "BKE_bad_level_calls.h" diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index a228e3cad04..aa36c0a5083 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -57,6 +57,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_image_types.h" +#include "DNA_world_types.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -74,6 +75,7 @@ #include "BKE_material.h" #include "BKE_texture.h" #include "BKE_key.h" +#include "BKE_icons.h" #include "BKE_ipo.h" @@ -157,6 +159,10 @@ void open_plugin_tex(PluginTex *pit) /* ------------------------------------------------------------------------- */ +/* very badlevel define to bypass linking with BIF_interface.h */ +#define INT 96 +#define FLO 128 + PluginTex *add_plugin_tex(char *str) { PluginTex *pit; @@ -196,27 +202,72 @@ void free_plugin_tex(PluginTex *pit) MEM_freeN(pit); } +/* ****************** Mapping ******************* */ + +TexMapping *add_mapping(void) +{ + TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "Tex map"); + + texmap->size[0]= texmap->size[1]= texmap->size[2]= 1.0f; + texmap->max[0]= texmap->max[1]= texmap->max[2]= 1.0f; + Mat4One(texmap->mat); + + return texmap; +} + +void init_mapping(TexMapping *texmap) +{ + float eul[3], smat[3][3], rmat[3][3], mat[3][3]; + + SizeToMat3(texmap->size, smat); + + eul[0]= (M_PI/180.0f)*texmap->rot[0]; + eul[1]= (M_PI/180.0f)*texmap->rot[1]; + eul[2]= (M_PI/180.0f)*texmap->rot[2]; + EulToMat3(eul, rmat); + + Mat3MulMat3(mat, rmat, smat); + + Mat4CpyMat3(texmap->mat, mat); + VECCOPY(texmap->mat[3], texmap->loc); + +} + /* ****************** COLORBAND ******************* */ -ColorBand *add_colorband() +ColorBand *add_colorband(int rangetype) { ColorBand *coba; int a; coba= MEM_callocN( sizeof(ColorBand), "colorband"); - coba->data[0].r= 0.0; - coba->data[0].g= 0.0; - coba->data[0].b= 0.0; - coba->data[0].a= 0.0; coba->data[0].pos= 0.0; - - coba->data[1].r= 0.0; - coba->data[1].g= 1.0; - coba->data[1].b= 1.0; - coba->data[1].a= 1.0; coba->data[1].pos= 1.0; + if(rangetype==0) { + coba->data[0].r= 0.0; + coba->data[0].g= 0.0; + coba->data[0].b= 0.0; + coba->data[0].a= 0.0; + + coba->data[1].r= 0.0; + coba->data[1].g= 1.0; + coba->data[1].b= 1.0; + coba->data[1].a= 1.0; + } + else { + coba->data[0].r= 0.0; + coba->data[0].g= 0.0; + coba->data[0].b= 0.0; + coba->data[0].a= 1.0; + + coba->data[1].r= 1.0; + coba->data[1].g= 1.0; + coba->data[1].b= 1.0; + coba->data[1].a= 1.0; + } + for(a=2; adata[a].r= 0.5; coba->data[a].g= 0.5; @@ -335,7 +386,9 @@ void free_texture(Tex *tex) { free_plugin_tex(tex->plugin); if(tex->coba) MEM_freeN(tex->coba); - if(tex->env) RE_free_envmap(tex->env); + if(tex->env) BKE_free_envmap(tex->env); + BKE_icon_delete((struct ID*)tex); + tex->id.icon_id = 0; } /* ------------------------------------------------------------------------- */ @@ -479,7 +532,7 @@ Tex *copy_texture(Tex *tex) } if(texn->coba) texn->coba= MEM_dupallocN(texn->coba); - if(texn->env) texn->env= RE_copy_envmap(texn->env); + if(texn->env) texn->env= BKE_copy_envmap(texn->env); return texn; } @@ -666,3 +719,69 @@ Tex *give_current_texture(Object *ob, int act) return tex; } + + +/* ------------------------------------------------------------------------- */ + +EnvMap *BKE_add_envmap(void) +{ + EnvMap *env; + + env= MEM_callocN(sizeof(EnvMap), "envmap"); + env->type= ENV_CUBE; + env->stype= ENV_STATIC; + env->clipsta= 0.1; + env->clipend= 100.0; + env->cuberes= 100; + + return env; +} + +/* ------------------------------------------------------------------------- */ + +EnvMap *BKE_copy_envmap(EnvMap *env) +{ + EnvMap *envn; + int a; + + envn= MEM_dupallocN(env); + envn->ok= 0; + for(a=0; a<6; a++) envn->cube[a]= 0; + if(envn->ima) id_us_plus((ID *)envn->ima); + + return envn; +} + +/* ------------------------------------------------------------------------- */ + +void BKE_free_envmapdata(EnvMap *env) +{ + Image *ima; + unsigned int a, part; + + for(part=0; part<6; part++) { + ima= env->cube[part]; + if(ima) { + if(ima->ibuf) IMB_freeImBuf(ima->ibuf); + + for(a=0; amipmap); a++) { + if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]); + } + MEM_freeN(ima); + env->cube[part]= 0; + } + } + env->ok= 0; +} + +/* ------------------------------------------------------------------------- */ + +void BKE_free_envmap(EnvMap *env) +{ + + BKE_free_envmapdata(env); + MEM_freeN(env); + +} + +/* ------------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 9f46b697cab..3ff980110e7 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -55,6 +55,7 @@ #include "BKE_world.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_icons.h" #include "BPY_extern.h" @@ -75,6 +76,8 @@ void free_world(World *wrld) if(mtex) MEM_freeN(mtex); } wrld->ipo= 0; + BKE_icon_delete((struct ID*)wrld); + wrld->id.icon_id = 0; } @@ -175,38 +178,3 @@ void make_local_world(World *wrld) } } } - - -void init_render_world() -{ - int a; - char *cp; - - if(G.scene->world) { - R.wrld= *(G.scene->world); - - cp= (char *)&R.wrld.fastcol; - - cp[0]= 255.0*R.wrld.horr; - cp[1]= 255.0*R.wrld.horg; - cp[2]= 255.0*R.wrld.horb; - cp[3]= 1; - - VECCOPY(R.grvec, R.viewmat[2]); - Normalise(R.grvec); - Mat3CpyMat4(R.imat, R.viewinv); - - for(a=0; atex) R.wrld.skytype |= WO_SKYTEX; - - while(R.wrld.aosamp*R.wrld.aosamp < R.osa) R.wrld.aosamp++; - } - else { - memset(&R.wrld, 0, sizeof(World)); - R.wrld.exp= 0.0; - R.wrld.range= 1.0; - } - - R.wrld.linfac= 1.0 + pow((2.0*R.wrld.exp + 0.5), -10); - R.wrld.logfac= log( (R.wrld.linfac-1.0)/R.wrld.linfac )/R.wrld.range; -} diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index 77c35cc46ab..d754a694d5d 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -1,5 +1,6 @@ /** * Functions for writing avi-format files. + * Added interface for generic movie support (ton) * * $Id$ * @@ -35,73 +36,104 @@ #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" + #include "BLI_blenlib.h" +#include "BKE_global.h" +#include "BKE_writeavi.h" + #include "AVI_avi.h" -#include "BKE_bad_level_calls.h" -#include "BKE_global.h" -#include "IMB_imbuf_types.h" -#include "IMB_imbuf.h" +/* ********************** general blender movie support ***************************** */ -/* RPW 11-21-2002 */ -#include "DNA_scene_types.h" -/* RPW - End */ +#ifdef WITH_QUICKTIME +#include "quicktime_export.h" +#endif + +bMovieHandle *BKE_get_movie_handle(int imtype) +{ + static bMovieHandle mh; + + /* set the default handle, as builtin */ + mh.start_movie= start_avi; + mh.append_movie= append_avi; + mh.end_movie= end_avi; + + /* do the platform specific handles */ +#ifdef __sgi + if (imtype == R_MOVIE) { + + } +#endif +#if defined(_WIN32) && !defined(FREE_WINDOWS) + if (imtype == R_AVICODEC) { + + } +#endif +#ifdef WITH_QUICKTIME + if (imtype == R_QUICKTIME) { + mh.start_movie= start_qt; + mh.append_movie= append_qt; + mh.end_movie= end_qt; + } +#endif + + return &mh; +} + +/* ****************************************************************** */ -#include "BKE_writeavi.h" static AviMovie *avi=NULL; static int sframe; -void makeavistring (char *string) +void makeavistring (RenderData *rd, char *string) { char txt[64]; if (string==0) return; - strcpy(string, G.scene->r.pic); - BLI_convertstringcode(string, G.sce, G.scene->r.cfra); + strcpy(string, rd->pic); + BLI_convertstringcode(string, G.sce, rd->cfra); - RE_make_existing_file(string); + BLI_make_existing_file(string); if (BLI_strcasecmp(string + strlen(string) - 4, ".avi")) { - sprintf(txt, "%04d_%04d.avi", (G.scene->r.sfra) , (G.scene->r.efra) ); + sprintf(txt, "%04d_%04d.avi", (rd->sfra) , (rd->efra) ); strcat(string, txt); } } -void start_avi(void) +void start_avi(RenderData *rd, int rectx, int recty) { int x, y; char name[256]; AviFormat format; int quality, framerate; - makeavistring(name); + makeavistring(rd, name); - sframe = (G.scene->r.sfra); - x = R.rectx; - y = R.recty; + sframe = (rd->sfra); + x = rectx; + y = recty; - quality= R.r.quality; - framerate= R.r.frs_sec; + quality= rd->quality; + framerate= rd->frs_sec; avi = MEM_mallocN (sizeof(AviMovie), "avimovie"); /* RPW 11-21-2002 - if (R.r.imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB; + if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB; */ - if (R.r.imtype != R_AVIJPEG ) format = AVI_FORMAT_AVI_RGB; + if (rd->imtype != R_AVIJPEG ) format = AVI_FORMAT_AVI_RGB; else format = AVI_FORMAT_MJPEG; if (AVI_open_compress (name, avi, 1, format) != AVI_ERROR_NONE) { - error("open movie"); + printf("cannot open or start AVI movie file"); MEM_freeN (avi); avi = NULL; return; @@ -114,36 +146,45 @@ void start_avi(void) avi->interlace= 0; avi->odd_fields= 0; -/* avi->interlace= R.r.mode & R_FIELDS; */ -/* avi->odd_fields= (R.r.mode & R_ODDFIELD)?1:0; */ +/* avi->interlace= rd->mode & R_FIELDS; */ +/* avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */ printf("Created avi: %s\n", name); } -void append_avi(int frame) +void append_avi(int frame, int *pixels, int rectx, int recty) { - unsigned int *rt1, *rt2, *temp; - int y; - + unsigned int *rt1, *rt2, *rectot; + int x, y; + char *cp, rt; + if (avi == NULL) { G.afbreek = 1; return; } - /* note that libavi free's the buffer... stupid interface - zr */ - temp = MEM_mallocN(R.rectx*R.recty*4, "append_avi buf"); - - rt1= temp; - rt2= R.rectot + (R.recty-1)*R.rectx; - for (y=0; y < R.recty; y++, rt1+= R.rectx, rt2-= R.rectx) { - memcpy (rt1, rt2, R.rectx*4); + /* note that libavi free's the buffer... stupid interface - zr */ + rectot= MEM_mallocN(rectx*recty*sizeof(int), "rectot"); + rt1= rectot; + rt2= pixels + (recty-1)*rectx; + /* flip y and convert to abgr */ + for (y=0; y < recty; y++, rt1+= rectx, rt2-= rectx) { + memcpy (rt1, rt2, rectx*sizeof(int)); + + cp= (char *)rt1; + for(x= rectx; x>0; x--) { + rt= cp[0]; + cp[0]= cp[3]; + cp[3]= rt; + rt= cp[1]; + cp[1]= cp[2]; + cp[2]= rt; + cp+= 4; + } } - - IMB_convert_rgba_to_abgr(R.rectx*R.recty, temp); - AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, - temp, R.rectx*R.recty*4); - printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); + AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, rectot, rectx*recty*4); +// printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); } void end_avi(void) diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 15ab7825cf6..c920d7127ae 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -93,6 +93,7 @@ extern "C" { char *BLI_gethome(void); void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file); void BLI_make_exist(char *dir); +void BLI_make_existing_file(char *name); void BLI_split_dirfile(char *string, char *dir, char *file); int BLI_testextensie(char *str, char *ext); void addlisttolist(ListBase *list1, ListBase *list2); @@ -111,6 +112,13 @@ int BLI_countlist(struct ListBase *listbase); void BLI_freelinkN(ListBase *listbase, void *vlink); void BLI_splitdirstring(char *di,char *fi); + /** + * dir can be any input, like from buttons, and this function + * converts it to a regular full path. + * Also removes garbage from directory paths, like /../ or double slashes etc + */ +void BLI_cleanup_dir(const char *relabase, char *dir); + /** * Blender's path code replacement function. * Bases @a path strings leading with "//" by the @@ -123,7 +131,7 @@ void BLI_splitdirstring(char *di,char *fi); * @a framenum The framenumber to replace the frame code with. * @retval Returns true if the path was relative (started with "//"). */ -int BLI_convertstringcode(char *path, char *basepath, int framenum); +int BLI_convertstringcode(char *path, const char *basepath, int framenum); void BLI_makestringcode(const char *relfile, char *file); @@ -270,13 +278,15 @@ char *BLI_last_slash(char *string); * * @return True if @a rect is empty. */ -int BLI_rcti_is_empty(struct rcti * rect); +int BLI_rcti_is_empty(struct rcti * rect); void BLI_init_rctf(struct rctf *rect, float xmin, float xmax, float ymin, float ymax); +void BLI_init_rcti(struct rcti *rect, int xmin, int xmax, int ymin, int ymax); +void BLI_translate_rctf(struct rctf *rect, float x, float y); +void BLI_translate_rcti(struct rcti *rect, int x, int y); int BLI_in_rcti(struct rcti * rect, int x, int y); int BLI_in_rctf(struct rctf *rect, float x, float y); int BLI_isect_rctf(struct rctf *src1, struct rctf *src2, struct rctf *dest); -/* why oh why doesn't this work? */ -//void BLI_union_rctf(struct rctf *rct1, struct rctf *rct2); +int BLI_isect_rcti(struct rcti *src1, struct rcti *src2, struct rcti *dest); void BLI_union_rctf(struct rctf *rcta, struct rctf *rctb); /* scanfill.c: used in displist only... */ @@ -329,6 +339,7 @@ void BLI_setInterruptCallBack(int (*f)(void)); int BLI_strcasecmp(const char *s1, const char *s2); int BLI_strncasecmp(const char *s1, const char *s2, int n); +void BLI_timestr(double time, char *str); #define PRNTSUB(type,arg) printf(#arg ": %" #type " ", arg) diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 5e393570e94..315498bab4c 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -43,7 +43,18 @@ struct DerivedMesh; /* note; changing this also might affect the undo copy in editmesh.c */ typedef struct EditVert { - struct EditVert *next, *prev, *vn; + struct EditVert *next, *prev; + union { + /* some lean storage for temporary usage + * in editmesh routines + */ + struct EditVert *v; + struct EditEdge *e; + struct EditFace *f; + float *fp; + void *p; + long l; + } tmp; float no[3]; float co[3]; short xs, ys; @@ -66,7 +77,17 @@ typedef struct HashEdge { typedef struct EditEdge { struct EditEdge *next, *prev; - struct EditVert *v1, *v2, *vn; + struct EditVert *v1, *v2; + union { + /* some lean storage for temporary usage + * in editmesh routines + */ + struct EditVert *v; + struct EditEdge *e; + struct EditFace *f; + void *p; + long l; + } tmp; short f1, f2; /* short, f1 is (ab)used in subdiv */ unsigned char f, h, dir, seam; float crease; @@ -81,6 +102,16 @@ typedef struct EditFace struct EditFace *next, *prev; struct EditVert *v1, *v2, *v3, *v4; struct EditEdge *e1, *e2, *e3, *e4; + union { + /* some lean storage for temporary usage + * in editmesh routines + */ + struct EditVert *v; + struct EditEdge *e; + struct EditFace *f; + void *p; + long l; + } tmp; float n[3], cent[3]; struct TFace tf; /* a copy of original tface. */ unsigned char mat_nr, flag; diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index d2f2bcc95e4..ce5be5fc311 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -48,6 +48,7 @@ GHash* BLI_ghash_new (GHashHashFP hashfp, GHashCmpFP cmpfp); void BLI_ghash_free (GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); void BLI_ghash_insert (GHash *gh, void *key, void *val); +int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); void* BLI_ghash_lookup (GHash *gh, void *key); int BLI_ghash_haskey (GHash *gh, void *key); @@ -110,5 +111,8 @@ int BLI_ghashutil_ptrcmp (void *a, void *b); unsigned int BLI_ghashutil_strhash (void *key); int BLI_ghashutil_strcmp (void *a, void *b); +unsigned int BLI_ghashutil_inthash (void *ptr); +int BLI_ghashutil_intcmp(void *a, void *b); + #endif diff --git a/source/blender/include/BSE_buttons.h b/source/blender/blenlib/BLI_jitter.h similarity index 66% rename from source/blender/include/BSE_buttons.h rename to source/blender/blenlib/BLI_jitter.h index 63ac472f032..1cd4880d0b7 100644 --- a/source/blender/include/BSE_buttons.h +++ b/source/blender/blenlib/BLI_jitter.h @@ -1,15 +1,14 @@ -/** +/* + * jitter.h + * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,13 +26,15 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ -#ifndef BSE_BUTTONS_H -#define BSE_BUTTONS_H +#ifndef BLI_JITTER_H +#define BLI_JITTER_H -void clever_numbuts_buts(); +extern void BLI_initjit(float *jitarr, int num); +extern void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1); +extern void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2); -#endif /* BSE_BUTTONS_H */ +#endif diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 379817cc322..8b8740a2e6b 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -25,6 +25,7 @@ source_files = ['intern/BLI_dynstr.c', 'intern/util.c', 'intern/vectorops.c', 'intern/freetypefont.c', + 'intern/jitter.c', 'intern/winstuff.c'] diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 23e21d4fb45..bc0f79d2cc4 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -128,6 +128,34 @@ void* BLI_ghash_lookup(GHash *gh, void *key) { return NULL; } +int BLI_ghash_remove (GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) +{ + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + Entry *p = 0; + + for (e= gh->buckets[hash]; e; e= e->next) { + if (gh->cmpfp(key, e->key)==0) { + Entry *n= e->next; + + if (keyfreefp) keyfreefp(e->key); + if (valfreefp) valfreefp(e->val); + free(e); + + + e= n; + if (p) + p->next = n; + else + gh->buckets[hash] = n; + return 1; + } + p = e; + } + + return 0; +} + int BLI_ghash_haskey(GHash *gh, void *key) { unsigned int hash= gh->hashfp(key)%gh->nbuckets; Entry *e; @@ -161,6 +189,9 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef } free(gh->buckets); + gh->buckets = 0; + gh->nentries = 0; + gh->nbuckets = 0; MEM_freeN(gh); } @@ -223,6 +254,30 @@ int BLI_ghashutil_ptrcmp(void *a, void *b) { return (a> 5); + key += (key << 3); + key ^= (key >> 13); + key += ~(key << 9); + key ^= (key >> 17); + + return (unsigned int)(key & 0xffffffff); +} + +int BLI_ghashutil_intcmp(void *a, void *b) { + if (a==b) + return 0; + else + return (a @@ -39,16 +36,10 @@ #include "BLI_arithb.h" #include "BLI_rand.h" -#include "render.h" -#include "jitter.h" +#include "BLI_jitter.h" -float jit[64][2]; - -void init_render_jit(int nr); - - -void RE_jitterate1(float *jit1, float *jit2, int num, float rad1) +void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1) { int i , j , k; float vecx, vecy, dvecx, dvecy, x, y, len; @@ -106,7 +97,7 @@ void RE_jitterate1(float *jit1, float *jit2, int num, float rad1) memcpy(jit1,jit2,2 * num * sizeof(float)); } -void RE_jitterate2(float *jit1, float *jit2, int num, float rad2) +void BLI_jitterate2(float *jit1, float *jit2, int num, float rad2) { int i, j; float vecx, vecy, dvecx, dvecy, x, y; @@ -146,7 +137,7 @@ void RE_jitterate2(float *jit1, float *jit2, int num, float rad2) } -void initjit(float *jitarr, int num) +void BLI_initjit(float *jitarr, int num) { float *jit2, x, rad1, rad2, rad3; int i; @@ -168,9 +159,9 @@ void initjit(float *jitarr, int num) } for (i=0 ; i<24 ; i++) { - RE_jitterate1(jitarr, jit2, num, rad1); - RE_jitterate1(jitarr, jit2, num, rad1); - RE_jitterate2(jitarr, jit2, num, rad2); + BLI_jitterate1(jitarr, jit2, num, rad1); + BLI_jitterate1(jitarr, jit2, num, rad1); + BLI_jitterate2(jitarr, jit2, num, rad2); } MEM_freeN(jit2); @@ -183,16 +174,5 @@ void initjit(float *jitarr, int num) } -void init_render_jit(int nr) -{ - static int lastjit= 0; - - if(lastjit==nr) return; - - memset(jit, 0, 64*2*4); - initjit(jit[0], nr); - - lastjit= nr; -} /* eof */ diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index 1b19a6b769d..60d96922544 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -87,6 +87,28 @@ void BLI_init_rctf(rctf *rect, float xmin, float xmax, float ymin, float ymax) rect->ymin= ymin; rect->ymax= ymax; } +void BLI_init_rcti(rcti *rect, int xmin, int xmax, int ymin, int ymax) +{ + rect->xmin= xmin; + rect->xmax= xmax; + rect->ymin= ymin; + rect->ymax= ymax; +} + +void BLI_translate_rcti(rcti *rect, int x, int y) +{ + rect->xmin += x; + rect->ymin += y; + rect->xmax += x; + rect->ymax += y; +} +void BLI_translate_rctf(rctf *rect, float x, float y) +{ + rect->xmin += x; + rect->ymin += y; + rect->xmax += x; + rect->ymax += y; +} int BLI_isect_rctf(rctf *src1, rctf *src2, rctf *dest) { @@ -117,3 +139,33 @@ int BLI_isect_rctf(rctf *src1, rctf *src2, rctf *dest) return 0; } } + +int BLI_isect_rcti(rcti *src1, rcti *src2, rcti *dest) +{ + int xmin, xmax; + int ymin, ymax; + + xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin); + xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax); + ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin); + ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax); + + if(xmax>=xmin && ymax>=ymin) { + if(dest) { + dest->xmin = xmin; + dest->xmax = xmax; + dest->ymin = ymin; + dest->ymax = ymax; + } + return 1; + } + else { + if(dest) { + dest->xmin = 0; + dest->xmax = 0; + dest->ymin = 0; + dest->ymax = 0; + } + return 0; + } +} diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 90ada479ca5..1e11bec25ff 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -581,18 +581,18 @@ static void scanfill(PolyFill *pf, int mat_nr) if(eed->v1->co[coy]==eed->v2->co[coy]) { if(eed->v1->f==255 && eed->v2->f!=255) { eed->v2->f= 255; - eed->v2->vn= eed->v1->vn; + eed->v2->tmp.v= eed->v1->tmp.v; } else if(eed->v2->f==255 && eed->v1->f!=255) { eed->v1->f= 255; - eed->v1->vn= eed->v2->vn; + eed->v1->tmp.v= eed->v2->tmp.v; } else if(eed->v2->f==255 && eed->v1->f==255) { - eed->v1->vn= eed->v2->vn; + eed->v1->tmp.v= eed->v2->tmp.v; } else { eed->v2->f= 255; - eed->v2->vn= eed->v1; + eed->v2->tmp.v = eed->v1; } } } @@ -627,11 +627,13 @@ static void scanfill(PolyFill *pf, int mat_nr) BLI_remlink(&filledgebase,eed); if(eed->v1->f==255) { v1= eed->v1; - while(eed->v1->f==255 && eed->v1->vn!=v1) eed->v1= eed->v1->vn; + while((eed->v1->f == 255) && (eed->v1->tmp.v != v1)) + eed->v1 = eed->v1->tmp.v; } if(eed->v2->f==255) { v2= eed->v2; - while(eed->v2->f==255 && eed->v2->vn!=v2) eed->v2= eed->v2->vn; + while((eed->v2->f == 255) && (eed->v2->tmp.v != v2)) + eed->v2 = eed->v2->tmp.v; } if(eed->v1!=eed->v2) addedgetoscanlist(eed,verts); @@ -808,7 +810,7 @@ int BLI_edgefill(int mode, int mat_nr) { /* - fill works with its own lists, so create that first (no faces!) - - for vertices, put in ->vn the old pointer + - for vertices, put in ->tmp.v the old pointer - struct elements xs en ys are not used here: don't hide stuff in it - edge flag ->f becomes 2 when it's a new edge - mode: & 1 is check for crossings, then create edges (TO DO ) @@ -980,10 +982,10 @@ int BLI_edgefill(int mode, int mat_nr) /* CURRENT STATUS: - - eve->f :1= availalble in edges - - eve->xs :polynumber - - eve->h :amount of edges connected to vertex - - eve->vn :store! original vertex number + - eve->f :1= availalble in edges + - eve->xs :polynumber + - eve->h :amount of edges connected to vertex + - eve->tmp.v :store! original vertex number - eed->f : - eed->f1 :poly number diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 74e8e575fda..d6ed130c9bc 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -139,6 +139,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen) else if (BLI_strncasecmp(string + len - 4, ".rgb", 4) == 0) len -= 4; else if (BLI_strncasecmp(string + len - 4, ".psx", 4) == 0) len -= 4; else if (BLI_strncasecmp(string + len - 4, ".ble", 4) == 0) len -= 4; + else if (BLI_strncasecmp(string + len - 4, ".exr", 4) == 0) len -= 4; } } @@ -431,6 +432,96 @@ int BLI_strcaseeq(char *a, char *b) { return (BLI_strcasecmp(a, b)==0); } +/* ******************** string encoding ***************** */ + +/* This is quite an ugly function... its purpose is to + * take the dir name, make it absolute, and clean it up, replacing + * excess file entry stuff (like /tmp/../tmp/../) + * note that dir isn't protected for max string names... + */ + +void BLI_cleanup_dir(const char *relabase, char *dir) +{ + short a; + char *start, *eind; + + BLI_convertstringcode(dir, relabase, 0); + +#ifdef WIN32 + if(dir[0]=='.') { /* happens for example in FILE_MAIN */ + dir[0]= '\\'; + dir[1]= 0; + return; + } + + while ( (start = strstr(dir, "\\..\\")) ) { + eind = start + strlen("\\..\\") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '\\') break; + a--; + } + strcpy(dir+a,eind); + } + + while ( (start = strstr(dir,"\\.\\")) ){ + eind = start + strlen("\\.\\") - 1; + strcpy(start,eind); + } + + while ( (start = strstr(dir,"\\\\" )) ){ + eind = start + strlen("\\\\") - 1; + strcpy(start,eind); + } + + if((a = strlen(dir))){ /* remove the '\\' at the end */ + while(a>0 && dir[a-1] == '\\'){ + a--; + dir[a] = 0; + } + } + + strcat(dir, "\\"); +#else + if(dir[0]=='.') { /* happens, for example in FILE_MAIN */ + dir[0]= '/'; + dir[1]= 0; + return; + } + + while ( (start = strstr(dir, "/../")) ) { + eind = start + strlen("/../") - 1; + a = start-dir-1; + while (a>0) { + if (dir[a] == '/') break; + a--; + } + strcpy(dir+a,eind); + } + + while ( (start = strstr(dir,"/./")) ){ + eind = start + strlen("/./") - 1; + strcpy(start,eind); + } + + while ( (start = strstr(dir,"//" )) ){ + eind = start + strlen("//") - 1; + strcpy(start,eind); + } + + if( (a = strlen(dir)) ){ /* remove all '/' at the end */ + while(dir[a-1] == '/'){ + a--; + dir[a] = 0; + if (a<=0) break; + } + } + + strcat(dir, "/"); +#endif +} + + void BLI_makestringcode(const char *relfile, char *file) { char * p; @@ -491,7 +582,7 @@ void BLI_makestringcode(const char *relfile, char *file) } strcat(res, q+1); /* don't copy the slash at the beginning */ - + #ifdef WIN32 BLI_char_switch(res+2, '/', '\\'); #endif @@ -499,7 +590,7 @@ void BLI_makestringcode(const char *relfile, char *file) } } -int BLI_convertstringcode(char *path, char *basepath, int framenum) +int BLI_convertstringcode(char *path, const char *basepath, int framenum) { int len, wasrelative; char tmp[FILE_MAXDIR+FILE_MAXFILE]; @@ -690,6 +781,20 @@ void BLI_make_exist(char *dir) { #endif } +void BLI_make_existing_file(char *name) +{ + char di[FILE_MAXDIR], fi[FILE_MAXFILE]; + + strcpy(di, name); + BLI_splitdirstring(di, fi); + + /* test exist */ + if (BLI_exists(di) == 0) { + BLI_recurdir_fileops(di); + } +} + + void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file) { @@ -1028,3 +1133,22 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) { return 0; } + +void BLI_timestr(double time, char *str) +{ + /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ + int hr= (int) time/(60*60); + int min= (int) fmod(time/60, 60.0); + int sec= (int) fmod(time, 60.0); + int hun= (int) fmod(time*100.0, 100.0); + + if (hr) { + sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun); + } else { + sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun); + } + + str[11]=0; +} + + diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 2c216f122cc..29650953641 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -116,6 +116,10 @@ BlendFileData* BLO_read_from_file (char *file, BlendReadError *error_r); */ BlendFileData* BLO_read_from_memory(void *mem, int memsize, BlendReadError *error_r); +/** + * file name is current file, only for retrieving library data */ + +BlendFileData *BLO_read_from_memfile(const char *filename, struct MemFile *memfile, BlendReadError *error_r); /** * Convert a BlendReadError to a human readable string. @@ -126,8 +130,6 @@ BlendFileData* BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro * of @a error. */ -BlendFileData *BLO_read_from_memfile(struct MemFile *memfile, BlendReadError *error_r); - char* BLO_bre_as_string( BlendReadError error); diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index ceb226f67fb..2da43013318 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -83,7 +83,7 @@ static IDType idtypes[]= { { ID_AR, "Armature", IDTYPE_FLAGS_ISLINKABLE}, { ID_CA, "Camera", IDTYPE_FLAGS_ISLINKABLE}, { ID_CU, "Curve", IDTYPE_FLAGS_ISLINKABLE}, - { ID_GR, "Group", 0}, + { ID_GR, "Group", IDTYPE_FLAGS_ISLINKABLE}, { ID_ID, "ID", 0}, { ID_IM, "Image", IDTYPE_FLAGS_ISLINKABLE}, { ID_IP, "Ipo", IDTYPE_FLAGS_ISLINKABLE}, @@ -95,6 +95,7 @@ static IDType idtypes[]= { { ID_MA, "Material", IDTYPE_FLAGS_ISLINKABLE}, { ID_MB, "Metaball", IDTYPE_FLAGS_ISLINKABLE}, { ID_ME, "Mesh", IDTYPE_FLAGS_ISLINKABLE}, + { ID_NT, "NodeTree", IDTYPE_FLAGS_ISLINKABLE}, { ID_OB, "Object", IDTYPE_FLAGS_ISLINKABLE}, { ID_SAMPLE, "Sample", 0}, { ID_SCE, "Scene", IDTYPE_FLAGS_ISLINKABLE}, @@ -287,13 +288,14 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro return bfd; } -BlendFileData *BLO_read_from_memfile(MemFile *memfile, BlendReadError *error_r) +BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, BlendReadError *error_r) { BlendFileData *bfd = NULL; FileData *fd; fd = blo_openblendermemfile(memfile, error_r); if (fd) { + strcpy(fd->filename, filename); bfd= blo_read_file_internal(fd, error_r); if (bfd) { bfd->type= BLENFILETYPE_BLEND; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 96737509092..1d523cbec29 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1,19 +1,12 @@ /* - * readfile.c - * - * .blend file reading - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -31,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** * */ @@ -66,6 +59,7 @@ #include "DNA_ID.h" #include "DNA_actuator_types.h" #include "DNA_camera_types.h" +#include "DNA_color_types.h" #include "DNA_controller_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" @@ -83,6 +77,7 @@ #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_nla_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_object_fluidsim.h" // NT @@ -125,6 +120,7 @@ #include "BKE_main.h" // for Main #include "BKE_mesh.h" // for ME_ defines (patching) #include "BKE_modifier.h" +#include "BKE_node.h" // for tree type defines #include "BKE_object.h" #include "BKE_sca.h" // for init_actuator #include "BKE_scene.h" @@ -133,7 +129,7 @@ #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BIF_butspace.h" // for do_versions, patching event codes - +#include "BIF_previewrender.h" // for struct RenderInfo #include "BLO_readfile.h" #include "BLO_undofile.h" #include "BLO_readblenfile.h" // streaming read pipe, for BLO_readblenfile BLO_readblenfilememory @@ -235,7 +231,7 @@ typedef struct OldNew { typedef struct OldNewMap { OldNew *entries; int nentries, entriessize; - + int sorted; int lasthit; } OldNewMap; @@ -244,19 +240,39 @@ typedef struct OldNewMap { extern short freeN(void *vmemh); /* defined in util.h */ -static OldNewMap *oldnewmap_new(void) { - OldNewMap *onm= MEM_mallocN(sizeof(*onm), "OldNewMap"); - onm->lasthit= 0; - onm->nentries= 0; +static OldNewMap *oldnewmap_new(void) +{ + OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap"); + onm->entriessize= 1024; onm->entries= MEM_mallocN(sizeof(*onm->entries)*onm->entriessize, "OldNewMap.entries"); - + return onm; } -static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr) { +static int verg_oldnewmap(const void *v1, const void *v2) +{ + const struct OldNew *x1=v1, *x2=v2; + + if( x1->old > x2->old) return 1; + else if( x1->old < x2->old) return -1; + return 0; +} + + +static void oldnewmap_sort(FileData *fd) +{ + qsort(fd->libmap->entries, fd->libmap->nentries, sizeof(OldNew), verg_oldnewmap); + fd->libmap->sorted= 1; +} + +/* nr is zero for data, and ID code for libdata */ +static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr) +{ OldNew *entry; + if(oldaddr==NULL || newaddr==NULL) return; + if (onm->nentries==onm->entriessize) { int osize= onm->entriessize; OldNew *oentries= onm->entries; @@ -274,7 +290,8 @@ static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int n entry->nr= nr; } -static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) { +static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) +{ int i; if (onm->lasthitnentries-1) { @@ -300,23 +317,29 @@ static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr) { return NULL; } -static void *oldnewmap_liblookup_and_inc(OldNewMap *onm, void *addr, void *lib) { +/* for libdate, nr has ID code, no increment */ +static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib) +{ int i; - - if (onm->lasthitnentries-1) { - OldNew *entry= &onm->entries[++onm->lasthit]; - - if (entry->old==addr) { + + if(addr==NULL) return NULL; + + /* lasthit works fine for non-libdata, linking there is done in same sequence as writing */ + if(onm->sorted) { + OldNew entry_s, *entry; + + entry_s.old= addr; + + entry= bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap); + if(entry) { ID *id= entry->newp; - + if (id && (!lib || id->lib)) { - entry->nr++; - return entry->newp; } } } - + for (i=0; inentries; i++) { OldNew *entry= &onm->entries[i]; @@ -324,8 +347,6 @@ static void *oldnewmap_liblookup_and_inc(OldNewMap *onm, void *addr, void *lib) ID *id= entry->newp; if (id && (!lib || id->lib)) { - entry->nr++; - return entry->newp; } } @@ -334,41 +355,8 @@ static void *oldnewmap_liblookup_and_inc(OldNewMap *onm, void *addr, void *lib) return NULL; } -static void *oldnewmap_typelookup_and_inc(OldNewMap *onm, void *addr, short type) { - int i; - - if (onm->lasthitnentries-1) { - OldNew *entry= &onm->entries[++onm->lasthit]; - - if (entry->old==addr) { - ID *id= entry->newp; - - if (id && (GS(id->name) == type)) { - entry->nr++; - - return entry->newp; - } - } - } - - for (i=0; inentries; i++) { - OldNew *entry= &onm->entries[i]; - - if (entry->old==addr) { - ID *id= entry->newp; - - if (id && (GS(id->name) == type)) { - entry->nr++; - - return entry->newp; - } - } - } - - return NULL; -} - -static void oldnewmap_free_unused(OldNewMap *onm) { +static void oldnewmap_free_unused(OldNewMap *onm) +{ int i; for (i=0; inentries; i++) { @@ -380,12 +368,14 @@ static void oldnewmap_free_unused(OldNewMap *onm) { } } -static void oldnewmap_clear(OldNewMap *onm) { +static void oldnewmap_clear(OldNewMap *onm) +{ onm->nentries= 0; onm->lasthit= 0; } -static void oldnewmap_free(OldNewMap *onm) { +static void oldnewmap_free(OldNewMap *onm) +{ MEM_freeN(onm->entries); MEM_freeN(onm); } @@ -455,7 +445,6 @@ void blo_split_main(ListBase *mainlist) for (lib= mainl->library.first; lib; lib= lib->id.next) { Main *libmain= MEM_callocN(sizeof(Main), "libmain"); libmain->curlib= lib; - BLI_addtail(mainlist, libmain); } @@ -464,25 +453,35 @@ void blo_split_main(ListBase *mainlist) split_libdata(lbarray[i], mainl->next); } -static Main *blo_find_main(ListBase *mainlist, char *name) +/* removes things like /blah/blah/../../blah/ etc, then writes in *name the full path */ +static void cleanup_path(const char *relabase, char *name) +{ + char filename[FILE_MAXFILE]; + + BLI_splitdirstring(name, filename); + BLI_cleanup_dir(relabase, name); + strcat(name, filename); +} + +static Main *blo_find_main(ListBase *mainlist, const char *name, const char *relabase) { Main *m; Library *lib; char name1[FILE_MAXDIR+FILE_MAXFILE]; char libname1[FILE_MAXDIR+FILE_MAXFILE]; - - /* name can be stringcode too */ + strcpy(name1, name); - BLI_convertstringcode(name1, G.sce, 0); + cleanup_path(relabase, name1); +// printf("blo_find_main: original in %s\n", name); +// printf("blo_find_main: converted to %s\n", name1); for (m= mainlist->first; m; m= m->next) { - char *libname= (m->curlib)?m->curlib->name:m->name; + char *libname= (m->curlib)?m->curlib->filename:m->name; - strcpy(libname1, libname); - BLI_convertstringcode(libname1, G.sce, 0); - - if (BLI_streq(name1, libname1)) + if (BLI_streq(name1, libname)) { + printf("blo_find_main: found library %s\n", libname); return m; + } } m= MEM_callocN(sizeof(Main), "find_main"); @@ -490,8 +489,11 @@ static Main *blo_find_main(ListBase *mainlist, char *name) lib= alloc_libblock(&m->library, ID_LI, "lib"); strcpy(lib->name, name); + strcpy(lib->filename, name1); + m->curlib= lib; - + + printf("blo_find_main: added new lib %s\n", name); return m; } @@ -896,19 +898,13 @@ static FileData *blo_decode_and_check(FileData *fd, BlendReadError *error_r) return fd; } +/* cannot be called with relative paths anymore! */ +/* on each new library added, it now checks for the current FileData and expands relativeness */ FileData *blo_openblenderfile(char *name, BlendReadError *error_r) { gzFile gzfile; - char name1[FILE_MAXDIR+FILE_MAXFILE]; - /* library files can have stringcodes */ - strcpy(name1, name); - if(name[0]=='/' && name[1]=='/') - BLI_convertstringcode(name1, G.sce, 0); - else - strcpy(G.sce, name); // global... is set in blender.c setup_app_data too. should be part of Main immediate? - - gzfile= gzopen(name1, "rb"); + gzfile= gzopen(name, "rb"); if (NULL == gzfile) { *error_r = BRE_UNABLE_TO_OPEN; @@ -1016,18 +1012,7 @@ static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with glob static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ { - return oldnewmap_liblookup_and_inc(fd->libmap, adr, lib); -} - -static void *newlibadr_us_type(FileData *fd, short type, void *adr) /* only Lib data */ -{ - ID *id= oldnewmap_typelookup_and_inc(fd->libmap, adr, type); - - if (id) { - id->us++; - } - - return id; + return oldnewmap_liblookup(fd->libmap, adr, lib); } static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user number */ @@ -1041,51 +1026,36 @@ static void *newlibadr_us(FileData *fd, void *lib, void *adr) /* increases user return id; } -static void change_libadr(FileData *fd, void *old, void *new) +static void change_idid_adr_fd(FileData *fd, void *old, void *new) { int i; - - /* changed one thing here, the old change_libadr - * only remapped addresses that had an id->lib, - * but that doesn't make sense to me... its an - * old pointer, period, it needs to be remapped. - zr - */ - - /* - * Ton seemed to think it was necessary to look - * through all entries, and not return after finding - * a match, leaving this cryptic comment, - * // no return, maybe there can be more? - * - * That doesn't make sense to me either but I am - * too scared to remove it... it only would make - * sense if two distinct old address map to the - * same new address - obviously that shouldn't happen - * because memory addresses are unique. - * - * The only case it might happen is when two distinct - * libraries are mapped using the same table... this - * won't work to start with... At some point this - * all needs to be made sense of and made understandable, - * but I'm afraid I don't have time now. -zr - * - */ - /* the code is nasty, and needs a lot of energy to get into full understanding - again... i now translate dutch comments, maybe that gives me more insight! - But i guess it has to do with the assumption that 2 addresses can be allocated - in different sessions, and therefore be the same... like the remark in the top - of this c file (ton) */ - + for (i=0; ilibmap->nentries; i++) { OldNew *entry= &fd->libmap->entries[i]; - - if (old==entry->newp) { + + if (old==entry->newp && entry->nr==ID_ID) { entry->newp= new; + if(new) entry->nr= GS( ((ID *)new)->name ); break; } } } +static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, void *new) +{ + Main *main; + + for(main= mainlist->first; main; main= main->next) { + FileData *fd; + + if(main->curlib) fd= main->curlib->filedata; + else fd= basefd; + + if(fd) { + change_idid_adr_fd(fd, old, new); + } + } +} /* ********** END OLD POINTERS ****************** */ /* ********** READ FILE ****************** */ @@ -1218,6 +1188,117 @@ static void test_pointer_array(FileData *fd, void **mat) } } +/* ************ READ CurveMapping *************** */ + +/* cuma itself has been read! */ +static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap) +{ + int a; + + for(a=0; acm[a].curve= newdataadr(fd, cumap->cm[a].curve); + cumap->cm[a].table= NULL; + } +} + +/* ************ READ NODE TREE *************** */ + +/* singe node tree, ntree is not NULL */ +static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) + node->id= newlibadr_us(fd, id->lib, node->id); +} + +/* library linking after fileread */ +static void lib_link_nodetree(FileData *fd, Main *main) +{ + Scene *sce; + Material *ma; + bNodeTree *ntree; + bNode *node; + + /* in multiple steps, first link ID pointers */ + for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) { + if(ntree->id.flag & LIB_NEEDLINK) { + lib_link_ntree(fd, &ntree->id, ntree); + } + } + + /* now create the own typeinfo structs an verify nodes */ + /* here we still assume no groups in groups */ + for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) { + if(ntree->id.flag & LIB_NEEDLINK) { + ntree->id.flag -= LIB_NEEDLINK; + + ntreeVerifyTypes(ntree); /* internal nodes, no groups! */ + ntreeMakeOwnType(ntree); /* for group usage */ + } + } + + /* now verify all types in material trees, groups are set OK now */ + for(ma= main->mat.first; ma; ma= ma->id.next) { + if(ma->nodetree) + ntreeVerifyTypes(ma->nodetree); + } + /* and scene trees */ + for(sce= main->scene.first; sce; sce= sce->id.next) { + if(sce->nodetree) + ntreeVerifyTypes(sce->nodetree); + } +} + +/* ntree itself has been read! */ +static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) +{ + /* note: writing and reading goes in sync, for speed */ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + ntree->init= 0; /* to set callbacks */ + ntree->owntype= NULL; + ntree->timecursor= NULL; + + link_list(fd, &ntree->nodes); + for(node= ntree->nodes.first; node; node= node->next) { + node->storage= newdataadr(fd, node->storage); + if(node->storage) { + + /* could be handlerized at some point, now only 1 exception still */ + if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) + direct_link_curvemapping(fd, node->storage); + else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB)) + direct_link_curvemapping(fd, node->storage); + + } + link_list(fd, &node->inputs); + link_list(fd, &node->outputs); + } + link_list(fd, &ntree->links); + + /* and we connect the rest */ + for(node= ntree->nodes.first; node; node= node->next) { + node->preview= NULL; + node->block= NULL; + node->lasty= 0; + for(sock= node->inputs.first; sock; sock= sock->next) + sock->link= newdataadr(fd, sock->link); + for(sock= node->outputs.first; sock; sock= sock->next) + sock->ns.data= NULL; + } + for(link= ntree->links.first; link; link= link->next) { + link->fromnode= newdataadr(fd, link->fromnode); + link->tonode= newdataadr(fd, link->tonode); + link->fromsock= newdataadr(fd, link->fromsock); + link->tosock= newdataadr(fd, link->tosock); + } + + /* type verification is in lib-link */ +} + /* ************ READ PACKEDFILE *************** */ static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf) @@ -1265,6 +1346,7 @@ static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist) bActionStrip *strip; for (strip=striplist->first; strip; strip=strip->next){ + strip->object = newlibadr(fd, id->lib, strip->object); strip->act = newlibadr_us(fd, id->lib, strip->act); strip->ipo = newlibadr(fd, id->lib, strip->ipo); } @@ -1391,6 +1473,7 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose) lib_link_constraints(fd, (ID *)ob, &pchan->constraints); // hurms... loop in a loop, but yah... later... (ton) pchan->bone= get_named_bone(arm, pchan->name); + pchan->custom= newlibadr(fd, arm->id.lib, pchan->custom); if(pchan->bone==NULL) rebuild= 1; } @@ -2002,7 +2085,8 @@ static void lib_link_material(FileData *fd, Main *main) if(ma->id.flag & LIB_NEEDLINK) { ma->ipo= newlibadr_us(fd, ma->id.lib, ma->ipo); - + ma->group= newlibadr_us(fd, ma->id.lib, ma->group); + for(a=0; amtex[a]; if(mtex) { @@ -2011,6 +2095,10 @@ static void lib_link_material(FileData *fd, Main *main) } } lib_link_scriptlink(fd, &ma->id, &ma->scriptlink); + + if(ma->nodetree) + lib_link_ntree(fd, &ma->id, ma->nodetree); + ma->id.flag -= LIB_NEEDLINK; } ma= ma->id.next; @@ -2021,8 +2109,6 @@ static void direct_link_material(FileData *fd, Material *ma) { int a; - direct_link_scriptlink(fd, &ma->scriptlink); - for(a=0; amtex[a]= newdataadr(fd, ma->mtex[a]); } @@ -2030,6 +2116,11 @@ static void direct_link_material(FileData *fd, Material *ma) ma->ramp_col= newdataadr(fd, ma->ramp_col); ma->ramp_spec= newdataadr(fd, ma->ramp_spec); + direct_link_scriptlink(fd, &ma->scriptlink); + + ma->nodetree= newdataadr(fd, ma->nodetree); + if(ma->nodetree) + direct_link_nodetree(fd, ma->nodetree); } /* ************ READ MESH ***************** */ @@ -2045,8 +2136,9 @@ static void lib_link_mesh(FileData *fd, Main *main) /* this check added for python created meshes */ if(me->mat) { - for(i=0; itotcol; i++) + for(i=0; itotcol; i++) { me->mat[i]= newlibadr_us(fd, me->id.lib, me->mat[i]); + } } else me->totcol= 0; @@ -2140,6 +2232,7 @@ static void lib_link_modifiers(FileData *fd, Object *ob) static void lib_link_object(FileData *fd, Main *main) { Object *ob; + PartEff *paf; bSensor *sens; bController *cont; bActuator *act; @@ -2154,10 +2247,11 @@ static void lib_link_object(FileData *fd, Main *main) ob->track= newlibadr(fd, ob->id.lib, ob->track); ob->ipo= newlibadr_us(fd, ob->id.lib, ob->ipo); ob->action = newlibadr_us(fd, ob->id.lib, ob->action); - + ob->dup_group= newlibadr_us(fd, ob->id.lib, ob->dup_group); + poin= ob->data; ob->data= newlibadr_us(fd, ob->id.lib, ob->data); - + if(ob->data==NULL && poin!=NULL) { ob->type= OB_EMPTY; warn= 1; @@ -2175,6 +2269,11 @@ static void lib_link_object(FileData *fd, Main *main) lib_link_nlastrips(fd, &ob->id, &ob->nlastrips); lib_link_constraint_channels(fd, &ob->id, &ob->constraintChannels); + for(paf= ob->effect.first; paf; paf= paf->next) { + if(paf->type==EFF_PARTICLE) { + paf->group= newlibadr_us(fd, ob->id.lib, paf->group); + } + } sens= ob->sensors.first; while(sens) { @@ -2348,7 +2447,7 @@ static void direct_link_object(FileData *fd, Object *ob) paf= ob->effect.first; while(paf) { if(paf->type==EFF_PARTICLE) { - paf->keys= 0; + paf->keys= NULL; } if(paf->type==EFF_WAVE) { WaveEff *wav = (WaveEff*) paf; @@ -2507,19 +2606,18 @@ 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->group= newlibadr_us(fd, sce->id.lib, sce->group); base= sce->base.first; while(base) { next= base->next; /* base->object= newlibadr_us(fd, sce->id.lib, base->object); */ - base->object= newlibadr_us_type(fd, ID_OB, 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==0) { + if(base->object==NULL) { printf("LIB ERROR: base removed\n"); BLI_remlink(&sce->base, base); if(base==sce->basact) sce->basact= 0; @@ -2547,6 +2645,9 @@ static void lib_link_scene(FileData *fd, Main *main) lib_link_scriptlink(fd, &sce->id, &sce->scriptlink); + if(sce->nodetree) + lib_link_ntree(fd, &sce->id, sce->nodetree); + sce->id.flag -= LIB_NEEDLINK; } @@ -2709,6 +2810,12 @@ static void direct_link_scene(FileData *fd, Scene *sce) } link_list(fd, &(sce->markers)); + link_list(fd, &(sce->r.layers)); + + sce->nodetree= newdataadr(fd, sce->nodetree); + if(sce->nodetree) + direct_link_nodetree(fd, sce->nodetree); + } /* ************ READ SCREEN ***************** */ @@ -2749,6 +2856,7 @@ static void lib_link_screen(FileData *fd, Main *main) if(v3d->localvd) { v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera); } + v3d->ri= NULL; } else if(sl->spacetype==SPACE_IPO) { SpaceIpo *sipo= (SpaceIpo *)sl; @@ -2762,8 +2870,8 @@ static void lib_link_screen(FileData *fd, Main *main) } else if(sl->spacetype==SPACE_BUTS) { SpaceButs *sbuts= (SpaceButs *)sl; - sbuts->rect= NULL; sbuts->lockpoin= NULL; + sbuts->ri= NULL; if(main->versionfile<132) set_rects_butspace(sbuts); } else if(sl->spacetype==SPACE_FILE) { @@ -2931,7 +3039,7 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene) else if(sl->spacetype==SPACE_BUTS) { SpaceButs *sbuts= (SpaceButs *)sl; sbuts->lockpoin= NULL; - sbuts->cury= 0; // we leave rect, for nicer redraws + if (sbuts->ri) sbuts->ri->cury = 0; } else if(sl->spacetype==SPACE_FILE) { SpaceFile *sfile= (SpaceFile *)sl; @@ -2990,6 +3098,12 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene) ssound->sound= restore_pointer_by_name(newmain, (ID *)ssound->sound, 1); } + else if(sl->spacetype==SPACE_NODE) { + SpaceNode *snode= (SpaceNode *)sl; + + snode->nodetree= snode->edittree= NULL; + snode->flag |= SNODE_DO_PREVIEW; + } } sa= sa->next; } @@ -3080,6 +3194,18 @@ static void direct_link_screen(FileData *fd, bScreen *sc) soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw } } + else if(sl->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sl; + + sima->cumap= newdataadr(fd, sima->cumap); + if(sima->cumap) + direct_link_curvemapping(fd, sima->cumap); + } + else if(sl->spacetype==SPACE_NODE) { + SpaceNode *snode= (SpaceNode *)sl; + snode->nodetree= snode->edittree= NULL; + snode->flag |= SNODE_DO_PREVIEW; + } } sa->v1= newdataadr(fd, sa->v1); @@ -3101,10 +3227,34 @@ static void direct_link_screen(FileData *fd, bScreen *sc) /* ********** READ LIBRARY *************** */ -static void direct_link_library(FileData *fd, Library *lib) +static void direct_link_library(FileData *fd, Library *lib, Main *main) { Main *newmain; - + Library *libr; + + for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) { + if(newmain->curlib) { + if(strcmp(newmain->curlib->filename, lib->filename)==0) { + printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filename); + + change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib); +// change_idid_adr_fd(fd, lib, newmain->curlib); + + BLI_remlink(&main->library, lib); + MEM_freeN(lib); + + error("Library had multiple instances, save and reload!"); + return; + } + } + } + /* make sure we have full path in lib->filename */ + BLI_strncpy(lib->filename, lib->name, sizeof(lib->name)); + cleanup_path(fd->filename, lib->filename); + +// printf("direct_link_library: name %s\n", lib->name); +// printf("direct_link_library: filename %s\n", lib->filename); + /* new main */ newmain= MEM_callocN(sizeof(Main), "directlink"); BLI_addtail(&fd->mainlist, newmain); @@ -3151,47 +3301,34 @@ static void lib_link_sound(FileData *fd, Main *main) static void direct_link_group(FileData *fd, Group *group) { - GroupObject *go; - ObjectKey *ok; - link_list(fd, &group->gobject); - link_list(fd, &group->gkey); - group->active= newdataadr(fd, group->active); - - go= group->gobject.first; - while(go) { - link_list(fd, &go->okey); - ok= go->okey.first; - while(ok) { - ok->gkey= newdataadr(fd, ok->gkey); - ok= ok->next; - } - go= go->next; - } } static void lib_link_group(FileData *fd, Main *main) { Group *group= main->group.first; GroupObject *go; - ObjectKey *ok; - + int add_us; + while(group) { if(group->id.flag & LIB_NEEDLINK) { group->id.flag -= LIB_NEEDLINK; - + + add_us= 0; + go= group->gobject.first; while(go) { go->ob= newlibadr(fd, group->id.lib, go->ob); - ok= go->okey.first; - while(ok) { - ok->parent= newlibadr(fd, group->id.lib, ok->parent); - ok->track= newlibadr(fd, group->id.lib, ok->track); - ok->ipo= newlibadr_us(fd, group->id.lib, ok->ipo); - ok= ok->next; + if(go->ob) { + /* if group has an object, it increments user... */ + add_us= 1; + if(go->ob->id.us==0) + go->ob->id.us= 1; } go= go->next; } + if(add_us) group->id.us++; + rem_from_group(group, NULL); /* removes NULL entries */ } group= group->id.next; } @@ -3199,6 +3336,43 @@ static void lib_link_group(FileData *fd, Main *main) /* ************** GENERAL & MAIN ******************** */ +static char *libname(short id_code) +{ + +} + +static char *dataname(short id_code) +{ + + switch( id_code ) { + case ID_OB: return "Data from OB"; + case ID_ME: return "Data from ME"; + case ID_IP: return "Data from IP"; + case ID_SCE: return "Data from SCE"; + case ID_MA: return "Data from MA"; + case ID_TE: return "Data from TE"; + case ID_CU: return "Data from CU"; + case ID_GR: return "Data from GR"; + case ID_AR: return "Data from AR"; + case ID_AC: return "Data from AC"; + case ID_LI: return "Data from LI"; + case ID_MB: return "Data from MB"; + case ID_IM: return "Data from IM"; + case ID_LT: return "Data from LT"; + case ID_LA: return "Data from LA"; + case ID_CA: return "Data from CA"; + case ID_KE: return "Data from KE"; + case ID_WO: return "Data from WO"; + case ID_SCR: return "Data from SCR"; + case ID_VF: return "Data from VF"; + case ID_TXT : return "Data from TXT"; + case ID_SO: return "Data from SO"; + case ID_SAMPLE: return "Data from SAMPLE"; + } + return "Data from Lib Block"; + +} + 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 @@ -3207,8 +3381,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID ID *id; ListBase *lb; - char *str = NULL; - + char *allocname; + if(bhead->code==ID_ID) { ID *linkedid= (ID *)(bhead + 1); /* BHEAD+DATA dependancy */ @@ -3224,8 +3398,8 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID *id_r= id; if (!id) return blo_nextbhead(fd, bhead); - - oldnewmap_insert(fd->libmap, bhead->old, id, 1); + + oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); /* for ID_ID check */ BLI_addtail(lb, id); /* clear first 8 bits */ @@ -3233,6 +3407,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID id->lib= main->curlib; if(id->flag & LIB_FAKEUSER) id->us= 1; else id->us= 0; + id->icon_id = 0; /* this case cannot be direct_linked: it's just the ID part */ if(bhead->code==ID_ID) { @@ -3241,40 +3416,12 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID bhead = blo_nextbhead(fd, bhead); - switch( GS(id->name) ) { - case ID_OB: str= "ID_OB"; break; - case ID_SCE: str= "ID_SCE"; break; - case ID_LI: str= "ID_LI"; break; - case ID_ME: str= "ID_ME"; break; - case ID_CU: str= "ID_CU"; break; - case ID_MB: str= "ID_MB"; break; - case ID_MA: str= "ID_MA"; break; - case ID_TE: str= "ID_TE"; break; - case ID_IM: str= "ID_IM"; break; - case ID_IK: str= "ID_IK"; break; - case ID_WV: str= "ID_WV"; break; - case ID_LT: str= "ID_LT"; break; - case ID_SE: str= "ID_SE"; break; - case ID_LF: str= "ID_LF"; break; - case ID_LA: str= "ID_LA"; break; - case ID_CA: str= "ID_CA"; break; - case ID_IP: str= "ID_IP"; break; - case ID_KE: str= "ID_KE"; break; - case ID_WO: str= "ID_WO"; break; - case ID_SCR: str= "ID_SCR"; break; - case ID_VF: str= "ID_VF"; break; - case ID_TXT : str= "ID_TXT"; break; - case ID_SO: str= "ID_SO"; break; - case ID_SAMPLE: str= "ID_SAMPLE"; break; - case ID_GR: str= "ID_GR"; break; - case ID_ID: str= "ID_ID"; break; - case ID_SEQ: str= "ID_SEQ"; break; - case ID_AR: str= "ID_AR"; break; - case ID_AC: str= "ID_AC"; break; - } + /* 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= read_struct(fd, bhead, str); + void *data= read_struct(fd, bhead, allocname); if (data) { oldnewmap_insert(fd->datamap, bhead->old, data, 0); @@ -3334,7 +3481,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID direct_link_world(fd, (World *)id); break; case ID_LI: - direct_link_library(fd, (Library *)id); + direct_link_library(fd, (Library *)id, main); break; case ID_CA: direct_link_camera(fd, (Camera *)id); @@ -3351,6 +3498,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_AC: direct_link_action(fd, (bAction*)id); break; + case ID_NT: + direct_link_nodetree(fd, (bNodeTree*)id); + break; } oldnewmap_free_unused(fd->datamap); @@ -3432,6 +3582,17 @@ static void bone_version_238(ListBase *lb) } } +static void bone_version_239(ListBase *lb) +{ + Bone *bone; + + for(bone= lb->first; bone; bone= bone->next) { + if(bone->layer==0) + bone->layer= 1; + bone_version_239(&bone->childbase); + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -4784,12 +4945,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(v3d->twtype==0) v3d->twtype= V3D_MANIP_TRANSLATE; } #ifndef SHOWDEPGRAPH - if(sl->spacetype==SPACE_OOPS) { + else if(sl->spacetype==SPACE_OOPS) { if ( ((SpaceOops *)sl)->type==SO_DEPSGRAPH) ((SpaceOops *)sl)->type=SO_OOPS; } #endif - if(sl->spacetype==SPACE_TIME) { + else if(sl->spacetype==SPACE_TIME) { SpaceTime *stime= (SpaceTime *)sl; if(stime->redraws==0) stime->redraws= TIME_ALL_3D_WIN|TIME_ALL_ANIM_WIN; @@ -5050,6 +5211,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* updating stepsize for ghost drawing */ for(arm= main->armature.first; arm; arm= arm->id.next) { if (arm->ghostsize==0) arm->ghostsize=1; + bone_version_239(&arm->bonebase); + if(arm->layer==0) arm->layer= 1; } for(;sce;sce= sce->id.next) { @@ -5084,14 +5247,41 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ma->strand_sta= ma->strand_end= 1.0f; ma->mode |= MA_TANGENT_STR; } - /* remove this test before 2.41! pad is set to denote check was done */ - if(ma->pad==0) { - if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF; - ma->pad= 1; - } + if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF; } } + if(main->versionfile <= 240) { + Scene *sce; + bArmature *arm; + + /* updating layers still */ + for(arm= main->armature.first; arm; arm= arm->id.next) { + bone_version_239(&arm->bonebase); + if(arm->layer==0) arm->layer= 1; + } + for(sce= main->scene.first; sce; sce= sce->id.next) { + if(sce->r.xparts<2) sce->r.xparts= 4; + if(sce->r.yparts<2) sce->r.yparts= 4; + /* adds default layer */ + if(sce->r.layers.first==NULL) + scene_add_render_layer(sce); + } + } + + if(main->versionfile <= 241) { + Object *ob; + + /* for empty drawsize and drawtype */ + /* uncomment before release! --broken + for(ob=main->object.first; ob; ob= ob->id.next) { + ob->empty_drawtype = OB_ARROWS; + ob->empty_drawsize = 1.0; + } + */ + } + + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ @@ -5100,6 +5290,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) static void lib_link_all(FileData *fd, Main *main) { + oldnewmap_sort(fd); + lib_link_screen(fd, main); lib_link_scene(fd, main); lib_link_object(fd, main); @@ -5120,10 +5312,11 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_armature(fd, main); lib_link_action(fd, main); lib_link_vfont(fd, main); + lib_link_nodetree(fd, main); /* has to be done after materials, it will verify group nodes */ - lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ + lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ - lib_link_library(fd, main); /* only init users */ + lib_link_library(fd, main); /* only init users */ } static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) @@ -5186,9 +5379,9 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) */ bhead = read_libblock(fd, fd->mainlist.last, bhead, LIB_READ+LIB_EXTERN, NULL); break; - case ID_GR: - bhead = blo_nextbhead(fd, bhead); - break; +// case ID_GR: +// bhead = blo_nextbhead(fd, bhead); +// break; default: bhead = read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL); @@ -5202,6 +5395,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, BlendReadError *error_r) blo_join_main(&fd->mainlist); lib_link_all(fd, bfd->main); + link_global(fd, bfd, fg); /* as last */ /* removed here: check for existance of curscreen/scene, moved to kernel setup_app */ @@ -5268,17 +5462,20 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) if(bheadlib) { // BHEAD+DATA dependancy Library *lib= (Library *)(bheadlib+1); - mainvar= blo_find_main(&fd->mainlist, lib->name); + /* we read the lib->name directly from the bhead, potential danger (64 bits?) */ + mainvar= blo_find_main(&fd->mainlist, lib->name, fd->filename); id= is_yet_read(mainvar, bhead); if(id==0) { read_libblock(fd, mainvar, bhead, LIB_READ+LIB_INDIRECT, NULL); - printf("expand: other lib %s\n", lib->name); + printf("expand_doit: other lib %s\n", lib->name); } else { - oldnewmap_insert(fd->libmap, bhead->old, id, 1); - printf("expand: already linked: %s lib: %s\n", id->name, lib->name); + //oldnewmap_insert(fd->libmap, bhead->old, id, 1); + + change_idid_adr_fd(fd, bhead->old, id); + printf("expand_doit: already linked: %s lib: %s\n", id->name, lib->name); } } } @@ -5290,13 +5487,24 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old) read_libblock(fd, mainvar, bhead, LIB_TESTIND, NULL); } else { - oldnewmap_insert(fd->libmap, bhead->old, id, 1); + /* removed line below... I *really* dont know whatfor (Id is read, so...) + it caused a whole lot of extra and unneeded oldmap entries */ + /* oldnewmap_insert(fd->libmap, bhead->old, id, 1); */ /* printf("expand: already read %s\n", id->name); */ } } } } +static void expand_group(FileData *fd, Main *mainvar, Group *group) +{ + GroupObject *go; + + for(go= group->gobject.first; go; go= go->next) { + expand_doit(fd, mainvar, go->ob); + } +} + static void expand_key(FileData *fd, Main *mainvar, Key *key) { expand_doit(fd, mainvar, key->ipo); @@ -5309,6 +5517,16 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex) expand_doit(fd, mainvar, tex->ipo); } +static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree) +{ + bNode *node; + + for(node= ntree->nodes.first; node; node= node->next) + if(node->id) + expand_doit(fd, mainvar, node->id); + +} + static void expand_material(FileData *fd, Main *mainvar, Material *ma) { int a; @@ -5319,7 +5537,11 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma) expand_doit(fd, mainvar, ma->mtex[a]->object); } } + expand_doit(fd, mainvar, ma->ipo); + + if(ma->nodetree) + expand_nodetree(fd, mainvar, ma->nodetree); } static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) @@ -5565,6 +5787,7 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob) expand_constraint_channels(fd, mainvar, &ob->constraintChannels); for (strip=ob->nlastrips.first; strip; strip=strip->next){ + expand_doit(fd, mainvar, strip->object); expand_doit(fd, mainvar, strip->act); expand_doit(fd, mainvar, strip->ipo); } @@ -5728,6 +5951,12 @@ static void expand_main(FileData *fd, Main *mainvar) case ID_AC: expand_action(fd, mainvar, (bAction *)id); break; + case ID_GR: + expand_group(fd, mainvar, (Group *)id); + break; + case ID_NT: + expand_nodetree(fd, mainvar, (bNodeTree *)id); + break; } doit= 1; @@ -5757,8 +5986,9 @@ static void give_base_to_objects(Scene *sce, ListBase *lb) BLI_addtail(&(sce->base), base); base->lay= ob->lay; base->object= ob; + base->flag= ob->flag; ob->id.us= 1; - + ob->id.flag -= LIB_INDIRECT; ob->id.flag |= LIB_EXTERN; @@ -5859,21 +6089,15 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcod ListBase mainlist; Main *mainl; FileData *fd = (FileData *)bh; - char filename[FILE_MAXDIR+FILE_MAXFILE]; mainlist.first= mainlist.last= G.main; G.main->next= NULL; - /* make copy of the 'last loaded filename', we need to restore it */ - BLI_strncpy(filename, G.sce, sizeof(filename)); - /* already opened file, to reconstruct relative paths */ - BLI_strncpy(G.sce, fd->filename, sizeof(filename)); - /* make mains */ blo_split_main(&mainlist); /* which one do we need? */ - mainl = blo_find_main(&mainlist, dir); + mainl = blo_find_main(&mainlist, dir, G.sce); append_named_part(fd, mainl, G.scene, name, idcode, 0); @@ -5887,13 +6111,12 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcod G.main= mainlist.first; lib_link_all(fd, G.main); - - /* restore the 'last loaded filename' */ - BLI_strncpy(G.sce, filename, sizeof(filename)); + DAG_scene_sort(G.scene); } - /* append to G.scene */ +/* append to G.scene */ +/* dir is a full path */ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) { FileData *fd= (FileData*) sfile->libfiledata; @@ -5902,7 +6125,6 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) Object *ob; float *curs,centerloc[3],vec[3],min[3],max[3]; int a, totsel=0,count=0; - char filename[FILE_MAXDIR+FILE_MAXFILE]; INIT_MINMAX(min, max); @@ -5931,10 +6153,6 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) } /* now we have or selected, or an indicated file */ - /* make copy of the 'last loaded filename', we need to restore it */ - BLI_strncpy(filename, G.sce, sizeof(filename)); - BLI_strncpy(G.sce, fd->filename, sizeof(filename)); // already opened file, to reconstruct relative paths - if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene); fd->mainlist.first= fd->mainlist.last= G.main; @@ -5944,7 +6162,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) blo_split_main(&fd->mainlist); /* which one do we need? */ - mainl = blo_find_main(&fd->mainlist, dir); + mainl = blo_find_main(&fd->mainlist, dir, G.sce); mainl->versionfile= fd->fileversion; // needed for do_version if(totsel==0) { @@ -5965,10 +6183,12 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) read_libraries(fd, &fd->mainlist); if(sfile->flag & FILE_STRINGCODE) { - /* uses old .blend file (*filename) as reference */ - BLI_makestringcode(filename, mainl->curlib->name); - /* the caller checks for appended library, so we make sure names match */ - BLI_strncpy(dir, mainl->curlib->name, sizeof(mainl->curlib->name)); + + /* use the full path, this could have been read by other library even */ + BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name)); + + /* uses current .blend file as reference */ + BLI_makestringcode(G.sce, mainl->curlib->name); } blo_join_main(&fd->mainlist); @@ -6017,9 +6237,6 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode) } } } - - /* restore the 'last loaded filename' */ - BLI_strncpy(G.sce, filename, sizeof(filename)); DAG_scene_sort(G.scene); } @@ -6062,14 +6279,13 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if(fd==NULL) { BlendReadError err; - printf("read lib %s\n", mainptr->curlib->name); - fd= blo_openblenderfile(mainptr->curlib->name, &err); + printf("read_libraries: lib %s\n", mainptr->curlib->name); + fd= blo_openblenderfile(mainptr->curlib->filename, &err); if (fd) { if (fd->libmap) oldnewmap_free(fd->libmap); - fd->libmap= basefd->libmap; - fd->flags|= FD_FLAGS_NOT_MY_LIBMAP; + fd->libmap = oldnewmap_new(); mainptr->curlib->filedata= fd; mainptr->versionfile= fd->fileversion; @@ -6077,7 +6293,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) else mainptr->curlib->filedata= NULL; if (fd==NULL) - printf("ERROR: can't find lib %s \n", mainptr->curlib->name); + printf("ERROR: can't find lib %s \n", mainptr->curlib->filename); } if(fd) { doit= 1; @@ -6094,7 +6310,8 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) append_id_part(fd, mainptr, id, &realid); if (!realid) printf("LIB ERROR: can't find %s\n", id->name); - change_libadr(fd, id, realid); + + change_idid_adr(mainlist, basefd, id, realid); MEM_freeN(id); } @@ -6116,9 +6333,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) mainptr= mainptr->next; } } - mainptr= mainl->next; - while(mainptr) { - /* test if there are unread libblocks */ + + /* test if there are unread libblocks */ + for(mainptr= mainl->next; mainptr; mainptr= mainptr->next) { a= set_listbasepointers(mainptr, lbarray); while(a--) { ID *id= lbarray[a]->first; @@ -6128,14 +6345,17 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) BLI_remlink(lbarray[a], id); printf("LIB ERROR: can't find %s\n", id->name); - change_libadr(basefd, id, 0); + change_idid_adr(mainlist, basefd, id, NULL); MEM_freeN(id); } id= idn; } } - + } + + /* do versions, link, and free */ + for(mainptr= mainl->next; mainptr; mainptr= mainptr->next) { /* some mains still have to be read, then * versionfile is still zero! */ if(mainptr->versionfile) { @@ -6145,10 +6365,12 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) do_versions(basefd, NULL, mainptr); } + if(mainptr->curlib->filedata) + lib_link_all(mainptr->curlib->filedata, mainptr); + if(mainptr->curlib->filedata) blo_freefiledata(mainptr->curlib->filedata); mainptr->curlib->filedata= NULL; - mainptr= mainptr->next; } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f941b5f77d2..ccd9314d4fd 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -109,6 +109,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "DNA_curve_types.h" #include "DNA_constraint_types.h" #include "DNA_camera_types.h" +#include "DNA_color_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" #include "DNA_image_types.h" @@ -124,6 +125,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "DNA_material_types.h" #include "DNA_modifier_types.h" #include "DNA_nla_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_oops_types.h" @@ -141,6 +143,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "DNA_view3d_types.h" #include "DNA_vfont_types.h" #include "DNA_userdef_types.h" +#include "DNA_world_types.h" #include "MEM_guardedalloc.h" // MEM_freeN #include "BLI_blenlib.h" @@ -153,6 +156,7 @@ Important to know is that 'streaming' has been added to files, for Blender Publi #include "BKE_global.h" // for G #include "BKE_library.h" // for set_listbasepointers #include "BKE_main.h" // G.main +#include "BKE_node.h" #include "BKE_packedFile.h" // for packAll #include "BKE_screen.h" // for waitcursor #include "BKE_scene.h" // for do_seq @@ -317,7 +321,7 @@ static void writestruct(WriteData *wd, int filecode, char *structname, int nr, v BHead bh; short *sp; - if(adr==0 || nr==0) return; + if(adr==NULL || nr==0) return; /* init BHead */ bh.code= filecode; @@ -326,7 +330,7 @@ static void writestruct(WriteData *wd, int filecode, char *structname, int nr, v bh.SDNAnr= dna_findstruct_nr(wd->sdna, structname); if(bh.SDNAnr== -1) { - printf("error: can't find SDNA code %s\n", structname); + printf("error: can't find SDNA code <%s>\n", structname); return; } sp= wd->sdna->structs[bh.SDNAnr]; @@ -360,6 +364,49 @@ static void writedata(WriteData *wd, int filecode, int len, void *adr) /* do not if(len) mywrite(wd, adr, len); } +/* *************** writing some direct data structs used in more code parts **************** */ + +static void write_curvemapping(WriteData *wd, CurveMapping *cumap) +{ + int a; + + writestruct(wd, DATA, "CurveMapping", 1, cumap); + for(a=0; acm[a].totpoint, cumap->cm[a].curve); +} + +/* this is only direct data, tree itself should have been written */ +static void write_nodetree(WriteData *wd, bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + bNodeLink *link; + + /* for link_list() speed, we write per list */ + + for(node= ntree->nodes.first; node; node= node->next) + writestruct(wd, DATA, "bNode", 1, node); + + for(node= ntree->nodes.first; node; node= node->next) { + if(node->storage) { + /* could be handlerized at some point, now only 1 exception still */ + if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) + write_curvemapping(wd, node->storage); + else if(ntree->type==NTREE_COMPOSIT && (node->type==CMP_NODE_CURVE_VEC || node->type==CMP_NODE_CURVE_RGB)) + write_curvemapping(wd, node->storage); + else + writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); + } + for(sock= node->inputs.first; sock; sock= sock->next) + writestruct(wd, DATA, "bNodeSocket", 1, sock); + for(sock= node->outputs.first; sock; sock= sock->next) + writestruct(wd, DATA, "bNodeSocket", 1, sock); + } + + for(link= ntree->links.first; link; link= link->next) + writestruct(wd, DATA, "bNodeLink", 1, link); +} + static void write_scriptlink(WriteData *wd, ScriptLink *slink) { writedata(wd, DATA, sizeof(void *)*slink->totscript, slink->scripts); @@ -1010,6 +1057,12 @@ static void write_materials(WriteData *wd, ListBase *idbase) if(ma->ramp_spec) writestruct(wd, DATA, "ColorBand", 1, ma->ramp_spec); write_scriptlink(wd, &ma->scriptlink); + + /* nodetree is integral part of material, no libdata */ + if(ma->nodetree) { + writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree); + write_nodetree(wd, ma->nodetree); + } } ma= ma->id.next; } @@ -1084,7 +1137,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase) MetaStack *ms; Strip *strip; TimeMarker *marker; - + SceneRenderLayer *srl; + sce= scebase->first; while(sce) { /* write LibData */ @@ -1160,10 +1214,15 @@ static void write_scenes(WriteData *wd, ListBase *scebase) } /* writing dynamic list of TimeMarkers to the blend file */ - marker= sce->markers.first; - while(marker){ + for(marker= sce->markers.first; marker; marker= marker->next) writestruct(wd, DATA, "TimeMarker", 1, marker); - marker= marker->next; + + for(srl= sce->r.layers.first; srl; srl= srl->next) + writestruct(wd, DATA, "SceneRenderLayer", 1, srl); + + if(sce->nodetree) { + writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree); + write_nodetree(wd, sce->nodetree); } sce= sce->id.next; @@ -1265,7 +1324,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } } else if(sl->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sl; + writestruct(wd, DATA, "SpaceImage", 1, sl); + if(sima->cumap) + write_curvemapping(wd, sima->cumap); } else if(sl->spacetype==SPACE_IMASEL) { writestruct(wd, DATA, "SpaceImaSel", 1, sl); @@ -1288,6 +1351,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) else if(sl->spacetype==SPACE_TIME){ writestruct(wd, DATA, "SpaceTime", 1, sl); } + else if(sl->spacetype==SPACE_NODE){ + writestruct(wd, DATA, "SpaceNode", 1, sl); + } sl= sl->next; } @@ -1328,6 +1394,8 @@ static void write_libraries(WriteData *wd, Main *main) while(a--) { id= lbarray[a]->first; while(id) { + if(G.rt==127 && GS(id->name)!=ID_GR) break; + if(id->us>0 && (id->flag & LIB_EXTERN)) { writestruct(wd, ID_ID, "ID", 1, id); @@ -1387,8 +1455,8 @@ static void write_actions(WriteData *wd, ListBase *idbase) { bAction *act; bActionChannel *chan; - act=idbase->first; - while (act) { + + for(act=idbase->first; act; act= act->id.next) { if (act->id.us>0 || wd->current) { writestruct(wd, ID_AC, "bAction", 1, act); @@ -1397,7 +1465,6 @@ static void write_actions(WriteData *wd, ListBase *idbase) write_constraint_channels(wd, &chan->constraintChannels); } } - act=act->id.next; } } @@ -1487,39 +1554,31 @@ static void write_sounds(WriteData *wd, ListBase *idbase) static void write_groups(WriteData *wd, ListBase *idbase) { Group *group; - GroupKey *gk; GroupObject *go; - ObjectKey *ok; - group= idbase->first; - while(group) { + for(group= idbase->first; group; group= group->id.next) { if(group->id.us>0 || wd->current) { /* write LibData */ writestruct(wd, ID_GR, "Group", 1, group); - gk= group->gkey.first; - while(gk) { - writestruct(wd, DATA, "GroupKey", 1, gk); - gk= gk->next; - } - go= group->gobject.first; while(go) { writestruct(wd, DATA, "GroupObject", 1, go); go= go->next; } - go= group->gobject.first; - while(go) { - ok= go->okey.first; - while(ok) { - writestruct(wd, DATA, "ObjectKey", 1, ok); - ok= ok->next; - } - go= go->next; - } - } - group= group->id.next; + } +} + +static void write_nodetrees(WriteData *wd, ListBase *idbase) +{ + bNodeTree *ntree; + + for(ntree=idbase->first; ntree; ntree= ntree->id.next) { + if (ntree->id.us>0 || wd->current) { + writestruct(wd, ID_NT, "bNodeTree", 1, ntree); + write_nodetree(wd, ntree); + } } } @@ -1580,6 +1639,7 @@ static int write_file_handle(int handle, MemFile *compare, MemFile *current, int write_materials(wd, &G.main->mat); write_textures (wd, &G.main->tex); write_meshs (wd, &G.main->mesh); + write_nodetrees(wd, &G.main->nodetree); write_libraries(wd, G.main->next); write_global(wd); diff --git a/source/blender/blenpluginapi/iff.h b/source/blender/blenpluginapi/iff.h index 4fa3e0214fa..456291e664b 100644 --- a/source/blender/blenpluginapi/iff.h +++ b/source/blender/blenpluginapi/iff.h @@ -44,10 +44,16 @@ #define IB_zbuf (1 << 13) #define IB_rgba (1 << 14) -#define AMI (1 << 31) -#define Anim (1 << 29) -#define TGA (1 << 28) -#define JPG (1 << 27) +#define AMI (1 << 31) +#define PNG (1 << 30) +#define Anim (1 << 29) +#define TGA (1 << 28) +#define JPG (1 << 27) +#define BMP (1 << 26) +#ifdef WITH_QUICKTIME +#define QUICKTIME (1 << 25) +#endif +#define RADHDR (1<<24) #define RAWTGA (TGA | 1) @@ -90,6 +96,7 @@ #define IS_amiga(x) (x->ftype & AMI) #define IS_ham(x) ((x->ftype & AM_ham) == AM_ham) #define IS_hbrite(x) ((x->ftype & AM_hbrite) == AM_hbrite) + #define IS_lace(x) ((x->ftype & AM_lace) == AM_lace) #define IS_hires(x) ((x->ftype & AM_hires) == AM_hires) #define IS_hblace(x) ((x->ftype & AM_hblace) == AM_hblace) @@ -98,9 +105,14 @@ #define IS_anim(x) (x->ftype & Anim) #define IS_hamx(x) (x->ftype == AN_hamx) - #define IS_tga(x) (x->ftype & TGA) +#define IS_png(x) (x->ftype & PNG) +#define IS_bmp(x) (x->ftype & BMP) +#define IS_radhdr(x) (x->ftype & RADHDR) #define IS_tim(x) (x->ftype & TIM) +#define IS_tiff(x) (x->ftype & TIFF) +#define IS_openexr(x) (x->ftype & OPENEXR) + #define IMAGIC 0732 #define IS_iris(x) (x->ftype == IMAGIC) @@ -136,6 +148,7 @@ typedef struct ImBuf{ unsigned char *encodedbuffer; unsigned int encodedsize; unsigned int encodedbuffersize; + float *rect_float; } ImBuf; extern struct ImBuf *allocImBuf(short,short,uchar,uint,uchar); diff --git a/source/blender/blenpluginapi/intern/pluginapi.c b/source/blender/blenpluginapi/intern/pluginapi.c index aefd8d3f458..bb64e9caa8f 100644 --- a/source/blender/blenpluginapi/intern/pluginapi.c +++ b/source/blender/blenpluginapi/intern/pluginapi.c @@ -41,10 +41,6 @@ * - util.h : Useful defines, memory management. */ -#ifdef HAVE_CONFIG_H -#include -#endif - #ifdef WIN32 #include "blenpluginapi\util.h" #else @@ -250,20 +246,6 @@ void de_interlace(struct ImBuf *ib) IMB_de_interlace(ib); } -void rectop(struct ImBuf *dbuf, - struct ImBuf *sbuf, - int destx, - int desty, - int srcx, - int srcy, - int width, - int height, - void (*operation)(unsigned int *, unsigned int*, int, int), - int value) -{ - IMB_rectop(dbuf, sbuf, destx, desty, srcx, srcy, width, height, operation, value); -} - /* -------------------------------------------------------------------------- */ /* stuff from plugin.h */ /* -------------------------------------------------------------------------- */ @@ -354,6 +336,5 @@ int pluginapi_force_ref(void) (int) turbulence1 + (int) de_interlace + (int) interlace + - (int) gamwarp + - (int) rectop; + (int) gamwarp; } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index b631ac79a06..ae7a7f527f1 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -185,6 +185,7 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1); * @attention Defined in allocimbuf.c */ short addzbufImBuf(struct ImBuf * ibuf); +short addzbuffloatImBuf(struct ImBuf * ibuf); /** * @@ -196,31 +197,8 @@ void IMB_freecmapImBuf(struct ImBuf * ibuf); * * @attention Defined in rectop.c */ -void IMB_rectop(struct ImBuf *dbuf, - struct ImBuf *sbuf, - int destx, - int desty, - int srcx, - int srcy, - int width, - int height, - void (*operation)(unsigned int *, unsigned int*, int, int), - int value); - -/** - * - * @attention Defined in rectop.c - */ -void IMB_rectoptot(struct ImBuf *dbuf, - struct ImBuf *sbuf, - void (*operation)(unsigned int *, unsigned int*, int, int), - int value); - -/** - * - * @attention Defined in rectop.c - */ -void IMB_rectcpy(unsigned int *drect, unsigned int *srect, int x, int dummy); +void IMB_rectcpy(struct ImBuf *drect, struct ImBuf *srect, int destx, + int desty, int srcx, int srcy, int width, int height); /** * Return the length (in frames) of the given @a anim. @@ -353,6 +331,8 @@ int imb_get_anim_type(char * name); void IMB_de_interlace(struct ImBuf *ibuf); void IMB_interlace(struct ImBuf *ibuf); void IMB_gamwarp(struct ImBuf *ibuf, double gamma); +void IMB_rect_from_float(struct ImBuf *ibuf); +void IMB_float_from_rect(struct ImBuf *ibuf); /** * Change the ordering of the colour bytes pointed to by rect from @@ -360,7 +340,7 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma); * * @attention Defined in imageprocess.c */ -void IMB_convert_rgba_to_abgr(int size, unsigned int *rect); +void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf); /** * Change the ordering of the colour bytes pointed to by rect from @@ -490,13 +470,17 @@ void IMB_cspace(struct ImBuf *ibuf, float mat[][4]); * @attention Defined in allocimbuf.c */ void IMB_freezbufImBuf(struct ImBuf * ibuf); +void IMB_freezbuffloatImBuf(struct ImBuf * ibuf); /** * * @attention Defined in rectop.c */ -void IMB_rectfill(unsigned int *drect, unsigned int *srect, int x, int value); +void IMB_rectfill(struct ImBuf *drect, float col[4]); +/* exported for image tools in blender, to quickly allocate 32 bits rect */ +short imb_addrectImBuf(struct ImBuf * ibuf); +void imb_freerectImBuf(struct ImBuf * ibuf); #ifdef WITH_QUICKTIME /** @@ -513,12 +497,6 @@ void quicktime_exit(void); #endif //WITH_QUICKTIME -/* radhdr: Temporary routine to save directly from render floatbuffer. - Defined in radiance_hdr.c - Called by schrijfplaatje() in toets.c */ -short imb_savehdr_fromfloat(float *fbuf, char *name, int width, int height); - - /* intern/dynlibtiff.c */ void libtiff_exit(void); diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 56a28850e71..ef1aa631fc6 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -88,11 +88,13 @@ typedef struct ImBuf{ char name[1023]; /**< The file name assocated with this image */ char namenull; /**< Unused don't want to remove it thought messes things up */ int userflags; /**< Used to set imbuf to Dirty and other stuff */ - int *zbuf; /**< z buffer data */ + int *zbuf; /**< z buffer data, original zbuffer */ + float *zbuf_float; /**< z buffer data, camera coordinates */ void *userdata; unsigned char *encodedbuffer; /**< Compressed image only used with png currently */ unsigned int encodedsize; /**< Size of data written to encodedbuffer */ unsigned int encodedbuffersize; /**< Size of encodedbuffer */ + float *rect_float; /**< floating point Rect equivilant */ } ImBuf; /* Moved from BKE_bmfont_types.h because it is a userflag bit mask. */ @@ -131,27 +133,30 @@ typedef enum { #define IB_zbuf (1 << 13) #define IB_mem (1 << 14) -/**@}*/ +#define IB_rectfloat (1 << 15) +#define IB_zbuffloat (1 << 16) -/** \name imbuf_formats Image file formats - * \brief These defines are bit flags for the various image file formats. - */ -/**@{*/ -/** \brief Identifier for an image file format. - * +/* * The bit flag is stored in the ImBuf.ftype variable. + * Note that the lower 10 bits is used for storing custom flags */ -#define AMI (1 << 31) -#define PNG (1 << 30) +#define AMI (1 << 31) +#define PNG (1 << 30) #define Anim (1 << 29) -#define TGA (1 << 28) -#define JPG (1 << 27) -#define BMP (1 << 26) +#define TGA (1 << 28) +#define JPG (1 << 27) +#define BMP (1 << 26) + #ifdef WITH_QUICKTIME -#define QUICKTIME (1 << 25) +#define QUICKTIME (1 << 25) #endif -#define RADHDR (1<<24) -#define TIF (1<<23) + +#define RADHDR (1 << 24) +#define TIF (1 << 23) + +#define OPENEXR (1 << 22) +#define OPENEXR_HALF (1 << 8 ) +#define OPENEXR_COMPRESS (7) #define RAWTGA (TGA | 1) @@ -188,6 +193,7 @@ typedef enum { #define IS_hamx(x) (x->ftype == AN_hamx) #define IS_tga(x) (x->ftype & TGA) #define IS_png(x) (x->ftype & PNG) +#define IS_openexr(x) (x->ftype & OPENEXR) #define IS_bmp(x) (x->ftype & BMP) #define IS_tiff(x) (x->ftype & TIF) #define IS_radhdr(x) (x->ftype & RADHDR) diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript index c4146b6450a..c73c0593a86 100644 --- a/source/blender/imbuf/SConscript +++ b/source/blender/imbuf/SConscript @@ -5,6 +5,9 @@ Import ('library_env') imbuf_env = library_env.Copy () +#if user_options_dict['USE_OPENEXR'] == 1: +# SConscript (['intern/openexr/SConscript']) + source_files = ['intern/allocimbuf.c', 'intern/amiga.c', 'intern/anim.c', diff --git a/source/blender/imbuf/intern/IMB_allocimbuf.h b/source/blender/imbuf/intern/IMB_allocimbuf.h index c01c9d60dd7..7ff44ef29f9 100644 --- a/source/blender/imbuf/intern/IMB_allocimbuf.h +++ b/source/blender/imbuf/intern/IMB_allocimbuf.h @@ -43,12 +43,14 @@ struct ImBuf; short imb_addrectImBuf(struct ImBuf * ibuf); +short imb_addrectfloatImBuf(struct ImBuf * ibuf); short imb_addplanesImBuf(struct ImBuf *ibuf); short imb_addencodedbufferImBuf(struct ImBuf *ibuf); short imb_enlargeencodedbufferImBuf(struct ImBuf *ibuf); void imb_freerectImBuf(struct ImBuf *ibuf); +void imb_freerectfloatImBuf(struct ImBuf *ibuf); void imb_freeplanesImBuf(struct ImBuf *ibuf); short imb_addcmapImBuf(struct ImBuf *ibuf); diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile index 859f7c4cd34..6f8fc7d31bb 100644 --- a/source/blender/imbuf/intern/Makefile +++ b/source/blender/imbuf/intern/Makefile @@ -33,8 +33,17 @@ LIBNAME = imbuf DIR = $(OCGDIR)/blender/imbuf +SOURCEDIR = source/blender/imbuf/intern +include nan_subdirs.mk include nan_compile.mk +include nan_definitions.mk + +ifeq ($(WITH_OPENEXR), true) + DIRS = openexr + CFLAGS += -DWITH_OPENEXR +endif + ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows")) CFLAGS += -funsigned-char diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 3178e15ffee..0c1d182f4b2 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -53,30 +53,48 @@ static unsigned int dfltcmap[16] = { void imb_freeplanesImBuf(struct ImBuf * ibuf) { - if (ibuf==0) return; + if (ibuf==NULL) return; if (ibuf->planes){ - if (ibuf->mall & IB_planes) free(ibuf->planes); + if (ibuf->mall & IB_planes) MEM_freeN(ibuf->planes); } ibuf->planes = 0; ibuf->mall &= ~IB_planes; } +void imb_freerectfloatImBuf(struct ImBuf * ibuf) +{ + if (ibuf==NULL) return; + + if (ibuf->rect_float) { + if (ibuf->mall & IB_rectfloat) { + MEM_freeN(ibuf->rect_float); + ibuf->rect_float=NULL; + } + } + + ibuf->rect_float= NULL; + ibuf->mall &= ~IB_rectfloat; +} void imb_freerectImBuf(struct ImBuf * ibuf) { - if (ibuf==0) return; - if (ibuf->rect){ - if (ibuf->mall & IB_rect) free(ibuf->rect); + if (ibuf==NULL) return; + + if (ibuf->rect) { + if (ibuf->mall & IB_rect) { + MEM_freeN(ibuf->rect); + } } - ibuf->rect=0; + + ibuf->rect= NULL; ibuf->mall &= ~IB_rect; } static void freeencodedbufferImBuf(struct ImBuf * ibuf) { - if (ibuf==0) return; + if (ibuf==NULL) return; if (ibuf->encodedbuffer){ - if (ibuf->mall & IB_mem) free(ibuf->encodedbuffer); + if (ibuf->mall & IB_mem) MEM_freeN(ibuf->encodedbuffer); } ibuf->encodedbuffer = 0; ibuf->encodedbuffersize = 0; @@ -86,57 +104,88 @@ static void freeencodedbufferImBuf(struct ImBuf * ibuf) void IMB_freezbufImBuf(struct ImBuf * ibuf) { - if (ibuf==0) return; + if (ibuf==NULL) return; if (ibuf->zbuf){ - if (ibuf->mall & IB_zbuf) free(ibuf->zbuf); + if (ibuf->mall & IB_zbuf) MEM_freeN(ibuf->zbuf); } - ibuf->zbuf=0; + ibuf->zbuf= NULL; ibuf->mall &= ~IB_zbuf; } +void IMB_freezbuffloatImBuf(struct ImBuf * ibuf) +{ + if (ibuf==NULL) return; + if (ibuf->zbuf_float){ + if (ibuf->mall & IB_zbuffloat) MEM_freeN(ibuf->zbuf_float); + } + ibuf->zbuf_float= NULL; + ibuf->mall &= ~IB_zbuffloat; +} + void IMB_freecmapImBuf(struct ImBuf * ibuf) { - if (ibuf == 0) return; + if (ibuf==NULL) return; if (ibuf->cmap){ - if (ibuf->mall & IB_cmap) free(ibuf->cmap); + if (ibuf->mall & IB_cmap) MEM_freeN(ibuf->cmap); } ibuf->cmap = 0; ibuf->mall &= ~IB_cmap; } - void IMB_freeImBuf(struct ImBuf * ibuf) { if (ibuf){ imb_freeplanesImBuf(ibuf); imb_freerectImBuf(ibuf); + imb_freerectfloatImBuf(ibuf); IMB_freezbufImBuf(ibuf); + IMB_freezbuffloatImBuf(ibuf); IMB_freecmapImBuf(ibuf); freeencodedbufferImBuf(ibuf); - free(ibuf); + MEM_freeN(ibuf); } } short addzbufImBuf(struct ImBuf * ibuf) { int size; - - if (ibuf==0) return(FALSE); + + if (ibuf==NULL) return(FALSE); + IMB_freezbufImBuf(ibuf); - + size = ibuf->x * ibuf->y * sizeof(unsigned int); if ( (ibuf->zbuf = MEM_mallocN(size, "addzbufImBuf")) ){ ibuf->mall |= IB_zbuf; + ibuf->flags |= IB_zbuf; return (TRUE); } + + return (FALSE); +} +short addzbuffloatImBuf(struct ImBuf * ibuf) +{ + int size; + + if (ibuf==NULL) return(FALSE); + + IMB_freezbuffloatImBuf(ibuf); + + size = ibuf->x * ibuf->y * sizeof(float); + if ( (ibuf->zbuf_float = MEM_mallocN(size, "addzbuffloatImBuf")) ){ + ibuf->mall |= IB_zbuffloat; + ibuf->flags |= IB_zbuffloat; + return (TRUE); + } + return (FALSE); } short imb_addencodedbufferImBuf(struct ImBuf * ibuf) { - if (ibuf==0) return(FALSE); + if (ibuf==NULL) return(FALSE); freeencodedbufferImBuf(ibuf); @@ -147,6 +196,7 @@ short imb_addencodedbufferImBuf(struct ImBuf * ibuf) if ( (ibuf->encodedbuffer = MEM_mallocN(ibuf->encodedbuffersize, "addencodedbufferImBuf") )){ ibuf->mall |= IB_mem; + ibuf->flags |= IB_mem; return (TRUE); } @@ -159,7 +209,7 @@ short imb_enlargeencodedbufferImBuf(struct ImBuf * ibuf) unsigned int newsize, encodedsize; void *newbuffer; - if (ibuf==0) return(FALSE); + if (ibuf==NULL) return(FALSE); if (ibuf->encodedbuffersize < ibuf->encodedsize) { printf("imb_enlargeencodedbufferImBuf: error in parameters\n"); @@ -186,21 +236,45 @@ short imb_enlargeencodedbufferImBuf(struct ImBuf * ibuf) ibuf->encodedsize = encodedsize; ibuf->encodedbuffer = newbuffer; ibuf->mall |= IB_mem; + ibuf->flags |= IB_mem; return (TRUE); } +short imb_addrectfloatImBuf(struct ImBuf * ibuf) +{ + int size; + + if (ibuf==NULL) return(FALSE); + + imb_freerectfloatImBuf(ibuf); + + size = ibuf->x * ibuf->y; + size = size * 4 * sizeof(float); + + if ( (ibuf->rect_float = MEM_mallocN(size, "imb_addrectfloatImBuf")) ){ + ibuf->mall |= IB_rectfloat; + ibuf->flags |= IB_rectfloat; + return (TRUE); + } + + return (FALSE); +} +/* question; why also add zbuf? */ short imb_addrectImBuf(struct ImBuf * ibuf) { int size; - if (ibuf==0) return(FALSE); + if (ibuf==NULL) return(FALSE); imb_freerectImBuf(ibuf); - size = ibuf->x * ibuf->y * sizeof(unsigned int); + size = ibuf->x * ibuf->y; + size = size * sizeof(unsigned int); + if ( (ibuf->rect = MEM_mallocN(size, "imb_addrectImBuf")) ){ ibuf->mall |= IB_rect; + ibuf->flags |= IB_rect; if (ibuf->depth > 32) return (addzbufImBuf(ibuf)); else return (TRUE); } @@ -213,7 +287,7 @@ short imb_addcmapImBuf(struct ImBuf *ibuf) { int min; - if (ibuf==0) return(FALSE); + if (ibuf==NULL) return(FALSE); IMB_freecmapImBuf(ibuf); imb_checkncols(ibuf); @@ -224,6 +298,7 @@ short imb_addcmapImBuf(struct ImBuf *ibuf) if (min > sizeof(dfltcmap)) min = sizeof(dfltcmap); memcpy(ibuf->cmap, dfltcmap, min); ibuf->mall |= IB_cmap; + ibuf->flags |= IB_cmap; return (TRUE); } @@ -238,7 +313,7 @@ short imb_addplanesImBuf(struct ImBuf *ibuf) unsigned int **planes; unsigned int *point2; - if (ibuf==0) return(FALSE); + if (ibuf==NULL) return(FALSE); imb_freeplanesImBuf(ibuf); skipx = ((ibuf->x+31) >> 5); @@ -259,12 +334,13 @@ short imb_addplanesImBuf(struct ImBuf *ibuf) point2 += size; } ibuf->mall |= IB_planes; + ibuf->flags |= IB_planes; return (TRUE); } -struct ImBuf *IMB_allocImBuf(short x,short y,uchar d,unsigned int flags,uchar bitmap) +struct ImBuf *IMB_allocImBuf(short x, short y, uchar d, unsigned int flags, uchar bitmap) { struct ImBuf *ibuf; @@ -272,44 +348,60 @@ struct ImBuf *IMB_allocImBuf(short x,short y,uchar d,unsigned int flags,uchar bi if (bitmap) flags |= IB_planes; if (ibuf){ - ibuf->x=x; - ibuf->y=y; - ibuf->depth=d; - ibuf->ftype=TGA; + ibuf->x= x; + ibuf->y= y; + ibuf->depth= d; + ibuf->ftype= TGA; if (flags & IB_rect){ if (imb_addrectImBuf(ibuf)==FALSE){ IMB_freeImBuf(ibuf); - return (0); + return NULL; + } + } + + if (flags & IB_rectfloat){ + if (imb_addrectfloatImBuf(ibuf)==FALSE){ + IMB_freeImBuf(ibuf); + return NULL; } } if (flags & IB_zbuf){ if (addzbufImBuf(ibuf)==FALSE){ IMB_freeImBuf(ibuf); - return (0); + return NULL; + } + } + + if (flags & IB_zbuffloat){ + if (addzbuffloatImBuf(ibuf)==FALSE){ + IMB_freeImBuf(ibuf); + return NULL; } } if (flags & IB_planes){ if (imb_addplanesImBuf(ibuf)==FALSE){ IMB_freeImBuf(ibuf); - return (0); + return NULL; } } } return (ibuf); } +/* does no zbuffers? */ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1) { struct ImBuf *ibuf2, tbuf; int flags = 0; int x, y; - if (ibuf1 == 0) return (0); + if (ibuf1 == NULL) return NULL; if (ibuf1->rect) flags |= IB_rect; + if (ibuf1->rect_float) flags |= IB_rectfloat; if (ibuf1->planes) flags |= IB_planes; x = ibuf1->x; @@ -317,31 +409,40 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1) if (ibuf1->flags & IB_fields) y *= 2; ibuf2 = IMB_allocImBuf(x, y, ibuf1->depth, flags, 0); - if (ibuf2 == 0) return (0); + if (ibuf2 == NULL) return NULL; - if (flags & IB_rect) memcpy(ibuf2->rect,ibuf1->rect,x * y * sizeof(int)); - if (flags & IB_planes) memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int)); + if (flags & IB_rect) + memcpy(ibuf2->rect, ibuf1->rect, x * y * sizeof(int)); + + if (flags & IB_rectfloat) + memcpy(ibuf2->rect_float, ibuf1->rect_float, 4 * x * y * sizeof(float)); + + if (flags & IB_planes) + memcpy(*(ibuf2->planes),*(ibuf1->planes),ibuf1->depth * ibuf1->skipx * y * sizeof(int)); if (ibuf1->encodedbuffer) { ibuf2->encodedbuffersize = ibuf1->encodedbuffersize; if (imb_addencodedbufferImBuf(ibuf2) == FALSE) { IMB_freeImBuf(ibuf2); - return(0); + return NULL; } memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize); } - + /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */ tbuf = *ibuf1; - // pointers goedzetten + // fix pointers tbuf.rect = ibuf2->rect; + tbuf.rect_float = ibuf2->rect_float; tbuf.planes = ibuf2->planes; tbuf.cmap = ibuf2->cmap; tbuf.encodedbuffer = ibuf2->encodedbuffer; + tbuf.zbuf= NULL; + tbuf.zbuf_float= NULL; - // malloc flag goed zetten + // set malloc flag tbuf.mall = ibuf2->mall; *ibuf2 = tbuf; diff --git a/source/blender/imbuf/intern/amiga.c b/source/blender/imbuf/intern/amiga.c index 20655b3a211..d0b794c23ec 100644 --- a/source/blender/imbuf/intern/amiga.c +++ b/source/blender/imbuf/intern/amiga.c @@ -531,7 +531,7 @@ struct ImBuf *imb_loadamiga(int *iffmem,int flags) if (ibuf) { if (ibuf->rect) - if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); } return (ibuf); diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index 284339ece48..51fadc5c06a 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -572,7 +572,7 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) { ibuf = movie_fetchibuf(anim, position); if (ibuf) { anim->curposition = position; - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); } break; case ANIM_AVI: diff --git a/source/blender/imbuf/intern/anim5.c b/source/blender/imbuf/intern/anim5.c index 9f87ba09f5f..89ddf177efe 100644 --- a/source/blender/imbuf/intern/anim5.c +++ b/source/blender/imbuf/intern/anim5.c @@ -161,7 +161,7 @@ static void planes_to_rect(struct ImBuf * ibuf, int flags) { if (ibuf->cmap){ if ((flags & IB_cmap) == 0) { IMB_applycmap(ibuf); - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); } } else if (ibuf->depth == 18){ int i,col; diff --git a/source/blender/imbuf/intern/bitplanes.c b/source/blender/imbuf/intern/bitplanes.c index 6bc2155c949..b80e829da08 100644 --- a/source/blender/imbuf/intern/bitplanes.c +++ b/source/blender/imbuf/intern/bitplanes.c @@ -178,6 +178,8 @@ void imb_bptolong(struct ImBuf *ibuf) { int nobp,i,x; unsigned int *rect,offset; + float black[4] = {0.0,0.0,0.0,1.0}; + float clear[4] = {0.0,0.0,0.0,0.0}; /* first clear all ints */ @@ -187,8 +189,8 @@ void imb_bptolong(struct ImBuf *ibuf) nobp=ibuf->depth; if (nobp != 32){ - if (nobp == 24) IMB_rectoptot(ibuf, 0, IMB_rectfill, 0xff000000); /* set alpha */ - else IMB_rectoptot(ibuf, 0, IMB_rectfill, 0); + if (nobp == 24) IMB_rectfill(ibuf, black); /* set alpha */ + else IMB_rectfill(ibuf, clear); } rect= ibuf->rect; diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 8c579156691..71292e27611 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -38,6 +38,7 @@ #include "imbuf_patch.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_allocimbuf.h" #include "IMB_divers.h" void imb_checkncols(struct ImBuf *ibuf) @@ -95,12 +96,12 @@ void IMB_de_interlace(struct ImBuf *ibuf) tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0); ibuf->x *= 2; - IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_rectcpy(tbuf2, ibuf, 0, 0, tbuf2->x, 0, ibuf->x, ibuf->y); ibuf->x /= 2; - IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y); + IMB_rectcpy(ibuf, tbuf2, 0, tbuf2->y, 0, 0, tbuf2->x, tbuf2->y); IMB_freeImBuf(tbuf1); IMB_freeImBuf(tbuf2); @@ -122,16 +123,12 @@ void IMB_interlace(struct ImBuf *ibuf) tbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0); tbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, 32, IB_rect, 0); - IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, - 0); - IMB_rectop(tbuf2, ibuf, 0, 0, 0, tbuf2->y, 32767, 32767, - IMB_rectcpy,0); + IMB_rectcpy(tbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_rectcpy(tbuf2, ibuf, 0, 0, 0, tbuf2->y, ibuf->x, ibuf->y); ibuf->x *= 2; - IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, - 0); - IMB_rectop(ibuf, tbuf2, tbuf2->x, 0, 0, 0, 32767, 32767, - IMB_rectcpy,0); + IMB_rectcpy(ibuf, tbuf1, 0, 0, 0, 0, tbuf1->x, tbuf1->y); + IMB_rectcpy(ibuf, tbuf2, tbuf2->x, 0, 0, 0, tbuf2->x, tbuf2->y); ibuf->x /= 2; IMB_freeImBuf(tbuf1); @@ -143,11 +140,13 @@ void IMB_interlace(struct ImBuf *ibuf) void IMB_gamwarp(struct ImBuf *ibuf, double gamma) { uchar gam[256]; - int i; - uchar *rect; + int i, do_float=0; + uchar *rect = (uchar *) ibuf->rect; + float *rectf = ibuf->rect_float; if (ibuf == 0) return; if (ibuf->rect == 0) return; + if (ibuf->rect != NULL) do_float = 1; if (gamma == 1.0) return; gamma = 1.0 / gamma; @@ -159,5 +158,61 @@ void IMB_gamwarp(struct ImBuf *ibuf, double gamma) rect[0] = gam[rect[0]]; rect[1] = gam[rect[1]]; rect[2] = gam[rect[2]]; + if (do_float) { + rectf[0] = pow(rectf[0] / 255.0, gamma); + rectf[1] = pow(rectf[1] / 255.0, gamma); + rectf[2] = pow(rectf[2] / 255.0, gamma); + } } } + +#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val)) + +void IMB_rect_from_float(struct ImBuf *ibuf) +{ + /* quick method to convert floatbuf to byte */ + float *tof = ibuf->rect_float; + int i; + unsigned char *to = (unsigned char *) ibuf->rect; + + if(tof==NULL) return; + if(to==NULL) { + imb_addrectImBuf(ibuf); + to = (unsigned char *) ibuf->rect; + } + + for (i = ibuf->x * ibuf->y; i > 0; i--) + { + to[0] = FTOCHAR(tof[0]); + to[1] = FTOCHAR(tof[1]); + to[2] = FTOCHAR(tof[2]); + to[3] = FTOCHAR(tof[3]); + to += 4; + tof += 4; + } +} + +void IMB_float_from_rect(struct ImBuf *ibuf) +{ + /* quick method to convert byte to floatbuf */ + float *tof = ibuf->rect_float; + int i; + unsigned char *to = (unsigned char *) ibuf->rect; + + if(to==NULL) return; + if(tof==NULL) { + imb_addrectfloatImBuf(ibuf); + tof = ibuf->rect_float; + } + + for (i = ibuf->x * ibuf->y; i > 0; i--) + { + tof[0] = ((float)to[0])*(1.0f/255.0f); + tof[1] = ((float)to[1])*(1.0f/255.0f); + tof[2] = ((float)to[2])*(1.0f/255.0f); + tof[3] = ((float)to[3])*(1.0f/255.0f); + to += 4; + tof += 4; + } +} + diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c index 8aea42c7008..810e012761b 100644 --- a/source/blender/imbuf/intern/filter.c +++ b/source/blender/imbuf/intern/filter.c @@ -65,6 +65,25 @@ static void filtrow(unsigned char *point, int x) } } +static void filtrowf(float *point, int x) +{ + float c1,c2,c3; + + if (x>1){ + c1 = c2 = *point; + for(x--;x>0;x--){ + c3 = point[4]; + c1 += (c2 * 2) + c3; + *point = 0.25f*c1; + point += 4; + c1=c2; + c2=c3; + } + *point = 0.25f*(c1 + (c2 * 2) + c2); + } +} + + static void filtcolum(unsigned char *point, int y, int skip) { @@ -89,13 +108,37 @@ static void filtcolum(unsigned char *point, int y, int skip) } } +static void filtcolumf(float *point, int y, int skip) +{ + float c1,c2,c3, *point2; + + if (y>1){ + c1 = c2 = *point; + point2 = point; + for(y--;y>0;y--){ + point2 += skip; + c3 = *point2; + c1 += (c2 * 2) + c3; + *point = 0.25f*c1; + point=point2; + c1=c2; + c2=c3; + } + *point = 0.25f*(c1 + (c2 * 2) + c2); + } +} void IMB_filtery(struct ImBuf *ibuf) { unsigned char *point; - int x, y, skip; + float *pointf; + int x, y, skip, do_float = 0; point = (unsigned char *)ibuf->rect; + pointf = ibuf->rect_float; + + if (ibuf->rect_float != NULL) do_float = 1; + x = ibuf->x; y = ibuf->y; skip = x<<2; @@ -109,6 +152,16 @@ void IMB_filtery(struct ImBuf *ibuf) point++; filtcolum(point,y,skip); point++; + if (do_float) { + if (ibuf->depth > 24) filtcolumf(pointf,y,skip); + pointf++; + filtcolumf(pointf,y,skip); + pointf++; + filtcolumf(pointf,y,skip); + pointf++; + filtcolumf(pointf,y,skip); + pointf++; + } } } @@ -116,9 +169,14 @@ void IMB_filtery(struct ImBuf *ibuf) void imb_filterx(struct ImBuf *ibuf) { unsigned char *point; - int x, y, skip; + float *pointf; + int x, y, skip, do_float =0; point = (unsigned char *)ibuf->rect; + pointf = ibuf->rect_float; + + if (ibuf->rect_float != NULL) do_float = 1; + x = ibuf->x; y = ibuf->y; skip = (x<<2) - 3; @@ -132,6 +190,16 @@ void imb_filterx(struct ImBuf *ibuf) point++; filtrow(point,x); point+=skip; + if (do_float) { + if (ibuf->depth > 24) filtrowf(pointf,x); + pointf++; + filtrowf(pointf,x); + pointf++; + filtrowf(pointf,x); + pointf++; + filtrowf(pointf,x); + pointf+=skip; + } } } diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index dcdd0692fc4..f98244c5a0f 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -40,13 +40,19 @@ * $Id$ */ +#include "IMB_imbuf_types.h" #include "IMB_imbuf.h" /* Only this one is used liberally here, and in imbuf */ -void IMB_convert_rgba_to_abgr(int size, unsigned int *rect) +void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) { - char *cp= (char *)rect, rt; + int size, do_float=0; + unsigned char rt, *cp = (unsigned char *)ibuf->rect; + float rtf, *cpf = ibuf->rect_float; + if (ibuf->rect_float) do_float = 1; + size = ibuf->x * ibuf->y; + while(size-- > 0) { rt= cp[0]; cp[0]= cp[3]; @@ -55,5 +61,15 @@ void IMB_convert_rgba_to_abgr(int size, unsigned int *rect) cp[1]= cp[2]; cp[2]= rt; cp+= 4; + if (do_float) { + rtf= cpf[0]; + cpf[0]= cpf[3]; + cpf[3]= rtf; + rtf= cpf[1]; + cpf[1]= cpf[2]; + cpf[2]= rtf; + cpf+= 4; + } } } + diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 20aa9d75fd2..5c0a3f94a0e 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -398,7 +398,7 @@ struct ImBuf *imb_loadiris(unsigned char *mem, int flags) if (ibuf) { if (ibuf->rect) - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); } return(ibuf); @@ -639,13 +639,13 @@ short imb_saveiris(struct ImBuf * ibuf, char *name, int flags) zsize = (ibuf->depth + 7) >> 3; if (flags & IB_zbuf && ibuf->zbuf != 0) zsize = 8; - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); test_endian_zbuf(ibuf); ret = output_iris(ibuf->rect, ibuf->x, ibuf->y, zsize, name, ibuf->zbuf); /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */ - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); test_endian_zbuf(ibuf); return(ret); diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index 34796bac9d5..afd1038a80f 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -553,15 +553,12 @@ static int save_jstjpeg(char * name, struct ImBuf * ibuf) ibuf->x *= 2; ibuf->y /= 2; - /* extra argument assumed to be 0 (nzc) */ - IMB_rectop(tbuf, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(tbuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); sprintf(fieldname, "%s.jf0", name); returnval = save_vidjpeg(fieldname, tbuf) ; if (returnval == 1) { - /* extra argument assumed to be 0 (nzc) */ - IMB_rectop(tbuf, ibuf, 0, 0, tbuf->x, 0, 32767, 32767, - IMB_rectcpy, 0); + IMB_rectcpy(tbuf, ibuf, 0, 0, tbuf->x, 0, ibuf->x, ibuf->y); sprintf(fieldname, "%s.jf1", name); returnval = save_vidjpeg(fieldname, tbuf); } diff --git a/source/blender/imbuf/intern/openexr/Makefile b/source/blender/imbuf/intern/openexr/Makefile new file mode 100644 index 00000000000..48abc4c4331 --- /dev/null +++ b/source/blender/imbuf/intern/openexr/Makefile @@ -0,0 +1,51 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Gernot Ziegler +# +# ***** END GPL/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = openexr +DIR = $(OCGDIR)/blender/imbuf/openexr + +include nan_compile.mk + +ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows")) + CFLAGS += -funsigned-char +endif + +CFLAGS += $(LEVEL_1_C_WARNINGS) + +CPPFLAGS += -I../../../makesdna +CPPFLAGS += -I../../../blenkernel +CPPFLAGS += -I../../../blenlib +CPPFLAGS += -I../../../imbuf +CPPFLAGS += -I../../../imbuf/intern +CPPFLAGS += $(NAN_OPENEXR_INC) +CPPFLAGS += -I. diff --git a/source/blender/imbuf/intern/openexr/SConscript b/source/blender/imbuf/intern/openexr/SConscript new file mode 100644 index 00000000000..22b61500cc2 --- /dev/null +++ b/source/blender/imbuf/intern/openexr/SConscript @@ -0,0 +1,22 @@ +#!/usr/bin/python +Import ('extra_includes') +Import ('user_options_dict') +Import ('library_env') + +openexr_env = library_env.Copy () + +source_files = ['openexr_api.cpp' + ] + +include_paths = ['.', + '../../../blenkernel', + '../../', + '..', + '../../../blenlib', + '../../../makesdna'] + +openexr_env.Append(CPPPATH = extra_includes) +openexr_env.Append(CPPPATH = include_paths) +openexr_env.Prepend (CPPPATH = user_options_dict['OPENEXR_INCLUDE']) +#ftf_env.Append(CPPDEFINES = 'FTGL_STATIC_LIBRARY') +openexr_env.Library (target='#'+user_options_dict['BUILD_DIR']+'/lib/blender_openexr', source=source_files) diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp new file mode 100644 index 00000000000..b310f128d8e --- /dev/null +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -0,0 +1,438 @@ +/** +* + * ***** BEGIN GPLLICENSE 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. + * + * Copyright by Gernot Ziegler . + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Austin Benesh, Ton Roosendaal (float, half, speedup, cleanup...). + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + + +#include + +extern "C" +{ +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "IMB_allocimbuf.h" +} + +#include + +#if defined (_WIN32) && !defined(FREE_WINDOWS) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +using namespace Imf; +using namespace Imath; + +class Mem_IStream: public IStream +{ +public: + + Mem_IStream (unsigned char *exrbuf, int exrsize): + IStream("dummy"), _exrpos (0), _exrsize(exrsize) { _exrbuf = exrbuf; } + + virtual bool read (char c[], int n); + virtual Int64 tellg (); + virtual void seekg (Int64 pos); + virtual void clear (); + //virtual ~Mem_IStream() {}; // unused + +private: + + Int64 _exrpos; + Int64 _exrsize; + unsigned char *_exrbuf; +}; + +bool Mem_IStream::read (char c[], int n) +{ + if (n + _exrpos <= _exrsize) + { + memcpy(c, (void *)(&_exrbuf[_exrpos]), n); + _exrpos += n; + return true; + } + else + return false; +} + +Int64 Mem_IStream::tellg () +{ + return _exrpos; +} + +void Mem_IStream::seekg (Int64 pos) +{ + _exrpos = pos; +} + +void Mem_IStream::clear () +{ +} + +struct _RGBAZ +{ + half r; + half g; + half b; + half a; + half z; +}; + +typedef struct _RGBAZ RGBAZ; + +extern "C" +{ + +int imb_is_a_openexr(unsigned char *mem) +{ + return Imf::isImfMagic ((const char *)mem); +} + +static void openexr_header_compression(Header *header, int compression) +{ + switch(compression) + { + case 0: + header->compression() = NO_COMPRESSION; + break; + case 1: + header->compression() = PXR24_COMPRESSION; + break; + case 2: + header->compression() = ZIP_COMPRESSION; + break; + case 3: + header->compression() = PIZ_COMPRESSION; + break; + case 4: + header->compression() = RLE_COMPRESSION; + break; + default: + header->compression() = NO_COMPRESSION; + break; + } +} + +static short imb_save_openexr_half(struct ImBuf *ibuf, char *name, int flags) +{ + + int width = ibuf->x; + int height = ibuf->y; + int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize + + try + { + Header header (width, height); + + openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); + + header.channels().insert ("R", Channel (HALF)); + header.channels().insert ("G", Channel (HALF)); + header.channels().insert ("B", Channel (HALF)); + header.channels().insert ("A", Channel (HALF)); + if (write_zbuf) // z we do as float always + header.channels().insert ("Z", Channel (FLOAT)); + + FrameBuffer frameBuffer; + OutputFile *file = new OutputFile(name, header); + + /* we store first everything in half array */ + RGBAZ *pixels = new RGBAZ[height * width]; + RGBAZ *to = pixels; + int xstride= sizeof (RGBAZ); + int ystride= xstride*width; + + /* indicate used buffers */ + frameBuffer.insert ("R", Slice (HALF, (char *) &pixels[0].r, xstride, ystride)); + frameBuffer.insert ("G", Slice (HALF, (char *) &pixels[0].g, xstride, ystride)); + frameBuffer.insert ("B", Slice (HALF, (char *) &pixels[0].b, xstride, ystride)); + frameBuffer.insert ("A", Slice (HALF, (char *) &pixels[0].a, xstride, ystride)); + + if (write_zbuf) + frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width, + sizeof(float), sizeof(float) * -width)); + if(ibuf->rect_float) { + float *from; + + for (int i = ibuf->y-1; i >= 0; i--) + { + from= ibuf->rect_float + 4*i*width; + + for (int j = ibuf->x; j > 0; j--) + { + to->r = from[0]; + to->g = from[1]; + to->b = from[2]; + to->a = from[3]; + to++; from += 4; + } + } + } + else { + unsigned char *from; + + for (int i = ibuf->y-1; i >= 0; i--) + { + from= (unsigned char *)(ibuf->rect + i*width); + + for (int j = ibuf->x; j > 0; j--) + { + to->r = (float)(from[0])/255.0; + to->g = (float)(from[1])/255.0; + to->b = (float)(from[2])/255.0; + to->a = (float)(from[3])/255.0; + to++; from += 4; + } + } + } + +// printf("OpenEXR-save: Writing OpenEXR file of height %d.\n", height); + + file->setFrameBuffer (frameBuffer); + file->writePixels (height); + delete file; + } + catch (const std::exception &exc) + { + printf("OpenEXR-save: ERROR: %s\n", exc.what()); + if (ibuf) IMB_freeImBuf(ibuf); + + return (0); + } + + return (1); +} + +static short imb_save_openexr_float(struct ImBuf *ibuf, char *name, int flags) +{ + + int width = ibuf->x; + int height = ibuf->y; + int write_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != NULL; // summarize + + try + { + Header header (width, height); + + openexr_header_compression(&header, ibuf->ftype & OPENEXR_COMPRESS); + + header.channels().insert ("R", Channel (FLOAT)); + header.channels().insert ("G", Channel (FLOAT)); + header.channels().insert ("B", Channel (FLOAT)); + header.channels().insert ("A", Channel (FLOAT)); + if (write_zbuf) + header.channels().insert ("Z", Channel (FLOAT)); + + FrameBuffer frameBuffer; + OutputFile *file = new OutputFile(name, header); + float *first= ibuf->rect_float + 4*(height-1)*width; + int xstride = sizeof(float) * 4; + int ystride = - xstride*width; + + frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride)); + frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride)); + frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride)); + frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride)); + + if (write_zbuf) + frameBuffer.insert ("Z", Slice (FLOAT, (char *) ibuf->zbuf_float + 4*(height-1)*width, + sizeof(float), sizeof(float) * -width)); + file->setFrameBuffer (frameBuffer); + file->writePixels (height); + delete file; + } + catch (const std::exception &exc) + { + printf("OpenEXR-save: ERROR: %s\n", exc.what()); + if (ibuf) IMB_freeImBuf(ibuf); + + return (0); + } + + return (1); + // printf("OpenEXR-save: Done.\n"); +} + + +short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags) +{ + if (flags & IB_mem) + { + printf("OpenEXR-save: Create EXR in memory CURRENTLY NOT SUPPORTED !\n"); + imb_addencodedbufferImBuf(ibuf); + ibuf->encodedsize = 0; + return(0); + } + + if (ibuf->ftype & OPENEXR_HALF) + return imb_save_openexr_half(ibuf, name, flags); + else { + /* when no float rect, we save as half (16 bits is sufficient) */ + if (ibuf->rect_float==NULL) + return imb_save_openexr_half(ibuf, name, flags); + else + return imb_save_openexr_float(ibuf, name, flags); + } +} + + +typedef struct RGBA +{ + float r; + float g; + float b; + float a; +} RGBA; + + +static void exr_print_filecontents(InputFile *file) +{ + const ChannelList &channels = file->header().channels(); + + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) + { + const Channel &channel = i.channel(); + printf("OpenEXR-load: Found channel %s of type %d\n", i.name(), channel.type); + } +} + +static int exr_has_zbuffer(InputFile *file) +{ + const ChannelList &channels = file->header().channels(); + + for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) + { + const Channel &channel = i.channel(); + if(strcmp("Z", i.name())==0) + return 1; + } + return 0; +} + + +struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags) +{ + struct ImBuf *ibuf = NULL; + InputFile *file = NULL; + + if (imb_is_a_openexr(mem) == 0) return(NULL); + + try + { + Mem_IStream membuf(mem, size); + file = new InputFile(membuf); + + Box2i dw = file->header().dataWindow(); + int width = dw.max.x - dw.min.x + 1; + int height = dw.max.y - dw.min.y + 1; + + //printf("OpenEXR-load: image data window %d %d %d %d\n", + // dw.min.x, dw.min.y, dw.max.x, dw.max.y); + + //exr_print_filecontents(file); + + ibuf = IMB_allocImBuf(width, height, 32, 0, 0); + + if (ibuf) + { + ibuf->ftype = OPENEXR; + + if (!(flags & IB_test)) + { + FrameBuffer frameBuffer; + float *first; + int xstride = sizeof(float) * 4; + int ystride = - xstride*width; + + imb_addrectfloatImBuf(ibuf); + + /* inverse correct first pixel for datawindow coordinates (- dw.min.y because of y flip) */ + first= ibuf->rect_float - 4*(dw.min.x - dw.min.y*width); + /* but, since we read y-flipped (negative y stride) we move to last scanline */ + first+= 4*(height-1)*width; + + frameBuffer.insert ("R", Slice (FLOAT, (char *) first, xstride, ystride)); + frameBuffer.insert ("G", Slice (FLOAT, (char *) (first+1), xstride, ystride)); + frameBuffer.insert ("B", Slice (FLOAT, (char *) (first+2), xstride, ystride)); + /* 1.0 is fill value */ + frameBuffer.insert ("A", Slice (FLOAT, (char *) (first+3), xstride, ystride, 1, 1, 1.0f)); + + if(exr_has_zbuffer(file)) { + float *firstz; + + addzbuffloatImBuf(ibuf); + firstz= ibuf->zbuf_float - (dw.min.x - dw.min.y*width); + firstz+= (height-1)*width; + frameBuffer.insert ("Z", Slice (FLOAT, (char *)firstz , sizeof(float), -width*sizeof(float))); + } + + file->setFrameBuffer (frameBuffer); + file->readPixels (dw.min.y, dw.max.y); + + IMB_rect_from_float(ibuf); + } + } + return(ibuf); + + } + catch (const std::exception &exc) + { + std::cerr << exc.what() << std::endl; + if (ibuf) IMB_freeImBuf(ibuf); + + return (0); + } + +} + + +} // export "C" diff --git a/source/blender/render/intern/include/jitter.h b/source/blender/imbuf/intern/openexr/openexr_api.h similarity index 70% rename from source/blender/render/intern/include/jitter.h rename to source/blender/imbuf/intern/openexr/openexr_api.h index 696ded297b1..c12eb1f05ae 100644 --- a/source/blender/render/intern/include/jitter.h +++ b/source/blender/imbuf/intern/openexr/openexr_api.h @@ -1,7 +1,5 @@ -/* - * jitter.h - * - * $Id$ +/** + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -27,26 +25,38 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Austin Benesh. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifndef JITTER_H -#define JITTER_H +#ifndef _OPENEXR_API_H +#define _OPENEXR_API_H #ifdef __cplusplus -extern "C" { +extern "C" { #endif -extern float jit[64][2]; +#define OPENEXR_FLOATRGB 0x1 +#define OPENEXR_ZBUF 0x2 + +#include + + /** + * Test presence of OpenEXR file. + * @param mem pointer to loaded OpenEXR bitstream + */ + +int imb_is_a_openexr(unsigned char *mem); + +short imb_save_openexr(struct ImBuf *ibuf, char *name, int flags); -extern void initjit(float *jitarr, int num); -extern void init_render_jit(int nr); +struct ImBuf *imb_load_openexr(unsigned char *mem, int size, int flags); #ifdef __cplusplus } #endif -#endif + +#endif /* __OPENEXR_API_H */ diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index fe18d4e3574..bd2d41881db 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -29,13 +29,12 @@ * ***** END GPL LICENSE BLOCK ***** */ - -/* - ------------------------------------------------------------------------------------------------- +/* ---------------------------------------------------------------------- Radiance High Dynamic Range image file IO - For description and code for reading/writing of radiance hdr files by Greg Ward, refer to: + For description and code for reading/writing of radiance hdr files + by Greg Ward, refer to: http://radsite.lbl.gov/radiance/refer/Notes/picture_format.html - ------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------- */ #ifdef WIN32 @@ -68,9 +67,7 @@ typedef float fCOLOR[3]; #define copy_rgbe(c1, c2) (c2[RED]=c1[RED], c2[GRN]=c1[GRN], c2[BLU]=c1[BLU], c2[EXP]=c1[EXP]) #define copy_fcol(f1, f2) (f2[RED]=f1[RED], f2[GRN]=f1[GRN], f2[BLU]=f1[BLU]) -/*-------------------------------------------------------------------------------------------------*/ /* read routines */ - static unsigned char* oldreadcolrs(RGBE *scan, unsigned char *mem, int xmax) { int i, rshift = 0, len = xmax; @@ -127,7 +124,6 @@ static unsigned char* freadcolrs(RGBE *scan, unsigned char* mem, int xmax) return mem; } -/*-------------------------------------------------------------------------------------------------*/ /* helper functions */ /* rgbe -> float color */ @@ -161,7 +157,6 @@ static void FLOAT2RGBE(fCOLOR fcol, RGBE rgbe) } } -/*-------------------------------------------------------------------------------------------------*/ /* ImBuf read */ int imb_is_a_hdr(void *buf) @@ -174,16 +169,17 @@ int imb_is_a_hdr(void *buf) struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags) { - int found=0; - char oriY[80], oriX[80]; - int width=0, height=0; - RGBE* sline; - int x, y; - char* ptr; - fCOLOR fcol; - int ir, ig, ib; - unsigned char* rect; struct ImBuf* ibuf; + RGBE* sline; + fCOLOR fcol; + float* rect_float; + int found=0; + int width=0, height=0; + int x, y; + int ir, ig, ib; + unsigned char* ptr; + unsigned char* rect; + char oriY[80], oriX[80]; if (imb_is_a_hdr((void*)mem)) { @@ -198,11 +194,11 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags) sscanf((char*)&mem[x+1], "%s %d %s %d", (char*)&oriY, &height, (char*)&oriX, &width); /* find end of this line, data right behind it */ - ptr = strchr((char*)&mem[x+1], '\n'); + ptr = (unsigned char *)strchr((char*)&mem[x+1], '\n'); ptr++; - if (flags & IB_test) ibuf = IMB_allocImBuf(width, height, 24, 0, 0); - else ibuf = IMB_allocImBuf(width, height, 24, 1, 0); + if (flags & IB_test) ibuf = IMB_allocImBuf(width, height, 32, 0, 0); + else ibuf = IMB_allocImBuf(width, height, 32, IB_rect|IB_rectfloat, 0); if (ibuf==NULL) return NULL; ibuf->ftype = RADHDR; @@ -213,6 +209,8 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags) /* read in and decode the actual data */ sline = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_read_tmpscan"); rect = (unsigned char*)ibuf->rect; + rect_float = (float *)ibuf->rect_float; + for (y=0;y255) ? 255 : ig)); *rect++ = (unsigned char)((ib<0) ? 0 : ((ib>255) ? 255 : ib)); *rect++ = 255; - /*--------------------------------------------------------------------------------------*/ } } MEM_freeN(sline); @@ -251,36 +251,39 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags) return NULL; } -/*-------------------------------------------------------------------------------------------------*/ /* ImBuf write */ - - -static int fwritecolrs(FILE* file, int width, RGBE* rgbe_scan, unsigned char* ibufscan, float* fpscan) +static int fwritecolrs(FILE* file, int width, unsigned char* ibufscan, float* fpscan) { - int i, j, beg, c2, cnt=0; + int x, i, j, beg, c2, cnt=0; fCOLOR fcol; - RGBE rgbe; + RGBE rgbe, *rgbe_scan; if ((ibufscan==NULL) && (fpscan==NULL)) return 0; + rgbe_scan = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_write_tmpscan"); + /* convert scanline */ - for (i=0, j=0;i MAXELEN)) /* OOBs, write out flat */ - return (fwrite((char *)rgbe_scan, sizeof(RGBE), width, file) - width); + if ((width < MINELEN) | (width > MAXELEN)) { /* OOBs, write out flat */ + x=fwrite((char *)rgbe_scan, sizeof(RGBE), width, file) - width; + MEM_freeN(rgbe_scan); + return x; + } /* put magic header */ putc(2, file); putc(2, file); @@ -315,6 +318,7 @@ static int fwritecolrs(FILE* file, int width, RGBE* rgbe_scan, unsigned char* ib else cnt = 0; } } + MEM_freeN(rgbe_scan); return(ferror(file) ? -1 : 0); } @@ -335,58 +339,31 @@ static void writeHeader(FILE *file, int width, int height) short imb_savehdr(struct ImBuf *ibuf, char *name, int flags) { + FILE* file = fopen(name, "wb"); + float *fp= NULL; int y, width=ibuf->x, height=ibuf->y; - RGBE* sline; - - FILE* file = fopen(name, "wb"); + char *cp= NULL; + if (file==NULL) return 0; writeHeader(file, width, height); - sline = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_write_tmpscan"); - + if(ibuf->rect) + cp= (char *)(ibuf->rect + (height-1)*width); + if(ibuf->rect_float) + fp= ibuf->rect_float + 4*(height-1)*width; + for (y=height-1;y>=0;y--) { - if (fwritecolrs(file, width, sline, (unsigned char*)&ibuf->rect[y*width], NULL) < 0) - { // error + if (fwritecolrs(file, width, cp, fp) < 0) { fclose(file); - MEM_freeN(sline); printf("HDR write error\n"); return 0; } + if(cp) cp-= 4*width; + if(fp) fp-= 4*width; } fclose(file); - MEM_freeN(sline); return 1; } -/* Temporary routine to save directly from render floatbuffer. - Called by schrijfplaatje() in toets.c */ -short imb_savehdr_fromfloat(float *fbuf, char *name, int width, int height) -{ - int y; - RGBE* sline; - - FILE* file = fopen(name, "wb"); - if (file==NULL) return 0; - - writeHeader(file, width, height); - - sline = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_write_tmpscan"); - - for (y=height-1;y>=0;y--) { - if (fwritecolrs(file, width, sline, NULL, &fbuf[y*width*4]) < 0) - { // error - fclose(file); - MEM_freeN(sline); - printf("HDR write error\n"); - return 0; - } - } - - fclose(file); - MEM_freeN(sline); - return 1; -} - -/*-------------------------------------------------------------------------------------------------*/ diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c index 779401c3183..42b23dfb6e9 100644 --- a/source/blender/imbuf/intern/readimage.c +++ b/source/blender/imbuf/intern/readimage.c @@ -54,6 +54,10 @@ #include "IMB_radiance_hdr.h" #include "BKE_global.h" +#ifdef WITH_OPENEXR +#include "openexr/openexr_api.h" +#endif + #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined (__APPLE__) #include "quicktime_import.h" @@ -138,6 +142,11 @@ ImBuf *IMB_ibImageFromMemory(int *mem, int size, int flags) { ibuf = imb_loadhdr((uchar*)mem, size, flags); if (ibuf) return (ibuf); +#ifdef WITH_OPENEXR + ibuf = imb_load_openexr((uchar *)mem, size, flags); + if (ibuf) return (ibuf); +#endif + #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined (__APPLE__) if(G.have_quicktime) { diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 22f2698a8c5..c764d06b500 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -41,33 +41,17 @@ #include "IMB_allocimbuf.h" -void IMB_rectcpy(unsigned int *drect, unsigned int *srect, int x, int dummy) +void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx, + int desty, int srcx, int srcy, int width, int height) { - memcpy(drect,srect, x * sizeof(int)); -} + unsigned int *drect, *srect; + float *drectf = NULL; + float *srectf = NULL; + int tmp, do_float = 0; - -void IMB_rectfill(unsigned int *drect, unsigned int *srect, int x, int value) -{ - for (;x > 0; x--) *drect++ = value; -} - -void IMB_rectop(struct ImBuf *dbuf, - struct ImBuf *sbuf, - int destx, - int desty, - int srcx, - int srcy, - int width, - int height, - void (*operation)(unsigned int *, unsigned int*, int, int), - int value) -{ - unsigned int *drect,*srect; - int tmp; - - if (dbuf == 0) return; - if (operation == 0) return; + if (dbuf == NULL) return; + + if (sbuf->rect_float) do_float = 1; if (destx < 0){ srcx -= destx ; @@ -96,6 +80,7 @@ void IMB_rectop(struct ImBuf *dbuf, if (height > tmp) height = tmp; drect = dbuf->rect + desty * dbuf->x + destx; + if (do_float) drectf = dbuf->rect_float + desty * dbuf->x + destx; destx = dbuf->x; if (sbuf){ @@ -110,25 +95,60 @@ void IMB_rectop(struct ImBuf *dbuf, srect = sbuf->rect; srect += srcy * sbuf->x; srect += srcx; + if (do_float) { + srectf = sbuf->rect_float; + srectf += srcy * sbuf->x; + srectf += srcx; + } srcx = sbuf->x; } else{ if (width <= 0) return; if (height <= 0) return; srect = drect; + srectf = drectf; srcx = destx; } for (;height > 0; height--){ - operation(drect,srect,width, value); + + memcpy(drect,srect, width * sizeof(int)); drect += destx; srect += srcx; + + if (do_float) { + memcpy(drectf,srectf, width * sizeof(float) * 4); + drectf += destx; + srectf += srcx; + } } } - -void IMB_rectoptot(struct ImBuf *dbuf, struct ImBuf *sbuf, - void (*operation)(unsigned int *, unsigned int*, int, int), int value) +void IMB_rectfill(struct ImBuf *drect, float col[4]) { - IMB_rectop(dbuf,sbuf,0,0,0,0,32767,32767,operation, value); + int num; + unsigned int *rrect = drect->rect; + unsigned char *spot; + + num = drect->x * drect->y; + for (;num > 0; num--) { + spot = (unsigned char *)rrect; + spot[0] = (int)(col[0]*255); + spot[1] = (int)(col[1]*255); + spot[2] = (int)(col[2]*255); + spot[3] = (int)(col[3]*255); + *rrect++; + } + if(drect->rect_float) { + float *rrectf = drect->rect_float; + + num = drect->x * drect->y; + for (;num > 0; num--) { + *rrectf++ = col[0]; + *rrectf++ = col[1]; + *rrectf++ = col[2]; + *rrectf++ = col[3]; + } + } } + diff --git a/source/blender/imbuf/intern/rotate.c b/source/blender/imbuf/intern/rotate.c index f8d01789cdc..13edfbf0a33 100644 --- a/source/blender/imbuf/intern/rotate.c +++ b/source/blender/imbuf/intern/rotate.c @@ -43,26 +43,46 @@ void IMB_flipy(struct ImBuf * ibuf) { - short x,y,backx; - unsigned int *top,*bottom,temp; + short x, y; + unsigned int *top, *bottom, do_float=0, *line; + float *topf=NULL, *bottomf=NULL, *linef=NULL; - if (ibuf == 0) return; - if (ibuf->rect == 0) return; + if (ibuf == NULL) return; + if (ibuf->rect == NULL) return; + + if (ibuf->rect_float) do_float =1; x = ibuf->x; y = ibuf->y; - backx = x<<1; top = ibuf->rect; bottom = top + ((y-1) * x); + line= MEM_mallocN(x*sizeof(int), "linebuf"); + + if (do_float) { + topf= ibuf->rect_float; + bottomf = topf + 4*((y-1) * x); + linef= MEM_mallocN(4*x*sizeof(float), "linebuff"); + } y >>= 1; - for(;y>0;y--){ - for(x = ibuf->x; x > 0; x--){ - temp = *top; - *(top++) = *bottom; - *(bottom++) = temp; + for(;y>0;y--) { + + memcpy(line, top, x*sizeof(int)); + memcpy(top, bottom, x*sizeof(int)); + memcpy(bottom, line, x*sizeof(int)); + bottom -= x; + top+= x; + + if(do_float) { + memcpy(linef, topf, 4*x*sizeof(float)); + memcpy(topf, bottomf, 4*x*sizeof(float)); + memcpy(bottomf, linef, 4*x*sizeof(float)); + bottomf -= 4*x; + topf+= 4*x; } - bottom -= backx; } + + MEM_freeN(line); + if(linef) MEM_freeN(linef); } diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c index 7749dadb2ca..c962f1fbde5 100644 --- a/source/blender/imbuf/intern/scaling.c +++ b/source/blender/imbuf/intern/scaling.c @@ -52,20 +52,27 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) struct ImBuf *ibuf2; uchar *p1,*_p1,*dest; short a,r,g,b,x,y; + float af,rf,gf,bf, *p1f, *_p1f, *destf; + int do_float = 0; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1)); - ibuf2 = IMB_allocImBuf((ibuf1->x)/2 , ibuf1->y , ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2 = IMB_allocImBuf((ibuf1->x)/2, ibuf1->y, ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); _p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; + + _p1f = ibuf1->rect_float; + destf= ibuf2->rect_float; for(y=ibuf2->y;y>0;y--){ p1 = _p1; + p1f = _p1f; for(x = ibuf2->x ; x>0 ; x--){ a = *(p1++) ; b = *(p1++) ; @@ -79,8 +86,23 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) *(dest++) = b >> 1; *(dest++) = g >> 1; *(dest++) = r >> 1; + if (do_float) { + af = *(p1f++); + bf = *(p1f++); + gf = *(p1f++); + rf = *(p1f++); + af += *(p1f++); + bf += *(p1f++); + gf += *(p1f++); + rf += *(p1f++); + *(destf++) = 0.5f*af; + *(destf++) = 0.5f*bf; + *(destf++) = 0.5f*gf; + *(destf++) = 0.5f*rf; + } } _p1 += (ibuf1->x << 2); + if (do_float) _p1f += (ibuf1->x << 2); } return (ibuf2); } @@ -89,21 +111,30 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - int *p1,*dest, i, col; + int *p1,*dest, i, col, do_float=0; + float *p1f, *destf, colf; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; - ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); p1 = (int *) ibuf1->rect; dest=(int *) ibuf2->rect; + p1f = ibuf1->rect_float; + destf = ibuf2->rect_float; for(i = ibuf1->y * ibuf1->x ; i>0 ; i--) { col = *p1++; *dest++ = col; *dest++ = col; + if (do_float) { + colf = *p1f++; + *destf++ = col; + *destf++ = col; + } } return (ibuf2); @@ -113,8 +144,8 @@ struct ImBuf *IMB_double_x(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); ibuf2 = IMB_double_fast_x(ibuf1); @@ -128,20 +159,30 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1) struct ImBuf *ibuf2; uchar *p1,*p2,*_p1,*dest; short a,r,g,b,x,y; + int do_float = 0; + float af,rf,gf,bf,*p1f,*p2f,*_p1f,*destf; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + p1f = NULL; p2f = NULL; + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1)); - ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); _p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; + _p1f = ibuf1->rect_float; + destf= ibuf2->rect_float; for(y=ibuf2->y ; y>0 ; y--){ p1 = _p1; p2 = _p1 + (ibuf1->x << 2); + if (do_float) { + p1f = _p1f; + p2f = _p1f + (ibuf1->x << 2); + } for(x = ibuf2->x ; x>0 ; x--){ a = *(p1++) ; b = *(p1++) ; @@ -155,8 +196,23 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1) *(dest++) = b >> 1; *(dest++) = g >> 1; *(dest++) = r >> 1; + if (do_float) { + af = *(p1f++) ; + bf = *(p1f++) ; + gf = *(p1f++) ; + rf = *(p1f++); + af += *(p2f++) ; + bf += *(p2f++) ; + gf += *(p2f++) ; + rf += *(p2f++); + *(destf++) = 0.5f*af; + *(destf++) = 0.5f*bf; + *(destf++) = 0.5f*gf; + *(destf++) = 0.5f*rf; + } } _p1 += (ibuf1->x << 3); + if (do_float) _p1f += (ibuf1->x << 3); } return (ibuf2); } @@ -166,21 +222,31 @@ struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; int *p1, *dest1, *dest2; + float *p1f, *dest1f, *dest2f; short x,y; + int do_float =0; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float =1; - ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); p1 = (int *) ibuf1->rect; dest1=(int *) ibuf2->rect; + p1f = ibuf1->rect_float; + dest1f= ibuf2->rect_float; for(y = ibuf1->y ; y>0 ; y--){ dest2 = dest1 + ibuf2->x; for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++; dest1 = dest2; + if (do_float) { + dest2f = dest1f + ibuf2->x; + for(x = ibuf2->x ; x>0 ; x--) *dest1f++ = *dest2f++ = *p1f++; + dest1f = dest2f; + } } return (ibuf2); @@ -190,8 +256,8 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - if (ibuf1==0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); ibuf2 = IMB_double_fast_y(ibuf1); @@ -203,23 +269,29 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - uchar *p1,*p2,*dest; + uchar *p1, *p2, *dest; + float *p1f, *destf, *p2f = NULL; int x,y; + int do_float =0; - if (ibuf1 == 0) return (0); - if (ibuf1->rect == 0) return (0); + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; if (ibuf1->x <= 1) return(IMB_half_y(ibuf1)); if (ibuf1->y <= 1) return(IMB_half_x(ibuf1)); - ibuf2=IMB_allocImBuf((ibuf1->x)/2,(ibuf1->y)/2,ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2=IMB_allocImBuf((ibuf1->x)/2, (ibuf1->y)/2, ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); + p1f = ibuf1->rect_float; + destf=ibuf2->rect_float; p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; for(y=ibuf2->y;y>0;y--){ p2 = p1 + (ibuf1->x << 2); + if (do_float) p2f = p1f + (ibuf1->x << 2); for(x=ibuf2->x;x>0;x--){ dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2; dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2; @@ -228,10 +300,21 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) p1 += 8; p2 += 8; dest += 4; + if (do_float){ + destf[0] = 0.25f*(p1f[0] + p2f[0] + p1f[4] + p2f[4]); + destf[1] = 0.25f*(p1f[1] + p2f[1] + p1f[5] + p2f[5]); + destf[2] = 0.25f*(p1f[2] + p2f[2] + p1f[6] + p2f[6]); + destf[3] = 0.25f*(p1f[3] + p2f[3] + p1f[7] + p2f[7]); + p1f += 8; + p2f += 8; + destf += 4; + } } p1=p2; + if (do_float) p1f=p2f; if(ibuf1->x & 1) { p1+=4; + if (do_float) p1f+=4; } } return (ibuf2); @@ -243,34 +326,59 @@ struct ImBuf *IMB_onethird(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; uchar *p1,*p2,*p3,*dest; + float *p1f, *p2f, *p3f, *destf; + int do_float=0; short a,r,g,b,x,y,i; + float af,rf,gf,bf; - if (ibuf1 == 0) return (0); - if (ibuf1->rect == 0) return (0); + p2f = NULL; p3f = NULL; + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; - ibuf2=IMB_allocImBuf((ibuf1->x)/3,(ibuf1->y)/3,ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2=IMB_allocImBuf((ibuf1->x)/3, (ibuf1->y)/3, ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); + p1f = ibuf1->rect_float; + destf = ibuf2->rect_float; p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; for(y=ibuf2->y;y>0;y--){ p2 = p1 + (ibuf1->x << 2); p3 = p2 + (ibuf1->x << 2); + if (do_float) { + p2f = p1f + (ibuf1->x <<2); + p3f = p2f + (ibuf1->x <<2); + } for(x=ibuf2->x;x>0;x--){ a=r=g=b=0; + af=rf=gf=bf=0; for (i=3;i>0;i--){ a += *(p1++) + *(p2++) + *(p3++); b += *(p1++) + *(p2++) + *(p3++); g += *(p1++) + *(p2++) + *(p3++); r += *(p1++) + *(p2++) + *(p3++); + if (do_float) { + af += *(p1f++) + *(p2f++) + *(p3f++); + bf += *(p1f++) + *(p2f++) + *(p3f++); + gf += *(p1f++) + *(p2f++) + *(p3f++); + rf += *(p1f++) + *(p2f++) + *(p3f++); + } } *(dest++) = a/9; *(dest++) = b/9; *(dest++) = g/9; *(dest++) = r/9; + if (do_float) { + *(destf++) = af/9.0f; + *(destf++) = bf/9.0f; + *(destf++) = gf/9.0f; + *(destf++) = rf/9.0f; + } } p1=p3; + if (do_float) p1f = p3f; } return (ibuf2); } @@ -280,33 +388,55 @@ struct ImBuf *IMB_halflace(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; uchar *p1,*p2,*dest; + float *p1f,*p2f,*destf; short a,r,g,b,x,y,i; + float af,rf,gf,bf; + int do_float = 0; - if (ibuf1 == 0) return (0); - if (ibuf1->rect == 0) return (0); + p2f = NULL; + if (ibuf1==NULL) return (0); + if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect_float) do_float = 1; - ibuf2=IMB_allocImBuf((ibuf1->x)/4,(ibuf1->y)/2,ibuf1->depth,1,0); - if (ibuf2==0) return (0); + ibuf2=IMB_allocImBuf((ibuf1->x)/4, (ibuf1->y)/2, ibuf1->depth, ibuf1->flags, 0); + if (ibuf2==NULL) return (0); + p1f = ibuf1->rect_float; + destf= ibuf2->rect_float; p1 = (uchar *) ibuf1->rect; dest=(uchar *) ibuf2->rect; for(y= ibuf2->y / 2 ; y>0;y--){ p2 = p1 + (ibuf1->x << 3); + if (do_float) p2f = p1f + (ibuf1->x << 3); for(x = 2 * ibuf2->x;x>0;x--){ a=r=g=b=0; + af=rf=gf=bf=0; for (i=4;i>0;i--){ a += *(p1++) + *(p2++); b += *(p1++) + *(p2++); g += *(p1++) + *(p2++); r += *(p1++) + *(p2++); + if (do_float) { + af += *(p1f++) + *(p2f++); + bf += *(p1f++) + *(p2f++); + gf += *(p1f++) + *(p2f++); + rf += *(p1f++) + *(p2f++); + } } *(dest++) = a >> 3; *(dest++) = b >> 3; *(dest++) = g >> 3; *(dest++) = r >> 3; + if (do_float) { + *(destf++) = 0.125f*af; + *(destf++) = 0.125f*bf; + *(destf++) = 0.125f*gf; + *(destf++) = 0.125f*rf; + } } p1 = p2; + if (do_float) p1f = p2f; } return (ibuf2); } @@ -315,14 +445,23 @@ struct ImBuf *IMB_halflace(struct ImBuf *ibuf1) static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) { uchar *rect,*_newrect,*newrect; - float sample, add, val, nval; - int x, y, i; + float *rectf,*_newrectf,*newrectf; + float sample, add, val, nval, valf, nvalf; + int x, y, i, do_float=0; - if (ibuf == 0) return(0); - if (ibuf->rect == 0) return(ibuf); + rectf = NULL; _newrectf= NULL; newrectf = NULL; + nval = 0; nvalf = 0; + + if (ibuf==NULL) return(0); + if (ibuf->rect==NULL) return(ibuf); + if (ibuf->rect_float) { + do_float = 1; + _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf"); + if (_newrectf==NULL) return(ibuf); + } - _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int)); - if (_newrect == 0) return(ibuf); + _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaledownx"); + if (_newrect==NULL) return(ibuf); add = (ibuf->x - 0.001) / newx; @@ -331,22 +470,39 @@ static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) rect = (uchar *) ibuf->rect; rect += i; newrect = _newrect + i; + if (do_float) { + rectf = ibuf->rect_float; + rectf += i; + newrectf = _newrectf + i; + } for (y = ibuf->y; y>0 ; y--){ - val = sample = 0.0; + val = sample = valf = 0.0; for (x = newx ; x>0 ; x--){ nval = - val * sample; + if (do_float) nvalf = - valf * sample; sample += add; while (sample >= 1.0){ sample -= 1.0; nval += *rect; rect += 4; + if (do_float) { + nvalf += *rectf; + rectf += 4; + } } val = *rect; rect += 4; nval += sample * val; + if (do_float) { + valf = *rectf; + rectf += 4; + nvalf += sample * valf; + *newrectf = (nvalf/add) + 0.5; + newrectf += 4; + } sample -= 1.0; *newrect = (nval/add) + 0.5; newrect += 4; @@ -357,6 +513,13 @@ static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (unsigned int *) _newrect; + + if (do_float) { + imb_freerectfloatImBuf(ibuf); + ibuf->mall |= IB_rectfloat; + ibuf->rect_float = _newrectf; + } + ibuf->x = newx; return(ibuf); } @@ -364,15 +527,25 @@ static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx) static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) { - uchar *rect,*_newrect,*newrect; - float sample,add,val,nval; - int x,y,i,skipx; + uchar *rect, *_newrect, *newrect; + float *rectf, *_newrectf, *newrectf; + float sample, add, val, nval, valf, nvalf; + int x, y, i, skipx, do_float = 0; - if (ibuf == 0) return(0); - if (ibuf->rect == 0) return(ibuf); + rectf= NULL; _newrectf = NULL; newrectf = NULL; + nval = 0; nvalf = 0; - _newrect = (uchar *) malloc(newy * ibuf->x * sizeof(int)); - if (_newrect == 0) return(ibuf); + if (ibuf==NULL) return(0); + if (ibuf->rect==NULL) return(ibuf); + + if (ibuf->rect_float) { + do_float = 1; + _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaldownyf"); + if (_newrectf==NULL) return(ibuf); + } + + _newrect = MEM_mallocN(newy * ibuf->x * sizeof(int), "scaledowny"); + if (_newrect==NULL) return(ibuf); add = (ibuf->y - 0.001) / newy; skipx = 4 * ibuf->x; @@ -382,23 +555,39 @@ static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) for (x = skipx - 4; x>=0 ; x-= 4){ rect = ((uchar *) ibuf->rect) + i + x; newrect = _newrect + i + x; + if (do_float) { + rectf = ((float *) ibuf->rect_float) + i + x; + newrectf = _newrectf + i + x; + } val = sample = 0.0; for (y = newy ; y>0 ; y--){ nval = - val * sample; + if (do_float) nvalf = - val * sample; sample += add; while (sample >= 1.0){ sample -= 1.0; nval += *rect; rect += skipx; + if (do_float) { + nvalf += *rectf; + rectf += skipx; + } } val = *rect; rect += skipx; nval += sample * val; - sample -= 1.0; *newrect = (nval/add) + 0.5; newrect += skipx; + if (do_float) { + valf = *rectf; + rectf += skipx; + nvalf += sample * valf; + *newrectf = (nvalf/add) + 0.5; + newrectf += skipx; + } + sample -= 1.0; } } } @@ -406,6 +595,13 @@ static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (unsigned int *) _newrect; + + if (do_float) { + imb_freerectfloatImBuf(ibuf); + ibuf->mall |= IB_rectfloat; + ibuf->rect_float = (float *) _newrectf; + } + ibuf->y = newy; return(ibuf); } @@ -414,23 +610,39 @@ static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy) static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) { uchar *rect,*_newrect,*newrect; + float *rectf,*_newrectf,*newrectf; float sample,add; float val_a,nval_a,diff_a; float val_b,nval_b,diff_b; float val_g,nval_g,diff_g; float val_r,nval_r,diff_r; - int x,y; + float val_af,nval_af,diff_af; + float val_bf,nval_bf,diff_bf; + float val_gf,nval_gf,diff_gf; + float val_rf,nval_rf,diff_rf; + int x,y, do_float = 0; - if (ibuf == 0) return(0); - if (ibuf->rect == 0) return(ibuf); + val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0; + val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0; + if (ibuf==NULL) return(0); + if (ibuf->rect==NULL) return(ibuf); + + _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx"); + if (_newrect==NULL) return(ibuf); + + if (ibuf->rect_float) { + do_float = 1; + _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf"); + if (_newrectf==NULL) return(ibuf); + } - _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int)); - if (_newrect == 0) return(ibuf); add = (ibuf->x - 1.001) / (newx - 1.0); rect = (uchar *) ibuf->rect; + rectf = (float *) ibuf->rect_float; newrect = _newrect; + newrectf = _newrectf = NULL; for (y = ibuf->y; y>0 ; y--){ @@ -456,9 +668,34 @@ static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) val_r += 0.5; rect += 8; + + if (do_float) { + val_af = rectf[0] ; + nval_af = rectf[4]; + diff_af = nval_af - val_af; + val_af += 0.5; + + val_bf = rectf[1] ; + nval_bf = rectf[5]; + diff_bf = nval_bf - val_bf; + val_bf += 0.5; + + val_gf = rectf[2] ; + nval_gf = rectf[6]; + diff_gf = nval_gf - val_gf; + val_gf += 0.5; + + val_rf = rectf[3] ; + nval_rf = rectf[7]; + diff_rf = nval_rf - val_rf; + val_rf += 0.5; + + rectf += 8; + } for (x = newx ; x>0 ; x--){ if (sample >= 1.0){ sample -= 1.0; + val_a = nval_a ; nval_a = rect[0] ; diff_a = nval_a - val_a ; @@ -479,12 +716,42 @@ static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) diff_r = nval_r - val_r ; val_r += 0.5; rect += 4; + + if (do_float) { + val_af = nval_af ; + nval_af = rectf[0] ; + diff_af = nval_af - val_af ; + val_af += 0.5; + + val_bf = nval_bf ; + nval_bf = rectf[1] ; + diff_bf = nval_bf - val_bf ; + val_bf += 0.5; + + val_gf = nval_gf ; + nval_gf = rectf[2] ; + diff_gf = nval_gf - val_gf ; + val_gf += 0.5; + + val_rf = nval_rf ; + nval_rf = rectf[3] ; + diff_rf = nval_rf - val_rf; + val_rf += 0.5; + rectf += 4; + } } newrect[0] = val_a + sample * diff_a; newrect[1] = val_b + sample * diff_b; newrect[2] = val_g + sample * diff_g; newrect[3] = val_r + sample * diff_r; newrect += 4; + if (do_float) { + newrectf[0] = val_af + sample * diff_af; + newrectf[1] = val_bf + sample * diff_bf; + newrectf[2] = val_gf + sample * diff_gf; + newrectf[3] = val_rf + sample * diff_rf; + newrectf += 4; + } sample += add; } } @@ -492,6 +759,13 @@ static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (unsigned int *) _newrect; + + if (do_float) { + imb_freerectfloatImBuf(ibuf); + ibuf->mall |= IB_rectfloat; + ibuf->rect_float = (float *) _newrectf; + } + ibuf->x = newx; return(ibuf); } @@ -500,24 +774,44 @@ static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) { uchar *rect,*_newrect,*newrect; - float sample,add,val,nval,diff; - int x,y,i,skipx; + float *rectf = NULL, *newrectf = NULL, *_newrectf = NULL; + float sample,add,val,nval,diff, valf=0.0f, nvalf=0.0f, difff=0.0f; + int x,y,i,skipx, do_float = 0; - if (ibuf == 0) return(0); - if (ibuf->rect == 0) return(ibuf); + if (ibuf==NULL) return(0); + if (ibuf->rect==NULL) return(ibuf); - _newrect = (uchar *)malloc(newy * ibuf->x * sizeof(int)); - if (_newrect == 0) return(ibuf); + _newrect = MEM_mallocN(newy * ibuf->x * sizeof(int), "scaleupy"); + if (_newrect==NULL) return(ibuf); + if (ibuf->rect_float) { + do_float = 1; + _newrectf = MEM_mallocN(newy * ibuf->y * sizeof(float) * 4, "scaleupyf"); + if (_newrectf==NULL) return(ibuf); + } + add = (ibuf->y - 1.001) / (newy - 1.0); skipx = 4 * ibuf->x; /* all four components, rgba/abgr */ for(i=3 ; i>=0 ; i--){ for (x = skipx - 4; x >= 0 ; x -= 4){ + rect = (uchar *) ibuf->rect; rect += i + x; newrect = _newrect + i + x; + + if (do_float) { + rectf = ibuf->rect_float; + rectf += i * x; + newrectf = _newrectf + i + x; + valf = *rectf; + rectf += skipx; + nvalf = *rectf; + rectf += skipx; + difff = nvalf - valf; + valf += 0.5; + } sample = 0; val = *rect ; @@ -535,9 +829,22 @@ static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) rect += skipx; diff = nval - val; val += 0.5; + + if (do_float) { + valf = nvalf; + nvalf = *rectf; + rectf += skipx; + difff = nvalf - valf; + valf += 0.5; + } } *newrect = val + sample * diff; newrect += skipx; + + if (do_float) { + *newrectf = valf + sample * difff; + newrectf += skipx; + } sample += add; } } @@ -546,20 +853,28 @@ static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) imb_freerectImBuf(ibuf); ibuf->mall |= IB_rect; ibuf->rect = (unsigned int *) _newrect; + + if(do_float) { + imb_freerectfloatImBuf(ibuf); + ibuf->mall |= IB_rectfloat; + ibuf->rect_float = _newrectf; + } + ibuf->y = newy; return(ibuf); } +/* no float buf needed here! */ static void scalefast_Z_ImBuf(ImBuf *ibuf, short newx, short newy) { - unsigned int *rect,*_newrect,*newrect; - int x,y; - int ofsx,ofsy,stepx,stepy; + unsigned int *rect, *_newrect, *newrect; + int x, y; + int ofsx, ofsy, stepx, stepy; if (ibuf->zbuf) { - _newrect = malloc(newx * newy * sizeof(int)); - if (_newrect == 0) return; - + _newrect = MEM_mallocN(newx * newy * sizeof(int), "z rect"); + if (_newrect==NULL) return; + stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; ofsy = 32768; @@ -585,8 +900,8 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, short newx, short newy) struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) { - if (ibuf == 0) return (0); - if (ibuf->rect == 0) return (ibuf); + if (ibuf==NULL) return (0); + if (ibuf->rect==NULL) return (ibuf); // scaleup / scaledown functions below change ibuf->x and ibuf->y // so we first scale the Z-buffer (if any) @@ -600,40 +915,73 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) return(ibuf); } +struct imbufRGBA { + float r, g, b, a; +}; struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy) { unsigned int *rect,*_newrect,*newrect; - int x,y; + struct imbufRGBA *rectf, *_newrectf, *newrectf; + int x,y, do_float=0, do_rect=0; int ofsx,ofsy,stepx,stepy; - if (ibuf == 0) return(0); - if (ibuf->rect == 0) return(ibuf); + rect = NULL; _newrect = NULL; newrect = NULL; + rectf = NULL; _newrectf = NULL; newrectf = NULL; + if (ibuf==NULL) return(0); + if (ibuf->rect) do_rect = 1; + if (ibuf->rect_float) do_float = 1; + if (do_rect==0 && do_float==0) return(ibuf); + if (newx == ibuf->x && newy == ibuf->y) return(ibuf); + + if(do_rect) { + _newrect = MEM_mallocN(newx * newy * sizeof(int), "scalefastimbuf"); + if (_newrect==NULL) return(ibuf); + newrect = _newrect; + } + + if (do_float) { + _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f"); + if (_newrectf==NULL) return(ibuf); + newrectf = _newrectf; + } - _newrect = malloc(newx * newy * sizeof(int)); - if (_newrect == 0) return(ibuf); - - newrect = _newrect; stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5; stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5; ofsy = 32768; for (y = newy; y > 0 ; y--){ - rect = ibuf->rect; - rect += (ofsy >> 16) * ibuf->x; + if(do_rect) { + rect = ibuf->rect; + rect += (ofsy >> 16) * ibuf->x; + } + if (do_float) { + rectf = (struct imbufRGBA *)ibuf->rect_float; + rectf += (ofsy >> 16) * ibuf->x; + } ofsy += stepy; ofsx = 32768; + for (x = newx ; x>0 ; x--){ - *newrect++ = rect[ofsx >> 16]; + if (do_rect) *newrect++ = rect[ofsx >> 16]; + if (do_float) *newrectf++ = rectf[ofsx >> 16]; ofsx += stepx; } } - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = _newrect; + if (do_rect) { + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = _newrect; + } + + if (do_float) { + imb_freerectfloatImBuf(ibuf); + ibuf->mall |= IB_rectfloat; + ibuf->rect_float = (float *)_newrectf; + } scalefast_Z_ImBuf(ibuf, newx, newy); @@ -646,33 +994,34 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy) static struct ImBuf *generic_fieldscale(struct ImBuf *ibuf, short newx, short newy, struct ImBuf *(*scalefunc)(ImBuf *, short, short) ) { struct ImBuf *sbuf1, *sbuf2; -/* extern void rectcpy(); */ - sbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0); - sbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0); + sbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, ibuf->flags, 0); + sbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, ibuf->flags, 0); ibuf->x *= 2; + /* more args needed, 0 assumed... (nzc) */ -/* rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, rectcpy); */ -/* rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, rectcpy); */ - IMB_rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(sbuf1, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_rectcpy(sbuf2, ibuf, 0, 0, sbuf2->x, 0, ibuf->x, ibuf->y); imb_freerectImBuf(ibuf); + imb_freerectfloatImBuf(ibuf); + ibuf->x = newx; ibuf->y = newy; - imb_addrectImBuf(ibuf); + imb_addrectImBuf(ibuf); + if(ibuf->flags & IB_rectfloat) + imb_addrectfloatImBuf(ibuf); + scalefunc(sbuf1, newx, newy / 2); scalefunc(sbuf2, newx, newy / 2); ibuf->x *= 2; /* more args needed, 0 assumed... (nzc) */ -/* rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, rectcpy); */ -/* rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, rectcpy); */ - IMB_rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); - IMB_rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, sbuf1, 0, 0, 0, 0, sbuf1->x, sbuf1->y); + IMB_rectcpy(ibuf, sbuf2, sbuf2->x, 0, 0, 0, sbuf2->x, sbuf2->y); ibuf->x /= 2; @@ -683,9 +1032,7 @@ static struct ImBuf *generic_fieldscale(struct ImBuf *ibuf, short newx, short ne } -struct ImBuf *IMB_scalefastfieldImBuf(struct ImBuf *ibuf, - short newx, - short newy) +struct ImBuf *IMB_scalefastfieldImBuf(struct ImBuf *ibuf, short newx, short newy) { return(generic_fieldscale(ibuf, newx, newy, IMB_scalefastImBuf)); } @@ -694,3 +1041,4 @@ struct ImBuf *IMB_scalefieldImBuf(struct ImBuf *ibuf, short newx, short newy) { return(generic_fieldscale(ibuf, newx, newy, IMB_scaleImBuf)); } + diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c index 5c064098671..331c1031599 100644 --- a/source/blender/imbuf/intern/targa.c +++ b/source/blender/imbuf/intern/targa.c @@ -518,8 +518,8 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int flags) if (checktarga(&tga,mem) == 0) return(0); - if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize,0,0); - else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7,1,0); + if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,tga.pixsize, 0, 0); + else ibuf = IMB_allocImBuf(tga.xsize,tga.ysize,(tga.pixsize + 0x7) & ~0x7, IB_rect, 0); if (ibuf == 0) return(0); ibuf->ftype = TGA; @@ -629,7 +629,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, int flags) if (ibuf) { if (ibuf->rect && (flags & IB_cmap)==0) - IMB_convert_rgba_to_abgr((ibuf->x+ibuf->skipx)*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); } return(ibuf); diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 616531b3a77..6fc5fb99f8b 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -399,7 +399,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags) /* close the client layer interface to the in-memory file */ libtiff_TIFFClose(image); - if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + if (G.order == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); /* return successfully */ return (ibuf); diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 4cdfa852df1..8110a115471 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -50,6 +50,10 @@ #include "IMB_anim.h" +#ifdef WITH_OPENEXR +#include "openexr/openexr_api.h" +#endif + #ifdef WITH_QUICKTIME #include "quicktime_import.h" #endif @@ -97,7 +101,9 @@ static int IMB_ispic_name(char *name) } if (imb_is_a_png(buf)) return(PNG); if (imb_is_a_targa(buf)) return(TGA); - +#ifdef WITH_OPENEXR + if (imb_is_a_openexr((uchar *)buf)) return(OPENEXR); +#endif if (imb_is_a_tiff(buf)) return(TIF); /* radhdr: check if hdr format */ diff --git a/source/blender/imbuf/intern/writeimage.c b/source/blender/imbuf/intern/writeimage.c index 340f8ace415..ae75de8f54f 100644 --- a/source/blender/imbuf/intern/writeimage.c +++ b/source/blender/imbuf/intern/writeimage.c @@ -57,12 +57,17 @@ #include "IMB_bmp.h" #include "IMB_tiff.h" #include "IMB_radiance_hdr.h" +#ifdef WITH_OPENEXR +#include "openexr/openexr_api.h" +#endif #include "IMB_iff.h" #include "IMB_bitplanes.h" #include "IMB_divers.h" -short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags) +/* added facility to copy with saving non-float rects */ + +short IMB_saveiff(struct ImBuf *ibuf, char *name, int flags) { short ok=TRUE,delpl=FALSE; int file = -1; @@ -72,28 +77,45 @@ short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags) /* Put formats that take a filename here */ if (IS_jpg(ibuf)) { - return imb_savejpeg(ibuf, naam, flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_savejpeg(ibuf, name, flags); } if (IS_radhdr(ibuf)) { - return imb_savehdr(ibuf, naam, flags); + return imb_savehdr(ibuf, name, flags); } if (IS_png(ibuf)) { - return imb_savepng(ibuf,naam,flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_savepng(ibuf, name, flags); } if (IS_bmp(ibuf)) { - return imb_savebmp(ibuf,naam,flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_savebmp(ibuf, name, flags); } if (IS_tga(ibuf)) { - return imb_savetarga(ibuf,naam,flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_savetarga(ibuf, name, flags); } if (IS_iris(ibuf)) { - return imb_saveiris(ibuf,naam,flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_saveiris(ibuf, name, flags); } if (G.have_libtiff && IS_tiff(ibuf)) { - return imb_savetiff(ibuf,naam,flags); + if(ibuf->rect==NULL && ibuf->rect_float) + IMB_rect_from_float(ibuf); + return imb_savetiff(ibuf, name, flags); } +#ifdef WITH_OPENEXR + if (IS_openexr(ibuf)) { + return imb_save_openexr(ibuf, name, flags); + } +#endif - file = open(naam, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); + file = open(name, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); if (file < 0) return (FALSE); if (flags & IB_rect){ @@ -103,7 +125,6 @@ short IMB_saveiff(struct ImBuf *ibuf,char *naam,int flags) } /* Put formats that take a filehandle here */ - ok = imb_start_iff(ibuf,file); if (IS_amiga(ibuf)){ IMB_flipy(ibuf); diff --git a/source/blender/include/BDR_drawobject.h b/source/blender/include/BDR_drawobject.h index c9b3a357a97..99aa76b2462 100644 --- a/source/blender/include/BDR_drawobject.h +++ b/source/blender/include/BDR_drawobject.h @@ -63,11 +63,12 @@ void get_local_bounds(struct Object *ob, float *centre, float *size); #define DRAW_PICKING 1 #define DRAW_CONSTCOLOR 2 void draw_object(struct Base *base, int flag); -void drawaxes(float size, int flag); +void drawaxes(float size, int flag, char drawtype); void draw_object_ext(struct Base *base); void drawsolidcube(float size); extern void draw_object_backbufsel(struct Object *ob); +void draw_object_instance(struct Object *ob, int dt, int outline); #ifdef __cplusplus } diff --git a/source/blender/include/BDR_unwrapper.h b/source/blender/include/BDR_unwrapper.h index 176bf8c8e68..f8c73dfdea2 100644 --- a/source/blender/include/BDR_unwrapper.h +++ b/source/blender/include/BDR_unwrapper.h @@ -34,9 +34,16 @@ #define BDR_UNWRAPPER_H void set_seamtface(void); /* set TF_SEAM flags in tfaces */ -void unwrap_lscm(void); /* unwrap selected tfaces */ -void unwrap_lscm_live(void); /* unwrap selected tfaces (for live mode, with no undo pushes) */ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index); +void unwrap_lscm(void); /* unwrap faces selected in 3d view */ +void unwrap_lscm_new(void); +void minimize_stretch_tface_uv(void); /* optimize faces selected in uv editor */ + +/* for live mode: no undo pushes, caching for quicky re-unwrap */ +void unwrap_lscm_live_begin(void); +void unwrap_lscm_live_re_solve(void); +void unwrap_lscm_live_end(void); + #endif /* BDR_UNWRAPPER_H */ diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h index c8220fabe33..7766accdab6 100644 --- a/source/blender/include/BIF_editarmature.h +++ b/source/blender/include/BIF_editarmature.h @@ -64,7 +64,7 @@ typedef struct EditBone float xwidth, length, zwidth; /* put them in order! transform uses this as scale */ float ease1, ease2; float rad_head, rad_tail; - short boneclass, segments; + short layer, segments; float oldlength; /* for envelope scaling */ diff --git a/source/blender/include/BIF_editgroup.h b/source/blender/include/BIF_editgroup.h index 01102649fd6..63399be30d8 100644 --- a/source/blender/include/BIF_editgroup.h +++ b/source/blender/include/BIF_editgroup.h @@ -31,10 +31,9 @@ */ struct Group; -void set_active_group(void); -void add_selected_to_group(void); +struct Base; + +void add_selected_to_group(struct Group *group); void rem_selected_from_group(void); -void prev_group_key(struct Group *group); -void next_group_key(struct Group *group); -void select_group_menu(void); -void select_group(short nr); +void group_operation_with_menu(void); + diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h index f2e759ad6d6..b1620ec58a6 100644 --- a/source/blender/include/BIF_editmesh.h +++ b/source/blender/include/BIF_editmesh.h @@ -134,6 +134,8 @@ extern void editmesh_align_view_to_selected(struct View3D *v3d, int axis); /* Selection */ extern void select_non_manifold(void); +extern void select_sharp_edges(void); +extern void select_linked_flat_faces(void); extern void select_faces_by_numverts(int numverts); extern void select_more(void); extern void select_less(void); @@ -197,5 +199,8 @@ 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 shape_copy_select_from(void); +void shape_propagate(void); + #endif diff --git a/source/blender/include/BIF_editnla.h b/source/blender/include/BIF_editnla.h index 1b62de6a317..4cd9a136c2a 100644 --- a/source/blender/include/BIF_editnla.h +++ b/source/blender/include/BIF_editnla.h @@ -54,6 +54,8 @@ void reset_action_strips(int val); void synchronize_action_strips(void); void snap_action_strips(void); +/* Baking */ +void bake_all_to_action(void); #endif diff --git a/source/blender/include/BIF_editsima.h b/source/blender/include/BIF_editsima.h index 7c9accdeed5..3c0084cf3f1 100644 --- a/source/blender/include/BIF_editsima.h +++ b/source/blender/include/BIF_editsima.h @@ -67,5 +67,7 @@ void weld_align_tface_uv(char tool); void be_square_tface_uv(struct Mesh *me); void select_pinned_tface_uv(void); +void sima_sample_color(void); + #define UV_SELECT_ALL 1 #define UV_SELECT_PINNED 2 diff --git a/source/blender/include/BIF_glutil.h b/source/blender/include/BIF_glutil.h index 43fa758d3cf..0edc73eee2d 100644 --- a/source/blender/include/BIF_glutil.h +++ b/source/blender/include/BIF_glutil.h @@ -125,7 +125,7 @@ void glaRasterPosSafe2f (float x, float y, float known_good_x, float known_good * to use the glScissor functionality if images are to be drawn * with an inset view matrix. */ -void glaDrawPixelsSafe (float x, float y, int img_w, int img_h, void *rect); +void glaDrawPixelsSafe (float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect); /** * Functions like a limited glDrawPixels, but actually draws the @@ -135,11 +135,11 @@ void glaDrawPixelsSafe (float x, float y, int img_w, int img_h, void *rect); * pixel unpacking parameters are _not_ respected. * @attention This routine makes many assumptions: the rect data - * is expected to be in RGBA unsigned byte format, and the + * is expected to be in RGBA byte or float format, and the * modelview and projection matrices are assumed to define a * 1-to-1 mapping to screen space. */ -void glaDrawPixelsTex (float x, float y, int img_w, int img_h, void *rect); +void glaDrawPixelsTex (float x, float y, int img_w, int img_h, int format, void *rect); /* 2D Drawing Assistance */ diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h index aa3b873abd2..41a5bc5e5a1 100644 --- a/source/blender/include/BIF_interface.h +++ b/source/blender/include/BIF_interface.h @@ -77,6 +77,7 @@ struct ScrArea; #define UI_BLOCK_ENTER_OK 32 #define UI_BLOCK_NOSHADOW 64 #define UI_BLOCK_FRONTBUFFER 128 +#define UI_BLOCK_NO_HILITE 256 /* block->flag bits 12-15 are identical to but->flag bits */ @@ -92,6 +93,7 @@ struct ScrArea; #define UI_PNL_STOW 64 #define UI_PNL_TO_MOUSE 128 #define UI_PNL_UNSTOW 256 +#define UI_PNL_SCALE 512 /* warning the first 4 flags are internal */ /* but->flag */ @@ -113,7 +115,13 @@ struct ScrArea; #define UI_BUT_ALIGN_DOWN (1<<15) -/* Button types */ +/* Button types, bits stored in 1 value... and a short even! +- bits 0-4: bitnr (0-31) +- bits 5-7: pointer type +- bit 8: for 'bit' +- bit 9-15: button type (now 6 bits, 64 types) +*/ + #define CHA 32 #define SHO 64 #define INT 96 @@ -152,8 +160,11 @@ struct ScrArea; #define PULLDOWN (27<<9) #define ROUNDBOX (28<<9) #define CHARTAB (29<<9) +#define BUT_COLORBAND (30<<9) +#define BUT_NORMAL (31<<9) +#define BUT_CURVE (32<<9) -#define BUTTYPE (31<<9) +#define BUTTYPE (63<<9) @@ -242,6 +253,7 @@ uiBut *uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *func_arg1, char * uiBut *uiDefPulldownBut(uiBlock *block, uiBlockFuncFP func, void *func_arg1, char *str, short x1, short y1, short x2, short y2, char *tip); uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, int icon, char *str, short x1, short y1, short x2, short y2, char *tip); +uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, int retval, int icon, 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); @@ -277,7 +289,7 @@ void uiButSetFunc (uiBut *but, void (*func)(void *arg1, void *arg2), void *arg void uiButSetCompleteFunc(uiBut *but, void (*func)(char *str, void *arg), void *arg); -void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)()); +void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(struct ScrArea *sa, uiBlock *block)); extern void pupmenu_set_active(int val); @@ -300,6 +312,9 @@ extern int uiAlignPanelStep(struct ScrArea *sa, float fac); extern void uiPanelControl(int); extern void uiSetPanelHandler(int); +extern void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy); +extern void *uiSetCurFont_ext(float aspect); + void shade_buttons_change_3d(void); #endif /* BIF_INTERFACE_H */ diff --git a/source/blender/render/intern/include/outerRenderLoop.h b/source/blender/include/BIF_interface_icons.h similarity index 66% rename from source/blender/render/intern/include/outerRenderLoop.h rename to source/blender/include/BIF_interface_icons.h index 1c0faf666ae..1eb70c5185c 100644 --- a/source/blender/render/intern/include/outerRenderLoop.h +++ b/source/blender/include/BIF_interface_icons.h @@ -1,6 +1,4 @@ -/* - * outerRenderLoop.h - * +/** * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -28,17 +26,32 @@ * The Original Code is: all of this file. * * Contributor(s): none yet. - * + * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifndef OUTERRENDERLOOP_H -#define OUTERRENDERLOOP_H +#ifndef BIF_PREVIEW_ICONS_H +#define BIF_PREVIEW_ICONS_H -/** - * Outer loop for rendering a single picture. - */ -void unifiedRenderingLoop(void); +struct Image; +struct ImBuf; +struct World; +struct Tex; +struct Lamp; +struct Material; -#endif +#define ICON_DEFAULT_HEIGHT 16 +/* + Resizable Icons for Blender +*/ +void BIF_icons_init(int first_dyn_id); +int BIF_icon_get_width(int icon_id); +int BIF_icon_get_height(int icon_id); +void BIF_icon_set_aspect(int icon_id, float aspect); +void BIF_icon_draw(float x, float y, int icon_id); +void BIF_icon_draw_blended(float x, float y, int icon_id, int colorid, int shade); +void BIF_icons_free(); +void BIF_icons_free_drawinfo(void *drawinfo); + +#endif /* BIF_ICONS_H */ diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h index a0ee42081bd..e926d41faf1 100644 --- a/source/blender/include/BIF_meshtools.h +++ b/source/blender/include/BIF_meshtools.h @@ -34,6 +34,7 @@ #define BIF_MESHTOOLS_H struct Object; +struct EditVert; extern int join_mesh(void); @@ -42,8 +43,9 @@ extern void slowerdraw(void); extern void sort_faces(void); -extern int mesh_octree_table(struct Object *ob, float *co, char mode); +extern long mesh_octree_table(struct Object *ob, float *co, char mode); extern int mesh_get_x_mirror_vert(struct Object *ob, int index); +extern struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, float *co); #endif diff --git a/source/blender/include/BIF_outliner.h b/source/blender/include/BIF_outliner.h index 1a33b3d0810..442247864b5 100644 --- a/source/blender/include/BIF_outliner.h +++ b/source/blender/include/BIF_outliner.h @@ -62,7 +62,7 @@ typedef struct TreeElement { #define TSE_CONSTRAINT 8 #define TSE_MODIFIER_BASE 9 #define TSE_MODIFIER 10 -#define TSE_MODIFIER_OB 11 +#define TSE_LINKED_OB 11 #define TSE_SCRIPT_BASE 12 #define TSE_POSE_BASE 13 #define TSE_POSE_CHANNEL 14 diff --git a/source/blender/include/BIF_poseobject.h b/source/blender/include/BIF_poseobject.h index 7ff4c0a516b..835b808c9ba 100644 --- a/source/blender/include/BIF_poseobject.h +++ b/source/blender/include/BIF_poseobject.h @@ -65,6 +65,7 @@ void pose_clear_paths(struct Object *ob); void pose_flip_names(void); void pose_activate_flipped_bone(void); +void pose_movetolayer(void); #endif diff --git a/source/blender/include/BIF_previewrender.h b/source/blender/include/BIF_previewrender.h index e35aee60587..dec85f5f6e7 100644 --- a/source/blender/include/BIF_previewrender.h +++ b/source/blender/include/BIF_previewrender.h @@ -30,10 +30,59 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ +#include "DNA_vec_types.h" + struct SpaceButs; +struct RenderInfo; +struct Image; +struct ScrArea; +struct uiBlock; +struct Render; -void BIF_all_preview_changed(void); -void BIF_preview_changed (struct SpaceButs *area); -void BIF_previewrender (struct SpaceButs *area); -void BIF_previewdraw (void); +#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; + int pr_recty; + short cury, status; + rcti disprect; /* storage for view3d preview rect */ + unsigned int* rect; + struct Render *re; /* persistant render */ +} RenderInfo; + +/* ri->status */ +#define PR_DBASE 1 +#define PR_DISPRECT 2 +#define PR_PROJECTED 4 +#define PR_ROTATED 8 + +/* 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. +*/ + +#define PR_DRAW_RENDER 0 +#define PR_ICON_RENDER 1 +#define PR_DO_RENDER 2 + +void BIF_previewrender (struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method); +void BIF_previewrender_buts (struct SpaceButs *sbuts); +void BIF_previewdraw (struct ScrArea *sa, struct uiBlock *block); +void BIF_preview_changed (short id_code); + +void BIF_preview_init_dbase (void); +void BIF_preview_free_dbase (void); + +void BIF_view3d_previewrender(struct ScrArea *sa); +void BIF_view3d_previewdraw (struct ScrArea *sa, struct uiBlock *block); +void BIF_view3d_previewrender_free(struct ScrArea *sa); +void BIF_view3d_previewrender_clear(struct ScrArea *sa); +void BIF_view3d_previewrender_signal(struct ScrArea *sa, short signal); diff --git a/source/blender/include/BIF_renderwin.h b/source/blender/include/BIF_renderwin.h index 6b607b110d6..eeb48ad8c27 100644 --- a/source/blender/include/BIF_renderwin.h +++ b/source/blender/include/BIF_renderwin.h @@ -32,7 +32,7 @@ struct ScrArea; -void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[2]); +void calc_renderwin_rectangle(int rectx, int recty, int posmask, int renderpos_r[2], int rendersize_r[2]); void BIF_close_render_display(void); diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h index 853e09f258f..ecf6f67331a 100644 --- a/source/blender/include/BIF_resources.h +++ b/source/blender/include/BIF_resources.h @@ -33,6 +33,8 @@ #ifndef BIF_RESOURCES_H #define BIF_RESOURCES_H +/* elubie: TODO: move the typedef for icons to BIF_interface_icons.h */ +/* and add/replace include of BIF_resources.h by BIF_interface_icons.h */ typedef enum { #define BIFICONID_FIRST (ICON_VIEW3D) ICON_VIEW3D, @@ -117,8 +119,8 @@ typedef enum { ICON_ENVMAP, ICON_TRANSP_HLT, ICON_TRANSP_DEHLT, - ICON_RADIO_DEHLT, - ICON_RADIO_HLT, + ICON_CIRCLE_DEHLT, + ICON_CIRCLE_HLT, ICON_TPAINT_DEHLT, ICON_TPAINT_HLT, ICON_WPAINT_DEHLT, @@ -180,8 +182,8 @@ typedef enum { ICON_CHECKBOX_HLT, ICON_LINK, ICON_INLINK, - ICON_BEVELBUT_HLT, - ICON_BEVELBUT_DEHLT, + ICON_ZOOMIN, + ICON_ZOOMOUT, ICON_PASTEDOWN, ICON_COPYDOWN, ICON_CONSTANT, @@ -270,7 +272,7 @@ typedef enum { ICON_SYNTAX_OFF, ICON_BLANK52, ICON_BLANK53, - ICON_BLANK54, + ICON_PLUS, ICON_VIEWMOVE, ICON_HOME, ICON_CLIPUV_DEHLT, @@ -454,7 +456,13 @@ enum { TH_STRIP, TH_STRIP_SELECT, - TH_LAMP + TH_LAMP, + + TH_NODE, + TH_NODE_IN_OUT, + TH_NODE_OPERATOR, + TH_NODE_GENERATOR, + TH_NODE_GROUP, }; /* XXX WARNING: previous is saved in file, so do not change order! */ @@ -508,13 +516,6 @@ void BIF_resources_free (void); void BIF_colors_init (void); void BIF_load_ui_colors (void); - -// icon API -int BIF_get_icon_width (BIFIconID icon); -int BIF_get_icon_height (BIFIconID icon); -void BIF_draw_icon (float x, float y, BIFIconID icon); -void BIF_draw_icon_blended (float x, float y, BIFIconID icon, int colorid, int shade); - /* only for buttons in theme editor! */ char *BIF_ThemeGetColorPtr(struct bTheme *btheme, int spacetype, int colorid); char *BIF_ThemeColorsPup(int spacetype); diff --git a/source/blender/include/BIF_screen.h b/source/blender/include/BIF_screen.h index b47f005c2b3..c76f961014a 100644 --- a/source/blender/include/BIF_screen.h +++ b/source/blender/include/BIF_screen.h @@ -73,7 +73,7 @@ void set_g_activearea(struct ScrArea *sa); void getmouseco_sc(short *mval); void getmouseco_areawin(short *mval); void getmouseco_headwin(short *mval); -unsigned short qtest(void); +int qtest(void); int anyqtest(void); void areawinset(short win); void headerbox(struct ScrArea *sa); diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index 189adc0a20a..3585e46c0aa 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -53,6 +53,7 @@ struct SpaceOops; #define VIEW3D_HANDLER_BACKGROUND 1 #define VIEW3D_HANDLER_PROPERTIES 2 #define VIEW3D_HANDLER_OBJECT 3 +#define VIEW3D_HANDLER_PREVIEW 4 /* ipo handler codes */ #define IPO_HANDLER_PROPERTIES 20 @@ -60,6 +61,7 @@ struct SpaceOops; /* image handler codes */ #define IMAGE_HANDLER_PROPERTIES 30 #define IMAGE_HANDLER_PAINT 31 +#define IMAGE_HANDLER_CURVES 32 /* action handler codes */ #define ACTION_HANDLER_PROPERTIES 40 @@ -105,7 +107,7 @@ extern void extern_set_butspace(int fkey); extern void force_draw(int header); extern void force_draw_all(int header); extern void force_draw_plus(int type, int header); -extern void freespacelist(struct ListBase *lb); +extern void freespacelist(struct ScrArea *sa); extern void handle_view3d_around(void); extern void handle_view3d_lock(void); extern void init_v2d_oops(struct ScrArea *, struct SpaceOops *); @@ -114,9 +116,8 @@ extern void newspace(struct ScrArea *sa, int type); extern void set_rects_butspace(struct SpaceButs *buts); extern void test_butspace(void); extern void start_game(void); -extern void select_group_menu(void); +extern void select_grouped(short nr); extern void join_menu(void); -extern void select_group(short nr); extern void BIF_undo_push(char *str); extern void BIF_undo(void); diff --git a/source/blender/include/BIF_spacetypes.h b/source/blender/include/BIF_spacetypes.h index 0b07be60129..e825acf676f 100644 --- a/source/blender/include/BIF_spacetypes.h +++ b/source/blender/include/BIF_spacetypes.h @@ -62,4 +62,5 @@ SpaceType *spacetext_get_type (void); SpaceType *spacescript_get_type (void); SpaceType *spaceview3d_get_type (void); SpaceType *spacetime_get_type (void); +SpaceType *spacenode_get_type (void); diff --git a/source/blender/include/BIF_toets.h b/source/blender/include/BIF_toets.h index ef16186f15f..f5a435d3d50 100644 --- a/source/blender/include/BIF_toets.h +++ b/source/blender/include/BIF_toets.h @@ -33,9 +33,6 @@ #ifndef BIF_TOETS_H #define BIF_TOETS_H -void BIF_save_rendered_image(void); - -int save_image_filesel_str(char *str); int blenderqread(unsigned short event, short val); void persptoetsen(unsigned short event); /* dutch rules man */ int untitled(char *name); diff --git a/source/blender/include/BIF_toolbox.h b/source/blender/include/BIF_toolbox.h index a2c88ba52ac..9e9365f3bc3 100644 --- a/source/blender/include/BIF_toolbox.h +++ b/source/blender/include/BIF_toolbox.h @@ -120,7 +120,10 @@ int okee (char *fmt, ...); short button (short *var, short min, short max, char *str); short fbutton (float *var, float min, float max, float a1, float a2, char *str); short sbutton (char *var, float min, float max, char *str); /* __NLA */ + int movetolayer_buts (unsigned int *lay); +int movetolayer_short_buts (short *lay); + void draw_numbuts_tip (char *str, int x1, int y1, int x2, int y2); int do_clever_numbuts (char *name, int tot, int winevent); void clever_numbuts_buts(void); diff --git a/source/blender/include/BIF_writeimage.h b/source/blender/include/BIF_writeimage.h index 318a4294371..70978a033c2 100644 --- a/source/blender/include/BIF_writeimage.h +++ b/source/blender/include/BIF_writeimage.h @@ -36,8 +36,10 @@ struct ImBuf; struct EnvMap; -int BIF_write_ibuf(struct ImBuf *ibuf, char *name); +void BIF_save_rendered_image(char *name); +void BIF_save_rendered_image_fs(void); void BIF_save_envmap(struct EnvMap *env, char *str); +void save_image_filesel_str(char *str); #endif diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h index b0e40699f42..1d04062fb8d 100644 --- a/source/blender/include/BSE_drawview.h +++ b/source/blender/include/BSE_drawview.h @@ -46,16 +46,18 @@ void circ(float x, float y, float rad); void do_viewbuts(unsigned short event); +/* View3DAfter->type */ +#define V3D_XRAY 1 +#define V3D_TRANSP 2 void add_view3d_after(struct View3D *v3d, struct Base *base, int type); void backdrawview3d(int test); void drawview3dspace(struct ScrArea *sa, void *spacedata); -void drawview3d_render(struct View3D *v3d); +void drawview3d_render(struct View3D *v3d, int winx, int winy); int update_time(void); void calc_viewborder(struct View3D *v3d, struct rcti *viewborder_r); void view3d_set_1_to_1_viewborder(struct View3D *v3d); -void timestr(double time, char *str); int view3d_test_clipping(struct View3D *v3d, float *vec); void view3d_set_clipping(struct View3D *v3d); diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h index 38c54d95956..06611ec6dda 100644 --- a/source/blender/include/BSE_editipo.h +++ b/source/blender/include/BSE_editipo.h @@ -143,6 +143,8 @@ void duplicate_ipo_keys(struct Ipo *ipo); void borderselect_ipo_key(struct Ipo *ipo, float xmin, float xmax, int val); void borderselect_icu_key(struct IpoCurve *icu, float xmin, float xmax, int (*select_function)(struct BezTriple *)); +void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4]); +void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue); void select_ipo_key(struct Ipo *ipo, float selx, int sel); void select_icu_key(struct IpoCurve *icu, float selx, int selectmode); diff --git a/source/blender/include/BSE_filesel.h b/source/blender/include/BSE_filesel.h index f76f5e11258..29f9c52f79f 100644 --- a/source/blender/include/BSE_filesel.h +++ b/source/blender/include/BSE_filesel.h @@ -42,7 +42,6 @@ struct BWinEvent; void clear_global_filesel_vars(void); void filesel_statistics(struct SpaceFile *sfile, int *totfile, int *selfile, float *totlen, float *sellen); -void checkdir(char *dir); void test_flags_file(struct SpaceFile *sfile); void sort_filelist(struct SpaceFile *sfile); void read_dir(struct SpaceFile *sfile); diff --git a/source/blender/include/BSE_headerbuttons.h b/source/blender/include/BSE_headerbuttons.h index 4f2179cca28..e9aea3fbada 100644 --- a/source/blender/include/BSE_headerbuttons.h +++ b/source/blender/include/BSE_headerbuttons.h @@ -40,13 +40,13 @@ struct SpaceIpo; struct Ipo; /* these used to be in blender/src/headerbuttons.c: */ -#define SPACEICONMAX 15 /* See release/datafiles/blenderbuttons */ +#define SPACEICONMAX 16 /* See release/datafiles/blenderbuttons */ #define XIC 20 #define YIC 20 int std_libbuttons(struct uiBlock *block, short xco, short yco, int pin, short *pinpoin, - int browse, struct ID *id, struct ID *parid, + int browse, short id_code, short special, struct ID *id, struct ID *parid, short *menupoin, int users, int lib, int del, int autobut, int keepbut); @@ -89,8 +89,9 @@ void seq_buttons(void); void sound_buttons(void); void text_buttons(void); void script_buttons(void); -void time_buttons(struct ScrArea *sa); void view3d_buttons(void); +void time_buttons(struct ScrArea *sa); +void node_buttons(struct ScrArea *sa); void do_global_buttons(unsigned short event); void do_global_buttons2(short event); @@ -108,9 +109,10 @@ void do_oops_buttons(short event); void do_seq_buttons(short event); void do_sound_buttons(unsigned short event); void do_text_buttons(unsigned short event); -void do_time_buttons(struct ScrArea *sa, unsigned short event); void do_script_buttons(unsigned short event); void do_view3d_buttons(short event); +void do_time_buttons(struct ScrArea *sa, unsigned short event); +void do_node_buttons(struct ScrArea *sa, unsigned short event); void do_headerbuttons(short event); diff --git a/source/blender/include/BSE_node.h b/source/blender/include/BSE_node.h new file mode 100644 index 00000000000..7ad973d4915 --- /dev/null +++ b/source/blender/include/BSE_node.h @@ -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 opt ion) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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): none yet. + * + * ***** END GPL BLOCK ***** + */ + +#ifndef BSE_NODE_H +#define BSE_NODE_H + +/* ********** drawing sizes *********** */ +#define NODE_DY 20 +#define NODE_DYS 10 +#define NODE_SOCKSIZE 5 +#define BASIS_RAD 8.0f +#define HIDDEN_RAD 15.0f + + +struct SpaceNode; +struct bNode; +struct bNodeTree; +struct Material; +struct ID; +struct Scene; + +/* ************* API for editnode.c *********** */ + + /* helper calls to retreive active context for buttons, does groups */ +struct Material *editnode_get_active_material(struct Material *ma); +struct bNode *editnode_get_active_idnode(struct bNodeTree *ntree, short id_code); +struct bNode *editnode_get_active(struct bNodeTree *ntree); + +void snode_tag_dirty(struct SpaceNode *snode); + +void snode_set_context(struct SpaceNode *snode); + +void node_deselectall(struct SpaceNode *snode, int swap); +void node_transform_ext(int mode, int unused); +void node_shader_default(struct Material *ma); +void node_composit_default(struct Scene *scene); + +int node_has_hidden_sockets(struct bNode *node); + +struct bNode *node_add_node(struct SpaceNode *snode, int type, float locx, float locy); + +/* ************* drawnode.c *************** */ +void node_draw_link(struct SpaceNode *snode, struct bNodeLink *link); + +void init_node_butfuncs(void); + +/* ************* Shader nodes ***************** */ + + +#endif + diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 994559e6194..df38389892a 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -125,11 +125,14 @@ struct StripElem *give_stripelem(struct Sequence *seq, int cfra); void set_meta_stripdata(struct Sequence *seqm); void do_seq_count_cfra(struct ListBase *seqbase, int *totseq, int cfra); void do_build_seqar_cfra(struct ListBase *seqbase, struct Sequence ***seqar, int cfra); -struct ImBuf *give_ibuf_seq(int cfra); +struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra); void free_imbuf_effect_spec(int cfra); void free_imbuf_seq_except(int cfra); void free_imbuf_seq(void); -void do_render_seq(void); + +/* still bad level call... */ +struct RenderResult; +void do_render_seq(struct RenderResult *rr); #endif diff --git a/source/blender/include/BSE_view.h b/source/blender/include/BSE_view.h index e241f92143b..2afbca2b30e 100644 --- a/source/blender/include/BSE_view.h +++ b/source/blender/include/BSE_view.h @@ -68,7 +68,10 @@ void sdrawbox(short x1, short y1, short x2, short y2); void calctrackballvecfirst(struct rcti *area, short *mval, float *vec); void calctrackballvec(struct rcti *area, short *mval, float *vec); void viewmove(int mode); -void setwinmatrixview3d(struct rctf *rect); + +int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend); +void setwinmatrixview3d(int winx, int winy, struct rctf *rect); + void obmat_to_viewmat(struct Object *ob); void setviewmatrixview3d(void); float *give_cursor(void); diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index cc6e8d054f5..52638e6f988 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -310,6 +310,11 @@ #define B_SIMACLONEDELETE 366 #define B_SIMABRUSHCHANGE 367 #define B_SIMANOTHING 368 +#define B_SIMACURVES 369 +#define B_SIMARANGE 370 +#define B_SIMA_USE_ALPHA 371 +#define B_SIMA_SHOW_ALPHA 372 +#define B_SIMA_SHOW_ZBUF 373 /* BUTS: 400 */ #define B_BUTSHOME 401 @@ -370,10 +375,15 @@ #define B_TL_NEXTKEY 755 #define B_TL_STOP 756 -/* NLA: 801-900 */ +/* NLA: 801-850 */ #define B_NLAHOME 801 -/* FREE 900 - 999 */ +/* NODE: 851-900 */ +#define B_NODEHOME 851 +#define B_NODE_USEMAT 852 +#define B_NODE_USESCENE 853 + +/* FREE 901 - 999 */ #define B_NOTHING -1 @@ -389,7 +399,7 @@ #define B_AUTOFGON 32 #define B_KNIFE 0x80 #define B_PERCENTSUBD 0x40 - +#define B_MESH_X_MIRROR 0x100 /* DISPLAYMODE */ #define R_DISPLAYVIEW 0 diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 33a074ba46d..930327f3489 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -37,7 +37,10 @@ struct Base; struct Object; struct ID; - +struct ColorBand; +struct uiBlock; +struct rctf; +struct CurveMap; /* buts->scaflag */ #define BUTS_SENS_SEL 1 @@ -87,6 +90,7 @@ extern void do_armbuts(unsigned short event); extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons /* shading */ +extern void draw_colorband_buts_small(struct uiBlock *block, struct ColorBand *coba, rctf *rct, int event); extern void material_panels(void); extern void do_matbuts(unsigned short event); extern void lamp_panels(void); @@ -121,8 +125,14 @@ void test_scenepoin_but(char *name, struct ID **idpp); void test_matpoin_but(char *name, struct ID **idpp); void test_scriptpoin_but(char *name, struct ID **idpp); void test_actionpoin_but(char *name, ID **idpp); +void test_grouppoin_but(char *name, ID **idpp); +void test_texpoin_but(char *name, ID **idpp); +void test_imapoin_but(char *name, ID **idpp); + void test_idbutton_cb(void *namev, void *arg2_unused); +void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char labeltype, short event, short redraw, struct rctf *rect); + /* -------------- internal event defines ------------ */ @@ -132,29 +142,31 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_VIEWBUTS 1100 #define B_LOADBGPIC 1001 -#define B_BLENDBGPIC 1002 -#define B_BGPICBROWSE 1003 +#define B_BLENDBGPIC 1002 +#define B_BGPICBROWSE 1003 #define B_BGPICTEX 1004 -#define B_BGPICCLEAR 1005 -#define B_BGPICTEXCLEAR 1006 +#define B_BGPICCLEAR 1005 +#define B_BGPICTEXCLEAR 1006 #define B_OBJECTPANELROT 1007 -#define B_OBJECTPANELMEDIAN 1008 +#define B_OBJECTPANELMEDIAN 1008 #define B_ARMATUREPANEL1 1009 #define B_ARMATUREPANEL2 1010 -#define B_OBJECTPANELPARENT 1011 +#define B_OBJECTPANELPARENT 1011 #define B_OBJECTPANEL 1012 #define B_ARMATUREPANEL3 1013 /* *********************** */ #define B_LAMPBUTS 1200 -#define B_LAMPREDRAW 1101 +#define B_LAMPREDRAW 1101 #define B_COLLAMP 1102 -#define B_TEXCLEARLAMP 1103 +#define B_TEXCLEARLAMP 1103 #define B_SBUFF 1104 #define B_SHADBUF 1105 #define B_SHADRAY 1106 +#define B_LMTEXPASTE 1107 +#define B_LMTEXCOPY 1108 /* *********************** */ #define B_MATBUTS 1300 @@ -165,18 +177,23 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_ACTCOL 1204 #define B_MATFROM 1205 #define B_MATPRV 1206 -#define B_MTEXCOL 1207 -#define B_TEXCLEAR 1208 -#define B_MATPRV_DRAW 1209 -#define B_MTEXPASTE 1210 -#define B_MTEXCOPY 1211 -#define B_MATLAY 1212 -#define B_MATHALO 1213 -#define B_MATZTRANSP 1214 -#define B_MATRAYTRANSP 1215 -#define B_MATCOLORBAND 1216 -/* yafray: material preset menu event */ -#define B_MAT_YF_PRESET 1217 +#define B_LAMPPRV 1207 +#define B_WORLDPRV 1208 +#define B_TEXPRV 1209 +#define B_MTEXCOL 1210 +#define B_TEXCLEAR 1211 +#define B_MTEXPASTE 1212 +#define B_MTEXCOPY 1213 +#define B_MATLAY 1214 +#define B_MATHALO 1215 +#define B_MATZTRANSP 1216 +#define B_MATRAYTRANSP 1217 +#define B_MATCOLORBAND 1218 + /* yafray: material preset menu event */ +#define B_MAT_YF_PRESET 1219 + +#define B_MAT_LAYERBROWSE 1220 +#define B_MAT_USENODES 1221 /* *********************** */ #define B_TEXBUTS 1400 @@ -201,7 +218,6 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_REDRAWCBAND 1318 #define B_BANDCOL 1319 #define B_LOADTEXIMA1 1320 -#define B_TEXPRV 1321 #define B_PLUGBUT 1325 /* B_PLUGBUT reserves 24 buttons at least! */ @@ -218,7 +234,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_ENV_FREE_ALL 1357 #define B_UNLINKIMA 1358 -/* *********************** */ +/* **************** animbuts = object buttons ******* */ #define B_ANIMBUTS 1500 #define B_RECALCPATH 1401 @@ -234,14 +250,15 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SOFTBODY_BAKE 1422 #define B_SOFTBODY_BAKE_FREE 1423 - /* this has MAX_EFFECT settings! Next free define is 1450... */ -#define B_SELEFFECT 1430 +/* this has MAX_EFFECT settings! Next free define is 1450... */ +#define B_SELEFFECT 1430 /* Fluidsim button defines */ #define B_FLUIDSIM_BAKE 1450 -#define B_FLUIDSIM_SELDIR 1451 +#define B_FLUIDSIM_SELDIR 1451 #define B_FLUIDSIM_FORCEREDRAW 1452 +#define B_GROUP_RELINK 1460 /* *********************** */ #define B_WORLDBUTS 1600 @@ -249,6 +266,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_TEXCLEARWORLD 1501 #define B_COLHOR 1502 #define B_COLZEN 1503 +#define B_WMTEXPASTE 1504 +#define B_WMTEXCOPY 1505 /* *********************** */ @@ -268,7 +287,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_PR_PAL169 1612 #define B_PR_D2MAC 1613 #define B_PR_MPEG 1614 -#define B_REDRAWDISP 1615 +#define B_REDRAWDISP 1615 #define B_SETBROWSE 1616 #define B_CLEARSET 1617 #define B_PR_PRESET 1618 @@ -276,32 +295,33 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_PR_NTSC 1620 #define B_IS_FTYPE 1622 -#define B_IS_BACKBUF 1623 +#define B_IS_BACKBUF 1623 #define B_PR_PC 1624 -#define B_PR_PANO360 1627 -#define B_PR_HALFFIELDS 1628 -#define B_NEWRENDERPIPE 1629 -#define B_R_SCALE 1630 -#define B_G_SCALE 1631 -#define B_B_SCALE 1632 -#define B_USE_R_SCALE 1633 -#define B_USE_G_SCALE 1634 -#define B_USE_B_SCALE 1635 -#define B_EDGECOLSLI 1636 -#define B_GAMMASLI 1637 +#define B_PR_PANO360 1627 +#define B_PR_HALFFIELDS 1628 +#define B_NEWRENDERPIPE 1629 +#define B_R_SCALE 1630 +#define B_G_SCALE 1631 +#define B_B_SCALE 1632 +#define B_USE_R_SCALE 1633 +#define B_USE_G_SCALE 1634 +#define B_USE_B_SCALE 1635 +#define B_EDGECOLSLI 1636 +#define B_GAMMASLI 1637 -#define B_FILETYPEMENU 1638 -#define B_SELECTCODEC 1639 +#define B_FILETYPEMENU 1638 +#define B_SELECTCODEC 1639 #define B_RTCHANGED 1640 -#define B_SWITCHRENDER 1641 +#define B_SWITCHRENDER 1641 #define B_FBUF_REDO 1642 -#define B_SET_EDGE 1643 -#define B_SET_ZBLUR 1644 +#define B_SET_EDGE 1643 +#define B_SET_ZBLUR 1644 +#define B_ADD_RENDERLAYER 1645 /* *********************** */ -#define B_ARMATUREBUTS 1800 +#define B_ARMATUREBUTS 1800 #define B_POSE 1701 /* *********************** */ @@ -321,7 +341,7 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SETSOLID 2013 #define B_AUTOTEX 2014 #define B_DOCENTRE 2015 -#define B_DOCENTRENEW 2016 +#define B_DOCENTRENEW 2016 #define B_DOCENTRECURSOR 2017 /* 20 values! */ @@ -346,43 +366,43 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SPLIT 2056 #define B_REMDOUB 2057 #define B_SUBDIV 2058 -#define B_FRACSUBDIV 2059 +#define B_FRACSUBDIV 2059 #define B_XSORT 2060 #define B_HASH 2061 #define B_DELSTICKY 2062 -#define B_DELVERTCOL 2063 -#define B_MAKE_TFACES 2064 +#define B_DELVERTCOL 2063 +#define B_MAKE_TFACES 2064 #define B_TOSPHERE 2065 -#define B_DEL_TFACES 2066 +#define B_DEL_TFACES 2066 #define B_NEWVGROUP 2067 #define B_DELVGROUP 2068 -#define B_ASSIGNVGROUP 2069 -#define B_REMOVEVGROUP 2070 +#define B_ASSIGNVGROUP 2069 +#define B_REMOVEVGROUP 2070 #define B_SELVGROUP 2071 -#define B_DESELVGROUP 2072 -#define B_DECIM_FACES 2073 -#define B_DECIM_CANCEL 2074 -#define B_DECIM_APPLY 2075 -#define B_AUTOVGROUP 2076 -#define B_SLOWERDRAW 2077 -#define B_FASTERDRAW 2078 -#define B_VERTEXNOISE 2079 -#define B_VERTEXSMOOTH 2080 -#define B_MAKESTICKY 2082 -#define B_MAKEVERTCOL 2083 -#define B_CHROMADEPTH 2084 +#define B_DESELVGROUP 2072 +#define B_DECIM_FACES 2073 +#define B_DECIM_CANCEL 2074 +#define B_DECIM_APPLY 2075 +#define B_AUTOVGROUP 2076 +#define B_SLOWERDRAW 2077 +#define B_FASTERDRAW 2078 +#define B_VERTEXNOISE 2079 +#define B_VERTEXSMOOTH 2080 +#define B_MAKESTICKY 2082 +#define B_MAKEVERTCOL 2083 +#define B_CHROMADEPTH 2084 #define B_DRAWEDGES 2087 -#define B_DRAWCREASES 2088 -#define B_LINKEDVGROUP 2089 +#define B_DRAWCREASES 2088 +#define B_LINKEDVGROUP 2089 /* *********************** */ #define B_CURVEBUTS 2200 -#define B_CONVERTPOLY 2101 -#define B_CONVERTBEZ 2102 -#define B_CONVERTBSPL 2103 -#define B_CONVERTCARD 2104 -#define B_CONVERTNURB 2105 +#define B_CONVERTPOLY 2101 +#define B_CONVERTBEZ 2102 +#define B_CONVERTBSPL 2103 +#define B_CONVERTCARD 2104 +#define B_CONVERTNURB 2105 #define B_UNIFU 2106 #define B_ENDPU 2107 #define B_BEZU 2108 @@ -395,12 +415,12 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SETW3 2115 #define B_SETORDER 2116 #define B_MAKEDISP 2117 -#define B_SUBDIVCURVE 2118 +#define B_SUBDIVCURVE 2118 #define B_SPINNURB 2119 #define B_CU3D 2120 #define B_SETRESOLU 2121 #define B_SETW4 2122 -#define B_SUBSURFTYPE 2123 +#define B_SUBSURFTYPE 2123 /* *********************** */ #define B_FONTBUTS 2300 @@ -409,16 +429,16 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_TOUPPER 2202 #define B_SETFONT 2203 #define B_LOADFONT 2204 -#define B_TEXTONCURVE 2205 +#define B_TEXTONCURVE 2205 #define B_PACKFONT 2206 -#define B_LOAD3DTEXT 2207 +#define B_LOAD3DTEXT 2207 #define B_LOREM 2208 #define B_FASTFONT 2209 #define B_INSTB 2210 #define B_DELTB 2211 -#define B_STYLETOSELB 2212 -#define B_STYLETOSELU 2213 -#define B_STYLETOSELI 2214 +#define B_STYLETOSELB 2212 +#define B_STYLETOSELU 2213 +#define B_STYLETOSELI 2214 #define B_SETCHAR 2215 #define B_SETUPCHAR 2216 @@ -438,106 +458,106 @@ void test_idbutton_cb(void *namev, void *arg2_unused); /* *********************** */ #define B_MBALLBUTS 2600 -#define B_RECALCMBALL 2501 +#define B_RECALCMBALL 2501 /* *********************** */ #define B_LATTBUTS 2700 #define B_RESIZELAT 2601 #define B_DRAWLAT 2602 -#define B_LATTCHANGED 2603 -#define B_REGULARLAT 2604 +#define B_LATTCHANGED 2603 +#define B_REGULARLAT 2604 /* *********************** */ #define B_GAMEBUTS 2800 #define B_ADD_PROP 2701 -#define B_CHANGE_PROP 2702 +#define B_CHANGE_PROP 2702 #define B_ADD_SENS 2703 -#define B_CHANGE_SENS 2704 +#define B_CHANGE_SENS 2704 #define B_DEL_SENS 2705 #define B_ADD_CONT 2706 -#define B_CHANGE_CONT 2707 +#define B_CHANGE_CONT 2707 #define B_DEL_CONT 2708 #define B_ADD_ACT 2709 -#define B_CHANGE_ACT 2710 +#define B_CHANGE_ACT 2710 #define B_DEL_ACT 2711 #define B_SOUNDACT_BROWSE 2712 -#define B_SETSECTOR 2713 -#define B_SETPROP 2714 -#define B_SETACTOR 2715 +#define B_SETSECTOR 2713 +#define B_SETPROP 2714 +#define B_SETACTOR 2715 #define B_SETMAINACTOR 2716 -#define B_SETDYNA 2717 +#define B_SETDYNA 2717 /* *********************** */ -#define B_FPAINTBUTS 2900 +#define B_FPAINTBUTS 2900 #define B_VPCOLSLI 2801 #define B_VPGAMMA 2802 -#define B_COPY_TF_MODE 2804 -#define B_COPY_TF_UV 2805 -#define B_COPY_TF_COL 2806 -#define B_REDR_3D_IMA 2807 +#define B_COPY_TF_MODE 2804 +#define B_COPY_TF_UV 2805 +#define B_COPY_TF_COL 2806 +#define B_REDR_3D_IMA 2807 #define B_SET_VCOL 2808 -#define B_COPY_TF_TEX 2814 -#define B_TFACE_HALO 2815 -#define B_TFACE_BILLB 2816 +#define B_COPY_TF_TEX 2814 +#define B_TFACE_HALO 2815 +#define B_TFACE_BILLB 2816 #define B_SHOWTEX 2832 -#define B_ASSIGNMESH 2833 +#define B_ASSIGNMESH 2833 -#define B_WEIGHT0_0 2840 -#define B_WEIGHT1_4 2841 -#define B_WEIGHT1_2 2842 -#define B_WEIGHT3_4 2843 -#define B_WEIGHT1_0 2844 +#define B_WEIGHT0_0 2840 +#define B_WEIGHT1_4 2841 +#define B_WEIGHT1_2 2842 +#define B_WEIGHT3_4 2843 +#define B_WEIGHT1_0 2844 -#define B_OPA1_8 2845 -#define B_OPA1_4 2846 -#define B_OPA1_2 2847 -#define B_OPA3_4 2848 -#define B_OPA1_0 2849 +#define B_OPA1_8 2845 +#define B_OPA1_4 2846 +#define B_OPA1_2 2847 +#define B_OPA3_4 2848 +#define B_OPA1_0 2849 -#define B_CLR_WPAINT 2850 +#define B_CLR_WPAINT 2850 /* *********************** */ #define B_RADIOBUTS 3000 #define B_RAD_GO 2901 #define B_RAD_INIT 2902 -#define B_RAD_LIMITS 2903 +#define B_RAD_LIMITS 2903 #define B_RAD_FAC 2904 -#define B_RAD_NODELIM 2905 -#define B_RAD_NODEFILT 2906 -#define B_RAD_FACEFILT 2907 +#define B_RAD_NODELIM 2905 +#define B_RAD_NODEFILT 2906 +#define B_RAD_FACEFILT 2907 #define B_RAD_ADD 2908 -#define B_RAD_DELETE 2909 -#define B_RAD_COLLECT 2910 -#define B_RAD_SHOOTP 2911 -#define B_RAD_SHOOTE 2912 -#define B_RAD_REPLACE 2913 +#define B_RAD_DELETE 2909 +#define B_RAD_COLLECT 2910 +#define B_RAD_SHOOTP 2911 +#define B_RAD_SHOOTE 2912 +#define B_RAD_REPLACE 2913 #define B_RAD_DRAW 2914 #define B_RAD_FREE 2915 -#define B_RAD_ADDMESH 2916 +#define B_RAD_ADDMESH 2916 /* *********************** */ -#define B_SCRIPTBUTS 3100 +#define B_SCRIPTBUTS 3100 -#define B_SCRIPT_ADD 3001 -#define B_SCRIPT_DEL 3002 -#define B_SCRIPT_TYPE 3003 +#define B_SCRIPT_ADD 3001 +#define B_SCRIPT_DEL 3002 +#define B_SCRIPT_TYPE 3003 /* Scene script buttons */ -#define B_SSCRIPT_ADD 3004 -#define B_SSCRIPT_DEL 3005 -#define B_SSCRIPT_TYPE 3006 +#define B_SSCRIPT_ADD 3004 +#define B_SSCRIPT_DEL 3005 +#define B_SSCRIPT_TYPE 3006 /* *********************** */ #define B_SOUNDBUTS 3200 @@ -608,36 +628,44 @@ enum { B_UVAUTO_LSCM }; -#define B_EFFECTSBUTS 3500 +#define B_EFFECTSBUTS 3500 -#define B_AUTOTIMEOFS 3403 +#define B_AUTOTIMEOFS 3403 #define B_FRAMEMAP 3404 #define B_NEWEFFECT 3405 -#define B_PREVEFFECT 3406 -#define B_NEXTEFFECT 3407 -#define B_CHANGEEFFECT 3408 -#define B_CALCEFFECT 3409 +#define B_PREVEFFECT 3406 +#define B_NEXTEFFECT 3407 +#define B_CHANGEEFFECT 3408 +#define B_CALCEFFECT 3409 #define B_DELEFFECT 3410 #define B_RECALCAL 3411 -#define B_RECALC_DEFL 3412 -#define B_EFFECT_DEP 3413 +#define B_RECALC_DEFL 3412 +#define B_EFFECT_DEP 3413 #define B_FIELD_DEP 3414 -#define B_FIELD_CHANGE 3415 -#define B_PAF_SET_VG 3416 -#define B_PAF_SET_VG1 3417 +#define B_FIELD_CHANGE 3415 +#define B_PAF_SET_VG 3416 +#define B_PAF_SET_VG1 3417 #define B_MODIFIER_BUTS 3600 #define B_MODIFIER_RECALC 3501 #define B_MODIFIER_REDRAW 3502 +/* *********************** */ +#define B_NODE_BUTS 4000 + /* 400 slots reserved, we want an exec event for each node */ +#define B_NODE_LOADIMAGE 3601 +#define B_NODE_TREE_EXEC 3602 + + /* exec should be last in this list */ +#define B_NODE_EXEC 3610 + /* *********************** */ +/* BUTTON 4001-4032: layers? (sort this out!) */ /* *********************** */ -/* BUTTON BUT: > 4000 */ -/* BUTTON 4001-4032: layers */ - +/* event code 0x4000 (16384) and larger: general events (redraws, etc) */ #endif diff --git a/source/blender/include/interface.h b/source/blender/include/interface.h index 7a45e6566b4..f2f6aad855d 100644 --- a/source/blender/include/interface.h +++ b/source/blender/include/interface.h @@ -41,6 +41,10 @@ #define UI_MAX_NAME_STR 64 #define UI_ARRAY 29 +/* panel limits */ +#define UI_PANEL_MINX 100 +#define UI_PANEL_MINY 70 + /* uiBut->flag */ #define UI_SELECT 1 #define UI_MOUSE_OVER 2 @@ -85,14 +89,13 @@ typedef struct { void *xl, *large, *medium, *small; } uiFont; -typedef struct uiLinkLine uiLinkLine; -struct uiLinkLine { /* only for draw/edit */ - uiLinkLine *next, *prev; +typedef struct uiLinkLine { /* only for draw/edit */ + struct uiLinkLine *next, *prev; short flag, pad; - uiBut *from, *to; -}; + struct uiBut *from, *to; +} uiLinkLine; typedef struct { void **poin; /* pointer to original pointer */ @@ -106,7 +109,7 @@ typedef struct { } uiLink; struct uiBut { - uiBut *next, *prev; + struct uiBut *next, *prev; short type, pointype, bit, bitnr, retval, strwidth, ofs, pos, selsta, selend; int flag; @@ -203,6 +206,7 @@ struct uiBlock { /* interface.c */ extern void ui_graphics_to_window(int win, float *x, float *y); +extern void ui_graphics_to_window_rct(int win, rctf *graph, rcti *winr); extern void ui_window_to_graphics(int win, float *x, float *y); extern void ui_block_flush_back(uiBlock *block); @@ -217,6 +221,7 @@ extern void ui_autofill(uiBlock *block); /* interface_panel.c */ extern void ui_draw_panel(uiBlock *block); extern void ui_do_panel(uiBlock *block, uiEvent *uevent); +extern void ui_scale_panel(uiBlock *block); extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown); @@ -224,6 +229,8 @@ extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, flo extern void ui_set_embossfunc(uiBut *but, int drawtype); extern void ui_draw_but(uiBut *but); extern void ui_rasterpos_safe(float x, float y, float aspect); +extern void ui_draw_tria_icon(float x, float y, float aspect, char dir); +extern void ui_draw_anti_x(float x1, float y1, float x2, float y2); #endif diff --git a/source/blender/include/mydevice.h b/source/blender/include/mydevice.h index bc0ed319ed7..8db7d7ce194 100644 --- a/source/blender/include/mydevice.h +++ b/source/blender/include/mydevice.h @@ -251,6 +251,7 @@ #define ONLOAD_SCRIPT 0x4035 #define SCREEN_HANDLER 0x4036 #define REDRAWANIM 0x4037 +#define REDRAWNODE 0x4038 #endif /* !__MYDEVICE_H__ */ diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 463fceaa0a1..ac04cdc95d5 100755 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -125,6 +125,7 @@ typedef struct TransData { struct Object *ob; TransDataExtension *ext; /* for objects, poses. 1 single malloc per TransInfo! */ TransDataIpokey *tdi; /* for objects, ipo keys. per transdata a malloc */ + void *tdmir; /* mirrored element pointer, in editmode mesh to EditVert */ short flag; /* Various flags */ short protectflag; /* If set, copy of Object or PoseChannel protection */ } TransData; @@ -283,7 +284,6 @@ int BoneEnvelope(TransInfo *t, short mval[2]); /*********************** transform_conversions.c ********** */ struct ListBase; -void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it); void flushTransUVs(TransInfo *t); int clipUVTransform(TransInfo *t, float *vec, int resize); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index da1bd98a603..71f4a30bb24 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -62,7 +62,7 @@ typedef struct ID { * to. */ short flag; - int pad; + int icon_id; } ID; /** @@ -72,7 +72,8 @@ typedef struct Library { ID id; ID *idblock; struct FileData *filedata; - char name[160]; + char name[240]; /* reveiled in the UI, can store relative path */ + char filename[240]; /* expanded name, not relative, used while reading */ int tot, pad; /* tot, idblock and filedata are only fo read and write */ } Library; @@ -126,6 +127,7 @@ typedef struct Library { #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') /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */ #define ID_SEQ MAKE_ID2('S', 'Q') diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index db9926d4653..9191e0b6c48 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -36,6 +36,7 @@ struct SpaceLink; struct ListBase; +struct Object; /* PoseChannel stores the results of Actions (ipos) and transform information with respect to the restposition of Armature bones */ @@ -73,6 +74,7 @@ typedef struct bPoseChannel { float ikstretch; float *path; /* totpath x 3 x float */ + struct Object *custom; /* draws custom object instead of this channel */ } bPoseChannel; @@ -116,6 +118,7 @@ typedef struct SpaceAction { /* Action Channel flags */ #define ACHAN_SELECTED 0x00000001 #define ACHAN_HILIGHTED 0x00000002 +#define ACHAN_HIDDEN 0x00000004 #define ACHAN_MOVED 0x80000000 /* SpaceAction flag */ diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 77b8ffd2286..809ff15e46d 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -66,7 +66,7 @@ typedef struct Bone { float rad_head, rad_tail; /* radius for head/tail sphere, defining deform as well */ float size[3]; /* patch for upward compat, UNUSED! */ - short boneclass; + short layer; short segments; /* for B-bones */ }Bone; @@ -76,7 +76,7 @@ typedef struct bArmature { ListBase chainbase; int flag; int drawtype; - int deformflag; + short deformflag, layer; short ghostep, ghostsize; }bArmature; diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h new file mode 100644 index 00000000000..5f48daa0931 --- /dev/null +++ b/source/blender/makesdna/DNA_color_types.h @@ -0,0 +1,75 @@ +/** + * + * $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): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ +#ifndef DNA_COLOR_TYPES_H +#define DNA_COLOR_TYPES_H + +#include "DNA_vec_types.h" + +/* general defines for kernel functions */ +#define CM_RESOL 32 +#define CM_TABLE 256 +#define CM_TABLEDIV (1.0f/256.0f) + +#define CM_TOT 4 + +typedef struct CurveMapPoint { + float x, y; + short flag, shorty; /* shorty for result lookup */ +} CurveMapPoint; + +/* curvepoint->flag */ +#define CUMA_SELECT 1 +#define CUMA_VECTOR 2 + +typedef struct CurveMap { + short totpoint, flag; + + float range; /* quick multiply value for reading table */ + float mintable, maxtable; /* the x-axis range for the table */ + CurveMapPoint *curve; /* actual curve */ + CurveMapPoint *table; /* display and evaluate table */ + +} CurveMap; + +typedef struct CurveMapping { + int flag, cur; /* cur; for buttons, to show active curve */ + + rctf curr, clipr; /* current rect, clip rect (is default rect too) */ + + CurveMap cm[4]; /* max 4 builtin curves per mapping struct now */ + float black[3], white[3]; /* black/white point */ + float bwmul[3], padf; /* black/white point multiply value, for speed */ +} CurveMapping; + +/* cumap->flag */ +#define CUMA_DO_CLIP 1 + +#endif + diff --git a/source/blender/makesdna/DNA_effect_types.h b/source/blender/makesdna/DNA_effect_types.h index 46ce9b7d017..571f87ae33f 100644 --- a/source/blender/makesdna/DNA_effect_types.h +++ b/source/blender/makesdna/DNA_effect_types.h @@ -104,6 +104,7 @@ typedef struct Particle { short mat_nr, rt; } Particle; +struct Group; typedef struct PartEff { struct PartEff *next, *prev; @@ -125,7 +126,10 @@ typedef struct PartEff { short disp, vertgroup_v; char vgroupname[32], vgroupname_v[32]; + float imat[4][4]; /* inverse matrix of parent Object */ + Particle *keys; + struct Group *group; } PartEff; diff --git a/source/blender/makesdna/DNA_group_types.h b/source/blender/makesdna/DNA_group_types.h index f7139101476..09ecc3a68c1 100644 --- a/source/blender/makesdna/DNA_group_types.h +++ b/source/blender/makesdna/DNA_group_types.h @@ -38,50 +38,13 @@ #include "DNA_ID.h" struct Object; -struct Ipo; - -typedef struct GroupKey { - struct GroupKey *next, *prev; - short sfra, efra; - float cfra; - char name[32]; -} GroupKey; - -typedef struct ObjectKey { - struct ObjectKey *next, *prev; - GroupKey *gkey; /* for reference */ - - /* copy of relevant data */ - short partype, pad; - int par1, par2, par3; - - struct Object *parent, *track; - struct Ipo *ipo; - - /* this block identical to object */ - float loc[3], dloc[3], orig[3]; - float size[3], dsize[3]; - float rot[3], drot[3]; - float quat[4], dquat[4]; - float obmat[4][4]; - float parentinv[4][4]; - float imat[4][4]; /* voor bij render, tijdens simulate, tijdelijk: ipokeys van transform */ - - unsigned int lay; /* kopie van Base */ - - char transflag, ipoflag; - char trackflag, upflag; - - float sf, ctime, padf; - - -} ObjectKey; typedef struct GroupObject { struct GroupObject *next, *prev; struct Object *ob; - ListBase okey; /* ObjectKey */ - + void *lampren; /* used while render */ + int recalc; /* copy of ob->recalc, used to set animated groups OK */ + int pad; } GroupObject; @@ -89,11 +52,9 @@ typedef struct Group { ID id; ListBase gobject; /* GroupObject */ - ListBase gkey; /* GroupKey */ - - GroupKey *active; } Group; + #endif diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 7b26a3c2b57..a6dca412d9c 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -50,7 +50,7 @@ typedef struct Image { struct ImBuf *mipmap[10]; short ok, flag; - short lastframe, lastquality; + short lastframe, pad; /* texture page */ short tpageflag, totbind; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 451b8ba692f..15cee1a288e 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -34,10 +34,9 @@ #ifndef DNA_MATERIAL_TYPES_H #define DNA_MATERIAL_TYPES_H -/* #include "BLI_listBase.h" */ - #include "DNA_ID.h" #include "DNA_scriptlink_types.h" +#include "DNA_listBase.h" #ifndef MAX_MTEX #define MAX_MTEX 10 @@ -47,6 +46,8 @@ struct MTex; struct Ipo; struct Material; struct ColorBand; +struct Group; +struct bNodeTree; /* WATCH IT: change type? also make changes in ipo.h */ @@ -54,14 +55,16 @@ typedef struct Material { ID id; short colormodel, lay; /* lay: for dynamics (old engine, until 2.04) */ + /* note, keep this below synced with render_types.h */ float r, g, b; float specr, specg, specb; float mirr, mirg, mirb; float ambr, ambb, ambg; - float amb, emit, ang, spectra, ray_mirror; float alpha, ref, spec, zoffs, add; float translucency; + /* end synced with render_types.h */ + float fresnel_mir, fresnel_mir_i; float fresnel_tra, fresnel_tra_i; float filter; /* filter added, for raytrace transparency */ @@ -69,16 +72,15 @@ typedef struct Material { short har; char seed1, seed2; - int mode; - int mode2; /* even more material settings :) */ + int mode, mode_l; /* mode_l is the or-ed result of all layer modes */ short flarec, starc, linec, ringc; float hasize, flaresize, subsize, flareboost; float strand_sta, strand_end, strand_ease; + float sbias; /* shadow bias */ /* for buttons and render*/ - char rgbsel, texact, pr_type, pad; - short pr_back, pr_lamp, septex, pad4; - int pad5; + char rgbsel, texact, pr_type, use_nodes; + short pr_back, pr_lamp, septex, ml_flag; /* ml_flag is for disable base material */ /* shaders */ short diff_shader, spec_shader; @@ -97,7 +99,9 @@ typedef struct Material { float rampfac_col, rampfac_spec; struct MTex *mtex[10]; + struct bNodeTree *nodetree; struct Ipo *ipo; + struct Group *group; /* light group */ /* dynamic properties */ float friction, fh, reflect; @@ -107,7 +111,7 @@ typedef struct Material { /* yafray: absorption color, dispersion parameters and material preset menu */ float YF_ar, YF_ag, YF_ab, YF_dscale, YF_dpwr; int YF_dsmp, YF_preset, YF_djit; - + ScriptLink scriptlink; } Material; @@ -156,6 +160,8 @@ typedef struct Material { #define MA_FULL_OSA 0x800000 #define MA_TANGENT_STR 0x1000000 #define MA_SHADBUF 0x2000000 + /* note; we drop MA_TANGENT_STR later to become tangent_u */ +#define MA_TANGENT_V 0x4000000 #define MA_MODE_MASK 0x3ffffff /* all valid mode bits */ @@ -163,7 +169,8 @@ typedef struct Material { #define MA_DIFF_LAMBERT 0 #define MA_DIFF_ORENNAYAR 1 #define MA_DIFF_TOON 2 -#define MA_DIFF_MINNAERT 3 +#define MA_DIFF_MINNAERT 3 +#define MA_DIFF_FRESNEL 4 /* spec_shader */ #define MA_SPEC_COOKTORR 0 @@ -205,10 +212,10 @@ typedef struct Material { #define TEXCO_OSA 512 #define TEXCO_WINDOW 1024 #define NEED_UV 2048 - /* optim = use simpler AA */ -#define TEXCO_OPTIM 4096 - /* stored in vertex->accum, 1 D */ +#define TEXCO_TANGENT 4096 + /* still stored in vertex->accum, 1 D */ #define TEXCO_STRAND 8192 +#define TEXCO_STRESS 16384 /* mapto */ #define MAP_COL 1 @@ -226,11 +233,14 @@ typedef struct Material { #define MAP_AMB 2048 #define MAP_DISPLACE 4096 #define MAP_WARP 8192 +#define MAP_LAYER 16384 /* pr_type */ -#define MA_FLAT 0 -#define MA_SPHERE 1 -#define MA_CUBE 2 +#define MA_SPHERE 0 +#define MA_CUBE 1 +#define MA_FLAT 2 +#define MA_MONKEY 3 +#define MA_SPHERE_A 4 /* pr_back */ #define MA_DARK 1 diff --git a/source/blender/makesdna/DNA_nla_types.h b/source/blender/makesdna/DNA_nla_types.h index bf3d7820dae..fe01fa91eb2 100644 --- a/source/blender/makesdna/DNA_nla_types.h +++ b/source/blender/makesdna/DNA_nla_types.h @@ -35,6 +35,7 @@ struct bAction; struct Ipo; +struct Object; typedef struct bActionStrip { struct bActionStrip *next, *prev; @@ -43,9 +44,10 @@ typedef struct bActionStrip { struct Ipo *ipo; /* Blending ipo */ struct bAction *act; /* The action referenced by this strip */ - + struct Object *object; /* For groups, the actual object being nla'ed */ float start, end; /* The range of frames covered by this strip */ float actstart, actend; /* The range of frames taken from the action */ + float actoffs, padf; /* Offset within action, for cycles and striding */ float stridelen; /* The stridelength (considered when flag & ACT_USESTRIDE) */ float repeat; /* The number of times to repeat the action range */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h new file mode 100644 index 00000000000..853857f6915 --- /dev/null +++ b/source/blender/makesdna/DNA_node_types.h @@ -0,0 +1,189 @@ +/** + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef DNA_NODE_TYPES_H +#define DNA_NODE_TYPES_H + +#include "DNA_ID.h" +#include "DNA_vec_types.h" +#include "DNA_listBase.h" + + +struct SpaceNode; +struct bNodeLink; +struct bNodeType; +struct bNodeGroup; +struct uiBlock; + +#define NODE_MAXSTR 32 + + +typedef struct bNodeStack { + float vec[4]; + float min, max; /* min/max for values (UI writes it, execute might use it) */ + void *data; + short hasinput; /* when input has link, tagged before executing */ + short hasoutput; /* when output is linked, tagged before executing */ + short datatype; /* type of data pointer */ + short pad; +} bNodeStack; + +/* ns->datatype, shadetree only */ +#define NS_OSA_VECTORS 1 +#define NS_OSA_VALUES 2 + +typedef struct bNodeSocket { + struct bNodeSocket *next, *prev; + + char name[32]; + bNodeStack ns; /* custom data for inputs, only UI writes in this */ + + short type, flag; /* type is copy from socket type struct */ + short limit, stack_index; /* limit for dependency sort, stack_index for exec */ + short intern; /* intern = tag for group nodes */ + short stack_index_ext; /* for groups, to find the caller stack index */ + int pad1; + + float locx, locy; + + /* internal data to retrieve relations and groups */ + + int own_index, to_index; /* group socket identifiers, to find matching pairs after reading files */ + + struct bNodeSocket *tosock; /* group-node sockets point to the internal group counterpart sockets, set after read file */ + struct bNodeLink *link; /* a link pointer, set in nodeSolveOrder() */ + +} bNodeSocket; + +/* sock->type */ +#define SOCK_VALUE 0 +#define SOCK_VECTOR 1 +#define SOCK_RGBA 2 +#define SOCK_IMAGE 3 + +/* sock->flag, first bit is select */ +#define SOCK_HIDDEN 2 + /* only used now for groups... */ +#define SOCK_IN_USE 4 + +# +# +typedef struct bNodePreview { + float *rect; + short xsize, ysize; +} bNodePreview; + + +/* limit data in bNode to what we want to see saved? */ +typedef struct bNode { + struct bNode *next, *prev, *new; + + char name[32]; + short type, flag; + short done, level; /* both for dependency and sorting */ + short lasty, menunr; /* lasty: check preview render status, menunr: browse ID blocks */ + short stack_index; /* for groupnode, offset in global caller stack */ + short nr; /* number of this node in list, used for exec events */ + + ListBase inputs, outputs; + struct ID *id; /* optional link to libdata */ + void *storage; /* custom data, must be struct, for storage in file */ + struct uiBlock *block; /* each node has own block */ + + float locx, locy; /* root offset for drawing */ + float width, miniwidth; + short custom1, custom2; /* to be abused for buttons */ + + short need_exec, pad1; /* need_exec is set to optimize execution */ + + rctf totr; /* entire boundbox */ + rctf butr; /* optional buttons area */ + rctf prvr; /* optional preview area */ + bNodePreview *preview; /* optional preview image */ + + struct bNodeType *typeinfo; /* lookup of callbacks and defaults */ + +} bNode; + +/* node->flag */ +#define NODE_SELECT 1 +#define NODE_OPTIONS 2 +#define NODE_PREVIEW 4 +#define NODE_HIDDEN 8 +#define NODE_ACTIVE 16 +#define NODE_ACTIVE_ID 32 +#define NODE_DO_OUTPUT 64 +#define NODE_GROUP_EDIT 128 + +typedef struct bNodeLink { + struct bNodeLink *next, *prev; + + bNode *fromnode, *tonode; + bNodeSocket *fromsock, *tosock; + +} bNodeLink; + +/* the basis for a Node tree, all links and nodes reside internal here */ +/* only re-usable node trees are in the library though, materials allocate own tree struct */ +typedef struct bNodeTree { + ID id; + + ListBase nodes, links; + + bNodeStack *stack; /* stack is only while executing, no read/write in file */ + bNodeStack *stack1; /* for other thread, easy to expand though... */ + + int type, init; /* set init on fileread */ + int stacksize; /* amount of elements in stack */ + int cur_index; /* sockets in groups have unique identifiers, adding new sockets always will increase this counter */ + struct bNodeType **alltypes; /* type definitions, set on fileread, no read/write */ + struct bNodeType *owntype; /* for groups or dynamic trees, no read/write */ + + /* callbacks */ + void (*timecursor)(int nr); + +} bNodeTree; + +/* ntree->type, index */ +#define NTREE_SHADER 0 +#define NTREE_COMPOSIT 1 + +/* ntree->init, flag */ +#define NTREE_TYPE_INIT 1 +#define NTREE_EXEC_INIT 2 + +/* data structs, for node->storage */ + +typedef struct NodeImageAnim { + short frames, sfra, nr; + char cyclic, movie; +} NodeImageAnim; + +#endif + diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 1d16015a628..c34b14f30af 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -148,6 +148,8 @@ typedef struct Object { char dt, dtx; char totcol; /* copy of mesh or curve or meta */ char actcol; + char empty_drawtype, pad1[3]; + float empty_drawsize; ScriptLink scriptlink; ListBase prop; @@ -188,10 +190,7 @@ typedef struct Object { struct PartDeflect *pd; /* particle deflector/attractor/collision data */ struct SoftBody *soft; /* if exists, saved in file */ - struct Life *life; - - LBuf lbuf; - LBuf port; + struct Group *dup_group; /* object duplicator for group */ short fluidsimFlag; /* NT toggle fluidsim participation on/off */ char shapenr, shapeflag; /* current shape key for menu or pinned, flag for pinning */ @@ -262,13 +261,13 @@ extern Object workob; #define OB_OFFS_LOCAL 1 #define OB_QUAT 2 #define OB_NEG_SCALE 4 -#define OB_DUPLI (8+16) +#define OB_DUPLI (8+16+256) #define OB_DUPLIFRAMES 8 #define OB_DUPLIVERTS 16 #define OB_DUPLIROT 32 #define OB_DUPLINOSPEED 64 - #define OB_POWERTRACK 128 +#define OB_DUPLIGROUP 256 /* (short) ipoflag */ #define OB_DRAWKEY 1 @@ -314,6 +313,11 @@ extern Object workob; /* enable transparent draw */ #define OB_DRAWTRANSP 128 +/* empty_drawtype: no flags */ +#define OB_ARROWS 1 +#define OB_PLAINAXES 2 +#define OB_CIRCLE 3 + /* boundtype */ #define OB_BOUND_BOX 0 #define OB_BOUND_SPHERE 1 @@ -329,10 +333,9 @@ extern Object workob; #define BA_HAS_RECALC_DATA 8 #define BA_DO_IPO 32 -#define OB_GONNA_MOVE 32 #define BA_FROMSET 128 -#define OB_DO_IMAT 256 + #define OB_FROMDUPLI 512 #define OB_DONE 1024 #define OB_RADIO 2048 diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index f4ee028aed6..01776a2e981 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1,9 +1,4 @@ /** - * blenlib/DNA_scene_types.h (mar-2001 nzc) - * - * Renderrecipe and scene decription. The fact that there is a - * hierarchy here is a bit strange, and not desirable. - * * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -53,6 +48,7 @@ struct World; struct Scene; struct Image; struct Group; +struct bNodeTree; typedef struct Base { struct Base *next, *prev; @@ -98,6 +94,34 @@ typedef struct AudioData { short pad[3]; } AudioData; +typedef struct SceneRenderLayer { + struct SceneRenderLayer *next, *prev; + + char name[32]; + struct Scene *scene; /* unused still */ + unsigned int lay; /* scene->lay itself has priority over this */ + short layflag; + short passflag; +} SceneRenderLayer; + +/* srl->layflag */ +#define SCE_LAY_SOLID 1 +#define SCE_LAY_ZTRA 2 +#define SCE_LAY_HALO 4 +#define SCE_LAY_STRAND 8 + +/* srl->passflag */ +#define SCE_PASS_COMBINED 1 +#define SCE_PASS_Z 2 +#define SCE_PASS_RGBA 4 +#define SCE_PASS_DIFFUSE 8 +#define SCE_PASS_SPEC 16 +#define SCE_PASS_SHADOW 32 +#define SCE_PASS_AO 64 +#define SCE_PASS_MIRROR 128 +#define SCE_PASS_NORMAL 256 +#define SCE_PASS_VECTOR 512 + typedef struct RenderData { struct AviCodecData *avicodecdata; struct QuicktimeCodecData *qtcodecdata; @@ -117,7 +141,7 @@ typedef struct RenderData { short dimensionspreset; /* for the dimensions presets menu */ - short filtertype, pad; /* filter is box, tent, gauss, mitch, etc */ + short filtertype; /* filter is box, tent, gauss, mitch, etc */ short size, maximsize; /* size in %, max in Kb */ @@ -146,14 +170,14 @@ typedef struct RenderData { * The number of part to use in the y direction */ short yparts; - /* should rewrite this I think... */ - rctf safety, border; - short winpos, planes, imtype; + short winpos, planes, imtype, subimtype; + /** Mode bits: */ /* 0: Enable backbuffering for images */ short bufflag; short quality; + /** * Flags for render settings. Use bit-masking to access the settings. * 0: enable sequence output rendering @@ -210,6 +234,14 @@ typedef struct RenderData { * identical materials with this number.*/ short same_mat_redux; + /* safety and border rect */ + rctf safety, border; + + /* information on different layers to be rendered */ + ListBase layers; + short actlay, pad; + int pad2; + /** * The gamma for the normal rendering. Used when doing * oversampling, to correctly blend subpixels to pixels. */ @@ -289,7 +321,6 @@ typedef struct Scene { ListBase base; struct Base *basact; - struct Group *group; float cursor[3]; float twcent[3]; /* center for transform widget */ @@ -297,9 +328,12 @@ typedef struct Scene { unsigned int lay; /* editmode stuff */ - short selectmode, pad; - short proportional, prop_mode; float editbutsize; /* size of normals */ + short selectmode; + short proportional, prop_mode; + + short use_nodes; + struct bNodeTree *nodetree; void *ed; struct Radio *radio; @@ -321,7 +355,7 @@ typedef struct Scene { /* none of the dependancy graph vars is mean to be saved */ struct DagForest *theDag; short dagisvalid, dagflags; - int dirty; + short dirty, recalc; /* recalc = counterpart of ob->recalc */ } Scene; @@ -377,7 +411,8 @@ typedef struct Scene { #define R_PASSEPARTOUT 0x0004 #define R_EXTENSION 0x0010 -#define R_OGL 0x0020 +#define R_NODE_PREVIEW 0x0020 +#define R_DOCOMP 0x0040 /* alphamode */ #define R_ADDSKY 0 @@ -406,33 +441,12 @@ typedef struct Scene { #define R_BMP 20 #define R_RADHDR 21 #define R_TIFF 22 +#define R_OPENEXR 23 -/* **************** RENDER ********************* */ -/* mode flag is same as for renderdata */ -/* flag */ -#define R_ZTRA 1 -#define R_HALO 2 -#define R_SEC_FIELD 4 -#define R_LAMPHALO 8 -#define R_RENDERING 16 -#define R_ANIMRENDER 32 -#define R_REDRAW_PRV 64 +/* subimtype, flag options for imtype */ +#define R_OPENEXR_HALF 1 +#define R_OPENEXR_ZBUF 2 -/* vlakren->flag (vlak = face in dutch) char!!! */ -#define R_SMOOTH 1 -#define R_VISIBLE 2 - /* strand flag, means special handling */ -#define R_STRAND 4 -#define R_NOPUNOFLIP 8 -#define R_FULL_OSA 16 -#define R_FACE_SPLIT 32 - /* Tells render to divide face other way. */ -#define R_DIVIDE_24 64 - /* vertex normals are tangent or view-corrected vector, for hair strands */ -#define R_TANGENT 128 - -/* vertren->texofs (texcoordinate offset relative to vertren->orco */ -#define R_UVOFS3 1 /* **************** SCENE ********************* */ #define RAD_PHASE_PATCHES 1 @@ -452,6 +466,9 @@ typedef struct Scene { #define SCE_CLEAN 0 #define SCE_DIRTY 1 +/* sce->recalc (now in use by previewrender) */ +#define SCE_PRV_CHANGED 1 + /* sce->prop_mode (proportional falloff) */ #define PROP_SMOOTH 0 #define PROP_SPHERE 1 diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index ad45ae7d58d..e0b2a337d9f 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -172,11 +172,12 @@ enum { SPACE_ACTION, SPACE_NLA, SPACE_SCRIPT, - SPACE_TIME + SPACE_TIME, + SPACE_NODE /* SPACE_LOGIC */ }; -/* Adding a new space type? Change SPACEICONMAX in headerbuttons.c */ +/* Adding a new space type? Change SPACEICONMAX in BSE_headerbuttons.h */ /* -- should rather handle this with the above enum... */ #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7007981ff64..ed842ad232a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -48,7 +48,9 @@ struct Image; struct SpaceIpo; struct BlendHandle; struct TreeStore; - +struct RenderInfo; +struct bNodeTree; +struct uiBlock; /** * The base structure all the other spaces @@ -106,6 +108,7 @@ typedef struct SpaceButs { int spacetype; float blockscale; struct ScrArea *area; + struct RenderInfo *ri; short blockhandler[8]; @@ -120,15 +123,13 @@ typedef struct SpaceButs { short texnr; char texfrom, showgroup; - short rectx, recty; /* preview render */ - unsigned int *rect; - short cury, modeltype; - + short modeltype; short scriptblock; short scaflag; - short re_align, pad1; + short re_align; - int oldkeypress; /* for keeping track of the sub tab key cycling */ + short oldkeypress; /* for keeping track of the sub tab key cycling */ + char use_nodes, pad; char texact, tab[7]; /* storing tabs for each context */ @@ -218,6 +219,7 @@ typedef struct SpaceImage { View2D v2d; struct Image *image; + struct CurveMapping *cumap; float zoom; short mode, menunr; short imanr, curtile; @@ -292,7 +294,26 @@ typedef struct SpaceTime { } SpaceTime; +typedef struct SpaceNode { + SpaceLink *next, *prev; + int spacetype; + float blockscale; + struct ScrArea *area; + + View2D v2d; + + struct ID *id, *from; /* context, no need to save in file? well... pinning... */ + short flag, menunr; /* menunr: browse id block in header */ + float aspect; + void *curfont; + + struct bNodeTree *nodetree, *edittree; + int treetype, pad; /* treetype: as same nodetree->type */ + +} SpaceNode; +/* snode->flag */ +#define SNODE_DO_PREVIEW 1 # # @@ -445,6 +466,10 @@ typedef struct SpaceImaSel { #define SI_COORDFLOATS 512 #define SI_PIXELSNAP 1024 #define SI_LSCM_LIVE 2048 +#define SI_USE_ALPHA 4096 +#define SI_SHOW_ALPHA 8192 +#define SI_SHOW_ZBUF 16384 + /* SpaceText flags (moved from DNA_text_types.h) */ @@ -483,6 +508,7 @@ typedef struct SpaceImaSel { #define SO_SELECTED 3 #define SO_ACTIVE 4 #define SO_SAME_TYPE 5 +#define SO_GROUPS 6 /* SpaceOops->storeflag */ #define SO_TREESTORE_CLEANUP 1 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 21ae86ea68a..3cb37dff29e 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -163,6 +163,23 @@ typedef struct Tex { } Tex; +/* used for mapping node. note: rot is in degrees */ + +typedef struct TexMapping { + float loc[3], rot[3], size[3]; + int flag; + + float mat[4][4]; + float min[3], max[3]; + struct Object *ob; + +} TexMapping; + +/* texmap->flag */ +#define TEXMAP_CLIP_MIN 1 +#define TEXMAP_CLIP_MAX 2 + + /* **************** TEX ********************* */ /* type */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index aa835780b1a..f5cc2ce4810 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -85,7 +85,7 @@ typedef struct ThemeSpace { char edge[4], edge_select[4]; char edge_seam[4], edge_facesel[4]; char face[4], face_select[4]; // solid faces - char face_dot[4]; // selected color + char face_dot[4]; // selected color char normal[4]; char bone_solid[4], bone_pose[4]; char strip[4], strip_select[4]; @@ -93,8 +93,8 @@ typedef struct ThemeSpace { char vertex_size, facedot_size; char bpad[2]; - char syntaxl[4], syntaxn[4], syntaxb[4]; //syn- - char syntaxv[4], syntaxc[4]; //tax + char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes + char syntaxv[4], syntaxc[4]; } ThemeSpace; @@ -119,6 +119,7 @@ typedef struct bTheme { ThemeSpace text; ThemeSpace toops; ThemeSpace ttime; + ThemeSpace tnode; } bTheme; @@ -207,6 +208,7 @@ extern UserDef U; /* from usiblender.c !!!! */ #define USER_LOCKAROUND 4096 #define USER_GLOBALUNDO 8192 #define USER_ORBIT_SELECTION 16384 +#define USER_KEYINSERTAVAI 32768 #define USER_HIDE_DOT 65536 /* transopts */ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index bf4f44a421d..03c6aad6cf6 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -40,6 +40,7 @@ struct Tex; struct SpaceLink; struct Base; struct BoundBox; +struct RenderInfo; /* This is needed to not let VC choke on near and far... old * proprietary MS extensions... */ @@ -63,18 +64,6 @@ typedef struct BGpic { unsigned int *rect; } BGpic; -# -# -typedef struct View3DAfter { - struct View3DAfter *next, *prev; - struct Base *base; - int type; -} View3DAfter; - -/* View3DAfter->type */ -#define V3D_XRAY 1 -#define V3D_TRANSP 2 - typedef struct View3D { struct SpaceLink *next, *prev; int spacetype; @@ -104,6 +93,7 @@ typedef struct View3D { struct Object *camera; struct BGpic *bgpic; struct View3D *localvd; + struct RenderInfo *ri; /** * The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID, @@ -114,6 +104,7 @@ typedef struct View3D { short scenelock, around, camzoom, flag; float lens, grid, gridview, pixsize, near, far; + float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */ float ofs[3], cursor[3]; short gridlines, viewbut; @@ -138,7 +129,7 @@ typedef struct View3D { #define V3D_MODE (16+32+64+128+256+512) #define V3D_DISPIMAGE 1 #define V3D_DISPBGPIC 2 -#define V3D_SETUPBUTS 4 +#define V3D_HIDE_HELPLINES 4 #define V3D_NEEDBACKBUFDRAW 8 #define V3D_EDITMODE 16 #define V3D_VERTEXPAINT 32 diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index e284044a633..edc621ba758 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -152,12 +152,13 @@ typedef struct World { #define WOMAP_HORIZ 2 #define WOMAP_ZENUP 4 #define WOMAP_ZENDOWN 8 +#define WOMAP_MIST 16 /* physicsEngine */ #define WOPHY_NONE 0 #define WOPHY_ENJI 1 #define WOPHY_SUMO 2 -#define WOPHY_DYNAMO 3 +#define WOPHY_DYNAMO 3 #define WOPHY_ODE 4 #define WOPHY_BULLET 5 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index d0186deefad..87174abab38 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -123,6 +123,8 @@ char *includefiles[] = { "DNA_action_types.h", "DNA_constraint_types.h", "DNA_nla_types.h", + "DNA_node_types.h", + "DNA_color_types.h", // if you add files here, please add them at the end // of makesdna.c (this file) as well @@ -1129,4 +1131,6 @@ int main(int argc, char ** argv) #include "DNA_action_types.h" #include "DNA_constraint_types.h" #include "DNA_nla_types.h" +#include "DNA_node_types.h" +#include "DNA_color_types.h" /* end of list */ diff --git a/source/blender/python/SConscript b/source/blender/python/SConscript index dec55ab52cb..aedafd84e96 100644 --- a/source/blender/python/SConscript +++ b/source/blender/python/SConscript @@ -34,6 +34,7 @@ source_files = ['BPY_interface.c', 'api2_2x/Noise.c', 'api2_2x/NMesh.c', 'api2_2x/Object.c', + 'api2_2x/Pose.c', 'api2_2x/point.c', 'api2_2x/Registry.c', 'api2_2x/Scene.c', diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c index 3760d139d02..28ae3eadcc7 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -477,6 +477,7 @@ static PyObject *Armature_update(BPy_Armature *self) BLI_freelistN(&self->Bones->editbones); }else{ goto AttributeError; + } return EXPP_incr_ret(Py_None); @@ -513,6 +514,71 @@ AttributeError: return EXPP_intError(PyExc_AttributeError, "%s%s", sArmatureBadArgs, "Expects True or False"); } +//------------------------Armature.layers (getter) +static PyObject *Armature_getLayers(BPy_Armature *self, void *closure) +{ + int layers, bit = 0, val = 0; + PyObject *item = NULL, *laylist = PyList_New( 0 ); + + if( !laylist ) + return EXPP_ReturnPyObjError( PyExc_MemoryError, + "couldn't create pylist!" ); + + layers = self->armature->layer; + + while( bit < 20 ) { + val = 1 << bit; + if( layers & val ) { + item = Py_BuildValue( "i", bit + 1 ); + PyList_Append( laylist, item ); + Py_DECREF( item ); + } + bit++; + } + return laylist; +} +//------------------------Armature.layer (setter) +static int Armature_setLayers(BPy_Armature *self, PyObject *value, void *closure) +{ + if(value){ + if(PyList_Check(value)){ + int layers = 0, len_list = 0; + int val; + PyObject *item = NULL; + + len_list = PyList_Size(value); + + if( len_list == 0 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "list can't be empty, at least one layer must be set" ); + + while( len_list ) { + --len_list; + item = PyList_GetItem( value, len_list ); + if( !PyInt_Check( item ) ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "list must contain only integer numbers" ); + + val = ( int ) PyInt_AsLong( item ); + if( val < 1 || val > 20 ) + return EXPP_ReturnIntError( PyExc_AttributeError, + "layer values must be in the range [1, 20]" ); + + layers |= 1 << ( val - 1 ); + } + + /* update any bases pointing to our object */ + self->armature->layer = layers; + + return 0; + } + } + goto AttributeError; + +AttributeError: + return EXPP_ReturnIntError( PyExc_TypeError, + "expected a list of integers" ); +} //------------------------Armature.mirrorEdit (getter) static PyObject *Armature_getMirrorEdit(BPy_Armature *self, void *closure) { @@ -903,7 +969,9 @@ static PyGetSetDef BPy_Armature_getset[] = { "Enable/Disable X-axis mirrored editing", NULL}, {"autoIK", (getter)Armature_getAutoIK, (setter)Armature_setAutoIK, "Adds temporal IK chains while grabbing bones", NULL}, - {NULL, NULL, NULL, NULL, NULL} + {"layers", (getter)Armature_getLayers, (setter)Armature_setLayers, + "List of layers for the armature", NULL}, + {NULL} }; //------------------------tp_new //This methods creates a new object (note it does not initialize it - only the building) diff --git a/source/blender/python/api2_2x/Bone.h b/source/blender/python/api2_2x/Bone.h index 756651d79c2..8c10aeb3075 100644 --- a/source/blender/python/api2_2x/Bone.h +++ b/source/blender/python/api2_2x/Bone.h @@ -73,4 +73,3 @@ PyObject *PyEditBone_FromBone(Bone *bone); PyObject *PyEditBone_FromEditBone(struct EditBone *editbone); #endif - diff --git a/source/blender/python/api2_2x/NLA.c b/source/blender/python/api2_2x/NLA.c index 96701c124f5..dd891472155 100644 --- a/source/blender/python/api2_2x/NLA.c +++ b/source/blender/python/api2_2x/NLA.c @@ -79,6 +79,7 @@ static PyObject *Action_getName( BPy_Action * self ); static PyObject *Action_setName( BPy_Action * self, PyObject * args ); static PyObject *Action_setActive( BPy_Action * self, PyObject * args ); static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args ); +static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args ); static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args ); static PyObject *Action_getAllChannelIpos( BPy_Action * self ); @@ -95,6 +96,8 @@ static PyMethodDef BPy_Action_methods[] = { "(str) -set this action as the active action for an object"}, {"getChannelIpo", ( PyCFunction ) Action_getChannelIpo, METH_VARARGS, "(str) -get the Ipo from a named action channel in this action"}, + {"verifyChannel", ( PyCFunction ) Action_verifyChannel, METH_VARARGS, + "(str) -verify the channel in this action"}, {"removeChannel", ( PyCFunction ) Action_removeChannel, METH_VARARGS, "(str) -remove the channel from the action"}, {"getAllChannelIpos", ( PyCFunction ) Action_getAllChannelIpos, @@ -317,6 +320,27 @@ static PyObject *Action_getChannelIpo( BPy_Action * self, PyObject * args ) return Ipo_CreatePyObject( chan->ipo ); } +//---------------------------------------------------------------------- +static PyObject *Action_verifyChannel( BPy_Action * self, PyObject * args ) +{ + char *chanName; + bActionChannel *chan; + + if( !self->action ) + ( EXPP_ReturnPyObjError( PyExc_RuntimeError, + "couldn't create channel for a NULL action" ) ); + + if( !PyArg_ParseTuple( args, "s", &chanName ) ) + return ( EXPP_ReturnPyObjError( PyExc_AttributeError, + "expected string argument" ) ); + + chan = verify_action_channel(self->action, chanName); + + Py_INCREF( Py_None ); + return Py_None; +} + + static PyObject *Action_removeChannel( BPy_Action * self, PyObject * args ) { char *chanName; diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 472d8d08043..89ad6f36576 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -44,6 +44,9 @@ struct rctf; #include "DNA_view3d_types.h" #include "DNA_object_force.h" #include "DNA_userdef_types.h" +#include "DNA_oops_types.h" + +#include "BKE_action.h" #include "BKE_depsgraph.h" #include "BKE_effect.h" #include "BKE_font.h" @@ -60,19 +63,23 @@ struct rctf; #include "BKE_global.h" #include "BKE_main.h" #include "BKE_scene.h" -#include "BIF_editview.h" + #include "BSE_editipo.h" #include "BSE_edit.h" + #include "BIF_space.h" +#include "BIF_editview.h" #include "BIF_drawscene.h" #include "BIF_meshtools.h" #include "BIF_editarmature.h" -#include "DNA_oops_types.h" + #include "BLI_arithb.h" #include "BLI_blenlib.h" + #include "BDR_editobject.h" -#include "BDR_editcurve.h" + #include "MEM_guardedalloc.h" + #include "mydevice.h" #include "blendef.h" #include "Scene.h" @@ -82,6 +89,7 @@ struct rctf; #include "Curve.h" #include "Ipo.h" #include "Armature.h" +#include "Pose.h" #include "Camera.h" #include "Lamp.h" #include "Lattice.h" @@ -173,7 +181,6 @@ struct PyMethodDef M_Object_methods[] = { int setupSB(Object* ob); /*Make sure Softbody Pointer is initialized */ int setupPI(Object* ob); -static PyObject *Object_getPose( BPy_Object *self); static PyObject *Object_buildParts( BPy_Object * self ); static PyObject *Object_clearIpo( BPy_Object * self ); static PyObject *Object_clrParent( BPy_Object * self, PyObject * args ); @@ -197,6 +204,7 @@ static PyObject *Object_getTracked( BPy_Object * self ); static PyObject *Object_getType( BPy_Object * self ); static PyObject *Object_getBoundBox( BPy_Object * self ); static PyObject *Object_getAction( BPy_Object * self ); +static PyObject *Object_getPose( BPy_Object * self ); static PyObject *Object_isSelected( BPy_Object * self ); static PyObject *Object_makeDisplayList( BPy_Object * self ); static PyObject *Object_link( BPy_Object * self, PyObject * args ); @@ -214,6 +222,10 @@ static PyObject *Object_setEuler( BPy_Object * self, PyObject * args ); static PyObject *Object_setMatrix( BPy_Object * self, PyObject * args ); static PyObject *Object_setIpo( BPy_Object * self, PyObject * args ); static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args ); +static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args ); +static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args ); +static PyObject *Object_insertMatrixKey( BPy_Object * self, PyObject * args ); +static PyObject *Object_bake_to_action( BPy_Object * self, PyObject * args ); static PyObject *Object_setLocation( BPy_Object * self, PyObject * args ); static PyObject *Object_setMaterials( BPy_Object * self, PyObject * args ); static PyObject *Object_setName( BPy_Object * self, PyObject * args ); @@ -312,6 +324,8 @@ If 'name_only' is nonzero or True, only the name of the datablock is returned"}, "Returns the object draw type"}, {"getAction", ( PyCFunction ) Object_getAction, METH_NOARGS, "Returns the active action for this object"}, + {"getPose", ( PyCFunction ) Object_getPose, METH_NOARGS, + "() - returns the pose from an object if it exists, else None"}, {"isSelected", ( PyCFunction ) Object_isSelected, METH_NOARGS, "Return a 1 or 0 depending on whether the object is selected"}, {"getEuler", ( PyCFunction ) Object_getEuler, METH_NOARGS, @@ -537,6 +551,14 @@ works only if self and the object specified are of the same type."}, "() - Unlink ipo from this object"}, {"insertIpoKey", ( PyCFunction ) Object_insertIpoKey, METH_VARARGS, "( Object IPO type ) - Inserts a key into IPO"}, + {"insertPoseKey", ( PyCFunction ) Object_insertPoseKey, METH_VARARGS, + "( Object Pose type ) - Inserts a key into Action"}, + {"insertCurrentPoseKey", ( PyCFunction ) Object_insertCurrentPoseKey, METH_VARARGS, + "( Object Pose type ) - Inserts a key into Action based on current pose"}, + {"insertMatrixKey", ( PyCFunction ) Object_insertMatrixKey, METH_VARARGS, + "( ) - Inserts a key into Action based on current/giventime object matrix"}, + {"bake_to_action", ( PyCFunction ) Object_bake_to_action, METH_VARARGS, + "( ) - creates a new action with the information from object animations"}, {"getAllProperties", ( PyCFunction ) Object_getAllProperties, METH_NOARGS, "() - Get all the properties from this object"}, @@ -568,8 +590,6 @@ works only if self and the object specified are of the same type."}, METH_VARARGS, "() - set or reset duplicate child objects on all vertices"}, {"insertShapeKey", ( PyCFunction ) Object_insertShapeKey, METH_NOARGS, "() - Insert a Shape Key in the current object"}, - {"getPose", (PyCFunction)Object_getPose, METH_NOARGS, - "() - returns the pose from an object if it exists, else None"}, {NULL, NULL, 0, NULL} }; @@ -1171,6 +1191,26 @@ static PyObject *Object_getAction( BPy_Object * self ) } } +#if 0 +static PyObject *Object_getPose( BPy_Object * self ) +{ + /*BPy_Action *py_action = NULL; */ + + if( !self->object->pose ) { + Py_INCREF( Py_None ); + return ( Py_None ); + } + else + return Pose_CreatePyObject( self->object->pose ); +} + +#endif + +static PyObject * Object_getPose(BPy_Object *self) +{ + //if there is no pose will return PyNone + return PyPose_FromPose(self->object->pose, self->object->id.name+2); +} static PyObject *Object_isSelected( BPy_Object * self ) { @@ -2206,7 +2246,7 @@ static PyObject *Object_setIpo( BPy_Object * self, PyObject * args ) static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args ) { Object *ob= self->object; - int key = 0; + int key = 0; char *actname= NULL; if( !PyArg_ParseTuple( args, "i", &( key ) ) ) @@ -2261,7 +2301,213 @@ static PyObject *Object_insertIpoKey( BPy_Object * self, PyObject * args ) return EXPP_incr_ret( Py_None ); } +/* + * Object_insertPoseKey() + * inserts a Action Pose key from a given pose (sourceaction, frame) to the active action to a given framenum + */ +static PyObject *Object_insertPoseKey( BPy_Object * self, PyObject * args ) +{ + Object *ob= self->object; + BPy_Action *sourceact; + char *chanName; + int actframe; + + //for debug prints + bActionChannel *achan; + bPoseChannel *pchan; + + /* for doing the time trick, similar to editaction bake_action_with_client() */ + int oldframe; + int curframe; + + if( !PyArg_ParseTuple( args, "O!sii", &Action_Type, &sourceact, &chanName, &actframe, &curframe ) ) + return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expects an action to copy poses from, a string for chan/bone name, an int argument for frame-to-extract from the action and finally another int for the frame where to put the new key in the active object.action" ) ); + + printf("%s %s %d %d, ", sourceact->action->id.name, chanName, actframe, curframe); + printf("%s\n", ob->action->id.name); + + /* */ + extract_pose_from_action(ob->pose, sourceact->action, actframe); + + oldframe = G.scene->r.cfra; + G.scene->r.cfra = curframe; + + //debug + pchan = get_pose_channel(ob->pose, chanName); + printquat(pchan->name, pchan->quat); + + achan = get_action_channel(sourceact->action, chanName); + if(achan->ipo) { + IpoCurve* icu; + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + printvecf("bezt", icu->bezt->vec[1]); + } + } + + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z); + + /* + for (achan = ob->action->chanbase.first; achan; achan=achan->next) { + if(achan->ipo) { + IpoCurve* icu; + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + printf("result: %f %f %f %f", icu->bp->vec[0], icu->bp->vec[1], icu->bp->vec[2], icu->bp->vec[3]); + } + } + } + */ + + G.scene->r.cfra = oldframe; + + allspace(REMAKEIPO, 0); + EXPP_allqueue(REDRAWIPO, 0); + EXPP_allqueue(REDRAWVIEW3D, 0); + EXPP_allqueue(REDRAWACTION, 0); + EXPP_allqueue(REDRAWNLA, 0); + + /* restore, but now with the new action in place */ + //extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra); + //where_is_pose(ob); + + allqueue(REDRAWACTION, 1); + + return EXPP_incr_ret( Py_None ); +} + +static PyObject *Object_insertCurrentPoseKey( BPy_Object * self, PyObject * args ) +{ + Object *ob= self->object; + //bPoseChannel *pchan; //for iterating over all channels in object->pose + char *chanName; + + /* for doing the time trick, similar to editaction bake_action_with_client() */ + int oldframe; + int curframe; + + if( !PyArg_ParseTuple( args, "si", &chanName, &curframe ) ) + return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expected chan/bone name, and a time (int) argument" ) ); + + oldframe = G.scene->r.cfra; + G.scene->r.cfra = curframe; + + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y); + insertkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z); + + G.scene->r.cfra = oldframe; + + allspace(REMAKEIPO, 0); + EXPP_allqueue(REDRAWIPO, 0); + EXPP_allqueue(REDRAWVIEW3D, 0); + EXPP_allqueue(REDRAWACTION, 0); + EXPP_allqueue(REDRAWNLA, 0); + + /* restore */ + extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra); + where_is_pose(ob); + + allqueue(REDRAWACTION, 1); + + return EXPP_incr_ret( Py_None ); +} + +static PyObject *Object_insertMatrixKey( BPy_Object * self, PyObject * args ) +{ + Object *ob= self->object; + char *chanName; + + /* for doing the time trick, similar to editaction bake_action_with_client() */ + int oldframe; + int curframe; + + /* for copying the current object/bone matrices to the new action */ + float localQuat[4]; + float tmat[4][4], startpos[4][4]; + + //to get the matrix + bArmature *arm; + Bone *bone; + + if( !PyArg_ParseTuple( args, "si", &chanName, &curframe ) ) + return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expects a string for chan/bone name and an int for the frame where to put the new key" ) ); + + oldframe = G.scene->r.cfra; + G.scene->r.cfra = curframe; + + //just to get the armaturespace mat + arm = get_armature(ob); + for (bone = arm->bonebase.first; bone; bone=bone->next) + if (bone->name == chanName) break; + //XXX does not check for if-not-found + + where_is_object(ob); + world2bonespace(tmat, ob->obmat, bone->arm_mat, startpos); + Mat4ToQuat(tmat, localQuat); + + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_X, tmat[3][0]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Y, tmat[3][1]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_LOC_Z, tmat[3][2]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_W, localQuat[0]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_X, localQuat[1]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Y, localQuat[2]); + insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_QUAT_Z, localQuat[3]); + //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_X, ); + //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Y); + //insertmatrixkey(&ob->id, ID_PO, chanName, NULL, AC_SIZE_Z); + + allspace(REMAKEIPO, 0); + EXPP_allqueue(REDRAWIPO, 0); + EXPP_allqueue(REDRAWVIEW3D, 0); + EXPP_allqueue(REDRAWACTION, 0); + EXPP_allqueue(REDRAWNLA, 0); + + G.scene->r.cfra = oldframe; + + /* restore, but now with the new action in place */ + extract_pose_from_action(ob->pose, ob->action, G.scene->r.cfra); + where_is_pose(ob); + + allqueue(REDRAWACTION, 1); + + return EXPP_incr_ret( Py_None ); +} + +static PyObject *Object_bake_to_action( BPy_Object * self, PyObject * args ) +{ + + /* for doing the time trick, similar to editaction bake_action_with_client() */ + //int oldframe; + //int curframe; + + //if( !PyArg_ParseTuple( args, "i", &curframe ) ) + // return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "expects an int for the frame where to put the new key" ) ); + + //oldframe = G.scene->r.cfra; + //G.scene->r.cfra = curframe; + + bake_all_to_action(); //ob); + + //G.scene->r.cfra = oldframe; + + return EXPP_incr_ret( Py_None ); +} static PyObject *Object_setLocation( BPy_Object * self, PyObject * args ) { @@ -2793,12 +3039,6 @@ static PyObject *Object_insertShapeKey(BPy_Object * self) return Py_None; } -static PyObject * Object_getPose(BPy_Object *self) -{ - //if there is no pose will return PyNone - return PyPose_FromPose(self->object->pose, self->object->id.name+2); -} - /*****************************************************************************/ /* Function: Object_CreatePyObject */ /* Description: This function will create a new BlenObject from an existing */ diff --git a/source/blender/python/api2_2x/Texture.c b/source/blender/python/api2_2x/Texture.c index 157f2e19cb7..30fbc22214a 100644 --- a/source/blender/python/api2_2x/Texture.c +++ b/source/blender/python/api2_2x/Texture.c @@ -37,13 +37,15 @@ #include "BLI_blenlib.h" #include "BKE_texture.h" #include "BKE_utildefines.h" +#include "DNA_object_types.h" #include "DNA_material_types.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" #include "MTex.h" #include "Image.h" #include "Ipo.h" #include "constant.h" #include "blendef.h" -#include "render.h" #include "gen_utils.h" /*****************************************************************************/ @@ -1863,7 +1865,7 @@ static int Texture_setType( BPy_Texture * self, PyObject * value ) if( !err && self->texture->type == TEX_ENVMAP && !self->texture->env ) { - self->texture->env = RE_add_envmap(); + self->texture->env = BKE_add_envmap(); self->texture->env->object= OBACT; } return err; @@ -2541,7 +2543,7 @@ static PyObject *Texture_oldsetType( BPy_Texture * self, PyObject * args ) if( self->texture->type == TEX_ENVMAP && !self->texture->env ) { - self->texture->env = RE_add_envmap(); + self->texture->env = BKE_add_envmap(); self->texture->env->object= OBACT; } diff --git a/source/blender/python/api2_2x/Types.c b/source/blender/python/api2_2x/Types.c index 6f5bbac6a3a..8eb2ed3c2cb 100644 --- a/source/blender/python/api2_2x/Types.c +++ b/source/blender/python/api2_2x/Types.c @@ -48,6 +48,7 @@ struct PyMethodDef Null_methods[] = { {NULL, NULL, 0, NULL} }; void types_InitAll( void ) { Action_Type.ob_type = &PyType_Type; + Pose_Type.ob_type = &PyType_Type; Armature_Type.ob_type = &PyType_Type; BezTriple_Type.ob_type = &PyType_Type; Bone_Type.ob_type = &PyType_Type; @@ -183,6 +184,8 @@ PyObject *Types_Init( void ) ( PyObject * ) &BezTriple_Type ); PyDict_SetItemString( dict, "ActionType", ( PyObject * ) &Action_Type ); + PyDict_SetItemString( dict, "PoseType", + ( PyObject * ) &Pose_Type ); PyDict_SetItemString( dict, "propertyType", ( PyObject * ) &property_Type ); PyDict_SetItemString( dict, "pointType", diff --git a/source/blender/python/api2_2x/Types.h b/source/blender/python/api2_2x/Types.h index ea8a80a1a98..349c4af545b 100644 --- a/source/blender/python/api2_2x/Types.h +++ b/source/blender/python/api2_2x/Types.h @@ -36,6 +36,7 @@ #include extern PyTypeObject Action_Type, Armature_Type; +extern PyTypeObject Pose_Type; extern PyTypeObject BezTriple_Type, Bone_Type, Button_Type; extern PyTypeObject Camera_Type; extern PyTypeObject CurNurb_Type; diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index 4ad440ee476..01329dd36c4 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -33,15 +33,20 @@ struct View3D; /* keep me up here */ #include "sceneRender.h" /*This must come first*/ -#include "BIF_renderwin.h" #include "DNA_image_types.h" -#include "BIF_drawscene.h" -#include "BLI_blenlib.h" + #include "BKE_image.h" #include "BKE_global.h" + +#include "BIF_drawscene.h" +#include "BIF_renderwin.h" + +#include "BLI_blenlib.h" + +#include "RE_pipeline.h" + #include "mydevice.h" #include "butspace.h" -#include "render.h" /* RE_animrender() */ #include "blendef.h" #include "gen_utils.h" @@ -55,8 +60,6 @@ struct View3D; /* keep me up here */ #define PY_SKYDOME 1 #define PY_FULL 2 -extern RE_Render R; -extern void schrijfplaatje(char *name); extern void waitcursor(int); //---------------------------------------Render prototypes------------- @@ -872,6 +875,7 @@ PyObject *RenderData_Render( BPy_RenderData * self ) } else { /* background mode (blender -b file.blend -P script) */ + Render *re= RE_NewRender("Render"); int end_frame = G.scene->r.efra; /* is of type short currently */ @@ -881,7 +885,7 @@ PyObject *RenderData_Render( BPy_RenderData * self ) G.scene->r.efra = G.scene->r.sfra; - RE_animrender(NULL); + RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); G.scene->r.efra = (short)end_frame; } @@ -907,7 +911,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args ) BLI_strncpy( filepath, self->renderContext->pic, sizeof(filepath) ); strcat(filepath, name_str); - if(!R.rectot) { + if(0) {//!R.rectot) { return EXPP_ReturnPyObjError (PyExc_RuntimeError, "No image rendered"); } else { @@ -917,9 +921,9 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args ) strcpy(G.ima, dir); } - R.r.imtype= G.scene->r.imtype; - R.r.quality= G.scene->r.quality; - R.r.planes= G.scene->r.planes; +// R.r.imtype= G.scene->r.imtype; +// R.r.quality= G.scene->r.quality; +// R.r.planes= G.scene->r.planes; strcpy(strn, filepath); BLI_convertstringcode(strn, G.sce, G.scene->r.cfra); @@ -929,7 +933,7 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args ) } waitcursor(1); - schrijfplaatje(strn); +// schrijfplaatje(strn); strcpy(G.ima, filepath); waitcursor(0); } @@ -948,6 +952,8 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self ) set_scene( oldsce ); } else { /* background mode (blender -b file.blend -P script) */ + Render *re= RE_NewRender("Render"); + if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "scene to render in bg mode must be the active scene"); @@ -955,7 +961,8 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self ) if (G.scene->r.sfra > G.scene->r.efra) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "start frame must be less or equal to end frame"); - RE_animrender(NULL); + + RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); } return EXPP_incr_ret( Py_None ); } @@ -975,7 +982,7 @@ PyObject *RenderData_Play( BPy_RenderData * self ) strcpy( file, self->renderContext->pic ); BLI_convertstringcode( file, (char *) self->scene, self->renderContext->cfra ); - RE_make_existing_file( file ); + BLI_make_existing_file( file ); if( BLI_strcasecmp( file + strlen( file ) - 4, ".mov" ) ) { sprintf( txt, "%04d_%04d.mov", ( self->renderContext->sfra ), @@ -989,7 +996,7 @@ PyObject *RenderData_Play( BPy_RenderData * self ) strcpy( file, self->renderContext->pic ); BLI_convertstringcode( file, G.sce, self->renderContext->cfra ); - RE_make_existing_file( file ); + BLI_make_existing_file( file ); if( BLI_strcasecmp( file + strlen( file ) - 4, ".avi" ) ) { sprintf( txt, "%04d_%04d.avi", ( self->renderContext->sfra ), @@ -998,14 +1005,14 @@ PyObject *RenderData_Play( BPy_RenderData * self ) } } if( BLI_exist( file ) ) { - calc_renderwin_rectangle( G.winpos, pos, size ); + calc_renderwin_rectangle(640, 480, G.winpos, pos, size); sprintf( str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file ); system( str ); } else { - makepicstring( file, self->renderContext->sfra ); + BKE_makepicstring( file, self->renderContext->sfra ); if( BLI_exist( file ) ) { - calc_renderwin_rectangle( G.winpos, pos, size ); + calc_renderwin_rectangle(640, 480, G.winpos, pos, size); sprintf( str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file ); system( str ); diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index 5c59f734345..462ee77cf25 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -34,15 +34,21 @@ #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined(__APPLE__) +#include "DNA_scene_types.h" + #include "BKE_global.h" #include "BKE_scene.h" + #include "BLI_blenlib.h" #include "BIF_toolbox.h" /* error() */ + #include "BLO_sys_types.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" + #include "MEM_guardedalloc.h" -#include "render.h" + #include "quicktime_import.h" #include "quicktime_export.h" @@ -69,10 +75,10 @@ #define kTrackStart 0 #define kMediaStart 0 -static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame); -static void QT_DoAddVideoSamplesToMedia (int frame); +static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame, int rectx, int recty); +static void QT_DoAddVideoSamplesToMedia (int frame, int *pixels, int rectx, int recty); static void QT_EndAddVideoSamplesToMedia (void); -static void QT_CreateMyVideoTrack (void); +static void QT_CreateMyVideoTrack (int rectx, int recty); static void QT_EndCreateMyVideoTrack (void); static void check_renderbutton_framerate(void); @@ -249,7 +255,7 @@ static OSErr QT_AddUserDataTextToMovie (Movie theMovie, char *theText, OSType th } -static void QT_CreateMyVideoTrack(void) +static void QT_CreateMyVideoTrack(int rectx, int recty) { OSErr err = noErr; Rect trackFrame; @@ -257,8 +263,8 @@ static void QT_CreateMyVideoTrack(void) trackFrame.top = 0; trackFrame.left = 0; - trackFrame.bottom = R.recty; - trackFrame.right = R.rectx; + trackFrame.bottom = recty; + trackFrame.right = rectx; qtexport->theTrack = NewMovieTrack (qtexport->theMovie, FixRatio(trackFrame.right,1), @@ -281,7 +287,7 @@ static void QT_CreateMyVideoTrack(void) err = BeginMediaEdits (qtexport->theMedia); CheckError( err, "BeginMediaEdits error" ); - QT_StartAddVideoSamplesToMedia (&trackFrame); + QT_StartAddVideoSamplesToMedia (&trackFrame, rectx, recty); } @@ -303,19 +309,19 @@ static void QT_EndCreateMyVideoTrack(void) } -static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame) +static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame, int rectx, int recty) { OSErr err = noErr; - qtexport->ibuf = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0); - qtexport->ibuf2 = IMB_allocImBuf (R.rectx, R.recty, 32, IB_rect, 0); + qtexport->ibuf = IMB_allocImBuf (rectx, recty, 32, IB_rect, 0); + qtexport->ibuf2 = IMB_allocImBuf (rectx, recty, 32, IB_rect, 0); err = NewGWorldFromPtr( &qtexport->theGWorld, k32ARGBPixelFormat, trackFrame, NULL, NULL, 0, (unsigned char *)qtexport->ibuf->rect, - R.rectx * 4 ); + rectx * 4 ); CheckError (err, "NewGWorldFromPtr error"); qtexport->thePixMap = GetGWorldPixMap(qtexport->theGWorld); @@ -332,7 +338,7 @@ static void QT_StartAddVideoSamplesToMedia (const Rect *trackFrame) } -static void QT_DoAddVideoSamplesToMedia (int frame) +static void QT_DoAddVideoSamplesToMedia (int frame, int *pixels, int rectx, int recty) { OSErr err = noErr; Rect imageRect; @@ -348,7 +354,7 @@ static void QT_DoAddVideoSamplesToMedia (int frame) //copy and flip renderdata - memcpy(qtexport->ibuf2->rect, R.rectot, 4*R.rectx*R.recty); + memcpy(qtexport->ibuf2->rect, pixels, 4*rectx*recty); IMB_flipy(qtexport->ibuf2); //get pointers to parse bitmapdata @@ -359,7 +365,7 @@ static void QT_DoAddVideoSamplesToMedia (int frame) to = (unsigned char *) myPtr; //parse RGBA bitmap into Quicktime's ARGB GWorld - boxsize = R.rectx * R.recty; + boxsize = rectx * recty; for( index = 0; index < boxsize; index++) { to[0] = from[3]; to[1] = from[0]; @@ -415,7 +421,7 @@ void makeqtstring (char *string) { strcpy(string, G.scene->r.pic); BLI_convertstringcode(string, G.sce, G.scene->r.cfra); - RE_make_existing_file(string); + BLI_make_existing_file(string); if (BLI_strcasecmp(string + strlen(string) - 4, ".mov")) { sprintf(txt, "%04d_%04d.mov", (G.scene->r.sfra) , (G.scene->r.efra) ); @@ -424,7 +430,7 @@ void makeqtstring (char *string) { } -void start_qt(void) { +void start_qt(struct RenderData *rd, int rectx, int recty) { OSErr err = noErr; char name[2048]; @@ -446,7 +452,7 @@ void start_qt(void) { qtdata = MEM_callocN(sizeof(QuicktimeComponentData), "QuicktimeCodecDataExt"); - if(G.scene->r.qtcodecdata == NULL && G.scene->r.qtcodecdata->cdParms == NULL) { + if(rd->qtcodecdata == NULL && rd->qtcodecdata->cdParms == NULL) { get_qtcodec_settings(); } else { qtdata->theComponent = OpenDefaultComponent(StandardCompressionType, StandardCompressionSubType); @@ -456,7 +462,7 @@ void start_qt(void) { } if (G.afbreek != 1) { - sframe = (G.scene->r.sfra); + sframe = (rd->sfra); makeqtstring(name); @@ -499,14 +505,14 @@ void start_qt(void) { } else { printf("Created QuickTime movie: %s\n", name); - QT_CreateMyVideoTrack(); + QT_CreateMyVideoTrack(rectx, recty); } } } -void append_qt(int frame) { - QT_DoAddVideoSamplesToMedia(frame); +void append_qt(int frame, int *pixels, int rectx, int recty) { + QT_DoAddVideoSamplesToMedia(frame, pixels, rectx, recty); } diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index 3ecea889fa6..5962ae3d713 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -37,9 +37,10 @@ #define __AIFF__ // quicktime movie output functions +struct RenderData; -void start_qt(void); //for initrender.c -void append_qt(int frame); +void start_qt(struct RenderData *rd, int rectx, int recty); //for movie handle (BKE writeavi.c now) +void append_qt(int frame, int *pixels, int rectx, int recty); void end_qt(void); int get_qtcodec_settings(void); //for buttons.c diff --git a/source/blender/radiosity/SConscript b/source/blender/radiosity/SConscript index 6aef7396fd0..0c7205e6a83 100644 --- a/source/blender/radiosity/SConscript +++ b/source/blender/radiosity/SConscript @@ -18,7 +18,8 @@ rad_env.Append (CPPPATH = ['extern/include', '../makesdna', '../include', '#/intern/guardedalloc', - '../render/extern/include']) + '../render/extern/include', + '../render/intern/include']) rad_env.Append (CPPPATH = user_options_dict['OPENGL_INCLUDE']) diff --git a/source/blender/radiosity/extern/include/radio.h b/source/blender/radiosity/extern/include/radio.h index 81fd9fdda2e..23aa30e3bda 100644 --- a/source/blender/radiosity/extern/include/radio.h +++ b/source/blender/radiosity/extern/include/radio.h @@ -166,7 +166,8 @@ extern void drawpatch_ext(RPatch *patch, unsigned int col); extern void RAD_drawall(int depth_is_on); /* radrender.c */ -extern void do_radio_render(void); +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 index 442e00cb8ed..ae1f1e4f7ee 100644 --- a/source/blender/radiosity/extern/include/radio_types.h +++ b/source/blender/radiosity/extern/include/radio_types.h @@ -41,6 +41,8 @@ #include "DNA_listBase.h" #include "DNA_material_types.h" +struct Render; + #define DTWIRE 0 #define DTGOUR 2 #define DTSOLID 1 @@ -162,6 +164,7 @@ typedef struct { 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; diff --git a/source/blender/radiosity/intern/source/Makefile b/source/blender/radiosity/intern/source/Makefile index fd2ff50ca41..54a3af8e098 100644 --- a/source/blender/radiosity/intern/source/Makefile +++ b/source/blender/radiosity/intern/source/Makefile @@ -57,3 +57,4 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include # third is the external interface. there should be a nicer way to say this CPPFLAGS += -I../include -I../../../include -I../../extern/include CPPFLAGS += -I../../../render/extern/include +CPPFLAGS += -I../../../render/intern/include diff --git a/source/blender/radiosity/intern/source/radfactors.c b/source/blender/radiosity/intern/source/radfactors.c index cbe861fa443..64beea24d23 100644 --- a/source/blender/radiosity/intern/source/radfactors.c +++ b/source/blender/radiosity/intern/source/radfactors.c @@ -53,11 +53,7 @@ #include "BIF_screen.h" #include "radio.h" -#include "render.h" /* for `RE_zbufferall_radio and RE_zbufferall_radio */ - -#ifdef HAVE_CONFIG_H -#include -#endif +#include "RE_render_ext.h" /* for `RE_zbufferall_radio and RE_zbufferall_radio */ /* locals */ void rad_setmatrices(RadView *vw); @@ -290,7 +286,7 @@ void hemizbuf(RadView *vw) int a, b, inda, hres; rad_setmatrices(vw); - RE_zbufferall_radio(vw, RG.elem, RG.totelem); + 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; diff --git a/source/blender/radiosity/intern/source/radio.c b/source/blender/radiosity/intern/source/radio.c index 923ab69db6e..21292e14df3 100644 --- a/source/blender/radiosity/intern/source/radio.c +++ b/source/blender/radiosity/intern/source/radio.c @@ -238,6 +238,8 @@ void set_radglobal() RG.gamma= rad->gamma; RG.maxiter= rad->maxiter; + RG.re= NULL; /* struct render, for when call it from render engine */ + rad_setlimits(); } diff --git a/source/blender/radiosity/intern/source/radrender.c b/source/blender/radiosity/intern/source/radrender.c index 50b9569c09f..ffb896a8c49 100644 --- a/source/blender/radiosity/intern/source/radrender.c +++ b/source/blender/radiosity/intern/source/radrender.c @@ -69,7 +69,11 @@ #include "BIF_screen.h" #include "radio.h" -#include "render.h" + +/* the radiosity module uses internal includes from render! */ +#include "renderpipeline.h" +#include "render_types.h" +#include "renderdatabase.h" #ifdef HAVE_CONFIG_H #include @@ -80,7 +84,7 @@ static float maxenergy; /* find the face with maximum energy to become shooter */ /* nb: _rr means rad-render version of existing radio call */ -static VlakRen *findshoot_rr(void) +static VlakRen *findshoot_rr(Render *re) { RadFace *rf; VlakRen *vlr=NULL, *shoot; @@ -90,8 +94,8 @@ static VlakRen *findshoot_rr(void) shoot= NULL; maxenergy= 0.0; - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; rf->flag &= ~RAD_SHOOT; @@ -116,7 +120,7 @@ static VlakRen *findshoot_rr(void) return shoot; } -static void backface_test_rr(VlakRen *shoot) +static void backface_test_rr(Render *re, VlakRen *shoot) { VlakRen *vlr=NULL; RadFace *rf; @@ -124,8 +128,8 @@ static void backface_test_rr(VlakRen *shoot) int a; /* backface testing */ - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { if(vlr!=shoot) { rf= vlr->radface; @@ -139,15 +143,15 @@ static void backface_test_rr(VlakRen *shoot) } } -static void clear_backface_test_rr() +static void clear_backface_test_rr(Render *re) { VlakRen *vlr=NULL; RadFace *rf; int a; /* backface flag clear */ - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -159,7 +163,7 @@ static void clear_backface_test_rr() extern RadView hemitop, hemiside; // radfactors.c /* hemi-zbuffering, delivers formfactors array */ -static void makeformfactors_rr(VlakRen *shoot) +static void makeformfactors_rr(Render *re, VlakRen *shoot) { VlakRen *vlr=NULL; RadFace *rf; @@ -203,8 +207,8 @@ static void makeformfactors_rr(VlakRen *shoot) /* convert factors to real radiosity */ fp= RG.formfactors; - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -218,7 +222,7 @@ static void makeformfactors_rr(VlakRen *shoot) } /* based at RG.formfactors array, distribute shoot energy over other faces */ -static void applyformfactors_rr(VlakRen *shoot) +static void applyformfactors_rr(Render *re, VlakRen *shoot) { VlakRen *vlr=NULL; RadFace *rf; @@ -231,8 +235,8 @@ static void applyformfactors_rr(VlakRen *shoot) fp= RG.formfactors; - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -263,52 +267,51 @@ static void applyformfactors_rr(VlakRen *shoot) /* main loop for itterations */ -static void progressiverad_rr() +static void progressiverad_rr(Render *re) { - extern void RE_local_timecursor(int); // RE_callbacks.c VlakRen *shoot; float unshot[3]; int it= 0; - shoot= findshoot_rr(); + shoot= findshoot_rr(re); while( shoot ) { /* backfaces receive no energy, but are zbuffered... */ - backface_test_rr(shoot); + backface_test_rr(re, shoot); /* ...unless it's two sided */ if(shoot->radface->flag & RAD_TWOSIDED) { VECCOPY(unshot, shoot->radface->unshot); VecMulf(shoot->radface->norm, -1.0); - makeformfactors_rr(shoot); - applyformfactors_rr(shoot); + makeformfactors_rr(re, shoot); + applyformfactors_rr(re, shoot); VecMulf(shoot->radface->norm, -1.0); VECCOPY(shoot->radface->unshot, unshot); } /* hemi-zbuffers */ - makeformfactors_rr(shoot); + makeformfactors_rr(re, shoot); /* based at RG.formfactors array, distribute shoot energy over other faces */ - applyformfactors_rr(shoot); + applyformfactors_rr(re, shoot); it++; - RE_local_timecursor(it); + re->timecursor(it); - clear_backface_test_rr(); + clear_backface_test_rr(re); if(blender_test_break()) break; if(RG.maxiter && RG.maxiter<=it) break; - shoot= findshoot_rr(); + shoot= findshoot_rr(re); } printf(" Unshot energy:%f\n", 1000.0*maxenergy); - RE_local_timecursor((G.scene->r.cfra)); + re->timecursor((G.scene->r.cfra)); } static RadFace *radfaces=NULL; -static void initradfaces(void) +static void initradfaces(Render *re) { VlakRen *vlr= NULL; RadFace *rf; @@ -323,8 +326,8 @@ static void initradfaces(void) RG.max[0]= RG.max[1]= RG.max[2]= -1.0e20; /* count first for fast malloc */ - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->mat->mode & MA_RADIO) { if(vlr->mat->emit > 0.0) { @@ -339,8 +342,8 @@ printf(" Rad elems: %d emittors %d\n", RG.totelem, RG.totpatch); /* make/init radfaces */ rf=radfaces= MEM_callocN(RG.totelem*sizeof(RadFace), "radfaces"); - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->mat->mode & MA_RADIO) { @@ -399,108 +402,24 @@ static void vecaddfac(float *vec, float *v1, float *v2, float fac) } -#if 0 -/* unused now, doesnt work... */ -static void filter_rad_values(void) -{ - VlakRen *vlr=NULL; - VertRen *v1=NULL; - RadFace *rf; - float n1[3], n2[3], n3[4], n4[3], co[4]; - int a; - - /* one filter pass */ - for(a=0; a>8]; else v1++; - if(v1->accum>0.0) { - v1->rad[0]= v1->rad[0]/v1->accum; - v1->rad[1]= v1->rad[1]/v1->accum; - v1->rad[2]= v1->rad[2]/v1->accum; - v1->accum= 0.0; - } - } - /* cosines in verts accumulate in faces */ - for(a=0; a>8]; else vlr++; - - if(vlr->radface) { - rf= vlr->radface; - - /* calculate cosines of angles, for weighted add (irregular faces) */ - VecSubf(n1, vlr->v2->co, vlr->v1->co); - VecSubf(n2, vlr->v3->co, vlr->v2->co); - Normalise(n1); - Normalise(n2); - - if(vlr->v4==NULL) { - VecSubf(n3, vlr->v1->co, vlr->v3->co); - Normalise(n3); - - co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2])/M_PI; - co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI; - co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI; - co[0]= co[1]= co[2]= 1.0/3.0; - } - else { - VecSubf(n3, vlr->v4->co, vlr->v3->co); - VecSubf(n4, vlr->v1->co, vlr->v4->co); - Normalise(n3); - Normalise(n4); - - co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2])/M_PI; - co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2])/M_PI; - co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2])/M_PI; - co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2])/M_PI; - co[0]= co[1]= co[2]= co[3]= 1.0/4.0; - } - - rf->totrad[0]= rf->totrad[1]= rf->totrad[2]= 0.0; +/* unused now, doesnt work..., find it in cvs of nov 2005 or older */ +/* static void filter_rad_values(void) */ - vecaddfac(rf->totrad, rf->totrad, vlr->v1->rad, co[0]); - vecaddfac(rf->totrad, rf->totrad, vlr->v2->rad, co[1]); - vecaddfac(rf->totrad, rf->totrad, vlr->v3->rad, co[2]); - if(vlr->v4) { - vecaddfac(rf->totrad, rf->totrad, vlr->v4->rad, co[3]); - } - } - } - /* accumulate vertexcolors again */ - for(a=0; a>8]; else vlr++; - - if(vlr->radface) { - rf= vlr->radface; - - vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); - vlr->v1->accum+= rf->area; - vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); - vlr->v2->accum+= rf->area; - vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); - vlr->v3->accum+= rf->area; - if(vlr->v4) { - vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); - vlr->v4->accum+= rf->area; - } - } - } - -} -#endif - -static void make_vertex_rad_values() +static void make_vertex_rad_values(Render *re) { VertRen *v1=NULL; VlakRen *vlr=NULL; RadFace *rf; + 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(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -515,48 +434,57 @@ static void make_vertex_rad_values() if(vlr->mat->g > 0.0) rf->totrad[1]/= vlr->mat->g; if(vlr->mat->b > 0.0) rf->totrad[2]/= vlr->mat->b; - vecaddfac(vlr->v1->rad, vlr->v1->rad, rf->totrad, rf->area); - vlr->v1->accum+= rf->area; - vecaddfac(vlr->v2->rad, vlr->v2->rad, rf->totrad, rf->area); - vlr->v2->accum+= rf->area; - vecaddfac(vlr->v3->rad, vlr->v3->rad, rf->totrad, rf->area); - vlr->v3->accum+= rf->area; + col= RE_vertren_get_rad(re, vlr->v1, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + + col= RE_vertren_get_rad(re, vlr->v2, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + + col= RE_vertren_get_rad(re, vlr->v3, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; + if(vlr->v4) { - vecaddfac(vlr->v4->rad, vlr->v4->rad, rf->totrad, rf->area); - vlr->v4->accum+= rf->area; + col= RE_vertren_get_rad(re, vlr->v4, 1); + vecaddfac(col, col, rf->totrad, rf->area); + col[3]+= rf->area; } } } /* make vertex colors */ - for(a=0; a>8]; else v1++; - if(v1->accum>0.0) { - v1->rad[0]/= v1->accum; - v1->rad[1]/= v1->accum; - v1->rad[2]/= v1->accum; + for(a=0; atotvert; a++) { + if((a & 255)==0) v1= RE_findOrAddVert(re, a); else v1++; + col= RE_vertren_get_rad(re, v1, 0); + if(col[3]>0.0) { + col[0]/= col[3]; + col[1]/= col[3]; + col[2]/= col[3]; } } } /* main call, extern */ -void do_radio_render(void) +void do_radio_render(Render *re) { if(G.scene->radio==NULL) add_radio(); freeAllRad(); /* just in case radio-tool is still used */ set_radglobal(); /* init the RG struct */ - - initradfaces(); /* add radface structs to render faces */ + 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(); /* main radio loop */ + progressiverad_rr(re); /* main radio loop */ - make_vertex_rad_values(); /* convert face energy to vertex ones */ + make_vertex_rad_values(re); /* convert face energy to vertex ones */ } diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 71be91f1be3..256d4b16d86 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -4,27 +4,21 @@ Import ('library_env') render_env = library_env.Copy () -source_files = ['intern/source/RE_callbacks.c', +source_files = ['intern/source/convertblender.c', 'intern/source/edgeRender.c', 'intern/source/envmap.c', - 'intern/source/errorHandler.c', 'intern/source/gammaCorrectionTables.c', 'intern/source/imagetexture.c', 'intern/source/initrender.c', - 'intern/source/jitter.c', 'intern/source/pixelblending.c', 'intern/source/pixelshading.c', + 'intern/source/pipeline.c', 'intern/source/ray.c', - 'intern/source/renderHelp.c', - 'intern/source/renderPreAndPost.c', 'intern/source/rendercore.c', 'intern/source/renderdatabase.c', 'intern/source/shadbuf.c', 'intern/source/texture.c', - 'intern/source/vanillaRenderPipe.c', - 'intern/source/zblur.c', - 'intern/source/zbuf.c', - 'intern/source/zbufferdatastruct.c'] + 'intern/source/zbuf.c'] render_env.Append (CPPPATH = ['intern/include', diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h new file mode 100644 index 00000000000..d34fc968e77 --- /dev/null +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -0,0 +1,169 @@ +/** + * $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): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef RE_PIPELINE_H +#define RE_PIPELINE_H + +#include "DNA_listBase.h" +#include "DNA_vec_types.h" +#include "BKE_utildefines.h" + +struct Scene; +struct RenderData; + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* this include is what is exposed of render to outside world */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + +#define RE_MAXNAME 32 + +/* only used as handle */ +typedef struct Render Render; + +/* Render Result usage: + +- render engine allocates/frees and delivers raw floating point rects +- right now it's full rects, but might become tiles or file +- the display client has to allocate display rects, sort out what to display, + and how it's converted +*/ + +/* a renderlayer is a full image, but with all passes and samples */ +/* size of the rects is defined in RenderResult */ +typedef struct RenderLayer { + struct RenderLayer *next, *prev; + + /* copy of RenderData */ + char name[RE_MAXNAME]; + unsigned int lay; + int layflag, passflag; + + float *rectf; /* standard rgba buffer */ + float *rectz; /* standard camera coordinate zbuffer */ + + ListBase passes; + +} RenderLayer; + +typedef struct RenderResult { + + /* target image size */ + int rectx, recty; + short crop, pad; + + /* optional, 32 bits version of picture, used for ogl render and image curves */ + int *rect32; + /* if this exists, a copy of one of layers, or result of composited layers */ + float *rectf; + /* if this exists, a copy of one of layers, or result of composited layers */ + float *rectz; + + /* coordinates within final image (after cropping) */ + rcti tilerect; + + /* the main buffers */ + ListBase layers; + int actlay; /* copy of renderdata..., so display callbacks can find out */ + + /* optional saved endresult on disk */ + char exrfile[FILE_MAXDIR]; + int filehandle; + +} RenderResult; + +typedef struct RenderStats { + int totface, totvert, tothalo, totlamp, totpart; + short curfield, curblur, curpart, partsdone, convertdone; + double starttime, lastframetime; + +} RenderStats; + +/* *********************** API ******************** */ + +/* the name is used as identifier, so elsewhere in blender the result can retrieved */ +/* calling a new render with same name, frees automatic existing render */ +Render *RE_NewRender (const char *name); +Render *RE_GetRender(const char *name); + +/* use free render as signal to do everything over (previews) */ +void RE_FreeRender (Render *re); +/* only called on exit */ +void RE_FreeAllRender (void); + +/* get results and statistics */ +RenderResult *RE_GetResult(Render *re); +void RE_GetResultImage(Render *re, RenderResult *rr); +RenderStats *RE_GetStats(Render *re); +void RE_ResultGet32(Render *re, unsigned int *rect); + +/* obligatory initialize call, disprect is optional */ +void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect); + +/* use this to change disprect of active render */ +void RE_SetDispRect (struct Render *re, rcti *disprect); + +/* set up the viewplane/perspective matrix, three choices */ +void RE_SetCamera(Render *re, struct Object *camera); +void RE_SetWindow (Render *re, rctf *viewplane, float clipsta, float clipend); +void RE_SetOrtho (Render *re, rctf *viewplane, float clipsta, float clipend); + +/* option to set viewmatrix before making dbase */ +void RE_SetView (Render *re, float mat[][4]); + +/* make or free the dbase */ +void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view); +void RE_Database_Free (Render *re); + +/* project dbase again, when viewplane/perspective changed */ +void RE_DataBase_ApplyWindow(Render *re); + +/* the main processor, assumes all was set OK! */ +void RE_TileProcessor(Render *re); + +/* only RE_NewRender() needed, main Blender render calls */ +void RE_BlenderFrame(Render *re, struct Scene *scene, int frame); +void RE_BlenderAnim(Render *re, struct Scene *scene, int sfra, int efra); + + +/* display and event callbacks */ +void RE_display_init_cb (Render *re, void (*f)(RenderResult *rr)); +void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr)); +void RE_display_draw_cb (Render *re, void (*f)(RenderResult *rr, struct rcti *rect)); +void RE_stats_draw_cb (Render *re, void (*f)(RenderStats *rs)); +void RE_timecursor_cb (Render *re, void (*f)(int)); +void RE_test_break_cb (Render *re, int (*f)(void)); +void RE_test_return_cb (Render *re, int (*f)(void)); +void RE_error_cb (Render *re, void (*f)(const char *str)); + + + + +#endif /* RE_PIPELINE_H */ + diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h new file mode 100644 index 00000000000..b8fc573a9a5 --- /dev/null +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -0,0 +1,49 @@ +/** + * $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 by Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef RE_RENDER_EXT_H +#define RE_RENDER_EXT_H + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* this include is for non-render pipeline exports (still old cruft here) */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* called by meshtools */ +void RE_make_sticky(void); + +/* for radiosity module */ +struct RadView; +struct RNode; +void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); + +/* effect.c and editmesh_modes. */ +void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta); + +#endif /* RE_RENDER_EXT_H */ + diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h new file mode 100644 index 00000000000..84204d88976 --- /dev/null +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -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) 2006 by Blender Foundation + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef RE_SHADER_EXT_H +#define RE_SHADER_EXT_H + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* this include is for shading and texture exports */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* localized texture result data */ +/* note; tr tg tb ta has to remain in this order */ +typedef struct TexResult { + float tin, tr, tg, tb, ta; + int talpha; + float *nor; +} TexResult; + +/* localized shade result data */ +typedef struct ShadeResult +{ + float diff[3]; + float spec[3]; + float alpha; + +} ShadeResult; + +/* localized renderloop data */ +typedef struct ShadeInput +{ + struct Material *mat; + struct VlakRen *vlr; + float co[3]; + + /* copy from material, keep synced so we can do memcopy */ + /* current size: 23*4 */ + float r, g, b; + float specr, specg, specb; + float mirr, mirg, mirb; + float ambr, ambb, ambg; + + float amb, emit, ang, spectra, ray_mirror; + float alpha, refl, spec, zoffs, add; + float translucency; + /* end direct copy from material */ + + /* individual copies: */ + int har; + float layerfac; + + /* texture coordinates */ + float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; + float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3], stress; + + /* dx/dy OSA coordinates */ + float dxco[3], dyco[3]; + float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3]; + float dxref[3], dyref[3], dxorn[3], dyorn[3]; + float dxno[3], dyno[3], dxview, dyview; + float dxlv[3], dylv[3]; + float dxwin[3], dywin[3]; + float dxsticky[3], dysticky[3]; + float dxrefract[3], dyrefract[3]; + float dxstrand, dystrand; + + int xs, ys; /* pixel to be rendered */ + short do_preview; /* for nodes, in previewrender */ + short thread; + short osatex, puno; + int mask; + int depth; + +} ShadeInput; + + +/* node shaders... */ +int multitex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); + + +#endif /* RE_SHADER_EXT_H */ + diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h deleted file mode 100644 index e3eb926192c..00000000000 --- a/source/blender/render/extern/include/render.h +++ /dev/null @@ -1,288 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Interface to transform the Blender scene into renderable data. - */ - -#ifndef RENDER_H -#define RENDER_H - -/* ------------------------------------------------------------------------- */ -/* This little preamble might be moved to a separate include. It contains */ -/* some defines that should become functions, and some platform dependency */ -/* fixes. I think it is risky to always include it... */ -/* ------------------------------------------------------------------------- */ - - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------------------------------------------------------- */ -/* Types */ -/* Both external and internal types can be placed here. Make sure there are */ -/* no dirty extras in the type files so they can be included without */ -/* problems. If possible, make a note why the include is needed. */ -/* ------------------------------------------------------------------------- */ - -#include "render_types.h" - -/* ------------------------------------------------------------------------- */ -/* Global variables */ -/* These variable are global to the render module, and also externally */ -/* visible. The file where they are defined must be added. */ -/* ------------------------------------------------------------------------- */ - -extern RE_Render R; /* rendercore.c */ -extern unsigned short *igamtab1; /* initrender.c */ -extern unsigned short *gamtab; /* initrender.c */ - -struct View3D; - -/* ------------------------------------------------------------------------- */ -/* Function definitions */ -/* */ -/* All functions that need to be externally visible must be declared here. */ -/* Currently, this interface contains 38 functions and 11 callbacks. */ -/* ------------------------------------------------------------------------- */ - - -/* ------------------------------------------------------------------------- */ -/* shadbuf.c (1) */ -/* ------------------------------------------------------------------------- */ - -/* only for renderconvertor */ -void RE_initshadowbuf(struct LampRen *lar, float mat[][4]); - - -/* ------------------------------------------------------------------------- */ -/* initrender (9) */ -/* ------------------------------------------------------------------------- */ - -struct View3D; - -/** - * Guarded call to frame renderer? Tests several limits and boundary - * conditions. - * - * @param ogl_render_area The View3D area to use for OpenGL rendering - * (can be NULL unless render R_OGL flag is set) - */ -void RE_initrender(struct View3D *ogl_render_view3d); - -/** - * only for renderconvertor - */ -void RE_setwindowclip(int mode, int jmode); - -/* - * @param ogl_render_area The View3D area to use for OpenGL rendering - * (can be NULL unless render R_OGL flag is set) - */ -void RE_animrender(struct View3D *ogl_render_view3d); -void RE_free_render_data(void); -void RE_init_render_data(void); - /* jitterate is used by blenkernel effect */ -void RE_jitterate1(float *jit1, float *jit2, int num, float rad1); -void RE_jitterate2(float *jit1, float *jit2, int num, float rad2); -void RE_make_existing_file(char *name); -void RE_floatbuffer_to_output(void); - -/* ------------------------------------------------------------------------- */ -/* zbuf (2) */ -/* ------------------------------------------------------------------------- */ - -/** - * Converts a world coordinate into a homogenous coordinate in view - * coordinates. (WCS -> HCS) - * Also called in: shadbuf.c render.c radfactors.c - * initrender.c envmap.c editmesh.c - * @param v1 [3 floats] the world coordinate - * @param adr [4 floats] the homogenous view coordinate - */ -void RE_projectverto(float *v1,float *adr); - -/** - * Something about doing radiosity z buffering? - * (called in radfactors.c), hope the RadView is defined already... - * Also called in: radfactors.c - * Note: Uses globals. - * @param radview radiosity view definition - */ - struct RadView; - struct RNode; -void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem); - - -/* ------------------------------------------------------------------------- */ -/* texture (9) */ -/* ------------------------------------------------------------------------- */ -struct MTex; -struct Tex; - -void init_render_textures(void); -void end_render_textures(void); -void init_render_texture(struct Tex *tex); -void end_render_texture(struct Tex *tex); - -void do_material_tex(ShadeInput *shi); -void do_lamp_tex(struct LampRen *la, float *lavec, ShadeInput *shi, float *fcol); - -int multitex_ext(struct Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta); -void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta); - -/* ------------------------------------------------------------------------- */ -/* envmap (4) */ -/* ------------------------------------------------------------------------- */ -struct EnvMap; -struct Tex; - -void RE_free_envmapdata(struct EnvMap *env); -void RE_free_envmap(struct EnvMap *env); -struct EnvMap *RE_add_envmap(void); -/* these two maybe not external? yes, they are, for texture.c */ -struct EnvMap *RE_copy_envmap(struct EnvMap *env); - -/* --------------------------------------------------------------------- */ -/* rendercore (12) */ -/* --------------------------------------------------------------------- */ -float Phong_Spec(float *n, float *l, float *v, int hard, int tangent); -float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent); -float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent); -float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent); -float WardIso_Spec(float *n, float *l, float *v, float rms, int tangent); - -float OrenNayar_Diff(float *n, float *l, float *v, float rough); -float Toon_Diff( float *n, float *l, float *v, float size, float smooth); -float Minnaert_Diff( float nl, float *n, float *v, float darkness); - -void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b); -void ramp_diffuse_result(float *diff, ShadeInput *shi); -void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec); -void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi); - - -/* --------------------------------------------------------------------- */ -/* ray.c (2) */ -/* --------------------------------------------------------------------- */ -void init_jitter_plane(LampRen *lar); -void init_ao_sphere(float *sphere, int tot, int iter); - - -/* --------------------------------------------------------------------- */ -/* renderdatabase (3) */ -/* --------------------------------------------------------------------- */ -struct VlakRen *RE_findOrAddVlak(int nr); -struct VertRen *RE_findOrAddVert(int nr); -struct HaloRen *RE_findOrAddHalo(int nr); -HaloRen *RE_inithalo(struct Material *ma, float *vec, float *vec1, float *orco, float hasize, - float vectsize, int seed); - -/** - * callbacks (11): - * - * If the callbacks aren't set, rendering will still proceed as - * desired, but the concerning functionality will not be enabled. - * - * There need to be better uncoupling between the renderer and - * these functions still! - * */ - -void RE_set_test_break_callback(int (*f)(void)); - -void RE_set_timecursor_callback(void (*f)(int)); - -void RE_set_renderdisplay_callback(void (*f)(int, int, int, int, unsigned int *)); -void RE_set_initrenderdisplay_callback(void (*f)(void)); -void RE_set_clearrenderdisplay_callback(void (*f)(short)); - -void RE_set_printrenderinfo_callback(void (*f)(double,int)); - -void RE_set_getrenderdata_callback(void (*f)(void)); -void RE_set_freerenderdata_callback(void (*f)(void)); - - -/*from renderhelp, should disappear!!! */ -/** Recalculate all normals on renderdata. */ -void set_normalflags(void); -/** - * On loan from zbuf.h: - * Tests whether the first three coordinates should be clipped - * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on - * y, 5 and 6 test on z: - * xyz > test => set first bit (01), - * xyz < -test => set second bit (10), - * xyz == test => reset both bits (00). - * Note: functionality is duplicated from an internal function - * Also called in: initrender.c, radfactors.c - * @param v [4 floats] a coordinate - * @return a vector of bitfields - */ -int RE_testclip(float *v); - -/* patch for the external if, to support the split for the ui */ -void RE_addalphaAddfac(char *doel, char *bron, char addfac); -void RE_sky_char(float *view, char *col); -void RE_renderflare(struct HaloRen *har); -/** - * Shade the pixel at xn, yn for halo har, and write the result to col. - * Also called in: previewrender.c - * @param har The halo to be rendered on this location - * @param col [char 4] The destination colour vector - * @param colf [float 4] destination colour vector (need both) - * @param zz Some kind of distance - * @param dist Square of the distance of this coordinate to the halo's center - * @param x [f] Pixel x relative to center - * @param y [f] Pixel y relative to center - * @param flarec Flare counter? Always har->flarec... - */ -void RE_shadehalo(struct HaloRen *har, - char *col, float *colf, - int zz, - float dist, - float x, - float y, - short flarec); - -/***/ - -/* haloren->type: flags */ - -#define HA_ONLYSKY 1 -#define HA_VECT 2 -#define HA_XALPHA 4 -#define HA_FLARECIRC 8 - -#ifdef __cplusplus -} -#endif - -#endif /* RENDER_H */ - diff --git a/source/blender/render/intern/include/RE_callbacks.h b/source/blender/render/intern/include/RE_callbacks.h deleted file mode 100644 index 159eaa84ca4..00000000000 --- a/source/blender/render/intern/include/RE_callbacks.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Callbacks to make the renderer interact with calling modules. - */ - -#ifndef RE_CALLBACKS_H -#define RE_CALLBACKS_H - -#ifdef __cplusplus -extern "C" { -#endif - - /** - * Test whether operation should be prematurely terminated. - * - * @returns 0 to continue, any other value to break. - */ - int RE_local_test_break(void); - - /** - * Set a red square with the argument as text as cursor. - */ - void RE_local_timecursor(int i); - - /** - * Render these lines from the renderbuffer on screen (needs better spec) - */ - void RE_local_render_display(int i, int j, int k, int l, unsigned int *m); - - /** - * Initialise a render display (needs better spec) - */ - void RE_local_init_render_display(void); - - /** - * Clear/close a render display (needs better spec) - */ - void RE_local_clear_render_display(short); - - /** - * Print render statistics. - */ - void RE_local_printrenderinfo(double time, int i); - - /** Get the data for the scene to render. */ - void RE_local_get_renderdata(void); - - /** Release the data for the scene that was rendered. */ - void RE_local_free_renderdata(void); - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index 7a44a139b20..32d72555ca4 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -41,10 +41,11 @@ * (initrender.c) */ +struct Render; struct TexResult; -void make_envmaps(void); -int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +void make_envmaps(struct Render *re); +int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); #endif /* ENVMAP_EXT_H */ diff --git a/source/blender/render/intern/include/errorHandler.h b/source/blender/render/intern/include/errorHandler.h deleted file mode 100644 index fb980fa255a..00000000000 --- a/source/blender/render/intern/include/errorHandler.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * errorHandler.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef ERRORHANDLER_H -#define ERRORHANDLER_H - -/* error codes */ -enum RE_RENDER_ERROR { - RE_NO_ERROR, - RE_DEPTH_MISMATCH, /* 1. conflict resolution detects a bad z value */ - RE_BAD_FACE_TYPE, /* 2. a face type switch fails */ - RE_BAD_FACE_INDEX, /* 3. tried to do an operation with a bad index */ - RE_BAD_DATA_POINTER, - RE_TRACE_COUNTER, - RE_TOO_MANY_FACES, /* 6. overflow on z-buffer depth */ - RE_EDGERENDER_WRITE_OUTSIDE_BUFFER, /* 7. write value outside buffer */ - RE_CANNOT_ALLOCATE_MEMORY, /* 8. no memory for malloc */ - RE_WRITE_OUTSIDE_COLOUR_BUFFER, /* 9. write outside colour target buffer */ - RE_MAX_ERROR -}; - -/** - * Reset all counters for the error trace - */ -void RE_errortrace_reset(void); - -/** - * Signals an error to screen. Counts repetitive errors - */ -void RE_error(int errType, char* fname); - -/** - * Signals an error, and prints an integer argument - */ -void RE_error_int(int errType, char* fname, int valye); - -#endif /* ERRORHANDLER_H */ - diff --git a/source/blender/render/intern/include/gammaCorrectionTables.h b/source/blender/render/intern/include/gammaCorrectionTables.h index 6197f769f6f..3d0928f84a3 100644 --- a/source/blender/render/intern/include/gammaCorrectionTables.h +++ b/source/blender/render/intern/include/gammaCorrectionTables.h @@ -35,25 +35,11 @@ #ifndef GAMMACORRECTIONTABLES_H #define GAMMACORRECTIONTABLES_H -/* Default gamma. For most CRTs, gamma ranges from 2.2 to 2.5 (Foley), so */ -/* 2.35 seems appropriate enough. Experience teaches a different number */ -/* though. Old blender: 2.0. It might be nice to make this a slider */ -#define RE_DEFAULT_GAMMA 2.0 -/* This 400 is sort of based on the number of intensity levels needed for */ -/* the typical dynamic range of a medium, in this case CRTs. (Foley) */ -/* (Actually, it says the number should be between 400 and 535.) */ -#define RE_GAMMA_TABLE_SIZE 400 - /** * Initialise the gamma lookup tables */ void makeGammaTables(float gamma); -/** - * Returns true if the table is initialised, false otherwise - */ -int gammaTableIsInitialised(void); - /** * Apply gamma correction on col */ @@ -64,10 +50,5 @@ float gammaCorrect(float col); */ float invGammaCorrect(float col); -/** - * Tell whether or not to do gamma. - */ -extern int do_gamma; - #endif diff --git a/source/blender/render/intern/include/initrender.h b/source/blender/render/intern/include/initrender.h index 15ec3eb69a3..9a94d193990 100644 --- a/source/blender/render/intern/include/initrender.h +++ b/source/blender/render/intern/include/initrender.h @@ -32,19 +32,21 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifndef INITRENDER_EXT_H -#define INITRENDER_EXT_H +#ifndef INITRENDER_H +#define INITRENDER_H -/* type includes */ - -#include "DNA_effect_types.h" /* for PartEff type */ -#include "render_types.h" +struct Object; /* Functions */ -void schrijfplaatje(char *name); -void render(void); /* Switch between the old and the unified renderer. */ -/* void write_screendump(char *name); not here !*/ +void free_sample_tables(Render *re); +void make_sample_tables(Render *re); -#endif /* INITRENDER_EXT_H */ +void render_scene_set_window(Render *re, struct Object *camera, int blursample); + +void initparts(Render *re); +void freeparts(Render *re); + + +#endif /* INITRENDER_H */ diff --git a/source/blender/render/intern/include/pixelblending.h b/source/blender/render/intern/include/pixelblending.h index b82642a34d0..bc44c916701 100644 --- a/source/blender/render/intern/include/pixelblending.h +++ b/source/blender/render/intern/include/pixelblending.h @@ -1,18 +1,12 @@ /* - * pixelblending_ext.h - * external interface for pixelblending - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,9 +20,7 @@ * 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. + * Contributor(s): 2004-2006 Blender Foundation, full recode * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -36,41 +28,12 @@ #ifndef PIXELBLENDING_EXT_H #define PIXELBLENDING_EXT_H -/* local includes */ -#include "vanillaRenderPipe_types.h" - -/** - * Halo-add pixel, bring your own R.osa setting, and add factor - */ -void addAddSampColF(float *s, float *d, int m, int osa, char add); - -/** - * Alpha undersamples pixel, bring your own R.osa setting - */ -int addUnderSampColF(float *sampcol, float *dest, int mask, int osaNr); - -/** - * Alpha oversample pixel, bring your own R.osa setting - */ -void addOverSampColF(float *sampcol, float *dest, int mask, int osaNr); /** * add 1 pixel to into filtered three lines * (float vecs to float vec) */ -void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float *rb3); - -/** - * Convert a series of oversampled pixels into filtered three lines - * (float vecs to float vec) - */ -void sampleFloatColV2FloatColVFilter(float *sample, float *dest1, float *dest2, float *dest3, int osaNr); - -/** - * Convert a series of oversampled pixels into a single pixel. Uses R.osa to - * count the length! (short vecs to short vec) - */ -void sampleShortColV2ShortColV(unsigned short *sample, unsigned short *dest, int osaNr); +void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w); /** * Alpha-over blending for floats. @@ -82,50 +45,6 @@ void addAlphaOverFloat(float *dest, float *source); */ void addAlphaUnderFloat(float *dest, float *source); -/** - * Write a 16-bit-colour colour vector to a 8-bit-colour colour vector. - */ -void cpShortColV2CharColV(unsigned short *source, char *dest); - -/** - * Write a 8-bit-colour colour vector to a 16-bit-colour colour vector. - */ -void cpCharColV2ShortColV(char *source, unsigned short *dest); - -/** - * Write a 32-bit-colour colour vector to a 8-bit-colour colour vector. - */ -void cpIntColV2CharColV(unsigned int *source, char *dest); - -/** - * Write a floating-point-colour colour vector to a 8-bit-colour colour - * vector. Clip colours to [0, 1]. - */ -void cpFloatColV2CharColV(float *source, char *dest); - -/** - * Cpoy a 8-bit-colour vector to floating point colour vector. - */ -void cpCharColV2FloatColV(char *source, float *dest); -/** - * Cpoy a 16-bit-colour vector to floating point colour vector. - */ -void cpShortColV2FloatColV(unsigned short *source, float *dest); - -/** - * Copy a float-colour colour vector. - */ -void cpFloatColV(float *source, float *dest); - -/** - * Copy a 16-bit-colour colour vector. - */ -void cpShortColV(unsigned short *source, unsigned short *dest); - -/** - * Copy an 8-bit-colour colour vector. - */ -void cpCharColV(char *source, char *dest); /** * Same for floats @@ -137,26 +56,20 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac); */ void addalphaAddFloat(float *dest, float *source); -/** ols functions: side effects? -void addalphaUnderFloat(char *doel, char *bron); think this already exists... -void addalphaUnderGammaFloat(char *doel, char *bron); -*/ /** * Blend bron under doel, while doing gamma correction */ void addalphaUnderGammaFloat(float *doel, float *bron); /** - * Transform an premul-alpha 32-bit colour into a key-alpha 32-bit colour. +* Copy the colour buffer output to R.rectot, to line y. */ -void applyKeyAlphaCharCol(char* target); +void transferColourBufferToOutput(float *buf, int y); +/** +* using default transforms for brightness, gamma, hue, saturation etc. + */ +void std_floatcol_to_charcol(float *buf, char *target); -/* Old blending functions */ -void keyalpha(char *doel); /* maakt premul 255 */ -void addalphaUnder(char *doel, char *bron); -void addalphaUnderGamma(char *doel, char *bron); -void addalphaOver(char *doel, char *bron); -void addalphaAdd(char *doel, char *bron); #endif /* PIXELBLENDING_EXT_H */ diff --git a/source/blender/render/intern/include/pixelshading.h b/source/blender/render/intern/include/pixelshading.h index 6b9e13c069f..67b0e5bcf3c 100644 --- a/source/blender/render/intern/include/pixelshading.h +++ b/source/blender/render/intern/include/pixelshading.h @@ -1,19 +1,12 @@ /* - * pixelshading.h - * - * These functions determine what actual colour a pixel will have. - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,19 +20,20 @@ * 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): 2004-2006, Blender Foundation, full recode * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ +/* pixelshading.h +* +* These functions determine what actual colour a pixel will have. +*/ + + #ifndef PIXELSHADING_H #define PIXELSHADING_H -#include "render.h" -#include "vanillaRenderPipe_types.h" - /** * Render the pixel at (x,y) for object ap. Apply the jitter mask. * Output is given in float collector[4]. The type vector: @@ -51,31 +45,17 @@ * mask is pixel coverage in bits * @return pointer to the object */ -void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *t, int mask); - - -void setSkyBlendingMode(enum RE_SkyAlphaBlendingType mode); - void shadeHaloFloat(HaloRen *har, float *col, int zz, float dist, float xn, float yn, short flarec); -/** - * Get the sky blending mode. - */ -enum RE_SkyAlphaBlendingType getSkyBlendingMode(void); /** * Render the sky at pixel (x, y). */ -void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y); - -/* used by shadeSkyPixel: */ -void shadeSkyPixelFloat(float *colf, float *view, float *dxyview); -void renderSpotHaloPixel(float x, float y, float *target); -void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy); -void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y); -void fillBackgroundImageChar(char *col, float x, float y); +void renderSkyPixelFloat(float *collector, float x, float y, float *rco); +void shadeSkyPixel(float *collector, float fx, float fy, float *rco); +void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview); /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/include/renderHelp.h b/source/blender/render/intern/include/renderHelp.h deleted file mode 100644 index 318b538d510..00000000000 --- a/source/blender/render/intern/include/renderHelp.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * renderhelp_ext.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef RENDERHELP_EXT_H -#define RENDERHELP_EXT_H - -#ifdef __cplusplus -extern "C" { -#endif - - /* Push-pop, because this sometimes is necessary... */ - void pushTempPanoPhi(float p); - void popTempPanoPhi(void); - - float getPanoPhi(void); - float getPanovCo(void); - float getPanovSi(void); - void setPanoRot(int part); - - /** Set clip flags on all data entries, using the given projection - * function */ - void setzbufvlaggen( void (*projectfunc)(float *, float *) ); - -/* external for the time being, since the converter calls it. */ -/** Recalculate all normals on renderdata. */ -/* void set_normalflags(void); */ - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/source/blender/render/extern/include/render_types.h b/source/blender/render/intern/include/render_types.h similarity index 52% rename from source/blender/render/extern/include/render_types.h rename to source/blender/render/intern/include/render_types.h index 3a09ba133ef..c73deca6d22 100644 --- a/source/blender/render/extern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,149 +20,158 @@ * 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): (c) 2006 Blender Foundation, full refactor * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #ifndef RENDER_TYPES_H #define RENDER_TYPES_H +/* ------------------------------------------------------------------------- */ +/* exposed internal in render module only! */ +/* ------------------------------------------------------------------------- */ + #include "DNA_scene_types.h" #include "DNA_world_types.h" #include "DNA_object_types.h" +#include "DNA_vec_types.h" + +#include "RE_pipeline.h" +#include "RE_shader_ext.h" /* TexResult, ShadeResult, ShadeInput */ + +struct MemArena; +struct VertTableNode; +struct Octree; +struct GHash; #define TABLEINITSIZE 1024 #define LAMPINITSIZE 256 -/* This is needed to not let VC choke on near and far... old - * proprietary MS extensions... */ -#ifdef WIN32 -#undef near -#undef far -#define near clipsta -#define far clipend -#endif - -/* ------------------------------------------------------------------------- */ - -/* localized texture result data */ -typedef struct TexResult { - float tin, tr, tg, tb, ta; - int talpha; - float *nor; -} TexResult; - -/* localized renderloop data */ -typedef struct ShadeInput +typedef struct SampleTables { - struct Material *mat; - struct VlakRen *vlr; - float co[3]; + float centLut[16]; + float *fmask1[9], *fmask2[9]; + char cmask[256], *centmask; - /* copy from material, keep synced so we can do memcopy */ - /* current size: 23*4 */ - float r, g, b; - float specr, specg, specb; - float mirr, mirg, mirb; - float ambr, ambb, ambg; - - float amb, emit, ang, spectra, ray_mirror; - float alpha, refl, spec, zoffs, add; - float translucency; - /* end direct copy from material */ - - /* individual copies: */ - int har; - - /* texture coordinates */ - float lo[3], gl[3], uv[3], ref[3], orn[3], winco[3], sticky[3], vcol[3], rad[3]; - float vn[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3]; - - /* dx/dy OSA coordinates */ - float dxco[3], dyco[3]; - float dxlo[3], dylo[3], dxgl[3], dygl[3], dxuv[3], dyuv[3]; - float dxref[3], dyref[3], dxorn[3], dyorn[3]; - float dxno[3], dyno[3], dxview, dyview; - float dxlv[3], dylv[3]; - float dxwin[3], dywin[3]; - float dxsticky[3], dysticky[3]; - float dxrefract[3], dyrefract[3]; - float dxstrand, dystrand; - - float xs, ys; /* pixel to be rendered */ - short osatex, puno; - int mask; - int depth; - -} ShadeInput; +} SampleTables; -struct MemArena; - -/* here only stuff to initalize the render itself */ -typedef struct RE_Render +/* this is handed over to threaded hiding/passes/shading engine */ +typedef struct RenderPart { - float grvec[3]; - float imat[3][3]; + struct RenderPart *next, *prev; + + /* result of part rendering */ + RenderResult *result; + + unsigned int *rectp; /* polygon index table */ + int *rectz; /* zbuffer */ + long *rectdaps; /* delta acum buffer for pixel structs */ + + rcti disprect; /* part coordinates within total picture */ + int rectx, recty; /* the size */ + short crop, ready; /* crop is amount of pixels we crop, for filter */ + short sample, nr; /* sample can be used by zbuffers, nr is partnr */ + short thread; /* thread id */ + +} RenderPart; +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; +} Octree; + + +/* controls state of render, everything that's read-only during render stage */ +struct Render +{ + struct Render *next, *prev; + char name[RE_MAXNAME]; + + /* state settings */ + short flag, osa, ok, do_gamma; + + /* result of rendering */ + RenderResult *result; + + /* window size, display rect, viewplane */ + int winx, winy; + rcti disprect; /* part within winx winy */ + rctf viewplane; /* mapped on winx winy */ + float viewdx, viewdy; /* size of 1 pixel */ + + /* final picture width and height (within disprect) */ + int rectx, recty; + + /* correction values for pixels or view */ + float ycor, viewfac; + float bluroffsx, bluroffsy; + float panosi, panoco; + + /* Matrices */ + float grvec[3]; /* for world */ + float imat[3][3]; /* copy of viewinv */ float viewmat[4][4], viewinv[4][4]; - float persmat[4][4], persinv[4][4]; float winmat[4][4]; - short flag, osa, rt, pad; - /** - * Screen sizes and positions, in pixels - */ - short xstart, xend, ystart, yend, afmx, afmy; - short rectx; /* Picture width - 1, normally xend - xstart. */ - short recty; /* picture height - 1, normally yend - ystart. */ - - /** - * Distances and sizes in world coordinates nearvar, farvar were - * near and far, but VC in cpp mode chokes on it :( */ - float near; /* near clip distance */ - float far; /* far clip distance */ - float ycor, pixsize, viewfac; - - - /* These three need to be 'handlerized'. Not an easy task... */ -/* RE_RenderDataHandle r; */ + /* clippping */ + float clipsta; + float clipend; + + /* samples */ + SampleTables *samples; + float jit[32][2]; + + /* scene, and its full copy of renderdata and world */ + Scene *scene; RenderData r; World wrld; + ListBase parts; + /* octree tables and variables for raytrace */ + Octree oc; + + /* use this instead of R.r.cfra */ + float cfra; + + /* render database */ int totvlak, totvert, tothalo, totlamp; - - /* internal, fortunately */ - struct LampRen **la; - struct VlakRen **blovl; - struct VertRen **blove; + ListBase lights; + + int vertnodeslen; + struct VertTableNode *vertnodes; + int blohalen; struct HaloRen **bloha; + int blovllen; + struct VlakRen **blovl; + + struct GHash *orco_hash; /* arena for allocating data for use during render, for - * example dynamic TFaces to go in the VlakRen structure. - */ + * example dynamic TFaces to go in the VlakRen structure. + */ struct MemArena *memArena; - - int *rectaccu; - int *rectz; /* z buffer: distance buffer */ - unsigned int *rectf1, *rectf2; - unsigned int *rectot; /* z buffer: face index buffer, recycled as colour buffer! */ - unsigned int *rectspare; /* */ - /* for 8 byte systems! */ - long *rectdaps; - float *rectftot; /* original full color buffer */ - short win, winpos, winx, winy, winxof, winyof; - short winpop, displaymode, sparex, sparey; - - /* Not sure what these do... But they're pointers, so good for handlerization */ - struct Image *backbuf, *frontbuf; - /* backbuf is an image that drawn as background */ + /* callbacks */ + void (*display_init)(RenderResult *rr); + void (*display_clear)(RenderResult *rr); + void (*display_draw)(RenderResult *rr, rcti *rect); -} RE_Render; + void (*stats_draw)(RenderStats *ri); + void (*timecursor)(int i); + + int (*test_break)(void); + int (*test_return)(void); + void (*error)(const char *str); + + RenderStats i; +}; /* ------------------------------------------------------------------------- */ @@ -176,7 +182,7 @@ typedef struct ShadBuf { float viewmat[4][4]; float winmat[4][4]; float *jit; - float d,far,pixsize,soft; + float d,clipend,pixsize,soft; int co[3]; int size,bias; long *zbuf; @@ -190,13 +196,11 @@ typedef struct VertRen float co[3]; float n[3]; float ho[4]; - float rad[3]; /* result radio rendering */ float *orco; - float *sticky; - void *svert; /* smooth vert, only used during initrender */ - short clip, texofs; /* texofs= flag */ - float accum; /* accum for radio weighting, and for strand texco static particles */ - short flag; /* in use for clipping ztra parts */ + short clip; + unsigned short flag; /* in use for clipping zbuffer parts, temp setting stuff in convertblender.c */ + float accum; /* accum for radio weighting, and for strand texco static particles */ + int index; /* index allows extending vertren with any property */ } VertRen; /* ------------------------------------------------------------------------- */ @@ -220,7 +224,6 @@ typedef struct VlakRen { struct VertRen *v1, *v2, *v3, *v4; unsigned int lay; - unsigned int raycount; float n[3]; struct Material *mat; struct TFace *tface; @@ -231,8 +234,6 @@ typedef struct VlakRen Object *ob; } VlakRen; -/* vlakren->flag is in DNA_scene_types.h */ - typedef struct HaloRen { short miny, maxy; @@ -313,6 +314,34 @@ typedef struct LampRen struct MTex *mtex[MAX_MTEX]; } LampRen; +/* **************** defines ********************* */ + +/* mode flag is same as for renderdata */ +/* flag */ +#define R_ZTRA 1 +#define R_HALO 2 +#define R_SEC_FIELD 4 +#define R_LAMPHALO 8 +#define R_RENDERING 16 +#define R_ANIMRENDER 32 +#define R_REDRAW_PRV 64 + +/* vlakren->flag (vlak = face in dutch) char!!! */ +#define R_SMOOTH 1 +#define R_VISIBLE 2 +/* strand flag, means special handling */ +#define R_STRAND 4 +#define R_NOPUNOFLIP 8 +#define R_FULL_OSA 16 +#define R_FACE_SPLIT 32 +/* Tells render to divide face other way. */ +#define R_DIVIDE_24 64 +/* vertex normals are tangent or view-corrected vector, for hair strands */ +#define R_TANGENT 128 + + + + #endif /* RENDER_TYPES_H */ diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 5163b85d8c0..cfdf34c205b 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -46,13 +46,7 @@ struct HaloRen; struct ShadeInput; -typedef struct ShadeResult -{ - float diff[3]; - float spec[3]; - float alpha; - -} ShadeResult; +/* ------------------------------------------------------------------------- */ typedef struct PixStr { @@ -61,14 +55,15 @@ typedef struct PixStr unsigned short mask, amount; } PixStr; -/* ------------------------------------------------------------------------- */ - typedef struct PixStrMain { + struct PixStrMain *next, *prev; struct PixStr *ps; - struct PixStrMain *next; + int counter; } PixStrMain; +/* ------------------------------------------------------------------------- */ + void calc_view_vector(float *view, float x, float y); float mistfactor(float zcor, float *co); /* dist and height, return alpha */ @@ -82,34 +77,30 @@ void shade_lamp_loop(struct ShadeInput *shi, ShadeResult *shr); float fresnel_fac(float *view, float *vn, float fresnel, float fac); void calc_R_ref(struct ShadeInput *shi); -float spec(float inp, int hard); + +/* for nodes */ +void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); + +void zbufshade(void); +void zbufshadeDA(void); /* Delta Accum Pixel Struct */ + +void *shadepixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *col, float *rco); + +int count_mask(unsigned short mask); + +void zbufshade_tile(struct RenderPart *pa); +void zbufshadeDA_tile(struct RenderPart *pa); /* -------- ray.c ------- */ +extern void freeoctree(Render *re); +extern void makeoctree(Render *re); + extern void ray_shadow(ShadeInput *, LampRen *, float *); extern void ray_trace(ShadeInput *, ShadeResult *); -extern void ray_ao(ShadeInput *, World *, float *); - -/** - * Do z buffer and shade - */ -void zbufshade(void); - -/** - * zbuffer and shade, anti aliased - */ -void zbufshadeDA(void); /* Delta Accum Pixel Struct */ - -/** - * Also called in: zbuf.c - */ -void *shadepixel(float x, float y, int z, int facenr, int mask, float *col); - -/** - * A cryptic but very efficient way of counting the number of bits that - * is set in the unsigned short. - */ -int count_mask(unsigned short mask); +extern void ray_ao(ShadeInput *, float *); +extern void init_jitter_plane(LampRen *lar); +extern void init_ao_sphere(float *sphere, int tot, int iter); #endif /* RENDER_EXT_H */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h new file mode 100644 index 00000000000..6996bca7a5c --- /dev/null +++ b/source/blender/render/intern/include/renderdatabase.h @@ -0,0 +1,69 @@ +/** + * $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): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef RENDERDATABASE_H +#define RENDERDATABASE_H + +struct VlakRen; +struct VertRen; +struct HaloRen; +struct Material; +struct Render; + +/* renderdatabase.c */ +void free_renderdata_tables(struct Render *re); +void set_normalflags(Render *re); +void project_renderdata(struct Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int part); + +/* functions are not exported... so wrong names */ + +struct VlakRen *RE_findOrAddVlak(struct Render *re, int nr); +struct VertRen *RE_findOrAddVert(struct Render *re, int nr); +struct HaloRen *RE_findOrAddHalo(struct Render *re, int nr); +struct HaloRen *RE_inithalo(struct Render *re, struct Material *ma, float *vec, float *vec1, float *orco, float hasize, + float vectsize, int seed); + +float *RE_vertren_get_sticky(struct Render *re, struct VertRen *ver, int verify); +float *RE_vertren_get_stress(struct Render *re, struct VertRen *ver, int verify); +float *RE_vertren_get_rad(struct Render *re, struct VertRen *ver, int verify); +float *RE_vertren_get_strand(struct Render *re, struct VertRen *ver, int verify); +float *RE_vertren_get_tangent(struct Render *re, struct VertRen *ver, int verify); + +/* haloren->type: flags */ +#define HA_ONLYSKY 1 +#define HA_VECT 2 +#define HA_XALPHA 4 +#define HA_FLARECIRC 8 + + +void init_render_world(Render *re); + + +#endif /* RENDERDATABASE_H */ + diff --git a/source/blender/render/intern/include/renderPreAndPost.h b/source/blender/render/intern/include/renderpipeline.h similarity index 57% rename from source/blender/render/intern/include/renderPreAndPost.h rename to source/blender/render/intern/include/renderpipeline.h index 59315868010..5ccb2f318dc 100644 --- a/source/blender/render/intern/include/renderPreAndPost.h +++ b/source/blender/render/intern/include/renderpipeline.h @@ -1,17 +1,12 @@ -/* - * renderpreandpost.h - * +/** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,22 +17,25 @@ * 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. + * The Original Code is Copyright (C) 2006 Blender Foundation. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ -#ifndef RENDERPREANDPOST_H -#define RENDERPREANDPOST_H +#ifndef PIPELINE_H +#define PIPELINE_H -void prepareScene(void); -void finalizeScene(void); -void doClipping( void (*projectfunc)(float *, float *) ); +struct Render; -#endif +void *RE_mallocN(int len, char *name); +void *RE_callocN(int len, char *name); +void RE_freeN(void *poin); + + +#endif /* PIPELINE_H */ diff --git a/source/blender/render/intern/include/shadbuf.h b/source/blender/render/intern/include/shadbuf.h index 279d5319b21..16127537975 100644 --- a/source/blender/render/intern/include/shadbuf.h +++ b/source/blender/render/intern/include/shadbuf.h @@ -41,7 +41,7 @@ * Calculates shadowbuffers for a vector of shadow-giving lamps * @param lar The vector of lamps */ -void makeshadowbuf(LampRen *lar); +void makeshadowbuf(struct Render *re, LampRen *lar); /** * Determines the shadow factor for a face and lamp. There is some diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 525f8455aa2..9eb4f16a60d 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -55,7 +55,12 @@ struct Image; /* texture.h */ void do_halo_tex(struct HaloRen *har, float xn, float yn, float *colf); -void do_sky_tex(float *lo, float *dxyview, float *hor, float *zen, float *blend); +void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend); +void do_material_tex(struct ShadeInput *shi); +void do_lamp_tex(LampRen *la, float *lavec, struct ShadeInput *shi, float *colf); + +void init_render_textures(void); + void render_realtime_texture(struct ShadeInput *shi); /* imagetexture.h */ diff --git a/source/blender/render/intern/include/vanillaRenderPipe.h b/source/blender/render/intern/include/vanillaRenderPipe.h deleted file mode 100644 index f242b8522fc..00000000000 --- a/source/blender/render/intern/include/vanillaRenderPipe.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * vanillaRenderPipe_ext.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef VANILLARENDERPIPE_EXT_H -#define VANILLARENDERPIPE_EXT_H - -#include "vanillaRenderPipe_types.h" - -/** - * Render pipeline with all kinds of extras. - * status-------------------------\/ - * - integrated z buffering ok - * - integrated halo rendering ok - */ -void zBufShadeAdvanced(void); - -/** - * Copy the colour buffer output to R.rectot, to line y. - */ -void transferColourBufferToOutput(float *buf, int y); -/** - * using default transforms for brightness, gamma, hue, saturation etc. - */ -void std_floatcol_to_charcol(float *buf, char *target); - - -#endif /* VANILLARENDERPIPE_EXT_H */ - diff --git a/source/blender/render/intern/include/vanillaRenderPipe_types.h b/source/blender/render/intern/include/vanillaRenderPipe_types.h deleted file mode 100644 index df24ed01f5e..00000000000 --- a/source/blender/render/intern/include/vanillaRenderPipe_types.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * vanillaRenderPipe_types.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef VANILLARENDERPIPE_TYPES_H -#define VANILLARENDERPIPE_TYPES_H - -/* Render defines */ -#define RE_MAX_OSA_COUNT 16 /* The max. number of possible oversamples */ -#define RE_MAX_FACES_PER_PIXEL 1000 /* max. nr of faces rendered behind one */ - /* pixel */ - -enum RE_SkyAlphaBlendingType { - RE_ALPHA_NODEF = 0, - RE_ALPHA_PREMUL, - RE_ALPHA_KEY, - RE_ALPHA_SKY, - RE_ALPHA_MAX -}; - - -/* Render typedefs */ -typedef float RE_COLBUFTYPE; /* datatype for the colour buffer */ - - -/** - * Threshold for add-blending for faces - */ -#define RE_FACE_ADD_THRESHOLD 0.001 - -/** - For oversampling - - New stack: the old stack limits our freedom to do all kinds of - manipulation, so we rewrite it. - - A stacked face needs: - - a face type - - a colour - - a conflict count - - a data pointer (void*) - - a mask - - The stack starts at index 0, with the closest face, and stacks up. - -*/ - -struct RE_faceField { - int faceType; - float colour[4]; - int conflictCount; - void *data; - int mask; -}; - -#endif /* VANILLARENDERPIPE_TYPES_H */ - diff --git a/source/blender/render/intern/include/zblur.h b/source/blender/render/intern/include/zblur.h deleted file mode 100644 index a0e1c6a39ce..00000000000 --- a/source/blender/render/intern/include/zblur.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef ZBLUR_H -#define ZBLUR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*-----------------------------------------------------------*/ -/* Includes */ -/*-----------------------------------------------------------*/ - -/*-----------------------------------------------------------*/ -/* Function */ -/*-----------------------------------------------------------*/ - -void add_zblur(void); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 394e38be47e..82455088565 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -1,18 +1,12 @@ /* - * zbuf_ext.h - * external interface for zbuf.h - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,7 +20,7 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * Full recode: 2004-2006 Blender Foundation * * Contributor(s): none yet. * @@ -36,158 +30,68 @@ #ifndef ZBUF_H #define ZBUF_H -#ifdef __cplusplus -extern "C" { -#endif - +struct RenderPart; +struct RenderLayer; struct LampRen; struct VlakRen; +struct ListBase; -/*-----------------------------------------------------------*/ -/* Includes */ -/*-----------------------------------------------------------*/ - -#include "zbuf_types.h" -#include "render_types.h" -#include "radio_types.h" /* for RadView */ - -/*-----------------------------------------------------------*/ -/* Function */ -/* (11 so far ) */ -/*-----------------------------------------------------------*/ - -/** - * Fill a 'rectangle' with a fixed value. The rectangle contains x by - * y points. The rows are assumed to be contiguous in memory, and to - * consist of uints. This function is used for initializing the z - * buffer. - * (why is x int and y uint? called in envmap, render, zbuf) - * @param rect Pointer to the data representing the rectangle. - * @param x The width of the rectangle - * @param y The height of the rectangle - * @param val The value used to fill the rectangle. - */ void fillrect(int *rect, int x, int y, int val); /** * Converts a world coordinate into a homogenous coordinate in view - * coordinates. The transformation matrix is only allowed to have a - * scaling and translation component. - * Also called in: shadbuf.c render.c radfactors.c - * initrender.c envmap.c editmesh.c - * @param v1 [3 floats] the world coordinate - * @param adr [4 floats] the homogenous view coordinate + * coordinates. */ -void projectvert(float *v1,float *adr); +void projectvert(float *v1, float winmat[][4], float *adr); +void projectverto(float *v1, float winmat[][4], float *adr); +int testclip(float *v); +void set_part_zbuf_clipflag(struct RenderPart *pa); +void zbuffer_shadow(struct Render *re, struct LampRen *lar, int *rectz, int size); +void zbuffer_solid(struct RenderPart *pa, unsigned int layer, short layflag); +void zbuffer_transp_shade(struct RenderPart *pa, float *pass, unsigned int layer, short layflag); +void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl); -/** - * Do a z buffer calculation pass for shadow calculations. - * Also called in: shadbuf.c - * Note: Uses globals. - * @param lar lamp definition data - */ -void zbuffershad(struct LampRen *lar); +typedef struct APixstr { + unsigned short mask[4]; /* jitter mask */ + int z[4]; /* distance */ + int p[4]; /* index */ + struct APixstr *next; +} APixstr; - /* to the external interface, temp, I hope... */ -/** - * Tests whether the first three coordinates should be clipped - * wrt. the fourth component. Bits 1 and 2 test on x, 3 and 4 test on - * y, 5 and 6 test on z: - * xyz > test => set first bit (01), - * xyz < -test => set second bit (10), - * xyz == test => reset both bits (00). - * Note: functionality is duplicated from an internal function - * Also called in: initrender.c, radfactors.c - * @param v [4 floats] a coordinate - * @return a vector of bitfields - */ -/* int testclip(float *v); */ +typedef struct APixstrMain +{ + struct APixstrMain *next, *prev; + struct APixstr *ps; +} APixstrMain; - -/* The following are only used in zbuf.c and render.c ---------------*/ -/** - * Fills the entire in the alpha DA buffer. (All of it!) - * Note: Uses globals. - * Also called in: render.c - * @param y the line number to set - */ -void abufsetrow(float *acolrow, int y); - - -/** - * Calculate the z buffer for all faces (or edges when in wireframe - * mode) presently visible. - * Note: Uses globals. - * Also called in: render.c - */ -void zbufferall(void); - - -/** - * Initialize accumulation buffers for alpha z buffering. - * The buffers are global variables. Also resets Accu buffer - * y bounds. - *
  • - * Acolrow : colour buffer for one line - * Arectz : distance buffer for one line, depth ABUFPART - * APixbuf : pixel data buffer for one line, depth ABUFPART - *
  • - * Also called in: render.c (should migrate) - * Note: Uses globals. - */ -void bgnaccumbuf(void); - -/** - * Discard accumulation buffers for alpha z buffering. - * The buffers are global variables. The released buffers are Acolrow, - * Arectz, APixBuf. - * Also called in: render.c (should migrate) - * Note: Uses globals. - */ -void endaccumbuf(void); - -/** - * Z face intersect? - */ -int vergzvlak(const void *x1, const void *x2); - -/** - * Clip and fill vertex into the z buffer. zbuffunc needs to be set - * before entering, to assure that there is a buffer fill function - * that can be called. Zvlnr must be set to the current valid face - * index . - * Note: uses globals - * @param f1 [4 floats] vertex 1 - * @param f2 [4 floats] vertex 2 - * @param f3 [4 floats] vertex 3 - * @param c1 clip conditions? - * @param c2 - * @param c3 - */ - -/* span fill in method */ +/* span fill in method, is also used to localize data for zbuffering */ typedef struct ZSpan { - int yres, miny, maxy; /* range for clipping */ + int rectx, recty; /* range for clipping */ + int miny1, maxy1, miny2, maxy2; /* actual filled in range */ float *minp1, *maxp1, *minp2, *maxp2; /* vertex pointers detect min/max range in */ float *span1, *span2; + + float zmulx, zmuly, zofsx, zofsy; /* transform from hoco to zbuf co */ + + int *rectz, *arectz; /* zbuffers, arectz is for transparant */ + int *rectp; /* polygon index buffer */ + APixstr *apixbuf, *curpstr; /* apixbuf for transparent */ + struct ListBase *apsmbase; + + int polygon_offset; /* offset in Z */ + int mask, apsmcounter; /* in use by apixbuf */ + + void (*zbuffunc)(struct ZSpan *, int, float *, float *, float *, float *); + void (*zbuflinefunc)(struct ZSpan *, int, float *, float *); + } ZSpan; -void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3); - -/* These function pointers are used for z buffer filling. */ -extern void (*zbuffunc)(struct ZSpan *zspan, int, float *, float *, float *); -extern void (*zbuflinefunc)(int, float *, float *); - -/** - * same, for edges - */ -void zbufclipwire(int zvlnr, struct VlakRen *vlr); - -#ifdef __cplusplus -} -#endif +/* exported for evil edge render... */ +void zbufclip(struct ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3); +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty); +void zbufclipwire(ZSpan *zspan, int zvlnr, struct VlakRen *vlr); #endif diff --git a/source/blender/render/intern/include/zbufferdatastruct.h b/source/blender/render/intern/include/zbufferdatastruct.h deleted file mode 100644 index 2cef53dc9f6..00000000000 --- a/source/blender/render/intern/include/zbufferdatastruct.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * zbufferdatastruct_ext.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef ZBUFFERDATASTRUCT_EXT_H -#define ZBUFFERDATASTRUCT_EXT_H - -#include "zbufferdatastruct_types.h" - -/** - * Set memory and counters for a fresh z buffer - */ -void initZbuffer(int linewidth); - -/** - * Release memory for the current z buffer - */ -void freeZbuffer(void); - -/** - * Release previous buffer and initialise new buffer. - */ -void resetZbuffer(void); - -/** - * Make a root for a memory block (internal) - */ -RE_APixstrExt *addpsemainA(void); - -/** - * Release a memory chunk - */ -void freepseA(void); - -/** - * Add a structure - */ -RE_APixstrExt *addpseA(void); - -/** - * Add an object to a zbuffer entry. - */ -void insertObject(int teller, - int obindex, - int obtype, - int dist, - int mask); - -/** - * Add a flat object to a zbuffer entry. - */ -void insertFlatObject(RE_APixstrExt* ap, - int obindex, - int obtype, - int dist, - int mask); - -/** - * Add a flat object to a zbuffer entry, but don't do OSA entry testing. - */ -void insertFlatObjectNoOsa(RE_APixstrExt* ap, - int obindex, - int obtype, - int dist, - int mask); - -#endif - diff --git a/source/blender/render/intern/include/zbufferdatastruct_types.h b/source/blender/render/intern/include/zbufferdatastruct_types.h deleted file mode 100644 index 5048adfa8bc..00000000000 --- a/source/blender/render/intern/include/zbufferdatastruct_types.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * zbufferdatastruct_types.h - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -#ifndef ZBUFFERDATASTRUCT_TYPES_H -#define ZBUFFERDATASTRUCT_TYPES_H - -#define RE_ZBUFLEN 64 /* number of lines in the accumulation buffer */ - -/** - * Primitive data structure for zbuffering. One struct - * stores data for 4 entries. This struct has been extended - * for the render pipeline overhaul. - */ -typedef struct RE_APixstrExt { - unsigned short mask[4]; /* jitter masks */ - int zmin[4]; /* min. distance of all samples */ - int zmax[4]; /* max. distance of all samples */ - int p[4]; /* index */ - int t[4]; /* entry type: ZB_POLY or ZB_HALO */ - struct RE_APixstrExt *next; -} RE_APixstrExt; - -/* For now I'll stick to the Blender convention of hand made defines */ -/* but this should definitely be done in a better way. An enum may */ -/* be some help, but masking is still a nice feature... */ -/* object types to buffer in the z buffer */ -/* RE_SOLID is flag for RE_POLY, as speedup */ -#define RE_NONE 0 -#define RE_POLY 1 -#define RE_HALO 2 -#define RE_SKY 4 -#define RE_SOLID 8 - -/* unique indices for each field */ -#define RE_ZMIN 0 -#define RE_INDEX 1 -#define RE_MASK 2 -#define RE_TYPE 3 -#define RE_ZMAX 4 -#define RE_PIXELFIELDSIZE 5 - -typedef struct RE_APixstrExtMain -{ - struct RE_APixstrExt *ps; - struct RE_APixstrExtMain *next; -} RE_APixstrExtMain; - -#endif - diff --git a/source/blender/render/intern/source/RE_callbacks.c b/source/blender/render/intern/source/RE_callbacks.c deleted file mode 100644 index acc115b2b87..00000000000 --- a/source/blender/render/intern/source/RE_callbacks.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Callbacks to make the renderer interact with calling modules. - */ - -#include /* for NULL??? */ -#include -#include "render.h" -#include "RE_callbacks.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* - * The callbacks are done in three parts: - * - * - a local static pointer to the eventual function. NULL if not - * defined, or if the behaviour is not required. - * - * - a hook that can be called locally - * - * - a hook that can be called externally, to set an external function - * to provide said functionality. - * - * These might be generated from a spec such as: - * - * callback { - * local = - * external = - * type = (,...) - * } - * - * Should generate: - * - a static var - * - an internal loop, plus decl. - * - an external setter, plus decl. - * - */ - -/* Part 1: ------------------------------------------------------------- */ - -static int (*RE_local_test_break_function)(void) = NULL; - -static void (*RE_local_timecursor_function)(int) = NULL; - -static void (*RE_local_renderdisplay_function)(int i, - int j, - int k, - int l, - unsigned int *m) - = NULL; - -static void (*RE_local_initrenderdisplay_function)(void) = NULL; -static void (*RE_local_clearrenderdisplay_function)(short) = NULL; - -static void (*RE_local_printrenderinfo_function)(double,int) = NULL; - -static void (*RE_local_getrenderdata_function)(void) = NULL; -static void (*RE_local_freerenderdata_function)(void) = NULL; - -/* Part 2: ------------------------------------------------------------- */ - -int RE_local_test_break(void) { - if (RE_local_test_break_function) { - return RE_local_test_break_function(); - } else { - /* transparant behaviour: proceed */ - return 0; - } -} - -void RE_local_timecursor(int i) { - if (RE_local_timecursor_function) RE_local_timecursor_function(i); -} - -void RE_local_render_display(int i, int j, int k, int l, unsigned int* m) { - if (RE_local_renderdisplay_function) RE_local_renderdisplay_function(i, j, k, l, m); - else { - if(j-i >= l-1) printf("\n");// full picture - else printf("\rRender %d%% ", (100*i)/l); - fflush(stdout); - } -} -void RE_local_init_render_display(void) { - if (RE_local_initrenderdisplay_function) RE_local_initrenderdisplay_function(); -} -void RE_local_clear_render_display(short i) { - if (RE_local_clearrenderdisplay_function) RE_local_clearrenderdisplay_function(i); -} - -void RE_local_printrenderinfo(double time, int i) { - if (RE_local_printrenderinfo_function) RE_local_printrenderinfo_function(time, i); -} - -void RE_local_get_renderdata(void) { - if (RE_local_getrenderdata_function) RE_local_getrenderdata_function(); -} -void RE_local_free_renderdata(void) { - if (RE_local_freerenderdata_function) RE_local_freerenderdata_function(); -} - -/* Part 3: ------------------------------------------------------------- */ - -void RE_set_test_break_callback(int (*f)(void)) { - RE_local_test_break_function = f; -} - -void RE_set_timecursor_callback(void (*f)(int)) { - RE_local_timecursor_function = f; -} - -void RE_set_renderdisplay_callback(void (*f)(int i, - int j, - int k, - int l, - unsigned int *)) -{ - RE_local_renderdisplay_function = f; -} - -void RE_set_initrenderdisplay_callback(void (*f)(void)) { - RE_local_initrenderdisplay_function = f; -} - -void RE_set_clearrenderdisplay_callback(void (*f)(short)) { - RE_local_clearrenderdisplay_function = f; -} - -void RE_set_printrenderinfo_callback(void (*f)(double,int)) { - RE_local_printrenderinfo_function = f; -} - -void RE_set_getrenderdata_callback(void (*f)(void)) { - RE_local_getrenderdata_function = f; -} - -void RE_set_freerenderdata_callback(void (*f)(void)) { - RE_local_freerenderdata_function = f; -} diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c new file mode 100644 index 00000000000..76f4b11fe7b --- /dev/null +++ b/source/blender/render/intern/source/convertblender.c @@ -0,0 +1,3108 @@ +/** + * $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. + * + * Contributors: 2004/2005/2006 Blender Foundation, full recode + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include +#include + +#include "blendef.h" +#include "MTC_matrixops.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_rand.h" +#include "BLI_memarena.h" +#include "BLI_ghash.h" + +#include "DNA_armature_types.h" +#include "DNA_camera_types.h" +#include "DNA_material_types.h" +#include "DNA_curve_types.h" +#include "DNA_effect_types.h" +#include "DNA_group_types.h" +#include "DNA_lamp_types.h" +#include "DNA_lattice_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_meta_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_scene_types.h" +#include "DNA_texture_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_anim.h" +#include "BKE_armature.h" +#include "BKE_action.h" +#include "BKE_curve.h" +#include "BKE_constraint.h" +#include "BKE_displist.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_key.h" +#include "BKE_ipo.h" +#include "BKE_lattice.h" +#include "BKE_material.h" +#include "BKE_main.h" +#include "BKE_mball.h" +#include "BKE_mesh.h" +#include "BKE_node.h" +#include "BKE_object.h" +#include "BKE_scene.h" +#include "BKE_subsurf.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" +#include "BKE_world.h" + +#include "envmap.h" +#include "render_types.h" +#include "rendercore.h" +#include "renderdatabase.h" +#include "renderpipeline.h" +#include "radio.h" +#include "shadbuf.h" +#include "texture.h" +#include "zbuf.h" + +#include "YafRay_Api.h" + +/* yafray: Identity transform 'hack' removed, exporter now transforms vertices back to world. + * Same is true for lamp coords & vec. + * Duplicated data objects & dupliframe/duplivert objects are only stored once, + * only the matrix is stored for all others, in yafray these objects are instances of the original. + * The main changes are in RE_rotateBlenderScene(). + */ + +/* ------------------------------------------------------------------------- */ +/* Local functions */ +/* ------------------------------------------------------------------------- */ +static short test_for_displace(Render *re, Object *ob); +static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert ); + +/* ------------------------------------------------------------------------- */ +/* tool functions/defines for ad hoc simplification and possible future + cleanup */ +/* ------------------------------------------------------------------------- */ + +#define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v)) +/* + +NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !! + +^ ()----p4----p3----() +| | | | | +u | | F1 | F2 | + | | | | + ()----p1----p2----() + v -> +*/ + +/* ------------------------------------------------------------------------- */ + +static VertRen *duplicate_vertren(Render *re, VertRen *ver) +{ + VertRen *v1= RE_findOrAddVert(re, re->totvert++); + int index= v1->index; + *v1= *ver; + v1->index= index; + return v1; +} + +static void split_v_renderfaces(Render *re, int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv) +{ + int vLen = vsize-1+(!!cyclv); + int v; + + for (v=0; vv2); + + if (cyclv) { + vlr->v2 = vert; + + if (v==vLen-1) { + VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + 0); + vlr->v1 = vert; + } else { + VlakRen *vlr = RE_findOrAddVlak(re, startvlak + vLen*uIndex + v+1); + vlr->v1 = vert; + } + } else { + vlr->v2 = vert; + + if (vv1 = vert; + } + + if (v==0) { + vlr->v1 = duplicate_vertren(re, vlr->v1); + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +static int contrpuntnormr(float *n, float *puno) +{ + float inp; + + inp=n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2]; + if(inp<0.0) return 1; + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2) +{ + float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco); + float *acc; + + acc= accum + 2*v1->index; + acc[0]+= len; + acc[1]+= 1.0f; + + acc= accum + 2*v2->index; + acc[0]+= len; + acc[1]+= 1.0f; +} + +static void calc_edge_stress(Render *re, Mesh *me, int startvert, int startvlak) +{ + float loc[3], size[3], *accum, *acc, *accumoffs, *stress; + int a; + + if(startvert==re->totvert) return; + + mesh_get_texspace(me, loc, NULL, size); + + accum= MEM_callocN(2*sizeof(float)*(re->totvert-startvert), "temp accum for stress"); + + /* de-normalize orco */ + for(a=startvert; atotvert; a++, acc+=2) { + VertRen *ver= RE_findOrAddVert(re, a); + if(ver->orco) { + ver->orco[0]= ver->orco[0]*size[0] +loc[0]; + ver->orco[1]= ver->orco[1]*size[1] +loc[1]; + ver->orco[2]= ver->orco[2]*size[2] +loc[2]; + } + } + + /* add stress values */ + accumoffs= accum - 2*startvert; /* so we can use vertex index */ + for(a=startvlak; atotvlak; a++) { + VlakRen *vlr= RE_findOrAddVlak(re, a); + + if(vlr->v1->orco && vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3); + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1); + if(vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4); + calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4); + } + } + } + + for(a=startvert; atotvert; a++) { + VertRen *ver= RE_findOrAddVert(re, a); + if(ver->orco) { + /* find stress value */ + acc= accumoffs + 2*ver->index; + if(acc[1]!=0.0f) + acc[0]/= acc[1]; + stress= RE_vertren_get_stress(re, ver, 1); + *stress= *acc; + + /* restore orcos */ + ver->orco[0] = (ver->orco[0]-loc[0])/size[0]; + ver->orco[1] = (ver->orco[1]-loc[1])/size[1]; + ver->orco[2] = (ver->orco[2]-loc[2])/size[2]; + } + } + + MEM_freeN(accum); +} + +static void calc_tangent_vector(Render *re, VlakRen *vlr, float fac1, float fac2, float fac3, float fac4) +{ + TFace *tface= vlr->tface; + + if(tface) { + VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4; + float *uv1= tface->uv[0], *uv2= tface->uv[1], *uv3= tface->uv[2], *uv4= tface->uv[3]; + float tang[3], *tav; + float s1, s2, t1, t2, det; + + /* we calculate quads as two triangles, so weight for diagonal gets halved */ + if(v4) { + fac1*= 0.5f; + fac3*= 0.5f; + } + + /* first tria, we use the V now */ + s1= uv2[0] - uv1[0]; + s2= uv3[0] - uv1[0]; + t1= uv2[1] - uv1[1]; + t2= uv3[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v2->co[0]) - t1 * (v1->co[0]-v3->co[0])); + tang[1]= (t2 * (v1->co[1]-v2->co[1]) - t1 * (v1->co[1]-v3->co[1])); + tang[2]= (t2 * (v1->co[2]-v2->co[2]) - t1 * (v1->co[2]-v3->co[2])); + + tav= RE_vertren_get_tangent(re, v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(re, v2, 1); + VECADDFAC(tav, tav, tang, fac2); + tav= RE_vertren_get_tangent(re, v3, 1); + VECADDFAC(tav, tav, tang, fac3); + + if(v4) { + /* 2nd tria, we use the V now */ + s1= uv3[0] - uv1[0]; + s2= uv4[0] - uv1[0]; + t1= uv3[1] - uv1[1]; + t2= uv4[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v3->co[0]) - t1 * (v1->co[0]-v4->co[0])); + tang[1]= (t2 * (v1->co[1]-v3->co[1]) - t1 * (v1->co[1]-v4->co[1])); + tang[2]= (t2 * (v1->co[2]-v3->co[2]) - t1 * (v1->co[2]-v4->co[2])); + + Normalise(tang); + + tav= RE_vertren_get_tangent(re, v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(re, v3, 1); + VECADDFAC(tav, tav, tang, fac3); + tav= RE_vertren_get_tangent(re, v4, 1); + VECADDFAC(tav, tav, tang, fac4); + } + } +} + +static void calc_vertexnormals(Render *re, int startvert, int startvlak, int do_tangent) +{ + int a; + + /* clear all vertex normals */ + for(a=startvert; atotvert; a++) { + VertRen *ver= RE_findOrAddVert(re, a); + ver->n[0]=ver->n[1]=ver->n[2]= 0.0; + } + + /* calculate cos of angles and point-masses, use as weight factor to + add face normal to vertex */ + for(a=startvlak; atotvlak; a++) { + VlakRen *vlr= RE_findOrAddVlak(re, a); + if(vlr->flag & ME_SMOOTH) { + VertRen *adrve1= vlr->v1; + VertRen *adrve2= vlr->v2; + VertRen *adrve3= vlr->v3; + VertRen *adrve4= vlr->v4; + float n1[3], n2[3], n3[3], n4[3]; + float fac1, fac2, fac3, fac4=0.0f; + + VecSubf(n1, adrve2->co, adrve1->co); + Normalise(n1); + VecSubf(n2, adrve3->co, adrve2->co); + Normalise(n2); + if(adrve4==NULL) { + VecSubf(n3, adrve1->co, adrve3->co); + Normalise(n3); + + fac1= saacos(-n1[0]*n3[0]-n1[1]*n3[1]-n1[2]*n3[2]); + fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + } + else { + VecSubf(n3, adrve4->co, adrve3->co); + Normalise(n3); + VecSubf(n4, adrve1->co, adrve4->co); + Normalise(n4); + + fac1= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]); + fac2= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]); + fac3= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]); + fac4= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]); + + if(!(vlr->flag & R_NOPUNOFLIP)) { + if( contrpuntnormr(vlr->n, adrve4->n) ) fac4= -fac4; + } + + adrve4->n[0] +=fac4*vlr->n[0]; + adrve4->n[1] +=fac4*vlr->n[1]; + adrve4->n[2] +=fac4*vlr->n[2]; + } + + if(!(vlr->flag & R_NOPUNOFLIP)) { + if( contrpuntnormr(vlr->n, adrve1->n) ) fac1= -fac1; + if( contrpuntnormr(vlr->n, adrve2->n) ) fac2= -fac2; + if( contrpuntnormr(vlr->n, adrve3->n) ) fac3= -fac3; + } + + adrve1->n[0] +=fac1*vlr->n[0]; + adrve1->n[1] +=fac1*vlr->n[1]; + adrve1->n[2] +=fac1*vlr->n[2]; + + adrve2->n[0] +=fac2*vlr->n[0]; + adrve2->n[1] +=fac2*vlr->n[1]; + adrve2->n[2] +=fac2*vlr->n[2]; + + adrve3->n[0] +=fac3*vlr->n[0]; + adrve3->n[1] +=fac3*vlr->n[1]; + adrve3->n[2] +=fac3*vlr->n[2]; + + if(do_tangent) + calc_tangent_vector(re, vlr, fac1, fac2, fac3, fac4); + } + } + + /* do solid faces */ + for(a=startvlak; atotvlak; a++) { + VlakRen *vlr= RE_findOrAddVlak(re, a); + if((vlr->flag & ME_SMOOTH)==0) { + float *f1= vlr->v1->n; + if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n); + f1= vlr->v2->n; + if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n); + f1= vlr->v3->n; + if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n); + if(vlr->v4) { + f1= vlr->v4->n; + if(f1[0]==0.0 && f1[1]==0.0 && f1[2]==0.0) VECCOPY(f1, vlr->n); + } + } + } + + /* normalise vertex normals */ + for(a=startvert; atotvert; a++) { + VertRen *ver= RE_findOrAddVert(re, a); + Normalise(ver->n); + if(do_tangent) { + float *tav= RE_vertren_get_tangent(re, ver, 0); + if(tav) Normalise(tav); + } + } + + /* vertex normal (puno) switch flags for during render */ + for(a=startvlak; atotvlak; a++) { + VlakRen *vlr= RE_findOrAddVlak(re, a); + + if((vlr->flag & R_NOPUNOFLIP)==0) { + VertRen *adrve1= vlr->v1; + VertRen *adrve2= vlr->v2; + VertRen *adrve3= vlr->v3; + VertRen *adrve4= vlr->v4; + vlr->puno &= ~15; + if ((vlr->n[0]*adrve1->n[0]+vlr->n[1]*adrve1->n[1]+vlr->n[2]*adrve1->n[2])<0.0) vlr->puno= 1; + if ((vlr->n[0]*adrve2->n[0]+vlr->n[1]*adrve2->n[1]+vlr->n[2]*adrve2->n[2])<0.0) vlr->puno+= 2; + if ((vlr->n[0]*adrve3->n[0]+vlr->n[1]*adrve3->n[1]+vlr->n[2]*adrve3->n[2])<0.0) vlr->puno+= 4; + if(adrve4) { + if((vlr->n[0]*adrve4->n[0]+vlr->n[1]*adrve4->n[1]+vlr->n[2]*adrve4->n[2])<0.0) vlr->puno+= 8; + } + } + } +} + +/* ------------------------------------------------------------------------- */ +/* Autosmoothing: */ +/* ------------------------------------------------------------------------- */ + +typedef struct ASvert { + int totface; + ListBase faces; +} ASvert; + +typedef struct ASface { + struct ASface *next, *prev; + VlakRen *vlr[4]; + VertRen *nver[4]; +} ASface; + +static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr) +{ + ASface *asf; + int a; + + if(v1 == NULL) return; + + if(asv->faces.first==NULL) { + asf= MEM_callocN(sizeof(ASface), "asface"); + BLI_addtail(&asv->faces, asf); + } + + asf= asv->faces.last; + for(a=0; a<4; a++) { + if(asf->vlr[a]==NULL) { + asf->vlr[a]= vlr; + asv->totface++; + break; + } + } + + /* new face struct */ + if(a==4) { + asf= MEM_callocN(sizeof(ASface), "asface"); + BLI_addtail(&asv->faces, asf); + asf->vlr[0]= vlr; + asv->totface++; + } +} + +static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) +{ + /* return 1: vertex needs a copy */ + ASface *asf; + float inp; + int a; + + if(vlr==0) return 0; + + asf= asv->faces.first; + while(asf) { + for(a=0; a<4; a++) { + if(asf->vlr[a] && asf->vlr[a]!=vlr) { + inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] ); + if(inp < thresh) return 1; + } + } + asf= asf->next; + } + + return 0; +} + +static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) +{ + /* return when new vertex already was made */ + ASface *asf; + float inp; + int a; + + asf= asv->faces.first; + while(asf) { + for(a=0; a<4; a++) { + if(asf->vlr[a] && asf->vlr[a]!=vlr) { + /* this face already made a copy for this vertex! */ + if(asf->nver[a]) { + inp= fabs( vlr->n[0]*asf->vlr[a]->n[0] + vlr->n[1]*asf->vlr[a]->n[1] + vlr->n[2]*asf->vlr[a]->n[2] ); + if(inp >= thresh) { + return asf->nver[a]; + } + } + } + } + asf= asf->next; + } + + return NULL; +} + +static void autosmooth(Render *re, int startvert, int startvlak, int degr) +{ + ASvert *asv, *asverts, *asvertoffs; + ASface *asf; + VertRen *ver, *v1; + VlakRen *vlr; + float thresh; + int a, b, totvert; + + if(startvert==re->totvert) return; + asverts= MEM_callocN(sizeof(ASvert)*(re->totvert-startvert), "all smooth verts"); + asvertoffs= asverts-startvert; /* se we can use indices */ + + thresh= cos( M_PI*((float)degr)/180.0 ); + + /* step one: construct listbase of all vertices and pointers to faces */ + for(a=startvlak; atotvlak; a++) { + vlr= RE_findOrAddVlak(re, a); + + as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr); + as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr); + as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr); + if(vlr->v4) + as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr); + } + + /* we now test all vertices, when faces have a normal too much different: they get a new vertex */ + totvert= re->totvert; + for(a=startvert, asv=asverts; atotface>1) { + ver= RE_findOrAddVert(re, a); + + asf= asv->faces.first; + while(asf) { + for(b=0; b<4; b++) { + + /* is there a reason to make a new vertex? */ + vlr= asf->vlr[b]; + if( as_testvertex(vlr, ver, asv, thresh) ) { + + /* already made a new vertex within threshold? */ + v1= as_findvertex(vlr, ver, asv, thresh); + if(v1==NULL) { + /* make a new vertex */ + v1= duplicate_vertren(re, ver); + } + asf->nver[b]= v1; + if(vlr->v1==ver) vlr->v1= v1; + if(vlr->v2==ver) vlr->v2= v1; + if(vlr->v3==ver) vlr->v3= v1; + if(vlr->v4==ver) vlr->v4= v1; + } + } + asf= asf->next; + } + } + } + + /* free */ + for(a=0; aorco_hash) + re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + + orco = BLI_ghash_lookup(re->orco_hash, ob); + + if (!orco) { + if (ob->type==OB_MESH) { + orco = mesh_create_orco_render(ob); + } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { + orco = make_orco_curve(ob); + } else if (ob->type==OB_SURF) { + orco = make_orco_surf(ob); + } + + if (orco) + BLI_ghash_insert(re->orco_hash, ob, orco); + } + + return orco; +} + +static void free_mesh_orco_hash(Render *re) +{ + if (re->orco_hash) { + BLI_ghash_free(re->orco_hash, NULL, (GHashValFreeFP)MEM_freeN); + re->orco_hash = NULL; + } +} + +/* ******************** END ORCO HASH ***************** */ + + +static void make_render_halos(Render *re, Object *ob, Mesh *me, int totvert, MVert *mvert, Material *ma, float *orco) +{ + HaloRen *har; + float xn, yn, zn, nor[3], view[3]; + 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); + + re->flag |= R_HALO; + + for(a=0; ahasize; + + VECCOPY(vec, mvert->co); + MTC_Mat4MulVecfl(mat, vec); + + if(ma->mode & MA_HALOPUNO) { + xn= mvert->no[0]; + yn= mvert->no[1]; + zn= mvert->no[2]; + + /* transpose ! */ + nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(nor); + + VECCOPY(view, vec); + Normalise(view); + + zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; + if(zn>=0.0) hasize= 0.0; + else hasize*= zn*zn*zn*zn; + } + + if(orco) har= RE_inithalo(re, ma, vec, NULL, orco, hasize, 0.0, seed); + else har= RE_inithalo(re, ma, vec, NULL, mvert->co, hasize, 0.0, seed); + if(har) har->lay= ob->lay; + } + if(orco) orco+= 3; + seed++; + } +} + +/* ------------------------------------------------------------------------- */ +static Material *give_render_material(Render *re, Object *ob, int nr) +{ + extern Material defmaterial; /* material.c */ + Material *ma; + + ma= give_current_material(ob, nr); + if(ma==NULL) + ma= &defmaterial; + else + if(ma->mode & MA_ZTRA) + re->flag |= R_ZTRA; + + return ma; +} + + + +static void render_particle_system(Render *re, Object *ob, PartEff *paf) +{ + Particle *pa=0; + HaloRen *har=0; + Material *ma=0; + float xn, yn, zn, imat[3][3], tmat[4][4], mat[4][4], hasize, stime, ptime, ctime, vec[3], vec1[3], view[3], nor[3]; + int a, mat_nr=1, seed; + + pa= paf->keys; + if(pa==NULL || paf->disp!=100) { + build_particle_system(ob); + pa= paf->keys; + if(pa==NULL) return; + } + + ma= give_render_material(re, ob, paf->omat); + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */ + + /* enable duplicators to work */ + Mat4MulMat4(tmat, paf->imat, ob->obmat); + MTC_Mat4MulMat4(mat, tmat, re->viewmat); + + MTC_Mat4Invert(tmat, mat); + MTC_Mat3CpyMat4(imat, tmat); + + re->flag |= R_HALO; + + if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; + else ptime= 0.0; + ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime); + seed= ma->seed1; + + for(a=0; atotpart; a++, pa+=paf->totkey, seed++) { + + /* offset time for calculating normal */ + stime= ctime; + ptime= ctime+1.0f; + if(ctime < pa->time) { + if(paf->flag & PAF_UNBORN) + ptime= pa->time+1.0f; + else + continue; + } + if(ctime > pa->time+pa->lifetime) { + if(paf->flag & PAF_DIED) + stime= pa->time+pa->lifetime-1.0f; + else + continue; + } + + /* watch it: also calculate the normal of a particle */ + if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) { + where_is_particle(paf, pa, stime, vec); + MTC_Mat4MulVecfl(mat, vec); + where_is_particle(paf, pa, ptime, vec1); + MTC_Mat4MulVecfl(mat, vec1); + } + else { + where_is_particle(paf, pa, ctime, vec); + MTC_Mat4MulVecfl(mat, vec); + } + + if(pa->mat_nr != mat_nr) { + mat_nr= pa->mat_nr; + ma= give_render_material(re, ob, mat_nr); + } + + if(ma->ipo) { + /* correction for lifetime */ + ptime= 100.0*(ctime-pa->time)/pa->lifetime; + calc_ipo(ma->ipo, ptime); + execute_ipo((ID *)ma, ma->ipo); + } + + hasize= ma->hasize; + + if(ma->mode & MA_HALOPUNO) { + xn= pa->no[0]; + yn= pa->no[1]; + zn= pa->no[2]; + + /* transpose ! */ + nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(nor); + + VECCOPY(view, vec); + Normalise(view); + + zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; + if(zn>=0.0) hasize= 0.0; + else hasize*= zn*zn*zn*zn; + } + + if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed); + else { + har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed); + if(har && ma->mode & MA_HALO_SHADE) { + VecSubf(har->no, vec, vec1); + Normalise(har->no); + } + } + if(har) har->lay= ob->lay; + } + + /* restore material */ + for(a=1; a<=ob->totcol; a++) { + ma= give_render_material(re, ob, a); + if(ma) do_mat_ipo(ma); + } + + if(paf->disp!=100) { + MEM_freeN(paf->keys); + paf->keys= NULL; + } +} + + +/* ------------------------------------------------------------------------- */ + +/* future thread problem... */ +static void static_particle_strand(Render *re, Object *ob, Material *ma, float *orco, float *vec, float *vec1, float ctime, int first) +{ + static VertRen *v1= NULL, *v2= NULL; + VlakRen *vlr; + float nor[3], cross[3], w, dx, dy; + int flag; + + VecSubf(nor, vec, vec1); + Normalise(nor); // nor needed as tangent + Crossf(cross, vec, nor); + + /* turn cross in pixelsize */ + w= vec[2]*re->winmat[2][3] + re->winmat[3][3]; + dx= re->winx*cross[0]*re->winmat[0][0]/w; + dy= re->winy*cross[1]*re->winmat[1][1]/w; + w= sqrt(dx*dx + dy*dy); + if(w!=0.0f) { + float fac; + if(ma->strand_ease!=0.0f) { + if(ma->strand_ease<0.0f) + fac= pow(ctime, 1.0+ma->strand_ease); + else + fac= pow(ctime, 1.0/(1.0f-ma->strand_ease)); + } + else fac= ctime; + + VecMulf(cross, ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end)/w); + } + + if(ma->mode & MA_TANGENT_STR) + flag= R_SMOOTH|R_NOPUNOFLIP|R_STRAND|R_TANGENT; + else + flag= R_SMOOTH|R_STRAND; + + /* first two vertices */ + if(first) { + v1= RE_findOrAddVert(re, re->totvert++); + v2= RE_findOrAddVert(re, re->totvert++); + + VECCOPY(v1->co, vec); + VecAddf(v1->co, v1->co, cross); + VECCOPY(v1->n, nor); + v1->orco= orco; + v1->accum= -1.0f; // accum abuse for strand texco + + VECCOPY(v2->co, vec); + VecSubf(v2->co, v2->co, cross); + VECCOPY(v2->n, nor); + v2->orco= orco; + v2->accum= v1->accum; + } + else { + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->flag= flag; + vlr->ob= ob; + vlr->v1= v1; + vlr->v2= v2; + vlr->v3= RE_findOrAddVert(re, re->totvert++); + vlr->v4= RE_findOrAddVert(re, re->totvert++); + + v1= vlr->v4; // cycle + v2= vlr->v3; // cycle + + VECCOPY(vlr->v4->co, vec); + VecAddf(vlr->v4->co, vlr->v4->co, cross); + VECCOPY(vlr->v4->n, nor); + vlr->v4->orco= orco; + vlr->v4->accum= -1.0f + 2.0f*ctime; // accum abuse for strand texco + + VECCOPY(vlr->v3->co, vec); + VecSubf(vlr->v3->co, vlr->v3->co, cross); + VECCOPY(vlr->v3->n, nor); + vlr->v3->orco= orco; + vlr->v3->accum= vlr->v4->accum; + + CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + + vlr->mat= ma; + vlr->ec= ME_V2V3; + vlr->lay= ob->lay; + } +} + +static void render_static_particle_system(Render *re, Object *ob, PartEff *paf) +{ + Particle *pa=0; + HaloRen *har=0; + Material *ma=0; + VertRen *v1= NULL; + VlakRen *vlr; + float xn, yn, zn, imat[3][3], mat[4][4], hasize; + float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3]; + float *orco= NULL, loc_tex[3], size_tex[3]; + int a, mat_nr=1, seed, totvlako, totverto, first; + + pa= paf->keys; + if(pa==NULL || (paf->flag & PAF_ANIMATED) || paf->disp!=100) { + build_particle_system(ob); + pa= paf->keys; + if(pa==NULL) return; + } + + totvlako= re->totvlak; + totverto= re->totvert; + + ma= give_render_material(re, ob, paf->omat); + if(ma->mode & MA_HALO) + re->flag |= R_HALO; + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ + + MTC_Mat3CpyMat4(imat, ob->imat); + + /* orcos */ + if(!(ma->mode & (MA_HALO|MA_WIRE))) { + orco= MEM_mallocN(3*sizeof(float)*paf->totpart, "static particle orcos"); + if (!re->orco_hash) + re->orco_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp); + BLI_ghash_insert(re->orco_hash, paf, orco); /* pointer is particles, otherwise object uses it */ + } + + mesh_get_texspace(ob->data, loc_tex, NULL, size_tex); + + if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; + else ptime= 0.0; + ctime= bsystem_time(ob, 0, (float)re->scene->r.cfra, ptime); + seed= ma->seed1; + + for(a=0; atotpart; a++, pa+=paf->totkey) { + + where_is_particle(paf, pa, pa->time, vec1); + if(orco) { + orco[0] = (vec1[0]-loc_tex[0])/size_tex[0]; + orco[1] = (vec1[1]-loc_tex[1])/size_tex[1]; + orco[2] = (vec1[2]-loc_tex[2])/size_tex[2]; + } + MTC_Mat4MulVecfl(mat, vec1); + mtime= pa->time+pa->lifetime+paf->staticstep-1; + + first= 1; + for(ctime= pa->time; ctimestaticstep) { + + /* make sure hair grows until the end.. */ + if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime; + + /* watch it: also calc the normal of a particle */ + if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) { + where_is_particle(paf, pa, ctime+1.0, vec); + MTC_Mat4MulVecfl(mat, vec); + } + else { + where_is_particle(paf, pa, ctime, vec); + MTC_Mat4MulVecfl(mat, vec); + } + + if(pa->mat_nr != mat_nr) { + mat_nr= pa->mat_nr; + ma= give_render_material(re, ob, mat_nr); + } + + /* wires */ + if(ma->mode & MA_WIRE) { + if(ctime == pa->time) { + v1= RE_findOrAddVert(re, re->totvert++); + VECCOPY(v1->co, vec); + } + else { + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= v1; + vlr->v2= RE_findOrAddVert(re, re->totvert++); + vlr->v3= vlr->v2; + vlr->v4= NULL; + + v1= vlr->v2; // cycle + VECCOPY(v1->co, vec); + + VecSubf(vlr->n, vec, vec1); + Normalise(vlr->n); + VECCOPY(v1->n, vlr->n); + + vlr->mat= ma; + vlr->ec= ME_V1V2; + vlr->lay= ob->lay; + } + } + else { + if(ma->ipo) { + /* correction for lifetime */ + ptime= 100.0*(ctime-pa->time)/pa->lifetime; + calc_ipo(ma->ipo, ptime); + execute_ipo((ID *)ma, ma->ipo); + } + + if(ma->mode & MA_HALO) { + hasize= ma->hasize; + + if(ma->mode & MA_HALOPUNO) { + xn= pa->no[0]; + yn= pa->no[1]; + zn= pa->no[2]; + + /* transpose ! */ + nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(nor); + + VECCOPY(view, vec); + Normalise(view); + + zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2]; + if(zn>=0.0) hasize= 0.0; + else hasize*= zn*zn*zn*zn; + } + + if(paf->stype==PAF_VECT) har= RE_inithalo(re, ma, vec, vec1, pa->co, hasize, paf->vectsize, seed); + else { + har= RE_inithalo(re, ma, vec, NULL, pa->co, hasize, 0.0, seed); + if(har && (ma->mode & MA_HALO_SHADE)) { + VecSubf(har->no, vec, vec1); + Normalise(har->no); + har->lay= ob->lay; + } + } + if(har) har->lay= ob->lay; + } + else { /* generate pixel sized hair strand */ + static_particle_strand(re, ob, ma, orco, vec, vec1, (ctime-pa->time)/(mtime-pa->time), first); + } + } + + VECCOPY(vec1, vec); + first= 0; + } + + seed++; + if(orco) orco+=3; + } + + if(paf->disp!=100) { + MEM_freeN(paf->keys); + paf->keys= NULL; + } + + if((ma->mode & MA_TANGENT_STR)==0) + calc_vertexnormals(re, totverto, totvlako, 0); +} + + +/* ------------------------------------------------------------------------- */ + +static int verghalo(const void *a1, const void *a2) +{ + const struct halosort *x1=a1, *x2=a2; + + if( x1->z < x2->z ) return 1; + else if( x1->z > x2->z) return -1; + return 0; +} + +/* ------------------------------------------------------------------------- */ +static void sort_halos(Render *re) +{ + struct halosort *hablock, *haso; + HaloRen *har = NULL, **bloha; + int a; + + if(re->tothalo==0) return; + + /* make datablock with halo pointers, sort */ + haso= hablock= MEM_mallocN(sizeof(struct halosort)*re->tothalo, "hablock"); + + for(a=0; atothalo; a++) { + if((a & 255)==0) har= re->bloha[a>>8]; + else har++; + haso->har= har; + haso->z= har->zs; + haso++; + } + + qsort(hablock, re->tothalo, sizeof(struct halosort), verghalo); + + /* re-assamble re->bloha */ + + bloha= re->bloha; + re->bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(re->blohalen),"Bloha"); + + haso= hablock; + for(a=0; atothalo; a++) { + har= RE_findOrAddHalo(re, a); + *har= *(haso->har); + + haso++; + } + + /* free */ + a= 0; + while(bloha[a]) { + MEM_freeN(bloha[a]); + a++; + } + MEM_freeN(bloha); + MEM_freeN(hablock); + +} + +/* ------------------------------------------------------------------------- */ +static void init_render_mball(Render *re, Object *ob) +{ + DispList *dl, *dlo; + VertRen *ver; + VlakRen *vlr, *vlr1; + Material *ma; + float *data, *nors, mat[4][4], imat[3][3], xn, yn, zn; + int a, need_orco, startvert, *index; + + if (ob!=find_basis_mball(ob)) + return; + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + MTC_Mat3CpyMat4(imat, ob->imat); + + ma= give_render_material(re, ob, 1); + + need_orco= 0; + if(ma->texco & TEXCO_ORCO) { + need_orco= 1; + } + + dlo= ob->disp.first; + if(dlo) BLI_remlink(&ob->disp, dlo); + + makeDispListMBall(ob); + dl= ob->disp.first; + if(dl==0) return; + + startvert= re->totvert; + data= dl->verts; + nors= dl->nors; + + for(a=0; anr; a++, data+=3, nors+=3) { + + ver= RE_findOrAddVert(re, re->totvert++); + VECCOPY(ver->co, data); + MTC_Mat4MulVecfl(mat, ver->co); + + xn= nors[0]; + yn= nors[1]; + zn= nors[2]; + + /* transpose ! */ + ver->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + ver->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + ver->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(ver->n); + //if(ob->transflag & OB_NEG_SCALE) VecMulf(ver->n. -1.0); + + if(need_orco) ver->orco= data; + } + + index= dl->index; + for(a=0; aparts; a++, index+=4) { + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= RE_findOrAddVert(re, startvert+index[0]); + vlr->v2= RE_findOrAddVert(re, startvert+index[1]); + vlr->v3= RE_findOrAddVert(re, startvert+index[2]); + vlr->v4= 0; + + if(ob->transflag & OB_NEG_SCALE) + CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n); + else + CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + + vlr->mat= ma; + vlr->flag= ME_SMOOTH+R_NOPUNOFLIP; + vlr->ec= 0; + vlr->lay= ob->lay; + + /* mball -too bad- always has triangles, because quads can be non-planar */ + if(index[3]) { + vlr1= RE_findOrAddVlak(re, re->totvlak++); + *vlr1= *vlr; + vlr1->v2= vlr1->v3; + vlr1->v3= RE_findOrAddVert(re, startvert+index[3]); + if(ob->transflag & OB_NEG_SCALE) + CalcNormFloat(vlr1->v1->co, vlr1->v2->co, vlr1->v3->co, vlr1->n); + else + CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n); + } + } + + if(need_orco) { + /* store displist and scale */ + make_orco_mball(ob); + if(dlo) BLI_addhead(&ob->disp, dlo); + + } + else { + freedisplist(&ob->disp); + if(dlo) BLI_addtail(&ob->disp, dlo); + } +} +/* ------------------------------------------------------------------------- */ +/* convert */ + +struct edgesort { + int v1, v2; + int has_mcol; + TFace *tface; + float uv1[2], uv2[2]; + unsigned int mcol1, mcol2; +}; + +/* edges have to be added with lowest index first for sorting */ +static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, unsigned int *mcol, TFace *tface) +{ + if(v1v1= v1; ed->v2= v2; + } + else { + ed->v1= v2; ed->v2= v1; + SWAP(int, i1, i2); + } + /* copy color and tface, edges use different ordering */ + ed->tface= tface; + if(tface) { + ed->uv1[0]= tface->uv[i1][0]; + ed->uv1[1]= tface->uv[i1][1]; + ed->uv2[0]= tface->uv[i2][0]; + ed->uv2[1]= tface->uv[i2][1]; + + ed->mcol1= tface->col[i1]; + ed->mcol2= tface->col[i2]; + } + ed->has_mcol= mcol!=NULL; + if(mcol) { + ed->mcol1= mcol[i1]; + ed->mcol2= mcol[i2]; + } +} + +static int vergedgesort(const void *v1, const void *v2) +{ + const struct edgesort *x1=v1, *x2=v2; + + if( x1->v1 > x2->v1) return 1; + else if( x1->v1 < x2->v1) return -1; + else if( x1->v2 > x2->v2) return 1; + else if( x1->v2 < x2->v2) return -1; + + return 0; +} + +static struct edgesort *make_mesh_edge_lookup(Mesh *me, DispListMesh *dlm, int *totedgesort) +{ + MFace *mf, *mface; + TFace *tface=NULL; + struct edgesort *edsort, *ed; + unsigned int *mcol=NULL; + int a, totedge=0, totface; + + if (dlm) { + mface= dlm->mface; + totface= dlm->totface; + if (dlm->tface) + tface= dlm->tface; + else if (dlm->mcol) + mcol= (unsigned int *)dlm->mcol; + } else { + mface= me->mface; + totface= me->totface; + if (me->tface) + tface= me->tface; + else if (me->mcol) + mcol= (unsigned int *)me->mcol; + } + + if(mcol==NULL && tface==NULL) return NULL; + + /* make sorted table with edges and and tface/mcol pointers in it */ + for(a= totface, mf= mface; a>0; a--, mf++) { + if(mf->v4) totedge+=4; + else if(mf->v3) totedge+=3; + } + if(totedge==0) return NULL; + + ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort"); + + for(a= me->totface, mf= mface; a>0; a--, mf++) { + if(mface->v4 || mface->v3) { + to_edgesort(ed++, 0, 1, mf->v1, mf->v2, mcol, tface); + to_edgesort(ed++, 1, 2, mf->v2, mf->v3, mcol, tface); + if(mf->v4) { + to_edgesort(ed++, 2, 3, mf->v3, mf->v4, mcol, tface); + to_edgesort(ed++, 3, 0, mf->v4, mf->v1, mcol, tface); + } + else if(mf->v3) { + to_edgesort(ed++, 2, 3, mf->v3, mf->v1, mcol, tface); + } + } + if(mcol) mcol+=4; + if(tface) tface++; + } + + qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort); + + *totedgesort= totedge; + return edsort; +} + +static void use_mesh_edge_lookup(Render *re, Mesh *me, DispListMesh *dlm, MEdge *medge, VlakRen *vlr, struct edgesort *edgetable, int totedge) +{ + struct edgesort ed, *edp; + + if(medge->v1 < medge->v2) { + ed.v1= medge->v1; ed.v2= medge->v2; + } + else { + ed.v1= medge->v2; ed.v2= medge->v1; + } + + edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort); + if(edp) { + /* since edges have different index ordering, we have to duplicate mcol and tface */ + if(edp->tface) { + vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace)); + vlr->vcol= vlr->tface->col; + memcpy(vlr->tface, edp->tface, sizeof(TFace)); + + if(edp->v1==medge->v1) { + vlr->vcol[0]= edp->mcol1; + vlr->vcol[1]= edp->mcol2; + } + else { + vlr->vcol[0]= edp->mcol2; + vlr->vcol[1]= edp->mcol1; + } + vlr->vcol[2]= vlr->vcol[1]; + vlr->vcol[3]= vlr->vcol[1]; + + if(edp->v1==medge->v1) { + memcpy(vlr->tface->uv[0], edp->uv1, 2*sizeof(float)); + memcpy(vlr->tface->uv[1], edp->uv2, 2*sizeof(float)); + } + else { + memcpy(vlr->tface->uv[0], edp->uv2, 2*sizeof(float)); + memcpy(vlr->tface->uv[1], edp->uv1, 2*sizeof(float)); + } + memcpy(vlr->tface->uv[2], vlr->tface->uv[1], 2*sizeof(float)); + memcpy(vlr->tface->uv[3], vlr->tface->uv[1], 2*sizeof(float)); + } + else if(edp->has_mcol) { + vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(MCol)*4); + vlr->vcol[0]= edp->mcol1; + vlr->vcol[1]= edp->mcol2; + vlr->vcol[2]= vlr->vcol[1]; + vlr->vcol[3]= vlr->vcol[1]; + } + } +} + +static void init_render_mesh(Render *re, Object *ob) +{ + Mesh *me; + MVert *mvert = NULL; + MFace *mface; + VlakRen *vlr; //, *vlr1; + VertRen *ver; + Material *ma; + MSticky *ms = NULL; + PartEff *paf; + DispListMesh *dlm = NULL; + DerivedMesh *dm; + unsigned int *vertcol; + float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], + float *orco=0; + int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs; + int end, do_autosmooth=0, totvert = 0, dm_needsfree; + + me= ob->data; + + paf = give_parteff(ob); + if(paf) { + /* warning; build_particle_system does modifier calls itself */ + if(paf->flag & PAF_STATIC) render_static_particle_system(re, ob, paf); + else render_particle_system(re, ob, paf); + if((paf->flag & PAF_SHOWE)==0) return; + } + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + MTC_Mat3CpyMat4(imat, ob->imat); + + if(me->totvert==0) { + return; + } + + totvlako= re->totvlak; + totverto= re->totvert; + + need_orco= 0; + for(a=1; a<=ob->totcol; a++) { + ma= give_render_material(re, ob, a); + if(ma) { + if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS)) + need_orco= 1; + if(ma->texco & TEXCO_STRESS) + need_stress= 1; + if(ma->mode & MA_TANGENT_V) + need_tangent= 1; + } + } + + if(need_orco) orco = get_object_orco(re, ob); + + dm = mesh_create_derived_render(ob); + dm_needsfree= 1; + + if(dm==NULL) return; /* in case duplicated object fails? */ + + dlm = dm->convertToDispListMesh(dm, 1); + + mvert= dlm->mvert; + totvert= dlm->totvert; + + ms = (totvert==me->totvert)?me->msticky:NULL; + + ma= give_render_material(re, ob, 1); + + if(ma->mode & MA_HALO) { + make_render_halos(re, ob, me, totvert, mvert, ma, orco); + } + else { + + for(a=0; atotvert++); + VECCOPY(ver->co, mvert->co); + MTC_Mat4MulVecfl(mat, ver->co); + + if(orco) { + ver->orco= orco; + orco+=3; + } + if(ms) { + float *sticky= RE_vertren_get_sticky(re, ver, 1); + sticky[0]= ms->co[0]; + sticky[1]= ms->co[1]; + ms++; + } + } + /* still to do for keys: the correct local texture coordinate */ + + /* faces in order of color blocks */ + vertofs= re->totvert - totvert; + for(a1=0; (a1totcol || (a1==0 && ob->totcol==0)); a1++) { + + ma= give_render_material(re, ob, a1+1); + + /* test for 100% transparant */ + ok= 1; + if(ma->alpha==0.0 && ma->spectra==0.0) { + ok= 0; + /* texture on transparency? */ + for(a=0; amtex[a] && ma->mtex[a]->tex) { + if(ma->mtex[a]->mapto & MAP_ALPHA) ok= 1; + } + } + } + + /* if wire material, and we got edges, don't do the faces */ + if(ma->mode & MA_WIRE) { + end= dlm?dlm->totedge:me->totedge; + if(end) ok= 0; + } + + if(ok) { + TFace *tface= NULL; + + /* radio faces need autosmooth, to separate shared vertices in corners */ + if(re->r.mode & R_RADIO) + if(ma->mode & MA_RADIO) + do_autosmooth= 1; + + end= dlm?dlm->totface:me->totface; + if (dlm) { + mface= dlm->mface; + if (dlm->tface) { + tface= dlm->tface; + vertcol= NULL; + } else if (dlm->mcol) { + vertcol= (unsigned int *)dlm->mcol; + } else { + vertcol= NULL; + } + } else { + mface= me->mface; + if (me->tface) { + tface= me->tface; + vertcol= NULL; + } else if (me->mcol) { + vertcol= (unsigned int *)me->mcol; + } else { + vertcol= NULL; + } + } + + for(a=0; amat_nr==a1 ) { + float len; + + v1= mface->v1; + v2= mface->v2; + v3= mface->v3; + v4= mface->v4; + flag= mface->flag & ME_SMOOTH; + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= RE_findOrAddVert(re, vertofs+v1); + vlr->v2= RE_findOrAddVert(re, vertofs+v2); + vlr->v3= RE_findOrAddVert(re, vertofs+v3); + if(v4) vlr->v4= RE_findOrAddVert(re, vertofs+v4); + else vlr->v4= 0; + + /* render normals are inverted in render */ + if(vlr->v4) len= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, + vlr->v1->co, vlr->n); + else len= CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, + vlr->n); + + vlr->mat= ma; + vlr->flag= flag; + if((me->flag & ME_NOPUNOFLIP) ) { + vlr->flag |= R_NOPUNOFLIP; + } + vlr->ec= 0; /* mesh edges rendered separately */ + vlr->lay= ob->lay; + + if(len==0) re->totvlak--; + else { + if(dlm) { + if(tface) { + vlr->tface= BLI_memarena_alloc(re->memArena, sizeof(TFace)); + vlr->vcol= vlr->tface->col; + memcpy(vlr->tface, tface, sizeof(TFace)); + } + else if (vertcol) { + vlr->vcol= BLI_memarena_alloc(re->memArena, sizeof(int)*4); + memcpy(vlr->vcol, vertcol+4*a, sizeof(int)*4); + } + } else { + if(tface) { + vlr->vcol= tface->col; + vlr->tface= tface; + } + else if (vertcol) { + vlr->vcol= vertcol+4*a; + } + } + } + } + + mface++; + if(tface) tface++; + } + } + } + + /* exception... we do edges for wire mode. potential conflict when faces exist... */ + end= dlm?dlm->totedge:me->totedge; + mvert= dlm?dlm->mvert:me->mvert; + ma= give_render_material(re, ob, 1); + if(end && (ma->mode & MA_WIRE)) { + MEdge *medge; + struct edgesort *edgetable; + int totedge; + + medge= dlm?dlm->medge:me->medge; + + /* we want edges to have UV and vcol too... */ + edgetable= make_mesh_edge_lookup(me, dlm, &totedge); + + for(a1=0; a1flag&ME_EDGERENDER) { + MVert *v0 = &mvert[medge->v1]; + MVert *v1 = &mvert[medge->v2]; + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= RE_findOrAddVert(re, vertofs+medge->v1); + vlr->v2= RE_findOrAddVert(re, vertofs+medge->v2); + vlr->v3= vlr->v2; + vlr->v4= NULL; + + if(edgetable) { + use_mesh_edge_lookup(re, me, dlm, medge, vlr, edgetable, totedge); + } + + xn= (v0->no[0]+v1->no[0]); + yn= (v0->no[1]+v1->no[1]); + zn= (v0->no[2]+v1->no[2]); + /* transpose ! */ + vlr->n[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn; + vlr->n[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn; + vlr->n[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn; + Normalise(vlr->n); + + vlr->mat= ma; + vlr->flag= 0; + vlr->ec= ME_V1V2; + vlr->lay= ob->lay; + } + } + if(edgetable) + MEM_freeN(edgetable); + } + } + + if (test_for_displace(re, ob ) ) { + calc_vertexnormals(re, totverto, totvlako, 0); + do_displacement(re, ob, totvlako, re->totvlak-totvlako, totverto, re->totvert-totverto); + } + + if(do_autosmooth || (me->flag & ME_AUTOSMOOTH)) { + autosmooth(re, totverto, totvlako, me->smoothresh); + } + + calc_vertexnormals(re, totverto, totvlako, need_tangent); + + if(need_stress) + calc_edge_stress(re, me, totverto, totvlako); + + if(dlm) displistmesh_free(dlm); + if(dm_needsfree) dm->release(dm); +} + +/* ------------------------------------------------------------------------- */ + +static void initshadowbuf(Render *re, LampRen *lar, float mat[][4]) +{ + struct ShadBuf *shb; + float hoek, temp, viewinv[4][4]; + + /* if(la->spsi<16) return; */ + + /* memory reservation */ + shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf"); + lar->shb= shb; + + if(shb==NULL) return; + + VECCOPY(shb->co, lar->co); + + /* percentage render: keep track of min and max */ + shb->size= (lar->bufsize*re->r.size)/100; + if(shb->size<512) shb->size= 512; + else if(shb->size > lar->bufsize) shb->size= lar->bufsize; + + shb->size &= ~15; /* make sure its multiples of 16 */ + + shb->samp= lar->samp; + shb->soft= lar->soft; + shb->shadhalostep= lar->shadhalostep; + + shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2"); + shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3"); + + if(shb->zbuf==0 || shb->cbuf==0) { + if(shb->zbuf) MEM_freeN(shb->zbuf); + MEM_freeN(lar->shb); + lar->shb= 0; + return; + } + + MTC_Mat4Ortho(mat); + MTC_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); + + /* projection */ + hoek= saacos(lar->spotsi); + temp= 0.5*shb->size*cos(hoek)/sin(hoek); + shb->d= lar->clipsta; + + shb->pixsize= (shb->d)/temp; + + shb->clipend= lar->clipend; + /* bias is percentage, made 2x karger because of correction for angle of incidence */ + /* when a ray is closer to parallel of a face, bias value is increased during render */ + shb->bias= (0.02*lar->bias)*0x7FFFFFFF; + shb->bias= shb->bias*(100/re->r.size); + +} + + +static void area_lamp_vectors(LampRen *lar) +{ + float xsize= 0.5*lar->area_size, ysize= 0.5*lar->area_sizey; + + /* corner vectors */ + lar->area[0][0]= lar->co[0] - xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; + lar->area[0][1]= lar->co[1] - xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; + lar->area[0][2]= lar->co[2] - xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; + + /* corner vectors */ + lar->area[1][0]= lar->co[0] - xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; + lar->area[1][1]= lar->co[1] - xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; + lar->area[1][2]= lar->co[2] - xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; + + /* corner vectors */ + lar->area[2][0]= lar->co[0] + xsize*lar->mat[0][0] + ysize*lar->mat[1][0]; + lar->area[2][1]= lar->co[1] + xsize*lar->mat[0][1] + ysize*lar->mat[1][1]; + lar->area[2][2]= lar->co[2] + xsize*lar->mat[0][2] + ysize*lar->mat[1][2]; + + /* corner vectors */ + lar->area[3][0]= lar->co[0] + xsize*lar->mat[0][0] - ysize*lar->mat[1][0]; + lar->area[3][1]= lar->co[1] + xsize*lar->mat[0][1] - ysize*lar->mat[1][1]; + lar->area[3][2]= lar->co[2] + xsize*lar->mat[0][2] - ysize*lar->mat[1][2]; + /* only for correction button size, matrix size works on energy */ + lar->areasize= lar->dist*lar->dist/(4.0*xsize*ysize); +} + +/* If lar takes more lamp data, the decoupling will be better. */ +static void add_render_lamp(Render *re, Object *ob, int actual_render) +{ + Lamp *la= ob->data; + LampRen *lar; + GroupObject *go; + float mat[4][4], hoek, xn, yn; + int c; + + /* prevent only shadow from rendering light, but only return on render, not preview */ + if(actual_render) { + if(la->mode & LA_ONLYSHADOW) + if((re->r.mode & R_SHADOW)==0) + return; + } + + go= MEM_callocN(sizeof(GroupObject), "groupobject"); + BLI_addtail(&re->lights, go); + re->totlamp++; + lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren"); + go->lampren= lar; + go->ob= ob; + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + + MTC_Mat3CpyMat4(lar->mat, mat); + MTC_Mat3CpyMat4(lar->imat, ob->imat); + + lar->bufsize = la->bufsize; + lar->samp = la->samp; + lar->soft = la->soft; + lar->shadhalostep = la->shadhalostep; + lar->clipsta = la->clipsta; + lar->clipend = la->clipend; + lar->bias = la->bias; + + lar->type= la->type; + lar->mode= la->mode; + + lar->energy= la->energy; + lar->energy= la->energy; + if(la->mode & LA_NEG) lar->energy= -lar->energy; + + lar->vec[0]= -mat[2][0]; + lar->vec[1]= -mat[2][1]; + lar->vec[2]= -mat[2][2]; + Normalise(lar->vec); + lar->co[0]= mat[3][0]; + lar->co[1]= mat[3][1]; + lar->co[2]= mat[3][2]; + lar->dist= la->dist; + lar->haint= la->haint; + lar->distkw= lar->dist*lar->dist; + lar->r= lar->energy*la->r; + lar->g= lar->energy*la->g; + lar->b= lar->energy*la->b; + lar->k= la->k; + + // area + lar->ray_samp= la->ray_samp; + lar->ray_sampy= la->ray_sampy; + lar->ray_sampz= la->ray_sampz; + + lar->area_size= la->area_size; + lar->area_sizey= la->area_sizey; + lar->area_sizez= la->area_sizez; + + lar->area_shape= la->area_shape; + lar->ray_samp_type= la->ray_samp_type; + + if(lar->type==LA_AREA) { + switch(lar->area_shape) { + case LA_AREA_SQUARE: + lar->ray_totsamp= lar->ray_samp*lar->ray_samp; + lar->ray_sampy= lar->ray_samp; + lar->area_sizey= lar->area_size; + break; + case LA_AREA_RECT: + lar->ray_totsamp= lar->ray_samp*lar->ray_sampy; + break; + case LA_AREA_CUBE: + lar->ray_totsamp= lar->ray_samp*lar->ray_samp*lar->ray_samp; + lar->ray_sampy= lar->ray_samp; + lar->ray_sampz= lar->ray_samp; + lar->area_sizey= lar->area_size; + lar->area_sizez= lar->area_size; + break; + case LA_AREA_BOX: + lar->ray_totsamp= lar->ray_samp*lar->ray_sampy*lar->ray_sampz; + break; + } + + area_lamp_vectors(lar); + } + else lar->ray_totsamp= 0; + + /* yafray: photonlight and other params */ + if (re->r.renderer==R_YAFRAY) { + lar->YF_numphotons = la->YF_numphotons; + lar->YF_numsearch = la->YF_numsearch; + lar->YF_phdepth = la->YF_phdepth; + lar->YF_useqmc = la->YF_useqmc; + lar->YF_causticblur = la->YF_causticblur; + lar->YF_ltradius = la->YF_ltradius; + lar->YF_bufsize = la->YF_bufsize; + lar->YF_glowint = la->YF_glowint; + lar->YF_glowofs = la->YF_glowofs; + lar->YF_glowtype = la->YF_glowtype; + } + + lar->spotsi= la->spotsize; + if(lar->mode & LA_HALO) { + if(lar->spotsi>170.0) lar->spotsi= 170.0; + } + lar->spotsi= cos( M_PI*lar->spotsi/360.0 ); + lar->spotbl= (1.0-lar->spotsi)*la->spotblend; + + memcpy(lar->mtex, la->mtex, MAX_MTEX*sizeof(void *)); + + lar->lay= ob->lay & 0xFFFFFF; // higher 8 bits are localview layers + + lar->ld1= la->att1; + lar->ld2= la->att2; + + if(lar->type==LA_SPOT) { + + Normalise(lar->imat[0]); + Normalise(lar->imat[1]); + Normalise(lar->imat[2]); + + xn= saacos(lar->spotsi); + xn= sin(xn)/cos(xn); + lar->spottexfac= 1.0/(xn); + + if(lar->mode & LA_ONLYSHADOW) { + if((lar->mode & (LA_SHAD|LA_SHAD_RAY))==0) lar->mode -= LA_ONLYSHADOW; + } + + } + + /* set flag for spothalo en initvars */ + if(la->type==LA_SPOT && (la->mode & LA_HALO)) { + if(la->haint>0.0) { + re->flag |= R_LAMPHALO; + + /* camera position (0,0,0) rotate around lamp */ + 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); + + /* z factor, for a normalized volume */ + hoek= saacos(lar->spotsi); + xn= lar->spotsi; + yn= sin(hoek); + lar->sh_zfac= yn/xn; + /* pre-scale */ + lar->sh_invcampos[2]*= lar->sh_zfac; + + } + } + + for(c=0; cmtex[c] && la->mtex[c]->tex) { + lar->mode |= LA_TEXTURE; + + if(G.rendering) { + if(re->osa) { + if(la->mtex[c]->tex->type==TEX_IMAGE) lar->mode |= LA_OSATEX; + } + } + } + } + + /* yafray: shadowbuffers and jitter only needed for internal render */ + if (actual_render && re->r.renderer==R_INTERN) { + if(re->r.mode & R_SHADOW) { + if (la->type==LA_SPOT && (lar->mode & LA_SHAD) ) { + /* Per lamp, one shadow buffer is made. */ + Mat4CpyMat4(mat, ob->obmat); + initshadowbuf(re, lar, mat); // mat is altered + } + else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) { + init_jitter_plane(lar); + } + } + } + + /* yafray: shadow flag should not be cleared, only used with internal renderer */ + if (re->r.renderer==R_INTERN) { + /* to make sure we can check ray shadow easily in the render code */ + if(lar->mode & LA_SHAD_RAY) { + if( (re->r.mode & R_RAYTRACE)==0) + lar->mode &= ~LA_SHAD_RAY; + } + } +} + +/* ------------------------------------------------------------------------- */ +static void init_render_surf(Render *re, Object *ob) +{ + extern Material defmaterial; // initrender.c + Nurb *nu=0; + Curve *cu; + ListBase displist; + DispList *dl; + VertRen *ver, *v1, *v2, *v3, *v4; + VlakRen *vlr; + Material *matar[32]; + float *data, *orco=NULL, *orcobase=NULL, n1[3], flen, mat[4][4]; + int a, need_orco=0, startvlak, startvert, p1, p2, p3, p4; + int u, v; + int sizeu, sizev; + VlakRen *vlr1, *vlr2, *vlr3; + float vn[3]; // n2[3], + + cu= ob->data; + nu= cu->nurb.first; + if(nu==0) return; + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + + /* material array */ + memset(matar, 0, 4*32); + matar[0]= &defmaterial; + for(a=0; atotcol; a++) { + matar[a]= give_render_material(re, ob, a+1); + if(matar[a] && matar[a]->texco & TEXCO_ORCO) { + need_orco= 1; + } + } + + if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1; + + if(need_orco) orcobase= orco= get_object_orco(re, ob); + + displist.first= displist.last= 0; + makeDispListSurf(ob, &displist, 1); + + dl= displist.first; + /* walk along displaylist and create rendervertices/-faces */ + while(dl) { + /* watch out: u ^= y, v ^= x !! */ + if(dl->type==DL_SURF) { + int nsizeu, nsizev; + + startvert= re->totvert; + nsizeu = sizeu = dl->parts; nsizev = sizev = dl->nr; + + data= dl->verts; + for (u = 0; u < sizeu; u++) { + v1 = RE_findOrAddVert(re, re->totvert++); /* save this for possible V wrapping */ + VECCOPY(v1->co, data); data += 3; + if(orco) { + v1->orco= orco; orco+= 3; + } + MTC_Mat4MulVecfl(mat, v1->co); + + for (v = 1; v < sizev; v++) { + ver= RE_findOrAddVert(re, re->totvert++); + VECCOPY(ver->co, data); data += 3; + if(orco) { + ver->orco= orco; orco+= 3; + } + MTC_Mat4MulVecfl(mat, ver->co); + } + /* if V-cyclic, add extra vertices at end of the row */ + if (dl->flag & DL_CYCL_U) { + ver= RE_findOrAddVert(re, re->totvert++); + VECCOPY(ver->co, v1->co); + if(orco) { + ver->orco= orcobase + 3*(u*sizev + 0); + } + } + } + + /* Done before next loop to get corner vert */ + if (dl->flag & DL_CYCL_U) nsizev++; + if (dl->flag & DL_CYCL_V) nsizeu++; + + /* if U cyclic, add extra row at end of column */ + if (dl->flag & DL_CYCL_V) { + for (v = 0; v < nsizev; v++) { + v1= RE_findOrAddVert(re, startvert + v); + ver= RE_findOrAddVert(re, re->totvert++); + VECCOPY(ver->co, v1->co); + if(orco) { + ver->orco= orcobase + 3*(0*sizev + v); + } + } + } + + sizeu = nsizeu; + sizev = nsizev; + + startvlak= re->totvlak; + + for(u = 0; u < sizeu - 1; u++) { + p1 = startvert + u * sizev; /* walk through face list */ + p2 = p1 + 1; + p3 = p2 + sizev; + p4 = p3 - 1; + + for(v = 0; v < sizev - 1; v++) { + v1= RE_findOrAddVert(re, p1); + v2= RE_findOrAddVert(re, p2); + v3= RE_findOrAddVert(re, p3); + v4= RE_findOrAddVert(re, p4); + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4; + + flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1); + VECCOPY(vlr->n, n1); + + vlr->lay= ob->lay; + vlr->mat= matar[ dl->col]; + vlr->ec= ME_V1V2+ME_V2V3; + vlr->flag= dl->rt; + if( (cu->flag & CU_NOPUNOFLIP) ) { + vlr->flag |= R_NOPUNOFLIP; + } + + VecAddf(v1->n, v1->n, n1); + VecAddf(v2->n, v2->n, n1); + VecAddf(v3->n, v3->n, n1); + VecAddf(v4->n, v4->n, n1); + + p1++; p2++; p3++; p4++; + } + } + /* fix normals for U resp. V cyclic faces */ + sizeu--; sizev--; /* dec size for face array */ + if (dl->flag & DL_CYCL_V) { + + for (v = 0; v < sizev; v++) + { + /* optimize! :*/ + vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, v)); + vlr1= RE_findOrAddVlak(re, UVTOINDEX(0, v)); + VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n); + VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n); + VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n); + VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n); + } + } + if (dl->flag & DL_CYCL_U) { + + for (u = 0; u < sizeu; u++) + { + /* optimize! :*/ + vlr= RE_findOrAddVlak(re, UVTOINDEX(u, 0)); + vlr1= RE_findOrAddVlak(re, UVTOINDEX(u, sizev-1)); + VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n); + VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n); + VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n); + VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n); + } + } + /* last vertex is an extra case: + + ^ ()----()----()----() + | | | || | + u | |(0,n)||(0,0)| + | | || | + ()====()====[]====() + | | || | + | |(m,n)||(m,0)| + | | || | + ()----()----()----() + v -> + + vertex [] is no longer shared, therefore distribute + normals of the surrounding faces to all of the duplicates of [] + */ + + if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U)) + { + vlr= RE_findOrAddVlak(re, UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */ + vlr1= RE_findOrAddVlak(re, UVTOINDEX(0,0)); /* (0,0) */ + VecAddf(vn, vlr->n, vlr1->n); + vlr2= RE_findOrAddVlak(re, UVTOINDEX(0, sizev-1)); /* (0,n) */ + VecAddf(vn, vn, vlr2->n); + vlr3= RE_findOrAddVlak(re, UVTOINDEX(sizeu-1, 0)); /* (m,0) */ + VecAddf(vn, vn, vlr3->n); + VECCOPY(vlr->v3->n, vn); + VECCOPY(vlr1->v1->n, vn); + VECCOPY(vlr2->v2->n, vn); + VECCOPY(vlr3->v4->n, vn); + } + for(a = startvert; a < re->totvert; a++) { + ver= RE_findOrAddVert(re, a); + Normalise(ver->n); + } + + + } + + dl= dl->next; + } + freedisplist(&displist); +} + +static void init_render_curve(Render *re, Object *ob) +{ + extern Material defmaterial; // initrender.c + Curve *cu; + VertRen *ver; + VlakRen *vlr; + DispList *dl; + Material *matar[32]; + float len, *data, *fp, *orco=NULL; + float n[3], mat[4][4]; + int nr, startvert, startvlak, a, b; + int frontside, need_orco=0; + + cu= ob->data; + if(cu->nurb.first==NULL) return; + + /* no modifier call here, is in makedisp */ + + /* test displist */ + if(cu->disp.first==0) makeDispListCurveTypes(ob, 0); + dl= cu->disp.first; + if(cu->disp.first==0) return; + + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + + /* material array */ + memset(matar, 0, 4*32); + matar[0]= &defmaterial; + for(a=0; atotcol; a++) { + matar[a]= give_render_material(re, ob, a+1); + if(matar[a]->texco & TEXCO_ORCO) { + need_orco= 1; + } + } + + if(need_orco) orco= get_object_orco(re, ob); + + dl= cu->disp.first; + while(dl) { + if(dl->type==DL_INDEX3) { + int *index; + + startvert= re->totvert; + data= dl->verts; + + n[0]= ob->imat[0][2]; + n[1]= ob->imat[1][2]; + n[2]= ob->imat[2][2]; + Normalise(n); + + /* copy first, rotate later for comparision trick */ + for(a=0; anr; a++, data+=3) { + ver= RE_findOrAddVert(re, re->totvert++); + VECCOPY(ver->co, data); + MTC_Mat4MulVecfl(mat, ver->co); + + if(ver->co[2] < 0.0) { + VECCOPY(ver->n, n); + ver->flag = 1; + } + else { + ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2]; + ver->flag = 0; + } + + if (orco) { + ver->orco = orco; + orco += 3; + } + } + + startvlak= re->totvlak; + index= dl->index; + for(a=0; aparts; a++, index+=3) { + + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob = ob; + vlr->v1= RE_findOrAddVert(re, startvert+index[0]); + vlr->v2= RE_findOrAddVert(re, startvert+index[1]); + vlr->v3= RE_findOrAddVert(re, startvert+index[2]); + vlr->v4= NULL; + + if(vlr->v1->flag) { + VECCOPY(vlr->n, n); + } + else { + vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2]; + } + + vlr->mat= matar[ dl->col ]; + vlr->flag= 0; + if( (cu->flag & CU_NOPUNOFLIP) ) { + vlr->flag |= R_NOPUNOFLIP; + } + vlr->ec= 0; + vlr->lay= ob->lay; + } + } + else if (dl->type==DL_SURF) { + int p1,p2,p3,p4; + + fp= dl->verts; + startvert= re->totvert; + nr= dl->nr*dl->parts; + + while(nr--) { + ver= RE_findOrAddVert(re, re->totvert++); + + VECCOPY(ver->co, fp); + MTC_Mat4MulVecfl(mat, ver->co); + fp+= 3; + + if (orco) { + ver->orco = orco; + orco += 3; + } + } + + startvlak= re->totvlak; + + for(a=0; aparts; a++) { + + frontside= (a >= dl->nr/2); + + DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts); + p1+= startvert; + p2+= startvert; + p3+= startvert; + p4+= startvert; + + for(; bnr; b++) { + vlr= RE_findOrAddVlak(re, re->totvlak++); + vlr->ob= ob; + vlr->v1= RE_findOrAddVert(re, p2); + vlr->v2= RE_findOrAddVert(re, p1); + vlr->v3= RE_findOrAddVert(re, p3); + vlr->v4= RE_findOrAddVert(re, p4); + vlr->ec= ME_V2V3+ME_V3V4; + if(a==0) vlr->ec+= ME_V1V2; + + vlr->flag= dl->rt; + vlr->lay= ob->lay; + + /* this is not really scientific: the vertices + * 2, 3 en 4 seem to give better vertexnormals than 1 2 3: + * front and backside treated different!! + */ + + if(frontside) + CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, vlr->n); + else + CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->n); + + vlr->mat= matar[ dl->col ]; + + p4= p3; + p3++; + p2= p1; + p1++; + } + } + + if (dl->bevelSplitFlag) { + for(a=0; aparts-1+!!(dl->flag&DL_CYCL_V); a++) + if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F))) + split_v_renderfaces(re, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U); + } + + /* vertex normals */ + for(a= startvlak; atotvlak; a++) { + vlr= RE_findOrAddVlak(re, a); + + VecAddf(vlr->v1->n, vlr->v1->n, vlr->n); + VecAddf(vlr->v3->n, vlr->v3->n, vlr->n); + VecAddf(vlr->v2->n, vlr->v2->n, vlr->n); + VecAddf(vlr->v4->n, vlr->v4->n, vlr->n); + } + for(a=startvert; atotvert; a++) { + ver= RE_findOrAddVert(re, a); + len= Normalise(ver->n); + if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */ + else ver->flag= 0; + } + for(a= startvlak; atotvlak; a++) { + vlr= RE_findOrAddVlak(re, a); + if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n); + if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n); + if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n); + if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n); + } + } + + dl= dl->next; + } +} + +/* prevent phong interpolation for giving ray shadow errors (terminator problem) */ +static void set_phong_threshold(Render *re, Object *ob, int startface, int numface, int startvert, int numvert ) +{ +// VertRen *ver; + VlakRen *vlr; + float thresh= 0.0, dot; + int tot=0, i; + + /* Added check for 'pointy' situations, only dotproducts of 0.9 and larger + are taken into account. This threshold is meant to work on smooth geometry, not + for extreme cases (ton) */ + + for(i=startface; iflag & R_SMOOTH) { + dot= INPR(vlr->n, vlr->v1->n); + dot= ABS(dot); + if(dot>0.9) { + thresh+= dot; tot++; + } + dot= INPR(vlr->n, vlr->v2->n); + dot= ABS(dot); + if(dot>0.9) { + thresh+= dot; tot++; + } + + dot= INPR(vlr->n, vlr->v3->n); + dot= ABS(dot); + if(dot>0.9) { + thresh+= dot; tot++; + } + + if(vlr->v4) { + dot= INPR(vlr->n, vlr->v4->n); + dot= ABS(dot); + if(dot>0.9) { + thresh+= dot; tot++; + } + } + } + } + + if(tot) { + thresh/= (float)tot; + ob->smoothresh= cos(0.5*M_PI-acos(thresh)); + } +} + +static void init_render_object(Render *re, Object *ob) +{ + float mat[4][4]; + int startface, startvert; + + startface=re->totvlak; + startvert=re->totvert; + + ob->flag |= OB_DONE; + + if(ob->type==OB_LAMP) + add_render_lamp(re, ob, 1); + else if ELEM(ob->type, OB_FONT, OB_CURVE) + init_render_curve(re, ob); + else if(ob->type==OB_SURF) + init_render_surf(re, ob); + else if(ob->type==OB_MESH) + init_render_mesh(re, ob); + else if(ob->type==OB_MBALL) + init_render_mball(re, ob); + else { + MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); + MTC_Mat4Invert(ob->imat, mat); + } + + /* generic post process here */ + if(startvert!=re->totvert) { + + /* the exception below is because displace code now is in init_render_mesh call, + I will look at means to have autosmooth enabled for all object types + and have it as general postprocess, like displace */ + if (ob->type!=OB_MESH && test_for_displace(re, ob ) ) + do_displacement(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert); + + /* phong normal interpolation can cause error in tracing (terminator prob) */ + ob->smoothresh= 0.0; + if( (re->r.mode & R_RAYTRACE) && (re->r.mode & R_SHADOW) ) + set_phong_threshold(re, ob, startface, re->totvlak-startface, startvert, re->totvert-startvert); + } +} + +void RE_Database_Free(Render *re) +{ + ShadBuf *shb; + Object *ob = NULL; + GroupObject *go; + unsigned long *ztile; + int b, v; + char *ctile; + + /* FREE */ + + if(re->memArena) { + BLI_memarena_free(re->memArena); + re->memArena = NULL; + } + + for(go= re->lights.first; go; go= go->next) { + struct LampRen *lar= go->lampren; + if(lar->shb) { + shb= lar->shb; + v= (shb->size*shb->size)/256; + ztile= shb->zbuf; + ctile= shb->cbuf; + for(b=0; bzbuf); + MEM_freeN(shb->cbuf); + MEM_freeN(lar->shb); + } + if(lar->jitter) MEM_freeN(lar->jitter); + MEM_freeN(lar); + } + + BLI_freelistN(&re->lights); + + free_renderdata_tables(re); + + /* free orco. check all objects because of duplis and sets */ + ob= G.main->object.first; + while(ob) { + if(ob->type==OB_MBALL) { + if(ob->disp.first && ob->disp.first!=ob->disp.last) { + DispList *dl= ob->disp.first; + BLI_remlink(&ob->disp, dl); + freedisplist(&ob->disp); + BLI_addtail(&ob->disp, dl); + } + } + ob= ob->id.next; + } + + free_mesh_orco_hash(re); + + end_radio_render(); + end_render_materials(); + + if(re->wrld.aosphere) { + MEM_freeN(re->wrld.aosphere); + re->wrld.aosphere= NULL; + re->scene->world->aosphere= NULL; + } + + if(re->r.mode & R_RAYTRACE) freeoctree(re); + + re->totvlak=re->totvert=re->totlamp=re->tothalo= 0; + re->i.convertdone= 0; + +} + +/* per face check if all samples should be taken. + if raytrace, do always for raytraced material, or when material full_osa set */ +static void set_fullsample_flag(Render *re) +{ + VlakRen *vlr; + int a, trace; + + trace= re->r.mode & R_RAYTRACE; + + for(a=re->totvlak-1; a>=0; a--) { + vlr= RE_findOrAddVlak(re, a); + + if(vlr->mat->mode & MA_FULL_OSA) vlr->flag |= R_FULL_OSA; + else if(trace) { + if(vlr->mat->mode & MA_SHLESS); + else if(vlr->mat->mode & (MA_RAYTRANSP|MA_RAYMIRROR|MA_SHADOW)) + vlr->flag |= R_FULL_OSA; + } + } +} + +/* 10 times larger than normal epsilon, test it on default nurbs sphere with ray_transp */ +#ifdef FLT_EPSILON +#undef FLT_EPSILON +#endif +#define FLT_EPSILON 1.19209290e-06F + + +static void check_non_flat_quads(Render *re) +{ + VlakRen *vlr, *vlr1; + VertRen *v1, *v2, *v3, *v4; + float nor[3], xn, flen; + int a; + + for(a=re->totvlak-1; a>=0; a--) { + vlr= RE_findOrAddVlak(re, a); + + /* test if rendering as a quad or triangle, skip wire */ + if(vlr->v4 && (vlr->flag & R_STRAND)==0 && (vlr->mat->mode & MA_WIRE)==0) { + + /* check if quad is actually triangle */ + v1= vlr->v1; + v2= vlr->v2; + v3= vlr->v3; + v4= vlr->v4; + VECSUB(nor, v1->co, v2->co); + if( ABS(nor[0])v1= v2; + vlr->v2= v3; + vlr->v3= v4; + vlr->v4= NULL; + } + else { + VECSUB(nor, v2->co, v3->co); + if( ABS(nor[0])v2= v3; + vlr->v3= v4; + vlr->v4= NULL; + } + else { + VECSUB(nor, v3->co, v4->co); + if( ABS(nor[0])v4= NULL; + } + else { + VECSUB(nor, v4->co, v1->co); + if( ABS(nor[0])v4= NULL; + } + } + } + } + + if(vlr->v4) { + + /* Face is divided along edge with the least gradient */ + /* Flagged with R_DIVIDE_24 if divide is from vert 2 to 4 */ + /* 4---3 4---3 */ + /* |\ 1| or |1 /| */ + /* |0\ | |/ 0| */ + /* 1---2 1---2 0 = orig face, 1 = new face */ + + /* render normals are inverted in render! we calculate normal of single tria here */ + flen= CalcNormFloat(vlr->v4->co, vlr->v3->co, vlr->v1->co, nor); + if(flen==0.0) CalcNormFloat(vlr->v4->co, vlr->v2->co, vlr->v1->co, nor); + + xn= nor[0]*vlr->n[0] + nor[1]*vlr->n[1] + nor[2]*vlr->n[2]; + if(ABS(xn) < 0.99995 ) { // checked on noisy fractal grid + float d1, d2; + + vlr1= RE_findOrAddVlak(re, re->totvlak++); + *vlr1= *vlr; + vlr1->flag |= R_FACE_SPLIT; + + /* split direction based on vnorms */ + CalcNormFloat(vlr->v1->co, vlr->v2->co, vlr->v3->co, nor); + d1= nor[0]*vlr->v1->n[0] + nor[1]*vlr->v1->n[1] + nor[2]*vlr->v1->n[2]; + + CalcNormFloat(vlr->v2->co, vlr->v3->co, vlr->v4->co, nor); + d2= nor[0]*vlr->v2->n[0] + nor[1]*vlr->v2->n[1] + nor[2]*vlr->v2->n[2]; + + if( fabs(d1) < fabs(d2) ) vlr->flag |= R_DIVIDE_24; + else vlr->flag &= ~R_DIVIDE_24; + + /* new vertex pointers */ + if (vlr->flag & R_DIVIDE_24) { + vlr1->v1= vlr->v2; + vlr1->v2= vlr->v3; + vlr1->v3= vlr->v4; + + vlr->v3 = vlr->v4; + + vlr1->flag |= R_DIVIDE_24; + } + else { + vlr1->v1= vlr->v1; + vlr1->v2= vlr->v3; + vlr1->v3= vlr->v4; + + vlr1->flag &= ~R_DIVIDE_24; + } + vlr->v4 = vlr1->v4 = NULL; + + /* new normals */ + CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + CalcNormFloat(vlr1->v3->co, vlr1->v2->co, vlr1->v1->co, vlr1->n); + + /* so later UV can be pulled from original tface, look for R_DIVIDE_24 for direction */ + vlr1->tface=vlr->tface; + + } + /* clear the flag when not divided */ + else vlr->flag &= ~R_DIVIDE_24; + } + } + } +} + +static void set_material_lightgroups(Render *re) +{ + GroupObject *go, *gol; + Material *ma; + + /* it's a bit too many loops in loops... but will survive */ + for(ma= G.main->mat.first; ma; ma=ma->id.next) { + if(ma->group) { + for(go= ma->group->gobject.first; go; go= go->next) { + for(gol= re->lights.first; gol; gol= gol->next) { + if(gol->ob==go->ob) { + go->lampren= gol->lampren; + break; + } + } + } + } + } +} + +void init_render_world(Render *re) +{ + int a; + char *cp; + + if(re->scene && re->scene->world) { + re->wrld= *(re->scene->world); + + cp= (char *)&re->wrld.fastcol; + + cp[0]= 255.0*re->wrld.horr; + cp[1]= 255.0*re->wrld.horg; + cp[2]= 255.0*re->wrld.horb; + cp[3]= 1; + + VECCOPY(re->grvec, re->viewmat[2]); + Normalise(re->grvec); + Mat3CpyMat4(re->imat, re->viewinv); + + for(a=0; awrld.mtex[a] && re->wrld.mtex[a]->tex) re->wrld.skytype |= WO_SKYTEX; + + while(re->wrld.aosamp*re->wrld.aosamp < re->osa) re->wrld.aosamp++; + } + else { + memset(&re->wrld, 0, sizeof(World)); + re->wrld.exp= 0.0; + re->wrld.range= 1.0; + } + + re->wrld.linfac= 1.0 + pow((2.0*re->wrld.exp + 0.5), -10); + re->wrld.logfac= log( (re->wrld.linfac-1.0)/re->wrld.linfac )/re->wrld.range; +} + +/* used to be 'rotate scene' */ +void RE_Database_FromScene(Render *re, Scene *scene, int use_camera_view) +{ + extern int slurph_opt; /* key.c */ + GroupObject *go; + Base *base; + Object *ob; + Scene *sce; + unsigned int lay; + float mat[4][4]; + + re->scene= scene; + + /* XXX add test if dbase was filled already? */ + + re->memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + re->totvlak=re->totvert=re->totlamp=re->tothalo= 0; + re->lights.first= re->lights.last= NULL; + + slurph_opt= 0; + + /* in localview, lamps are using normal layers, objects only local bits */ + if(re->scene->lay & 0xFF000000) lay= re->scene->lay & 0xFF000000; + else lay= re->scene->lay; + + /* applies changes fully */ + scene_update_for_newframe(re->scene, lay); + + /* if no camera, viewmat should have been set! */ + if(use_camera_view && re->scene->camera) { + Mat4Ortho(re->scene->camera->obmat); + Mat4Invert(mat, re->scene->camera->obmat); + RE_SetView(re, mat); + } + + init_render_world(re); /* do first, because of ambient. also requires re->osa set correct */ + if( (re->wrld.mode & WO_AMB_OCC) && (re->r.mode & R_RAYTRACE) ) { + re->wrld.aosphere= MEM_mallocN(2*3*re->wrld.aosamp*re->wrld.aosamp*sizeof(float), "AO sphere"); + /* we make twice the amount of samples, because only a hemisphere is used */ + init_ao_sphere(re->wrld.aosphere, 2*re->wrld.aosamp*re->wrld.aosamp, 16); + } + + /* still bad... doing all */ + init_render_textures(); + init_render_materials(re->osa, &re->wrld.ambr); + set_node_shader_lamp_loop(shade_material_loop); + + 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); + /* each object should only be rendered once */ + ob->flag &= ~OB_DONE; + } + + /* MAKE RENDER DATA */ + + for(SETLOOPER(re->scene, base)) { + ob= base->object; + + if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & re->scene->lay)) ) { + if(ob->transflag & OB_DUPLI) { + + /* exception: mballs! */ + /* yafray: Include at least one copy of a dupliframe object for yafray in the renderlist. + mballs comment above true as well for yafray, they are not included, only all other object types */ + if (re->r.renderer==R_YAFRAY) { + if ((ob->type!=OB_MBALL) && ((ob->transflag & OB_DUPLIFRAMES)!=0)) { + printf("Object %s has OB_DUPLIFRAMES set, adding to renderlist\n", ob->id.name); + init_render_object(re, ob); + } + } + /* before make duplis, update particle for current frame */ + if(ob->transflag & OB_DUPLIVERTS) { + PartEff *paf= give_parteff(ob); + if(paf) { + if(paf->flag & PAF_ANIMATED) build_particle_system(ob); + } + } + + if(ob->type==OB_MBALL) { + init_render_object(re, ob); + } + else { + DupliObject *dob; + ListBase *lb= object_duplilist(sce, ob); + + for(dob= lb->first; dob; dob= dob->next) { + Object *obd= dob->ob; + Mat4CpyMat4(obd->obmat, dob->mat); + + if(obd->type!=OB_MBALL) { + /* yafray: special handling of duplivert objects for yafray: + only the matrix is stored, together with the source object name. + Since the original object is needed as well, it is included in the renderlist (see above) + NOT done for lamps, these need to be included as normal lamps separately + correction: also ignore lattices, armatures and cameras (....) */ + if ((obd->type!=OB_LATTICE) && (obd->type!=OB_ARMATURE) && + (obd->type!=OB_LAMP) && (obd->type!=OB_CAMERA) && (re->r.renderer==R_YAFRAY)) + { + printf("Adding dupli matrix for object %s\n", obd->id.name); + YAF_addDupliMtx(obd); + } + else init_render_object(re, obd); + } + Mat4CpyMat4(obd->obmat, dob->omat); + } + BLI_freelistN(lb); + } + } + else { + /* yafray: if there are linked data objects (except lamps, empties or armatures), + yafray only needs to know about one, the rest can be instanciated. + The dupliMtx list is used for this purpose. + Exception: objects which have object linked materials, these cannot be instanciated. */ + if ((re->r.renderer==R_YAFRAY) && (ob->colbits==0)) + { + /* Special case, parent object dupli's: ignore if object itself is lamp or parent is lattice or empty */ + if (ob->parent) { + if ((ob->type!=OB_LAMP) && (ob->parent->type!=OB_EMPTY) && + (ob->parent->type!=OB_LATTICE) && YAF_objectKnownData(ob)) + printf("From parent: Added dupli matrix for linked data object %s\n", ob->id.name); + else + init_render_object(re, ob); + } + else if ((ob->type!=OB_EMPTY) && (ob->type!=OB_LAMP) && (ob->type!=OB_ARMATURE) && YAF_objectKnownData(ob)) + printf("Added dupli matrix for linked data object %s\n", ob->id.name); + else + init_render_object(re, ob); + } + else init_render_object(re, ob); + } + + } + + if(re->test_break()) break; + } + + + if(!re->test_break()) { + sort_halos(re); + + set_material_lightgroups(re); + + slurph_opt= 1; + + /* for now some clumsy copying still */ + re->i.totvert= re->totvert; + re->i.totface= re->totvlak; + re->i.tothalo= re->tothalo; + re->i.totlamp= re->totlamp; + re->stats_draw(&re->i); + + set_fullsample_flag(re); + check_non_flat_quads(re); + set_normalflags(re); + + /* SHADOW BUFFER */ + for(go=re->lights.first; go; go= go->next) { + LampRen *lar= go->lampren; + + if(re->test_break()) break; + if(lar->shb) { + makeshadowbuf(re, lar); + } + } + + /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */ + /* although radio mode could be useful at some point, later */ + if (re->r.renderer==R_INTERN) { + /* RADIO (uses no R anymore) */ + if(!re->test_break()) + if(re->r.mode & R_RADIO) do_radio_render(re); + + /* octree */ + if(!re->test_break()) + if(re->r.mode & R_RAYTRACE) makeoctree(re); + + /* ENVIRONMENT MAPS */ + if(!re->test_break()) + make_envmaps(re); + } + + if(!re->test_break()) + project_renderdata(re, projectverto, re->r.mode & R_PANORAMA, 0); + } + + if(re->test_break()) + RE_Database_Free(re); + else + re->i.convertdone= 1; + +} + +/* exported call to recalculate hoco for vertices, when winmat changed */ +void RE_DataBase_ApplyWindow(Render *re) +{ + project_renderdata(re, projectverto, 0, 0); +} + +/* **************************************************************** */ +/* Displacement mapping */ +/* **************************************************************** */ +static short test_for_displace(Render *re, Object *ob) +{ + /* return 1 when this object uses displacement textures. */ + Material *ma; + int i; + + for (i=1; i<=ob->totcol; i++) { + ma=give_render_material(re, ob, i); + /* ma->mapto is ORed total of all mapto channels */ + if(ma && (ma->mapto & MAP_DISPLACE)) return 1; + } + return 0; +} + +static void displace_render_vert(Render *re, ShadeInput *shi, VertRen *vr, float *scale) +{ + short texco= shi->mat->texco; + float sample=0; + /* shi->co is current render coord, just make sure at least some vector is here */ + VECCOPY(shi->co, vr->co); + /* vertex normal is used for textures type 'col' and 'var' */ + VECCOPY(shi->vn, vr->n); + + /* set all rendercoords, 'texco' is an ORed value for all textures needed */ + if ((texco & TEXCO_ORCO) && (vr->orco)) { + VECCOPY(shi->lo, vr->orco); + } + if (texco & TEXCO_STICKY) { + float *sticky= RE_vertren_get_sticky(re, vr, 0); + if(sticky) { + shi->sticky[0]= sticky[0]; + shi->sticky[1]= sticky[1]; + shi->sticky[2]= 0.0f; + } + } + if (texco & TEXCO_GLOB) { + VECCOPY(shi->gl, shi->co); + MTC_Mat4MulVecfl(re->viewinv, shi->gl); + } + if (texco & TEXCO_NORM) { + VECCOPY(shi->orn, shi->vn); + } + if(texco & TEXCO_REFL) { + /* not (yet?) */ + } + + shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; + + do_material_tex(shi); + + //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2], + //vr->co[0], vr->co[1], vr->co[2]); + + /* 0.5 could become button once? */ + vr->co[0] += shi->displace[0] * scale[0] ; + vr->co[1] += shi->displace[1] * scale[1] ; + vr->co[2] += shi->displace[2] * scale[2] ; + + //printf("after co=%f, %f, %f\n", vr->co[0], vr->co[1], vr->co[2]); + + /* we just don't do this vertex again, bad luck for other face using same vertex with + different material... */ + vr->flag |= 1; + + /* Pass sample back so displace_face can decide which way to split the quad */ + sample = shi->displace[0]*shi->displace[0]; + sample += shi->displace[1]*shi->displace[1]; + sample += shi->displace[2]*shi->displace[2]; + + vr->accum=sample; + /* Should be sqrt(sample), but I'm only looking for "bigger". Save the cycles. */ + return; +} + +static void displace_render_face(Render *re, VlakRen *vlr, float *scale) +{ + ShadeInput shi; + // VertRen vr; + // float samp1,samp2, samp3, samp4, xn; + short hasuv=0; + /* set up shadeinput struct for multitex() */ + + shi.osatex= 0; /* signal not to use dx[] and dy[] texture AA vectors */ + shi.vlr= vlr; /* current render face */ + shi.mat= vlr->mat; /* current input material */ + + + /* UV coords must come from face */ + hasuv = vlr->tface && (shi.mat->texco & TEXCO_UV); + if (hasuv) shi.uv[2]=0.0f; + /* I don't think this is used, but seting it just in case */ + + /* Displace the verts, flag is set when done */ + if (! (vlr->v1->flag)){ + if (hasuv) { + shi.uv[0] = 2*vlr->tface->uv[0][0]-1.0f; /* shi.uv and tface->uv are */ + shi.uv[1]= 2*vlr->tface->uv[0][1]-1.0f; /* scalled differently */ + } + displace_render_vert(re, &shi, vlr->v1, scale); + } + + if (! (vlr->v2->flag)) { + if (hasuv) { + shi.uv[0] = 2*vlr->tface->uv[1][0]-1.0f; + shi.uv[1]= 2*vlr->tface->uv[1][1]-1.0f; + } + displace_render_vert(re, &shi, vlr->v2, scale); + } + + if (! (vlr->v3->flag)) { + if (hasuv) { + shi.uv[0] = 2*vlr->tface->uv[2][0]-1.0f; + shi.uv[1]= 2*vlr->tface->uv[2][1]-1.0f; + } + displace_render_vert(re, &shi, vlr->v3, scale); + } + + if (vlr->v4) { + if (! (vlr->v4->flag)) { + if (hasuv) { + shi.uv[0] = 2*vlr->tface->uv[3][0]-1.0f; + shi.uv[1]= 2*vlr->tface->uv[3][1]-1.0f; + } + displace_render_vert(re, &shi, vlr->v4, scale); + } + /* We want to split the quad along the opposite verts that are */ + /* closest in displace value. This will help smooth edges. */ + if ( fabs(vlr->v1->accum - vlr->v3->accum) > fabs(vlr->v2->accum - vlr->v4->accum)) + vlr->flag |= R_DIVIDE_24; + else vlr->flag &= ~R_DIVIDE_24; // E: typo?, was missing '=' + } + + /* Recalculate the face normal - if flipped before, flip now */ + if(vlr->v4) { + CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + } + else { + CalcNormFloat(vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); + } + +} + + +static void do_displacement(Render *re, Object *ob, int startface, int numface, int startvert, int numvert ) +{ + VertRen *vr; + VlakRen *vlr; +// float min[3]={1e30, 1e30, 1e30}, max[3]={-1e30, -1e30, -1e30}; + float scale[3]={1.0f, 1.0f, 1.0f}, temp[3];//, xn + int i; //, texflag=0; + Object *obt; + + /* Object Size with parenting */ + obt=ob; + while(obt){ + VecAddf(temp, obt->size, obt->dsize); + scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2]; + obt=obt->parent; + } + + /* Clear all flags */ + for(i=startvert; iflag= 0; + } + + for(i=startface; i /* INT_MIN,MAX are used here */ #include +#include "DNA_material_types.h" + #include "MEM_guardedalloc.h" #include "MTC_vectorops.h" #include "BKE_utildefines.h" +#include "BLI_jitter.h" -#include "RE_callbacks.h" +#include "render_types.h" +#include "renderpipeline.h" #include "edgeRender.h" -#include "render.h" #include "zbuf.h" /* for zbufclipwire and zbufclip */ -#include "jitter.h" -#ifdef RE_EDGERENDERSAFE -char edgeRender_h[] = EDGERENDER_H; -char edgeRender_c[] = "$Id$"; -#include "errorHandler.h" -#endif -/* ------------------------------------------------------------------------- */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - /* These function pointers are used for z buffer filling. */ -extern float Zmulx, Zmuly; /* Some kind of scale? */ -extern float Zjitx,Zjity; /* The x,y values for jitter offset */ - -/* ------------------------------------------------------------------------- */ /* exp: */ static Material** matBuffer; /* buffer with material indices */ @@ -111,64 +104,59 @@ static char edgeB; /** * Initialise the edge render buffer memory. */ -void initEdgeRenderBuffer(void); +static void initEdgeRenderBuffer(void); /** * Release buffer memory. */ -void freeEdgeRenderBuffer(void); +static void freeEdgeRenderBuffer(void); /** * Set all distances in the distance buffer to the maximum distance. */ -void resetDistanceBuffer(void); +static void resetDistanceBuffer(void); /** * Insert this distance at these pixel coordinates. */ -void insertInEdgeBuffer(int x, int y, int dist); +static void insertInEdgeBuffer(int x, int y, int dist); /** * Renders enhanced edges. Distances from distRect are used to * determine a correction on colourRect */ -void renderEdges(char * colourRect); +static void renderEdges(char * colourRect); /** * Buffer an edge between these two vertices in the e.r. distance buffer. */ -static void fillEdgeRenderEdge(int, float *vec1, float *vec2); +static void fillEdgeRenderEdge(ZSpan *zspan, int, float *vec1, float *vec2); /** * Buffer a face between these two vertices in the e.r. distance buffer. */ -static void fillEdgeRenderFace(struct ZSpan *zspan, int, float *v1, float *v2, float *v3); +static void fillEdgeRenderFace(struct ZSpan *zspan, int, float *v1, float *v2, float *v3, float *v4); /** * Compose the edge render colour buffer. */ -void calcEdgeRenderColBuf(char * tarbuf); +static void calcEdgeRenderColBuf(char * tarbuf); /** * Loop over all objects that need to be edge rendered. This loop determines * which objects get to be elected for edge rendering. */ -int zBufferEdgeRenderObjects(void); +static int zBufferEdgeRenderObjects(void); /** * Add edge pixels to the original image. It blends over . */ -void addEdgeOver(unsigned char *dst, unsigned char *src); +static void addEdgeOver(unsigned char *dst, unsigned char *src); /* ------------------------------------------------------------------------- */ -void addEdges( - char * targetbuf, - int iw, int ih, - int osanr, - short int intens, short int intens_redux, - int compat, int mode, - float r, float g, float b - ) +/* this is main call! */ +void addEdges(char * targetbuf, int iw, int ih, int osanr, + short int intens, short int intens_redux, int compat, int mode, float r, float g, float b) { float rf, gf ,bf; /* render parameters */ @@ -178,6 +166,10 @@ void addEdges( compatible_mode = compat; osaCount = osanr; intensity = intens; + + printf("Unsuported code!\n"); + return; + /* Reduction doesn't exceed intensity. */ same_mat_redux = ((intens_redux < intensity)? intens_redux : intensity); @@ -197,7 +189,7 @@ void addEdges( /* ------------------------------------------------------------------------- */ -void initEdgeRenderBuffer() +static void initEdgeRenderBuffer() { char *ptr; int i; @@ -230,16 +222,10 @@ void initEdgeRenderBuffer() } } -#ifdef RE_EDGERENDERSAFE - if (!edgeBuffer || !colBuffer) { - char *fname = "initEdgeRenderBuffer"; - RE_error(RE_CANNOT_ALLOCATE_MEMORY, fname); - } -#endif } /* end of void initEdgeRenderBuffer(void) */ /* ------------------------------------------------------------------------- */ -void freeEdgeRenderBuffer(void) +static void freeEdgeRenderBuffer(void) { if(edgeBuffer) MEM_freeN(edgeBuffer); edgeBuffer= NULL; @@ -251,7 +237,7 @@ void freeEdgeRenderBuffer(void) /* ------------------------------------------------------------------------- */ -void resetDistanceBuffer(void) +static void resetDistanceBuffer(void) { int i; for(i = 0; i < bufWidth * bufHeight; i++) edgeBuffer[i] = 0x7FFFFFFF; @@ -259,17 +245,9 @@ void resetDistanceBuffer(void) /* ------------------------------------------------------------------------- */ -void insertInEdgeBuffer(int x, int y, int dist) +static void insertInEdgeBuffer(int x, int y, int dist) { int index; -#ifdef RE_EDGERENDERSAFE - char *fname = "insertInEdgeBuffer"; - if ((x < 0) || (x > imWidth ) || - (y < 0) || (y > (imHeight-1) ) ) { - RE_error(RE_EDGERENDER_WRITE_OUTSIDE_BUFFER, fname); - return; - } -#endif /* +1? */ index = (y * bufWidth) + x + maskBorder; @@ -286,7 +264,7 @@ void insertInEdgeBuffer(int x, int y, int dist) /* ------------------------------------------------------------------------- */ /* Modelled after rendercore.c/edge_enhance() */ -void renderEdges(char *colourRect) +static void renderEdges(char *colourRect) { /* use zbuffer to define edges, add it to the image */ int val, y, x, col, *rz, *rz1, *rz2, *rz3; @@ -496,7 +474,7 @@ void renderEdges(char *colourRect) /* ------------------------------------------------------------------------- */ /* adds src to dst */ -void addEdgeOver(unsigned char *dst, unsigned char *src) +static void addEdgeOver(unsigned char *dst, unsigned char *src) { unsigned char inverse; unsigned char alpha; @@ -534,20 +512,15 @@ void addEdgeOver(unsigned char *dst, unsigned char *src) dst[2] = c; } -void calcEdgeRenderColBuf(char* colTargetBuffer) +static void calcEdgeRenderColBuf(char* colTargetBuffer) { - int keepLooping = 1; int sample; /* zbuffer fix: here? */ - Zmulx= ((float) imWidth)/2.0; - Zmuly= ((float) imHeight)/2.0; +// Zmulx= ((float) imWidth)/2.0; +// Zmuly= ((float) imHeight)/2.0; - /* use these buffer fill functions */ - zbuffunc = fillEdgeRenderFace; - zbuflinefunc = fillEdgeRenderEdge; - /* always buffer the max. extent */ Aminy = 0; Amaxy = imHeight; @@ -555,8 +528,8 @@ void calcEdgeRenderColBuf(char* colTargetBuffer) sample = 0; /* Zsample is used internally ! */ while ( (sample < osaCount) && keepLooping ) { /* jitter */ - Zjitx= -jit[sample][0]; - Zjity= -jit[sample][1]; +// Zjitx= -R.jit[sample][0]; +// Zjity= -R.jit[sample][1]; /* should reset dis buffer here */ resetDistanceBuffer(); @@ -567,7 +540,7 @@ void calcEdgeRenderColBuf(char* colTargetBuffer) /* do filtering */ renderEdges(colTargetBuffer); - if(RE_local_test_break()) keepLooping = 0; + if(R.test_break()) keepLooping = 0; sample++; } @@ -589,13 +562,28 @@ void calcEdgeRenderColBuf(char* colTargetBuffer) /* ------------------------------------------------------------------------- */ /* Clip flags etc. should still be set. When called in the span of 'normal' */ /* rendering, this should be ok. */ -int zBufferEdgeRenderObjects(void) +static int zBufferEdgeRenderObjects(void) { + ZSpan zspan; VlakRen *vlr= NULL; + Material *ma; unsigned int zvlnr; int keepLooping; int faceCounter; /* counter for face number */ - Material *ma; + + zbuf_alloc_span(&zspan, imWidth, imHeight); + + /* needed for transform from hoco to zbuffer co */ + zspan.zmulx= ((float)imWidth)/2.0; + zspan.zmuly= ((float)imHeight)/2.0; + zspan.zofsx= -0.5f; + zspan.zofsy= -0.5f; + + /* the buffers ??? */ + + /* filling methods */ + zspan.zbuffunc = fillEdgeRenderFace; + zspan.zbuflinefunc = fillEdgeRenderEdge; keepLooping = 1; ma = NULL; @@ -618,19 +606,19 @@ int zBufferEdgeRenderObjects(void) /* here we cull all transparent faces if mode == 0 */ if (selectmode || !(ma->mode & MA_ZTRA)) { /* here we can add all kinds of extra selection criteria */ - if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); + if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr); else { - zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, + zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); if(vlr->v4) { zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ - zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, + zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); } } } }; - if(RE_local_test_break()) keepLooping = 0; + if(R.test_break()) keepLooping = 0; faceCounter++; } return keepLooping; @@ -638,7 +626,7 @@ int zBufferEdgeRenderObjects(void) /* ------------------------------------------------------------------------- */ -static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) +static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) { /* Coordinates of the vertices are specified in ZCS */ double z0; /* used as temp var*/ @@ -846,7 +834,7 @@ static void fillEdgeRenderFace(struct ZSpan *zspan, int zvlnr, float *v1, float /* ------------------------------------------------------------------------- */ -static void fillEdgeRenderEdge(int zvlnr, float *vec1, float *vec2) +static void fillEdgeRenderEdge(ZSpan *zspan, int zvlnr, float *vec1, float *vec2) { int start, end, x, y, oldx, oldy, ofs; int dz, vergz/* , mask */; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index e38d7e0d740..80e902e2a45 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -1,15 +1,12 @@ - -/* envmap.c RENDER +/* + * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,24 +20,14 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * Contributors: 2004/2005/2006 Blender Foundation, full recode * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * - * may 1999 - * - * $Id$ + * ***** END GPL LICENSE BLOCK ***** */ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - /* external modules: */ #include "MEM_guardedalloc.h" #include "BLI_arithb.h" @@ -50,7 +37,7 @@ #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" /* for rectcpy */ -#include "DNA_texture_types.h" +#include "DNA_group_types.h" #include "DNA_image_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -59,8 +46,8 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_global.h" -#include "BKE_world.h" // init_render_world #include "BKE_image.h" // BKE_write_ibuf +#include "BKE_texture.h" #include "MTC_matrixops.h" @@ -69,79 +56,16 @@ #define main main /* stupid SDL_main redefines main as SDL_main */ /* this module */ -#include "RE_callbacks.h" -#include "render.h" +#include "render_types.h" +#include "renderpipeline.h" #include "envmap.h" -#include "mydevice.h" #include "rendercore.h" -#include "renderHelp.h" +#include "renderdatabase.h" #include "texture.h" #include "zbuf.h" +#include "initrender.h" -/* ------------------------------------------------------------------------- */ - -EnvMap *RE_add_envmap(void) -{ - EnvMap *env; - - env= MEM_callocN(sizeof(EnvMap), "envmap"); - env->type= ENV_CUBE; - env->stype= ENV_STATIC; - env->clipsta= 0.1; - env->clipend= 100.0; - env->cuberes= 100; - - return env; -} /* end of EnvMap *RE_add_envmap() */ - -/* ------------------------------------------------------------------------- */ - -EnvMap *RE_copy_envmap(EnvMap *env) -{ - EnvMap *envn; - int a; - - envn= MEM_dupallocN(env); - envn->ok= 0; - for(a=0; a<6; a++) envn->cube[a]= 0; - if(envn->ima) id_us_plus((ID *)envn->ima); - - return envn; -} - -/* ------------------------------------------------------------------------- */ - -void RE_free_envmapdata(EnvMap *env) -{ - Image *ima; - unsigned int a, part; - - for(part=0; part<6; part++) { - ima= env->cube[part]; - if(ima) { - if(ima->ibuf) IMB_freeImBuf(ima->ibuf); - - for(a=0; amipmap); a++) { - if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]); - } - MEM_freeN(ima); - env->cube[part]= 0; - } - } - env->ok= 0; -} - -/* ------------------------------------------------------------------------- */ - -void RE_free_envmap(EnvMap *env) -{ - - RE_free_envmapdata(env); - MEM_freeN(env); - -} - /* ------------------------------------------------------------------------- */ static void envmap_split_ima(EnvMap *env) @@ -151,7 +75,7 @@ static void envmap_split_ima(EnvMap *env) /* extern rectcpy(); */ int dx, part; - RE_free_envmapdata(env); + BKE_free_envmapdata(env); dx= env->ima->ibuf->y; dx/= 2; @@ -168,18 +92,18 @@ static void envmap_split_ima(EnvMap *env) ima->ok= 1; env->cube[part]= ima; } - IMB_rectop(env->cube[0]->ibuf, env->ima->ibuf, - 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[1]->ibuf, env->ima->ibuf, - 0, 0, dx, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[2]->ibuf, env->ima->ibuf, - 0, 0, 2*dx, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[3]->ibuf, env->ima->ibuf, - 0, 0, 0, dx, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[4]->ibuf, env->ima->ibuf, - 0, 0, dx, dx, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[5]->ibuf, env->ima->ibuf, - 0, 0, 2*dx, dx, dx, dx, IMB_rectcpy, 0); + IMB_rectcpy(env->cube[0]->ibuf, env->ima->ibuf, + 0, 0, 0, 0, dx, dx); + IMB_rectcpy(env->cube[1]->ibuf, env->ima->ibuf, + 0, 0, dx, 0, dx, dx); + IMB_rectcpy(env->cube[2]->ibuf, env->ima->ibuf, + 0, 0, 2*dx, 0, dx, dx); + IMB_rectcpy(env->cube[3]->ibuf, env->ima->ibuf, + 0, 0, 0, dx, dx, dx); + IMB_rectcpy(env->cube[4]->ibuf, env->ima->ibuf, + 0, 0, dx, dx, dx, dx); + IMB_rectcpy(env->cube[5]->ibuf, env->ima->ibuf, + 0, 0, 2*dx, dx, dx, dx); env->ok= 2; } } @@ -187,52 +111,77 @@ static void envmap_split_ima(EnvMap *env) /* ------------------------------------------------------------------------- */ /* ****************** RENDER ********************** */ -static void envmap_renderdata(EnvMap *env) +/* copy current render */ +static Render *envmap_render_copy(Render *re, EnvMap *env) { - extern void init_filt_mask(void); - static RE_Render envR; - static Object *camera; + Render *envre; int cuberes; - if(env) { - envR= R; - camera= G.scene->camera; - - cuberes = (env->cuberes * R.r.size) / 100; - cuberes &= 0xFFFC; - env->lastsize= R.r.size; - R.rectx= R.r.xsch= R.recty= R.r.ysch= cuberes; - R.afmx= R.afmy= R.r.xsch/2; - R.xstart= R.ystart= -R.afmx; - R.xend= R.yend= R.xstart+R.rectx-1; - - R.r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); - R.r.filtertype= 0; - R.r.xparts= R.r.yparts= 1; - R.r.bufflag= 0; - R.r.size= 100; - R.ycor= 1.0; - R.r.yasp= R.r.xasp= 1; - - R.near= env->clipsta; - R.far= env->clipend; - - G.scene->camera= env->object; - - } - else { - /* this to make sure init_renderdisplay works */ - envR.winx= R.winx; - envR.winy= R.winy; - envR.winxof= R.winxof; - envR.winyof= R.winyof; - - R= envR; - G.scene->camera= camera; - } + envre= RE_NewRender("Envmap"); - /* gauss, gamma, etc */ - init_filt_mask(); + env->lastsize= re->r.size; + cuberes = (env->cuberes * re->r.size) / 100; + cuberes &= 0xFFFC; + + /* set up renderdata */ + envre->r= re->r; + envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); + envre->r.layers.first= envre->r.layers.last= NULL; + envre->r.filtertype= 0; + envre->r.xparts= envre->r.yparts= 2; + envre->r.bufflag= 0; + envre->r.size= 100; + envre->r.yasp= envre->r.xasp= 1; + + RE_InitState(envre, &re->r, cuberes, cuberes, NULL); + envre->scene= re->scene; /* unsure about this... */ + + /* view stuff in env render */ + envre->ycor= 1.0; + envre->clipsta= env->clipsta; /* render_scene_set_window() respects this for now */ + envre->clipend= env->clipend; + + RE_SetCamera(envre, env->object); + + /* callbacks */ + envre->display_draw= re->display_draw; + envre->test_break= re->test_break; + + /* and for the evil stuff; copy the database... */ + envre->totvlak= re->totvlak; + envre->totvert= re->totvert; + envre->tothalo= re->tothalo; + envre->totlamp= re->totlamp; + envre->lights= re->lights; + envre->vertnodeslen= re->vertnodeslen; + envre->vertnodes= re->vertnodes; + envre->blohalen= re->blohalen; + envre->bloha= re->bloha; + envre->blovllen= re->blovllen; + envre->blovl= re->blovl; + envre->oc= re->oc; + + return envre; +} + +static void envmap_free_render_copy(Render *envre) +{ + + envre->totvlak= 0; + envre->totvert= 0; + envre->tothalo= 0; + envre->totlamp= 0; + envre->lights.first= envre->lights.last= NULL; + envre->vertnodeslen= 0; + envre->vertnodes= NULL; + envre->blohalen= 0; + envre->bloha= NULL; + envre->blovllen= 0; + envre->blovl= NULL; + envre->oc.adrbranch= NULL; + envre->oc.adrnode= NULL; + + RE_FreeRender(envre); } /* ------------------------------------------------------------------------- */ @@ -269,8 +218,9 @@ static void envmap_transmatrix(float mat[][4], int part) /* ------------------------------------------------------------------------- */ -static void env_rotate_scene(float mat[][4], int mode) +static void env_rotate_scene(Render *re, float mat[][4], int mode) { + GroupObject *go; VlakRen *vlr = NULL; VertRen *ver = NULL; LampRen *lar = NULL; @@ -287,8 +237,8 @@ static void env_rotate_scene(float mat[][4], int mode) MTC_Mat3CpyMat4(imat, mat); } - for(a=0; a>8]; + for(a=0; atotvert; a++) { + if((a & 255)==0) ver= RE_findOrAddVert(re, a); else ver++; MTC_Mat4MulVecfl(tmat, ver->co); @@ -303,15 +253,15 @@ static void env_rotate_scene(float mat[][4], int mode) Normalise(ver->n); } - for(a=0; a>8]; + for(a=0; atothalo; a++) { + if((a & 255)==0) har= re->bloha[a>>8]; else har++; MTC_Mat4MulVecfl(tmat, har->co); } - for(a=0; a>8]; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; xn= vlr->n[0]; @@ -324,10 +274,10 @@ static void env_rotate_scene(float mat[][4], int mode) Normalise(vlr->n); } - set_normalflags(); + set_normalflags(re); - for(a=0; alights.first; go; go= go->next) { + lar= go->lampren; /* removed here some horrible code of someone in NaN who tried to fix prototypes... just solved by introducing a correct cmat[3][3] instead @@ -358,25 +308,25 @@ static void env_rotate_scene(float mat[][4], int mode) /* ------------------------------------------------------------------------- */ -static void env_layerflags(unsigned int notlay) +static void env_layerflags(Render *re, unsigned int notlay) { VlakRen *vlr = NULL; int a; - for(a=0; a>8]; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->lay & notlay) vlr->flag &= ~R_VISIBLE; } } -static void env_hideobject(Object *ob) +static void env_hideobject(Render *re, Object *ob) { VlakRen *vlr = NULL; int a; - for(a=0; a>8]; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->ob == ob) vlr->flag &= ~R_VISIBLE; } @@ -384,14 +334,14 @@ static void env_hideobject(Object *ob) /* ------------------------------------------------------------------------- */ -static void env_set_imats() +static void env_set_imats(Render *re) { Base *base; float mat[4][4]; base= G.scene->base.first; while(base) { - MTC_Mat4MulMat4(mat, base->object->obmat, R.viewmat); + MTC_Mat4MulMat4(mat, base->object->obmat, re->viewmat); MTC_Mat4Invert(base->object->imat, mat); base= base->next; @@ -401,112 +351,97 @@ static void env_set_imats() /* ------------------------------------------------------------------------- */ -static void render_envmap(EnvMap *env) +static void render_envmap(Render *re, EnvMap *env) { /* only the cubemap is implemented */ + Render *envre; ImBuf *ibuf; Image *ima; float oldviewinv[4][4], mat[4][4], tmat[4][4]; short part; /* need a recalc: ortho-render has no correct viewinv */ - MTC_Mat4Invert(oldviewinv, R.viewmat); + MTC_Mat4Invert(oldviewinv, re->viewmat); - /* do first, envmap_renderdata copies entire R struct */ - if(R.rectz) MEM_freeN(R.rectz); R.rectz= NULL; - if(R.rectot) MEM_freeN(R.rectot); R.rectot= NULL; - if(R.rectftot) MEM_freeN(R.rectftot); R.rectftot= NULL; + envre= envmap_render_copy(re, env); - /* setup necessary globals */ - envmap_renderdata(env); - - RE_local_init_render_display(); - - R.rectot= MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectot"); - R.rectz= MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz"); +// re->display_init(envre->result); for(part=0; part<6; part++) { - RE_local_clear_render_display(R.win); - fillrect(R.rectot, R.rectx, R.recty, 0); + re->display_clear(envre->result); - RE_setwindowclip(1,-1); /* no jit:(-1) */ - - MTC_Mat4CpyMat4(tmat, G.scene->camera->obmat); + MTC_Mat4CpyMat4(tmat, env->object->obmat); MTC_Mat4Ortho(tmat); envmap_transmatrix(tmat, part); MTC_Mat4Invert(mat, tmat); /* mat now is the camera 'viewmat' */ - MTC_Mat4CpyMat4(R.viewmat, mat); - MTC_Mat4CpyMat4(R.viewinv, tmat); + MTC_Mat4CpyMat4(envre->viewmat, mat); + MTC_Mat4CpyMat4(envre->viewinv, tmat); /* we have to correct for the already rotated vertexcoords */ - MTC_Mat4MulMat4(tmat, oldviewinv, R.viewmat); + MTC_Mat4MulMat4(tmat, oldviewinv, envre->viewmat); MTC_Mat4Invert(env->imat, tmat); - env_rotate_scene(tmat, 1); - init_render_world(); - setzbufvlaggen(RE_projectverto); - env_layerflags(env->notlay); - env_hideobject(env->object); - env_set_imats(); + env_rotate_scene(envre, tmat, 1); + init_render_world(envre); + project_renderdata(envre, projectverto, 0, 0); + env_layerflags(envre, env->notlay); + env_hideobject(envre, env->object); + env_set_imats(envre); - if(RE_local_test_break()==0) { - - RE_local_printrenderinfo(0.0, part); - - if(R.r.mode & R_OSA) zbufshadeDA(); - else zbufshade(); - + if(re->test_break()==0) { + RE_TileProcessor(envre); } /* rotate back */ - env_rotate_scene(tmat, 0); + env_rotate_scene(envre, tmat, 0); - if(RE_local_test_break()==0) { - ibuf= IMB_allocImBuf(R.rectx, R.recty, 24, IB_rect, 0); + if(re->test_break()==0) { + RenderLayer *rl= envre->result->layers.first; + + ibuf= IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect, 0); + ibuf->rect_float= rl->rectf; + IMB_rect_from_float(ibuf); + ibuf->rect_float= NULL; + ima= MEM_callocN(sizeof(Image), "image"); - memcpy(ibuf->rect, R.rectot, 4*ibuf->x*ibuf->y); + ima->ibuf= ibuf; ima->ok= 1; env->cube[part]= ima; } - if(RE_local_test_break()) break; + if(re->test_break()) break; } - if(R.rectz) MEM_freeN(R.rectz); R.rectz= NULL; - if(R.rectot) MEM_freeN(R.rectot); R.rectot= NULL; - if(R.rectftot) MEM_freeN(R.rectftot); R.rectftot= NULL; - - if(RE_local_test_break()) RE_free_envmapdata(env); + if(re->test_break()) BKE_free_envmapdata(env); else { - if(R.r.mode & R_OSA) env->ok= ENV_OSA; + if(envre->r.mode & R_OSA) env->ok= ENV_OSA; else env->ok= ENV_NORMAL; - env->lastframe= G.scene->r.cfra; + env->lastframe= G.scene->r.cfra; /* hurmf */ } /* restore */ - envmap_renderdata(0); - env_set_imats(); - init_render_world(); + envmap_free_render_copy(envre); + env_set_imats(re); } /* ------------------------------------------------------------------------- */ -void make_envmaps() +void make_envmaps(Render *re) { Tex *tex; int do_init= 0, depth= 0, trace; - if (!(R.r.mode & R_ENVMAP)) return; + if (!(re->r.mode & R_ENVMAP)) return; /* we dont raytrace, disabling the flag will cause ray_transp render solid */ - trace= (R.r.mode & R_RAYTRACE); - R.r.mode &= ~R_RAYTRACE; + trace= (re->r.mode & R_RAYTRACE); + re->r.mode &= ~R_RAYTRACE; /* 5 = hardcoded max recursion level */ while(depth<5) { @@ -524,21 +459,21 @@ void make_envmaps() if(tex->env->ok) { /* free when OSA, and old one isn't OSA */ - if((R.r.mode & R_OSA) && tex->env->ok==ENV_NORMAL) - RE_free_envmapdata(tex->env); + if((re->r.mode & R_OSA) && tex->env->ok==ENV_NORMAL) + BKE_free_envmapdata(tex->env); /* free when size larger */ - else if(tex->env->lastsize < R.r.size) - RE_free_envmapdata(tex->env); + else if(tex->env->lastsize < re->r.size) + BKE_free_envmapdata(tex->env); /* free when env is in recalcmode */ else if(tex->env->recalc) - RE_free_envmapdata(tex->env); + BKE_free_envmapdata(tex->env); } if(tex->env->ok==0 && depth==0) tex->env->recalc= 1; if(tex->env->ok==0) { do_init= 1; - render_envmap(tex->env); + render_envmap(re, tex->env); if(depth==tex->env->depth) tex->env->recalc= 0; } @@ -553,12 +488,12 @@ void make_envmaps() } if(do_init) { - RE_local_init_render_display(); - RE_local_clear_render_display(R.win); - R.flag |= R_REDRAW_PRV; + re->display_init(re->result); + re->display_clear(re->result); + re->flag |= R_REDRAW_PRV; } // restore - R.r.mode |= trace; + re->r.mode |= trace; } @@ -640,6 +575,7 @@ static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int fac int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { extern SDL_mutex *load_ibuf_lock; // initrender.c + extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ EnvMap *env; Image *ima; diff --git a/source/blender/render/intern/source/errorHandler.c b/source/blender/render/intern/source/errorHandler.c deleted file mode 100644 index 0ab927a9cd9..00000000000 --- a/source/blender/render/intern/source/errorHandler.c +++ /dev/null @@ -1,102 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Error handler for the rendering code. Maybe also useful elsewhere? - */ - -#include "GEN_messaging.h" -#include "stdio.h" - -#include "errorHandler.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* ------------------------------------------------------------------------- */ - -/* counters for error handling */ -static int lastError; /* code of last encountered error */ -static int errorCount; /* count how many time it occured */ -/* ------------------------------------------------------------------------- */ - -char errorStrings[RE_MAX_ERROR][100] = { - "0: No error", - "1: recalculated depth falls outside original range", - "2: invalid face/halo type", - "3: invalid face index", - "4: invalid data pointer", - "5: generic trace counter", - "6: overflow on z buffer depth", - "7: write outside edgerender buffer", - "8: cannot allocate memory", - "9: write outside colour target buffer", -}; - -/* ------------------------------------------------------------------------- */ - -void RE_errortrace_reset(void) -{ - lastError = RE_NO_ERROR; - errorCount = 0; -} - -void RE_error(int errType, char* fname) -{ - /* - * This memory behaviour should move to the generic stream... - */ - - if (lastError == errType) { - int teller; - errorCount++; - for (teller = 0; teller < 12; teller++) - fprintf(GEN_errorstream, "%c", 0x08); /* backspaces */ - fprintf(GEN_errorstream, "( %8u )", errorCount); - } else { - fprintf(GEN_errorstream, "\n*** %s: %s ", - fname, errorStrings[errType]); - lastError = errType; - errorCount = 1; - } -} /* end of void RE_error(int errType, char* errText) */ - -/* ------------------------------------------------------------------------- */ -/* note: non-repeating */ -void RE_error_int(int errType, char* fname, int value) -{ - fprintf(GEN_errorstream, "\n*** %s: %s : %d", - fname, errorStrings[errType], value); - lastError = RE_NO_ERROR; -} /* end of void RE_error_int(int errType, char* errText, int value) */ - -/* ------------------------------------------------------------------------- */ - -/* eof */ diff --git a/source/blender/render/intern/source/gammaCorrectionTables.c b/source/blender/render/intern/source/gammaCorrectionTables.c index 9273aa899ee..812feabede7 100644 --- a/source/blender/render/intern/source/gammaCorrectionTables.c +++ b/source/blender/render/intern/source/gammaCorrectionTables.c @@ -43,10 +43,9 @@ /* WARNING; optimized, cannot be used to do gamma(invgamma()) and expect */ /* result remain identical (ton) */ -/* Default gamma. For most CRTs, gamma ranges from 2.2 to 2.5 (Foley), so */ -/* 2.35 seems appropriate enough. Experience teaches a different number */ -/* though. Old blender: 2.0. It might be nice to make this a slider */ +/* gamma is only used here for correcting adding colors or alpha */ #define RE_DEFAULT_GAMMA 2.0 + /* This 400 is sort of based on the number of intensity levels needed for */ /* the typical dynamic range of a medium, in this case CRTs. (Foley) */ /* (Actually, it says the number should be between 400 and 535.) */ @@ -63,8 +62,7 @@ static float colour_step; static float inv_colour_step; static float valid_gamma; static float valid_inv_gamma; -static int gamma_table_initialised = 0; -int do_gamma=0; + /* ------------------------------------------------------------------------- */ float gammaCorrect(float c) @@ -141,15 +139,9 @@ void makeGammaTables(float gamma) * (inv_gamma_range_table[i + 1] - inv_gamma_range_table[i]) ; } - gamma_table_initialised = 1; } /* end of void makeGammaTables(float gamma) */ -/* ------------------------------------------------------------------------- */ -int gammaTableIsInitialised(void) -{ - return gamma_table_initialised; -} /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 7e0a26e2116..6a59250b448 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -2,15 +2,12 @@ * * $Id: * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -24,9 +21,7 @@ * 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. + * Contributors: 2004/2005/2006 Blender Foundation, full recode * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -63,22 +58,45 @@ #include "SDL_thread.h" -#include "render.h" +#include "renderpipeline.h" +#include "render_types.h" #include "texture.h" +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ int imaprepeat, imapextend; /* *********** IMAGEWRAPPING ****************** */ +/* x and y have to be checked for image size */ +static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y) +{ + int ofs = y * ibuf->x + x; + + if(ibuf->rect_float) { + float *fp= ibuf->rect_float + 4*ofs; + QUATCOPY(col, fp); + } + else { + char *rect = (char *)( ibuf->rect+ ofs); + + col[0] = ((float)rect[0])/255.0f; + col[1] = ((float)rect[1])/255.0f; + col[2] = ((float)rect[2])/255.0f; + col[3] = ((float)rect[3])/255.0f; + } +} int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres) { struct ImBuf *ibuf; float fx, fy, val1, val2, val3; - int ofs, x, y; - char *rect; + int x, y; texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0; @@ -164,9 +182,8 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres) ibuf->rect+= (ibuf->x*ibuf->y); } - ofs = y * ibuf->x + x; - rect = (char *)( ibuf->rect+ ofs); - + ibuf_get_color(&texres->tr, ibuf, x, y); + if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) { ibuf->rect-= (ibuf->x*ibuf->y); } @@ -175,10 +192,6 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres) if(tex->imaflag & TEX_CALCALPHA); else texres->talpha= 1; } - - texres->tr = ((float)rect[0])/255.0f; - texres->tg = ((float)rect[1])/255.0f; - texres->tb = ((float)rect[2])/255.0f; if(texres->nor) { if(tex->imaflag & TEX_NORMALMAP) { @@ -191,15 +204,16 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres) val1= texres->tr+texres->tg+texres->tb; if(xx-1) { - rect+=4; - val2= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; - rect-=4; + float col[4]; + ibuf_get_color(col, ibuf, x+1, y); + val2= (col[0]+col[1]+col[2]); } else val2= val1; if(yy-1) { - rect+= 4*ibuf->x; - val3= ((float)(rect[0]+rect[1]+rect[2]))/255.0f; + float col[4]; + ibuf_get_color(col, ibuf, x, y+1); + val3= (col[0]+col[1]+col[2]); } else val3= val1; @@ -211,7 +225,7 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres) BRICONTRGB; - if(texres->talpha) texres->ta= texres->tin= ((float)rect[3])/255.0f; + if(texres->talpha) texres->tin= texres->ta; else if(tex->imaflag & TEX_CALCALPHA) { texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb); } @@ -390,10 +404,8 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) /* sample box, is clipped already, and minx etc. have been set at ibuf size. Enlarge with antialiased edges of the pixels */ - float muly,mulx,div; - int ofs; + float muly, mulx, div, col[4]; int x, y, startx, endx, starty, endy; - char *rect; startx= (int)floor(rf->xmin); endx= (int)floor(rf->xmax); @@ -406,23 +418,12 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) if(endy>=ibuf->y) endy= ibuf->y-1; if(starty==endy && startx==endx) { - - ofs = starty*ibuf->x + startx; - rect = (char *)(ibuf->rect +ofs); - texres->tr= ((float)rect[0])/255.0f; - texres->tg= ((float)rect[1])/255.0f; - texres->tb= ((float)rect[2])/255.0f; - /* alpha has been set in function imagewraposa() */ - if(texres->talpha) { - texres->ta= ((float)rect[3])/255.0f; - } + ibuf_get_color(&texres->tr, ibuf, startx, starty); } else { div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0; - for(y=starty;y<=endy;y++) { - ofs = y*ibuf->x +startx; - rect = (char *)(ibuf->rect+ofs); - + for(y=starty; y<=endy; y++) { + muly= 1.0; if(starty==endy); @@ -430,49 +431,52 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) if(y==starty) muly= 1.0f-(rf->ymin - y); if(y==endy) muly= (rf->ymax - y); } + if(startx==endx) { mulx= muly; - if(texres->talpha) texres->ta+= mulx*rect[3]; - texres->tr+= mulx*rect[0]; - texres->tg+= mulx*rect[1]; - texres->tb+= mulx*rect[2]; + + ibuf_get_color(col, ibuf, startx, y); + + texres->ta+= mulx*col[3]; + texres->tr+= mulx*col[0]; + texres->tg+= mulx*col[1]; + texres->tb+= mulx*col[2]; div+= mulx; } else { - for(x=startx;x<=endx;x++) { + for(x=startx; x<=endx; x++) { mulx= muly; if(x==startx) mulx*= 1.0f-(rf->xmin - x); if(x==endx) mulx*= (rf->xmax - x); + ibuf_get_color(col, ibuf, x, y); + if(mulx==1.0) { - if(texres->talpha) texres->ta+= rect[3]; - texres->tr+= rect[0]; - texres->tg+= rect[1]; - texres->tb+= rect[2]; + texres->ta+= col[3]; + texres->tr+= col[0]; + texres->tg+= col[1]; + texres->tb+= col[2]; div+= 1.0; } else { - if(texres->talpha) texres->ta+= mulx*rect[3]; - texres->tr+= mulx*rect[0]; - texres->tg+= mulx*rect[1]; - texres->tb+= mulx*rect[2]; + texres->ta+= mulx*col[3]; + texres->tr+= mulx*col[0]; + texres->tg+= mulx*col[1]; + texres->tb+= mulx*col[2]; div+= mulx; } - rect+=4; } } } if(div!=0.0) { - div*= 255.0; - - texres->tb/= div; - texres->tg/= div; - texres->tr/= div; - - if(texres->talpha) texres->ta/= div; + div= 1.0f/div; + texres->tb*= div; + texres->tg*= div; + texres->tr*= div; + texres->ta*= div; } else { - texres->tr= texres->tg= texres->tb= texres->ta= 0.0; + texres->tr= texres->tg= texres->tb= texres->ta= 0.0f; } } } diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 84eb9d9dfca..786f720fddc 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,11 +20,9 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * Contributors: 2004/2005/2006 Blender Foundation, full recode * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ @@ -38,26 +33,23 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "blendef.h" #include "MEM_guardedalloc.h" #include "PIL_time.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_jitter.h" #include "BLI_rand.h" #include "MTC_matrixops.h" -#include "DNA_image_types.h" #include "DNA_camera_types.h" +#include "DNA_group_types.h" +#include "DNA_image_types.h" #include "DNA_lamp_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BKE_utildefines.h" #include "BKE_global.h" @@ -70,13 +62,6 @@ #include "BKE_writeavi.h" #include "BKE_scene.h" -#include "BIF_toolbox.h" -#include "BIF_writeavicodec.h" -#include "BIF_writemovie.h" /* start_movie(), append_movie(), end_movie() */ - -#include "BSE_drawview.h" -#include "BSE_sequence.h" - #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -87,34 +72,33 @@ #include "SDL_thread.h" /* this module */ -#include "render.h" +#include "renderpipeline.h" +#include "render_types.h" -#include "RE_callbacks.h" -#include "zbuf.h" -#include "rendercore.h" /* part handler for the old renderer, shading functions */ +#include "rendercore.h" #include "pixelshading.h" -#include "renderPreAndPost.h" -#include "vanillaRenderPipe.h" -#include "renderHelp.h" -#include "jitter.h" #include "gammaCorrectionTables.h" -#include "zblur.h" +#include "zbuf.h" /* Own includes */ #include "initrender.h" -/* yafray: include for yafray export/render */ -#include "YafRay_Api.h" +/* ********************** */ -float centLut[16], *fmask1[9], *fmask2[9]; -unsigned short *gamtab, *igamtab2, *igamtab1; -char cmask[256], *centmask; - -Material defmaterial; - -/* ------- prototypes ----------- */ -void init_filt_mask(void); +static void init_render_jit(Render *re) +{ + static float jit[32][2]; /* simple caching */ + static int lastjit= 0; + + if(lastjit!=re->osa) { + memset(jit, 0, sizeof(jit)); + BLI_initjit(jit[0], re->osa); + } + + lastjit= re->osa; + memcpy(re->jit, jit, sizeof(jit)); +} /* ****************** GAMMA, MASKS and LUTS **************** */ @@ -169,48 +153,48 @@ static float filt_mitchell(float x) /* Mitchell & Netravali's two-param cubic */ return 0.0; } -static float calc_weight(float *weight, int i, int j) +static float calc_weight(Render *re, float *weight, int i, int j) { float x, y, dist, totw= 0.0; int a; - for(a=0; aosa; a++) { + x= re->jit[a][0] + i; + y= re->jit[a][1] + j; dist= sqrt(x*x+y*y); weight[a]= 0.0; /* Weighting choices */ - switch(R.r.filtertype) { + switch(re->r.filtertype) { case R_FILTER_BOX: if(i==0 && j==0) weight[a]= 1.0; break; case R_FILTER_TENT: - if(dist < R.r.gauss) - weight[a]= R.r.gauss - dist; + if(dist < re->r.gauss) + weight[a]= re->r.gauss - dist; break; case R_FILTER_GAUSS: - x = dist*R.r.gauss; - weight[a]= (1.0/exp(x*x) - 1.0/exp(R.r.gauss*R.r.gauss*2.25)); + x = dist*re->r.gauss; + weight[a]= (1.0/exp(x*x) - 1.0/exp(re->r.gauss*re->r.gauss*2.25)); break; case R_FILTER_MITCH: - weight[a]= filt_mitchell(dist*R.r.gauss); + weight[a]= filt_mitchell(dist*re->r.gauss); break; case R_FILTER_QUAD: - weight[a]= filt_quadratic(dist*R.r.gauss); + weight[a]= filt_quadratic(dist*re->r.gauss); break; case R_FILTER_CUBIC: - weight[a]= filt_cubic(dist*R.r.gauss); + weight[a]= filt_cubic(dist*re->r.gauss); break; case R_FILTER_CATROM: - weight[a]= filt_catrom(dist*R.r.gauss); + weight[a]= filt_catrom(dist*re->r.gauss); break; } @@ -221,730 +205,427 @@ static float calc_weight(float *weight, int i, int j) return totw; } -// extern called in render_envmap, to disable gauss... -// extern called in sequence.c, it needs the gamtab -void init_filt_mask(void) +void free_sample_tables(Render *re) { - static int firsttime=1; - static int lastosa=0; - static int lastfilter= -1; - static float lastgamma= 0.0f, lastgaussdist=0.0f; - float gamma, igamma, flweight[32], fmask[256]; + int a; + + if(re->samples) { + for(a=0; a<9; a++) { + MEM_freeN(re->samples->fmask1[a]); + MEM_freeN(re->samples->fmask2[a]); + } + + MEM_freeN(re->samples->centmask); + MEM_freeN(re->samples); + re->samples= NULL; + } +} + +/* based on settings in render, it makes the lookup tables */ +void make_sample_tables(Render *re) +{ + static int firsttime= 1; + SampleTables *st; + float flweight[32], fmask[256]; float weight[32], totw, val, *fpx1, *fpx2, *fpy1, *fpy2, *m3, *m4; int i, j, a; + /* optimization tables, only once */ if(firsttime) { + makeGammaTables(2.0); /* tables only used for adding colors */ firsttime= 0; - - for(a=0; a<9;a++) { - fmask1[a]= MEM_mallocN(256*sizeof(float), "initfilt"); - fmask2[a]= MEM_mallocN(256*sizeof(float), "initfilt"); - } - for(a=0; a<256; a++) { - cmask[a]= 0; - if(a & 1) cmask[a]++; - if(a & 2) cmask[a]++; - if(a & 4) cmask[a]++; - if(a & 8) cmask[a]++; - if(a & 16) cmask[a]++; - if(a & 32) cmask[a]++; - if(a & 64) cmask[a]++; - if(a & 128) cmask[a]++; - } - centmask= MEM_mallocN(65536, "Initfilt3"); - for(a=0; a<16; a++) { - centLut[a]= -0.45+((float)a)/16.0; - } - - gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2"); - igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2"); - igamtab2= MEM_mallocN(65536*sizeof(short), "initGaus2"); - - return; // this case is called on startup } - - if(R.r.alphamode==R_ALPHAKEY) gamma= 1.0; /* gamma correction of alpha is nasty */ - else if(R.r.mode & R_GAMMA) gamma= 2.0; - else gamma= 1.0; - igamma= 1.0/gamma; + free_sample_tables(re); + + if(re->osa==0) { + /* just prevents cpu cycles for larger render and copying */ + re->r.filtertype= 0; + return; + } + + re->do_gamma= 0; + if(re->r.mode & R_GAMMA) { + if(re->r.alphamode!=R_ALPHAKEY) /* alpha corrected gamma doesnt work for key alpha */ + re->do_gamma= 1; + } + + init_render_jit(re); - if(gamma!= lastgamma) { - lastgamma= gamma; + st= re->samples= MEM_callocN(sizeof(SampleTables), "sample tables"); + + for(a=0; a<9;a++) { + st->fmask1[a]= MEM_callocN(256*sizeof(float), "initfilt"); + st->fmask2[a]= MEM_callocN(256*sizeof(float), "initfilt"); + } + for(a=0; a<256; a++) { + st->cmask[a]= 0; + if(a & 1) st->cmask[a]++; + if(a & 2) st->cmask[a]++; + if(a & 4) st->cmask[a]++; + if(a & 8) st->cmask[a]++; + if(a & 16) st->cmask[a]++; + if(a & 32) st->cmask[a]++; + if(a & 64) st->cmask[a]++; + if(a & 128) st->cmask[a]++; + } + + st->centmask= MEM_mallocN((1<osa), "Initfilt3"); + + for(a=0; a<16; a++) { + st->centLut[a]= -0.45+((float)a)/16.0; + } - /* gamtab: in short, out short */ - for(a=0; a<65536; a++) { - val= a; - val/= 65535.0; + val= 1.0/((float)re->osa); + for(a=0; a<256; a++) { + fmask[a]= ((float)st->cmask[a])*val; + } - if(gamma==2.0) val= sqrt(val); - else if(gamma!=1.0) val= pow(val, igamma); - - gamtab[a]= (65535.99*val); - } - /* inverse gamtab1 : in byte, out short */ - for(a=1; a<=256; a++) { - if(gamma==2.0) igamtab1[a-1]= a*a-1; - else if(gamma==1.0) igamtab1[a-1]= 256*a-1; - else { - val= a/256.0; - igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ; - } - } - - /* inverse gamtab2 : in short, out short */ - for(a=0; a<65536; a++) { - val= a; - val/= 65535.0; - if(gamma==2.0) val= val*val; - else val= pow(val, gamma); - - igamtab2[a]= 65535.0*val; + /* calculate totw */ + totw= 0.0; + for(j= -1; j<2; j++) { + for(i= -1; i<2; i++) { + totw+= calc_weight(re, weight, i, j); } } - if(R.osa && (lastosa!=R.osa || lastfilter != (R.r.filtertype) || lastgaussdist!=R.r.gauss)) { - lastosa= R.osa; - lastfilter= R.r.filtertype; - lastgaussdist= R.r.gauss; - - val= 1.0/((float)R.osa); - for(a=0; a<256; a++) { - fmask[a]= ((float)cmask[a])*val; - } + for(j= -1; j<2; j++) { + for(i= -1; i<2; i++) { + /* calculate using jit, with offset the weights */ - for(a=0; a<9;a++) { - memset(fmask1[a], 0, 256*sizeof(float)); - memset(fmask2[a], 0, 256*sizeof(float)); - } + memset(weight, 0, sizeof(weight)); + calc_weight(re, weight, i, j); - /* calculate totw */ - totw= 0.0; - for(j= -1; j<2; j++) { - for(i= -1; i<2; i++) { - totw+= calc_weight(weight, i, j); - } - } + for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw); - for(j= -1; j<2; j++) { - for(i= -1; i<2; i++) { - /* calculate using jit, with offset the weights */ + m3= st->fmask1[ 3*(j+1)+i+1 ]; + m4= st->fmask2[ 3*(j+1)+i+1 ]; - memset(weight, 0, sizeof(weight)); - calc_weight(weight, i, j); - - for(a=0; a<16; a++) flweight[a]= weight[a]*(1.0/totw); - - m3= fmask1[ 3*(j+1)+i+1 ]; - m4= fmask2[ 3*(j+1)+i+1 ]; - - for(a=0; a<256; a++) { - if(a & 1) { - m3[a]+= flweight[0]; - m4[a]+= flweight[8]; - } - if(a & 2) { - m3[a]+= flweight[1]; - m4[a]+= flweight[9]; - } - if(a & 4) { - m3[a]+= flweight[2]; - m4[a]+= flweight[10]; - } - if(a & 8) { - m3[a]+= flweight[3]; - m4[a]+= flweight[11]; - } - if(a & 16) { - m3[a]+= flweight[4]; - m4[a]+= flweight[12]; - } - if(a & 32) { - m3[a]+= flweight[5]; - m4[a]+= flweight[13]; - } - if(a & 64) { - m3[a]+= flweight[6]; - m4[a]+= flweight[14]; - } - if(a & 128) { - m3[a]+= flweight[7]; - m4[a]+= flweight[15]; - } + for(a=0; a<256; a++) { + if(a & 1) { + m3[a]+= flweight[0]; + m4[a]+= flweight[8]; + } + if(a & 2) { + m3[a]+= flweight[1]; + m4[a]+= flweight[9]; + } + if(a & 4) { + m3[a]+= flweight[2]; + m4[a]+= flweight[10]; + } + if(a & 8) { + m3[a]+= flweight[3]; + m4[a]+= flweight[11]; + } + if(a & 16) { + m3[a]+= flweight[4]; + m4[a]+= flweight[12]; + } + if(a & 32) { + m3[a]+= flweight[5]; + m4[a]+= flweight[13]; + } + if(a & 64) { + m3[a]+= flweight[6]; + m4[a]+= flweight[14]; + } + if(a & 128) { + m3[a]+= flweight[7]; + m4[a]+= flweight[15]; } } } + } - /* centmask: the correct subpixel offset per mask */ + /* centmask: the correct subpixel offset per mask */ - fpx1= MEM_mallocN(256*sizeof(float), "initgauss4"); - fpx2= MEM_mallocN(256*sizeof(float), "initgauss4"); - fpy1= MEM_mallocN(256*sizeof(float), "initgauss4"); - fpy2= MEM_mallocN(256*sizeof(float), "initgauss4"); - for(a=0; a<256; a++) { - fpx1[a]= fpx2[a]= 0.0; - fpy1[a]= fpy2[a]= 0.0; - if(a & 1) { - fpx1[a]+= jit[0][0]; - fpy1[a]+= jit[0][1]; - fpx2[a]+= jit[8][0]; - fpy2[a]+= jit[8][1]; - } - if(a & 2) { - fpx1[a]+= jit[1][0]; - fpy1[a]+= jit[1][1]; - fpx2[a]+= jit[9][0]; - fpy2[a]+= jit[9][1]; - } - if(a & 4) { - fpx1[a]+= jit[2][0]; - fpy1[a]+= jit[2][1]; - fpx2[a]+= jit[10][0]; - fpy2[a]+= jit[10][1]; - } - if(a & 8) { - fpx1[a]+= jit[3][0]; - fpy1[a]+= jit[3][1]; - fpx2[a]+= jit[11][0]; - fpy2[a]+= jit[11][1]; - } - if(a & 16) { - fpx1[a]+= jit[4][0]; - fpy1[a]+= jit[4][1]; - fpx2[a]+= jit[12][0]; - fpy2[a]+= jit[12][1]; - } - if(a & 32) { - fpx1[a]+= jit[5][0]; - fpy1[a]+= jit[5][1]; - fpx2[a]+= jit[13][0]; - fpy2[a]+= jit[13][1]; - } - if(a & 64) { - fpx1[a]+= jit[6][0]; - fpy1[a]+= jit[6][1]; - fpx2[a]+= jit[14][0]; - fpy2[a]+= jit[14][1]; - } - if(a & 128) { - fpx1[a]+= jit[7][0]; - fpy1[a]+= jit[7][1]; - fpx2[a]+= jit[15][0]; - fpy2[a]+= jit[15][1]; - } + fpx1= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpx2= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpy1= MEM_mallocN(256*sizeof(float), "initgauss4"); + fpy2= MEM_mallocN(256*sizeof(float), "initgauss4"); + for(a=0; a<256; a++) { + fpx1[a]= fpx2[a]= 0.0; + fpy1[a]= fpy2[a]= 0.0; + if(a & 1) { + fpx1[a]+= re->jit[0][0]; + fpy1[a]+= re->jit[0][1]; + fpx2[a]+= re->jit[8][0]; + fpy2[a]+= re->jit[8][1]; } - - for(a= (1<0; a--) { - val= count_mask(a); - i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val); - CLAMP(i, 0, 15); - j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val); - CLAMP(j, 0, 15); - i= j + (i<<4); - centmask[a]= i; + if(a & 2) { + fpx1[a]+= re->jit[1][0]; + fpy1[a]+= re->jit[1][1]; + fpx2[a]+= re->jit[9][0]; + fpy2[a]+= re->jit[9][1]; + } + if(a & 4) { + fpx1[a]+= re->jit[2][0]; + fpy1[a]+= re->jit[2][1]; + fpx2[a]+= re->jit[10][0]; + fpy2[a]+= re->jit[10][1]; + } + if(a & 8) { + fpx1[a]+= re->jit[3][0]; + fpy1[a]+= re->jit[3][1]; + fpx2[a]+= re->jit[11][0]; + fpy2[a]+= re->jit[11][1]; + } + if(a & 16) { + fpx1[a]+= re->jit[4][0]; + fpy1[a]+= re->jit[4][1]; + fpx2[a]+= re->jit[12][0]; + fpy2[a]+= re->jit[12][1]; + } + if(a & 32) { + fpx1[a]+= re->jit[5][0]; + fpy1[a]+= re->jit[5][1]; + fpx2[a]+= re->jit[13][0]; + fpy2[a]+= re->jit[13][1]; + } + if(a & 64) { + fpx1[a]+= re->jit[6][0]; + fpy1[a]+= re->jit[6][1]; + fpx2[a]+= re->jit[14][0]; + fpy2[a]+= re->jit[14][1]; + } + if(a & 128) { + fpx1[a]+= re->jit[7][0]; + fpy1[a]+= re->jit[7][1]; + fpx2[a]+= re->jit[15][0]; + fpy2[a]+= re->jit[15][1]; } - - MEM_freeN(fpx1); - MEM_freeN(fpx2); - MEM_freeN(fpy1); - MEM_freeN(fpy2); } -} -static void free_filt_mask() -{ - int a; - - for(a=0; a<9; a++) { - MEM_freeN(fmask1[a]); - MEM_freeN(fmask2[a]); + for(a= (1<osa)-1; a>0; a--) { + val= st->cmask[a & 255] + st->cmask[a>>8]; + i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val); + CLAMP(i, 0, 15); + j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val); + CLAMP(j, 0, 15); + i= j + (i<<4); + st->centmask[a]= i; } - MEM_freeN(gamtab); - MEM_freeN(igamtab1); - MEM_freeN(igamtab2); - MEM_freeN(centmask); -} - -/* unused */ - -#if 0 -void defaultlamp() -{ - LampRen *lar; - - lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren"); - R.la[R.totlamp++]=lar; - - lar->type= LA_SUN; - lar->vec[0]= -R.viewmat[2][0]; - lar->vec[1]= -R.viewmat[2][1]; - lar->vec[2]= -R.viewmat[2][2]; - Normalise(lar->vec); - lar->r= 1.0; - lar->g= 1.0; - lar->b= 1.0; - lar->lay= 65535; -} -#endif - - - -/* ********************* init calls *********************** */ - - -static void init_def_material(void) -{ - Material *ma; - - ma= &defmaterial; - - init_material(&defmaterial); - - init_render_material(ma); -} - -void RE_init_render_data(void) -{ - memset(&R, 0, sizeof(RE_Render)); - - R.blove= (VertRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blove"); - R.blovl= (VlakRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Blovl"); - R.bloha= (HaloRen **)MEM_callocN(sizeof(void *)*(TABLEINITSIZE),"Bloha"); - R.la= (LampRen **)MEM_mallocN(LAMPINITSIZE*sizeof(void *),"renderlamparray"); - - init_def_material(); - init_filt_mask(); -} - -void RE_free_render_data() -{ - MEM_freeN(R.blove); - R.blove= NULL; - MEM_freeN(R.blovl); - R.blovl= NULL; - MEM_freeN(R.bloha); - R.bloha= NULL; - MEM_freeN(R.la); - R.la= NULL; - if(R.rectot) MEM_freeN(R.rectot); - if(R.rectftot) MEM_freeN(R.rectftot); - if(R.rectz) MEM_freeN(R.rectz); - if(R.rectspare) MEM_freeN(R.rectspare); - R.rectot= NULL; - R.rectftot= NULL; - R.rectz= NULL; - R.rectspare= NULL; - - end_render_material(&defmaterial); - free_filt_mask(); -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -void RE_make_existing_file(char *name) -{ - char di[FILE_MAXDIR], fi[FILE_MAXFILE]; - - strcpy(di, name); - BLI_splitdirstring(di, fi); - - /* test exist */ - if (BLI_exists(di) == 0) { - BLI_recurdir_fileops(di); - } + MEM_freeN(fpx1); + MEM_freeN(fpx2); + MEM_freeN(fpy1); + MEM_freeN(fpy2); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void RE_setwindowclip(int mode, int jmode) +/* call this after InitState() */ +/* per render, there's one persistant viewplane. Parts will set their own viewplanes */ +void RE_SetCamera(Render *re, Object *camera) { - extern float bluroffsx, bluroffsy; // rendercore.c... hackish (ton) Camera *cam=NULL; - float lens, minx, miny, maxx, maxy; - float xd, yd, afmx, afmy; - - if(G.scene->camera==NULL) return; - - afmx= R.afmx; - afmy= R.afmy; - - if(mode) { - - if(G.scene->camera->type==OB_LAMP) { - /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */ - - /* phi= acos(fac); */ - /* lens= 16.0*fac/sin(phi); */ - lens= 35.0; - R.near= 0.1; - R.far= 1000.0; + rctf viewplane; + float pixsize, clipsta, clipend; + float lens; + float xd, yd; + int blursample= 0; /* make new call for that */ + + /* question mark */ + re->ycor= ( (float)re->r.yasp)/( (float)re->r.xasp); + + if(camera->type==OB_CAMERA) { + cam= camera->data; + + if(cam->type==CAM_ORTHO) re->r.mode |= R_ORTHO; + + /* solve this too... all time depending stuff is in convertblender.c? */ + if(cam->ipo) { + calc_ipo(cam->ipo, frame_to_float(re->r.cfra)); + execute_ipo(&cam->id, cam->ipo); } - else if(G.scene->camera->type==OB_CAMERA) { - cam= G.scene->camera->data; + lens= cam->lens; - lens= cam->lens; - R.near= cam->clipsta; - R.far= cam->clipend; + clipsta= cam->clipsta; + clipend= cam->clipend; + } + else if(camera->type==OB_LAMP) { + /* fac= cos( PI*((float)(256- la->spsi))/512.0 ); */ + + /* phi= acos(fac); */ + /* lens= 16.0*fac/sin(phi); */ + lens= 35.0; + clipsta= 0.1; + clipend= 1000.0; + } + else { /* envmap exception, can be done better... */ + lens= 16.0; + clipsta= re->clipsta; + clipend= re->clipend; + if(clipsta==0.0f || clipend==0.0f) { + clipsta= 0.1; + clipend= 1000.0; + } + } + + /* ortho only with camera available */ + if(re->r.mode & R_ORTHO) { + if( (re->r.xasp*re->winx) >= (re->r.yasp*re->winy) ) { + re->viewfac= re->winx; } else { - lens= 16.0; + re->viewfac= re->ycor*re->winy; } - - if(R.r.mode & R_ORTHO) { - if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) { - R.viewfac= 2.0*afmx; - } - else { - R.viewfac= 2.0*R.ycor*afmy; - } - /* ortho_scale == 1.0 means exact 1 to 1 mapping */ - R.pixsize= cam->ortho_scale/R.viewfac; + /* ortho_scale == 1.0 means exact 1 to 1 mapping */ + pixsize= cam->ortho_scale/re->viewfac; + } + else { + if( (re->r.xasp*re->winx) >= (re->r.yasp*re->winy) ) { + re->viewfac= (re->winx*lens)/32.0; } else { - if( (R.r.xasp*afmx) >= (R.r.yasp*afmy) ) { - R.viewfac= (afmx*lens)/16.0; - } - else { - R.viewfac= R.ycor*(afmy*lens)/16.0; - } - - R.pixsize= R.near/R.viewfac; + re->viewfac= re->ycor*(re->winy*lens)/32.0; } - /* pixsize is not a real global... get rid of it! (ton) */ + pixsize= clipsta/re->viewfac; } - + /* revision / simplification of subpixel offsets: - the matrix will go without offset from start (e.g. -100) to end (e.g. +99). - filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too - in shadepixel() again that 0.5 offset is corrected */ - minx= R.xstart; - miny= R.ycor*(R.ystart); - maxx= R.xend; - maxy= R.ycor*(R.yend); - - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) { - miny-= .5*R.ycor; - maxy-= .5*R.ycor; + viewplane.xmin= -0.5f*(float)re->winx; + viewplane.ymin= -0.5f*re->ycor*(float)re->winy; + viewplane.xmax= 0.5f*(float)re->winx; + viewplane.ymax= 0.5f*re->ycor*(float)re->winy; + + if(re->flag & R_SEC_FIELD) { + if(re->r.mode & R_ODDFIELD) { + viewplane.ymin-= .5*re->ycor; + viewplane.ymax-= .5*re->ycor; } else { - miny+= .5*R.ycor; - maxy+= .5*R.ycor; + viewplane.ymin+= .5*re->ycor; + viewplane.ymax+= .5*re->ycor; } } xd= yd= 0.0; - if(jmode!= -1) { - bluroffsx= xd= jit[jmode % R.osa][0]; - bluroffsy= yd= R.ycor*jit[jmode % R.osa][1]; + if(blursample != -1 && re->osa != 0 ) { + re->bluroffsx= xd= re->jit[blursample % re->osa][0]; + re->bluroffsy= yd= re->ycor*re->jit[blursample % re->osa][1]; } - else bluroffsx=bluroffsy= 0.0; + else re->bluroffsx=re->bluroffsy= 0.0f; - minx= R.pixsize*(minx+xd); - maxx= R.pixsize*(maxx+xd); - miny= R.pixsize*(miny+yd); - maxy= R.pixsize*(maxy+yd); - - if(R.r.mode & R_ORTHO) - i_ortho(minx, maxx, miny, maxy, R.near, R.far, R.winmat); + viewplane.xmin= pixsize*(viewplane.xmin+xd); + viewplane.xmax= pixsize*(viewplane.xmax+xd); + viewplane.ymin= pixsize*(viewplane.ymin+yd); + viewplane.ymax= pixsize*(viewplane.ymax+yd); + + re->viewdx= pixsize; + re->viewdy= re->ycor*pixsize; + + if(re->r.mode & R_ORTHO) + RE_SetOrtho(re, &viewplane, clipsta, clipend); else - i_window(minx, maxx, miny, maxy, R.near, R.far, R.winmat); + RE_SetWindow(re, &viewplane, clipsta, clipend); - //printmatrix4("win", R.winmat); + //printmatrix4("win", re->winmat); } -/* ~~~~~~~~~~~~~~~~ PARTS ~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~ part (tile) calculus ~~~~~~~~~~~~~~~~~~~~~~ */ -/** -* Part as in part-rendering. An image rendered in parts is rendered -* to a list of parts, with x,y size, and a pointer to the render -* output stored per part. Internal! -*/ -typedef struct Part + +void freeparts(Render *re) { - struct Part *next, *prev; - unsigned int *rect; // color 4x8 bits - float *rectf; // color 4x32 bits - unsigned int *rectz; // zbuffer - - short minx, miny, maxx, maxy, x, y; -} Part; - -static void freeparts(void) -{ - Part *part= R.parts.first; + RenderPart *part= re->parts.first; + while(part) { - if(part->rect) MEM_freeN(part->rect); + if(part->rectp) MEM_freeN(part->rectp); if(part->rectz) MEM_freeN(part->rectz); - if(part->rectf) MEM_freeN(part->rectf); part= part->next; } - BLI_freelistN(&R.parts); + BLI_freelistN(&re->parts); } -static void initparts(void) +void initparts(Render *re) { - Part *pa; - short nr, xd, yd, xpart, ypart, xparts, yparts; - short a, xminb, xmaxb, yminb, ymaxb; - - freeparts(); + int nr, xd, yd, xpart, ypart, xparts, yparts; + int xminb, xmaxb, yminb, ymaxb; - if(R.r.mode & R_BORDER) { - xminb= R.r.border.xmin*R.rectx; - xmaxb= R.r.border.xmax*R.rectx; - - yminb= R.r.border.ymin*R.recty; - ymaxb= R.r.border.ymax*R.recty; - - if(xminb<0) xminb= 0; - if(xmaxb>R.rectx) xmaxb= R.rectx; - if(yminb<0) yminb= 0; - if(ymaxb>R.recty) ymaxb= R.recty; - } - else { - xminb=yminb= 0; - xmaxb= R.rectx; - ymaxb= R.recty; - } - - xparts= R.r.xparts; /* for border */ - yparts= R.r.yparts; - - xpart= R.rectx/xparts; - ypart= R.recty/yparts; - - /* if border: test if amount of parts can be fewer */ - if(R.r.mode & R_BORDER) { - a= (xmaxb-xminb-1)/xpart+1; /* amount of parts in border */ - if(ai.totpart= 0; + re->i.curpart= 0; + re->i.partsdone= 0; + + /* just for readable code.. */ + xminb= re->disprect.xmin; + yminb= re->disprect.ymin; + xmaxb= re->disprect.xmax; + ymaxb= re->disprect.ymax; + + xparts= re->r.xparts; + yparts= re->r.yparts; + + /* mininum part size */ + if(re->rectx/xparts < 64) + xparts= 1 + re->rectx/64; + if(re->recty/yparts < 64) + yparts= 1 + re->recty/64; + + /* part size */ + xpart= re->rectx/xparts; + ypart= re->recty/yparts; for(nr=0; nrminx= pa->miny= 0; - pa->maxx= pa->x= R.rectx; - pa->maxy= pa->y= R.recty; - } - else { - xd= (nr % xparts); - yd= (nr-xd)/xparts; - - pa->minx= xminb+ xd*xpart; - pa->miny= yminb+ yd*ypart; - if(xdmaxx= pa->minx+xpart; - else pa->maxx= xmaxb; - if(ydmaxy= pa->miny+ypart; - else pa->maxy= ymaxb; - - pa->x= pa->maxx-pa->minx; - pa->y= pa->maxy-pa->miny; - } + xd= (nr % xparts); + yd= (nr-xd)/xparts; - if(pa->x>0 && pa->y>0) { - /* Non-box filters might need 1 pixel extra to work */ - if((R.r.filtertype)) { - pa->minx-= 1; - pa->miny-= 1; - pa->maxx+= 1; - pa->maxy+= 1; - pa->x+= 2; - pa->y+= 2; + disprect.xmin= xminb+ xd*xpart; + disprect.ymin= yminb+ yd*ypart; + + /* ensure we cover the entire picture, so last parts go to end */ + if(xd xmaxb) + disprect.xmax = xmaxb; + } + else disprect.xmax= xmaxb; + + if(yd ymaxb) + disprect.ymax = ymaxb; + } + else disprect.ymax= ymaxb; + + rectx= disprect.xmax - disprect.xmin; + recty= disprect.ymax - disprect.ymin; + + /* so, now can we add this part? */ + if(rectx>0 && recty>0) { + RenderPart *pa= MEM_callocN(sizeof(RenderPart), "new part"); + + /* Non-box filters need 2 pixels extra to work */ + if((re->r.filtertype || (re->r.mode & R_EDGE))) { + pa->crop= 2; + disprect.xmin -= pa->crop; + disprect.ymin -= pa->crop; + disprect.xmax += pa->crop; + disprect.ymax += pa->crop; + rectx+= 2*pa->crop; + recty+= 2*pa->crop; } - BLI_addtail(&R.parts, pa); + pa->disprect= disprect; + pa->rectx= rectx; + pa->recty= recty; + + BLI_addtail(&re->parts, pa); + re->i.totpart++; } - else MEM_freeN(pa); - } - -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static void setpart(Part *pa) -{ - - R.xstart= pa->minx-R.afmx; - R.ystart= pa->miny-R.afmy; - R.xend= pa->maxx-R.afmx; - R.yend= pa->maxy-R.afmy; - R.rectx= pa->x; - R.recty= pa->y; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -static void addparttorect(Part *pa) -{ - float *rf, *rfp; - unsigned int *rt, *rtp, *rz, *rzp; - int y, height, len, copylen; - - /* calc the right offset in rects, zbuffer cannot exist... */ - if(pa->rect==NULL) return; - - rtp= pa->rect; - rzp= pa->rectz; - rfp= pa->rectf; - - copylen=len= pa->x; - height= pa->y; - - if(R.r.filtertype) { /* filters added 1 pixel extra */ - - rtp+= 1+len; - if(rzp) rzp+= 1+len; - if(rfp) rfp+= 4*(1+len); - - copylen= len-2; - height -= 2; - rt= R.rectot+ (pa->miny + 1)*R.rectx+ (pa->minx+1); - rz= R.rectz+ (pa->miny + 1)*R.rectx+ (pa->minx+1); - rf= R.rectftot+ 4*( (pa->miny + 1)*R.rectx + (pa->minx+1) ); - } - else { - rt= R.rectot+ pa->miny*R.rectx+ pa->minx; - rz= R.rectz+ pa->miny*R.rectx+ pa->minx; - rf= R.rectftot+ 4*(pa->miny*R.rectx+ pa->minx); - } - - for(y=0; y>8; - rtb[0]= gamtab[ gamval ]>>8; - gamval= (facr* igamtab2[ rtr[1]<<8 ] + facb* igamtab2[ rtb[1]<<8 ])>>8; - rtb[1]= gamtab[ gamval ]>>8; - gamval= (facr* igamtab2[ rtr[2]<<8 ] + facb* igamtab2[ rtb[2]<<8 ])>>8; - rtb[2]= gamtab[ gamval ]>>8; - gamval= (facr* igamtab2[ rtr[3]<<8 ] + facb* igamtab2[ rtb[3]<<8 ])>>8; - rtb[3]= gamtab[ gamval ]>>8; - } - else { - rtb[0]= (facr*rtr[0] + facb*rtb[0])>>8; - rtb[1]= (facr*rtr[1] + facb*rtb[1])>>8; - rtb[2]= (facr*rtr[2] + facb*rtb[2])>>8; - rtb[3]= (facr*rtr[3] + facb*rtb[3])>>8; - } - } - rtr+= 4; - rtb+= 4; - } - } - if(blur==0) { - /* last time */ - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= blurrect; - blurrect= 0; - } - } -} - - -/* yafray: main yafray render/export call */ -static void yafrayRender(void) -{ - R.flag |= R_RENDERING; /* !!! */ - - /* bug #3193: these params were not initialized, needed later for winmat calc. */ - R.xstart = -R.afmx; - R.ystart = -R.afmy; - R.xend = R.xstart + R.rectx - 1; - R.yend = R.ystart + R.recty - 1; - - /* all allocs moved here, out of export code */ - /* display rgba buf */ - if (R.rectot) MEM_freeN(R.rectot); - R.rectot = MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - /* zbuf */ - if (R.rectz) MEM_freeN(R.rectz); - R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz"); - /* float rgba buf */ - if (R.rectftot) MEM_freeN(R.rectftot); - if (R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot"); - - // switch must be done before prepareScene() - if (!R.r.YFexportxml) - YAF_switchFile(); - else - YAF_switchPlugin(); - - RE_local_init_render_display(); - RE_local_clear_render_display(R.win); - RE_local_timecursor((G.scene->r.cfra)); - - printf("Starting scene conversion.\n"); - prepareScene(); - printf("Scene conversion done.\n"); - - YAF_exportScene(); - finalizeScene(); - - // show postpro effects if floatbuffer used (plugin only) - if (R.r.YFexportxml) { - if ((R.r.mode & R_FBUF) && R.rectftot) - RE_floatbuffer_to_output(); } } @@ -955,650 +636,15 @@ static void yafrayRender(void) SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL; -static void renderloop_setblending(void) + +/* **************************************************************** */ +/* sticky texture coords */ +/* **************************************************************** */ + +void RE_make_sticky(void) { - - /* this value should only be set here. do_gamma is for gammablended adding of subpixels */ - do_gamma= 0; - if(R.r.mode & R_GAMMA) { - if(R.r.alphamode==R_ALPHAKEY); // alpha corrected gamma doesnt work for key alpha - else if((R.r.mode & R_OSA)) do_gamma= 1; - } - - /* always call, it does gamma tables used by alphaunder, but call after R.osa and jit was set */ - init_filt_mask(); - - switch (R.r.alphamode) { - case R_ALPHAKEY: - setSkyBlendingMode(RE_ALPHA_KEY); - break; - case R_ALPHAPREMUL: - setSkyBlendingMode(RE_ALPHA_PREMUL); - break; - default: - setSkyBlendingMode(RE_ALPHA_SKY); - } - - /* SHould use slider when the gamma button is pressed. */ - if (do_gamma) { - makeGammaTables(2.0); - } else { - makeGammaTables(1.0); - } - -} - -static void mainRenderLoop(void) /* here the PART and FIELD loops */ -{ - Part *pa; - int blur, fields, fi, totparts, nr; - - /* create mutexes for threaded render */ - render_abuf_lock = SDL_CreateMutex(); - load_ibuf_lock = SDL_CreateMutex(); - - if(R.rectz) MEM_freeN(R.rectz); - R.rectz = NULL; - if(R.rectftot) MEM_freeN(R.rectftot); - R.rectftot = NULL; - - /* FIELD LOOP */ - totparts= R.r.xparts*R.r.yparts; - fields= 1; - - if(R.r.mode & R_FIELDS) { - fields= 2; - R.rectf1= R.rectf2= NULL; /* field rects */ - R.r.ysch/= 2; - R.afmy/= 2; - R.r.yasp*= 2; - R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); - - } - - for(fi=0; fir.cfra)+fi); - - R.flag|= R_RENDERING; - if(fi==1) R.flag |= R_SEC_FIELD; - - /* MOTIONBLUR loop */ - if(R.r.mode & R_MBLUR) blur= R.osa; - else blur= 1; - while(blur--) { - - /* WINDOW */ - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - R.xstart= -R.afmx; - R.ystart= -R.afmy; - R.xend= R.xstart+R.rectx-1; - R.yend= R.ystart+R.recty-1; - - if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur); - - initparts(); /* always do, because of border and gauss */ - if(R.parts.first==NULL) { - G.afbreek=1; - error("Image too small"); - break; - } - - setpart(R.parts.first); - - RE_local_init_render_display(); - RE_local_clear_render_display(R.win); - RE_local_timecursor((G.scene->r.cfra)); - - prepareScene(); - - /* PARTS LOOP */ - nr= 0; - for(pa= R.parts.first; pa; pa= pa->next, nr++) { - - if(RE_local_test_break()) break; - - setpart(pa); - - if(R.r.mode & R_MBLUR) RE_setwindowclip(0, blur); - else RE_setwindowclip(0,-1); - - if(R.r.mode & R_PANORAMA) setPanoRot(nr); - - /* HOMOGENIC COORDINATES AND ZBUF AND CLIP OPTIMISATION (per part) */ - /* There may be some interference with z-coordinate */ - /* calculation here? */ - - doClipping(RE_projectverto); - if(RE_local_test_break()) break; - - /* rectot is for result and integer face indices */ - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - - if(R.rectftot) MEM_freeN(R.rectftot); - if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot"); - - if(R.r.mode & R_MBLUR) { - RE_local_printrenderinfo(0.0, R.osa - blur); - if(G.background && blur1 || (R.r.mode & R_BORDER) || (R.r.filtertype)) { - - pa->rect= R.rectot; - R.rectot= NULL; - pa->rectf= R.rectftot; - R.rectftot= NULL; - pa->rectz= R.rectz; - R.rectz= NULL; - } - } - - if(RE_local_test_break()) break; - } - - /* JOIN PARTS OR INSERT BORDER */ - - /* exception: crop */ - if( (R.r.mode & R_BORDER) && (R.r.mode & R_MOVIECROP)) ; - else { - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - - if(R.r.mode & R_PANORAMA) R.rectx*= R.r.xparts; - - if(totparts>1 || (R.r.mode & R_BORDER) || (R.r.filtertype)) { - int a; - - if(R.rectot) MEM_freeN(R.rectot); - if(R.rectftot) MEM_freeN(R.rectftot); - if(R.rectz) MEM_freeN(R.rectz); - - R.rectot= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - - if(R.r.mode & R_UNIFIED) R.rectz= NULL; - else R.rectz= MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectz"); - - if(R.r.mode & R_FBUF) R.rectftot= MEM_callocN(4*sizeof(float)*R.rectx*R.recty, "rectftot"); - else R.rectftot= NULL; - - for(a=0, pa= R.parts.first; pa; pa= pa->next, a++) { - - if(R.r.mode & R_PANORAMA) { // pano is fake parts... - pa->minx += a*R.r.xsch; - pa->maxx += a*R.r.xsch; - } - addparttorect(pa); - } - } - } - - freeparts(); - - if( (R.flag & R_HALO)) { - if(RE_local_test_break()==0) add_halo_flare(); - } - - if( (R.r.mode & R_ZBLUR)) { - if(RE_local_test_break()==0) add_zblur(); - } - - if(R.r.mode & R_MBLUR) { - add_to_blurbuf(blur); - } - - /* END (blur loop) */ - finalizeScene(); - - if(RE_local_test_break()) break; - } - - /* definite free */ - add_to_blurbuf(-1); - - /* HANDLE FIELD */ - if(R.r.mode & R_FIELDS) { - if(R.flag & R_SEC_FIELD) R.rectf2= R.rectot; - else R.rectf1= R.rectot; - R.rectot= NULL; - } - - if(RE_local_test_break()) break; - } - - /* JOIN FIELDS */ - if(R.r.mode & R_FIELDS) { - R.r.ysch*= 2; - R.afmy*= 2; - R.recty*= 2; - R.r.yasp/=2; - - if(R.rectot) MEM_freeN(R.rectot); /* happens when a render has been stopped */ - R.rectot=(unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - - if(RE_local_test_break()==0) { - unsigned int *rt, *rt1, *rt2; - int len, a; - - rt= R.rectot; - - if(R.r.mode & R_ODDFIELD) { - rt2= R.rectf1; - rt1= R.rectf2; - } - else { - rt1= R.rectf1; - rt2= R.rectf2; - } - - len= 4*R.rectx; - - for(a=0; ar; - R.r.postigamma= 1.0/R.r.postgamma; - - /* WINDOW size (sch='scherm' dutch for screen...) */ - R.r.xsch= (R.r.size*R.r.xsch)/100; - R.r.ysch= (R.r.size*R.r.ysch)/100; - - R.afmx= R.r.xsch/2; - R.afmy= R.r.ysch/2; - - /* to be sure: when a premature return (rectx can differ from xsch) */ - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - - /* IS RENDERING ALLOWED? */ - - /* forbidden combination */ - if(R.r.mode & R_PANORAMA) { - if(R.r.mode & R_BORDER) { - error("No border supported for Panorama"); - G.afbreek= 1; - } - if(R.r.yparts>1) { - error("No Y-Parts supported for Panorama"); - G.afbreek= 1; - } - if(R.r.mode & R_ORTHO) { - error("No Ortho render possible for Panorama"); - G.afbreek= 1; - } - } - - if(R.r.mode & R_BORDER) { - if(R.r.border.xmax <= R.r.border.xmin || - R.r.border.ymax <= R.r.border.ymin) { - error("No border area selected."); - G.afbreek= 1; - } - } - - if(R.r.xparts*R.r.yparts>=2 && (R.r.mode & R_MOVIECROP) && (R.r.mode & R_BORDER)) { - error("Combination of border, crop and parts not allowed"); - G.afbreek= 1; - return; - } - - if(R.r.xparts*R.r.yparts>64) { - error("No more than 64 parts supported"); - G.afbreek= 1; - return; - } - - if(R.r.yparts>1 && (R.r.mode & R_PANORAMA)) { - error("No Y-Parts supported for Panorama"); - G.afbreek= 1; - return; - } - - if(G.afbreek==1) return; - - /* TEST BACKBUF */ - /* If an image is specified for use as backdrop, that image is loaded */ - /* here. */ - if((R.r.bufflag & 1) && (G.scene->r.scemode & R_OGL)==0) { - if(R.r.alphamode == R_ADDSKY) { - strcpy(name, R.r.backbuf); - BLI_convertstringcode(name, G.sce, G.scene->r.cfra); - - if(R.backbuf) { - R.backbuf->id.us--; - bima= R.backbuf; - } - else bima= NULL; - - R.backbuf= add_image(name); - - if(bima && bima->id.us<1) { - free_image_buffers(bima); - } - - if(R.backbuf && R.backbuf->ibuf==NULL) { - R.backbuf->ibuf= IMB_loadiffname(R.backbuf->name, IB_rect); - if(R.backbuf->ibuf==NULL) R.backbuf->ok= 0; - else R.backbuf->ok= 1; - } - if(R.backbuf==NULL || R.backbuf->ok==0) { - // error() doesnt work with render window open - //error("No backbuf there!"); - printf("Error: No backbuf %s\n", name); - } - } - } - - if(R.r.mode & (R_OSA|R_MBLUR)) { - R.osa= R.r.osa; - if(R.osa>16) R.osa= 16; - - init_render_jit(R.osa); - - } - else R.osa= 0; - - /* just prevents cpu cycles for larger render and copying */ - if((R.r.mode & R_OSA)==0) - R.r.filtertype= 0; - - renderloop_setblending(); // alpha, sky, gamma - - /* when rendered without camera object */ - /* it has to done here because of envmaps */ - R.near= 0.1; - R.far= 1000.0; - - - if(R.afmx<1 || R.afmy<1) { - error("Image too small"); - return; - } - R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp); - - start_time= PIL_check_seconds_timer(); - - if(R.r.scemode & R_OGL) { - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - - if(R.rectftot) MEM_freeN(R.rectftot); - R.rectftot= NULL; - - RE_local_init_render_display(); - drawview3d_render(ogl_render_view3d); - } - else if(R.r.scemode & R_DOSEQ) { - R.rectx= R.r.xsch; - R.recty= R.r.ysch; - if(R.r.mode & R_PANORAMA) { - R.rectx*= R.r.xparts; - } - - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - - if(R.rectftot) MEM_freeN(R.rectftot); - R.rectftot= NULL; - - RE_local_timecursor((G.scene->r.cfra)); - - if(RE_local_test_break()==0) do_render_seq(); - - /* display */ - if(R.rectot) RE_local_render_display(0, R.recty-1, R.rectx, R.recty,R.rectot); - } - else { - if(G.scene->camera==0) { - G.scene->camera= scene_find_camera(G.scene); - } - - if(G.scene->camera==0) { - error("No camera"); - /* needed because R.rectx and R.recty can be unmatching R.rectot */ - - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= NULL; - if(R.rectftot) MEM_freeN(R.rectftot); - R.rectftot= NULL; - - G.afbreek=1; - return; - } - else { - - if(G.scene->camera->type==OB_CAMERA) { - Camera *cam= G.scene->camera->data; - if(cam->type==CAM_ORTHO) R.r.mode |= R_ORTHO; - } - - render(); /* returns with complete rect xsch-ysch */ - } - } - - /* display again: fields/seq/parts/pano etc */ - if(R.rectot) { - RE_local_init_render_display(); - RE_local_render_display(0, R.recty-1, R.rectx, R.recty, R.rectot); - } - else RE_local_clear_render_display(R.win); - - if ((G.scene->r.scemode & R_OGL)==0) /* header gets scrabled if renderwindow holds OGL context */ - RE_local_printrenderinfo((PIL_check_seconds_timer() - start_time), -1); - - /* grms... this is a nasty global */ - do_gamma= 0; - - /* these flags remain on, until reset in caller to render (renderwin.c) */ - R.flag &= (R_RENDERING|R_ANIMRENDER|R_REDRAW_PRV); -} - -void RE_animrender(struct View3D *ogl_render_view3d) -{ - int cfrao; - char name[256]; - - if(G.scene==NULL) return; - if(G.scene->r.sfra > G.scene->r.efra) { - error("Startframe larger than Endframe"); - return; - } - - /* scenedata to R: (for backbuf, R.rectx etc) */ - R.r= G.scene->r; - - /* START ANIMLOOP, everywhere NOT the cfra from R.r is gebruikt: because of rest blender */ - cfrao= (G.scene->r.cfra); - - /* disable options for ogl render */ - if(G.scene->r.scemode & R_OGL) R.r.mode &= ~(R_PANORAMA|R_MOVIECROP); - - // these calculations apply for all movie formats - R.rectx= (R.r.size*R.r.xsch)/100; - R.recty= (R.r.size*R.r.ysch)/100; - if(R.r.mode & R_PANORAMA) { - R.rectx*= R.r.xparts; - R.recty*= R.r.yparts; - } - if(R.r.mode & R_MOVIECROP) { - initparts(); - setpart(R.parts.first); // this will adjust r.rectx - } - - if (0) { -#ifdef __sgi - } else if (R.r.imtype==R_MOVIE) { - start_movie(); -#endif -#if defined(_WIN32) && !defined(FREE_WINDOWS) - } else if (R.r.imtype == R_AVICODEC) { - start_avi_codec(); -#endif -#if WITH_QUICKTIME - } else if (R.r.imtype == R_QUICKTIME) { - start_qt(); -#endif - } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { - if ELEM(R.r.imtype, R_MOVIE, R_AVICODEC) { - printf("Selected movie format not supported on this platform,\nusing RAW AVI instead\n"); - } - start_avi(); - } -// set initial conditions for softbodies here -// ****************************************** - for((G.scene->r.cfra)=(G.scene->r.sfra); (G.scene->r.cfra)<=(G.scene->r.efra); (G.scene->r.cfra)++) { - double starttime= PIL_check_seconds_timer(); - - R.flag |= R_ANIMRENDER; // unused now (ton) - - RE_initrender(ogl_render_view3d); - - /* WRITE IMAGE */ - if(RE_local_test_break()==0) { - - if (0) { -#ifdef __sgi - } else if (R.r.imtype == R_MOVIE) { - append_movie((G.scene->r.cfra)); -#endif -#if defined(_WIN32) && !defined(FREE_WINDOWS) - } else if (R.r.imtype == R_AVICODEC) { - append_avi_codec((G.scene->r.cfra)); -#endif -#ifdef WITH_QUICKTIME - } else if (R.r.imtype == R_QUICKTIME) { - append_qt((G.scene->r.cfra)); -#endif - } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { - append_avi((G.scene->r.cfra)); - } else { - makepicstring(name, (G.scene->r.cfra)); - schrijfplaatje(name); - if(RE_local_test_break()==0) printf("Saved: %s", name); - } - - timestr(PIL_check_seconds_timer()-starttime, name); - printf(" Time: %s\n", name); - fflush(stdout); /* needed for renderd !! */ - } - - if(G.afbreek==1) break; - - } - - G.scene->r.cfra= cfrao; - - /* restore time */ - if(R.r.mode & (R_FIELDS|R_MBLUR)) { - /* applies changes fully */ - scene_update_for_newframe(G.scene, G.scene->lay); - } - - if (0) { -#ifdef __sgi - } else if (R.r.imtype==R_MOVIE) { - end_movie(); -#endif -#if defined(_WIN32) && !defined(FREE_WINDOWS) - } else if (R.r.imtype == R_AVICODEC) { - end_avi_codec(); -#endif -#ifdef WITH_QUICKTIME - } else if (R.r.imtype == R_QUICKTIME) { - end_qt(); -#endif - } else if ELEM4(R.r.imtype, R_AVIRAW, R_AVIJPEG, R_MOVIE, R_AVICODEC) { - end_avi(); - } -} - -/* *************************************************** */ -/* ******************* Screendumps ******************** */ -/* moved to the windowControl thing */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c new file mode 100644 index 00000000000..d1099891264 --- /dev/null +++ b/source/blender/render/intern/source/pipeline.c @@ -0,0 +1,1051 @@ +/** + * + * ***** 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): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "DNA_group_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_node.h" +#include "BKE_scene.h" +#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ + +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + +#include "PIL_time.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "RE_pipeline.h" +#include "radio.h" + +#include "BSE_sequence.h" /* <----------------- bad!!! */ + +/* internal */ +#include "render_types.h" +#include "renderpipeline.h" +#include "renderdatabase.h" +#include "rendercore.h" +#include "envmap.h" +#include "initrender.h" +#include "shadbuf.h" +#include "zbuf.h" + +#include "SDL_thread.h" +#include "SDL_mutex.h" + +/* render flow + +1) Initialize state +- state data, tables +- movie/image file init +- everything that doesn't change during animation + +2) Initialize data +- camera, world, matrices +- make render verts, faces, halos, strands +- everything can change per frame/field + +3) Render Processor +- multiple layers +- tiles, rect, baking +- layers/tiles optionally to disk or directly in Render Result + +4) Composit Render Result +- also read external files etc + +5) Image Files +- save file or append in movie + +*/ + + +/* ********* globals ******** */ + +/* here we store all renders */ +static struct ListBase RenderList= {NULL, NULL}; + +/* hardcopy of current render, used while rendering for speed */ +Render R; + +/* ********* alloc and free ******** */ + + +SDL_mutex *malloc_lock= NULL; + +void *RE_mallocN(int len, char *name) +{ + void *mem; + if(malloc_lock) SDL_mutexP(malloc_lock); + mem= MEM_mallocN(len, name); + if(malloc_lock) SDL_mutexV(malloc_lock); + return mem; +} +void *RE_callocN(int len, char *name) +{ + void *mem; + if(malloc_lock) SDL_mutexP(malloc_lock); + mem= MEM_callocN(len, name); + if(malloc_lock) SDL_mutexV(malloc_lock); + return mem; +} +void RE_freeN(void *poin) +{ + if(malloc_lock) SDL_mutexP(malloc_lock); + MEM_freeN(poin); + if(malloc_lock) SDL_mutexV(malloc_lock); +} + +/* ********************** */ + + +/* default callbacks, set in each new render */ +static void result_nothing(RenderResult *rr) {} +static void result_rcti_nothing(RenderResult *rr, rcti *rect) {} +static void stats_nothing(RenderStats *rs) {} +static void int_nothing(int val) {} +static int void_nothing(void) {return 0;} +static void print_error(const char *str) {printf("ERROR: %s\n", str);} + +static void free_render_result(RenderResult *res) +{ + if(res==NULL) return; + + while(res->layers.first) { + RenderLayer *rl= res->layers.first; + if(rl->rectf) RE_freeN(rl->rectf); + if(rl->rectz) RE_freeN(rl->rectz); + BLI_remlink(&res->layers, rl); + RE_freeN(rl); + } + + if(res->rect32) + RE_freeN(res->rect32); + if(res->rectz) + RE_freeN(res->rectz); + if(res->rectf) + RE_freeN(res->rectf); + + RE_freeN(res); +} + +/* called by main render as well for parts */ +/* will read info from Render *re to define layers */ +/* called in threads */ +/* winrct is coordinate rect of entire image, partrct the part within */ +static RenderResult *new_render_result(Render *re, rcti *partrct, int crop) +{ + RenderResult *rr; + RenderLayer *rl; + SceneRenderLayer *srl; + int rectx, recty; + + rectx= partrct->xmax - partrct->xmin; + recty= partrct->ymax - partrct->ymin; + + if(rectx<=0 || recty<=0) + return NULL; + + rr= RE_callocN(sizeof(RenderResult), "new render result"); + rr->rectx= rectx; + rr->recty= recty; + /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */ + rr->crop= crop; + + /* tilerect is relative coordinates within render disprect. do not subtract crop yet */ + rr->tilerect.xmin= partrct->xmin - re->disprect.xmin; + rr->tilerect.xmax= partrct->xmax - re->disprect.xmax; + rr->tilerect.ymin= partrct->ymin - re->disprect.ymin; + rr->tilerect.ymax= partrct->ymax - re->disprect.ymax; + + /* copy, so display callbacks can find out too */ + rr->actlay= re->r.actlay; + + /* check renderdata for amount of layers */ + for(srl= re->r.layers.first; srl; srl= srl->next) { + rl= RE_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + strcpy(rl->name, srl->name); + rl->lay= srl->lay; + rl->layflag= srl->layflag; + rl->passflag= srl->passflag; + + rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba"); + if(srl->passflag & SCE_PASS_Z) + rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z"); + + } + /* previewrender and envmap don't do layers, so we make a default one */ + if(rr->layers.first==NULL) { + rl= RE_callocN(sizeof(RenderLayer), "new render layer"); + BLI_addtail(&rr->layers, rl); + + rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba"); + rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z"); + + /* note, this has to be in sync with scene.c */ + rl->lay= (1<<20) -1; + rl->layflag= 0x7FFF; /* solid ztra halo strand */ + rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z; + + } + + return rr; +} + + +/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */ +/* no test happens here if it fits... we also assume layers are in sync */ +/* is used within threads */ +static void merge_render_result(RenderResult *rr, RenderResult *rrpart) +{ + RenderLayer *rl, *rlp; + float *rf, *rfp; + float *rz, *rzp; + int y, height, len, copylen; + + for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) { + + /* first combined and z pass */ + if(rl->rectf && rlp->rectf) { + int ofs; + + rzp= rlp->rectz; + rfp= rlp->rectf; + + copylen=len= rrpart->rectx; + height= rrpart->recty; + + if(rrpart->crop) { /* filters add pixel extra */ + + if(rzp) rzp+= rrpart->crop + rrpart->crop*len; + if(rfp) rfp+= 4*(rrpart->crop + rrpart->crop*len); + + copylen= len-2*rrpart->crop; + height -= 2*rrpart->crop; + + ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop); + rz= rl->rectz+ ofs; + rf= rl->rectf+ 4*ofs; + } + else { + ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin); + rz= rl->rectz+ ofs; + rf= rl->rectf+ 4*ofs; + } + + for(y=0; yrectx; + rzp+= len; + } + if(rfp) { + memcpy(rf, rfp, 16*copylen); + rf+= 4*rr->rectx; + rfp+= 4*len; + } + } + } + } +} + + +/* *************************************************** */ + +Render *RE_GetRender(const char *name) +{ + Render *re; + + /* search for existing renders */ + for(re= RenderList.first; re; re= re->next) { + if(strncmp(re->name, name, RE_MAXNAME)==0) { + break; + } + } + return re; +} + +/* if you want to know exactly what has been done */ +RenderResult *RE_GetResult(Render *re) +{ + if(re) + return re->result; + return NULL; +} + +/* fill provided result struct with what's currently active or done */ +void RE_GetResultImage(Render *re, RenderResult *rr) +{ + memset(rr, sizeof(RenderResult), 0); + + if(re && re->result) { + RenderLayer *rl; + + rr->rectx= re->result->rectx; + rr->recty= re->result->recty; + + rr->rectf= re->result->rectf; + rr->rectz= re->result->rectz; + rr->rect32= re->result->rect32; + + /* active layer */ + rl= BLI_findlink(&re->result->layers, re->r.actlay); + if(rl) { + if(rr->rectf==NULL) + rr->rectf= rl->rectf; + if(rr->rectz==NULL) + rr->rectz= rl->rectz; + } + } +} + +#define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val)) +/* caller is responsible for allocating rect in correct size! */ +void RE_ResultGet32(Render *re, unsigned int *rect) +{ + RenderResult rres; + + RE_GetResultImage(re, &rres); + if(rres.rect32) + memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty); + else if(rres.rectf) { + float *fp= rres.rectf; + int tot= rres.rectx*rres.recty; + char *cp= (char *)rect; + + for(;tot>0; tot--, cp+=4, fp+=4) { + cp[0] = FTOCHAR(fp[0]); + cp[1] = FTOCHAR(fp[1]); + cp[2] = FTOCHAR(fp[2]); + cp[3] = FTOCHAR(fp[3]); + } + } + else + /* else fill with black */ + memset(rect, sizeof(int)*re->rectx*re->recty, 0); +} + + +RenderStats *RE_GetStats(Render *re) +{ + return &re->i; +} + +Render *RE_NewRender(const char *name) +{ + Render *re; + + /* only one render per name exists */ + re= RE_GetRender(name); + if(re) { + BLI_remlink(&RenderList, re); + RE_FreeRender(re); + } + + /* new render data struct */ + re= RE_callocN(sizeof(Render), "new render"); + BLI_addtail(&RenderList, re); + strncpy(re->name, name, RE_MAXNAME); + + /* set default empty callbacks */ + re->display_init= result_nothing; + re->display_clear= result_nothing; + re->display_draw= result_rcti_nothing; + re->timecursor= int_nothing; + re->test_break= void_nothing; + re->test_return= void_nothing; + re->error= print_error; + re->stats_draw= stats_nothing; + + /* init some variables */ + re->ycor= 1.0f; + + return re; +} + +/* only call this while you know it will remove the link too */ +void RE_FreeRender(Render *re) +{ + + free_renderdata_tables(re); + free_sample_tables(re); + + free_render_result(re->result); + + BLI_remlink(&RenderList, re); + RE_freeN(re); +} + +/* exit blender */ +void RE_FreeAllRender(void) +{ + while(RenderList.first) { + RE_FreeRender(RenderList.first); + } +} + +/* ********* initialize state ******** */ + + +/* what doesn't change during entire render sequence */ +/* disprect is optional, if NULL it assumes full window render */ +void RE_InitState(Render *re, RenderData *rd, int winx, int winy, rcti *disprect) +{ + re->ok= TRUE; /* maybe flag */ + + re->i.starttime= PIL_check_seconds_timer(); + re->r= *rd; /* hardcopy */ + + re->winx= winx; + re->winy= winy; + if(disprect) { + re->disprect= *disprect; + re->rectx= disprect->xmax-disprect->xmin; + re->recty= disprect->ymax-disprect->ymin; + } + else { + re->disprect.xmin= re->disprect.xmax= 0; + re->disprect.xmax= winx; + re->disprect.ymax= winy; + re->rectx= winx; + re->recty= winy; + } + + if(re->rectx < 2 || re->recty < 2) { + re->error("Image too small"); + re->ok= 0; + } + else { + /* check state variables, osa? */ + if(re->r.mode & (R_OSA|R_MBLUR)) { + re->osa= re->r.osa; + if(re->osa>16) re->osa= 16; + } + else re->osa= 0; + + /* always call, checks for gamma, gamma tables and jitter too */ + make_sample_tables(re); + + /* initialize render result */ + free_render_result(re->result); + re->result= new_render_result(re, &re->disprect, 0); + + } +} + +void RE_SetDispRect (struct Render *re, rcti *disprect) +{ + re->disprect= *disprect; + re->rectx= disprect->xmax-disprect->xmin; + re->recty= disprect->ymax-disprect->ymin; + + /* initialize render result */ + free_render_result(re->result); + re->result= new_render_result(re, &re->disprect, 0); +} + +void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend) +{ + /* re->ok flag? */ + + re->viewplane= *viewplane; + re->clipsta= clipsta; + re->clipend= clipend; + + i_window(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat); +} + +void RE_SetOrtho(Render *re, rctf *viewplane, float clipsta, float clipend) +{ + /* re->ok flag? */ + + re->viewplane= *viewplane; + re->clipsta= clipsta; + re->clipend= clipend; + re->r.mode |= R_ORTHO; + + i_ortho(re->viewplane.xmin, re->viewplane.xmax, re->viewplane.ymin, re->viewplane.ymax, re->clipsta, re->clipend, re->winmat); +} + +void RE_SetView(Render *re, float mat[][4]) +{ + /* re->ok flag? */ + Mat4CpyMat4(re->viewmat, mat); + Mat4Invert(re->viewinv, re->viewmat); +} + +/* image and movie output has to move to either imbuf or kernel */ + +void RE_display_init_cb(Render *re, void (*f)(RenderResult *rr)) +{ + re->display_init= f; +} +void RE_display_clear_cb(Render *re, void (*f)(RenderResult *rr)) +{ + re->display_clear= f; +} +void RE_display_draw_cb(Render *re, void (*f)(RenderResult *rr, rcti *rect)) +{ + re->display_draw= f; +} + +void RE_stats_draw_cb(Render *re, void (*f)(RenderStats *rs)) +{ + re->stats_draw= f; +} +void RE_timecursor_cb(Render *re, void (*f)(int)) +{ + re->timecursor= f; +} + +void RE_test_break_cb(Render *re, int (*f)(void)) +{ + re->test_break= f; +} +void RE_test_return_cb(Render *re, int (*f)(void)) +{ + re->test_return= f; +} +void RE_error_cb(Render *re, void (*f)(const char *str)) +{ + re->error= f; +} + + +/* ********* add object data (later) ******** */ + +/* object is considered fully prepared on correct time etc */ +/* includes lights */ +void RE_AddObject(Render *re, Object *ob) +{ + +} + +/* ********** basic thread control API ************ */ + +#define RE_MAX_THREAD 4 + +typedef struct ThreadSlot { + RenderPart *part; + SDL_Thread *sdlthread; + int avail; +} ThreadSlot; + +static ThreadSlot threadslots[RE_MAX_THREAD]; + +static void init_threadslots(int tot) +{ + int a; + + if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD; + else if(tot<1) tot= 1; + + for(a=0; a< RE_MAX_THREAD; a++) { + threadslots[a].part= NULL; + threadslots[a].sdlthread= NULL; + if(athread= a; + threadslots[a].avail= 0; + threadslots[a].part= pa; + threadslots[a].sdlthread= SDL_CreateThread(do_part_thread, pa); + break; + } + } +} + +static void remove_threadslot(RenderPart *pa) +{ + int a; + for(a=0; a< RE_MAX_THREAD; a++) { + if(threadslots[a].part==pa) { + threadslots[a].avail= 1; + threadslots[a].part= NULL; + SDL_WaitThread(threadslots[a].sdlthread, NULL); + threadslots[a].sdlthread= NULL; + } + } +} + +/* ********** basic thread control API ************ */ + +static int do_part_thread(void *pa_v) +{ + RenderPart *pa= pa_v; + + /* need to return nicely all parts on esc */ + if(R.test_break()==0) { + + pa->result= new_render_result(&R, &pa->disprect, pa->crop); + + if(R.osa) + zbufshadeDA_tile(pa); + else + zbufshade_tile(pa); + + if(!R.test_break()) + merge_render_result(R.result, pa->result); + } + + pa->ready= 1; + + return 0; +} + +/* returns with render result filled, not threaded */ +static void render_tile_processor(Render *re) +{ + RenderPart *pa; + + if(re->test_break()) + return; + + re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; + re->stats_draw(&re->i); + re->i.starttime= PIL_check_seconds_timer(); + + if(re->result==NULL) + return; + + initparts(re); + + /* assuming no new data gets added to dbase... */ + R= *re; + + for(pa= re->parts.first; pa; pa= pa->next) { + do_part_thread(pa); + + if(pa->result) { + if(!re->test_break()) { + re->display_draw(pa->result, NULL); + re->i.partsdone++; + } + free_render_result(pa->result); + pa->result= NULL; + } + if(re->test_break()) + break; + } + + re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; + re->stats_draw(&re->i); + + freeparts(re); +} + +static RenderPart *find_nicest_part(Render *re) +{ + RenderPart *pa, *best= NULL; + int centx=re->winx/2, centy=re->winy/2, tot=1; + int mindist, distx, disty; + + /* find center of rendered parts, image center counts for 1 too */ + for(pa= re->parts.first; pa; pa= pa->next) { + if(pa->ready) { + centx+= (pa->disprect.xmin+pa->disprect.xmax)/2; + centy+= (pa->disprect.ymin+pa->disprect.ymax)/2; + tot++; + } + } + centx/=tot; + centy/=tot; + + /* closest of the non-rendering parts */ + mindist= re->winx*re->winy; + for(pa= re->parts.first; pa; pa= pa->next) { + if(pa->ready==0 && pa->nr==0) { + distx= centx - (pa->disprect.xmin+pa->disprect.xmax)/2; + disty= centy - (pa->disprect.ymin+pa->disprect.ymax)/2; + distx= (int)sqrt(distx*distx + disty*disty); + if(distxresult==NULL) + return; + if(re->test_break()) + return; + + initparts(re); + init_threadslots(maxthreads); + + /* assuming no new data gets added to dbase... */ + R= *re; + + malloc_lock = SDL_CreateMutex(); + + while(rendering) { + + /* I noted that test_break() in a thread doesn't make ghost send ESC */ + if(available_threadslots() && !re->test_break()) { + pa= find_nicest_part(re); + if(pa) { + pa->nr= counter++; /* only for stats */ + insert_threadslot(pa); + } + } + else + PIL_sleep_ms(50); + + /* check for ready ones to display, and if we need to continue */ + rendering= 0; + for(pa= re->parts.first; pa; pa= pa->next) { + if(pa->ready) { + if(pa->result) { + remove_threadslot(pa); /* do it here, not in thread */ + re->display_draw(pa->result, NULL); + free_render_result(pa->result); + pa->result= NULL; + re->i.partsdone++; + } + } + else rendering= 1; + } + + /* on break, wait for all slots to get freed */ + if(re->test_break() && available_threadslots()==maxthreads) + rendering= 0; + + } + + if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL; + + freeparts(re); +} + +void RE_TileProcessor(Render *re) +{ + if(re->r.mode & R_THREADS) + threaded_tile_processor(re); + else + render_tile_processor(re); +} + + +/* ************ This part uses API, for rendering Blender scenes ********** */ + +void render_one_frame(Render *re) +{ + +// re->cfra= cfra; /* <- unused! */ + + /* make render verts/faces/halos/lamps */ + RE_Database_FromScene(re, re->scene, 1); + + RE_TileProcessor(re); + + /* free all render verts etc */ + RE_Database_Free(re); +} + +/* accumulates osa frames */ +static void do_render_blurred(Render *re, float frame) +{ + +} + +/* interleaves 2 frames */ +static void do_render_fields(Render *re) +{ + +} + +static void do_render_final(Render *re, Scene *scene) +{ + /* we set start time here, for main Blender loops */ + re->i.starttime= PIL_check_seconds_timer(); + + if(re->r.scemode & R_DOSEQ) { + re->result->rect32= MEM_callocN(sizeof(int)*re->rectx*re->recty, "rectot"); + if(!re->test_break()) + do_render_seq(re->result); + } + else { + /* first check if theres nodetree with render result */ + int do_render= ntreeCompositNeedsRender(scene->nodetree); + /* but.. do we use nodes? */ + if(scene->use_nodes==0) do_render= 1; + + re->scene= scene; + + if(do_render) { + /* now use renderdata and camera to set viewplane */ + RE_SetCamera(re, re->scene->camera); + + if(re->r.mode & R_FIELDS) + do_render_fields(re); + else if(re->r.mode & R_MBLUR) + do_render_blurred(re, re->scene->r.cfra); + else + render_one_frame(re); + } + + ntreeCompositTagRender(scene->nodetree); + + if(re->r.scemode & R_DOCOMP) + ntreeCompositExecTree(scene->nodetree, &re->r, 0); + } + + + re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime; + re->stats_draw(&re->i); + + re->display_draw(re->result, NULL); + +} + + +static int is_rendering_allowed(Render *re) +{ + + /* forbidden combinations */ + if(re->r.mode & R_PANORAMA) { + if(re->r.mode & R_BORDER) { + re->error("No border supported for Panorama"); + return 0; + } + if(re->r.yparts>1) { + re->error("No Y-Parts supported for Panorama"); + return 0; + } + if(re->r.mode & R_ORTHO) { + re->error("No Ortho render possible for Panorama"); + return 0; + } + } + + if(re->r.mode & R_BORDER) { + if(re->r.border.xmax <= re->r.border.xmin || + re->r.border.ymax <= re->r.border.ymin) { + re->error("No border area selected."); + return 0; + } + } + + if(re->r.xparts*re->r.yparts>=2 && (re->r.mode & R_MOVIECROP) && (re->r.mode & R_BORDER)) { + re->error("Combination of border, crop and parts not allowed"); + return 0; + } + + if(re->r.xparts*re->r.yparts>64) { + re->error("No more than 64 parts supported"); + return 0; + } + + if(re->r.yparts>1 && (re->r.mode & R_PANORAMA)) { + re->error("No Y-Parts supported for Panorama"); + return 0; + } + + /* check valid camera */ + if(re->scene->camera==NULL) + re->scene->camera= scene_find_camera(re->scene); + if(re->scene->camera==NULL) { + re->error("No camera"); + return 0; + } + + + return 1; +} + +/* evaluating scene options for general Blender render */ +static int render_initialize_from_scene(Render *re, Scene *scene) +{ + int winx, winy; + rcti disprect; + + /* r.xsch and r.ysch has the actual view window size + r.border is the clipping rect */ + + /* calculate actual render result and display size */ + winx= (scene->r.size*scene->r.xsch)/100; + winy= (scene->r.size*scene->r.ysch)/100; + // if(scene->r.mode & R_PANORAMA) + // winx*= scene->r.xparts; + + /* only in movie case we render smaller part */ + if(scene->r.mode & R_BORDER) { + disprect.xmin= scene->r.border.xmin*winx; + disprect.xmax= scene->r.border.xmax*winx; + + disprect.ymin= scene->r.border.ymin*winy; + disprect.ymax= scene->r.border.ymax*winy; + } + else { + disprect.xmin= disprect.ymin= 0; + disprect.xmax= winx; + disprect.ymax= winy; + } + + RE_InitState(re, &scene->r, winx, winy, &disprect); + + re->scene= scene; + if(!is_rendering_allowed(re)) + return 0; + + re->display_init(re->result); + re->display_clear(re->result); + + return 1; +} + +/* general Blender frame render call */ +/* should return 1 when all is OK, otherwise it throws up errors */ +void RE_BlenderFrame(Render *re, Scene *scene, int frame) +{ + /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ + /* is also set by caller renderwin.c */ + G.rendering= 1; + + if(render_initialize_from_scene(re, scene)) { + do_render_final(re, scene); + } +} + + +/* saves images to disk */ +void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra) +{ + bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype); + int cfrao= scene->r.cfra; + char name[FILE_MAXDIR+FILE_MAXFILE]; + + /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ + /* is also set by caller renderwin.c */ + G.rendering= 1; + + if(!render_initialize_from_scene(re, scene)) + return; + + /* confusing... scene->r or re->r? make a decision once! */ + if(BKE_imtype_is_movie(scene->r.imtype)) + mh->start_movie(&scene->r, re->rectx, re->recty); + + for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) { + re->r.cfra= scene->r.cfra; /* weak.... */ + + do_render_final(re, scene); + + /* write image or movie */ + if(re->test_break()==0) { + RenderResult rres; + + RE_GetResultImage(re, &rres); + + /* write movie or image */ + if(BKE_imtype_is_movie(scene->r.imtype)) { + /* note; the way it gets 32 bits rects is weak... */ + int dofree=0; + if(rres.rect32==NULL) { + rres.rect32= MEM_mallocN(sizeof(int)*rres.rectx*rres.recty, "temp 32 bits rect"); + dofree= 1; + } + RE_ResultGet32(re, rres.rect32); + mh->append_movie(scene->r.cfra, rres.rect32, rres.rectx, rres.recty); + if(dofree) MEM_freeN(rres.rect32); + printf("Append frame %d", scene->r.cfra); + } + else { + ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.planes, 0, 0); + int ok; + + BKE_makepicstring(name, (scene->r.cfra)); + ibuf->rect= rres.rect32; /* if not exists, BKE_write_ibuf makes one */ + ibuf->rect_float= rres.rectf; + ibuf->zbuf_float= rres.rectz; + ok= BKE_write_ibuf(ibuf, name, scene->r.imtype, scene->r.subimtype, scene->r.quality); + IMB_freeImBuf(ibuf); /* imbuf knows which rects are not part of ibuf */ + + if(ok==0) { + printf("Render error: cannot save %s\n", name); + break; + } + else printf("Saved: %s", name); + } + + BLI_timestr(re->i.lastframetime, name); + printf(" Time: %s\n", name); + fflush(stdout); /* needed for renderd !! (not anymore... (ton)) */ + } + + if(G.afbreek==1) break; + } + + /* end movie */ + if(BKE_imtype_is_movie(scene->r.imtype)) + mh->end_movie(); + + scene->r.cfra= cfrao; +} + + + diff --git a/source/blender/render/intern/source/pixelblending.c b/source/blender/render/intern/source/pixelblending.c index f774a624ba9..73a8e86bc95 100644 --- a/source/blender/render/intern/source/pixelblending.c +++ b/source/blender/render/intern/source/pixelblending.c @@ -6,15 +6,12 @@ * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,29 +25,29 @@ * 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): Full recode, 2004-2006 Blender Foundation * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include /* global includes */ -#include "render.h" - -/* local includes */ -#include "vanillaRenderPipe_types.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" /* own includes */ +#include "render_types.h" +#include "renderpipeline.h" #include "pixelblending.h" #include "gammaCorrectionTables.h" -/* externals */ -#ifdef HAVE_CONFIG_H -#include -#endif +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + /* ------------------------------------------------------------------------- */ /* Debug/behaviour defines */ @@ -72,88 +69,6 @@ #define RE_EMPTY_COLOUR_FLOAT 0.0002 -/* functions --------------------------------------------------------------- */ - -/* - One things about key-alpha is that simply dividing by the alpha will - sometimes cause 'overflows' in that the pixel colours will be shot - way over full colour. This should be caught, and subsequently, the - operation will end up modifying the alpha as well. - - Actually, when the starting colour is premul, it shouldn't overflow - ever. Strange thing is that colours keep overflowing... - -*/ -void applyKeyAlphaCharCol(char* target) { - - if ((!(target[3] == 0)) - || (target[3] == 255)) { - /* else: nothing to do */ - /* check whether div-ing is enough */ - float cf[4]; - cf[0] = target[0]/target[3]; - cf[1] = target[1]/target[3]; - cf[2] = target[2]/target[3]; - if ((cf[0] <= 1.0) && (cf[1] <= 1.0) && (cf[2] <= 1.0)) { - /* all colours remain properly scaled? */ - /* scale to alpha */ - cf[0] = (float) target[0] * (255.0/ (float)target[3]); - cf[1] = (float) target[1] * (255.0/ (float)target[3]); - cf[2] = (float) target[2] * (255.0/ (float)target[3]); - - /* Clipping is important. */ - target[0] = (cf[0] > 255.0 ? 255 : (char) cf[0]); - target[1] = (cf[1] > 255.0 ? 255 : (char) cf[1]); - target[2] = (cf[2] > 255.0 ? 255 : (char) cf[2]); - - } else { - /* shouldn't happen! we were premul, remember? */ -/* should go to error handler: printf("Non-premul colour detected\n"); */ - } - } - -} - -/* ------------------------------------------------------------------------- */ - -void addAddSampColF(float *sampvec, float *source, int mask, int osaNr, - char addfac) -{ - int a; - - for(a=0; a < osaNr; a++) { - if(mask & (1< RE_FULL_COLOUR_FLOAT) retval--; - sampvec+= 4; - } - return retval; -} - - /* ------------------------------------------------------------------------- */ void addAlphaOverFloat(float *dest, float *source) @@ -211,106 +126,6 @@ void addAlphaUnderFloat(float *dest, float *source) } -/* ------------------------------------------------------------------------- */ - -void cpShortColV2CharColV(unsigned short *source, char *dest) -{ - dest[0] = source[0]>>8; - dest[1] = source[1]>>8; - dest[2] = source[2]>>8; - dest[3] = source[3]>>8; -} -/* ------------------------------------------------------------------------- */ - -void cpCharColV2ShortColV(char *source, unsigned short *dest) -{ - dest[0] = source[0]<<8; - dest[1] = source[1]<<8; - dest[2] = source[2]<<8; - dest[3] = source[3]<<8; -} - -/* ------------------------------------------------------------------------- */ - -void cpIntColV2CharColV(unsigned int *source, char *dest) -{ - dest[0] = source[0]>>24; - dest[1] = source[1]>>24; - dest[2] = source[2]>>24; - dest[3] = source[3]>>24; -} - -/* ------------------------------------------------------------------------- */ - -void cpCharColV2FloatColV(char *source, float *dest) -{ - dest[0] = source[0]/255.0; - dest[1] = source[1]/255.0; - dest[2] = source[2]/255.0; - dest[3] = source[3]/255.0; -} - -/* ------------------------------------------------------------------------- */ - -void cpShortColV2FloatColV(unsigned short *source, float *dest) -{ - dest[0] = source[0]/65535.0; - dest[1] = source[1]/65535.0; - dest[2] = source[2]/65535.0; - dest[3] = source[3]/65535.0; -} - -/* ------------------------------------------------------------------------- */ - -void cpFloatColV2CharColV(float* source, char *dest) -{ - /* can't this be done more efficient? hope the conversions are correct... */ - if (source[0] < 0.0) dest[0] = 0; - else if (source[0] > 1.0) dest[0] = 255; - else dest[0] = (char) (source[0] * 255.0); - - if (source[1] < 0.0) dest[1] = 0; - else if (source[1] > 1.0) dest[1] = 255; - else dest[1] = (char) (source[1] * 255.0); - - if (source[2] < 0.0) dest[2] = 0; - else if (source[2] > 1.0) dest[2] = 255; - else dest[2] = (char) (source[2] * 255.0); - - if (source[3] < 0.0) dest[3] = 0; - else if (source[3] > 1.0) dest[3] = 255; - else dest[3] = (char) (source[3] * 255.0); - -} - -/* ------------------------------------------------------------------------- */ - -void cpShortColV(unsigned short *source, unsigned short *dest) -{ - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; - dest[3] = source[3]; -} - -/* ------------------------------------------------------------------------- */ -void cpFloatColV(float *source, float *dest) -{ - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; - dest[3] = source[3]; -} - -/* ------------------------------------------------------------------------- */ - -void cpCharColV(char *source, char *dest) -{ - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; - dest[3] = source[3]; -} /* ------------------------------------------------------------------------- */ void addalphaAddfacFloat(float *dest, float *source, char addfac) @@ -353,43 +168,27 @@ void addalphaAddfacFloat(float *dest, float *source, char addfac) } -/* ------------------------------------------------------------------------- */ - -void sampleShortColV2ShortColV(unsigned short *sample, unsigned short *dest, int osaNr) -{ - unsigned int intcol[4] = {0}; - unsigned short *scol = sample; - int a = 0; - - for(a=0; a < osaNr; a++, scol+=4) { - intcol[0]+= scol[0]; intcol[1]+= scol[1]; - intcol[2]+= scol[2]; intcol[3]+= scol[3]; - } - - /* Now normalise the integrated colour. It is guaranteed */ - /* to be correctly bounded. */ - dest[0]= intcol[0]/osaNr; - dest[1]= intcol[1]/osaNr; - dest[2]= intcol[2]/osaNr; - dest[3]= intcol[3]/osaNr; - -} /* ------------------------------------------------------------------------- */ /* filtered adding to scanlines */ -void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float *rb3) +void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w) { /* calc the value of mask */ - extern float *fmask1[], *fmask2[]; + float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2; + float *rb1, *rb2, *rb3; float val, r, g, b, al; unsigned int a, maskand, maskshift; int j; - al= col[3]; r= col[0]; g= col[1]; b= col[2]; + al= col[3]; + + rb2= rowbuf-4; + rb1= rb2-4*row_w; + rb3= rb2+4*row_w; maskand= (mask & 255); maskshift= (mask >>8); @@ -400,28 +199,28 @@ void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); if(val!=0.0) { - rb1[3]+= val*al; rb1[0]+= val*r; rb1[1]+= val*g; rb1[2]+= val*b; + rb1[3]+= val*al; } a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); if(val!=0.0) { - rb2[3]+= val*al; rb2[0]+= val*r; rb2[1]+= val*g; rb2[2]+= val*b; + rb2[3]+= val*al; } a+=3; val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift); if(val!=0.0) { - rb3[3]+= val*al; rb3[0]+= val*r; rb3[1]+= val*g; rb3[2]+= val*b; + rb3[3]+= val*al; } rb1+= 4; @@ -430,186 +229,6 @@ void add_filt_fmask(unsigned int mask, float *col, float *rb1, float *rb2, float } } - -void sampleFloatColV2FloatColVFilter(float *sample, float *dest1, float *dest2, float *dest3, int osaNr) -{ - float intcol[4] = {0}; - float *scol = sample; - int a = 0; - - if(osaNr==1) { - dest2[4]= sample[0]; - dest2[5]= sample[1]; - dest2[6]= sample[2]; - dest2[7]= sample[3]; - } - else { - if (do_gamma) { - /* use a LUT and interpolation to do the gamma correction */ - for(a=0; a < osaNr; a++, scol+=4) { - intcol[0] = gammaCorrect( (scol[0]<1.0) ? scol[0]:1.0 ); - intcol[1] = gammaCorrect( (scol[1]<1.0) ? scol[1]:1.0 ); - intcol[2] = gammaCorrect( (scol[2]<1.0) ? scol[2]:1.0 ); - intcol[3] = scol[3]; - add_filt_fmask(1<255) doel[0]=255; - else doel[0]= c; - c= (doel[1]<<8)/div; - if(c>255) doel[1]=255; - else doel[1]= c; - c= (doel[2]<<8)/div; - if(c>255) doel[2]=255; - else doel[2]= c; - } -} - -/* ------------------------------------------------------------------------- */ -/* fills in bron (source) under doel (target) with alpha of doel*/ -void addalphaUnder(char *doel, char *bron) -{ - int c; - int mul; - - if(doel[3]==255) return; - if( doel[3]==0) { /* tested */ - *((unsigned int *)doel)= *((unsigned int *)bron); - return; - } - - mul= 255-doel[3]; - - c= doel[0]+ ((mul*bron[0])/255); - if(c>255) doel[0]=255; - else doel[0]= c; - c= doel[1]+ ((mul*bron[1])/255); - if(c>255) doel[1]=255; - else doel[1]= c; - c= doel[2]+ ((mul*bron[2])/255); - if(c>255) doel[2]=255; - else doel[2]= c; - - c= doel[3]+ ((mul*bron[3])/255); - if(c>255) doel[3]=255; - else doel[3]= c; - - /* doel[0]= MAX2(doel[0], bron[0]); */ -} - -/* ------------------------------------------------------------------------- */ -/* gamma-corrected */ -void addalphaUnderGamma(char *doel, char *bron) -{ - unsigned int tot; - int c, doe, bro; - int mul; - - /* if doel[3]==0 or doel==255 has been handled in sky loop */ - mul= 256-doel[3]; - - doe= igamtab1[(int)doel[0]]; - bro= igamtab1[(int)bron[0]]; - tot= (doe+ ((mul*bro)>>8)); - if(tot>65535) tot=65535; - doel[0]= *((gamtab+tot)) >>8; - - doe= igamtab1[(int)doel[1]]; - bro= igamtab1[(int)bron[1]]; - tot= (doe+ ((mul*bro)>>8)); - if(tot>65535) tot=65535; - doel[1]= *((gamtab+tot)) >>8; - - doe= igamtab1[(int)doel[2]]; - bro= igamtab1[(int)bron[2]]; - tot= (doe+ ((mul*bro)>>8)); - if(tot>65535) tot=65535; - doel[2]= *((gamtab+tot)) >>8; - - c= doel[3]+ ((mul*bron[3])/255); - if(c>255) doel[3]=255; - else doel[3]= c; - /* doel[0]= MAX2(doel[0], bron[0]); */ -} - -/* ------------------------------------------------------------------------- */ -/* doel= bron over doel */ -void addalphaOver(char *doel, char *bron) -{ - int c; - int mul; - - if(bron[3]==0) return; - if( bron[3]==255) { /* tested */ - *((unsigned int *)doel)= *((unsigned int *)bron); - return; - } - - mul= 255-bron[3]; - - c= ((mul*doel[0])/255)+bron[0]; - if(c>255) doel[0]=255; - else doel[0]= c; - c= ((mul*doel[1])/255)+bron[1]; - if(c>255) doel[1]=255; - else doel[1]= c; - c= ((mul*doel[2])/255)+bron[2]; - if(c>255) doel[2]=255; - else doel[2]= c; - c= ((mul*doel[3])/255)+bron[3]; - if(c>255) doel[3]=255; - else doel[3]= c; -} - -/* ------------------------------------------------------------------------- */ -void addalphaAdd(char *doel, char *bron) /* adds bron (source) to doel (target) */ -{ - int c; - - if( doel[3]==0 || bron[3]==255) { /* tested */ - *((unsigned int *)doel)= *((unsigned int *)bron); - return; - } - c= doel[0]+bron[0]; - if(c>255) doel[0]=255; - else doel[0]= c; - c= doel[1]+bron[1]; - if(c>255) doel[1]=255; - else doel[1]= c; - c= doel[2]+bron[2]; - if(c>255) doel[2]=255; - else doel[2]= c; - c= doel[3]+bron[3]; - if(c>255) doel[3]=255; - else doel[3]= c; -} - /* ------------------------------------------------------------------------- */ void addalphaAddFloat(float *dest, float *source) { @@ -631,44 +250,136 @@ void addalphaAddFloat(float *dest, float *source) } -/* ALPHADDFAC: - * - * Z= X alphaover Y: - * Zrgb= (1-Xa)*Yrgb + Xrgb - * - * (1-fac)*(1-Xa) + fac <=> - * 1-Xa-fac+fac*Xa+fac <=> - * Xa*(fac-1)+1 - */ - /* ------------------------------------------------------------------------- */ -/* doel= bron over doel */ -void RE_addalphaAddfac(char *doel, char *bron, char addfac) + +/* ------------------------------------------------------------------------- */ +/* Colour buffer related: */ +/* This transforms the 4 inputvalues RE_COLBUFTYPE to a new value */ +/* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd. */ +/* This is the standard transformation, more elaborate tools are for later. */ +/* ------------------------------------------------------------------------- */ +void std_floatcol_to_charcol( float *buf, char *target) { + float col[3]; - int c, mul; - - mul= 255 - (bron[3]*(255-addfac))/255; - - c= ((mul*doel[0])/255)+bron[0]; - if(c>255) doel[0]=255; - else doel[0]= c; - c= ((mul*doel[1])/255)+bron[1]; - if(c>255) doel[1]=255; - else doel[1]= c; - c= ((mul*doel[2])/255)+bron[2]; - if(c>255) doel[2]=255; - else doel[2]= c; + float dither_value; - /* c= ((mul*doel[3])/255)+bron[3]; */ - c= doel[3]+bron[3]; - if(c>255) doel[3]=255; - else doel[3]= c; + dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0; + + /* alpha */ + if((buf[3]+dither_value)<=0.0) target[3]= 0; + else if((buf[3]+dither_value)>1.0) target[3]= 255; + else target[3]= 255.0*(buf[3]+dither_value); + + if(R.r.postgamma==1.0) { + /* r */ + col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value; + /* g */ + col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value; + /* b */ + col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value; + } + else { + /* putting the postmul within the pow() gives an + * easier control for the user, values from 1.0-2.0 + * are relevant then + */ + + /* r */ + col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value; + /* g */ + col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value; + /* b */ + col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value; + } + + if(R.r.posthue!=0.0 || R.r.postsat!=1.0) { + float hsv[3]; + + rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2); + hsv[0]+= R.r.posthue; + if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; + hsv[1]*= R.r.postsat; + if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; + hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); + } + + if(col[0]<=0.0) target[0]= 0; + else if(col[0]>1.0) target[0]= 255; + else target[0]= 255.0*col[0]; + + if(col[1]<=0.0) target[1]= 0; + else if(col[1]>1.0) target[1]= 255; + else target[1]= 255.0*col[1]; + + if(col[2]<=0.0) target[2]= 0; + else if(col[2]>1.0) target[2]= 255; + else target[2]= 255.0*col[2]; } +/* ---------------------------------------------------------------------------- + +Colour buffer related: + +The colour buffer is a buffer of a single screen line. It contains +four fields of type RE_COLBUFTYPE per pixel. + +We can do several post-process steps. I would prefer to move them outside +the render module later on, but it's ok to leave it here for now. For the +time being, we have: +- post-process function + Does some operations with the colours. +- Multiply with some factor +- Add constant offset +- Apply extra gamma correction (seems weird...) +- key-alpha correction + Key alpha means 'un-applying' the alpha. For fully covered pixels, this + operation has no effect. + +- XXX WARNING! Added the inverse render gamma here, so this cannot be used external + without setting Osa or Gamma flags off (ton) + +---------------------------------------------------------------------------- */ +/* used external! */ +void transferColourBufferToOutput( float *buf, int y) +{ + /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */ + int x = 0; +// char *target = (char*) (R.rectot + (y * R.rectx)); + + /* Copy the first pixels. We can do some more clipping on */ + /* the z buffer, I think. */ + while (x < R.rectx) { + + + /* invert gamma corrected additions */ + if(R.do_gamma) { + buf[0] = invGammaCorrect(buf[0]); + buf[1] = invGammaCorrect(buf[1]); + buf[2] = invGammaCorrect(buf[2]); + } + +// std_floatcol_to_charcol(buf, target); + + /* + Key-alpha mode: + Need to un-apply alpha if alpha is non-full. For full alpha, + the operation doesn't have effect. Do this after the post- + processing, so we can still use the benefits of that. + + */ + + if (R.r.alphamode == R_ALPHAKEY) { +// applyKeyAlphaCharCol(target); + } + +// target+=4; + buf+=4; + x++; + } +} -/* ------------------------------------------------------------------------- */ /* eof pixelblending.c */ diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index d0c23f6daf3..53bce2cbb84 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -1,14 +1,11 @@ /** * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,17 +19,9 @@ * 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/BL DUAL LICENSE BLOCK ***** - * Shading of pixels - * - * 11-09-2000 nzc - * - * $Id$ + * Contributor(s): 2004-2006, Blender Foundation, full recode * + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -45,6 +34,7 @@ #include "MTC_vectorops.h" #include "DNA_camera_types.h" +#include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_image_types.h" @@ -56,112 +46,32 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" -#include "render.h" +/* own module */ +#include "render_types.h" +#include "renderpipeline.h" +#include "renderdatabase.h" #include "texture.h" - -#include "vanillaRenderPipe_types.h" #include "pixelblending.h" -#include "rendercore.h" /* for some shading functions... */ +#include "rendercore.h" #include "shadbuf.h" -#include "zbufferdatastruct.h" - -#include "renderHelp.h" - #include "gammaCorrectionTables.h" -#include "errorHandler.h" #include "pixelshading.h" +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/* ton: - - unified render now uses face render routines from rendercore.c - - todo still: shalo render and sky routines */ - - -/* ------------------------------------------------------------------------- */ -static int calcHaloZ(HaloRen *har, int zz) -{ - - if(har->type & HA_ONLYSKY) { - if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF; - } - else { - zz= (zz>>8); - } - return zz; -} - -static void *renderHaloPixel(RE_COLBUFTYPE *collector, float x, float y, int haloNr) -{ - HaloRen *har = NULL; - float dist = 0.0; - int zz = 0; - - /* Find har to go with haloNr */ - har = RE_findOrAddHalo(haloNr); - - /* zz is a strange number... This call should effect that halo's are */ - /* never cut? Seems a bit strange to me now... (nzc) */ - /* it checks for sky... which is info not available in unified (ton) */ - zz = calcHaloZ(har, 0x7FFFFFFF); - if(zz> har->zs) { - - /* distance of this point wrt. the halo center. Maybe xcor is also needed? */ - dist = ((x - har->xs) * (x - har->xs)) - + ((y - har->ys) * (y - har->ys) * R.ycor * R.ycor) ; - - collector[0] = 0.0f; collector[1] = 0.0f; - collector[2] = 0.0f; collector[3] = 0.0f; - - if (dist < har->radsq) { - shadeHaloFloat(har, collector, zz, dist, - (x - har->xs), (y - har->ys) * R.ycor, har->flarec); - }; /* else: this pixel is not rendered for this halo: no colour */ - } - return (void*) har; - -} /* end of void* renderHaloPixel(float x, float y, int haloNr) */ - - - -/* ------------------------------------------------------------------------- */ - -void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int mask) -{ - void* data = NULL; - - if (obdata[3] & RE_POLY) { - data = shadepixel(x, y, obdata[0], obdata[1], mask, collector); - } - else if (obdata[3] & RE_HALO) { - data = renderHaloPixel(collector, x, y, obdata[1]); - } - else if( obdata[1] == 0 ) { - /* for lamphalo, but doesn't seem to be called? Actually it is, and */ - /* it returns NULL pointers. */ - data = shadepixel(x, y, obdata[0], obdata[1], mask, collector); - } - return data; - -} /* end of void renderPixel(float x, float y, int *obdata) */ - -/* ------------------------------------------------------------------------- */ - -void renderSpotHaloPixel(float x, float y, float* fcol) -{ - shadepixel(x, y, 0, 0, 0, fcol); -} - - -/* ------------------------------------------------------------------------- */ extern float hashvectf[]; static void render_lighting_halo(HaloRen *har, float *colf) { + GroupObject *go; LampRen *lar; float i, inp, inpr, rco[3], dco[3], lv[3], lampdist, ld, t, *vn; float ir, ig, ib, shadfac, soft, lacol[3]; - int a; ir= ig= ib= 0.0; @@ -170,8 +80,8 @@ static void render_lighting_halo(HaloRen *har, float *colf) vn= har->no; - for(a=0; anext) { + lar= go->lampren; /* test for lamplayer */ if(lar->mode & LA_LAYER) if((lar->lay & har->lay)==0) continue; @@ -494,7 +404,7 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz, if(har->mat) { if(har->mat->mode & MA_HALO_SHADE) { /* we test for lights because of preview... */ - if(R.totlamp) render_lighting_halo(har, col); + if(R.lights.first) render_lighting_halo(har, col); } /* Next, we do the line and ring factor modifications. */ @@ -534,29 +444,14 @@ void shadeHaloFloat(HaloRen *har, float *col, int zz, */ -/* Sky vars. */ -enum RE_SkyAlphaBlendingType keyingType = RE_ALPHA_SKY; /* The blending type */ - -void setSkyBlendingMode(enum RE_SkyAlphaBlendingType mode) { - if ((RE_ALPHA_NODEF < mode) && (mode < RE_ALPHA_MAX) ) { - keyingType = mode; - } else { - /* error: false mode received */ - keyingType = RE_ALPHA_SKY; - } -} - -enum RE_SkyAlphaBlendingType getSkyBlendingMode() { - return keyingType; -} /* This one renders into collector, as always. */ -void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y) +void renderSkyPixelFloat(float *collector, float x, float y, float *rco) { - switch (keyingType) { - case RE_ALPHA_PREMUL: - case RE_ALPHA_KEY: + switch (R.r.alphamode) { + case R_ALPHAPREMUL: + case R_ALPHAKEY: /* Premul or key: don't fill, and don't change the values! */ /* key alpha used to fill in color in 'empty' pixels, doesn't work anymore this way */ collector[0] = 0.0; @@ -564,9 +459,9 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y) collector[2] = 0.0; collector[3] = 0.0; break; - case RE_ALPHA_SKY: + case R_ADDSKY: /* Fill in the sky as if it were a normal face. */ - shadeSkyPixel(collector, x, y); + shadeSkyPixel(collector, x, y, rco); collector[3]= 0.0; break; default: @@ -574,12 +469,10 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y) } } - - /* Stuff the sky colour into the collector. */ -void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy) +void shadeSkyPixel(float *collector, float fx, float fy, float *rco) { float view[3], dxyview[2]; @@ -593,7 +486,7 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy) /* 1. Do a backbuffer image: */ if(R.r.bufflag & 1) { - fillBackgroundImage(collector, fx, fy); +// fillBackgroundImage(collector, fx, fy); return; } else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { /* @@ -616,26 +509,17 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy) /* This one true because of the context of this routine */ /* if(rect[3] < 254) { */ if(R.wrld.skytype & WO_SKYPAPER) { - view[0]= (fx+(R.xstart))/(float)R.afmx; - view[1]= (fy+(R.ystart))/(float)R.afmy; + view[0]= (fx/(float)R.winx); + view[1]= (fy/(float)R.winy); view[2]= 0.0; - dxyview[0]= 1.0/(float)R.afmx; - dxyview[1]= 1.0/(float)R.afmy; + dxyview[0]= 1.0f/(float)R.winx; + dxyview[1]= 1.0f/(float)R.winy; } else { - /* Wasn't this some pano stuff? */ - view[0]= (fx+(R.xstart)+1.0); - - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (fy+R.ystart+0.5)*R.ycor; - else view[1]= (fy+R.ystart+1.5)*R.ycor; - } - else view[1]= (fy+R.ystart+1.0)*R.ycor; - - view[2]= -R.viewfac; - + calc_view_vector(view, fx, fy); fac= Normalise(view); + if(R.wrld.skytype & WO_SKYTEX) { dxyview[0]= 1.0/fac; dxyview[1]= R.ycor/fac; @@ -643,25 +527,20 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy) } if(R.r.mode & R_PANORAMA) { - float panoco, panosi; - float u, v; + float u= view[0]; float v= view[2]; - panoco = getPanovCo(); - panosi = getPanovSi(); - u= view[0]; v= view[2]; - - view[0]= panoco*u + panosi*v; - view[2]= -panosi*u + panoco*v; + view[0]= R.panoco*u + R.panosi*v; + view[2]= -R.panosi*u + R.panoco*v; } /* get sky colour in the collector */ - shadeSkyPixelFloat(collector, view, dxyview); + shadeSkyPixelFloat(collector, rco, view, dxyview); collector[3] = 1.0f; } } /* Only view vector is important here. Result goes to colf[3] */ -void shadeSkyPixelFloat(float *colf, float *view, float *dxyview) +void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview) { float lo[3], zen[3], hor[3], blend, blendm; @@ -698,7 +577,7 @@ void shadeSkyPixelFloat(float *colf, float *view, float *dxyview) SWAP(float, lo[1], lo[2]); } - do_sky_tex(lo, dxyview, hor, zen, &blend); + do_sky_tex(rco, lo, dxyview, hor, zen, &blend); } if(blend>1.0) blend= 1.0; @@ -718,68 +597,4 @@ void shadeSkyPixelFloat(float *colf, float *view, float *dxyview) } -/* - Render pixel (x,y) from the backbuffer into the collector - - backbuf is type Image, backbuf->ibuf is an ImBuf. ibuf->rect is the - rgba data (32 bit total), in ibuf->x by ibuf->y pixels. Copying - should be really easy. I hope I understand the way ImBuf works - correctly. (nzc) -*/ -void fillBackgroundImageChar(char *col, float x, float y) -{ - - int iy, ix; - unsigned int* imBufPtr; - - /* check to be sure... */ - if (R.backbuf==NULL || R.backbuf->ok==0) { - /* bail out */ - col[0] = 0; - col[1] = 0; - col[2] = 0; - col[3] = 255; - return; - } - /* load image if not already done?*/ - if(R.backbuf->ibuf==0) { - R.backbuf->ok= 0; - return; - } - - tag_image_time(R.backbuf); - - /* Now for the real extraction: */ - /* Get the y-coordinate of the scanline? */ - iy= (int) ((y+R.afmy+R.ystart)*R.backbuf->ibuf->y)/(2*R.afmy); - ix= (int) ((x+R.afmx+R.xstart)*R.backbuf->ibuf->x)/(2*R.afmx); - - /* correct in case of fields rendering: */ - if(R.flag & R_SEC_FIELD) { - if((R.r.mode & R_ODDFIELD)==0) { - if( iyibuf->y) iy++; - } - else { - if( iy>0) iy--; - } - } - - /* Offset into the buffer: start of scanline y: */ - imBufPtr = R.backbuf->ibuf->rect - + (iy * R.backbuf->ibuf->x) - + ix; - - *( (int *)col) = *imBufPtr; - -} - -void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y) -{ - char col[4]; - - fillBackgroundImageChar(col, x, y); - cpCharColV2FloatColV(col, collector); - -} - /* eof */ diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index d9f94c0be60..19ec1dd546d 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,15 +20,16 @@ * The Original Code is Copyright (C) 1990-1998 NeoGeo BV. * All rights reserved. * - * The Original Code is: all of this file. + * Contributors: 2004/2005 Blender Foundation, full recode * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include #include #include +#include #include "MEM_guardedalloc.h" @@ -42,17 +40,16 @@ #include "BKE_global.h" #include "BLI_arithb.h" -#include +#include "BLI_rand.h" +#include "BLI_jitter.h" -#include "render.h" +#include "render_types.h" +#include "renderpipeline.h" #include "rendercore.h" #include "pixelblending.h" #include "pixelshading.h" -#include "jitter.h" #include "texture.h" -#include "SDL_thread.h" - #define DDA_SHADOW 0 #define DDA_MIRROR 1 #define DDA_SHADOW_TRA 2 @@ -61,23 +58,17 @@ #define RAY_TRAFLIP 2 #define DEPTH_SHADOW_TRA 10 -/* from float.h */ -#define FLT_EPSILON 1.19209290e-07F +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* ********** structs *************** */ #define BRANCH_ARRAY 1024 - -typedef struct Octree { - struct Branch *adrbranch[BRANCH_ARRAY]; - struct Node *adrnode[4096]; - float ocsize; /* ocsize: mult factor, max size octree */ - float ocfacx,ocfacy,ocfacz; - float min[3], max[3]; - int ocres; - -} Octree; +#define NODE_ARRAY 4096 typedef struct Isect { float start[3], vec[3], end[3]; /* start+vec = end, in d3dda */ @@ -112,16 +103,10 @@ typedef struct Node /* ******** globals ***************** */ -static Octree g_oc; /* can be scene pointer or so later... */ - /* just for statistics */ -static int raycount, branchcount, nodecount; +static int raycount; static int accepted, rejected, coherent_ray; -/* prototypes ------------------------ */ -void freeoctree(void); -void makeoctree(void); -int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr); /* **************** ocval method ******************* */ /* within one octree node, a set of 3x15 bits defines a 'boundbox' to OR with */ @@ -190,36 +175,42 @@ static void calc_ocval_ray(OcVal *ov, float xo, float yo, float zo, float *vec1, /* ************* octree ************** */ -static Branch *addbranch(Branch *br, short oc) +static Branch *addbranch(Octree *oc, Branch *br, short ocb) { + int index; - if(br->b[oc]) return br->b[oc]; + if(br->b[ocb]) return br->b[ocb]; - branchcount++; - if(g_oc.adrbranch[branchcount>>12]==NULL) - g_oc.adrbranch[branchcount>>12]= MEM_callocN(4096*sizeof(Branch),"addbranch"); + oc->branchcount++; + index= oc->branchcount>>12; + + if(oc->adrbranch[index]==NULL) + oc->adrbranch[index]= MEM_callocN(4096*sizeof(Branch), "new oc branch"); - if(branchcount>= BRANCH_ARRAY*4096) { + if(oc->branchcount>= BRANCH_ARRAY*4096) { printf("error; octree branches full\n"); - branchcount=0; + oc->branchcount=0; } - return br->b[oc]=g_oc.adrbranch[branchcount>>12]+(branchcount & 4095); + return br->b[ocb]= oc->adrbranch[index]+(oc->branchcount & 4095); } -static Node *addnode(void) +static Node *addnode(Octree *oc) { + int index; - nodecount++; - if(g_oc.adrnode[nodecount>>12]==NULL) - g_oc.adrnode[nodecount>>12]= MEM_callocN(4096*sizeof(Node),"addnode"); + oc->nodecount++; + index= oc->nodecount>>12; + + if(oc->adrnode[index]==NULL) + oc->adrnode[index]= MEM_callocN(4096*sizeof(Node),"addnode"); - if(nodecount> 4096*4096) { + if(oc->nodecount> NODE_ARRAY*NODE_ARRAY) { printf("error; octree nodes full\n"); - nodecount=0; + oc->nodecount=0; } - return g_oc.adrnode[nodecount>>12]+(nodecount & 4095); + return oc->adrnode[index]+(oc->nodecount & 4095); } static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3]) @@ -262,7 +253,7 @@ static int face_in_node(VlakRen *vlr, short x, short y, short z, float rtf[][3]) return 0; } -static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3]) +static void ocwrite(Octree *oc, VlakRen *vlr, short x, short y, short z, float rtf[][3]) { Branch *br; Node *no; @@ -273,19 +264,19 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3]) x<<=2; y<<=1; - br= g_oc.adrbranch[0]; + br= oc->adrbranch[0]; - if(g_oc.ocres==512) { + if(oc->ocres==512) { oc0= ((x & 1024)+(y & 512)+(z & 256))>>8; - br= addbranch(br, oc0); + br= addbranch(oc, br, oc0); } - if(g_oc.ocres>=256) { + if(oc->ocres>=256) { oc0= ((x & 512)+(y & 256)+(z & 128))>>7; - br= addbranch(br, oc0); + br= addbranch(oc, br, oc0); } - if(g_oc.ocres>=128) { + if(oc->ocres>=128) { oc0= ((x & 256)+(y & 128)+(z & 64))>>6; - br= addbranch(br, oc0); + br= addbranch(oc, br, oc0); } oc0= ((x & 128)+(y & 64)+(z & 32))>>5; @@ -295,19 +286,19 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3]) oc4= ((x & 8)+(y & 4)+(z & 2))>>1; oc5= ((x & 4)+(y & 2)+(z & 1)); - br= addbranch(br,oc0); - br= addbranch(br,oc1); - br= addbranch(br,oc2); - br= addbranch(br,oc3); - br= addbranch(br,oc4); + 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()); + 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(); + no->next= addnode(oc); no= no->next; } else { @@ -320,7 +311,7 @@ static void ocwrite(VlakRen *vlr, short x, short y, short z, float rtf[][3]) } -static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rts[][3], float rtf[][3]) +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; @@ -333,7 +324,7 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt ocy2= rts[b2][c2]; if(ocx1==ocx2 && ocy1==ocy2) { - ocvlak[g_oc.ocres*ocx1+ocy1]= 1; + ocface[oc->ocres*ocx1+ocy1]= 1; return; } @@ -377,8 +368,8 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt while(TRUE) { - if(x<0 || y<0 || x>=g_oc.ocres || y>=g_oc.ocres); - else ocvlak[g_oc.ocres*x+y]= 1; + if(x<0 || y<0 || x>=oc->ocres || y>=oc->ocres); + else ocface[oc->ocres*x+y]= 1; labdao=labda; if(labdax==labday) { @@ -399,10 +390,10 @@ static void d2dda(short b1, short b2, short c1, short c2, char *ocvlak, short rt if(labda==labdao) break; if(labda>=1.0) break; } - ocvlak[g_oc.ocres*ocx2+ocy2]=1; + ocface[oc->ocres*ocx2+ocy2]=1; } -static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin) +static void filltriangle(Octree *oc, short c1, short c2, char *ocface, short *ocmin) { short *ocmax; int a, x, y, y1, y2; @@ -410,14 +401,14 @@ static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin) ocmax=ocmin+3; for(x=ocmin[c1];x<=ocmax[c1];x++) { - a= g_oc.ocres*x; + a= oc->ocres*x; for(y=ocmin[c2];y<=ocmax[c2];y++) { - if(ocvlak[a+y]) { + if(ocface[a+y]) { y++; - while(ocvlak[a+y] && y!=ocmax[c2]) y++; + while(ocface[a+y] && y!=ocmax[c2]) y++; for(y1=ocmax[c2];y1>y;y1--) { - if(ocvlak[a+y1]) { - for(y2=y;y2<=y1;y2++) ocvlak[a+y2]=1; + if(ocface[a+y1]) { + for(y2=y;y2<=y1;y2++) ocface[a+y2]=1; y1=0; } } @@ -427,35 +418,45 @@ static void filltriangle(short c1, short c2, char *ocvlak, short *ocmin) } } -void freeoctree(void) +void freeoctree(Render *re) { - int a= 0; - - while(g_oc.adrbranch[a]) { - MEM_freeN(g_oc.adrbranch[a]); - g_oc.adrbranch[a]= NULL; - a++; - } - - a= 0; - while(g_oc.adrnode[a]) { - MEM_freeN(g_oc.adrnode[a]); - g_oc.adrnode[a]= NULL; - a++; - } + Octree *oc= &re->oc; if(G.f & G_DEBUG) { - printf("branches %d nodes %d\n", branchcount, nodecount); + 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); } - branchcount= 0; - nodecount= 0; + + 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; } -void makeoctree(void) +void makeoctree(Render *re) { + Octree *oc; VlakRen *vlr=NULL; VertRen *v1, *v2, *v3, *v4; float ocfac[3], t00, t01, t02; @@ -463,68 +464,68 @@ void makeoctree(void) int v; int a, b, c, oc1, oc2, oc3, oc4, x, y, z, ocres2; short rts[4][3], ocmin[6], *ocmax; - char *ocvlak; // front, top, size view of face, to fill in + char *ocface; // front, top, size view of face, to fill in + + oc= &re->oc; + oc->adrbranch= MEM_callocN(sizeof(void *)*BRANCH_ARRAY, "octree branches"); + oc->adrnode= MEM_callocN(sizeof(void *)*NODE_ARRAY, "octree nodes"); ocmax= ocmin+3; - - memset(g_oc.adrnode, 0, sizeof(g_oc.adrnode)); - memset(g_oc.adrbranch, 0, sizeof(g_oc.adrbranch)); - branchcount=0; - nodecount=0; + /* only for debug info */ raycount=0; accepted= 0; rejected= 0; coherent_ray= 0; /* fill main octree struct */ - g_oc.ocres= R.r.ocres; - ocres2= g_oc.ocres*g_oc.ocres; - INIT_MINMAX(g_oc.min, g_oc.max); + oc->ocres= re->r.ocres; + ocres2= oc->ocres*oc->ocres; + INIT_MINMAX(oc->min, oc->max); /* first min max octree space */ - for(v=0;v>8]; + for(v=0;vtotvlak;v++) { + if((v & 255)==0) vlr= re->blovl[v>>8]; else vlr++; if(vlr->mat->mode & MA_TRACEBLE) { if((vlr->mat->mode & MA_WIRE)==0) { - DO_MINMAX(vlr->v1->co, g_oc.min, g_oc.max); - DO_MINMAX(vlr->v2->co, g_oc.min, g_oc.max); - DO_MINMAX(vlr->v3->co, g_oc.min, g_oc.max); + DO_MINMAX(vlr->v1->co, oc->min, oc->max); + DO_MINMAX(vlr->v2->co, oc->min, oc->max); + DO_MINMAX(vlr->v3->co, oc->min, oc->max); if(vlr->v4) { - DO_MINMAX(vlr->v4->co, g_oc.min, g_oc.max); + DO_MINMAX(vlr->v4->co, oc->min, oc->max); } } } } - if(g_oc.min[0] > g_oc.max[0]) return; /* empty octree */ + if(oc->min[0] > oc->max[0]) return; /* empty octree */ - g_oc.adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree"); + oc->adrbranch[0]=(Branch *)MEM_callocN(4096*sizeof(Branch), "makeoctree"); /* the lookup table, per face, for which nodes to fill in */ - ocvlak= MEM_callocN( 3*ocres2 + 8, "ocvlak"); - memset(ocvlak, 0, 3*ocres2); + ocface= MEM_callocN( 3*ocres2 + 8, "ocface"); + memset(ocface, 0, 3*ocres2); for(c=0;c<3;c++) { /* octree enlarge, still needed? */ - g_oc.min[c]-= 0.01; - g_oc.max[c]+= 0.01; + oc->min[c]-= 0.01; + oc->max[c]+= 0.01; } - t00= g_oc.max[0]-g_oc.min[0]; - t01= g_oc.max[1]-g_oc.min[1]; - t02= g_oc.max[2]-g_oc.min[2]; + 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? */ - g_oc.ocfacx=ocfac[0]= (g_oc.ocres-0.1)/t00; - g_oc.ocfacy=ocfac[1]= (g_oc.ocres-0.1)/t01; - g_oc.ocfacz=ocfac[2]= (g_oc.ocres-0.1)/t02; + oc->ocfacx=ocfac[0]= (oc->ocres-0.1)/t00; + oc->ocfacy=ocfac[1]= (oc->ocres-0.1)/t01; + oc->ocfacz=ocfac[2]= (oc->ocres-0.1)/t02; - g_oc.ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */ + oc->ocsize= sqrt(t00*t00+t01*t01+t02*t02); /* global, max size octree */ - for(v=0; v>8]; + for(v=0; vtotvlak; v++) { + if((v & 255)==0) vlr= re->blovl[v>>8]; else vlr++; if(vlr->mat->mode & MA_TRACEBLE) { @@ -536,14 +537,14 @@ void makeoctree(void) v4= vlr->v4; for(c=0;c<3;c++) { - rtf[0][c]= (v1->co[c]-g_oc.min[c])*ocfac[c] ; + rtf[0][c]= (v1->co[c]-oc->min[c])*ocfac[c] ; rts[0][c]= (short)rtf[0][c]; - rtf[1][c]= (v2->co[c]-g_oc.min[c])*ocfac[c] ; + rtf[1][c]= (v2->co[c]-oc->min[c])*ocfac[c] ; rts[1][c]= (short)rtf[1][c]; - rtf[2][c]= (v3->co[c]-g_oc.min[c])*ocfac[c] ; + rtf[2][c]= (v3->co[c]-oc->min[c])*ocfac[c] ; rts[2][c]= (short)rtf[2][c]; if(v4) { - rtf[3][c]= (v4->co[c]-g_oc.min[c])*ocfac[c] ; + rtf[3][c]= (v4->co[c]-oc->min[c])*ocfac[c] ; rts[3][c]= (short)rtf[3][c]; } } @@ -563,44 +564,44 @@ void makeoctree(void) ocmin[c]= MIN4(oc1,oc2,oc3,oc4); ocmax[c]= MAX4(oc1,oc2,oc3,oc4); } - if(ocmax[c]>g_oc.ocres-1) ocmax[c]=g_oc.ocres-1; + if(ocmax[c]>oc->ocres-1) ocmax[c]=oc->ocres-1; if(ocmin[c]<0) ocmin[c]=0; } - d2dda(0,1,0,1,ocvlak+ocres2,rts,rtf); - d2dda(0,1,0,2,ocvlak,rts,rtf); - d2dda(0,1,1,2,ocvlak+2*ocres2,rts,rtf); - d2dda(1,2,0,1,ocvlak+ocres2,rts,rtf); - d2dda(1,2,0,2,ocvlak,rts,rtf); - d2dda(1,2,1,2,ocvlak+2*ocres2,rts,rtf); + 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(2,0,0,1,ocvlak+ocres2,rts,rtf); - d2dda(2,0,0,2,ocvlak,rts,rtf); - d2dda(2,0,1,2,ocvlak+2*ocres2,rts,rtf); + 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(2,3,0,1,ocvlak+ocres2,rts,rtf); - d2dda(2,3,0,2,ocvlak,rts,rtf); - d2dda(2,3,1,2,ocvlak+2*ocres2,rts,rtf); - d2dda(3,0,0,1,ocvlak+ocres2,rts,rtf); - d2dda(3,0,0,2,ocvlak,rts,rtf); - d2dda(3,0,1,2,ocvlak+2*ocres2,rts,rtf); + 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(0,1,ocvlak+ocres2,ocmin); - filltriangle(0,2,ocvlak,ocmin); - filltriangle(1,2,ocvlak+2*ocres2,ocmin); + 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(vlr, 0,0,0, rtf); for(x=ocmin[0];x<=ocmax[0];x++) { - a= g_oc.ocres*x; + a= oc->ocres*x; for(y=ocmin[1];y<=ocmax[1];y++) { - if(ocvlak[a+y+ocres2]) { - b= g_oc.ocres*y+2*ocres2; + if(ocface[a+y+ocres2]) { + b= oc->ocres*y+2*ocres2; for(z=ocmin[2];z<=ocmax[2];z++) { - if(ocvlak[b+z] && ocvlak[a+z]) ocwrite(vlr, x,y,z, rtf); + if(ocface[b+z] && ocface[a+z]) ocwrite(oc, vlr, x,y,z, rtf); } } } @@ -608,17 +609,17 @@ void makeoctree(void) /* same loops to clear octree, doubt it can be done smarter */ for(x=ocmin[0];x<=ocmax[0];x++) { - a= g_oc.ocres*x; + a= oc->ocres*x; for(y=ocmin[1];y<=ocmax[1];y++) { /* x-y */ - ocvlak[a+y+ocres2]= 0; + ocface[a+y+ocres2]= 0; - b= g_oc.ocres*y + 2*ocres2; + b= oc->ocres*y + 2*ocres2; for(z=ocmin[2];z<=ocmax[2];z++) { /* y-z */ - ocvlak[b+z]= 0; + ocface[b+z]= 0; /* x-z */ - ocvlak[a+z]= 0; + ocface[a+z]= 0; } } } @@ -626,7 +627,7 @@ void makeoctree(void) } } - MEM_freeN(ocvlak); + MEM_freeN(ocface); } /* ************ raytracer **************** */ @@ -1007,23 +1008,23 @@ static Node *ocread(int x, int y, int z) x<<=2; y<<=1; - br= g_oc.adrbranch[0]; + br= R.oc.adrbranch[0]; - if(g_oc.ocres==512) { + if(R.oc.ocres==512) { oc1= ((x & 1024)+(y & 512)+(z & 256))>>8; br= br->b[oc1]; if(br==NULL) { return NULL; } } - if(g_oc.ocres>=256) { + if(R.oc.ocres>=256) { oc1= ((x & 512)+(y & 256)+(z & 128))>>7; br= br->b[oc1]; if(br==NULL) { return NULL; } } - if(g_oc.ocres>=128) { + if(R.oc.ocres>=128) { oc1= ((x & 256)+(y & 128)+(z & 64))>>6; br= br->b[oc1]; if(br==NULL) { @@ -1127,7 +1128,7 @@ static int d3dda(Isect *is) int ocx1,ocx2,ocy1, ocy2,ocz1,ocz2; /* clip with octree */ - if(branchcount==0) return 0; + if(R.oc.branchcount==0) return 0; /* do this before intersect calls */ is->vlrcontr= NULL; /* to check shared edge */ @@ -1150,14 +1151,14 @@ static int d3dda(Isect *is) u2= 1.0; /* clip with octree cube */ - if(cliptest(-ldx, is->start[0]-g_oc.min[0], &u1,&u2)) { - if(cliptest(ldx, g_oc.max[0]-is->start[0], &u1,&u2)) { + if(cliptest(-ldx, is->start[0]-R.oc.min[0], &u1,&u2)) { + if(cliptest(ldx, R.oc.max[0]-is->start[0], &u1,&u2)) { ldy= is->end[1] - is->start[1]; - if(cliptest(-ldy, is->start[1]-g_oc.min[1], &u1,&u2)) { - if(cliptest(ldy, g_oc.max[1]-is->start[1], &u1,&u2)) { + if(cliptest(-ldy, is->start[1]-R.oc.min[1], &u1,&u2)) { + if(cliptest(ldy, R.oc.max[1]-is->start[1], &u1,&u2)) { ldz= is->end[2] - is->start[2]; - if(cliptest(-ldz, is->start[2]-g_oc.min[2], &u1,&u2)) { - if(cliptest(ldz, g_oc.max[2]-is->start[2], &u1,&u2)) { + if(cliptest(-ldz, is->start[2]-R.oc.min[2], &u1,&u2)) { + if(cliptest(ldz, R.oc.max[2]-is->start[2], &u1,&u2)) { c1=1; if(u2<1.0) { is->end[0]= is->start[0]+u2*ldx; @@ -1179,15 +1180,15 @@ static int d3dda(Isect *is) if(c1==0) return 0; /* reset static variables in ocread */ - //ocread(g_oc.ocres, 0, 0); + //ocread(R.oc.ocres, 0, 0); /* setup 3dda to traverse octree */ - ox1= (is->start[0]-g_oc.min[0])*g_oc.ocfacx; - oy1= (is->start[1]-g_oc.min[1])*g_oc.ocfacy; - oz1= (is->start[2]-g_oc.min[2])*g_oc.ocfacz; - ox2= (is->end[0]-g_oc.min[0])*g_oc.ocfacx; - oy2= (is->end[1]-g_oc.min[1])*g_oc.ocfacy; - oz2= (is->end[2]-g_oc.min[2])*g_oc.ocfacz; + ox1= (is->start[0]-R.oc.min[0])*R.oc.ocfacx; + oy1= (is->start[1]-R.oc.min[1])*R.oc.ocfacy; + oz1= (is->start[2]-R.oc.min[2])*R.oc.ocfacz; + ox2= (is->end[0]-R.oc.min[0])*R.oc.ocfacx; + oy2= (is->end[1]-R.oc.min[1])*R.oc.ocfacy; + oz2= (is->end[2]-R.oc.min[2])*R.oc.ocfacz; ocx1= (int)ox1; ocy1= (int)oy1; @@ -1522,9 +1523,9 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen float ref[3]; VECCOPY(isec.start, start); - isec.end[0]= start[0]+g_oc.ocsize*vec[0]; - isec.end[1]= start[1]+g_oc.ocsize*vec[1]; - isec.end[2]= start[2]+g_oc.ocsize*vec[2]; + isec.end[0]= start[0]+R.oc.ocsize*vec[0]; + isec.end[1]= start[1]+R.oc.ocsize*vec[1]; + isec.end[2]= start[2]+R.oc.ocsize*vec[2]; isec.mode= DDA_MIRROR; isec.vlrorig= vlr; @@ -1623,7 +1624,7 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen VECCOPY(shi.view, vec); Normalise(shi.view); - shadeSkyPixelFloat(col, shi.view, NULL); + shadeSkyPixelFloat(col, NULL, shi.view, isec.start); } } @@ -1712,7 +1713,7 @@ void init_jitter_plane(LampRen *lar) } /* table around origin, -0.5*size to 0.5*size */ -static float *give_jitter_plane(LampRen *lar, int xs, int ys) +static float *give_jitter_plane(LampRen *lar, int thread, int xs, int ys) { int tot; @@ -1720,7 +1721,7 @@ static float *give_jitter_plane(LampRen *lar, int xs, int ys) if(lar->ray_samp_type & LA_SAMP_JITTER) { /* made it threadsafe */ - if(ys & 1) { + if(thread & 1) { if(lar->xold1!=xs || lar->yold1!=ys) { jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(1), BLI_thread_frand(1)); lar->xold1= xs; lar->yold1= ys; @@ -1886,9 +1887,9 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr) vec[2]-= vec[2]; } VECCOPY(isec.start, ship->co); - isec.end[0]= isec.start[0] + g_oc.ocsize*vec[0]; - isec.end[1]= isec.start[1] + g_oc.ocsize*vec[1]; - isec.end[2]= isec.start[2] + g_oc.ocsize*vec[2]; + isec.end[0]= isec.start[0] + R.oc.ocsize*vec[0]; + isec.end[1]= isec.start[1] + R.oc.ocsize*vec[1]; + isec.end[2]= isec.start[2] + R.oc.ocsize*vec[2]; if( d3dda(&isec)) { float fac; @@ -1976,13 +1977,13 @@ void init_ao_sphere(float *sphere, int tot, int iter) } -static float *threadsafe_table_sphere(int test, int xs, int ys) +static float *threadsafe_table_sphere(int test, int thread, int xs, int ys) { static float sphere1[2*3*256]; static float sphere2[2*3*256]; static int xs1=-1, xs2=-1, ys1=-1, ys2=-1; - if(ys & 1) { + if(thread & 1) { if(xs==xs1 && ys==ys1) return sphere1; if(test) return NULL; xs1= xs; ys1= ys; @@ -1996,7 +1997,7 @@ static float *threadsafe_table_sphere(int test, int xs, int ys) } } -static float *sphere_sampler(int type, int resol, int xs, int ys) +static float *sphere_sampler(int type, int resol, int thread, int xs, int ys) { int tot; float *vec; @@ -2023,14 +2024,14 @@ static float *sphere_sampler(int type, int resol, int xs, int ys) float ang, *vec1; int a; - sphere= threadsafe_table_sphere(1, xs, ys); // returns table if xs and ys were equal to last call + sphere= threadsafe_table_sphere(1, thread, xs, ys); // returns table if xs and ys were equal to last call if(sphere==NULL) { - sphere= threadsafe_table_sphere(0, xs, ys); + sphere= threadsafe_table_sphere(0, thread, xs, ys); // random rotation - ang= BLI_thread_frand(ys & 1); + ang= BLI_thread_frand(thread); sinfi= sin(ang); cosfi= cos(ang); - ang= BLI_thread_frand(ys & 1); + ang= BLI_thread_frand(thread); sint= sin(ang); cost= cos(ang); vec= R.wrld.aosphere; @@ -2047,11 +2048,11 @@ static float *sphere_sampler(int type, int resol, int xs, int ys) /* extern call from shade_lamp_loop, ambient occlusion calculus */ -void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) +void ray_ao(ShadeInput *shi, float *shadfac) { Isect isec; float *vec, *nrm, div, bias, sh=0; - float maxdist = wrld->aodist; + float maxdist = R.wrld.aodist; int j= -1, tot, actual=0, skyadded=0; isec.vlrorig= shi->vlr; @@ -2071,10 +2072,10 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) nrm= shi->facenor; } - vec= sphere_sampler(wrld->aomode, wrld->aosamp, floor(shi->xs+0.5), floor(shi->ys+0.5) ); + vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys); // warning: since we use full sphere now, and dotproduct is below, we do twice as much - tot= 2*wrld->aosamp*wrld->aosamp; + tot= 2*R.wrld.aosamp*R.wrld.aosamp; while(tot--) { @@ -2099,10 +2100,10 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) /* do the trace */ if (d3dda(&isec)) { - if (wrld->aomode & WO_AODIST) sh+= exp(-isec.labda*wrld->aodistfac); + if (R.wrld.aomode & WO_AODIST) sh+= exp(-isec.labda*R.wrld.aodistfac); else sh+= 1.0; } - else if(wrld->aocolor!=WO_AOPLAIN) { + else if(R.wrld.aocolor!=WO_AOPLAIN) { float skycol[4]; float fac, view[3]; @@ -2111,14 +2112,14 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) view[2]= -vec[2]; Normalise(view); - if(wrld->aocolor==WO_AOSKYCOL) { + if(R.wrld.aocolor==WO_AOSKYCOL) { fac= 0.5*(1.0+view[0]*R.grvec[0]+ view[1]*R.grvec[1]+ view[2]*R.grvec[2]); shadfac[0]+= (1.0-fac)*R.wrld.horr + fac*R.wrld.zenr; shadfac[1]+= (1.0-fac)*R.wrld.horg + fac*R.wrld.zeng; shadfac[2]+= (1.0-fac)*R.wrld.horb + fac*R.wrld.zenb; } else { - shadeSkyPixelFloat(skycol, view, NULL); + shadeSkyPixelFloat(skycol, NULL, view, isec.start); shadfac[0]+= skycol[0]; shadfac[1]+= skycol[1]; shadfac[2]+= skycol[2]; @@ -2133,7 +2134,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) if(actual==0) shadfac[3]= 1.0; else shadfac[3] = 1.0 - sh/((float)actual); - if(wrld->aocolor!=WO_AOPLAIN && skyadded) { + if(R.wrld.aocolor!=WO_AOPLAIN && skyadded) { div= shadfac[3]/((float)skyadded); shadfac[0]*= div; // average color times distances/hits formula @@ -2162,9 +2163,9 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) if(lar->type==LA_SUN || lar->type==LA_HEMI) { - lampco[0]= shi->co[0] - g_oc.ocsize*lar->vec[0]; - lampco[1]= shi->co[1] - g_oc.ocsize*lar->vec[1]; - lampco[2]= shi->co[2] - g_oc.ocsize*lar->vec[2]; + lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0]; + lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1]; + lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2]; } else { VECCOPY(lampco, lar->co); @@ -2202,7 +2203,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) else shadfac[3]= 1.0; // 1.0=full light fac= 0.0; - jitlamp= give_jitter_plane(lar, floor(shi->xs+0.5), floor(shi->ys+0.5)); + jitlamp= give_jitter_plane(lar, shi->thread, shi->xs, shi->ys); a= lar->ray_totsamp; @@ -2272,3 +2273,44 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) } +/* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */ +void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co) +{ + Isect isec; + float lampco[3]; + + /* setup isec */ + isec.mode= DDA_SHADOW_TRA; + + if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1; + + if(lar->type==LA_SUN || lar->type==LA_HEMI) { + lampco[0]= shi->co[0] - R.oc.ocsize*lar->vec[0]; + lampco[1]= shi->co[1] - R.oc.ocsize*lar->vec[1]; + lampco[2]= shi->co[2] - R.oc.ocsize*lar->vec[2]; + } + else { + VECCOPY(lampco, lar->co); + } + + isec.vlrorig= shi->vlr; + + /* set up isec vec */ + VECCOPY(isec.start, shi->co); + VECCOPY(isec.end, lampco); + + if( d3dda(&isec)) { + /* we got a face */ + + /* render co */ + co[0]= isec.start[0]+isec.labda*(isec.vec[0]); + co[1]= isec.start[1]+isec.labda*(isec.vec[1]); + co[2]= isec.start[2]+isec.labda*(isec.vec[2]); + + *distfac= VecLength(isec.vec); + } + else + *distfac= 0.0f; +} + + diff --git a/source/blender/render/intern/source/renderHelp.c b/source/blender/render/intern/source/renderHelp.c deleted file mode 100644 index aa966268aca..00000000000 --- a/source/blender/render/intern/source/renderHelp.c +++ /dev/null @@ -1,306 +0,0 @@ -/** - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Some helpful conversions/functions. - * - * $Id$ - */ - -#include -#include -#include - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "BKE_utildefines.h" -#include "BLI_arithb.h" - -#include "render.h" -#include "renderHelp.h" -#include "zbuf.h" - -static float panovco, panovsi; -static float panophi=0.0; -static float tempPanoPhi; - -static int panotestclip(float *v); - -void pushTempPanoPhi(float p) { - tempPanoPhi = panophi; - panophi = p; -} - -void popTempPanoPhi() { - panophi = tempPanoPhi; -} - -float getPanoPhi(){ - return panophi; -} -float getPanovCo(){ - return panovco; -} -float getPanovSi(){ - return panovsi; -} - -void setPanoRot(int part) -{ -/* extern float panovco, panovsi; */ - static float alpha= 1.0; - - /* part==0 init all */ - - if(part==0) { - - alpha= ((float)R.r.xsch)/R.viewfac; - alpha= 2.0*atan(alpha/2.0); - } - - - /* rotate it all around the y-as with phi degrees */ - - panophi= -0.5*(R.r.xparts-1)*alpha + part*alpha; - - panovsi= sin(-panophi); - panovco= cos(-panophi); - -} - - - - -static int panotestclip(float *v) -{ - /* to be used for halos en infos */ - float abs4; - short c=0; - - if((R.r.mode & R_PANORAMA)==0) return RE_testclip(v); - - abs4= fabs(v[3]); - - if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */ - else if(v[2]> abs4) c+= 32; - - if( v[1]>abs4) c+=4; - else if( v[1]< -abs4) c+=8; - - abs4*= R.r.xparts; - if( v[0]>abs4) c+=2; - else if( v[0]< -abs4) c+=1; - - return c; -} - -/* - - This adds the hcs coordinates to vertices. It iterates over all - vertices, halos and faces. After the conversion, we clip in hcs. - - Elsewhere, all primites are converted to vertices. - Called in - - envmapping (envmap.c) - - shadow buffering (shadbuf.c) - - preparation for rendering (renderPreAndPost.c) - -*/ - -/* move to renderer */ -void setzbufvlaggen( void (*projectfunc)(float *, float *) ) -/* homocos too */ -{ - VlakRen *vlr = NULL; - VertRen *ver = NULL; - HaloRen *har = NULL; - float zn, vec[3], si, co, hoco[4]; - int a; - float panophi = 0.0; - - panophi = getPanoPhi(); - si= sin(panophi); - co= cos(panophi); - - /* calculate view coordinates (and zbuffer value) */ - for(a=0; a< R.totvert;a++) { - if((a & 255)==0) ver= R.blove[a>>8]; - else ver++; - - if(R.r.mode & R_PANORAMA) { - vec[0]= co*ver->co[0] + si*ver->co[2]; - vec[1]= ver->co[1]; - vec[2]= -si*ver->co[0] + co*ver->co[2]; - } - else { - VECCOPY(vec, ver->co); - } - /* Go from wcs to hcs ... */ - projectfunc(vec, ver->ho); - /* ... and clip in that system. */ - ver->clip = RE_testclip(ver->ho); - /* - Because all other ops are performed in other systems, this is - the only thing that has to be done. - */ - } - - /* calculate view coordinates (and zbuffer value) */ - for(a=0; a>8]; - else har++; - - if(R.r.mode & R_PANORAMA) { - vec[0]= co*har->co[0] + si*har->co[2]; - vec[1]= har->co[1]; - vec[2]= -si*har->co[0] + co*har->co[2]; - } - else { - VECCOPY(vec, har->co); - } - - projectfunc(vec, hoco); - - /* we clip halos less critical, but not for the Z */ - hoco[0]*= 0.5; - hoco[1]*= 0.5; - - if( panotestclip(hoco) ) { - har->miny= har->maxy= -10000; /* that way render clips it */ - } - else if(hoco[3]<0.0) { - har->miny= har->maxy= -10000; /* render clips it */ - } - else /* do the projection...*/ - { - /* bring back hocos */ - hoco[0]*= 2.0; - hoco[1]*= 2.0; - - zn= hoco[3]; - har->xs= 0.5*R.rectx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ - har->ys= 0.5*R.recty*(1.0+hoco[1]/zn); - - /* this should be the zbuffer coordinate */ - har->zs= 0x7FFFFF*(hoco[2]/zn); - /* taking this from the face clip functions? seems ok... */ - har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); - - vec[0]+= har->hasize; - projectfunc(vec, hoco); - vec[0]-= har->hasize; - zn= hoco[3]; - har->rad= fabs(har->xs- 0.5*R.rectx*(1.0+hoco[0]/zn)); - - /* this clip is not really OK, to prevent stars to become too large */ - if(har->type & HA_ONLYSKY) { - if(har->rad>3.0) har->rad= 3.0; - } - - har->radsq= har->rad*har->rad; - - har->miny= har->ys - har->rad/R.ycor; - har->maxy= har->ys + har->rad/R.ycor; - - /* the Zd value is still not really correct for pano */ - - vec[2]-= har->hasize; /* z negative, otherwise it's clipped */ - projectfunc(vec, hoco); - zn= hoco[3]; - zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn)); - har->zd= CLAMPIS(zn, 0, INT_MAX); - - } - - } - - /* set flags at 0 if clipped away */ - for(a=0; a>8]; - else vlr++; - - vlr->flag |= R_VISIBLE; - if(vlr->v4) { - if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE; - } - else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE; - - } - -} - -/* ------------------------------------------------------------------------- */ -/* move to renderer */ - -void set_normalflags(void) -{ - VlakRen *vlr = NULL; - float *v1, xn, yn, zn; - int a1, doflip; - - /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */ - for(a1=0; a1>8]; - else vlr++; - - /* abuse of this flag... this is code that just sets face normal in direction of camera */ - /* that convention we should get rid of */ - if((vlr->flag & R_NOPUNOFLIP)==0) { - - doflip= 0; - if(R.r.mode & R_ORTHO) { - if(vlr->n[2]>0.0) doflip= 1; - } - else { - v1= vlr->v1->co; - if( (v1[0]*vlr->n[0] +v1[1]*vlr->n[1] +v1[2]*vlr->n[2])<0.0 ) doflip= 1; - } - if(doflip) { - vlr->n[0]= -vlr->n[0]; - vlr->n[1]= -vlr->n[1]; - vlr->n[2]= -vlr->n[2]; - } - } - - /* recalculate puno. Displace & flipped matrices can screw up */ - vlr->puno= 0; - if(!(vlr->flag & R_TANGENT)) { - if( Inpf(vlr->n, vlr->v1->n) < 0.0 ) vlr->puno |= ME_FLIPV1; - if( Inpf(vlr->n, vlr->v2->n) < 0.0 ) vlr->puno |= ME_FLIPV2; - if( Inpf(vlr->n, vlr->v3->n) < 0.0 ) vlr->puno |= ME_FLIPV3; - if(vlr->v4 && Inpf(vlr->n, vlr->v4->n) < 0.0 ) vlr->puno |= ME_FLIPV4; - } - xn= fabs(vlr->n[0]); - yn= fabs(vlr->n[1]); - zn= fabs(vlr->n[2]); - if(zn>=xn && zn>=yn) vlr->snproj= 0; - else if(yn>=xn && yn>=zn) vlr->snproj= 1; - else vlr->snproj= 2; - - } -} diff --git a/source/blender/render/intern/source/renderPreAndPost.c b/source/blender/render/intern/source/renderPreAndPost.c deleted file mode 100644 index defb6b97ff6..00000000000 --- a/source/blender/render/intern/source/renderPreAndPost.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Prepare the scene data for rendering. - * - * $Id$ - */ - -#include "MEM_guardedalloc.h" - -#include "render.h" -#include "renderPreAndPost.h" -#include "RE_callbacks.h" - -#include "shadbuf.h" -#include "envmap.h" -#include "renderHelp.h" -#include "radio.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/** - * Rotate all objects, make shadowbuffers and environment maps. - */ -void prepareScene() -{ - int a; - extern void makeoctree(void); - - RE_local_get_renderdata(); - - /* SHADOW BUFFER */ - for(a=0; ashb) makeshadowbuf(R.la[a]); - } - - /* yafray: 'direct' radiosity, environment maps and octree init not needed for yafray render */ - /* although radio mode could be useful at some point, later */ - if (R.r.renderer==R_INTERN) { - - /* RADIO */ - if(R.r.mode & R_RADIO) do_radio_render(); - - /* octree */ - if(R.r.mode & R_RAYTRACE) makeoctree(); - - /* ENVIRONMENT MAPS */ - make_envmaps(); - - } -} - -void finalizeScene(void) -{ - extern void freeoctree(void); - - /* Among other things, it releases the shadow buffers. */ - RE_local_free_renderdata(); - /* yafray: freeoctree not needed after yafray render, not initialized, see above */ - if (R.r.renderer==R_INTERN) { - if(R.r.mode & R_RAYTRACE) freeoctree(); - } -} - - -void doClipping( void (*projectfunc)(float *, float *) ) -{ - setzbufvlaggen(projectfunc); -} - -/* eof */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 92b26a59981..87c1330d5ef 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,11 +20,10 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * Contributors: Hos, Robert Wenzlaff. + * Contributors: 2004/2005/2006 Blender Foundation, full recode * - * Contributor(s): Hos, Robert Wenzlaff. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ /* system includes */ @@ -36,83 +32,125 @@ #include /* External modules: */ -#include "MEM_guardedalloc.h" -#include "BLI_arithb.h" #include "MTC_matrixops.h" +#include "BLI_arithb.h" +#include "BLI_blenlib.h" +#include "BLI_rand.h" +#include "BLI_jitter.h" #include "BKE_utildefines.h" +#include "DNA_group_types.h" +#include "DNA_image_types.h" +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_image_types.h" #include "DNA_object_types.h" -#include "DNA_camera_types.h" -#include "DNA_lamp_types.h" #include "DNA_texture_types.h" #include "BKE_global.h" +#include "BKE_material.h" +#include "BKE_node.h" #include "BKE_texture.h" -#include "BLI_rand.h" - /* local include */ -#include "RE_callbacks.h" -#include "render.h" -#include "zbuf.h" /* stuff like bgnaccumbuf, fillrect, ...*/ +#include "renderpipeline.h" +#include "render_types.h" +#include "renderdatabase.h" #include "pixelblending.h" #include "pixelshading.h" -#include "vanillaRenderPipe.h" /* transfercolour... */ #include "gammaCorrectionTables.h" #include "shadbuf.h" -#include "renderHelp.h" +#include "zbuf.h" -#include "jitter.h" #include "texture.h" /* own include */ #include "rendercore.h" -#ifdef HAVE_CONFIG_H -#include -#endif -#include "SDL_thread.h" +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -/* global for this file. struct render will be more dynamic later, to allow multiple renderers */ -RE_Render R; - -float bluroffsx=0.0, bluroffsy=0.0; // set in initrender.c (bad, ton) - -/* x and y are current pixels to be rendered */ +/* x and y are current pixels in rect to be rendered */ +/* do not normalize! */ void calc_view_vector(float *view, float x, float y) { - + if(R.r.mode & R_ORTHO) { view[0]= view[1]= 0.0; } else { - view[0]= (x+(R.xstart)+bluroffsx +0.5); + /* move x and y to real viewplane coords */ + x= (x/(float)R.winx); + view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin); - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; - else view[1]= (y+R.ystart+1.0)*R.ycor; - } - else view[1]= (y+R.ystart+bluroffsy+0.5)*R.ycor; - } - view[2]= -R.viewfac; + y= (y/(float)R.winy); + view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin); + +// if(R.flag & R_SEC_FIELD) { +// if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; +// else view[1]= (y+R.ystart+1.0)*R.ycor; +// } +// else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor; + } + + view[2]= -R.clipsta; if(R.r.mode & R_PANORAMA) { - float panoco, panosi, u, v; - panoco = getPanovCo(); - panosi = getPanovSi(); - - u= view[0]; v= view[2]; - view[0]= panoco*u + panosi*v; - view[2]= -panosi*u + panoco*v; + float u= view[0]; float v= view[2]; + view[0]= R.panoco*u + R.panosi*v; + view[2]= -R.panosi*u + R.panoco*v; } + } +#if 0 +static void fogcolor(float *colf, float *rco, float *view) +{ + float alpha, stepsize, startdist, dist, hor[4], zen[3], vec[3], dview[3]; + float div=0.0f, distfac; + + hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb; + zen[0]= R.wrld.zenr; zen[1]= R.wrld.zeng; zen[2]= R.wrld.zenb; + + VECCOPY(vec, rco); + + /* we loop from cur coord to mist start in steps */ + stepsize= 1.0f; + + div= ABS(view[2]); + dview[0]= view[0]/(stepsize*div); + dview[1]= view[1]/(stepsize*div); + dview[2]= -stepsize; + + startdist= -rco[2] + BLI_frand(); + for(dist= startdist; dist>R.wrld.miststa; dist-= stepsize) { + + hor[0]= R.wrld.horr; hor[1]= R.wrld.horg; hor[2]= R.wrld.horb; + alpha= 1.0f; + do_sky_tex(vec, vec, NULL, hor, zen, &alpha); + + distfac= (dist-R.wrld.miststa)/R.wrld.mistdist; + + hor[3]= hor[0]*distfac*distfac; + + /* premul! */ + alpha= hor[3]; + hor[0]= hor[0]*alpha; + hor[1]= hor[1]*alpha; + hor[2]= hor[2]*alpha; + addAlphaOverFloat(colf, hor); + + VECSUB(vec, vec, dview); + } +} +#endif + float mistfactor(float zcor, float *co) /* dist en height, return alpha */ { float fac, hi; @@ -150,32 +188,6 @@ float mistfactor(float zcor, float *co) /* dist en height, return alpha */ return (1.0-fac)* (1.0-R.wrld.misi); } -/* external for preview only */ -void RE_sky_char(float *view, char *col) -{ - float f, colf[3]; - float dither_value; - - dither_value = ( (BLI_frand()-0.5)*R.r.dither_intensity)/256.0; - - shadeSkyPixelFloat(colf, view, NULL); - - f= 255.0*(colf[0]+dither_value); - if(f<=0.0) col[0]= 0; else if(f>255.0) col[0]= 255; - else col[0]= (char)f; - f= 255.0*(colf[1]+dither_value); - if(f<=0.0) col[1]= 0; else if(f>255.0) col[1]= 255; - else col[1]= (char)f; - f= 255.0*(colf[2]+dither_value); - if(f<=0.0) col[2]= 0; else if(f>255.0) col[2]= 255; - else col[2]= (char)f; - col[3]= 1; /* to prevent wrong optimalisation alphaover of flares */ -} - - -/* ************************************** */ - - static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) { double a, b, c, disc, nray[3], npos[3]; @@ -364,14 +376,15 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens) static void renderspothalo(ShadeInput *shi, float *col, float alpha) { + GroupObject *go; LampRen *lar; float i; - int a; if(alpha==0.0f) return; - for(a=0; anext) { + lar= go->lampren; + if(lar->type==LA_SPOT && (lar->mode & LA_HALO) && lar->haint>0) { spothalo(lar, shi, &i); @@ -388,9 +401,18 @@ static void renderspothalo(ShadeInput *shi, float *col, float alpha) } + +/* also used in zbuf.c */ +int count_mask(unsigned short mask) +{ + if(R.samples) + return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]); + return 0; +} + static int calchalo_z(HaloRen *har, int zz) { - + if(har->type & HA_ONLYSKY) { if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF; } @@ -400,186 +422,120 @@ static int calchalo_z(HaloRen *har, int zz) return zz; } -static void scanlinehaloPS(int *rectz, long *rectdelta, float *rowbuf, short ys) +static void halo_pixelstruct(HaloRen *har, float *rb, float dist, float xn, float yn, PixStr *ps) +{ + float col[4], accol[4]; + int amount, amountm, zz, flarec; + + amount= 0; + accol[0]=accol[1]=accol[2]=accol[3]= 0.0; + flarec= har->flarec; + + while(ps) { + amountm= count_mask(ps->mask); + amount+= amountm; + + zz= calchalo_z(har, ps->z); + if(zz> har->zs) { + float fac; + + shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); + fac= ((float)amountm)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; + flarec= 0; + } + + ps= ps->next; + } + /* now do the sky sub-pixels */ + amount= R.osa-amount; + if(amount) { + float fac; + + shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec); + fac= ((float)amount)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; + } + col[0]= accol[0]; + col[1]= accol[1]; + col[2]= accol[2]; + col[3]= accol[3]; + + addalphaAddfacFloat(rb, col, har->add); + +} + +static void halo_tile(RenderPart *pa, float *pass, unsigned int lay) { HaloRen *har = NULL; - PixStr *ps; - float dist, xsq, ysq, xn, yn; - float *rb; - float col[4], accol[4]; - int a, *rz, zz, didgamma=0; - long *rd; - short minx, maxx, x, amount, amountm, flarec; + rcti disprect= pa->disprect; + float dist, xsq, ysq, xn, yn, *rb; + float col[4]; + long *rd= NULL; + int a, *rz, zz, y; + short minx, maxx, miny, maxy, x; for(a=0; a>8]; - if( RE_local_test_break() ) break; } else har++; - if(ys>har->maxy); - else if(ysminy); + /* layer test, clip halo with y */ + if((har->lay & lay)==0); + else if(disprect.ymin > har->maxy); + else if(disprect.ymax < har->miny); else { + minx= floor(har->xs-har->rad); maxx= ceil(har->xs+har->rad); - if(maxx<0); - else if(R.rectx maxx); + else if(disprect.xmax < minx); else { - if(minx<0) minx= 0; - if(maxx>=R.rectx) maxx= R.rectx-1; - - rb= rowbuf + 4*minx; - rd= rectdelta + minx; - rz= rectz + minx; - - yn= (ys-har->ys)*R.ycor; - ysq= yn*yn; - for(x=minx; x<=maxx; x++) { - - xn= x-har->xs; - xsq= xn*xn; - dist= xsq+ysq; - - if(distradsq) { - - /* well yah, halo adding shouldnt be done gamma corrected, have to bypass it this way */ - /* alternative is moving it outside of thread renderlineDA */ - /* on positive side; the invert correct cancels out correcting halo color */ - if(do_gamma && didgamma==0) { - float *buf= rowbuf; - int xt; - for(xt=0; xtflarec; /* har->pixels is only allowed to count once */ - - if(*rd) { /* theres a pixel struct */ - - ps= (PixStr *)(*rd); - amount= 0; - accol[0]=accol[1]=accol[2]=accol[3]= 0.0; - - while(ps) { - amountm= count_mask(ps->mask); - amount+= amountm; - - zz= calchalo_z(har, ps->z); - if(zz> har->zs) { - float fac; - - shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); - fac= ((float)amountm)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; - flarec= 0; - } - - ps= ps->next; - } - /* now do the sky sub-pixels */ - amount= R.osa-amount; - if(amount) { - float fac; - - shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec); - fac= ((float)amount)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; - } - col[0]= accol[0]; - col[1]= accol[1]; - col[2]= accol[2]; - col[3]= accol[3]; - - addalphaAddfacFloat(rb, col, har->add); - } - else { - zz= calchalo_z(har, *rz); - if(zz> har->zs) { - - shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); - addalphaAddfacFloat(rb, col, har->add); - } - } - } - rb+=4; - rz++; - rd++; - } - } - } - } - - /* the entire scanline has to be put back in gammaspace */ - if(didgamma) { - float *buf= rowbuf; - int xt; - for(xt=0; xt>8]; - else har++; - - if(RE_local_test_break() ) break; - - if(ys>har->maxy); - else if(ysminy); - else { - minx= floor(har->xs-har->rad); - maxx= ceil(har->xs+har->rad); - - if(maxx<0); - else if(R.rectx=R.rectx) maxx= R.rectx-1; - - rb= rowbuf + 4*minx; - rz= rectz + minx; - - yn= (ys-har->ys)*R.ycor; - ysq= yn*yn; - for(x=minx; x<=maxx; x++) { - zz= calchalo_z(har, *rz); - if(zz> har->zs) { + minx= MAX2(minx, disprect.xmin); + maxx= MIN2(maxx, disprect.xmax); + + miny= MAX2(har->miny, disprect.ymin); + maxy= MIN2(har->maxy, disprect.ymax); + + for(y=miny; yrectx + (minx - disprect.xmin); + rb= pass + 4*rectofs; + rz= pa->rectz + rectofs; + + if(pa->rectdaps) + rd= pa->rectdaps + rectofs; + + yn= (y-har->ys)*R.ycor; + ysq= yn*yn; + + for(x=minx; xxs; xsq= xn*xn; dist= xsq+ysq; if(distradsq) { - shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec); - addalphaAddfacFloat(rb, col, har->add); + if(rd && *rd) { + halo_pixelstruct(har, rb, dist, xn, yn, (PixStr *)*rd); + } + else { + zz= calchalo_z(har, *rz); + if(zz> har->zs) { + shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec); + addalphaAddfacFloat(rb, col, har->add); + } + } } + if(rd) rd++; } - - rb+=4; - rz++; } } } @@ -607,6 +563,23 @@ static double Normalise_d(double *n) return d; } +/* mix of 'real' fresnel and allowing control. grad defines blending gradient */ +float fresnel_fac(float *view, float *vn, float grad, float fac) +{ + float t1, t2; + + if(fac==0.0) return 1.0; + + t1= (view[0]*vn[0] + view[1]*vn[1] + view[2]*vn[2]); + if(t1>0.0) t2= 1.0+t1; + else t2= 1.0-t1; + + t2= grad + (1.0-grad)*pow(t2, fac); + + if(t2<0.0) return 0.0; + else if(t2>1.0) return 1.0; + return t2; +} static double saacos_d(double fac) { @@ -665,7 +638,7 @@ static float area_lamp_energy(float *co, float *vn, LampRen *lar) return pow(fac*lar->areasize, lar->k); // corrected for buttons size and lar->dist^2 } -float spec(float inp, int hard) +static float spec(float inp, int hard) { float b1; @@ -705,7 +678,7 @@ float spec(float inp, int hard) return inp; } -float Phong_Spec( float *n, float *l, float *v, int hard, int tangent ) +static float Phong_Spec( float *n, float *l, float *v, int hard, int tangent ) { float h[3]; float rslt; @@ -726,7 +699,7 @@ float Phong_Spec( float *n, float *l, float *v, int hard, int tangent ) /* reduced cook torrance spec (for off-specular peak) */ -float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent) +static float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent) { float i, nh, nv, h[3]; @@ -750,7 +723,7 @@ float CookTorr_Spec(float *n, float *l, float *v, int hard, int tangent) } /* Blinn spec */ -float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent) +static float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, int tangent) { float i, nh, nv, nl, vh, h[3]; float a, b, c, g=0.0, p, f, ang; @@ -804,7 +777,7 @@ float Blinn_Spec(float *n, float *l, float *v, float refrac, float spec_power, i } /* cartoon render spec */ -float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent) +static float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tangent) { float h[3]; float ang; @@ -828,7 +801,7 @@ float Toon_Spec( float *n, float *l, float *v, float size, float smooth, int tan } /* Ward isotropic gaussian spec */ -float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) +static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) { float i, nh, nv, nl, h[3], angle, alpha; @@ -854,13 +827,13 @@ float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) angle = tan(saacos(nh)); alpha = MAX2(rms,0.001); - i= nl * (1.0/(4*PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl))); + i= nl * (1.0/(4*M_PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl))); return i; } /* cartoon render diffuse */ -float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) +static float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) { float rslt, ang; @@ -879,7 +852,7 @@ float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) /* 'nl' is either dot product, or return value of area light */ /* in latter case, only last multiplication uses 'nl' */ -static float OrenNayar_Diff_i(float nl, float *n, float *l, float *v, float rough ) +static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough ) { float i, nh, nv, vh, realnl, h[3]; float a, b, t, A, B; @@ -938,15 +911,8 @@ static float OrenNayar_Diff_i(float nl, float *n, float *l, float *v, float roug return i; } -/* Oren Nayar diffuse */ -float OrenNayar_Diff(float *n, float *l, float *v, float rough ) -{ - float nl= n[0]*l[0] + n[1]*l[1] + n[2]*l[2]; - return OrenNayar_Diff_i(nl, n, l, v, rough); -} - /* Minnaert diffuse */ -float Minnaert_Diff(float nl, float *n, float *v, float darkness) +static float Minnaert_Diff(float nl, float *n, float *v, float darkness) { float i, nv; @@ -968,6 +934,11 @@ float Minnaert_Diff(float nl, float *n, float *v, float darkness) return i; } +static float Fresnel_Diff(float *vn, float *lv, float *view, float fac_i, float fac) +{ + return fresnel_fac(lv, vn, fac_i, fac); +} + /* --------------------------------------------- */ /* also called from texture.c */ void calc_R_ref(ShadeInput *shi) @@ -1017,24 +988,7 @@ void calc_R_ref(ShadeInput *shi) } -/* mix of 'real' fresnel and allowing control. grad defines blending gradient */ -float fresnel_fac(float *view, float *vn, float grad, float fac) -{ - float t1, t2; - - if(fac==0.0) return 1.0; - - t1= (view[0]*vn[0] + view[1]*vn[1] + view[2]*vn[2]); - if(t1>0.0) t2= 1.0+t1; - else t2= 1.0-t1; - - t2= grad + (1.0-grad)*pow(t2, fac); - - if(t2<0.0) return 0.0; - else if(t2>1.0) return 1.0; - return t2; -} - +/* called from ray.c */ void shade_color(ShadeInput *shi, ShadeResult *shr) { Material *ma= shi->mat; @@ -1065,72 +1019,8 @@ void shade_color(ShadeInput *shi, ShadeResult *shr) shr->alpha= shi->alpha; } -/* r g b = 1 value, col = vector */ -static void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) -{ - float tmp, facm= 1.0-fac; - - switch (type) { - case MA_RAMP_BLEND: - *r = facm*(*r) + fac*col[0]; - *g = facm*(*g) + fac*col[1]; - *b = facm*(*b) + fac*col[2]; - break; - case MA_RAMP_ADD: - *r += fac*col[0]; - *g += fac*col[1]; - *b += fac*col[2]; - break; - case MA_RAMP_MULT: - *r *= (facm + fac*col[0]); - *g *= (facm + fac*col[1]); - *b *= (facm + fac*col[2]); - break; - case MA_RAMP_SCREEN: - *r = 1.0-(facm + (1.0 - col[0]))*(1.0 - *r); - *g = 1.0-(facm + (1.0 - col[1]))*(1.0 - *g); - *b = 1.0-(facm + (1.0 - col[2]))*(1.0 - *b); - break; - case MA_RAMP_SUB: - *r -= fac*col[0]; - *g -= fac*col[1]; - *b -= fac*col[2]; - break; - case MA_RAMP_DIV: - if(col[0]!=0.0) - *r = facm*(*r) + fac*(*r)/col[0]; - if(col[1]!=0.0) - *g = facm*(*g) + fac*(*g)/col[1]; - if(col[2]!=0.0) - *b = facm*(*b) + fac*(*b)/col[2]; - break; - case MA_RAMP_DIFF: - *r = facm*(*r) + fac*fabs(*r-col[0]); - *g = facm*(*g) + fac*fabs(*g-col[1]); - *b = facm*(*b) + fac*fabs(*b-col[2]); - break; - case MA_RAMP_DARK: - tmp= fac*col[0]; - if(tmp < *r) *r= tmp; - tmp= fac*col[1]; - if(tmp < *g) *g= tmp; - tmp= fac*col[2]; - if(tmp < *b) *b= tmp; - break; - case MA_RAMP_LIGHT: - tmp= fac*col[0]; - if(tmp > *r) *r= tmp; - tmp= fac*col[1]; - if(tmp > *g) *g= tmp; - tmp= fac*col[2]; - if(tmp > *b) *b= tmp; - break; - } - -} - /* ramp for at end of shade */ -void ramp_diffuse_result(float *diff, ShadeInput *shi) +static void ramp_diffuse_result(float *diff, ShadeInput *shi) { Material *ma= shi->mat; float col[4], fac=0; @@ -1150,7 +1040,7 @@ void ramp_diffuse_result(float *diff, ShadeInput *shi) } /* r,g,b denote energy, ramp is used with different values to make new material color */ -void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b) +static void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b) { Material *ma= shi->mat; float col[4], colt[3], fac=0; @@ -1199,7 +1089,7 @@ void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, fl } } -void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) +static void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) { Material *ma= shi->mat; float col[4]; @@ -1218,7 +1108,7 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi) } /* is = dot product shade, t = spec energy */ -void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) +static void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) { Material *ma= shi->mat; float col[4]; @@ -1255,32 +1145,32 @@ void do_specular_ramp(ShadeInput *shi, float is, float t, float *spec) -static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) +static void ambient_occlusion(ShadeInput *shi, ShadeResult *shr) { float f, shadfac[4]; - if((wrld->mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) { - ray_ao(shi, wrld, shadfac); + if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) { + ray_ao(shi, shadfac); - if(wrld->aocolor==WO_AOPLAIN) { - if (wrld->aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0; - else if (wrld->aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0; + if(R.wrld.aocolor==WO_AOPLAIN) { + if (R.wrld.aomix==WO_AOADDSUB) shadfac[3] = 2.0*shadfac[3]-1.0; + else if (R.wrld.aomix==WO_AOSUB) shadfac[3] = shadfac[3]-1.0; - f= wrld->aoenergy*shadfac[3]*shi->amb; + f= R.wrld.aoenergy*shadfac[3]*shi->amb; add_to_diffuse(shr->diff, shi, f, f, f, f); } else { - if (wrld->aomix==WO_AOADDSUB) { + if (R.wrld.aomix==WO_AOADDSUB) { shadfac[0] = 2.0*shadfac[0]-1.0; shadfac[1] = 2.0*shadfac[1]-1.0; shadfac[2] = 2.0*shadfac[2]-1.0; } - else if (wrld->aomix==WO_AOSUB) { + else if (R.wrld.aomix==WO_AOSUB) { shadfac[0] = shadfac[0]-1.0; shadfac[1] = shadfac[1]-1.0; shadfac[2] = shadfac[2]-1.0; } - f= wrld->aoenergy*shi->amb; + f= R.wrld.aoenergy*shi->amb; add_to_diffuse(shr->diff, shi, f, f*shadfac[0], f*shadfac[1], f*shadfac[2]); } } @@ -1289,17 +1179,26 @@ static void ambient_occlusion(World *wrld, ShadeInput *shi, ShadeResult *shr) void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) { LampRen *lar; + GroupObject *go; Material *ma= shi->mat; VlakRen *vlr= shi->vlr; + ListBase *lights; float i, inp, inpr, is, t, lv[3], vnor[3], lacol[3], lampdist, ld = 0; float lvrot[3], *vn, *view, shadfac[4], soft, phongcorr; // shadfac = rgba - int a; vn= shi->vn; view= shi->view; memset(shr, 0, sizeof(ShadeResult)); + if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0; + + /* lights */ + if(ma->group) + lights= &ma->group->gobject; + else + lights= &R.lights; + /* separate loop */ if(ma->mode & MA_ONLYSHADOW) { float ir; @@ -1307,8 +1206,10 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(R.r.mode & R_SHADOW) { shadfac[3]= ir= 0.0; - for(a=0; afirst; go; go= go->next) { + lar= go->lampren; + if(lar==NULL) continue; + /* yafray: ignore shading by photonlights, not used in Blender */ if (lar->type==LA_YF_PHOTON) continue; @@ -1372,7 +1273,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if((R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) && shi->amb!=0.0) { float f; - ray_ao(shi, &R.wrld, shadfac); // shadfac==0: full light + ray_ao(shi, shadfac); // shadfac==0: full light shadfac[3]= 1.0-shadfac[3]; f= R.wrld.aoenergy*shadfac[3]*shi->amb; @@ -1432,10 +1333,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) shr->diff[2]= shi->b*shi->emit; } - ambient_occlusion(&R.wrld, shi, shr); + ambient_occlusion(shi, shr); - for(a=0; afirst; go; go= go->next) { + lar= go->lampren; + if(lar==NULL) continue; + /* yafray: ignore shading by photonlights, not used in Blender */ if (lar->type==LA_YF_PHOTON) continue; @@ -1552,7 +1455,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(vlr->flag & R_TANGENT) { float cross[3]; Crossf(cross, lv, vn); - Crossf(vnor, cross, shi->vn); + Crossf(vnor, cross, vn); + vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; + vn= vnor; + } + else if(ma->mode & MA_TANGENT_V) { + float cross[3]; + Crossf(cross, lv, shi->tang); + Crossf(vnor, cross, shi->tang); vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; vn= vnor; } @@ -1567,6 +1477,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) else phongcorr= 0.0; } + else if(ma->sbias!=0.0f) { + if(inp>ma->sbias) + phongcorr= (inp-ma->sbias)/(inp*(1.0-ma->sbias)); + else + phongcorr= 0.0; + } else phongcorr= 1.0; /* diffuse shaders */ @@ -1587,9 +1503,10 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } /* diffuse shaders (oren nayer gets inp from area light) */ - if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff_i(inp, vn, lv, view, ma->roughness); + if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(inp, vn, lv, view, ma->roughness); else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]); else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness); + else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]); else is= inp; // Lambert } @@ -1600,7 +1517,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } vn= shi->vn; // bring back original vector, we use special specular shaders for tangent - + if(ma->mode & MA_TANGENT_V) + vn= shi->tang; + /* shadow and spec, (lampdist==0 outside spot) */ if(lampdist> 0.0) { @@ -1632,6 +1551,22 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } } } +#if 0 + if(R.r.mode & R_RAYTRACE) { + extern void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co); + float co[3], distfac; + + ray_translucent(shi, lar, &distfac, co); + + if(distfac<0.01f*G.rt) { + // printf("distfac %f\n", distfac); + distfac= 1.0f - distfac/(0.01f*G.rt); + shr->diff[0]+= distfac; + shr->diff[1]+= distfac; + shr->diff[2]+= distfac; + } + } +#endif /* specularity */ if(shadfac[3]>0.0 && shi->spec!=0.0 && !(lar->mode & LA_NO_SPEC)) { @@ -1661,15 +1596,15 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) float specfac; if(ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(vn, lv, view, shi->har, vlr->flag & R_TANGENT); + specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(vn, lv, view, shi->har, vlr->flag & R_TANGENT); + specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, vlr->flag & R_TANGENT); + specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec( vn, lv, view, ma->rms, vlr->flag & R_TANGENT); + specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else - specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], vlr->flag & R_TANGENT); + specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); /* area lamp correction */ if(lar->type==LA_AREA) specfac*= inp; @@ -1718,21 +1653,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) shr->alpha= shi->alpha; - if(shr->spec[0]<0.0) shr->spec[0]= 0.0; - if(shr->spec[1]<0.0) shr->spec[1]= 0.0; - if(shr->spec[2]<0.0) shr->spec[2]= 0.0; - shr->diff[0]+= shi->r*shi->amb*shi->rad[0]; shr->diff[0]+= shi->ambr; - if(shr->diff[0]<0.0) shr->diff[0]= 0.0; shr->diff[1]+= shi->g*shi->amb*shi->rad[1]; shr->diff[1]+= shi->ambg; - if(shr->diff[1]<0.0) shr->diff[1]= 0.0; shr->diff[2]+= shi->b*shi->amb*shi->rad[2]; shr->diff[2]+= shi->ambb; - if(shr->diff[2]<0.0) shr->diff[2]= 0.0; if(ma->mode & MA_RAMP_COL) ramp_diffuse_result(shr->diff, shi); if(ma->mode & MA_RAMP_SPEC) ramp_spec_result(shr->spec, shr->spec+1, shr->spec+2, shi); @@ -1754,7 +1682,7 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i VlakRen *vlr= shi->vlr; float l, dl; short texco= shi->mat->texco; - int mode= shi->mat->mode; + int mode= shi->mat->mode_l; /* or-ed result for all layers */ char p1, p2, p3; /* for rendering of quads, the following values are used to denote vertices: @@ -1906,9 +1834,25 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->dyno[2]= dl*n3[2]-shi->dyuv[0]*n1[2]-shi->dyuv[1]*n2[2]; } + + if(mode & MA_TANGENT_V) { + float *s1, *s2, *s3; + + s1= RE_vertren_get_tangent(&R, v1, 0); + s2= RE_vertren_get_tangent(&R, v2, 0); + s3= RE_vertren_get_tangent(&R, v3, 0); + if(s1 && s2 && s3) { + shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]); + shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]); + shi->tang[2]= (l*s3[2] - u*s1[2] - v*s2[2]); + } + else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; + } } else { VECCOPY(shi->vn, shi->facenor); + if(mode & MA_TANGENT_V) + shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; } /* texture coordinates. shi->dxuv shi->dyuv have been set */ @@ -2026,7 +1970,6 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->dyuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); shi->dyuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); } - if(mode & MA_FACETEXTURE) { if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) { shi->vcol[0]= 1.0; @@ -2054,18 +1997,47 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->orn[2]= -shi->vn[2]; } if(mode & MA_RADIO) { - shi->rad[0]= (l*v3->rad[0] - u*v1->rad[0] - v*v2->rad[0]); - shi->rad[1]= (l*v3->rad[1] - u*v1->rad[1] - v*v2->rad[1]); - shi->rad[2]= (l*v3->rad[2] - u*v1->rad[2] - v*v2->rad[2]); + float *r1, *r2, *r3; + + r1= RE_vertren_get_rad(&R, v1, 0); + r2= RE_vertren_get_rad(&R, v2, 0); + r3= RE_vertren_get_rad(&R, v3, 0); + + if(r1 && r2 && r3) { + shi->rad[0]= (l*r3[0] - u*r1[0] - v*r2[0]); + shi->rad[1]= (l*r3[1] - u*r1[1] - v*r2[1]); + shi->rad[2]= (l*r3[2] - u*r1[2] - v*r2[2]); + } + else { + shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; + } } else { shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; } if(texco & TEXCO_REFL) { /* mirror reflection colour textures (and envmap) */ - calc_R_ref(shi); + calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */ + } + if(texco & TEXCO_STRESS) { + float *s1, *s2, *s3; + + s1= RE_vertren_get_stress(&R, v1, 0); + s2= RE_vertren_get_stress(&R, v2, 0); + s3= RE_vertren_get_stress(&R, v3, 0); + if(s1 && s2 && s3) { + shi->stress= l*s3[0] - u*s1[0] - v*s2[0]; + if(shi->stress<1.0f) shi->stress-= 1.0f; + else shi->stress= (shi->stress-1.0f)/shi->stress; + } + else shi->stress= 0.0f; + } + if(texco & TEXCO_TANGENT) { + if((mode & MA_TANGENT_V)==0) { + /* just prevent surprises */ + shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; + } } - } else { shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; @@ -2100,10 +2072,46 @@ static float isec_view_line(float *view, float *v3, float *v4) } #endif - + +/* also used as callback for nodes */ +void shade_material_loop(ShadeInput *shi, ShadeResult *shr) +{ + + shade_lamp_loop(shi, shr); /* clears shr */ + + if(shi->translucency!=0.0) { + ShadeResult shr_t; + + VECCOPY(shi->vn, shi->vno); + VecMulf(shi->vn, -1.0); + VecMulf(shi->facenor, -1.0); + shade_lamp_loop(shi, &shr_t); + + shr->diff[0]+= shi->translucency*shr_t.diff[0]; + shr->diff[1]+= shi->translucency*shr_t.diff[1]; + shr->diff[2]+= shi->translucency*shr_t.diff[2]; + VecMulf(shi->vn, -1.0); + VecMulf(shi->facenor, -1.0); + } + + if(R.r.mode & R_RAYTRACE) { + if(shi->ray_mirror!=0.0 || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0)) { + ray_trace(shi, shr); + } + } + else { + /* doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this */ + if(shi->mat->mode & MA_RAYTRANSP) shr->alpha= 1.0; + } + +} + /* x,y: window coordinate from 0 to rectx,y */ /* return pointer to rendered face */ -void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) +/* note, facenr declared volatile due to over-eager -O2 optimizations + * on cygwin (particularly -frerun-cse-after-loop) + */ +void *shadepixel(RenderPart *pa, float x, float y, int z, volatile int facenr, int mask, float *col, float *rco) { ShadeResult shr; ShadeInput shi; @@ -2112,31 +2120,29 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) if(facenr< 0) { /* error */ return NULL; } - /* currently in use for dithering (soft shadow) and detecting thread */ - shi.xs= x; - shi.ys= y; - + /* currently in use for dithering (soft shadow) node preview */ + shi.xs= (int)(x+0.5f); + shi.ys= (int)(y+0.5f); + shi.thread= pa->thread; + shi.do_preview= R.r.scemode & R_NODE_PREVIEW; + /* mask is used to indicate amount of samples (ray shad/mir and AO) */ shi.mask= mask; shi.depth= 0; // means first hit, not raytracing if(facenr==0) { /* sky */ col[0]= 0.0; col[1]= 0.0; col[2]= 0.0; col[3]= 0.0; + VECCOPY(rco, col); } else if( (facenr & 0x7FFFFF) <= R.totvlak) { - VertRen *v1, *v2, *v3; + VertRen *v1; float alpha, fac, zcor; - vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF); + vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF); shi.vlr= vlr; shi.mat= vlr->mat; - // copy all relevant material vars, note, keep this synced with render_types.h - memcpy(&shi.r, &shi.mat->r, 23*sizeof(float)); - // set special cases: - shi.har= shi.mat->har; - if((shi.mat->mode & MA_RAYMIRROR)==0) shi.ray_mirror= 0.0; shi.osatex= (shi.mat->texco & TEXCO_OSA); /* copy the face normal (needed because it gets flipped for tracing */ @@ -2146,14 +2152,14 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) v1= vlr->v1; /* COXYZ AND VIEW VECTOR */ - calc_view_vector(shi.view, x, y); + calc_view_vector(shi.view, x, y); /* returns not normalized, so is in viewplane coords */ /* wire cannot use normal for calculating shi.co */ if(shi.mat->mode & MA_WIRE) { float zco; /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */ - zco= ((float)z)/(float)0x7FFFFFFF; + zco= ((float)z)/2147483647.0f; shi.co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); fac= zcor= shi.co[2]/shi.view[2]; @@ -2169,11 +2175,11 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) /* ortho viewplane cannot intersect using view vector originating in (0,0,0) */ if(R.r.mode & R_ORTHO) { /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx= 2.0/(R.rectx*R.winmat[0][0]); - float fy= 2.0/(R.recty*R.winmat[1][1]); + float fx= 2.0/(R.winx*R.winmat[0][0]); + float fy= 2.0/(R.winy*R.winmat[1][1]); - shi.co[0]= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0]; - shi.co[1]= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1]; + shi.co[0]= (0.5 + x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; + shi.co[1]= (0.5 + y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; /* using a*x + b*y + c*z = d equation, (a b c) is normal */ if(shi.facenor[2]!=0.0f) @@ -2212,29 +2218,31 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) /* pixel dx/dy for render coord */ if(shi.osatex || (R.r.mode & R_SHADOW) ) { - float u= dface/(div-shi.facenor[0]); - float v= dface/(div- R.ycor*shi.facenor[1]); + float u= dface/(div - R.viewdx*shi.facenor[0]); + float v= dface/(div - R.viewdy*shi.facenor[1]); - shi.dxco[0]= shi.co[0]- (shi.view[0]-1.0)*u; + shi.dxco[0]= shi.co[0]- (shi.view[0]-R.viewdx)*u; shi.dxco[1]= shi.co[1]- (shi.view[1])*u; shi.dxco[2]= shi.co[2]- (shi.view[2])*u; shi.dyco[0]= shi.co[0]- (shi.view[0])*v; - shi.dyco[1]= shi.co[1]- (shi.view[1]-1.0*R.ycor)*v; + shi.dyco[1]= shi.co[1]- (shi.view[1]-R.viewdy)*v; shi.dyco[2]= shi.co[2]- (shi.view[2])*v; } } } + /* rco might be used for sky texture */ + VECCOPY(rco, shi.co); - /* cannot normalise earlier, code above needs it at pixel level */ + /* cannot normalise earlier, code above needs it at viewplane level */ fac= Normalise(shi.view); zcor*= fac; // for mist, distance of point from camera if(shi.osatex) { if( (shi.mat->texco & TEXCO_REFL) ) { - shi.dxview= -1.0/fac; - shi.dyview= -R.ycor/fac; + shi.dxview= -R.viewdx/fac; + shi.dyview= -R.viewdy/fac; } } @@ -2246,28 +2254,38 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) /* this only avalailable for scanline */ if(shi.mat->texco & TEXCO_WINDOW) { - shi.winco[0]= (x+(R.xstart))/(float)R.afmx; - shi.winco[1]= (y+(R.ystart))/(float)R.afmy; + shi.winco[0]= -1.0f + 2.0f*x/(float)R.winx; + shi.winco[1]= -1.0f + 2.0f*y/(float)R.winy; shi.winco[2]= 0.0; if(shi.osatex) { - shi.dxwin[0]= 0.5/(float)R.r.xsch; - shi.dywin[1]= 0.5/(float)R.r.ysch; + shi.dxwin[0]= 2.0/(float)R.winx; + shi.dywin[1]= 2.0/(float)R.winy; shi.dxwin[1]= shi.dxwin[2]= 0.0; shi.dywin[0]= shi.dywin[2]= 0.0; } } /* after this the u and v AND shi.dxuv and shi.dyuv are incorrect */ if(shi.mat->texco & TEXCO_STICKY) { - if(v1->sticky) { - extern float Zmulx, Zmuly; - float *o1, *o2, *o3, hox, hoy, l, dl, u, v; + VertRen *v2, *v3; + float *s1, *s2, *s3; + + if(facenr & 0x800000) { + v2= vlr->v3; v3= vlr->v4; + } else { + v2= vlr->v2; v3= vlr->v3; + } + + s1= RE_vertren_get_sticky(&R, v1, 0); + s2= RE_vertren_get_sticky(&R, v2, 0); + s3= RE_vertren_get_sticky(&R, v3, 0); + + if(s1 && s2 && s3) { + float Zmulx, Zmuly; + float hox, hoy, l, dl, u, v; float s00, s01, s10, s11, detsh; - if(facenr & 0x800000) { - v2= vlr->v3; v3= vlr->v4; - } else { - v2= vlr->v2; v3= vlr->v3; - } + /* XXXX */ + Zmulx= R.winx; Zmuly= R.winy; s00= v3->ho[0]/v3->ho[3] - v1->ho[0]/v1->ho[3]; s01= v3->ho[1]/v3->ho[3] - v1->ho[1]/v1->ho[3]; @@ -2285,12 +2303,8 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) v= (hoy - v3->ho[1]/v3->ho[3])*s00 - (hox - v3->ho[0]/v3->ho[3])*s01; l= 1.0+u+v; - o1= v1->sticky; - o2= v2->sticky; - o3= v3->sticky; - - shi.sticky[0]= l*o3[0]-u*o1[0]-v*o2[0]; - shi.sticky[1]= l*o3[1]-u*o1[1]-v*o2[1]; + shi.sticky[0]= l*s3[0]-u*s1[0]-v*s2[0]; + shi.sticky[1]= l*s3[1]-u*s1[1]-v*s2[1]; shi.sticky[2]= 0.0; if(shi.osatex) { @@ -2300,43 +2314,41 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) shi.dyuv[1]= s00/Zmuly; dl= shi.dxuv[0]+shi.dxuv[1]; - shi.dxsticky[0]= dl*o3[0]-shi.dxuv[0]*o1[0]-shi.dxuv[1]*o2[0]; - shi.dxsticky[1]= dl*o3[1]-shi.dxuv[0]*o1[1]-shi.dxuv[1]*o2[1]; + shi.dxsticky[0]= dl*s3[0]-shi.dxuv[0]*s1[0]-shi.dxuv[1]*s2[0]; + shi.dxsticky[1]= dl*s3[1]-shi.dxuv[0]*s1[1]-shi.dxuv[1]*s2[1]; dl= shi.dyuv[0]+shi.dyuv[1]; - shi.dysticky[0]= dl*o3[0]-shi.dyuv[0]*o1[0]-shi.dyuv[1]*o2[0]; - shi.dysticky[1]= dl*o3[1]-shi.dyuv[0]*o1[1]-shi.dyuv[1]*o2[1]; + shi.dysticky[0]= dl*s3[0]-shi.dyuv[0]*s1[0]-shi.dyuv[1]*s2[0]; + shi.dysticky[1]= dl*s3[1]-shi.dyuv[0]*s1[1]-shi.dyuv[1]*s2[1]; } } } - /* ------ main shading loop */ - shade_lamp_loop(&shi, &shr); - - if(shi.translucency!=0.0) { - ShadeResult shr_t; - - VecMulf(shi.vn, -1.0); - VecMulf(shi.facenor, -1.0); - shade_lamp_loop(&shi, &shr_t); - shr.diff[0]+= shi.translucency*shr_t.diff[0]; - shr.diff[1]+= shi.translucency*shr_t.diff[1]; - shr.diff[2]+= shi.translucency*shr_t.diff[2]; - VecMulf(shi.vn, -1.0); - VecMulf(shi.facenor, -1.0); - } + /* ------ main shading loop -------- */ + VECCOPY(shi.vno, shi.vn); - if(R.r.mode & R_RAYTRACE) { - if(shi.ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) { - ray_trace(&shi, &shr); - } + if(shi.mat->nodetree && shi.mat->use_nodes) { + ntreeShaderExecTree(shi.mat->nodetree, &shi, &shr); } else { - // doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this - if(shi.mat->mode & MA_RAYTRANSP) shr.alpha= 1.0; + /* copy all relevant material vars, note, keep this synced with render_types.h */ + memcpy(&shi.r, &shi.mat->r, 23*sizeof(float)); + shi.har= shi.mat->har; + + shade_material_loop(&shi, &shr); } + /* after shading and composit layers */ + if(shr.spec[0]<0.0f) shr.spec[0]= 0.0f; + if(shr.spec[1]<0.0f) shr.spec[1]= 0.0f; + if(shr.spec[2]<0.0f) shr.spec[2]= 0.0f; + + if(shr.diff[0]<0.0f) shr.diff[0]= 0.0f; + if(shr.diff[1]<0.0f) shr.diff[1]= 0.0f; + if(shr.diff[2]<0.0f) shr.diff[2]= 0.0f; + VECADD(col, shr.diff, shr.spec); + /* NOTE: this is not correct here, sky from raytrace gets corrected... */ /* exposure correction */ if(R.wrld.exp!=0.0 || R.wrld.range!=1.0) { if((shi.mat->mode & MA_SHLESS)==0) { @@ -2347,7 +2359,7 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) } /* MIST */ - if( (R.wrld.mode & WO_MIST) && (shi.mat->mode & MA_NOMIST)==0 ) { + if((R.wrld.mode & WO_MIST) && (shi.mat->mode & MA_NOMIST)==0 ) { if(R.r.mode & R_ORTHO) alpha= mistfactor(-shi.co[2], shi.co); else @@ -2400,137 +2412,47 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col) return vlr; } -static void shadepixel_sky(float x, float y, int z, int facenr, int mask, float *colf) +static void shadepixel_sky(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *colf) { VlakRen *vlr; - float collector[4]; + float collector[4], rco[3]; - vlr= shadepixel(x, y, z, facenr, mask, colf); + vlr= shadepixel(pa, x, y, z, facenr, mask, colf, rco); if(colf[3] != 1.0) { /* bail out when raytrace transparency (sky included already) */ if(vlr && (R.r.mode & R_RAYTRACE)) if(vlr->mat->mode & MA_RAYTRANSP) return; - - renderSkyPixelFloat(collector, x, y); + + renderSkyPixelFloat(collector, x, y, vlr?rco:NULL); addAlphaOverFloat(collector, colf); QUATCOPY(colf, collector); } } -/* ************* pixel struct ******** */ - -static PixStrMain psmfirst; -static int psmteller; - -static PixStr *addpsmain(void) -{ - PixStrMain *psm; - - psm= &psmfirst; - - while(psm->next) { - psm= psm->next; - } - - psm->next= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain"); - - psm= psm->next; - psm->next=0; - psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr"); - psmteller= 0; - - return psm->ps; -} - -static void freeps(void) -{ - PixStrMain *psm,*next; - - psm= &psmfirst; - - while(psm) { - next= psm->next; - if(psm->ps) { - MEM_freeN(psm->ps); - psm->ps= 0; - } - if(psm!= &psmfirst) MEM_freeN(psm); - psm= next; - } - - psmfirst.next= 0; - psmfirst.ps= 0; -} - -static void addps(long *rd, int facenr, int z, unsigned short mask) -{ - static PixStr *cur; - PixStr *ps, *last = NULL; - - if(*rd) { - ps= (PixStr *)(*rd); - - while(ps) { - if( ps->facenr == facenr ) { - ps->mask |= mask; - return; - } - last= ps; - ps= ps->next; - } - } - - /* make new PS (pixel struct) */ - if((psmteller & 4095)==0) cur= addpsmain(); - else cur++; - psmteller++; - - if(last) last->next= cur; - else *rd= (long)cur; - - cur->next= NULL; - cur->facenr= facenr; - cur->z= z; - cur->mask = mask; -} - - -int count_mask(unsigned short mask) -{ - extern char cmask[256]; - return (cmask[mask & 255]+cmask[mask>>8]); -} - -static void edge_enhance(void) +/* adds only alpha values */ +static void edge_enhance_calc(RenderPart *pa, float *rectf) { /* use zbuffer to define edges, add it to the image */ - int val, y, x, col, *rz, *rz1, *rz2, *rz3; + int y, x, col, *rz, *rz1, *rz2, *rz3; int zval1, zval2, zval3; - char *cp; + float *rf; /* shift values in zbuffer 4 to the right, for filter we need multiplying with 12 max */ - rz= (int *)R.rectz; + rz= pa->rectz; if(rz==NULL) return; - for(y=0; y>= 4; + for(y=0; yrecty; y++) { + for(x=0; xrectx; x++, rz++) (*rz)>>= 4; } - rz1= (int *)R.rectz; - rz2= rz1+R.rectx; - rz3= rz2+R.rectx; - - if(R.r.mode & R_OSA) { - cp= (char *)(R.rectaccu+R.rectx); - } - else { - cp= (char *)(R.rectot+R.rectx); - } - cp+= 4; + rz1= pa->rectz; + rz2= rz1+pa->rectx; + rz3= rz2+pa->rectx; - for(y=0; yrectx+1; + + for(y=0; yrecty-2; y++) { + for(x=0; xrectx-2; x++, rz1++, rz2++, rz3++, rf++) { /* prevent overflow with sky z values */ zval1= rz1[0] + 2*rz1[1] + rz1[2]; @@ -2544,482 +2466,383 @@ static void edge_enhance(void) else col= (R.r.edgeint*col)>>8; if(col>0) { - if(col>255) col= 255; + float fcol; - if(R.r.mode & R_OSA) { - col/= R.osa; - - val= cp[3]+col; - if(val>255) cp[3]= 255; else cp[3]= val; - } - else { - val= cp[0]- col; - if(val<0) cp[0]= 0; else cp[0]= val; - val= cp[1]- col; - if(val<0) cp[1]= 0; else cp[1]= val; - val= cp[2]- col; - if(val<0) cp[2]= 0; else cp[2]= val; - } + if(col>255) fcol= 1.0f; + else fcol= (float)col/255.0f; + + if(R.osa) + *rf+= fcol/(float)R.osa; + else + *rf= fcol; } } - rz++; rz1+= 2; rz2+= 2; rz3+= 2; - cp+= 8; + rf+= 2; } - } +static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect) +{ + float addcol[4]; + int pix; + + for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) { + if(*arect != 0.0f) { + addcol[0]= *arect * R.r.edgeR; + addcol[1]= *arect * R.r.edgeG; + addcol[2]= *arect * R.r.edgeB; + addcol[3]= *arect; + addAlphaOverFloat(rectf, addcol); + } + } +} + + /* ********************* MAINLOOPS ******************** */ -struct renderlineDA { - long *rd; - int *rz; - float *rb1, *rb2, *rb3; - float *acol; - int y; -}; -static int do_renderlineDA(void *poin) +static void shadeDA_tile(RenderPart *pa, float *rectf, float *recta) { - struct renderlineDA *rl= poin; PixStr *ps; float xs, ys; - float fcol[4], *acol=NULL, *rb1, *rb2, *rb3; - long *rd= rl->rd; + float fcol[4], *rf, *grf, *acol= NULL; + long *rd, *rectdaps= pa->rectdaps; int zbuf, samp, curmask, face, mask, fullmask; - int b, x, full_osa, seed; + int b, x, y, full_osa, seed, crop=0; + + if(R.test_break()) return; /* we set per pixel a fixed seed, for random AO and shadow samples */ - seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx; - + seed= pa->rectx*pa->disprect.ymin; + fullmask= (1<rb1; - rb2= rl->rb2; - rb3= rl->rb3; - if(R.flag & R_ZTRA) { /* zbuf tra */ - abufsetrow(rl->acol, rl->y); - acol= rl->acol; + /* might need it for gamma, in end of this function */ + grf= rectf; + + /* filtered render, for now we assume only 1 filter size */ + if(pa->crop) { + crop= 1; + rectf+= 4*(pa->rectx + 1); + rectdaps+= pa->rectx + 1; + if(recta) recta+= 4*(pa->rectx + 1); } + + for(y=pa->disprect.ymin+crop; ydisprect.ymax-crop; y++) { + rf= rectf; + rd= rectdaps; + if(recta) acol= recta; - for(x=0; xdisprect.xmin+crop; xdisprect.xmax-crop; x++, rd++, rf+=4) { + BLI_thread_srandom(pa->thread, seed+x); + + ps= (PixStr *)(*rd); + mask= 0; + + /* complex loop, because empty spots are sky, without mask */ + while(TRUE) { + + if(ps==NULL) { + face= 0; + curmask= (~mask) & fullmask; + zbuf= 0x7FFFFFFF; + } + else { + face= ps->facenr; + curmask= ps->mask; + zbuf= ps->z; + } + + /* check osa level */ + if(face==0) full_osa= 0; + else { + VlakRen *vlr= RE_findOrAddVlak(&R, (face-1) & 0x7FFFFF); + full_osa= (vlr->flag & R_FULL_OSA); + } + + if(full_osa) { + for(samp=0; samprectx); + } + } + } + else { + b= R.samples->centmask[curmask]; + xs= (float)x+R.samples->centLut[b & 15]; + ys= (float)y+R.samples->centLut[b>>4]; + shadepixel_sky(pa, xs, ys, zbuf, face, curmask, fcol); + + if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol); + + if(R.do_gamma) { + fcol[0]= gammaCorrect(fcol[0]); + fcol[1]= gammaCorrect(fcol[1]); + fcol[2]= gammaCorrect(fcol[2]); + } + add_filt_fmask(curmask, fcol, rf, pa->rectx); + } + + mask |= curmask; + + if(ps==NULL) break; + else ps= ps->next; + } + if(acol) acol+=4; + } - BLI_thread_srandom(rl->y & 1, seed+x); + rectf+= 4*pa->rectx; + rectdaps+= pa->rectx; + if(recta) recta+= 4*pa->rectx; + seed+= pa->rectx; + if(y&1) if(R.test_break()) break; + } + + if(R.do_gamma) { + for(y= pa->rectx*pa->recty; y>0; y--, grf+=4) { + grf[0] = invGammaCorrect(grf[0]); + grf[1] = invGammaCorrect(grf[1]); + grf[2] = invGammaCorrect(grf[2]); + } + } + +} + +/* ************* pixel struct ******** */ + + +static PixStrMain *addpsmain(ListBase *lb) +{ + PixStrMain *psm; + + psm= (PixStrMain *)RE_mallocN(sizeof(PixStrMain),"pixstrMain"); + BLI_addtail(lb, psm); + + psm->ps= (PixStr *)RE_mallocN(4096*sizeof(PixStr),"pixstr"); + psm->counter= 0; + + return psm; +} + +static void freeps(ListBase *lb) +{ + PixStrMain *psm, *psmnext; + + for(psm= lb->first; psm; psm= psmnext) { + psmnext= psm->next; + if(psm->ps) + RE_freeN(psm->ps); + RE_freeN(psm); + } + lb->first= lb->last= NULL; +} + +static void addps(ListBase *lb, long *rd, int facenr, int z, unsigned short mask) +{ + PixStrMain *psm; + PixStr *ps, *last= NULL; + + if(*rd) { ps= (PixStr *)(*rd); - mask= 0; - /* complex loop, because empty spots are sky, without mask */ - while(TRUE) { - - if(ps==NULL) { - face= 0; - curmask= (~mask) & fullmask; - zbuf= *(rl->rz+x); + while(ps) { + if( ps->facenr == facenr ) { + ps->mask |= mask; + return; } - else { - face= ps->facenr; - curmask= ps->mask; - zbuf= ps->z; - } - - /* check osa level */ - if(face==0) full_osa= 0; - else { - VlakRen *vlr= RE_findOrAddVlak( (face-1) & 0x7FFFFF); - full_osa= (vlr->flag & R_FULL_OSA); - } - - if(full_osa) { - for(samp=0; sampy + jit[samp][1]; - shadepixel_sky(xs, ys, zbuf, face, (1<y+centLut[b>>4]; - shadepixel_sky(xs, ys, zbuf, face, curmask, fcol); - - if(acol && acol[3]!=0.0) addAlphaOverFloat(fcol, acol); - - if(do_gamma) { - fcol[0]= gammaCorrect(fcol[0]); - fcol[1]= gammaCorrect(fcol[1]); - fcol[2]= gammaCorrect(fcol[2]); - } - add_filt_fmask(curmask, fcol, rb1, rb2, rb3); - } - - mask |= curmask; - - if(ps==NULL) break; - else ps= ps->next; + last= ps; + ps= ps->next; } - - rb1+=4; - rb2+=4; - rb3+=4; - if(acol) acol+=4; } - - return 1; + + /* make new PS (pixel struct) */ + psm= lb->last; + + if(psm->counter==4095) + psm= addpsmain(lb); + + ps= psm->ps + psm->counter++; + + if(last) last->next= ps; + else *rd= (long)ps; + + ps->next= NULL; + ps->facenr= facenr; + ps->z= z; + ps->mask = mask; } -void zbufshadeDA(void) /* Delta Accum Pixel Struct */ +static void make_pixelstructs(RenderPart *pa, ListBase *lb) { - extern float Zjitx,Zjity; - struct renderlineDA rl1, rl2; - float xd, yd, *rf; - long *rd; - int *rz, *rp, *rt; - float *rowbuf1, *rowbuf2, *rowbuf3, *rowbuf0, *rowbuf1a, *rowbuf2a, *rb3; - int a; - short v, x, y; - - R.rectdaps= MEM_callocN(sizeof(long)*R.rectx*R.recty+4,"zbufDArectd"); + long *rd= pa->rectdaps; + int *rp= pa->rectp; + int *rz= pa->rectz; + int x, y; + int mask= 1<sample; - if(R.flag & R_ZTRA) { - bgnaccumbuf(); - rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); - rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); - } - - psmteller= 0; - - if(R.r.mode & R_EDGE) { - R.rectaccu= (int *)MEM_callocN(sizeof(int)*R.rectx*R.recty,"zbufshadeDA"); - } - - for(v=0; vrecty; y++) { + for(x=0; xrectx; x++, rd++, rp++) { + if(*rp) { + addps(lb, rd, *rp, *(rz+x), mask); } - rz+= R.rectx; } + rz+= pa->rectx; + } +} - if(R.r.mode & R_EDGE) edge_enhance(); +/* supposed to be fully threadable! */ +void zbufshadeDA_tile(RenderPart *pa) +{ + RenderLayer *rl; + ListBase psmlist= {NULL, NULL}; + float *acolrect= NULL, *edgerect= NULL; + + set_part_zbuf_clipflag(pa); + + /* allocate the necessary buffers */ + /* zbuffer inits these rects */ + pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); + pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); + if(R.r.mode & R_EDGE) edgerect= RE_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); + + for(rl= pa->result->layers.first; rl; rl= rl->next) { + + /* initialize pixelstructs */ + addpsmain(&psmlist); + pa->rectdaps= RE_callocN(sizeof(long)*pa->rectx*pa->recty+4, "zbufDArectd"); - if(RE_local_test_break()) break; + if(rl->layflag & SCE_LAY_SOLID) { + for(pa->sample=0; pa->samplesample++) { + zbuffer_solid(pa, rl->lay, rl->layflag); + make_pixelstructs(pa, &psmlist); + + if(R.r.mode & R_EDGE) edge_enhance_calc(pa, edgerect); + if(R.test_break()) break; + } + } + else /* need to clear rectz for next passes */ + fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF); + + + /* we do transp layer first, so its get added with filter in main buffer... still incorrect though */ + if(R.flag & R_ZTRA) { + if(rl->layflag & SCE_LAY_ZTRA) { + acolrect= RE_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer"); + zbuffer_transp_shade(pa, acolrect, rl->lay, rl->layflag); + } + } + + /* shades solid and adds transparent layer */ + if(rl->layflag & SCE_LAY_SOLID) + shadeDA_tile(pa, rl->rectf, acolrect); + else if(acolrect) { + SWAP(float *, acolrect, rl->rectf); + } + + /* extra layers */ + if(R.r.mode & R_EDGE) + edge_enhance_add(pa, rl->rectf, edgerect); + if(R.flag & R_HALO) + if(rl->layflag & SCE_LAY_HALO) + halo_tile(pa, rl->rectf, rl->lay); + + if(rl->passflag & SCE_PASS_Z) + convert_zbuf_to_distbuf(pa, rl); + + /* free stuff within loop! */ + if(acolrect) { + RE_freeN(acolrect); + acolrect= NULL; + } + RE_freeN(pa->rectdaps); pa->rectdaps= NULL; + freeps(&psmlist); } - rd= R.rectdaps; - rz= R.rectz; - rt= R.rectot; - rf= R.rectftot; - - /* the rowbuf is 4 pixels larger than an image! */ - rowbuf0= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf1= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf2= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf1a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf2a= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - rowbuf3= MEM_callocN((R.rectx+4)*4*sizeof(float), "ZbufshadeDA3"); - - for(y=0; y<=R.recty; y++, rd+=R.rectx, rt+=R.rectx, rz+= R.rectx) { - - if(y0) { - /* halos are alpha-added, not in thread loop (yet) because of gauss mask */ - if(R.flag & R_HALO) { - /* one scanline older... */ - scanlinehaloPS(rz-R.rectx, rd-R.rectx, rowbuf3+4, y-1); - } - - /* convert 4x32 bits buffer to 4x8, this can't be threaded due to gauss */ - transferColourBufferToOutput(rowbuf3+4, y-1); - if(R.rectftot) { - memcpy(rf, rowbuf3+4, 4*sizeof(float)*R.rectx); - rf+= 4*R.rectx; - } - - } - if(y0) { - if((y & 1)==0) { - RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot); - } - } - } - if(RE_local_test_break()) break; - } - - if( (R.r.mode & R_EDGE) && RE_local_test_break()==0) { - if(R.rectftot) { - float *rtf= R.rectftot, colf[4]; - rp= R.rectaccu; - for(a= R.rectx*R.recty; a>0; a--, rtf+=4, rp++) { - cpCharColV2FloatColV((char *)rp, colf); - addAlphaOverFloat(rtf, colf); - } - RE_floatbuffer_to_output(); - } - else { - rt= R.rectot; - rp= R.rectaccu; - for(a= R.rectx*R.recty; a>0; a--, rt++, rp++) { - addalphaOver((char *)rt, (char *)rp); - } - } - } + /* free all */ + RE_freeN(pa->rectp); pa->rectp= NULL; + RE_freeN(pa->rectz); pa->rectz= NULL; + + if(edgerect) RE_freeN(edgerect); - MEM_freeN(R.rectdaps); - freeps(); - MEM_freeN(rowbuf0); - MEM_freeN(rowbuf1); - MEM_freeN(rowbuf2); - MEM_freeN(rowbuf1a); - MEM_freeN(rowbuf2a); - MEM_freeN(rowbuf3); - R.rectdaps= NULL; - if(R.r.mode & R_EDGE) if(R.rectaccu) MEM_freeN(R.rectaccu); - R.rectaccu= NULL; - if(R.flag & R_ZTRA) { - endaccumbuf(); - MEM_freeN(rl1.acol); - MEM_freeN(rl2.acol); - } +} -} /* end of void zbufshadeDA() */ /* ------------------------------------------------------------------------ */ -struct renderline { - float *rowbuf, *acol; - int *rp; - int *rz; - short ys; - float y; -}; - -static int do_renderline(void *poin) +/* supposed to be fully threadable! */ +void zbufshade_tile(RenderPart *pa) { - struct renderline *rl= poin; - float *fcol= rl->rowbuf; - float *acol=NULL; - int x, *rz, *rp, seed; + RenderLayer *rl; - /* we set per pixel a fixed seed, for random AO and shadow samples */ - seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx; + set_part_zbuf_clipflag(pa); - if(R.flag & R_ZTRA) { /* zbuf tra */ - abufsetrow(rl->acol, rl->ys); - acol= rl->acol; - } + /* zbuffer code clears/inits rects */ + pa->rectp= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); + pa->rectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); - for(x=0, rz= rl->rz, rp= rl->rp; xys & 1, seed+x); + for(rl= pa->result->layers.first; rl; rl= rl->next) { + zbuffer_solid(pa, rl->lay, rl->layflag); - shadepixel_sky((float)x, rl->y, *rz, *rp, 0, fcol); - if(acol) { - if(acol[3]!=0.0) addAlphaOverFloat(fcol, acol); - acol+= 4; - } - } + if(!R.test_break()) { + if(rl->layflag & SCE_LAY_SOLID) { + float *fcol= rl->rectf; + int x, y, *rp= pa->rectp, *rz= pa->rectz; - if(R.flag & R_HALO) { - scanlinehalo(rl->rz, rl->rowbuf, rl->ys); - } - - transferColourBufferToOutput(rl->rowbuf, rl->ys); - - if(R.rectftot) { - memcpy(R.rectftot + 4*rl->ys*R.rectx, rl->rowbuf, 4*sizeof(float)*R.rectx); - } - - return 1; -} - - -void zbufshade(void) -{ - struct renderline rl1, rl2; - extern float Zjitx,Zjity; - int *rz, *rp; - float fy; - int y; - - rl1.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade"); - rl2.rowbuf= MEM_callocN((R.rectx+4)*4*sizeof(float), "Zbufshade"); - - Zjitx=Zjity= -0.5; - - zbufferall(); - - /* SHADE */ - rp= R.rectot; - rz= R.rectz; - - if(R.flag & R_ZTRA) { - rl1.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); - rl2.acol= MEM_callocN((R.rectx+4)*4*sizeof(float), "Acol"); - bgnaccumbuf(); - } - - for(y=0; ydisprect.ymin; ydisprect.ymax; y++) { + for(x=pa->disprect.xmin; xdisprect.xmax; x++, rz++, rp++, fcol+=4) { + shadepixel_sky(pa, (float)x, (float)y, *rz, *rp, 0, fcol); + } + if(y&1) if(R.test_break()) break; + } } - rp+= R.rectx; - rz+= R.rectx; - - if(y < R.recty-1) { - rl2.rp= rp; - rl2.rz= rz; - rl2.y= fy+1.0; - rl2.ys= y+1; - do_renderline(&rl2); - rp+= R.rectx; - rz+= R.rectx; - y++; - } - SDL_WaitThread(thread, NULL); - } - else { - do_renderline(&rl1); - rp+= R.rectx; - rz+= R.rectx; } - if(y & 1) { - RE_local_render_display(y-1, y, R.rectx, R.recty, R.rectot); + if(!R.test_break()) + if(R.flag & R_ZTRA) + if(rl->layflag & SCE_LAY_ZTRA) + zbuffer_transp_shade(pa, rl->rectf, rl->lay, rl->layflag); + + if(!R.test_break()) { + if(R.r.mode & R_EDGE) { + fillrect(pa->rectp, pa->rectx, pa->recty, 0); + edge_enhance_calc(pa, (float *)pa->rectp); + edge_enhance_add(pa, rl->rectf, (float *)pa->rectp); + } } - if(RE_local_test_break()) break; - } - - MEM_freeN(rl1.rowbuf); - MEM_freeN(rl2.rowbuf); - - if(R.flag & R_ZTRA) { - endaccumbuf(); - MEM_freeN(rl1.acol); - MEM_freeN(rl2.acol); - } - - if(R.r.mode & R_EDGE) edge_enhance(); + if(!R.test_break()) + if(R.flag & R_HALO) + if(rl->layflag & SCE_LAY_HALO) + halo_tile(pa, rl->rectf, rl->lay); + + if(rl->passflag & SCE_PASS_Z) + convert_zbuf_to_distbuf(pa, rl); -} /* end of void zbufshade() */ + } + + RE_freeN(pa->rectp); pa->rectp= NULL; + RE_freeN(pa->rectz); pa->rectz= NULL; +} /* ------------------------------------------------------------------------ */ -void RE_shadehalo(HaloRen *har, char *col, float *colf, int zz, float dist, float xn, float yn, short flarec) -{ - - shadeHaloFloat(har, colf, zz, dist, xn, yn, flarec); - - if(colf[0]<=0.0) col[0]= 0; else if(colf[0]>=1.0) col[0]= 255; else col[0]= 255.0*colf[0]; - if(colf[1]<=0.0) col[1]= 0; else if(colf[1]>=1.0) col[1]= 255; else col[1]= 255.0*colf[1]; - if(colf[2]<=0.0) col[2]= 0; else if(colf[2]>=1.0) col[2]= 255; else col[2]= 255.0*colf[2]; - if(colf[3]<=0.0) col[3]= 0; else if(colf[3]>=1.0) col[3]= 255; else col[3]= 255.0*colf[3]; - -} - static void renderhalo(HaloRen *har) /* postprocess version */ { - +#if 0 float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf; int *rectt, *rt; int minx, maxx, miny, maxy, x, y; @@ -3064,7 +2887,7 @@ static void renderhalo(HaloRen *har) /* postprocess version */ if(R.rectftot) addalphaAddfacFloat(rtf, colf, har->add); else { std_floatcol_to_charcol(colf, col); - RE_addalphaAddfac((char *)rt, col, har->add); + addalphaAddfac((char *)rt, col, har->add); } } rt++; @@ -3074,14 +2897,15 @@ static void renderhalo(HaloRen *har) /* postprocess version */ rectt+= R.rectx; rectft+= 4*R.rectx; - if(RE_local_test_break()) break; + if(R.test_break()) break; } } } +#endif } /* ------------------------------------------------------------------------ */ -void RE_renderflare(HaloRen *har) +static void renderflare(HaloRen *har) { extern float hashvectf[]; HaloRen fla; @@ -3135,12 +2959,12 @@ void RE_renderflare(HaloRen *har) fla.radsq= fla.rad*fla.rad; - vec[0]= 1.4*rc[5]*(har->xs-R.afmx); - vec[1]= 1.4*rc[5]*(har->ys-R.afmy); + vec[0]= 1.4*rc[5]*(har->xs-R.winx/2); + vec[1]= 1.4*rc[5]*(har->ys-R.winy/2); vec[2]= 32.0*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0); - fla.xs= R.afmx + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2]; - fla.ys= R.afmy + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2]; + fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2]; + fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2]; if(R.flag & R_SEC_FIELD) { if(R.r.mode & R_ODDFIELD) fla.ys += 0.5; @@ -3157,36 +2981,35 @@ void RE_renderflare(HaloRen *har) rc+= 7; } -} /* end of void renderflare(HaloRen *har) */ +} +/* needs recode... integrate this! */ void add_halo_flare(void) { -/* extern void RE_projectverto(); */ /* zbuf.c */ HaloRen *har = NULL; int a, mode; mode= R.r.mode; R.r.mode &= ~R_PANORAMA; - R.xstart= -R.afmx; - R.ystart= -R.afmy; - R.xend= R.xstart+R.rectx-1; - R.yend= R.ystart+R.recty-1; +// R.xstart= -R.afmx; +// R.ystart= -R.afmy; +// R.xend= R.xstart+R.rectx-1; +// R.yend= R.ystart+R.recty-1; - RE_setwindowclip(1,-1); /* no jit:(-1) */ - setzbufvlaggen(RE_projectverto); +// RE_setwindowclip(1,-1); /* no jit:(-1) */ + project_renderdata(&R, projectverto, 0, 0); for(a=0; a>8]; else har++; if(har->flarec) { - RE_renderflare(har); + renderflare(har); } } R.r.mode= mode; - if(R.rectftot) RE_floatbuffer_to_output(); } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index ee003964764..098d4491060 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,15 +20,14 @@ * 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. + * Contributor(s): 2004-2006, Blender Foundation, full recode * * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * Storage, retrieval and query of render specific data. */ /* + * Storage, retrieval and query of render specific data. + * * All data from a Blender scene is converter by the renderconverter/ * into a special format that is used by the render module to make * images out of. These functions interface to the render-specific @@ -44,7 +40,7 @@ * offset in a 256-entry block. * * - If the 256-entry block entry has an entry in the - * blove/bloha/blovl array of the current block, the i-th entry in + * vertnodes/bloha/blovl array of the current block, the i-th entry in * that block is allocated to this entry. * * - If the entry has no block allocated for it yet, memory is @@ -57,6 +53,7 @@ * */ +#include #include #include @@ -66,74 +63,235 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "DNA_texture_types.h" #include "BKE_texture.h" -#include "render.h" +#include "RE_render_ext.h" /* externtex */ + +#include "renderpipeline.h" +#include "render_types.h" +#include "renderdatabase.h" +#include "texture.h" +#include "zbuf.h" /* ------------------------------------------------------------------------- */ -VertRen *RE_findOrAddVert(int nr) +/* More dynamic allocation of options for render vertices, so we dont + have to reserve this space inside vertices. + Important; vertices should have been created already (to get tables checked) + that's a reason why the calls demand VertRen * as arg, not the index */ + +/* NOTE! the hardcoded table size 256 is used still in code for going quickly over vertices/faces */ + +#define RE_STICKY_ELEMS 2 +#define RE_STRESS_ELEMS 1 +#define RE_RAD_ELEMS 4 +#define RE_STRAND_ELEMS 1 +#define RE_TANGENT_ELEMS 3 +#define RE_STRESS_ELEMS 1 + +/* render allocates totvert/256 of these nodes, for lookup and quick alloc */ +typedef struct VertTableNode { + struct VertRen *vert; + float *rad; + float *sticky; + float *strand; + float *tangent; + float *stress; +} VertTableNode; + +float *RE_vertren_get_sticky(Render *re, VertRen *ver, int verify) { - VertRen *v, **temp; - static int rblovelen=TABLEINITSIZE; + float *sticky; + int nr= ver->index>>8; + + sticky= re->vertnodes[nr].sticky; + if(sticky==NULL) { + if(verify) + sticky= re->vertnodes[nr].sticky= MEM_mallocN(256*RE_STICKY_ELEMS*sizeof(float), "sticky table"); + else + return NULL; + } + return sticky + (ver->index & 255)*RE_STICKY_ELEMS; +} + +float *RE_vertren_get_stress(Render *re, VertRen *ver, int verify) +{ + float *stress; + int nr= ver->index>>8; + + stress= re->vertnodes[nr].stress; + if(stress==NULL) { + if(verify) + stress= re->vertnodes[nr].stress= MEM_mallocN(256*RE_STRESS_ELEMS*sizeof(float), "stress table"); + else + return NULL; + } + return stress + (ver->index & 255)*RE_STRESS_ELEMS; +} + +/* this one callocs! */ +float *RE_vertren_get_rad(Render *re, VertRen *ver, int verify) +{ + float *rad; + int nr= ver->index>>8; + + rad= re->vertnodes[nr].rad; + if(rad==NULL) { + if(verify) + rad= re->vertnodes[nr].rad= MEM_callocN(256*RE_RAD_ELEMS*sizeof(float), "rad table"); + else + return NULL; + } + return rad + (ver->index & 255)*RE_RAD_ELEMS; +} + +float *RE_vertren_get_strand(Render *re, VertRen *ver, int verify) +{ + float *strand; + int nr= ver->index>>8; + + strand= re->vertnodes[nr].strand; + if(strand==NULL) { + if(verify) + strand= re->vertnodes[nr].strand= MEM_mallocN(256*RE_STRAND_ELEMS*sizeof(float), "strand table"); + else + return NULL; + } + return strand + (ver->index & 255)*RE_STRAND_ELEMS; +} + +/* needs calloc */ +float *RE_vertren_get_tangent(Render *re, VertRen *ver, int verify) +{ + float *tangent; + int nr= ver->index>>8; + + tangent= re->vertnodes[nr].tangent; + if(tangent==NULL) { + if(verify) + tangent= re->vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); + else + return NULL; + } + return tangent + (ver->index & 255)*RE_TANGENT_ELEMS; +} + + +VertRen *RE_findOrAddVert(Render *re, int nr) +{ + VertTableNode *temp; + VertRen *v; int a; if(nr<0) { printf("error in findOrAddVert: %d\n",nr); - return R.blove[0]; + return NULL; } a= nr>>8; - if (a>=rblovelen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ - //printf("Allocating %i more vert groups. %i total.\n", - // TABLEINITSIZE, rblovelen+TABLEINITSIZE ); - temp=R.blove; - R.blove=(VertRen**)MEM_callocN(sizeof(void*)*(rblovelen+TABLEINITSIZE) , "Blove"); - memcpy(R.blove, temp, rblovelen*sizeof(void*)); - memset(&(R.blove[rblovelen]), 0, TABLEINITSIZE*sizeof(void*)); - rblovelen+=TABLEINITSIZE; - MEM_freeN(temp); + if (a>=re->vertnodeslen-1) { /* Need to allocate more columns..., and keep last element NULL for free loop */ + temp= re->vertnodes; + + re->vertnodes= MEM_mallocN(sizeof(VertTableNode)*(re->vertnodeslen+TABLEINITSIZE) , "vertnodes"); + if(temp) memcpy(re->vertnodes, temp, re->vertnodeslen*sizeof(VertTableNode)); + memset(re->vertnodes+re->vertnodeslen, 0, TABLEINITSIZE*sizeof(VertTableNode)); + + re->vertnodeslen+=TABLEINITSIZE; + if(temp) MEM_freeN(temp); } - v= R.blove[a]; - if(v==0) { + v= re->vertnodes[a].vert; + if(v==NULL) { + int i; + v= (VertRen *)MEM_callocN(256*sizeof(VertRen),"findOrAddVert"); - R.blove[a]= v; + re->vertnodes[a].vert= v; + + for(i= (nr & 0xFFFFFF00), a=0; a<256; a++, i++) { + v[a].index= i; + } } v+= (nr & 255); return v; } +void free_renderdata_tables(Render *re) +{ + int a=0; + + if(re->blovl) { + for(a=0; re->blovl[a]; a++) + MEM_freeN(re->blovl[a]); + + MEM_freeN(re->blovl); + re->blovl= NULL; + re->blovllen= 0; + } + + if(re->bloha) { + for(a=0; re->bloha[a]; a++) + MEM_freeN(re->bloha[a]); + + MEM_freeN(re->bloha); + re->bloha= NULL; + re->blohalen= 0; + } + + if(re->vertnodes) { + for(a=0; re->vertnodes[a].vert; a++) { + MEM_freeN(re->vertnodes[a].vert); + + if(re->vertnodes[a].rad) + MEM_freeN(re->vertnodes[a].rad); + if(re->vertnodes[a].sticky) + MEM_freeN(re->vertnodes[a].sticky); + if(re->vertnodes[a].strand) + MEM_freeN(re->vertnodes[a].strand); + if(re->vertnodes[a].tangent) + MEM_freeN(re->vertnodes[a].tangent); + if(re->vertnodes[a].stress) + MEM_freeN(re->vertnodes[a].stress); + } + + MEM_freeN(re->vertnodes); + re->vertnodes= NULL; + re->vertnodeslen= 0; + } +} + + /* ------------------------------------------------------------------------ */ -int rblohalen=TABLEINITSIZE; -HaloRen *RE_findOrAddHalo(int nr) + +HaloRen *RE_findOrAddHalo(Render *re, int nr) { HaloRen *h, **temp; int a; if(nr<0) { printf("error in findOrAddHalo: %d\n",nr); - return R.bloha[0]; + return NULL; } a= nr>>8; - if (a>=rblohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ + if (a>=re->blohalen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ //printf("Allocating %i more halo groups. %i total.\n", - // TABLEINITSIZE, rblohalen+TABLEINITSIZE ); - temp=R.bloha; - R.bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(rblohalen+TABLEINITSIZE) , "Bloha"); - memcpy(R.bloha, temp, rblohalen*sizeof(void*)); - memset(&(R.bloha[rblohalen]), 0, TABLEINITSIZE*sizeof(void*)); - rblohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - MEM_freeN(temp); + // TABLEINITSIZE, re->blohalen+TABLEINITSIZE ); + temp=re->bloha; + + re->bloha=(HaloRen**)MEM_callocN(sizeof(void*)*(re->blohalen+TABLEINITSIZE) , "Bloha"); + if(temp) memcpy(re->bloha, temp, re->blohalen*sizeof(void*)); + memset(&(re->bloha[re->blohalen]), 0, TABLEINITSIZE*sizeof(void*)); + re->blohalen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ + if(temp) MEM_freeN(temp); } - h= R.bloha[a]; - if(h==0) { + h= re->bloha[a]; + if(h==NULL) { h= (HaloRen *)MEM_callocN(256*sizeof(HaloRen),"findOrAdHalo"); - R.bloha[a]= h; + re->bloha[a]= h; } h+= (nr & 255); return h; @@ -141,34 +299,34 @@ HaloRen *RE_findOrAddHalo(int nr) /* ------------------------------------------------------------------------ */ -VlakRen *RE_findOrAddVlak(int nr) +VlakRen *RE_findOrAddVlak(Render *re, int nr) { VlakRen *v, **temp; - static int rblovllen=TABLEINITSIZE; int a; if(nr<0) { printf("error in findOrAddVlak: %d\n",nr); - return R.blovl[0]; + return re->blovl[0]; } a= nr>>8; - if (a>=rblovllen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ + if (a>=re->blovllen-1){ /* Need to allocate more columns..., and keep last element NULL for free loop */ // printf("Allocating %i more face groups. %i total.\n", - // TABLEINITSIZE, rblovllen+TABLEINITSIZE ); - temp=R.blovl; - R.blovl=(VlakRen**)MEM_callocN(sizeof(void*)*(rblovllen+TABLEINITSIZE) , "Blovl"); - memcpy(R.blovl, temp, rblovllen*sizeof(void*)); - memset(&(R.blovl[rblovllen]), 0, TABLEINITSIZE*sizeof(void*)); - rblovllen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ - MEM_freeN(temp); + // TABLEINITSIZE, re->blovllen+TABLEINITSIZE ); + temp= re->blovl; + + re->blovl=(VlakRen**)MEM_callocN(sizeof(void*)*(re->blovllen+TABLEINITSIZE) , "Blovl"); + if(temp) memcpy(re->blovl, temp, re->blovllen*sizeof(void*)); + memset(&(re->blovl[re->blovllen]), 0, TABLEINITSIZE*sizeof(void*)); + re->blovllen+=TABLEINITSIZE; /*Does this really need to be power of 2?*/ + if(temp) MEM_freeN(temp); } - v= R.blovl[a]; + v= re->blovl[a]; - if(v==0) { + if(v==NULL) { v= (VlakRen *)MEM_callocN(256*sizeof(VlakRen),"findOrAddVlak"); - R.blovl[a]= v; + re->blovl[a]= v; } v+= (nr & 255); return v; @@ -176,7 +334,7 @@ VlakRen *RE_findOrAddVlak(int nr) /* ------------------------------------------------------------------------- */ -HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, +HaloRen *RE_inithalo(Render *re, Material *ma, float *vec, float *vec1, float *orco, float hasize, float vectsize, int seed) { HaloRen *har; @@ -186,18 +344,18 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, if(hasize==0.0) return NULL; - RE_projectverto(vec, hoco); + projectverto(vec, re->winmat, hoco); if(hoco[3]==0.0) return NULL; if(vec1) { - RE_projectverto(vec1, hoco1); + projectverto(vec1, re->winmat, hoco1); if(hoco1[3]==0.0) return NULL; } - har= RE_findOrAddHalo(R.tothalo++); + har= RE_findOrAddHalo(re, re->tothalo++); VECCOPY(har->co, vec); har->hasize= hasize; - /* projectvert is done in function 'zbufvlaggen' because of parts/border/pano */ + /* actual projectvert is done in function transform_renderdata() because of parts/border/pano */ /* halovect */ if(vec1) { @@ -205,14 +363,14 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, har->type |= HA_VECT; zn= hoco[3]; - har->xs= 0.5*R.rectx*(hoco[0]/zn); - har->ys= 0.5*R.recty*(hoco[1]/zn); + har->xs= 0.5*re->winx*(hoco[0]/zn); + har->ys= 0.5*re->winy*(hoco[1]/zn); har->zs= 0x7FFFFF*(hoco[2]/zn); har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); - xn= har->xs - 0.5*R.rectx*(hoco1[0]/hoco1[3]); - yn= har->ys - 0.5*R.recty*(hoco1[1]/hoco1[3]); + xn= har->xs - 0.5*re->winx*(hoco1[0]/hoco1[3]); + yn= har->ys - 0.5*re->winy*(hoco1[1]/hoco1[3]); if(xn==0.0 || (xn==0.0 && yn==0.0)) zn= 0.0; else zn= atan2(yn, xn); @@ -285,4 +443,228 @@ HaloRen *RE_inithalo(Material *ma, float *vec, float *vec1, return har; } + +/* -------------------------- operations on entire database ----------------------- */ + +static float get_pano_rot(Render *re, int part) +{ + static float alpha= 1.0; + + /* part==0 init all */ + if(part==0) { + alpha= ((float)re->r.xsch)/re->viewfac; + alpha= 2.0*atan(alpha/2.0); + } + + /* rotate it all around the y-as with phi degrees */ + return 0.5*(re->r.xparts-1)*alpha + part*alpha; +} + +/* ugly function for halos in panorama */ +static int panotestclip(Render *re, int do_pano, float *v) +{ + /* to be used for halos en infos */ + float abs4; + short c=0; + + if(do_pano) return testclip(v); + + abs4= fabs(v[3]); + + if(v[2]< -abs4) c=16; /* this used to be " if(v[2]<0) ", see clippz() */ + else if(v[2]> abs4) c+= 32; + + if( v[1]>abs4) c+=4; + else if( v[1]< -abs4) c+=8; + + abs4*= re->r.xparts; + if( v[0]>abs4) c+=2; + else if( v[0]< -abs4) c+=1; + + return c; +} + +/* + This adds the hcs coordinates to vertices. It iterates over all + vertices, halos and faces. After the conversion, we clip in hcs. + + Elsewhere, all primites are converted to vertices. + Called in + - envmapping (envmap.c) + - shadow buffering (shadbuf.c) +*/ + +void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4], float *), int do_pano, int part) +{ + VlakRen *vlr = NULL; + VertRen *ver = NULL; + HaloRen *har = NULL; + float zn, vec[3], hoco[4]; + int a; + + if(do_pano) { + float panophi= get_pano_rot(re, part); + + re->panosi= sin(panophi); + re->panoco= cos(panophi); + } + + /* calculate view coordinates (and zbuffer value) */ + for(a=0; a< re->totvert;a++) { + if((a & 255)==0) ver= RE_findOrAddVert(re, a); + else ver++; + + if(do_pano) { + vec[0]= re->panoco*ver->co[0] + re->panosi*ver->co[2]; + vec[1]= ver->co[1]; + vec[2]= -re->panosi*ver->co[0] + re->panoco*ver->co[2]; + } + else { + VECCOPY(vec, ver->co); + } + /* Go from wcs to hcs ... */ + projectfunc(vec, re->winmat, ver->ho); + /* ... and clip in that system. */ + ver->clip = testclip(ver->ho); + /* + Because all other ops are performed in other systems, this is + the only thing that has to be done. + */ + } + + /* calculate view coordinates (and zbuffer value) */ + for(a=0; atothalo; a++) { + if((a & 255)==0) har= re->bloha[a>>8]; + else har++; + + if(do_pano) { + vec[0]= re->panoco*har->co[0] + re->panosi*har->co[2]; + vec[1]= har->co[1]; + vec[2]= -re->panosi*har->co[0] + re->panoco*har->co[2]; + } + else { + VECCOPY(vec, har->co); + } + + projectfunc(vec, re->winmat, hoco); + + /* we clip halos less critical, but not for the Z */ + hoco[0]*= 0.5; + hoco[1]*= 0.5; + + if( panotestclip(re, do_pano, hoco) ) { + har->miny= har->maxy= -10000; /* that way render clips it */ + } + else if(hoco[3]<0.0) { + har->miny= har->maxy= -10000; /* render clips it */ + } + else /* do the projection...*/ + { + /* bring back hocos */ + hoco[0]*= 2.0; + hoco[1]*= 2.0; + + zn= hoco[3]; + har->xs= 0.5*re->winx*(1.0+hoco[0]/zn); /* the 0.5 negates the previous 2...*/ + har->ys= 0.5*re->winy*(1.0+hoco[1]/zn); + + /* this should be the zbuffer coordinate */ + har->zs= 0x7FFFFF*(hoco[2]/zn); + /* taking this from the face clip functions? seems ok... */ + har->zBufDist = 0x7FFFFFFF*(hoco[2]/zn); + + vec[0]+= har->hasize; + projectfunc(vec, re->winmat, hoco); + vec[0]-= har->hasize; + zn= hoco[3]; + har->rad= fabs(har->xs- 0.5*re->winx*(1.0+hoco[0]/zn)); + + /* this clip is not really OK, to prevent stars to become too large */ + if(har->type & HA_ONLYSKY) { + if(har->rad>3.0) har->rad= 3.0; + } + + har->radsq= har->rad*har->rad; + + har->miny= har->ys - har->rad/re->ycor; + har->maxy= har->ys + har->rad/re->ycor; + + /* the Zd value is still not really correct for pano */ + + vec[2]-= har->hasize; /* z negative, otherwise it's clipped */ + projectfunc(vec, re->winmat, hoco); + zn= hoco[3]; + zn= fabs( (float)har->zs - 0x7FFFFF*(hoco[2]/zn)); + har->zd= CLAMPIS(zn, 0, INT_MAX); + + } + + } + + /* set flags at 0 if clipped away */ + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; + else vlr++; + + vlr->flag |= R_VISIBLE; + if(vlr->v4) { + if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip & vlr->v4->clip) vlr->flag &= ~R_VISIBLE; + } + else if(vlr->v1->clip & vlr->v2->clip & vlr->v3->clip) vlr->flag &= ~R_VISIBLE; + + } + +} + /* ------------------------------------------------------------------------- */ + +void set_normalflags(Render *re) +{ + VlakRen *vlr = NULL; + float *v1, xn, yn, zn; + int a1, doflip; + + /* switch normal 'snproj' values (define which axis is the optimal one for calculations) */ + for(a1=0; a1totvlak; a1++) { + if((a1 & 255)==0) vlr= re->blovl[a1>>8]; + else vlr++; + + /* abuse of this flag... this is code that just sets face normal in direction of camera */ + /* that convention we should get rid of */ + if((vlr->flag & R_NOPUNOFLIP)==0) { + + doflip= 0; + if(re->r.mode & R_ORTHO) { + if(vlr->n[2]>0.0) doflip= 1; + } + else { + v1= vlr->v1->co; + if( (v1[0]*vlr->n[0] +v1[1]*vlr->n[1] +v1[2]*vlr->n[2])<0.0 ) doflip= 1; + } + if(doflip) { + vlr->n[0]= -vlr->n[0]; + vlr->n[1]= -vlr->n[1]; + vlr->n[2]= -vlr->n[2]; + } + } + + /* recalculate puno. Displace & flipped matrices can screw up */ + vlr->puno= 0; + if(!(vlr->flag & R_TANGENT)) { + if( Inpf(vlr->n, vlr->v1->n) < 0.0 ) vlr->puno |= ME_FLIPV1; + if( Inpf(vlr->n, vlr->v2->n) < 0.0 ) vlr->puno |= ME_FLIPV2; + if( Inpf(vlr->n, vlr->v3->n) < 0.0 ) vlr->puno |= ME_FLIPV3; + if(vlr->v4 && Inpf(vlr->n, vlr->v4->n) < 0.0 ) vlr->puno |= ME_FLIPV4; + } + xn= fabs(vlr->n[0]); + yn= fabs(vlr->n[1]); + zn= fabs(vlr->n[2]); + if(zn>=xn && zn>=yn) vlr->snproj= 0; + else if(yn>=xn && yn>=zn) vlr->snproj= 1; + else vlr->snproj= 2; + + } +} + + + diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index c942232bebb..1403139269f 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -1,14 +1,10 @@ -/* shadbuf.c RENDER - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +/* + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -22,20 +18,10 @@ * 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): 2004-2006, Blender Foundation * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * - * april 95 - * - * $Id$ - * - * 27-Jun-2001 switched the shadow buffer for UR to the object-shadow - * buffers, and removed all references and fixes for UR rendering from - * this one. - * */ + * ***** END GPL LICENSE BLOCK ***** + */ #include #include @@ -45,16 +31,18 @@ #include "DNA_lamp_types.h" #include "BKE_utildefines.h" -#include "BLI_arithb.h" -#include "render.h" +#include "BLI_arithb.h" +#include "BLI_jitter.h" + +#include "renderpipeline.h" +#include "render_types.h" +#include "renderdatabase.h" #include "shadbuf.h" -#include "renderHelp.h" -#include "jitter.h" #include "zbuf.h" -/* XXX, could be better implemented... +/* XXX, could be better implemented... this is for endian issues */ #if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) #define RCOMP 3 @@ -70,80 +58,27 @@ /* ------------------------------------------------------------------------- */ +/* initshadowbuf() in convertBlenderScene.c */ -void RE_initshadowbuf(LampRen *lar, float mat[][4]) -{ - struct ShadBuf *shb; - float hoek, temp, viewinv[4][4]; - - /* if(la->spsi<16) return; */ - - /* memory reservation */ - shb= (struct ShadBuf *)MEM_callocN( sizeof(struct ShadBuf),"initshadbuf"); - lar->shb= shb; - - if(shb==NULL) return; - - VECCOPY(shb->co, lar->co); - - /* percentage render: keep track of min and max */ - shb->size= (lar->bufsize*R.r.size)/100; - if(shb->size<512) shb->size= 512; - else if(shb->size > lar->bufsize) shb->size= lar->bufsize; - - shb->size &= ~15; /* make sure its multiples of 16 */ - - shb->samp= lar->samp; - shb->soft= lar->soft; - shb->shadhalostep= lar->shadhalostep; - - shb->zbuf= (unsigned long *)MEM_mallocN( sizeof(unsigned long)*(shb->size*shb->size)/256, "initshadbuf2"); - shb->cbuf= (char *)MEM_callocN( (shb->size*shb->size)/256, "initshadbuf3"); - - if(shb->zbuf==0 || shb->cbuf==0) { - if(shb->zbuf) MEM_freeN(shb->zbuf); - MEM_freeN(lar->shb); - lar->shb= 0; - return; - } - - MTC_Mat4Ortho(mat); - MTC_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, R.viewmat); - MTC_Mat4MulMat4(shb->viewmat, viewinv, shb->winmat); - - /* projection */ - hoek= saacos(lar->spotsi); - temp= 0.5*shb->size*cos(hoek)/sin(hoek); - shb->d= lar->clipsta; - - shb->pixsize= (shb->d)/temp; - - shb->far= lar->clipend; - /* bias is percentage, made 2x karger because of correction for angle of incidence */ - /* when a ray is closer to parallel of a face, bias value is increased during render */ - shb->bias= (0.02*lar->bias)*0x7FFFFFFF; - shb->bias= shb->bias*(100/R.r.size); - -} /* ------------------------------------------------------------------------- */ - -static void lrectreadRectz(int x1, int y1, int x2, int y2, char *r1) /* reads part from rectz in r1 */ +static void copy_to_ztile(int *rectz, int size, int x1, int y1, int tile, char *r1) { - unsigned int len4, *rz; + int len4, *rz; + int x2, y2; + + x2= x1+tile; + y2= y1+tile; + if(x2>=size) x2= size-1; + if(y2>=size) y2= size-1; - if(x1>=R.rectx || x2>=R.rectx || y1>=R.recty || y2>=R.recty) return; - if(x1>x2 || y1>y2) return; + if(x1>=x2 || y1>=y2) return; - len4= 4*(x2- x1+1); - rz= R.rectz+R.rectx*y1+x1; - for(;y1<=y2;y1++) { - memcpy(r1,rz,len4); - rz+= R.rectx; + len4= 4*(x2- x1); + rz= rectz + size*y1 + x1; + for(; y1shb; - float panophi; - float temp, wsize, dist; - int *rz, *rz1, verg, verg1; + float wsize, dist; + int *rectz, *rz, *rz1, verg, verg1; unsigned long *ztile; - int a, x, y, minx, miny, byt1, byt2, tempmode; - short temprx,tempry, square; + int a, x, y, minx, miny, byt1, byt2, square; char *rc, *rcline, *ctile, *zt; - panophi = getPanoPhi(); - - /* store viewvars */ - temprx= R.rectx; tempry= R.recty; - tempmode= R.r.mode; - R.r.mode &= ~R_ORTHO; - R.rectx= R.recty= shb->size; - shb->jit= give_jitter_tab(shb->samp); - /* matrices and window: in R.winmat the transformation is being put, + /* matrices and window: in winmat the transformation is being put, transforming from observer view to lamp view, including lamp window matrix */ - wsize= shb->pixsize*(shb->size/2.0); - i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->far, shb->winmat); + i_window(-wsize, wsize, -wsize, wsize, shb->d, shb->clipend, shb->winmat); MTC_Mat4MulMat4(shb->persmat, shb->viewmat, shb->winmat); /* temp, will be restored */ - MTC_Mat4SwapMat4(shb->persmat, R.winmat); + MTC_Mat4SwapMat4(shb->persmat, re->winmat); /* zbuffering */ - if(R.rectz) MEM_freeN(R.rectz); - R.rectz= (unsigned int *)MEM_mallocN(sizeof(int)*shb->size*shb->size,"makeshadbuf"); - rcline= MEM_mallocN(256*4+sizeof(int),"makeshadbuf2"); + rectz= MEM_mallocN(sizeof(int)*shb->size*shb->size, "makeshadbuf"); + rcline= MEM_mallocN(256*4+sizeof(int), "makeshadbuf2"); - /* store: panorama rot */ - temp= panophi; - panophi= 0.0; - pushTempPanoPhi(0.0); - - /* pano interference here? */ - setzbufvlaggen(projectvert); - - popTempPanoPhi(); - panophi= temp; + project_renderdata(re, projectvert, 0, 0); - zbuffershad(lar); + zbuffer_shadow(re, lar, rectz, shb->size); square= lar->mode & LA_SQUARE; @@ -263,7 +177,7 @@ void makeshadowbuf(LampRen *lar) rz1= (&verg)+1; } else { - lrectreadRectz(x, y, MIN2(shb->size-1,x+15), MIN2(shb->size-1,y+15), rcline); + copy_to_ztile(rectz, shb->size, x, y, 16, rcline); rz1= (int *)rcline; verg= (*rz1 & 0xFFFFFF00); @@ -334,12 +248,10 @@ void makeshadowbuf(LampRen *lar) } MEM_freeN(rcline); - MEM_freeN(R.rectz); R.rectz= NULL; + MEM_freeN(rectz); - /* old globals back */ - R.rectx= temprx; R.recty= tempry; - R.r.mode= tempmode; - MTC_Mat4SwapMat4(shb->persmat, R.winmat); + /* old matrix back */ + MTC_Mat4SwapMat4(shb->persmat, re->winmat); /* printf("lampbuf %d\n", sizeoflampbuf(shb)); */ } @@ -443,7 +355,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, f int xs,ys, zs, bias; short a,num; - /* if(inp <= 0.0) return 1.0; */ + if(inp <= 0.0) return 0.0; /* rotate renderco en osaco */ siz= 0.5*(float)shb->size; @@ -455,7 +367,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, f xs1= siz*(1.0+co[0]/co[3]); ys1= siz*(1.0+co[1]/co[3]); - /* Clip for z: near and far clip values of the shadow buffer. We + /* Clip for z: clipsta and clipend clip values of the shadow buffer. We * can test for -1.0/1.0 because of the properties of the * coordinate transformations. */ fac= (co[2]/co[3]); diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 9ea621fdfce..fae58a1ec29 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1,17 +1,12 @@ -/* texture.c - * - * +/* * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,11 +20,9 @@ * 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): 2004-2006, Blender Foundation, full recode * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -37,10 +30,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MTC_matrixops.h" #include "BLI_blenlib.h" @@ -70,11 +59,19 @@ #include "BKE_key.h" #include "BKE_ipo.h" -#include "render.h" +#include "renderpipeline.h" +#include "render_types.h" #include "rendercore.h" #include "envmap.h" #include "texture.h" +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + + /* prototypes */ static int calcimanr(int cfra, Tex *tex); @@ -174,12 +171,6 @@ void init_render_texture(Tex *tex) } } } - if(tex->imaflag & (TEX_ANTIALI+TEX_ANTISCALE)) { - if(tex->ima && tex->ima->lastqualityima->ibuf) IMB_freeImBuf(tex->ima->ibuf); - tex->ima->ibuf= 0; - } - } if(tex->type==TEX_PLUGIN) { if(tex->plugin && tex->plugin->doit) { @@ -194,8 +185,8 @@ void init_render_texture(Tex *tex) tex->extend= TEX_CLIP; if(tex->env) { - if(R.flag & R_RENDERING) { - if(tex->env->stype==ENV_ANIM) RE_free_envmapdata(tex->env); + if(G.rendering) { + if(tex->env->stype==ENV_ANIM) BKE_free_envmapdata(tex->env); } } } @@ -218,27 +209,6 @@ void init_render_textures() /* ------------------------------------------------------------------------- */ -void end_render_texture(Tex *tex) -{ - - -} - -/* ------------------------------------------------------------------------- */ - -void end_render_textures() -{ - Tex *tex; - - tex= G.main->tex.first; - while(tex) { - if(tex->id.us) end_render_texture(tex); - tex= tex->id.next; - } - -} - -/* ------------------------------------------------------------------------- */ /* this allows colorbanded textures to control normals as well */ static void tex_normal_derivate(Tex *tex, TexResult *texres) @@ -1159,7 +1129,7 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float /* ************************************** */ -static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) { int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ @@ -1253,33 +1223,6 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, return retval; } -int multitex_ext(Tex *tex, float *texvec, float *tin, float *tr, float *tg, float *tb, float *ta) -{ - TexResult texr; - float dummy[3]; - int retval; - - /* does not return Tin, hackish... */ - if(tex->type==TEX_STUCCI) { - texr.nor= dummy; - dummy[0]= 1.0; - dummy[1]= dummy[2]= 0.0; - } - else texr.nor= NULL; - - retval= multitex(tex, texvec, NULL, NULL, 0, &texr); - if(tex->type==TEX_STUCCI) { - *tin= 0.5 + 0.7*texr.nor[0]; - CLAMP(*tin, 0.0, 1.0); - } - else *tin= texr.tin; - *tr= texr.tr; - *tg= texr.tg; - *tb= texr.tb; - *ta= texr.ta; - return retval; -} - /* ------------------------------------------------------------------------- */ /* in = destination, tex = texture, out = previous color */ @@ -1309,9 +1252,9 @@ static void texture_rgb_blend(float *in, float *tex, float *out, float fact, flo case MTEX_SCREEN: fact*= facg; facm= 1.0-facg; - in[0]= 1.0-(facm+fact*(1.0-tex[0]))*(1.0-out[0]); - in[1]= 1.0-(facm+fact*(1.0-tex[1]))*(1.0-out[1]); - in[2]= 1.0-(facm+fact*(1.0-tex[2]))*(1.0-out[2]); + in[0]= 1.0 - (facm+fact*(1.0-tex[0])) * (1.0-out[0]); + in[1]= 1.0 - (facm+fact*(1.0-tex[1])) * (1.0-out[1]); + in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]); break; case MTEX_SUB: @@ -1482,6 +1425,9 @@ void do_material_tex(ShadeInput *shi) else if(mtex->texco==TEXCO_NORM) { co= shi->orn; dx= shi->dxno; dy= shi->dyno; } + else if(mtex->texco==TEXCO_TANGENT) { + co= shi->tang; dx= shi->dxno; dy= shi->dyno; + } else if(mtex->texco==TEXCO_GLOB) { co= shi->gl; dx= shi->dxco; dy= shi->dyco; } @@ -1500,6 +1446,15 @@ void do_material_tex(ShadeInput *shi) dy[0]= shi->dystrand; dy[1]= dy[2]= 0.0f; } + else if(mtex->texco==TEXCO_STRESS) { + co= tempvec; dx= dxt; dy= dyt; + co[0]= shi->stress; + co[1]= co[2]= 0.0f; + dx[0]= 0.0f; + dx[1]= dx[2]= 0.0f; + dy[0]= 0.0f; + dy[1]= dy[2]= 0.0f; + } else continue; // can happen when texco defines disappear and it renders old files /* de pointer defines if bumping happens */ @@ -1720,23 +1675,37 @@ void do_material_tex(ShadeInput *shi) fact= Tnor*tex->norfac; if(fact>1.0) fact= 1.0; else if(fact<-1.0) fact= -1.0; facm= 1.0- fact; - shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0]; - shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1]; - shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2]; + if(shi->mat->mode & MA_TANGENT_V) { + shi->tang[0]= facm*shi->tang[0] + fact*texres.nor[0]; + shi->tang[1]= facm*shi->tang[1] + fact*texres.nor[1]; + shi->tang[2]= facm*shi->tang[2] + fact*texres.nor[2]; + } + else { + shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0]; + shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1]; + shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2]; + } } else { - float nor[3], dot; + if(shi->mat->mode & MA_TANGENT_V) { + shi->tang[0]+= Tnor*tex->norfac*texres.nor[0]; + shi->tang[1]+= Tnor*tex->norfac*texres.nor[1]; + shi->tang[2]+= Tnor*tex->norfac*texres.nor[2]; + } + else { + float nor[3], dot; - /* prevent bump to become negative normal */ - nor[0]= Tnor*tex->norfac*texres.nor[0]; - nor[1]= Tnor*tex->norfac*texres.nor[1]; - nor[2]= Tnor*tex->norfac*texres.nor[2]; - - dot= 0.5f + 0.5f*INPR(nor, shi->vn); - - shi->vn[0]+= dot*nor[0]; - shi->vn[1]+= dot*nor[1]; - shi->vn[2]+= dot*nor[2]; + /* prevent bump to become negative normal */ + nor[0]= Tnor*tex->norfac*texres.nor[0]; + nor[1]= Tnor*tex->norfac*texres.nor[1]; + nor[2]= Tnor*tex->norfac*texres.nor[2]; + + dot= 0.5f + 0.5f*INPR(nor, shi->vn); + + shi->vn[0]+= dot*nor[0]; + shi->vn[1]+= dot*nor[1]; + shi->vn[2]+= dot*nor[2]; + } } Normalise(shi->vn); @@ -1852,6 +1821,13 @@ void do_material_tex(ShadeInput *shi) 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; @@ -1992,7 +1968,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) /* ------------------------------------------------------------------------- */ /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */ -void do_sky_tex(float *lo, float *dxyview, float *hor, float *zen, float *blend) +void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend) { MTex *mtex; TexResult texres; @@ -2060,6 +2036,22 @@ void do_sky_tex(float *lo, float *dxyview, float *hor, float *zen, float *blend) MTC_Mat4MulVecfl(mtex->object->imat, tempvec); co= tempvec; } + break; + + case TEXCO_GLOB: + if(rco) { + VECCOPY(tempvec, rco); + MTC_Mat4MulVecfl(R.viewinv, tempvec); + co= tempvec; + } + else + co= lo; + +// VECCOPY(shi->dxgl, shi->dxco); +// MTC_Mat3MulVecfl(R.imat, shi->dxco); +// VECCOPY(shi->dygl, shi->dyco); +// MTC_Mat3MulVecfl(R.imat, shi->dyco); + break; } /* placement */ @@ -2378,7 +2370,7 @@ void render_realtime_texture(ShadeInput *shi) tex2.type= TEX_IMAGE; } - if(((int)(shi->ys+0.5)) & 1) tex= &tex1; else tex= &tex2; // threadsafe + if(shi->ys & 1) tex= &tex1; else tex= &tex2; // threadsafe ima = shi->vlr->tface->tpage; if(ima) { diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c deleted file mode 100644 index 968f3e35e73..00000000000 --- a/source/blender/render/intern/source/vanillaRenderPipe.c +++ /dev/null @@ -1,1642 +0,0 @@ -/** - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * vanillaRenderPipe.c - * - * 28-06-2000 nzc - * - * $Id$ - * - */ - -/* - The render pipe - --------------- - - The overall results of the render pass should end up in R.rectot. This - buffer already exists, and although its contents may change, its location - may not. A lot of other routines depend on it! - -*/ - -/* global includes */ -#include -#include /* INT_MIN,MAX are used here */ -#include -#include "MTC_vectorops.h" -#include "MTC_matrixops.h" -#include "MEM_guardedalloc.h" - -#include "DNA_camera_types.h" -#include "DNA_object_types.h" -#include "BKE_global.h" -#include "BKE_utildefines.h" - -#include "BLI_arithb.h" -#include "BLI_rand.h" - -/* local includes (from the render module) */ -#include "RE_callbacks.h" -#include "render.h" /* all kinds of stuff */ -#include "zbuf.h" /* for vergzvlak, zbufclip, zbufclipwire */ -#include "edgeRender.h" /* all edge rendering stuff */ -#include "pixelshading.h" /* painting the pixels */ -#include "rendercore.h" - -/* general calculus and data manipulation, also local */ -#include "gammaCorrectionTables.h" -#include "jitter.h" -#include "pixelblending.h" -#include "zbufferdatastruct.h" - -/* own includes */ -#include "vanillaRenderPipe.h" - -#include "SDL_thread.h" - -/* threshold for alpha */ -#define RE_FULL_ALPHA_FLOAT 0.9998 - -/* ------------------------------------------------------------------------- */ -/* Debug defines: disable all for production level code. */ -/* These variables control faking of rendered colours, extra tracing, */ -/* extra error checking and such. */ -/* ------------------------------------------------------------------------- */ - -/* if defined: _very_ explicit tracing and checking enabled */ -/* #define RE_FULL_SAFETY */ -/* if defined: use 'simple' alpha thresholding on oversampling */ -/* #define RE_SIMPLE_ALPHA_THRESHOLD */ - -/* ------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------- */ - -/* External : -------------------------------------------------------------- */ - -extern float centLut[16]; /* Lookup for jitter offsets. */ -extern unsigned int Zsample; /* Nr. of the currently active oversample. This */ - /* counter must be set explicitly by the */ - /* function that builds the z-buffer. */ - /* The buffer-filling functions use it. */ -extern float Zjitx,Zjity; /* The x,y values for jitter offset */ - -extern float Zmulx, Zmuly; /* Some kind of scale? */ - -extern char cmask[256]; /* When a pixel is supersampled, we must */ -extern char *centmask; /* compute its colour on a point _on_ the face. */ - /* These two are used to compute an offset to */ - /* guarantee we use valid coordinates. */ - -extern RE_APixstrExt *APixbufExt;/*Zbuffer: linked list of face, halo indices*/ - -/* Globals : --------------------------------------------------------------- */ - /* we use 2 x three lines, for gaussian sample */ -RE_COLBUFTYPE *AColourBuffer0; /* Buffer for colours of 1 line of pixels */ -RE_COLBUFTYPE *AColourBuffer1; /* Buffer for colours of 1 line of pixels */ -RE_COLBUFTYPE *AColourBuffer2; /* Buffer for colours of 1 line of pixels */ -RE_COLBUFTYPE *AColourBuffer1a; /* Buffer for colours of 1 line of pixels */ -RE_COLBUFTYPE *AColourBuffer2a; /* Buffer for colours of 1 line of pixels */ -RE_COLBUFTYPE *AColourBuffer3; /* Buffer for colours of 1 line of pixels */ - -static int Aminy; /* y value of first line in the accu buffer */ -static int Amaxy; /* y value of last line in the accu buffer */ - /* -also used to clip when zbuffering */ - -/* Buffer width refers to the size of the buffers we build. Image size is */ -/* the same as R.rectx, R.recty. */ -static int zBufferWidth; /* special width because zbuffer needs to be */ - /* wider */ - -static int Azvoordeel; /* A small offset for transparent rendering. */ -int alphaLUT[32]; /* alpha lookuptable, for oversampling */ - /* Its function has been superceded because */ - /* pixels are always integrated. This */ - /* performs the same normalization. */ -int osaNr; /* The oversample number. I keep it */ - /* separately here, because I treat no OSA */ - /* as if it were osa=1. */ - -/* ------------------------------------------------------------------------- */ - -/** -* Z buffer initializer, for new pipeline. - *
  • - * AColourBuffer : colour buffer for one line - * APixbufExt : pixel data buffer for one line, depth RE_ZBUFLEN - *
  • - */ -static void initRenderBuffers(int bwidth) -{ - /* bwidth+4, as in rendercore.c. I think it's too much, but yah (ton) */ - AColourBuffer0 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - AColourBuffer1 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - AColourBuffer2 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - AColourBuffer1a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - AColourBuffer2a = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - AColourBuffer3 = MEM_callocN(4 * sizeof(RE_COLBUFTYPE) * (bwidth+4), "Acolrow"); - - /* The +1 is needed because the fill-functions use a +1 offset when */ - /* filling in pixels. Mind that also the buffer-clearing function needs */ - /* this offset (done in calcZBufLine). */ - /* The offset is wrong: it shouldn't be there. I need to fix this still. */ - zBufferWidth = bwidth + 1; - initZbuffer(bwidth + 1); - - Aminy= -1000; /* indices of lines in the z buffer: no lines buffered */ - Amaxy= -1000; - - -} - -/* ------------------------------------------------------------------------- */ -/** - * Z buffer destructor, frees stuff from initZBuffers(). - */ - -static void freeRenderBuffers(void) { - if (AColourBuffer0) MEM_freeN(AColourBuffer0); - if (AColourBuffer1) MEM_freeN(AColourBuffer1); - if (AColourBuffer2) MEM_freeN(AColourBuffer2); - if (AColourBuffer1a) MEM_freeN(AColourBuffer1a); - if (AColourBuffer2a) MEM_freeN(AColourBuffer2a); - if (AColourBuffer3) MEM_freeN(AColourBuffer3); - freeZbuffer(); -} -/* ------------------------------------------------------------------------- */ - -/** - * New fill function for z buffer, for edge-only rendering. - */ -static void zBufferFillFace(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) -{ - /* Coordinates of the vertices are specified in ZCS */ - VlakRen *vlr; - int apteller, apoffsetteller; - double z0; /* used as temp var*/ - double xx1; - double zxd,zyd,zy0, tmp; - float *minv,*maxv,*midv; - register int zverg,zvlak,x; - int my0,my2,sn1,sn2,rectx,zd; - int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask; - int obtype; - /* These used to be doubles. We may want to change them back if the */ - /* loss of accuracy proves to be a problem? There does not seem to be */ - /* any performance issues here, so I'll just keep the doubles. */ - /* float vec0[3], vec1[3], vec2[3]; */ - double vec0[3], vec1[3], vec2[3]; - - vlr= RE_findOrAddVlak( (zvlnr-1) & 0x7FFFFF); - if(vlr->mat->mode & MA_ZTRA) obtype= RE_POLY; - else obtype= RE_POLY|RE_SOLID; - - /* MIN MAX */ - /* sort vertices for min mid max y value */ - if(v1[1] Amaxy)) return; - - if(my02.0/65536.0) { - z0= (maxv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); - xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx0= 0; - xs0= 65536.0*(MIN2(minv[0],maxv[0])); - } - /* EDGES : THE TOP ONE */ - xx1= maxv[1]-midv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-midv[0])/xx1; - - tmp= (-65536.0*z0); - dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); - xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx1= 0; - xs1= 65536.0*(MIN2(midv[0],maxv[0])); - } - /* EDGES : THE BOTTOM ONE */ - xx1= midv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (midv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); - xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx2= 0; - xs2= 65536.0*(MIN2(minv[0],midv[0])); - } - - /* ZBUF DX DY */ - /* xyz_1 = v_1 - v_2 */ - MTC_diff3DFF(vec1, v1, v2); - /* xyz_2 = v_2 - v_3 */ - MTC_diff3DFF(vec2, v2, v3); - /* xyz_0 = xyz_1 cross xyz_2 */ - MTC_cross3Double(vec0, vec1, vec2); - - /* cross product of two of the sides is 0 => this face is too small */ - if(vec0[2]==0.0) return; - - if(midv[1] == maxv[1]) omsl= my2; - if(omsl < Aminy) omsl= Aminy-1; /* make sure it takes the first loop entirely */ - - while (my2 > Amaxy) { /* my2 can be larger */ - xs0+=dx0; - if (my2<=omsl) { - xs2+= dx2; - } - else{ - xs1+= dx1; - } - my2--; - } - - xx1= (vec0[0]*v1[0]+vec0[1]*v1[1])/vec0[2]+v1[2]; - - zxd= -vec0[0]/vec0[2]; - zyd= -vec0[1]/vec0[2]; - zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); - - /* start-ofset in rect */ - /* rectx= R.rectx; */ - /* I suspect this var needs very careful setting... When edge rendering */ - /* is on, this is strange */ - rectx = zBufferWidth; - apoffsetteller = rectx*(my2-Aminy); - - mask= 1<dx1) { - MTC_swapInt(&xs0, &xs1); - MTC_swapInt(&dx0, &dx1); - xs3= 1; /* flag */ - - } - - for(y=my2;y>omsl;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs1>>16; - xs1+= dx1; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - apteller = apoffsetteller + sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - insertObject(apteller, zvlnr, obtype, zverg, mask); - zverg+= zd; - apteller++; - x--; - } - zy0-= zyd; - apoffsetteller -= rectx; - } - - if(xs3) { - xs0= xs1; - dx0= dx1; - } - if(xs0>xs2) { - xs3= xs0; - xs0= xs2; - xs2= xs3; - xs3= dx0; - dx0= dx2; - dx2= xs3; - } - - for(; y>=my0; y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs2>>16; - xs2+= dx2; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - apteller = apoffsetteller + sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - insertObject(apteller, zvlnr, obtype, zverg, mask); - zverg+= zd; - apteller++; - x--; - } - - zy0-=zyd; - apoffsetteller -= rectx; - } -} -/* ------------------------------------------------------------------------- */ - -static void zBufferFillEdge(int zvlnr, float *vec1, float *vec2) -{ - int apteller; - int start, end, x, y, oldx, oldy, ofs; - int dz, vergz, mask, maxtest=0; - float dx, dy; - float v1[3], v2[3]; - - dx= vec2[0]-vec1[0]; - dy= vec2[1]-vec1[1]; - - if(fabs(dx) > fabs(dy)) { - - /* all lines from left to right */ - if(vec1[0]= zBufferWidth) end = zBufferWidth - 1; - - oldy= floor(v1[1]); - dy/= dx; - - vergz= v1[2]; - vergz-= Azvoordeel; - dz= (v2[2]-v1[2])/dx; - if(vergz>0x70000000 && dz>0) maxtest= 1; // prevent overflow - - apteller = zBufferWidth*(oldy-Aminy) +start; - mask = 1<=0 && y>=Aminy && y<=Amaxy) { - insertObject(apteller, zvlnr, RE_POLY, vergz, mask); - } - - v1[1]+= dy; - vergz+= dz; - if(maxtest && vergz<0) vergz= 0x7FFFFFF0; - } - } - else { - - /* all lines from top to bottom */ - if(vec1[1]Amaxy || endAmaxy) end= Amaxy; - - oldx= floor(v1[0]); - dx/= dy; - - vergz= v1[2]; - vergz-= Azvoordeel; - dz= (v2[2]-v1[2])/dy; - if(vergz>0x70000000 && dz>0) maxtest= 1; // prevent overflow - - apteller = zBufferWidth*(start-Aminy) +oldx; - - mask= 1<=0 && y>=Aminy && (x < zBufferWidth)) { - insertObject(apteller, zvlnr, RE_POLY, vergz, mask); - } - - v1[0]+= dx; - vergz+= dz; - if(maxtest && vergz<0) vergz= 0x7FFFFFF0; - } - } -} -/* ------------------------------------------------------------------------- */ - -/** - * Count and sort the list behind ap into buf. Sorts on min. distance. - * Low index <=> high z - */ -static int countAndSortPixelFaces(int zrow[][RE_PIXELFIELDSIZE], - RE_APixstrExt *ap) -{ - int totvlak; /* face counter */ - int i; /* generic counter */ - - totvlak= 0; - while(ap) { - for(i=0; i<4; i++) { - if(ap->t[i]) { - zrow[totvlak][0] = ap->zmin[i]; - zrow[totvlak][1] = ap->p[i]; - zrow[totvlak][2] = ap->mask[i]; - zrow[totvlak][3] = ap->t[i]; - zrow[totvlak][4] = ap->zmax[i]; - totvlak++; - if(totvlak > (RE_MAX_FACES_PER_PIXEL - 1)) - { - totvlak = (RE_MAX_FACES_PER_PIXEL - 1); - } - } else break; - }; - ap= ap->next; - } - - if(totvlak==2) { /* Sort faces ----------------------------- */ - if(zrow[0][0] < zrow[1][0]) { - i= zrow[0][0]; zrow[0][0]= zrow[1][0]; zrow[1][0]= i; - i= zrow[0][1]; zrow[0][1]= zrow[1][1]; zrow[1][1]= i; - i= zrow[0][2]; zrow[0][2]= zrow[1][2]; zrow[1][2]= i; - i= zrow[0][3]; zrow[0][3]= zrow[1][3]; zrow[1][3]= i; - i= zrow[0][4]; zrow[0][4]= zrow[1][4]; zrow[1][4]= i; - } /* else: two faces, and ordering is ok */ - } else if (totvlak != 1) qsort(zrow, totvlak, - sizeof(int)*RE_PIXELFIELDSIZE, vergzvlak); - return totvlak; -} - -/* ------------------------------------------------------------------------- */ -/* Oversampler v3 - check CVS for older versions */ -/* */ -/* In this version, I have split up the rendering into several parts, so I */ -/* can generate better profiles. */ -/* */ -/* - multiple blend functions ? */ -/* - x-rays? */ -/* - volumetric stuff ? */ -/* - maybe the oversampling should move to the shading part */ -/* */ -/* ------------------------------------------------------------------------- */ - -/* These variables describe the buffers needed for the oversampling. */ -/* 1. A bit vector with flags to indicate which pixels have received colour. */ -static int VR_covered = 0; -/* 2. The local vector collector, for resolving conflicts only. */ -static int VR_cbuf[RE_MAX_FACES_PER_PIXEL][2]; - -/** - * Analyze the z-buffer, and pre-sample the colours. - */ -static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector, - struct RE_faceField* stack, int ptr, - int totvlak, float x, float y, int osaNr) -{ - VlakRen *vlr= NULL; - float xs = 0.0; - float ys = 0.0; /* coordinates for the render-spot */ - - float alphathreshold[RE_MAX_OSA_COUNT]; - float colbuf[4]; - int inconflict = 0; - int saturationthreshold = 0; - int saturated = 0; - int i = 0; - int Ccount = 0; - int Cthresh = 0; - int save_totvlak = totvlak; - int fullsubpixelflags = 0; - int full_osa; - - VR_covered = 0; - for(i = 0; i < osaNr; i++) alphathreshold[i] = 0.0; - saturationthreshold = ( (1< 0) ) { - totvlak--; - - full_osa= 0; - if(R.osa && (zrow[totvlak][RE_TYPE] & RE_POLY)) { - vlr= RE_findOrAddVlak((zrow[totvlak][RE_INDEX]-1) & 0x7FFFFF); - if(vlr->flag & R_FULL_OSA) full_osa= 1; - } - - if(full_osa) { - float div=0.0, accol[4]={0.0, 0.0, 0.0, 0.0}; - int a, mask= zrow[totvlak][RE_MASK]; - - for(a=0; a> 4]; - } - else { - xs= (float)x; - ys= (float)y; - } - - /* stack face ----------- */ - stack[ptr].mask = zrow[totvlak][RE_MASK]; - stack[ptr].data = renderPixel(collector, xs, ys, zrow[totvlak], stack[ptr].mask); - } - stack[ptr].faceType = zrow[totvlak][RE_TYPE]; - cpFloatColV(collector, stack[ptr].colour); - - /* This is done so that spothalos are properly overlayed on halos */ - /* maybe we need to check the colour here... */ - if(zrow[totvlak][RE_TYPE] & RE_POLY) VR_covered |= zrow[totvlak][RE_MASK]; - - /* calculate conflict parameters: ---------------------------------- */ - if( zrow[totvlak][RE_ZMIN] < Cthresh ) { - inconflict = 1; - /* Prevent from switching on bad data. This may be done more */ - /* efficiently later on. It is _quite_ important. */ - if (totvlak == save_totvlak - 1) Ccount = 0; - else if(Ccount == 0) Ccount = 2; - else Ccount++; - stack[ptr].conflictCount = Ccount; - if (zrow[totvlak][RE_ZMAX] > Cthresh) - Cthresh = zrow[totvlak][RE_ZMAX]; - } else { - Cthresh = zrow[totvlak][RE_ZMAX]; - Ccount = 0; - stack[ptr].conflictCount = 0; - if (totvlak > 0 ) - inconflict = (zrow[totvlak-1][RE_ZMIN] < Cthresh); - else inconflict = 0; - } - - ptr++; - - /* alpha threshold ------------------------------------------------- */ - /* There are currently two ways of blending: alpha-over, and add. */ - /* Add-blending does strange things, in the sense that alpha is */ - /* simply added, and colour is sort of alpha-over blended. Using the */ - /* same thresholding relation seems to work ok. For less than unity */ - /* add factor, the alpha threshold may rise faster, but currently we */ - /* do not check for this factor. */ - for(i = 0; i < osaNr; i++) { - if ( zrow[totvlak][RE_MASK] & (1< RE_FULL_ALPHA_FLOAT) - fullsubpixelflags |= (1<= saturationthreshold); - - } /* done stacking ----------------------------------------------------- */ - - /* - STACK_SKY Sometimes, a sky pixel is needed. Since there are - some issues with mist/ ztra/ env, I always put the sky here. - */ -/* if (!saturated) { */ - totvlak--; - - xs= (float)x; - ys= (float)y; - - /* code identical for rendering empty sky pixel */ - renderSkyPixelFloat(collector, xs, ys); - cpFloatColV(collector, colbuf); - - if(R.flag & R_LAMPHALO) { - renderSpotHaloPixel(x, y, collector); - addAlphaOverFloat(colbuf, collector); - } - - stack[ptr].faceType = RE_SKY; - cpFloatColV(colbuf, stack[ptr].colour); - stack[ptr].data = NULL; - stack[ptr].mask = 0xFFFF; - stack[ptr].conflictCount = 0; - ptr++; -/* } */ - - /* Index of the top of the stack */ - return ptr; -} - -/* ------------------------------------------------------------------------- */ - -/** - * Calculate the view depth to this object on this location, with - * the current view parameters in R. - */ -static int calcDepth(float x, float y, void *data, int type) -{ - float view[3]; - - if (type & RE_POLY) { - VlakRen* vlr = (VlakRen*) data; - VertRen* v1; - float dface, div, zco, hoco_z, hoco_w; - int zbuf_co; - - v1 = vlr->v1; - - /* vertex dot face normal: WCS */ - dface= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; - - /* jitter has been added to x, y ! */ - /* view vector view: screen coords */ - view[0]= (x+(R.xstart)+0.5); - - if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor; - else view[1]= (y + R.ystart + 1.0)*R.ycor; - } - else view[1]= (y + R.ystart + 0.5)*R.ycor; - - - /* for pano, another rotation in the xz plane is needed.... */ - - /* this is ok, in WCS */ - view[2]= -R.viewfac; /* distance to viewplane */ - - /* calculate zcoord */ - if(R.r.mode & R_ORTHO) { - /* x and y 3d coordinate can be derived from pixel coord and winmat */ - float fx= 2.0/(R.rectx*R.winmat[0][0]); - float fy= 2.0/(R.recty*R.winmat[1][1]); - - fx= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0]; - fy= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1]; - - /* using a*x + b*y + c*z = d equation, (a b c) is normal */ - zco= (dface - vlr->n[0]*fx - vlr->n[1]*fy)/vlr->n[2]; - - } - else { - /* face normal dot view vector: but how can this work? (nzc) */ - div = MTC_dot3Float(vlr->n, view); - if (div!=0.0) zco = (view[2]*dface)/div; - else zco = 0.0; - } - - /* same as in zbuf.c */ - hoco_z = zco*R.winmat[2][2] + R.winmat[3][2]; - hoco_w = zco*R.winmat[2][3] + R.winmat[3][3]; - - if(hoco_w!=0.0) zbuf_co = 0x7FFFFFFF*(hoco_z/hoco_w); - else zbuf_co= 0x7FFFFFFF; - - return zbuf_co; /* z component of R.co */ - } else if (type & RE_HALO) { - HaloRen* har = (HaloRen*) data; - return har->zBufDist; - } - return 0; -} - -/** - * Blend source over dest, and leave result in dest. 1 pixel. - */ -static void blendOverFloat(int type, float* dest, float* source, void* data) -{ - - if (type & RE_POLY) { - VlakRen *ver = (VlakRen*) data; - if ((ver->mat != NULL) && (ver->mat->add > RE_FACE_ADD_THRESHOLD)) { - char addf = (char) (ver->mat->add * 255.0); - addalphaAddfacFloat(dest, source, addf); - } - else - addAlphaOverFloat(dest, source); - } else if (type & RE_HALO) { - HaloRen *har= (HaloRen*) data; - addalphaAddfacFloat(dest, source, har->add); - } else if (type & RE_SKY) { - addAlphaOverFloat(dest, source); - } - -} - - -/** - * New approach: sample substacks. Each substack is first copied into - * a stack buffer, and then blended down. - * */ -static void integratePerSubStack(float *sampcol, struct RE_faceField* stack, - int ptr, float x, float y, int osaNr) -{ - int i = 0; - int j = 0; - int k = 0; - int l = 0; - int filterMask = 0; - /* next step would be to improve on the substack, I guess */ - int subStack[RE_MAX_FACES_PER_PIXEL + 1]; - float colSubStack[4 * (RE_MAX_FACES_PER_PIXEL + 1)]; - int subStackPtr = 0; - int subStackSize = 0; - float xs, ys; - - - while (i < osaNr) { - xs = x + jit[i][0]; - ys = y + jit[i][1]; - - /* - * 1. Copy all relevant faces. Mind that stack is built from - * low index = low z to high index =high z. The sub-stack is - * exactly the other way around! (low index = high z) - */ - filterMask = (1 << i); - subStackPtr = 0; - j = ptr - 1; /* the topmost valid face */ - while (j >= 0) { - if (stack[j].conflictCount) { - /* Conflict: we sort the faces for distance right - * away. We could adapt conflict count, and adjust the - * stack later on, but that's really doing too much, - * too complicated. This is just fine. - * */ - k = 0; - l = 0; - /* check whether the face intersects, and if so, - * stores depth */ - while (k < stack[j].conflictCount) { - if (stack[j - k].mask & filterMask) { - VR_cbuf[l][0] = calcDepth(xs, ys, - stack[j - k].data, - stack[j - k].faceType); - VR_cbuf[l][1] = j - k; - l++; - } - k++; - } - /* VR_cbuf now contains l pairs (distance, stackindex) */ - qsort(VR_cbuf, l, sizeof(int)*2, vergzvlak); - /* - * Now we put the sorted indices on the - * substack. qsort delivers low index = low z, which - * is the right wrong order for the substack */ - k = 0; - while (k < l) { - subStack[subStackPtr] = VR_cbuf[k][1]; - cpFloatColV(stack[VR_cbuf[k][1]].colour, &colSubStack[4*subStackPtr]); - subStackPtr++; - k++; - } - - j -= stack[j].conflictCount; - } else { - /* no conflict */ - if (stack[j].mask & filterMask) { - subStack[subStackPtr] = j; - cpFloatColV(stack[j].colour, &colSubStack[4*subStackPtr]); - subStackPtr++; - } - j--; - } - } - subStackSize = subStackPtr; - - /* 2. Operations on the faces can go here for now. I might - * want to mix this code with the blending. Currently, I only - * handle env/ztra faces. It's a dirty patch now...*/ - subStackPtr = subStackSize - 1; - while (subStackPtr >= 0) { - /* we can make a general meachanism here for operations */ - if (stack[subStack[subStackPtr]].faceType & RE_POLY){ - VlakRen* vlr = (VlakRen*) stack[subStack[subStackPtr]].data; - if (vlr->mat) { - /* ENV faces */ - if (vlr->mat->mode & MA_ENV) { - int m; - colSubStack[4*subStackPtr] = 0.0; - colSubStack[(4*subStackPtr) + 1] = 0.0; - colSubStack[(4*subStackPtr) + 2] = 0.0; - colSubStack[(4*subStackPtr) + 3] = 0.0; - m = subStackPtr - 1; - while (m >= 0) { - if (stack[subStack[m]].faceType != RE_SKY) { - colSubStack[4*m] = 0.0; - colSubStack[(4*m) + 1] = 0.0; - colSubStack[(4*m) + 2] = 0.0; - colSubStack[(4*m) + 3] = 0.0; - } - m--; - } - } - /* ZTRA faces */ - else if (!(vlr->mat->mode & MA_ZTRA)) { - int m; - m = subStackPtr - 1; - while (m >= 0) { - if (stack[subStack[m]].faceType != RE_SKY) { - colSubStack[4*m] = 0.0; - colSubStack[(4*m) + 1] = 0.0; - colSubStack[(4*m) + 2] = 0.0; - colSubStack[(4*m) + 3] = 0.0; - } - m--; - } - } - } - } - subStackPtr--; - } - - /* 3. blend down */ - subStackPtr = 0; - while( subStackPtr < subStackSize ) { - blendOverFloat(stack[subStack[subStackPtr]].faceType, /* type */ - sampcol + (4 * i), /* dest */ - &colSubStack[4 * subStackPtr], - stack[subStack[subStackPtr]].data); /* data */ - subStackPtr++; - } - - i++; - } -} - - - -/* ------------------------------------------------------------------------- */ -/* Rendering: per line */ -/* */ -/* For each pixel in this line, we render as follows: */ -/* a. Count the number of objects buffered for this pixel, and sort on z */ -/* ------- Result is left in zrow */ -/* b. Shade the pixel: */ -/* 1. From front to back: calculate the colour for this object */ -/* 2. Blend this colour in with the already calculated colour */ -/* Repeat 1. and 2. until no faces remain. */ -/* For each pixel, a face is only rendered once, even if it is */ -/* jittered. All subpixels get the colour of the weighted centre */ -/* of the jitter-positions this face covers. */ -/* ------- Result is left in sampcol[] */ -/* c. Copy the result to the colour buffer */ -/* d. Do gamma-corrected blending */ -/* */ -/* zrow may need some clarification: */ -/* 0 - min. distance */ -/* 1 - face/halo index */ -/* 2 - masks */ -/* 3 - type RE_POLY or RE_HALO */ -/* 4 - max. distance */ -/* It is used to store copies of RE_APixstrExt records. These are sorted for */ -/* distance, and then used for rendering pixels. zrow might be replaced by */ -/* an RE_APixstrExt* array */ -/* - redo the numbering to something more logical */ - - -/* threadsafe global arrays, too large for stack */ -typedef struct zbufline { - int zrow[RE_MAX_FACES_PER_PIXEL][RE_PIXELFIELDSIZE]; - struct RE_faceField osastack[RE_MAX_FACES_PER_PIXEL + 1]; -} zbufline; - -static zbufline zb1, zb2; - -static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2, RE_COLBUFTYPE *colbuf3) -{ - RE_APixstrExt *ap; /* iterator for the face-lists */ - RE_COLBUFTYPE collector[4]; - RE_COLBUFTYPE sampcol[RE_MAX_OSA_COUNT * 4]; - RE_COLBUFTYPE *j = NULL; /* generic pixel pointer */ - int apteller; - int x; /* pixel counter */ - int i; /* yet another counter */ - int stackDepth; /* faces-behind-this-pixel counter */ - int osastack_ptr; /* Points to the lowest empty field. The indexed */ - zbufline *zbl; - - /* thread safe row buffers */ - if(y & 1) zbl= &zb1; - else zbl= &zb2; - - /* Prepare iterators */ - ap = APixbufExt + (zBufferWidth * (y - Aminy)); - apteller = (zBufferWidth * (y - Aminy)); - - /* Rendering: give the right colour to this pixel (shade it) */ - for( x = 0; x < R.rectx; x++, ap++, colbuf1+=4, colbuf2+=4, colbuf3+=4) { - if(ap->t[0]) { - /* reset sample collector */ - j = sampcol; - for(i = 0; i < osaNr; i++, j+=4) { - j[0] = 0.0f; j[1] = 0.0f; - j[2] = 0.0f; j[3] = 0.0f; - }; - - /* a. count and sort number of faces */ - stackDepth = countAndSortPixelFaces( zbl->zrow, ap); - - /* b,c. oversample all subpixels, then integrate */ - osastack_ptr = 0; - osastack_ptr = composeStack(zbl->zrow, collector, zbl->osastack, osastack_ptr, - stackDepth, x, y, osaNr); - integratePerSubStack(sampcol, zbl->osastack, osastack_ptr, x, y, osaNr); - - /* d. Gamma corrected blending and Gaussian */ - sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr); - - } else { - /* Remember to do things back-to-front! */ - - /* This is a bit dirty. Depending on sky-mode, the pixel is */ - /* blended in differently. */ - renderSkyPixelFloat(collector, x, y); - - j = sampcol; - for(i = 0; i < osaNr; i++, j+=4) { - j[0]= collector[0]; j[1]= collector[1]; - j[2]= collector[2]; j[3]= collector[3]; - } - - /* Spothalos are part of the normal pixelshader, so for covered */ - /* pixels they are handled ok. They are 'normally' alpha blended */ - /* onto the existing colour in the collector. */ - if(R.flag & R_LAMPHALO) { - renderSpotHaloPixel(x, y, collector); - if(do_gamma) { - collector[0]= gammaCorrect(collector[0]); - collector[1]= gammaCorrect(collector[1]); - collector[2]= gammaCorrect(collector[2]); - } - - j = sampcol; - for(i = 0; i < osaNr; i++, j+=4) { - addAlphaOverFloat(j, collector); - } - } - - sampleFloatColV2FloatColVFilter(sampcol, colbuf1, colbuf2, colbuf3, osaNr); - - } - } -} - - -/** - * Fills in distances of faces in the z buffer. - * - * Halo z buffering ---------------------------------------------- - * - * A halo is treated here as a billboard: no z-extension, always - * oriented perpendicular to the viewer. The rest of the z-buffer - * stores face-numbers first, then calculates colours as the - * final image is rendered. We'll use the same approach here, - * which differs from the original method (which was add halos per - * scan line). This means that the z-buffer now also needs to - * store info about what sort of 'thing' the index refers to. - * - * Halo extension: - * h.maxy --------- - * | h.xs + h.rad - * | h.xs - * | h.xs - h.rad - * h.miny --------- - * - * These coordinates must be clipped to picture size. - * I'm not quite certain about halo numbering. - * - * Halos and jittering ------------------------------------------- - * - * Halos were not jittered previously. Now they are. I wonder - * whether this may have some adverse effects here. - - * @return 1 for succes, 0 if the operation was interrupted. - */ - -/* ------------------------------------------------------------------------- */ -/* Transparent faces and the 'Azvoordeel' */ -/* A transparent face can get a z-offset, which is a */ -/* way of pretending the face is a bit closer than it */ -/* actually is. This is used in animations, when faces */ -/* that are used to glue on animated characters, items, */ -/* et. need their shadows to be drawn on top of the */ -/* objects they stand on. The Azvoordeel is added to */ -/* the calculated z-coordinate in the buffer-fill */ -/* procedures. */ - -/* static int RE_treat_face_as_opaque; */ - -static int zBufferAllFaces(void) -{ - VlakRen *vlr=NULL; - unsigned int zvlnr; - int faceCounter; - int keepLooping = 1; - float vec[3], hoco[4], mul, zval, fval; - Material *ma=0; - - faceCounter = 0; - -/* printf("Going to buffer faces:\n"); */ -/* printf("\tfirst pass:\n"); */ - -/* RE_treat_face_as_opaque = 1; */ - - while ( (faceCounter < R.totvlak) && keepLooping) { - if((faceCounter & 255)==0) { vlr= R.blovl[faceCounter>>8]; } - else vlr++; - - ma= vlr->mat; - - /* VERY dangerous construction... zoffs is set by a slide in the ui */ - /* so it should be safe... */ - if((ma->mode & (MA_ZTRA)) && (ma->zoffs != 0.0)) { - mul= 0x7FFFFFFF; - zval= mul*(1.0+vlr->v1->ho[2]/vlr->v1->ho[3]); - - VECCOPY(vec, vlr->v1->co); - /* z is negatief, wordt anders geclipt */ - vec[2]-= ma->zoffs; - RE_projectverto(vec, hoco); /* vec onto hoco */ - fval= mul*(1.0+hoco[2]/hoco[3]); - - Azvoordeel= (int) fabs(zval - fval ); - } else { - Azvoordeel= 0; - } - /* face number is used in the fill functions */ - zvlnr = faceCounter + 1; - - if(vlr->flag & R_VISIBLE) { /* might test for this sooner... */ - - if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); - else { - zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, - vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); - if(vlr->v4) { - zvlnr+= 0x800000; /* in a sense, the 'adjoint' face */ - zbufclip(NULL, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, - vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); - } - } - } - if(RE_local_test_break()) keepLooping = 0; - faceCounter++; - } - - return keepLooping; -} - -/** - * Fills in distances of halos in the z buffer. - * @return 1 for succes, 0 if the operation was interrupted. - */ - -/* ------------------------------------------------------------------------- */ -/* We cheat a little here: we only fill the halo on the first pass, and we */ -/* set a full complement of mask flags. This can be done because we consider */ -/* halos to be flat (billboards), so we do not have to correct the z range */ -/* every time we insert a halo. Also, halos fall off to zero at the edges, */ -/* so we can safely render them in pixels where they do not exist. */ -static int zBufferAllHalos(void) -{ - HaloRen *har = NULL; - int haloCounter = 0; - int dist = 0; - int keepLooping = 1; - short miny = 0, maxy = 0, minx = 0, maxx = 0; - short ycount = 0, xcount = 0; - RE_APixstrExt *ap, *apoffset; - int mask; /* jitter mask */ - - if (!Zsample) - { - mask = (1 << osaNr) - 1 ; /* Fill all samples together */ - - while ( (haloCounter < R.tothalo) && keepLooping) { - if((haloCounter & 255)==0) har= R.bloha[haloCounter>>8]; - else har++; - - /* Halos are sometimes wrongly kicked out of the box they belong */ - /* in... */ - - /* Only buffer the current alpha buffer contents!!! The line */ - /* indices have already been clipped to picture size. */ - minx = floor(har->xs - har->rad) - 1; /* assume min =< max is true*/ - if (minx < 0 ) minx = 0; - maxx = ceil(har->xs + har->rad ) + 1; - /* Do the extra -1 because of the +1 later on. I guess halos might */ - /* have to start one pixel sooner? Or maybe the lower clip should */ - /* be adjusted */ - if (maxx >= zBufferWidth - 1) maxx = zBufferWidth - 2; - - miny = har->miny; - if (miny < Aminy) miny = Aminy; - maxy = har->maxy; - if (maxy > Amaxy) maxy = Amaxy; - - if ( (minx <= maxx) && (miny <= maxy)) { - /* distance to this halo? */ - dist = har->zBufDist /* * R.ycor */; - /* strange that the ycor influences the z coordinate ..*/ - ycount = miny; - while (ycount <= maxy) { - apoffset = APixbufExt + (zBufferWidth * (ycount - Aminy)); - ap = apoffset + minx; - xcount = minx; - while (xcount <= maxx) { - insertFlatObjectNoOsa(ap, haloCounter, RE_HALO, dist, mask); - xcount++; - ap++; - } - ycount++; - } - } - if(RE_local_test_break()) keepLooping = 0; - haloCounter++; - } - } - - return keepLooping; -} -/* ------------------------------------------------------------------------- */ - -/** -* Fills in distances of all faces in a z buffer, for given jitter settings. - */ -static int fillZBufDistances() -{ - int keepLooping = 1; - - keepLooping = zBufferAllFaces(); /* Solid and transparent faces*/ - keepLooping = zBufferAllHalos() && keepLooping; /* ...and halos*/ - return keepLooping; - -} - - - -#if 0 -/* ------------------------------------------------------------------------- */ -/** - * One more filler: fill in halo data in z buffer. - * Empty so far, but may receive content of halo loop. - */ -void zBufferFillHalo(void) -{ - /* so far, intentionally empty */ -} -#endif - -/* ------------------------------------------------------------------------- */ -/* Colour buffer related: */ -/* This transforms the 4 inputvalues RE_COLBUFTYPE to a new value */ -/* It expects the values R.r.postigamma, R.r.postmul and R.r.postadd. */ -/* This is the standard transformation, more elaborate tools are for later. */ -/* ------------------------------------------------------------------------- */ -void std_floatcol_to_charcol( float *buf, char *target) -{ - float col[3]; - - float dither_value; - - dither_value = ((BLI_frand()-0.5)*R.r.dither_intensity)/256.0; - - /* alpha */ - if((buf[3]+dither_value)<=0.0) target[3]= 0; - else if((buf[3]+dither_value)>1.0) target[3]= 255; - else target[3]= 255.0*(buf[3]+dither_value); - - if(R.r.postgamma==1.0) { - /* r */ - col[0]= R.r.postmul*buf[0] + R.r.postadd + dither_value; - /* g */ - col[1]= R.r.postmul*buf[1] + R.r.postadd + dither_value; - /* b */ - col[2]= R.r.postmul*buf[2] + R.r.postadd + dither_value; - } - else { - /* putting the postmul within the pow() gives an - * easier control for the user, values from 1.0-2.0 - * are relevant then - */ - - /* r */ - col[0]= pow(R.r.postmul*buf[0], R.r.postigamma) + R.r.postadd + dither_value; - /* g */ - col[1]= pow( R.r.postmul*buf[1], R.r.postigamma) + R.r.postadd + dither_value; - /* b */ - col[2]= pow(R.r.postmul*buf[2], R.r.postigamma) + R.r.postadd + dither_value; - } - - if(R.r.posthue!=0.0 || R.r.postsat!=1.0) { - float hsv[3]; - - rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2); - hsv[0]+= R.r.posthue; - if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0; - hsv[1]*= R.r.postsat; - if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0; - hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); - } - - if(col[0]<=0.0) target[0]= 0; - else if(col[0]>1.0) target[0]= 255; - else target[0]= 255.0*col[0]; - - if(col[1]<=0.0) target[1]= 0; - else if(col[1]>1.0) target[1]= 255; - else target[1]= 255.0*col[1]; - - if(col[2]<=0.0) target[2]= 0; - else if(col[2]>1.0) target[2]= 255; - else target[2]= 255.0*col[2]; -} - -/* ---------------------------------------------------------------------------- - - Colour buffer related: - - The colour buffer is a buffer of a single screen line. It contains - four fields of type RE_COLBUFTYPE per pixel. - - We can do several post-process steps. I would prefer to move them outside - the render module later on, but it's ok to leave it here for now. For the - time being, we have: - - post-process function - Does some operations with the colours. - - Multiply with some factor - - Add constant offset - - Apply extra gamma correction (seems weird...) - - key-alpha correction - Key alpha means 'un-applying' the alpha. For fully covered pixels, this - operation has no effect. - - - XXX WARNING! Added the inverse render gamma here, so this cannot be used external - without setting Osa or Gamme flags off (ton) - ----------------------------------------------------------------------------- */ -/* used external! */ -void transferColourBufferToOutput( float *buf, int y) -{ - /* Copy the contents of AColourBuffer3 to R.rectot + y * R.rectx */ - int x = 0; - char *target = (char*) (R.rectot + (y * R.rectx)); - - /* Copy the first pixels. We can do some more clipping on */ - /* the z buffer, I think. */ - while (x < R.rectx) { - - - /* invert gamma corrected additions */ - if(do_gamma) { - buf[0] = invGammaCorrect(buf[0]); - buf[1] = invGammaCorrect(buf[1]); - buf[2] = invGammaCorrect(buf[2]); - } - - std_floatcol_to_charcol(buf, target); - - /* - Key-alpha mode: - Need to un-apply alpha if alpha is non-full. For full alpha, - the operation doesn't have effect. Do this after the post- - processing, so we can still use the benefits of that. - - */ - - if (getSkyBlendingMode() == RE_ALPHA_KEY) { - applyKeyAlphaCharCol(target); - } - - target+=4; - buf+=4; - x++; - } -} - -/* used for redisplay after render. assumes size globals to be set OK! */ -void RE_floatbuffer_to_output(void) -{ - float *buf= R.rectftot; - int pix= R.rectx*R.recty; - char *target = (char *)R.rectot; - - if(R.rectftot==NULL) return; - - while(pix--) { - std_floatcol_to_charcol(buf, target); - buf+= 4; - target+= 4; - } -} - -/* ------------------------------------------------------------------------- */ - -static void eraseColBuf(RE_COLBUFTYPE *buf) -{ - /* By definition, the buffer's length is 4 * R.rectx items */ - int i = 0; - - while (i < 4 * (R.rectx+3)) { - *buf = 0.0f; - buf++; i++; - } -} - -/* ------------------------------------------------------------------------- */ - - -/** - * Fill the accumulation buffer APixbufExt with face and halo indices. - * Note: Uses globals. - * @param y the line number to set - */ -static void calcZBufLine(int y) -{ - int part; - int keepLooping = 1; - - if(y<0) return; - - /* zbuffer fix: here? */ - Zmulx= ((float) R.rectx)/2.0; - Zmuly= ((float) R.recty)/2.0; - - - /* use these buffer fill functions */ - zbuffunc = zBufferFillFace; - zbuflinefunc = zBufferFillEdge; - - /* (FORALL y: Aminy =< y =< Amaxy: y is buffered) */ - if( (y < Aminy) || (y > Amaxy)) { - - /* prepare buffer */ - part = (y/RE_ZBUFLEN); /* These two lines are mystifying me... */ - Aminy = part * RE_ZBUFLEN; /* Possibly for rounding things? */ - Amaxy = Aminy + RE_ZBUFLEN - 1; - /* if(Amaxy >= R.recty) Amaxy = R.recty-1; */ - if(Amaxy >= R.recty) Amaxy = R.recty - 1; - resetZbuffer(); - - Zsample = 0; /* Zsample is used internally ! */ - while ( (Zsample < osaNr) && keepLooping ) { - /* Apply jitter to this pixel. The jitter offsets are globals. */ - /* They are added in zbufclip() */ - /* Negative: these offsets are added to the vertex coordinates */ - /* so it equals translating viewpoint over the positive vector. */ - Zjitx= -jit[Zsample][0]-0.5; - Zjity= -jit[Zsample][1]-0.5; - - keepLooping = fillZBufDistances(); - - if(RE_local_test_break()) keepLooping = 0; - Zsample++; - } - } - -} - - -/* ------------------------------------------------------------------------- */ - -struct renderline { - RE_COLBUFTYPE *buf1, *buf2, *buf3; - int y; -}; - -static int do_renderline(void *poin) -{ - struct renderline *rl= poin; - - renderZBufLine(rl->y, rl->buf1, rl->buf2, rl->buf3); - return 1; -} - -void zBufShadeAdvanced() -{ - RE_COLBUFTYPE *cycle; - struct renderline rl1, rl2; - int y, keepLooping = 1; - float xjit = 0.0, yjit = 0.0; - - Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */ - - /* Set osaNr. Treat 'no osa' as 'osa = 1' */ - if(R.r.mode & R_OSA) { - osaNr = R.osa; - if(osaNr > 16) { /* check was moved from calcZBufLine */ - printf("zBufShadeAdvanced> osa too large (internal error)\n"); - G.afbreek= 1; - return; - } - } else { - /* little hack */ - osaNr = 1; - xjit = jit[0][0]; - yjit = jit[0][1]; - jit[0][0] = 0.0; - jit[0][1] = 0.0; - } - - RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix */ - - initRenderBuffers(R.rectx); - - y = 0; - while ( (y < R.recty) && keepLooping) { - - calcZBufLine(y); - - rl1.buf1= AColourBuffer1; - rl1.buf2= AColourBuffer2; - rl1.buf3= AColourBuffer3; - rl1.y= y; - - if(R.r.mode & R_THREADS) { - if((y & 1)==0) { - SDL_Thread *thread; - - thread = SDL_CreateThread(do_renderline, &rl1); - if ( thread == NULL ) { - fprintf(stderr, "Unable to create thread"); - G.afbreek= 1; - break; - } - - rl2.buf1= AColourBuffer0; - rl2.buf2= AColourBuffer1a; - rl2.buf3= AColourBuffer2a; - rl2.y= y+1; - - do_renderline(&rl2); - - SDL_WaitThread(thread, NULL); - - if(R.r.filtertype) { - float *rb1= AColourBuffer1, *rb2= AColourBuffer2, *rb1a= AColourBuffer1a, *rb2a= AColourBuffer2a; - int a= 4*(R.rectx + 4); - while(a--) { - *rb1 += *rb1a; - *rb2 += *rb2a; - *(rb1a++)= 0.0; rb1++; - *(rb2a++)= 0.0; rb2++; - } - } - else { - cycle= AColourBuffer1a; AColourBuffer1a= AColourBuffer1; AColourBuffer1= cycle; - } - } - } - else do_renderline(&rl1); - - if(y) { - transferColourBufferToOutput(AColourBuffer3+4, y-1); - - if((y & 1)==0) RE_local_render_display(y-2, y-1, R.rectx, R.recty, R.rectot); - } - - /* buffer cycling */ - eraseColBuf(AColourBuffer3); - cycle= AColourBuffer3; - AColourBuffer3= AColourBuffer2; - AColourBuffer2= AColourBuffer1; - AColourBuffer1= AColourBuffer0; - AColourBuffer0= cycle; - - if(RE_local_test_break()) keepLooping = 0; - y++; - } - if(keepLooping) transferColourBufferToOutput(AColourBuffer3+4, y-1); - - freeRenderBuffers(); - - /* Edge rendering is done purely as a post-effect */ - if(R.r.mode & R_EDGE) { - addEdges((char*)R.rectot, R.rectx, R.recty, - osaNr, - R.r.edgeint, R.r.same_mat_redux, - G.compat, G.notonlysolid, - R.r.edgeR, R.r.edgeG, R.r.edgeB); - } - - if (!(R.r.mode & R_OSA)) { - jit[0][0] = xjit; - jit[0][1] = yjit; - } - -} - -/* ------------------------------------------------------------------------- */ - - - - -/* eof vanillaRenderPipe.c */ diff --git a/source/blender/render/intern/source/zblur.c b/source/blender/render/intern/source/zblur.c deleted file mode 100644 index a1e8304ba75..00000000000 --- a/source/blender/render/intern/source/zblur.c +++ /dev/null @@ -1,818 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - */ - -/* - * This file is largely based on the focal blur plugin by onk, 8.99 - * - */ - -#include -#include -#include -#include - -#include "MEM_guardedalloc.h" - -#include "DNA_camera_types.h" -#include "DNA_scene_types.h" - -#include "BKE_global.h" -#include "BKE_utildefines.h" - -#include "RE_callbacks.h" - -#include "render.h" -#include "pixelblending.h" - -#include "blendef.h" -#include "zblur.h" - -//#include "BIF_gl.h" - -/* ------------------------------------------------- - * defines, protos */ - -typedef enum { I_GRAY, I_FLOAT, I_FLOAT4 } IMGTYPE; - -typedef struct { - int x, y; - int size, el_size; - IMGTYPE type; - char *data; -} Image; - -typedef struct { /* blur mask struct */ - int size; - float fac; - float *val; -} Mask; - -typedef Mask* Maskarray; - -/* don't change these */ -#define NMASKS_SHIFT 2 -#define NMASKS 64 - - -static Image *alloc_img(int x, int y, IMGTYPE type) -{ - Image *ret; - int size, typesize; - - switch (type) { - case I_GRAY: - typesize = 1; - break; - case I_FLOAT: - typesize = sizeof(float); - break; - case I_FLOAT4: - typesize = 4 * sizeof(float); - break; - default: - return 0; - } - - size = x * y; - - ret = (Image *) MEM_mallocN(sizeof(Image) + size*typesize, "zblur_img"); - if (ret) { - ret->x = x; - ret->y = y; - ret->size = size; - ret->el_size = typesize; - ret->type = type; - ret->data = (char *) (ret + 1); - size *= typesize; - memset(ret->data, 0, size); - } - - return ret; -} - -static int free_img(Image *img) -{ - MEM_freeN(img); - return 1; -} - -/* 32 bits (int) rect to float buf */ -static void recti2imgf(unsigned int *src, Image *dest, int x, int y) -{ - char *from; - float *to; - int i, ix, iy; - - if(dest->type != I_FLOAT4) return; - - from = (char *) src; - to = (float *) dest->data; - - if (R.r.mode & R_FIELDS) { /* double each scanline */ - for (iy=0; iytype != I_FLOAT4) return; - - from = src; - to = (float *) dest->data; - - if (R.r.mode & R_FIELDS) { /* double each scanline */ - for (iy=0; iytype != I_FLOAT4) return; - - from = (float *) src->data; - to = (char *) dest; - - if (R.r.mode & R_FIELDS) { - for (iy=0; iyy; iy++) { - for (ix=0; ixx; ix++) { - *to++ = (char)(from[0]*255.0); - *to++ = (char)(from[1]*255.0); - *to++ = (char)(from[2]*255.0); - *to++ = (char)(from[3]*255.0); - from += 4; - } - iy++; - from+= 4*src->x; - } - } - else { - i = src->x * src->y; - while(i--) { - *to++ = (char)(from[0]*255.0); - *to++ = (char)(from[1]*255.0); - *to++ = (char)(from[2]*255.0); - *to++ = (char)(from[3]*255.0); - from += 4; - } - } -} - -/* floatbuf back to float rect */ -static void imgf2rectf(Image *src, float *dest) -{ - float *from; - float *to; - int i, iy; - - if(src->type != I_FLOAT4) return; - - from = (float *) src->data; - to = dest; - - if (R.r.mode & R_FIELDS) { - for (iy=0; iyy; iy++) { - - memcpy(to, from, 4*sizeof(float)*src->x); - - iy++; - to+= 4*src->x; - from+= 8*src->x; - } - } - else { - i = src->x * src->y; - memcpy(to, from, 4*sizeof(float)*i); - } -} - - -static void imgf_gamma(Image *src, float gamma) -{ - float *to; - int i; - - if(gamma==1.0) return; - - i = 4 * src->x * src->y; - to= (float *) src->data; - while(i--) { - *to = (float)pow(*to, gamma); - to++; - } -} - -#if 0 -/* create new image with alpha & color zero where mask is zero */ -static Image *imgf_apply_mask(Image *src, Image *zmask) -{ - Image *dest; - float *from, *to; - int i; - char *zptr; - - dest = alloc_img(src->x, src->y, I_FLOAT4); - - i= src->x * src->y; - from= (float *) src->data; - to= (float *) dest->data; - zptr= (char *)zmask->data; - - while(i--) { - if(*zptr) { - to[0]= from[0]; - to[1]= from[1]; - to[2]= from[2]; - to[3]= from[3]; - } - else { - to[0]= to[1]= to[2]= to[3]= 0.0f; - } - zptr++; - to+= 4; - from+= 4; - } - - return dest; -} - -static void imgf_alpha_over(Image *dest, Image *src) -{ - float *from, *to; - int i; - - i= src->x * src->y; - from= (float *) src->data; - to= (float *) dest->data; - - while(i--) { - addAlphaOverFloat(to, from); - to+= 4; - from+= 4; - } -} - -#endif - -/* --------------------------------------------------------------------- */ -/* mask routines */ - -static Mask *alloc_mask(int size) -{ - Mask *m; - int memsize; - - memsize = (sizeof(Mask) + (2 * size +1) * (2 * size +1) * sizeof(float)); - - m = (Mask*) MEM_mallocN(memsize, "zblur_mask"); - m->size = size; - m->val = (float *) (m + 1); - - return m; -} - -static void free_mask(Mask *m) -{ - int memsize; - - memsize = 2 * m->size + 1; - memsize *= memsize * sizeof(float); - memsize += sizeof(Mask); - - MEM_freeN(m); -} - -/* normalize mask to 1 */ - -static void norm_mask(Mask *m) -{ - float fac; - int size; - float *v; - - fac = m->fac; - size = (2 * m->size +1)*(2 * m->size +1); - - v = m->val; - while(size--) { - *v++ *= fac; - } - m->fac = 1.0; -} - -/* filters a grayvalue image with a gaussian IIR filter with blur radius "rad" - * For large blurs, it's more efficient to call the routine several times - * instead of using big blur radii. - * The original image is changed */ - - -static void gauss_blur(Image *img, float rad) -{ - Image *new; - register float sum, val; - float gval; - float *gausstab, *v; - int r, n, m; - int x, y; - int i; - int step, bigstep; - char *src, *dest; - - r = (1.5 * rad + 1.5); - n = 2 * r + 1; - - /* ugly : */ - if ((img->x <= n) || (img->y <= n)) { - return; - } - - gausstab = (float *) MEM_mallocN(n * sizeof(float), "zblur_gauss"); - if (!gausstab) { - return; - } - - sum = 0.0; - v = gausstab; - for (x = -r; x <= r; x++) { - - val = exp(-4*(float ) (x*x)/ (float) (r*r)); - sum += val; - *v++ = val; - } - - i = n; - v = gausstab; - while (i--) { - *v++ /= sum; - } - - new = alloc_img(img->x, img->y, I_GRAY); - if (!new) { - return; - } - - /* horizontal */ - - step = (n - 1); - - for (y = 0; y < img->y; y++) { - src = (char *)img->data + (y * img->x); - dest = (char *)new->data + (y * img->x); - - for (x = r; x > 0 ; x--) { - m = n - x; - gval = 0.0; - sum = 0.0; - v = gausstab + x; - for (i = 0; i < m; i++) { - val = *v++; - sum += val; - gval += val * (*src++); - } - *dest++ = gval / sum; - src -= m; - } - - for (x = 0; x <= (img->x - n); x++) { - gval = 0.0; - v = gausstab; - - for (i = 0; i < n; i++) { - val = *v++; - gval += val * (*src++); - } - *dest++ = gval; - src -= step; - } - - for (x = 1; x <= r ; x++) { - m = n - x; - gval = 0.0; - sum = 0.0; - v = gausstab; - for (i = 0; i < m; i++) { - val = *v++; - sum += val; - gval += val * (*src++); - } - *dest++ = gval / sum; - src -= (m - 1); - } - } - - /* vertical */ - - step = img->x; - bigstep = (n - 1) * step; - for (x = 0; x < step ; x++) { - src = new->data + x; - dest = img->data + x; - - for (y = r; y > 0; y--) { - m = n - y; - gval = 0.0; - sum = 0.0; - v = gausstab + y; - for (i = 0; i < m; i++) { - val = *v++; - sum += val; - gval += val * src[0]; - src += step; - } - dest[0] = gval / sum; - src -= m * step; - dest+= step; - } - for (y = 0; y <= (img->y - n); y++) { - gval = 0.0; - v = gausstab; - for (i = 0; i < n; i++) { - val = *v++; - gval += val * src[0]; - src += step; - } - dest[0] = gval; - dest += step; - src -= bigstep; - } - for (y = 1; y <= r ; y++) { - m = n - y; - gval = 0.0; - sum = 0.0; - v = gausstab; - for (i = 0; i < m; i++) { - val = *v++; - sum += val; - gval += val * src[0]; - src += step; - } - dest[0] = gval / sum; - dest += step; - src -= (m - 1) * step; - } - } - MEM_freeN(gausstab); - free_img(new); -} - -static float zigma(float x, float sigma, float sigma4) -{ - //return 1.0/(1.0+pow(x, sigma)); - - if(x < sigma) { - x*= sigma; - return 1.0/exp(x*x) - sigma4; - } - return 0.0; -} - - -static Mask *gauss_mask(float rad, float sigma) -{ - Mask *m; - float sum, val, *v, fac, radsq= rad*rad; - float sigma4; - int r; - int ix, iy; - - r = (1.0 * rad + 1.0); - m = alloc_mask(r); - v = m->val; - sum = 0.0; - - sigma4= 1.0/exp(sigma*sigma*sigma*sigma); - - for (iy = -r; iy <= r; iy++) { - for (ix = -r; ix <= r; ix++) { - - fac= ((float)(ix*ix + iy*iy))/(radsq); - val = zigma(fac, sigma, sigma4); - - // val = exp(-(float) (ix*ix + iy*iy)/(rad * rad)); - sum += val; - *v++ = val; - } - } - - m->fac = 1.0 / sum; - - norm_mask(m); - return m; -} - -/* generates #num masks with the maximal blur radius 'rad' - * */ -static Maskarray *init_masks(int num, float rad, float sigma) -{ - int i; - float r, step; - Maskarray *maskarray; - - maskarray = (Maskarray*) MEM_mallocN(num * sizeof (Maskarray), "zblur_masks"); - step = rad / num; - r = 0.1; - for (i = 0; i < num; i++) { - maskarray[i] = gauss_mask(r, sigma); - r += step; - } - return maskarray; -} - - -/* ********************* Do the blur ******************************** */ - -static Image *zblur(Image *src, Image *zbuf, float radius, float sigma) -{ - Image *dest; - Maskarray *mar; - Mask *m; - float *sptr, *dptr; - float *mval; /* mask value pointer */ - float rval, gval, bval, aval; - float norm, fac; - int tmp; - int zval; - int size; - int row; - int mrow; - int x, y; - int i; - int sx, sy, ex, ey; - int mx, my; - char *zptr; - - if(src->type != I_FLOAT4) return NULL; - - dest = alloc_img(src->x, src->y, I_FLOAT4); - row = src->x * 4; - - mar = init_masks(NMASKS, radius, sigma); - - for (y = 0; y < src->y ; y++) { - for (x = 0; x < src->x; x++) { - dptr = (float *) (dest->data + ((y * src->x + x) * src->el_size)); - zptr = zbuf->data + (y * src->x + x); - zval = *zptr; - sptr = (float *) (src->data + ((y *src->x + x )* src->el_size)); - - m = mar[zval >> NMASKS_SHIFT]; - - size = m->size; - - if(size==0 || zval==0) { - dptr[0] = sptr[0]; - dptr[1] = sptr[1]; - dptr[2] = sptr[2]; - dptr[3] = sptr[3]; - continue; - } - - ex = src->x - x; - ey = src->y - y; - - sx = (x < size) ? x : size; - sy = (y < size) ? y : size; - ex = (ex <= size) ? ex - 1: size; - ey = (ey <= size) ? ey - 1: size; - - sptr -= sy *src->x * 4; - zptr -= sy * src->x; - mrow = (size << 1) + 1; - mval = m->val + (size - sy) * mrow + size; - - norm = rval = gval = bval = aval= 0.0; - - for (my = -sy; my <= ey; my++) { - for (mx = -sx; mx <= ex; mx++) { - if( zptr[mx] ) { - tmp = 4 * mx; - fac = mval[mx] * (float) zptr[mx] /255.0 ; - - norm += fac; - rval += fac * sptr[tmp]; - gval += fac * sptr[tmp + 1]; - bval += fac * sptr[tmp + 2]; - aval += fac * sptr[tmp + 3]; - } - } - mval += mrow; - sptr += row; - zptr += src->x; - } - - dptr[0] = rval / norm; - dptr[1] = gval / norm; - dptr[2] = bval / norm; - dptr[3] = aval / norm; - } - if(!(y % 4) && RE_local_test_break()) break; - } - - for (i= 0; i < NMASKS; i++) { - free_mask(mar[i]); - } - - MEM_freeN(mar); - - return dest; -} - - -/* this splits the z-buffer into 2 gray-images (background, foreground) -* which are used for the weighted blur */ - -static void zsplit(int *zptr, Image *fg, Image *bg, int zfocus, int zmax, int zmin, int x, int y) -{ - char *p, *q; - int i, ix, iy; - float fdist; - float fgnorm, bgnorm; - - p = fg->data; - q = bg->data; - bgnorm = 255.0 / ((float) zmax - (float) zfocus); - fgnorm = 255.0 / ((float) zfocus - (float) zmin); - - if (R.r.mode & R_FIELDS) { - for (iy=0; iyzfocus) zmin= zfocus; - - zfront = alloc_img(x, y, I_GRAY); - zback = alloc_img(x, y, I_GRAY); - orig = alloc_img(x, y, I_FLOAT4); - - if(R.rectftot) rectf2imgf(R.rectftot, orig, x, y); - else recti2imgf(R.rectot, orig, x, y); - - imgf_gamma(orig, R.r.zgamma); // pregamma correct if required - - - /* split up z buffer into 2 gray images */ - zsplit(R.rectz, zfront, zback, zfocus, INT_MAX, zmin, x, y); - -// glDrawBuffer(GL_FRONT); -// glRasterPos2i(0, 0); -// glDrawPixels(x, y, GL_RED, GL_UNSIGNED_BYTE, zback->data); -// glFlush(); -// glDrawBuffer(GL_BACK); - - gauss_blur(zback, 1.0); - gauss_blur(zfront, zblurr); - - /* blur back part */ - work = zblur(orig, zback, zblurr, R.r.zsigma); - free_img(orig); - - /* blur front part */ - orig = zblur(work, zfront, zblurr, R.r.zsigma); - - imgf_gamma(orig, 1.0/R.r.zgamma); // pregamma correct if required - - if(R.rectftot) imgf2rectf(orig, R.rectftot); - else imgf2recti(orig, R.rectot); - - free_img(work); - free_img(orig); - free_img(zfront); - free_img(zback); - - /* make new display rect */ - if(R.rectftot) RE_floatbuffer_to_output(); -} - - diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index b99f4d8e768..3be859019ed 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1,15 +1,12 @@ /** * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,21 +20,24 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * Contributors: Hos, RPW + * 2004-2006 Blender Foundation, full recode * - * Contributor(s): Hos, RPW. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ + /*---------------------------------------------------------------------------*/ /* Common includes */ /*---------------------------------------------------------------------------*/ #include +#include #include #include #include + +#include "BLI_blenlib.h" #include "MTC_matrixops.h" #include "MEM_guardedalloc.h" @@ -49,75 +49,57 @@ #include "BKE_utildefines.h" #include "radio_types.h" -#include "radio.h" /* needs RG, some root data for radiosity */ +#include "radio.h" /* needs RG, some root data for radiosity */ #include "SDL_thread.h" -#include "render.h" -#include "RE_callbacks.h" +#include "RE_render_ext.h" /* local includes */ -#include "rendercore.h" /* shade_pixel and count_mask */ +#include "render_types.h" +#include "renderpipeline.h" +#include "renderdatabase.h" +#include "rendercore.h" #include "pixelblending.h" -#include "jitter.h" /* own includes */ #include "zbuf.h" -#define FLT_EPSILON 1.19209290e-07F +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* 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; +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -/*-----------------------------------------------------------*/ -/* Globals for this file */ -/* main reason for globals; unified zbuffunc() with simple args */ -/*-----------------------------------------------------------*/ - -float Zmulx; /* Half the screenwidth, in pixels. (used in render.c, */ - /* zbuf.c) */ -float Zmuly; /* Half the screenheight, in pixels. (used in render.c,*/ - /* zbuf.c) */ -float Zjitx; /* Jitter offset in x. When jitter is disabled, this */ - /* should be 0.5. (used in render.c, zbuf.c) */ -float Zjity; /* Jitter offset in y. When jitter is disabled, this */ - /* should be 0.5. (used in render.c, zbuf.c) */ - -int Zsample; -void (*zbuffunc)(ZSpan *, int, float *, float *, float *); -void (*zbuffunc4)(ZSpan *, int, float *, float *, float *, float *); -void (*zbuflinefunc)(int, float *, float *); - -static APixstr *APixbuf; /* Zbuffer: linked list of face indices */ -static int *Arectz; /* Zbuffer: distance buffer, almost obsolete */ -static int Aminy; /* y value of first line in the accu buffer */ -static int Amaxy; /* y value of last line in the accu buffer */ -static int Azvoordeel = 0; -static APixstrMain apsmfirst; -static short apsmteller = 0; /* ****************** Spans ******************************* */ -static void zbuf_alloc_span(ZSpan *zspan, int yres) +/* each zbuffer has coordinates transformed to local rect coordinates, so we can simply clip */ +void zbuf_alloc_span(ZSpan *zspan, int rectx, int recty) { - zspan->yres= yres; + memset(zspan, 0, sizeof(ZSpan)); - zspan->span1= MEM_callocN(yres*sizeof(float), "zspan"); - zspan->span2= MEM_callocN(yres*sizeof(float), "zspan"); + zspan->rectx= rectx; + zspan->recty= recty; + + zspan->span1= RE_mallocN(recty*sizeof(float), "zspan"); + zspan->span2= RE_mallocN(recty*sizeof(float), "zspan"); } static void zbuf_free_span(ZSpan *zspan) { if(zspan) { - if(zspan->span1) MEM_freeN(zspan->span1); - if(zspan->span2) MEM_freeN(zspan->span2); + if(zspan->span1) RE_freeN(zspan->span1); + if(zspan->span2) RE_freeN(zspan->span2); zspan->span1= zspan->span2= NULL; } } -static void zbuf_init_span(ZSpan *zspan, int miny, int maxy) +/* reset range for clipping */ +static void zbuf_init_span(ZSpan *zspan) { - zspan->miny= miny; /* range for clipping */ - zspan->maxy= maxy; - zspan->miny1= zspan->miny2= maxy+1; - zspan->maxy1= zspan->maxy2= miny-1; + zspan->miny1= zspan->miny2= zspan->recty+1; + zspan->maxy1= zspan->maxy2= -1; zspan->minp1= zspan->maxp1= zspan->minp2= zspan->maxp2= NULL; } @@ -137,12 +119,12 @@ static void zbuf_add_to_span(ZSpan *zspan, float *v1, float *v2) my0= ceil(minv[1]); my2= floor(maxv[1]); - if(my2miny || my0> zspan->maxy) return; + if(my2<0 || my0>= zspan->recty) return; /* clip top */ - if(my2>=zspan->maxy) my2= zspan->maxy-1; + if(my2>=zspan->recty) my2= zspan->recty-1; /* clip bottom */ - if(my0miny) my0= zspan->miny; + if(my0<0) my0= 0; if(my0>my2) return; /* if(my0>my2) should still fill in, that way we get spans that skip nicely */ @@ -217,16 +199,7 @@ void fillrect(int *rect, int x, int y, int val) } } -/** -* Tests whether this coordinate is 'inside' or 'outside' of the view - * volume? By definition, this is in [0, 1]. - * @param p vertex z difference plus coordinate difference? - * @param q origin z plus r minus some coordinate? - * @param u1 [in/out] clip fraction for ? - * @param u2 [in/out] - * @return 0 if point is outside, or 1 if the point lies on the clip - * boundary - */ +/* based on Liang&Barsky, for clipping of pyramidical volume */ static short cliptestf(float p, float q, float *u1, float *u2) { float r; @@ -253,7 +226,7 @@ static short cliptestf(float p, float q, float *u1, float *u2) return 1; } -int RE_testclip(float *v) +int testclip(float *v) { float abs4; /* WATCH IT: this function should do the same as cliptestf, otherwise troubles in zbufclip()*/ short c=0; @@ -278,315 +251,42 @@ int RE_testclip(float *v) /* ************* ACCUMULATION ZBUF ************ */ -/*-APixstr---------------------(antialised pixel struct)------------------------------*/ -static APixstr *addpsmainA() +static APixstr *addpsmainA(ListBase *lb) { APixstrMain *psm; - psm= &apsmfirst; - - while(psm->next) { - psm= psm->next; - } - - psm->next= MEM_mallocN(sizeof(APixstrMain), "addpsmainA"); - - psm= psm->next; - psm->next=0; - psm->ps= MEM_callocN(4096*sizeof(APixstr),"pixstr"); - apsmteller= 0; + psm= RE_mallocN(sizeof(APixstrMain), "addpsmainA"); + BLI_addtail(lb, psm); + psm->ps= RE_mallocN(4096*sizeof(APixstr),"pixstr"); return psm->ps; } -static void freepsA() +static void freepsA(ListBase *lb) { - APixstrMain *psm, *next; + APixstrMain *psm, *psmnext; - psm= &apsmfirst; - - while(psm) { - next= psm->next; - if(psm->ps) { - MEM_freeN(psm->ps); - psm->ps= 0; - } - if(psm!= &apsmfirst) MEM_freeN(psm); - psm= next; + for(psm= lb->first; psm; psm= psmnext) { + psmnext= psm->next; + if(psm->ps) + RE_freeN(psm->ps); + RE_freeN(psm); } - - apsmfirst.next= 0; - apsmfirst.ps= 0; - apsmteller= 0; } -static APixstr *addpsA(void) +static APixstr *addpsA(ZSpan *zspan) { - static APixstr *prev; - - /* make first PS */ - if((apsmteller & 4095)==0) prev= addpsmainA(); - else prev++; - apsmteller++; - - return prev; -} - -/** - * Fill the z buffer for accumulation (transparency) - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ -static void zbufinvulAc(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) -{ - APixstr *ap, *apofs, *apn; - double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; - double zxd,zyd,zy0, tmp; - float *minv,*maxv,*midv; - int *rz,zverg,x; - int my0,my2,sn1,sn2,rectx,zd,*rectzofs; - int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2, mask; - - /* MIN MAX */ - if(v1[1]apsmcounter==0) { + zspan->curpstr= addpsmainA(zspan->apsmbase); + zspan->apsmcounter= 4095; } else { - if(v1[1] Amaxy) return; - - if(my02.0/65536.0) { - z0= (maxv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); - xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx0= 0; - xs0= 65536.0*(MIN2(minv[0],maxv[0])); - } - /* EDGES : THE TOP ONE */ - xx1= maxv[1]-midv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-midv[0])/xx1; - - tmp= (-65536.0*z0); - dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); - xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx1= 0; - xs1= 65536.0*(MIN2(midv[0],maxv[0])); - } - /* EDGES : BOTTOM ONE */ - xx1= midv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (midv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); - xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx2= 0; - xs2= 65536.0*(MIN2(minv[0],midv[0])); - } - - /* ZBUF DX DY */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - if(z0==0.0) return; - - if(midv[1]==maxv[1]) omsl= my2; - if(omsl Amaxy) { /* my2 can be larger */ - xs0+=dx0; - if (my2<=omsl) { - xs2+= dx2; - } - else{ - xs1+= dx1; - } - my2--; - } - - xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2]; - - zxd= -x0/z0; - zyd= -y0/z0; - zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); - - /* start-offset in rect */ - rectx= R.rectx; - rectzofs= (int *)(Arectz+rectx*(my2-Aminy)); - apofs= (APixbuf+ rectx*(my2-Aminy)); - mask= 1<dx1) { - xs3= xs0; - xs0= xs1; - xs1= xs3; - xs3= dx0; - dx0= dx1; - dx1= xs3; - xs3= 1; /* flag */ - - } - - for(y=my2;y>omsl;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs1>>16; - xs1+= dx1; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - ap= apofs+sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - if(zverg< *rz) { - apn= ap; - while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } - if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } - if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } - if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } - if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if(apn->next==0) apn->next= addpsA(); - apn= apn->next; - } - } - zverg+= zd; - rz++; - ap++; - x--; - } - zy0-= zyd; - rectzofs-= rectx; - apofs-= rectx; - } - - if(xs3) { - xs0= xs1; - dx0= dx1; - } - if(xs0>xs2) { - xs3= xs0; - xs0= xs2; - xs2= xs3; - xs3= dx0; - dx0= dx2; - dx2= xs3; - } - - for(; y>=my0; y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs2>>16; - xs2+= dx2; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - ap= apofs+sn1; - x= sn2-sn1; - - zverg-= Azvoordeel; - - while(x>=0) { - if(zverg< *rz) { - apn= ap; - while(apn) { /* loop unrolled */ - if(apn->p[0]==0) {apn->p[0]= zvlnr; apn->z[0]= zverg; apn->mask[0]= mask; break; } - if(apn->p[0]==zvlnr) {apn->mask[0]|= mask; break; } - if(apn->p[1]==0) {apn->p[1]= zvlnr; apn->z[1]= zverg; apn->mask[1]= mask; break; } - if(apn->p[1]==zvlnr) {apn->mask[1]|= mask; break; } - if(apn->p[2]==0) {apn->p[2]= zvlnr; apn->z[2]= zverg; apn->mask[2]= mask; break; } - if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } - if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= zverg; apn->mask[3]= mask; break; } - if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if(apn->next==0) apn->next= addpsA(); - apn= apn->next; - } - } - zverg+= zd; - rz++; - ap++; - x--; - } - - zy0-=zyd; - rectzofs-= rectx; - apofs-= rectx; + zspan->curpstr++; + zspan->apsmcounter--; } + return zspan->curpstr; } static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) @@ -600,13 +300,17 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v int sn1, sn2, rectx, *rectzofs, my0, my2, mask; /* init */ - zbuf_init_span(zspan, Aminy, Amaxy+1); + zbuf_init_span(zspan); /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); + if(v4) { + zbuf_add_to_span(zspan, v3, v4); + zbuf_add_to_span(zspan, v4, v1); + } + else + zbuf_add_to_span(zspan, v3, v1); /* clipped */ if(zspan->minp2==NULL || zspan->maxp2==NULL) return; @@ -636,11 +340,11 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v zy0= ((double)my2)*zyd + (double)xx1; /* start-offset in rect */ - rectx= R.rectx; - rectzofs= (int *)(Arectz+rectx*(my2-Aminy)); - apofs= (APixbuf+ rectx*(my2-Aminy)); - mask= 1<rectx; + rectzofs= (int *)(zspan->arectz+rectx*(my2)); + apofs= (zspan->apixbuf+ rectx*(my2)); + mask= zspan->mask; + /* correct span */ sn1= (my0 + my2)/2; if(zspan->span1[sn1] < zspan->span2[sn1]) { @@ -667,7 +371,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v ap= apofs+sn1; x= sn2-sn1; - zverg-= Azvoordeel; + zverg-= zspan->polygon_offset; while(x>=0) { if( (int)zverg < *rz) { @@ -685,7 +389,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } // if(apn->p[i]==0) {apn->p[i]= zvlnr; apn->z[i]= zverg; apn->mask[i]= mask; break; } // if(apn->p[i]==zvlnr) {apn->mask[i]|= mask; break; } - if(apn->next==NULL) apn->next= addpsA(); + if(apn->next==NULL) apn->next= addpsA(zspan); apn= apn->next; } } @@ -704,7 +408,7 @@ static void zbufinvulAc4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v -static void zbuflineAc(int zvlnr, float *vec1, float *vec2) +static void zbuflineAc(ZSpan *zspan, int zvlnr, float *vec1, float *vec2) { APixstr *ap, *apn; int *rectz; @@ -716,6 +420,8 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) dx= vec2[0]-vec1[0]; dy= vec2[1]-vec1[1]; + mask= zspan->mask; + if(fabs(dx) > fabs(dy)) { /* all lines from left to right */ @@ -731,22 +437,21 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) start= floor(v1[0]); end= start+floor(dx); - if(end>=R.rectx) end= R.rectx-1; + if(end>=zspan->rectx) end= zspan->rectx-1; oldy= floor(v1[1]); dy/= dx; vergz= v1[2]; - vergz-= Azvoordeel; + vergz-= zspan->polygon_offset; dz= (v2[2]-v1[2])/dx; if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= (int *)(Arectz+R.rectx*(oldy-Aminy) +start); - ap= (APixbuf+ R.rectx*(oldy-Aminy) +start); - mask= 1<arectz+zspan->rectx*(oldy) +start); + ap= (zspan->apixbuf+ zspan->rectx*(oldy) +start); + + if(dy<0) ofs= -zspan->rectx; + else ofs= zspan->rectx; for(x= start; x<=end; x++, rectz++, ap++) { @@ -757,7 +462,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) ap+= ofs; } - if(x>=0 && y>=Aminy && y<=Amaxy) { + if(x>=0 && y>=0 && yrecty) { if(vergz<*rectz) { apn= ap; @@ -770,7 +475,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if(apn->next==0) apn->next= addpsA(); + if(apn->next==0) apn->next= addpsA(zspan); apn= apn->next; } @@ -798,26 +503,25 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) start= floor(v1[1]); end= start+floor(dy); - if(start>Amaxy || end=zspan->recty || end<0) return; - if(end>Amaxy) end= Amaxy; + if(end>=zspan->recty) end= zspan->recty-1; oldx= floor(v1[0]); dx/= dy; vergz= v1[2]; - vergz-= Azvoordeel; + vergz-= zspan->polygon_offset; dz= (v2[2]-v1[2])/dy; if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= (int *)( Arectz+ (start-Aminy)*R.rectx+ oldx ); - ap= (APixbuf+ R.rectx*(start-Aminy) +oldx); - mask= 1<arectz+ (start)*zspan->rectx+ oldx ); + ap= (zspan->apixbuf+ zspan->rectx*(start) +oldx); if(dx<0) ofs= -1; else ofs= 1; - for(y= start; y<=end; y++, rectz+=R.rectx, ap+=R.rectx) { + for(y= start; y<=end; y++, rectz+=zspan->rectx, ap+=zspan->rectx) { x= floor(v1[0]); if(x!=oldx) { @@ -826,7 +530,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) ap+= ofs; } - if(x>=0 && y>=Aminy && x=0 && y>=0 && xrectx) { if(vergz<*rectz) { apn= ap; @@ -839,7 +543,7 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) if(apn->p[2]==zvlnr) {apn->mask[2]|= mask; break; } if(apn->p[3]==0) {apn->p[3]= zvlnr; apn->z[3]= vergz; apn->mask[3]= mask; break; } if(apn->p[3]==zvlnr) {apn->mask[3]|= mask; break; } - if(apn->next==0) apn->next= addpsA(); + if(apn->next==0) apn->next= addpsA(zspan); apn= apn->next; } @@ -853,30 +557,9 @@ static void zbuflineAc(int zvlnr, float *vec1, float *vec2) } } - - /* ************* NORMAL ZBUFFER ************ */ -/** - * Convert a homogenous coordinate to a z buffer coordinate. The - * function makes use of Zmulx, Zmuly, the x and y scale factors for - * the screen, and Zjitx, Zjity, the pixel offset. (These are declared - * in render.c) The normalised z coordinate must fall on [0, 1]. - * @param zco [3, 4 floats] pointer to the resulting z buffer coordinate - * @param hoco [4 floats] pointer to the homogenous coordinate of the - * vertex in world space. - */ -static void hoco_to_zco(float *zco, float *hoco) -{ - float deler; - - deler= hoco[3]; - zco[0]= Zmulx*(1.0+hoco[0]/deler)+ Zjitx; - zco[1]= Zmuly*(1.0+hoco[1]/deler)+ Zjity; - zco[2]= 0x7FFFFFFF *(hoco[2]/deler); -} - -static void zbufline(int zvlnr, float *vec1, float *vec2) +static void zbufline(ZSpan *zspan, int zvlnr, float *vec1, float *vec2) { int *rectz, *rectp; int start, end, x, y, oldx, oldy, ofs; @@ -902,7 +585,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) start= floor(v1[0]); end= start+floor(dx); - if(end>=R.rectx) end= R.rectx-1; + if(end>=zspan->rectx) end= zspan->rectx-1; oldy= floor(v1[1]); dy/= dx; @@ -911,11 +594,11 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) dz= floor((v2[2]-v1[2])/dx); if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= R.rectz+ oldy*R.rectx+ start; - rectp= R.rectot+ oldy*R.rectx+ start; + rectz= zspan->rectz + oldy*zspan->rectx+ start; + rectp= zspan->rectp + oldy*zspan->rectx+ start; - if(dy<0) ofs= -R.rectx; - else ofs= R.rectx; + if(dy<0) ofs= -zspan->rectx; + else ofs= zspan->rectx; for(x= start; x<=end; x++, rectz++, rectp++) { @@ -926,7 +609,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) rectp+= ofs; } - if(x>=0 && y>=0 && y=0 && y>=0 && yrecty) { if(vergz<*rectz) { *rectz= vergz; *rectp= zvlnr; @@ -954,7 +637,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) start= floor(v1[1]); end= start+floor(dy); - if(end>=R.recty) end= R.recty-1; + if(end>=zspan->recty) end= zspan->recty-1; oldx= floor(v1[0]); dx/= dy; @@ -963,13 +646,13 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) dz= floor((v2[2]-v1[2])/dy); if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= R.rectz+ start*R.rectx+ oldx; - rectp= R.rectot+ start*R.rectx+ oldx; + rectz= zspan->rectz + start*zspan->rectx+ oldx; + rectp= zspan->rectp + start*zspan->rectx+ oldx; if(dx<0) ofs= -1; else ofs= 1; - for(y= start; y<=end; y++, rectz+=R.rectx, rectp+=R.rectx) { + for(y= start; y<=end; y++, rectz+=zspan->rectx, rectp+=zspan->rectx) { x= floor(v1[0]); if(x!=oldx) { @@ -978,7 +661,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) rectp+= ofs; } - if(x>=0 && y>=0 && x=0 && y>=0 && xrectx) { if(vergz<*rectz) { *rectz= vergz; *rectp= zvlnr; @@ -992,7 +675,7 @@ static void zbufline(int zvlnr, float *vec1, float *vec2) } } -static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) +static void zbufline_onlyZ(ZSpan *zspan, int zvlnr, float *vec1, float *vec2) { int *rectz; int start, end, x, y, oldx, oldy, ofs; @@ -1018,7 +701,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) start= floor(v1[0]); end= start+floor(dx); - if(end>=R.rectx) end= R.rectx-1; + if(end>=zspan->rectx) end= zspan->rectx-1; oldy= floor(v1[1]); dy/= dx; @@ -1027,10 +710,10 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) dz= floor((v2[2]-v1[2])/dx); if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= R.rectz+ oldy*R.rectx+ start; + rectz= zspan->rectz + oldy*zspan->rectx+ start; - if(dy<0) ofs= -R.rectx; - else ofs= R.rectx; + if(dy<0) ofs= -zspan->rectx; + else ofs= zspan->rectx; for(x= start; x<=end; x++, rectz++) { @@ -1040,7 +723,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) rectz+= ofs; } - if(x>=0 && y>=0 && y=0 && y>=0 && yrecty) { if(vergz<*rectz) { *rectz= vergz; } @@ -1067,7 +750,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) start= floor(v1[1]); end= start+floor(dy); - if(end>=R.recty) end= R.recty-1; + if(end>=zspan->recty) end= zspan->recty-1; oldx= floor(v1[0]); dx/= dy; @@ -1076,12 +759,12 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) dz= floor((v2[2]-v1[2])/dy); if(vergz>0x50000000 && dz>0) maxtest= 1; // prevent overflow - rectz= R.rectz+ start*R.rectx+ oldx; + rectz= zspan->rectz + start*zspan->rectx+ oldx; if(dx<0) ofs= -1; else ofs= 1; - for(y= start; y<=end; y++, rectz+=R.rectx) { + for(y= start; y<=end; y++, rectz+=zspan->rectx) { x= floor(v1[0]); if(x!=oldx) { @@ -1089,7 +772,7 @@ static void zbufline_onlyZ(int zvlnr, float *vec1, float *vec2) rectz+= ofs; } - if(x>=0 && y>=0 && x=0 && y>=0 && xrectx) { if(vergz<*rectz) { *rectz= vergz; } @@ -1153,10 +836,19 @@ static int clipline(float *v1, float *v2) /* return 0: do not draw */ return 0; } - -void zbufclipwire(int zvlnr, VlakRen *vlr) +static void hoco_to_zco(ZSpan *zspan, float *zco, float *hoco) { - float vez[20], *f1, *f2, *f3, *f4= 0, deler; + float div; + + div= 1.0f/hoco[3]; + zco[0]= zspan->zmulx*(1.0+hoco[0]*div) + zspan->zofsx; + zco[1]= zspan->zmuly*(1.0+hoco[1]*div) + zspan->zofsy; + zco[2]= 0x7FFFFFFF *(hoco[2]*div); +} + +void zbufclipwire(ZSpan *zspan, int zvlnr, VlakRen *vlr) +{ + float vez[20], *f1, *f2, *f3, *f4= 0; int c1, c2, c3, c4, ec, and, or; /* edgecode: 1= draw */ @@ -1192,18 +884,18 @@ void zbufclipwire(int zvlnr, VlakRen *vlr) QUATCOPY(vez, f1); QUATCOPY(vez+4, f2); if( clipline(vez, vez+4)) { - hoco_to_zco(vez, vez); - hoco_to_zco(vez+4, vez+4); - zbuflinefunc(zvlnr, vez, vez+4); + hoco_to_zco(zspan, vez, vez); + hoco_to_zco(zspan, vez+4, vez+4); + zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); } } if(ec & ME_V2V3) { QUATCOPY(vez, f2); QUATCOPY(vez+4, f3); if( clipline(vez, vez+4)) { - hoco_to_zco(vez, vez); - hoco_to_zco(vez+4, vez+4); - zbuflinefunc(zvlnr, vez, vez+4); + hoco_to_zco(zspan, vez, vez); + hoco_to_zco(zspan, vez+4, vez+4); + zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); } } if(vlr->v4) { @@ -1211,18 +903,18 @@ void zbufclipwire(int zvlnr, VlakRen *vlr) QUATCOPY(vez, f3); QUATCOPY(vez+4, f4); if( clipline(vez, vez+4)) { - hoco_to_zco(vez, vez); - hoco_to_zco(vez+4, vez+4); - zbuflinefunc(zvlnr, vez, vez+4); + hoco_to_zco(zspan, vez, vez); + hoco_to_zco(zspan, vez+4, vez+4); + zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); } } if(ec & ME_V4V1) { QUATCOPY(vez, f4); QUATCOPY(vez+4, f1); if( clipline(vez, vez+4)) { - hoco_to_zco(vez, vez); - hoco_to_zco(vez+4, vez+4); - zbuflinefunc(zvlnr, vez, vez+4); + hoco_to_zco(zspan, vez, vez); + hoco_to_zco(zspan, vez+4, vez+4); + zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); } } } @@ -1231,9 +923,9 @@ void zbufclipwire(int zvlnr, VlakRen *vlr) QUATCOPY(vez, f3); QUATCOPY(vez+4, f1); if( clipline(vez, vez+4)) { - hoco_to_zco(vez, vez); - hoco_to_zco(vez+4, vez+4); - zbuflinefunc(zvlnr, vez, vez+4); + hoco_to_zco(zspan, vez, vez); + hoco_to_zco(zspan, vez+4, vez+4); + zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); } } } @@ -1242,36 +934,21 @@ void zbufclipwire(int zvlnr, VlakRen *vlr) } } - deler= f1[3]; - vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx; - vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity; - vez[2]= 0x7FFFFFFF *(f1[2]/deler); - - deler= f2[3]; - vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx; - vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity; - vez[6]= 0x7FFFFFFF *(f2[2]/deler); - - deler= f3[3]; - vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx; - vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity; - vez[10]= 0x7FFFFFFF *(f3[2]/deler); - + hoco_to_zco(zspan, vez, f1); + hoco_to_zco(zspan, vez+4, f2); + hoco_to_zco(zspan, vez+8, f3); if(vlr->v4) { - deler= f4[3]; - vez[12]= Zmulx*(1.0+f4[0]/deler)+ Zjitx; - vez[13]= Zmuly*(1.0+f4[1]/deler)+ Zjity; - vez[14]= 0x7FFFFFFF *(f4[2]/deler); + hoco_to_zco(zspan, vez+12, f4); - if(ec & ME_V3V4) zbuflinefunc(zvlnr, vez+8, vez+12); - if(ec & ME_V4V1) zbuflinefunc(zvlnr, vez+12, vez); + if(ec & ME_V3V4) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez+12); + if(ec & ME_V4V1) zspan->zbuflinefunc(zspan, zvlnr, vez+12, vez); } else { - if(ec & ME_V3V1) zbuflinefunc(zvlnr, vez+8, vez); + if(ec & ME_V3V1) zspan->zbuflinefunc(zspan, zvlnr, vez+8, vez); } - if(ec & ME_V1V2) zbuflinefunc(zvlnr, vez, vez+4); - if(ec & ME_V2V3) zbuflinefunc(zvlnr, vez+4, vez+8); + if(ec & ME_V1V2) zspan->zbuflinefunc(zspan, zvlnr, vez, vez+4); + if(ec & ME_V2V3) zspan->zbuflinefunc(zspan, zvlnr, vez+4, vez+8); } @@ -1286,95 +963,40 @@ void zbufclipwire(int zvlnr, VlakRen *vlr) * @param v2 [4 floats, world coordinates] second vertex * @param v3 [4 floats, world coordinates] third vertex */ -static void zbufinvulGLinv(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) +static void zbufinvulGLinv4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) { - double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; - double zxd,zyd,zy0,tmp; - float *minv,*maxv,*midv; - int *rectpofs,*rp; - int *rz,zverg,zvlak,x; - int my0,my2,sn1,sn2,rectx,zd,*rectzofs; - int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2; + double zxd, zyd, zy0, zverg; + float x0,y0,z0; + float x1,y1,z1,x2,y2,z2,xx1; + float *span1, *span2; + int *rectpofs, *rp; + int *rz, x, y; + int sn1, sn2, rectx, *rectzofs, my0, my2; - /* MIN MAX */ - if(v1[1] R.recty) return; - - if(my0<0) my0=0; - - /* EDGES : LONGEST */ - xx1= maxv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); - xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx0= 0; - xs0= 65536.0*(MIN2(minv[0],maxv[0])); - } - /* EDGES : THE TOP ONE */ - xx1= maxv[1]-midv[1]; - if(xx1>2.0/65536.0) { - z0= (maxv[0]-midv[0])/xx1; - - tmp= (-65536.0*z0); - dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); - xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx1= 0; - xs1= 65536.0*(MIN2(midv[0],maxv[0])); - } - /* EDGES : THE BOTTOM ONE */ - xx1= midv[1]-minv[1]; - if(xx1>2.0/65536.0) { - z0= (midv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); - xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx2= 0; - xs2= 65536.0*(MIN2(minv[0],midv[0])); - } - - /* ZBUF DX DY */ + else + zbuf_add_to_span(zspan, v3, v1); + + /* clipped */ + if(zspan->minp2==NULL || zspan->maxp2==NULL) return; + + if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1; + if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1; + + // printf("my %d %d\n", my0, my2); + if(my2= R.recty) { /* my2 can be larger */ - xs0+=dx0; - if (my2<=omsl) { - xs2+= dx2; - } - else{ - xs1+= dx1; - } - my2--; - } - - xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2]; - - zxd= -x0/z0; - zyd= -y0/z0; - zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); - + + xx1= (x0*v1[0] + y0*v1[1])/z0 + v1[2]; + + zxd= -(double)x0/(double)z0; + zyd= -(double)y0/(double)z0; + zy0= ((double)my2)*zyd + (double)xx1; + /* start-offset in rect */ - rectx= R.rectx; - rectzofs= (int *)(R.rectz+rectx*my2); - rectpofs= (R.rectot+rectx*my2); - zvlak= zvlnr; - - xs3= 0; /* flag */ - if(dx0>dx1) { - xs3= xs0; - xs0= xs1; - xs1= xs3; - xs3= dx0; - dx0= dx1; - dx1= xs3; - xs3= 1; /* flag */ - + rectx= zspan->rectx; + rectzofs= (zspan->rectz+rectx*my2); + rectpofs= (zspan->rectp+rectx*my2); + + /* correct span */ + sn1= (my0 + my2)/2; + if(zspan->span1[sn1] < zspan->span2[sn1]) { + span1= zspan->span1+my2; + span2= zspan->span2+my2; } - - for(y=my2;y>omsl;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs1>>16; - xs1+= dx1; - - sn1++; - + else { + span1= zspan->span2+my2; + span2= zspan->span1+my2; + } + + for(y=my2; y>=my0; y--, span1--, span2--) { + + sn1= floor(*span1); + sn2= floor(*span2); + sn1++; + if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - rp= rectpofs+sn1; - x= sn2-sn1; - while(x>=0) { - if(zverg> *rz || *rz==0x7FFFFFFF) { - *rz= zverg; - *rp= zvlak; + + if(sn2>=sn1) { + zverg= (double)sn1*zxd + zy0; + rz= rectzofs+sn1; + rp= rectpofs+sn1; + x= sn2-sn1; + + while(x>=0) { + if( (int)zverg > *rz || *rz==0x7FFFFFFF) { + *rz= (int)zverg; + *rp= zvlnr; + } + zverg+= zxd; + rz++; + rp++; + x--; } - zverg+= zd; - rz++; - rp++; - x--; } - zy0-=zyd; - rectzofs-= rectx; - rectpofs-= rectx; - } - - if(xs3) { - xs0= xs1; - dx0= dx1; - } - if(xs0>xs2) { - xs3= xs0; - xs0= xs2; - xs2= xs3; - xs3= dx0; - dx0= dx2; - dx2= xs3; - } - - for(;y>=my0;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs2>>16; - xs2+= dx2; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - rp= rectpofs+sn1; - x= sn2-sn1; - while(x>=0) { - if(zverg> *rz || *rz==0x7FFFFFFF) { - *rz= zverg; - *rp= zvlak; - } - zverg+= zd; - rz++; - rp++; - x--; - } - + zy0-=zyd; rectzofs-= rectx; rectpofs-= rectx; @@ -1516,14 +1077,18 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v int sn1, sn2, rectx, *rectzofs, my0, my2; /* init */ - zbuf_init_span(zspan, 0, R.recty); + zbuf_init_span(zspan); /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); - zbuf_add_to_span(zspan, v3, v4); - zbuf_add_to_span(zspan, v4, v1); - + if(v4) { + zbuf_add_to_span(zspan, v3, v4); + zbuf_add_to_span(zspan, v4, v1); + } + else + zbuf_add_to_span(zspan, v3, v1); + /* clipped */ if(zspan->minp2==NULL || zspan->maxp2==NULL) return; @@ -1554,9 +1119,9 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v zy0= ((double)my2)*zyd + (double)xx1; /* start-offset in rect */ - rectx= R.rectx; - rectzofs= (int *)(R.rectz+rectx*my2); - rectpofs= (R.rectot+rectx*my2); + rectx= zspan->rectx; + rectzofs= (zspan->rectz+rectx*my2); + rectpofs= (zspan->rectp+rectx*my2); /* correct span */ sn1= (my0 + my2)/2; @@ -1602,23 +1167,38 @@ static void zbufinvulGL4(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v } } -static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) +/** + * Fill the z buffer. The face buffer is not operated on! + * + * This is one of the z buffer fill functions called in zbufclip() and + * zbufwireclip(). + * + * @param v1 [4 floats, world coordinates] first vertex + * @param v2 [4 floats, world coordinates] second vertex + * @param v3 [4 floats, world coordinates] third vertex + */ + +static void zbufinvulGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3, float *v4) { - double x0,y0,z0; - double x1,y1,z1,x2,y2,z2,xx1; - double zxd, zyd, zy0, zverg, zd; + double zxd, zyd, zy0, zverg; + float x0,y0,z0; + float x1,y1,z1,x2,y2,z2,xx1; float *span1, *span2; - int *rectpofs, *rp; - int *rz, zvlak, x, y, my0, my2; - int sn1,sn2, rectx, *rectzofs; + int *rz, x, y; + int sn1, sn2, rectx, *rectzofs, my0, my2; /* init */ - zbuf_init_span(zspan, 0, R.recty); + zbuf_init_span(zspan); /* set spans */ zbuf_add_to_span(zspan, v1, v2); zbuf_add_to_span(zspan, v2, v3); - zbuf_add_to_span(zspan, v3, v1); + if(v4) { + zbuf_add_to_span(zspan, v3, v4); + zbuf_add_to_span(zspan, v4, v1); + } + else + zbuf_add_to_span(zspan, v3, v1); /* clipped */ if(zspan->minp2==NULL || zspan->maxp2==NULL) return; @@ -1626,9 +1206,11 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3 if(zspan->miny1 < zspan->miny2) my0= zspan->miny2; else my0= zspan->miny1; if(zspan->maxy1 > zspan->maxy2) my2= zspan->maxy2; else my2= zspan->maxy1; + // printf("my %d %d\n", my0, my2); if(my2rectx; + rectzofs= (zspan->rectz+rectx*my2); - /* find correct span */ + /* correct span */ sn1= (my0 + my2)/2; if(zspan->span1[sn1] < zspan->span2[sn1]) { span1= zspan->span1+my2; @@ -1669,264 +1248,26 @@ static void zbufinvulGL(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3 sn1= floor(*span1); sn2= floor(*span2); - sn1++; if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; if(sn2>=sn1) { - zverg= sn1*zxd+zy0; + zverg= (double)sn1*zxd + zy0; rz= rectzofs+sn1; - rp= rectpofs+sn1; x= sn2-sn1; while(x>=0) { - if(zverg< *rz) { - *rz= floor(zverg); - *rp= zvlak; + if( (int)zverg < *rz) { + *rz= (int)zverg; } - zverg+= zd; + zverg+= zxd; rz++; - rp++; x--; } } - zy0-=zyd; - rectzofs-= rectx; - rectpofs-= rectx; - } -} - - - -/** - * Fill the z buffer. The face buffer is not operated on! - * - * This is one of the z buffer fill functions called in zbufclip() and - * zbufwireclip(). - * - * @param v1 [4 floats, world coordinates] first vertex - * @param v2 [4 floats, world coordinates] second vertex - * @param v3 [4 floats, world coordinates] third vertex - */ - -static void zbufinvulGL_onlyZ(ZSpan *zspan, int zvlnr, float *v1, float *v2, float *v3) -{ - double x0,y0,z0,x1,y1,z1,x2,y2,z2,xx1; - double zxd,zyd,zy0,tmp; - float *minv,*maxv,*midv; - int *rz,zverg,x; - int my0,my2,sn1,sn2,rectx,zd,*rectzofs; - int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2; - - /* MIN MAX */ - if(v1[1] R.recty) return; - - if(my0<0) my0=0; - - /* EDGES : LONGEST */ - xx1= maxv[1]-minv[1]; - if(xx1!=0.0) { - z0= (maxv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx0= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-minv[1])+minv[0]); - xs0= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx0= 0; - xs0= 65536.0*(MIN2(minv[0],maxv[0])); - } - /* EDGES : TOP */ - xx1= maxv[1]-midv[1]; - if(xx1!=0.0) { - z0= (maxv[0]-midv[0])/xx1; - - tmp= (-65536.0*z0); - dx1= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(my2-midv[1])+midv[0]); - xs1= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx1= 0; - xs1= 65536.0*(MIN2(midv[0],maxv[0])); - } - /* EDGES : BOTTOM */ - xx1= midv[1]-minv[1]; - if(xx1!=0.0) { - z0= (midv[0]-minv[0])/xx1; - - tmp= (-65536.0*z0); - dx2= CLAMPIS(tmp, INT_MIN, INT_MAX); - - tmp= 65536.0*(z0*(omsl-minv[1])+minv[0]); - xs2= CLAMPIS(tmp, INT_MIN, INT_MAX); - } - else { - dx2= 0; - xs2= 65536.0*(MIN2(minv[0],midv[0])); - } - - /* ZBUF DX DY */ - x1= v1[0]- v2[0]; - x2= v2[0]- v3[0]; - y1= v1[1]- v2[1]; - y2= v2[1]- v3[1]; - z1= v1[2]- v2[2]; - z2= v2[2]- v3[2]; - x0= y1*z2-z1*y2; - y0= z1*x2-x1*z2; - z0= x1*y2-y1*x2; - - if(z0==0.0) return; - - if(midv[1]==maxv[1]) omsl= my2; - if(omsl<0) omsl= -1; /* then it takes first loop entirely */ - - while (my2 >= R.recty) { /* my2 can be larger */ - xs0+=dx0; - if (my2<=omsl) { - xs2+= dx2; - } - else{ - xs1+= dx1; - } - my2--; - } - - xx1= (x0*v1[0]+y0*v1[1])/z0+v1[2]; - - zxd= -x0/z0; - zyd= -y0/z0; - zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); - - /* start-offset in rect */ - rectx= R.rectx; - rectzofs= (int *)(R.rectz+rectx*my2); - - xs3= 0; /* flag */ - if(dx0>dx1) { - xs3= xs0; - xs0= xs1; - xs1= xs3; - xs3= dx0; - dx0= dx1; - dx1= xs3; - xs3= 1; /* flag */ - - } - - for(y=my2;y>omsl;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs1>>16; - xs1+= dx1; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - - x= sn2-sn1; - while(x>=0) { - if(zverg< *rz) { - *rz= zverg; - } - zverg+= zd; - rz++; - x--; - } - zy0-=zyd; - rectzofs-= rectx; - } - - if(xs3) { - xs0= xs1; - dx0= dx1; - } - if(xs0>xs2) { - xs3= xs0; - xs0= xs2; - xs2= xs3; - xs3= dx0; - dx0= dx2; - dx2= xs3; - } - - for(;y>=my0;y--) { - - sn1= xs0>>16; - xs0+= dx0; - - sn2= xs2>>16; - xs2+= dx2; - - sn1++; - - if(sn2>=rectx) sn2= rectx-1; - if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); - rz= rectzofs+sn1; - - x= sn2-sn1; - while(x>=0) { - if(zverg< *rz) { - *rz= zverg; - } - zverg+= zd; - rz++; - x--; - } - zy0-=zyd; rectzofs-= rectx; } @@ -1958,7 +1299,7 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a db= v2[3]-v1[3]; /* according the original article by Liang&Barsky, for clipping of - * homeginic coordinates with viewplane, the value of "0" is used instead of "-w" . + * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" . * This differs from the other clipping cases (like left or top) and I considered * it to be not so 'homogenic'. But later it has proven to be an error, * who would have thought that of L&B! @@ -2032,7 +1373,7 @@ static void makevertpyra(float *vez, float *labda, float **trias, float *v1, flo /* ------------------------------------------------------------------------- */ -void RE_projectverto(float *v1, float *adr) +void projectverto(float *v1, float winmat[][4], float *adr) { /* calcs homogenic coord of vertex v1 */ float x,y,z; @@ -2040,17 +1381,17 @@ void RE_projectverto(float *v1, float *adr) x= v1[0]; y= v1[1]; z= v1[2]; - adr[0]= x*R.winmat[0][0] + z*R.winmat[2][0] + R.winmat[3][0]; - adr[1]= y*R.winmat[1][1] + z*R.winmat[2][1] + R.winmat[3][1]; - adr[2]= z*R.winmat[2][2] + R.winmat[3][2]; - adr[3]= z*R.winmat[2][3] + R.winmat[3][3]; + adr[0]= x*winmat[0][0] + z*winmat[2][0] + winmat[3][0]; + adr[1]= y*winmat[1][1] + z*winmat[2][1] + winmat[3][1]; + adr[2]= z*winmat[2][2] + winmat[3][2]; + adr[3]= z*winmat[2][3] + winmat[3][3]; //printf("hoco %f %f %f %f\n", adr[0], adr[1], adr[2], adr[3]); } /* ------------------------------------------------------------------------- */ -void projectvert(float *v1, float *adr) +void projectvert(float *v1, float winmat[][4], float *adr) { /* calcs homogenic coord of vertex v1 */ float x,y,z; @@ -2058,17 +1399,16 @@ void projectvert(float *v1, float *adr) x= v1[0]; y= v1[1]; z= v1[2]; - adr[0]= x*R.winmat[0][0]+ y*R.winmat[1][0]+ z*R.winmat[2][0]+ R.winmat[3][0]; - adr[1]= x*R.winmat[0][1]+ y*R.winmat[1][1]+ z*R.winmat[2][1]+ R.winmat[3][1]; - adr[2]= x*R.winmat[0][2]+ y*R.winmat[1][2]+ z*R.winmat[2][2]+ R.winmat[3][2]; - adr[3]= x*R.winmat[0][3]+ y*R.winmat[1][3]+ z*R.winmat[2][3]+ R.winmat[3][3]; + adr[0]= x*winmat[0][0]+ y*winmat[1][0]+ z*winmat[2][0]+ winmat[3][0]; + adr[1]= x*winmat[0][1]+ y*winmat[1][1]+ z*winmat[2][1]+ winmat[3][1]; + adr[2]= x*winmat[0][2]+ y*winmat[1][2]+ z*winmat[2][2]+ winmat[3][2]; + adr[3]= x*winmat[0][3]+ y*winmat[1][3]+ z*winmat[2][3]+ winmat[3][3]; } /* do zbuffering and clip, f1 f2 f3 are hocos, c1 c2 c3 are clipping flags */ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, int c2, int c3) { - float deler; float *vlzp[32][3], labda[3][2]; float vez[400], *trias[40]; @@ -2127,7 +1467,7 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, clipflag[1]= clipflag[2]= 0; f1= vez; for(b3=0; b3zbuffunc(zspan, zvlnr, vlzp[b][0],vlzp[b][1],vlzp[b][2], NULL); } } return; @@ -2171,28 +1508,15 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, } /* perspective division: HCS to ZCS */ - - deler= f1[3]; - vez[0]= Zmulx*(1.0+f1[0]/deler)+ Zjitx; - vez[1]= Zmuly*(1.0+f1[1]/deler)+ Zjity; - vez[2]= 0x7FFFFFFF *(f1[2]/deler); + hoco_to_zco(zspan, vez, f1); + hoco_to_zco(zspan, vez+4, f2); + hoco_to_zco(zspan, vez+8, f3); - deler= f2[3]; - vez[4]= Zmulx*(1.0+f2[0]/deler)+ Zjitx; - vez[5]= Zmuly*(1.0+f2[1]/deler)+ Zjity; - vez[6]= 0x7FFFFFFF *(f2[2]/deler); - - deler= f3[3]; - vez[8]= Zmulx*(1.0+f3[0]/deler)+ Zjitx; - vez[9]= Zmuly*(1.0+f3[1]/deler)+ Zjity; - vez[10]= 0x7FFFFFFF *(f3[2]/deler); - - zbuffunc(zspan, zvlnr, vez,vez+4,vez+8); + zspan->zbuffunc(zspan, zvlnr, vez,vez+4,vez+8, NULL); } static void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, float *f4, int c1, int c2, int c3, int c4) { - float div; float vez[16]; if(c1 | c2 | c3 | c4) { /* not in middle */ @@ -2206,83 +1530,144 @@ static void zbufclip4(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, } /* perspective division: HCS to ZCS */ + hoco_to_zco(zspan, vez, f1); + hoco_to_zco(zspan, vez+4, f2); + hoco_to_zco(zspan, vez+8, f3); + hoco_to_zco(zspan, vez+12, f4); - div= 1.0f/f1[3]; - vez[0]= Zmulx*(1.0+f1[0]*div)+ Zjitx; - vez[1]= Zmuly*(1.0+f1[1]*div)+ Zjity; - vez[2]= 0x7FFFFFFF *(f1[2]*div); - - div= 1.0f/f2[3]; - vez[4]= Zmulx*(1.0+f2[0]*div)+ Zjitx; - vez[5]= Zmuly*(1.0+f2[1]*div)+ Zjity; - vez[6]= 0x7FFFFFFF *(f2[2]*div); - - div= 1.0f/f3[3]; - vez[8]= Zmulx*(1.0+f3[0]*div)+ Zjitx; - vez[9]= Zmuly*(1.0+f3[1]*div)+ Zjity; - vez[10]= 0x7FFFFFFF *(f3[2]*div); - - div= 1.0f/f4[3]; - vez[12]= Zmulx*(1.0+f4[0]*div)+ Zjitx; - vez[13]= Zmuly*(1.0+f4[1]*div)+ Zjity; - vez[14]= 0x7FFFFFFF *(f4[2]*div); - - zbuffunc4(zspan, zvlnr, vez, vez+4, vez+8, vez+12); + zspan->zbuffunc(zspan, zvlnr, vez, vez+4, vez+8, vez+12); } /* ***************** ZBUFFER MAIN ROUTINES **************** */ +void set_part_zbuf_clipflag(RenderPart *pa) +{ + VertRen *ver=NULL; + float minx, miny, maxx, maxy, wco; + unsigned short clipclear; + int v; -void zbufferall(void) + minx= (2*pa->disprect.xmin - R.winx-1)/(float)R.winx; + maxx= (2*pa->disprect.xmax - R.winx+1)/(float)R.winx; + miny= (2*pa->disprect.ymin - R.winy-1)/(float)R.winy; + maxy= (2*pa->disprect.ymax - R.winy+1)/(float)R.winy; + + /* supports up to 4 threads this way */ + clipclear= ~(15 << 4*(pa->thread & 3)); + + for(v=0; vho[3]; + ver->flag &= clipclear; + + switch(pa->thread & 3) { + case 0: + if( ver->ho[0] > maxx*wco) ver->flag |= 1; + else if( ver->ho[0]< minx*wco) ver->flag |= 2; + if( ver->ho[1] > maxy*wco) ver->flag |= 4; + else if( ver->ho[1]< miny*wco) ver->flag |= 8; + break; + case 1: + if( ver->ho[0] > maxx*wco) ver->flag |= 16; + else if( ver->ho[0]< minx*wco) ver->flag |= 32; + if( ver->ho[1] > maxy*wco) ver->flag |= 64; + else if( ver->ho[1]< miny*wco) ver->flag |= 128; + break; + case 2: + if( ver->ho[0] > maxx*wco) ver->flag |= 256; + else if( ver->ho[0]< minx*wco) ver->flag |= 512; + if( ver->ho[1] > maxy*wco) ver->flag |= 1024; + else if( ver->ho[1]< miny*wco) ver->flag |= 2048; + break; + case 3: + if( ver->ho[0] > maxx*wco) ver->flag |= 4096; + else if( ver->ho[0]< minx*wco) ver->flag |= 8192; + if( ver->ho[1] > maxy*wco) ver->flag |= 16384; + else if( ver->ho[1]< miny*wco) ver->flag |= 32768; + break; + } + } +} + +void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag) { ZSpan zspan; VlakRen *vlr= NULL; Material *ma=0; int v, zvlnr; + unsigned short clipmask; short transp=0, env=0, wire=0; - Zmulx= ((float)R.rectx)/2.0; - Zmuly= ((float)R.recty)/2.0; - - fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF); - - zbuf_alloc_span(&zspan, R.recty); + zbuf_alloc_span(&zspan, pa->rectx, pa->recty); - zbuffunc= zbufinvulGL; - zbuffunc4= zbufinvulGL4; - zbuflinefunc= zbufline; + /* needed for transform from hoco to zbuffer co */ + zspan.zmulx= ((float)R.winx)/2.0; + zspan.zmuly= ((float)R.winy)/2.0; + if(R.osa) { + zspan.zofsx= -pa->disprect.xmin - R.jit[pa->sample][0]; + zspan.zofsy= -pa->disprect.ymin - R.jit[pa->sample][1]; + } + else { + zspan.zofsx= -pa->disprect.xmin -0.5f; + zspan.zofsy= -pa->disprect.ymin -0.5f; + } + + /* the buffers */ + zspan.rectz= pa->rectz; + zspan.rectp= pa->rectp; + fillrect(pa->rectp, pa->rectx, pa->recty, 0); + fillrect(pa->rectz, pa->rectx, pa->recty, 0x7FFFFFFF); + + /* filling methods */ + zspan.zbuffunc= zbufinvulGL4; + zspan.zbuflinefunc= zbufline; + + /* part clipflag, threaded */ + clipmask= (15 << 4*(pa->thread & 3)); for(v=0; v>8]; else vlr++; - if(vlr->flag & R_VISIBLE) { + if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) { if(vlr->mat!=ma) { ma= vlr->mat; transp= ma->mode & MA_ZTRA; env= (ma->mode & MA_ENV); wire= (ma->mode & MA_WIRE); - if(ma->mode & MA_ZINV) zbuffunc= zbufinvulGLinv; - else zbuffunc= zbufinvulGL; + if(ma->mode & MA_ZINV) zspan.zbuffunc= zbufinvulGLinv4; + else zspan.zbuffunc= zbufinvulGL4; } if(transp==0) { - if(env) zvlnr= 0; - else zvlnr= v+1; + unsigned short partclip; - if(wire) zbufclipwire(zvlnr, vlr); - else { - if(vlr->v4 && (vlr->flag & R_STRAND)) { - zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip); - } + /* partclipping doesn't need viewplane clipping */ + if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag; + else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag; + + if((partclip & clipmask)==0) { + + if(env) zvlnr= 0; + else zvlnr= v+1; + + if(wire) zbufclipwire(&zspan, zvlnr, vlr); else { - zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); - if(vlr->v4) { - if(zvlnr) zvlnr+= 0x800000; - zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); + /* strands allow to be filled in as quad */ + if(vlr->v4 && (vlr->flag & R_STRAND)) { + zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip); + } + else { + zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); + if(vlr->v4) { + if(zvlnr) zvlnr+= 0x800000; + zbufclip(&zspan, zvlnr, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); + } } } } @@ -2293,11 +1678,19 @@ void zbufferall(void) zbuf_free_span(&zspan); } -static int hashlist_projectvert(float *v1, float *hoco) +typedef struct { + float *vert; + float hoco[4]; + int clip; +} VertBucket; + +/* warning, not threaded! */ +static int hashlist_projectvert(float *v1, float winmat[][4], float *hoco) { static VertBucket bucket[256], *buck; - if(v1==0) { + /* init static bucket */ + if(v1==NULL) { memset(bucket, 0, 256*sizeof(VertBucket)); return 0; } @@ -2308,49 +1701,42 @@ static int hashlist_projectvert(float *v1, float *hoco) return buck->clip; } - projectvert(v1, hoco); - buck->clip = RE_testclip(hoco); + projectvert(v1, winmat, hoco); + buck->clip = testclip(hoco); buck->vert= v1; QUATCOPY(buck->hoco, 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) +void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Render *re) { ZSpan zspan; - float hoco[4][4]; + float hoco[4][4], winmat[4][4]; int a, zvlnr; int c1, c2, c3, c4= 0; - int *rectoto, *rectzo; - int rectxo, rectyo; if(rg_totelem==0) return; - hashlist_projectvert(NULL, NULL); + hashlist_projectvert(NULL, winmat, NULL); - rectxo= R.rectx; - rectyo= R.recty; - rectoto= R.rectot; - rectzo= R.rectz; - - R.rectx= vw->rectx; - R.recty= vw->recty; - R.rectot= vw->rect; - R.rectz= vw->rectz; - - Zmulx= ((float)R.rectx)/2.0; - Zmuly= ((float)R.recty)/2.0; - /* needed for projectvert */ - MTC_Mat4MulMat4(R.winmat, vw->viewmat, vw->winmat); + MTC_Mat4MulMat4(winmat, vw->viewmat, vw->winmat); - fillrect(R.rectz, R.rectx, R.recty, 0x7FFFFFFF); - fillrect(R.rectot, R.rectx, R.recty, 0xFFFFFF); - - zbuf_alloc_span(&zspan, R.recty); + zbuf_alloc_span(&zspan, vw->rectx, vw->recty); + zspan.zmulx= ((float)vw->rectx)/2.0; + zspan.zmuly= ((float)vw->recty)/2.0; + zspan.zofsx= 0; + zspan.zofsy= 0; - zbuffunc= zbufinvulGL; + /* the buffers */ + zspan.rectz= vw->rectz; + zspan.rectp= vw->rect; + fillrect(zspan.rectz, vw->rectx, vw->recty, 0x7FFFFFFF); + fillrect(zspan.rectp, vw->rectx, vw->recty, 0xFFFFFF); + + /* filling methods */ + zspan.zbuffunc= zbufinvulGL4; if(rg_elem) { /* radio tool */ RNode **re, *rn; @@ -2365,18 +1751,18 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) else if( rn->f & RAD_BACKFACE) zvlnr= 0xFFFFFF; else zvlnr= a; - c1= hashlist_projectvert(rn->v1, hoco[0]); - c2= hashlist_projectvert(rn->v2, hoco[1]); - c3= hashlist_projectvert(rn->v3, hoco[2]); + 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, hoco[3]); + c4= hashlist_projectvert(rn->v4, winmat, hoco[3]); } - zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - if(rn->v4) { - zbufclip(&zspan, zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4); - } + if(rn->v4) + zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); + else + zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); } } } @@ -2385,8 +1771,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) RadFace *rf; int totface=0; - for(a=0; a>8]; else vlr++; + for(a=0; atotvlak; a++) { + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->radface) { rf= vlr->radface; @@ -2396,34 +1782,28 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem) else if( rf->flag & RAD_BACKFACE) zvlnr= 0xFFFFFF; /* receives no energy, but is zbuffered */ else zvlnr= totface; - c1= hashlist_projectvert(vlr->v1->co, hoco[0]); - c2= hashlist_projectvert(vlr->v2->co, hoco[1]); - c3= hashlist_projectvert(vlr->v3->co, hoco[2]); + 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, hoco[3]); + c4= hashlist_projectvert(vlr->v4->co, winmat, hoco[3]); } - zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); - if(vlr->v4) { - zbufclip(&zspan, zvlnr, hoco[0], hoco[2], hoco[3], c1, c3, c4); - } + if(vlr->v4) + zbufclip4(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], hoco[3], c1, c2, c3, c4); + else + zbufclip(&zspan, zvlnr, hoco[0], hoco[1], hoco[2], c1, c2, c3); } totface++; } } } - - /* restore */ - R.rectx= rectxo; - R.recty= rectyo; - R.rectot= rectoto; - R.rectz= rectzo; zbuf_free_span(&zspan); } -void zbuffershad(LampRen *lar) +void zbuffer_shadow(Render *re, LampRen *lar, int *rectz, int size) { ZSpan zspan; VlakRen *vlr= NULL; @@ -2432,20 +1812,23 @@ void zbuffershad(LampRen *lar) if(lar->mode & LA_LAYER) lay= lar->lay; - Zmulx= ((float)R.rectx)/2.0; - Zmuly= ((float)R.recty)/2.0; - Zjitx= Zjity= -0.5; - - fillrect(R.rectz,R.rectx,R.recty,0x7FFFFFFE); - - zbuf_alloc_span(&zspan, R.recty); + zbuf_alloc_span(&zspan, size, size); + zspan.zmulx= ((float)size)/2.0; + zspan.zmuly= ((float)size)/2.0; + zspan.zofsx= -0.5f; + zspan.zofsy= -0.5f; - zbuflinefunc= zbufline_onlyZ; - zbuffunc= zbufinvulGL_onlyZ; + /* the buffers */ + zspan.rectz= rectz; + fillrect(rectz, size, size, 0x7FFFFFFE); + + /* filling methods */ + zspan.zbuflinefunc= zbufline_onlyZ; + zspan.zbuffunc= zbufinvulGL_onlyZ; - for(a=0;atotvlak; a++) { - if((a & 255)==0) vlr= R.blovl[a>>8]; + if((a & 255)==0) vlr= re->blovl[a>>8]; else vlr++; if(vlr->mat!= ma) { @@ -2455,11 +1838,13 @@ void zbuffershad(LampRen *lar) } if(ok && (vlr->flag & R_VISIBLE) && (vlr->lay & lay)) { - if(ma->mode & MA_WIRE) zbufclipwire(a+1, vlr); - else if(vlr->flag & R_STRAND) zbufclipwire(a+1, vlr); + if(ma->mode & MA_WIRE) zbufclipwire(&zspan, a+1, vlr); + else if(vlr->flag & R_STRAND) zbufclipwire(&zspan, a+1, vlr); else { - zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); - if(vlr->v4) zbufclip(&zspan, 0, vlr->v1->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v3->clip, vlr->v4->clip); + if(vlr->v4) + zbufclip4(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip); + else + zbufclip(&zspan, 0, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip); } } } @@ -2470,57 +1855,31 @@ void zbuffershad(LampRen *lar) /* ******************** ABUF ************************* */ - -void bgnaccumbuf(void) -{ - - Arectz= MEM_mallocN(sizeof(int)*ABUFPART*R.rectx, "Arectz"); - APixbuf= MEM_mallocN(ABUFPART*R.rectx*sizeof(APixstr), "APixbuf"); - - Aminy= -1000; - Amaxy= -1000; - - apsmteller= 0; - apsmfirst.next= 0; - apsmfirst.ps= 0; -} -/* ------------------------------------------------------------------------ */ - -void endaccumbuf(void) -{ - - MEM_freeN(Arectz); - MEM_freeN(APixbuf); - freepsA(); -} - -/* ------------------------------------------------------------------------ */ - /** * Copy results from the solid face z buffering to the transparent * buffer. */ -static void copyto_abufz(int sample) +static void copyto_abufz(RenderPart *pa, int *arectz, int sample) { PixStr *ps; int x, y, *rza; long *rd; /* now, in OSA the pixstructs contain all faces filled in */ - if(R.r.mode & R_OSA) fillrect(Arectz, R.rectx, Amaxy-Aminy+1, 0x7FFFFFFF); + if(R.r.mode & R_OSA) fillrect(arectz, pa->rectx, pa->recty, 0x7FFFFFFF); else { - memcpy(Arectz, R.rectz+ R.rectx*Aminy, 4*R.rectx*(Amaxy-Aminy+1)); + memcpy(arectz, pa->rectz, 4*pa->rectx*pa->recty); return; } - //if( (R.r.mode & R_OSA)==0 || sample==0) return; + if( (R.r.mode & R_OSA)==0 || sample==0) return; - rza= Arectz; - rd= (R.rectdaps+ R.rectx*Aminy); + rza= arectz; + rd= pa->rectdaps; sample= (1<recty; y++) { + for(x=0; xrectx; x++) { if(*rd) { ps= (PixStr *)(*rd); @@ -2547,95 +1906,60 @@ static void copyto_abufz(int sample) * Do accumulation z buffering. */ - -static void set_faces_raycountflag(void) -{ - VertRen *ver=NULL; - VlakRen *vlr=NULL; - float wco, miny, maxy; - int v, clipval; - - miny= (float)(2*Aminy-R.recty-1)/(float)R.recty; - maxy= (float)(2*Amaxy-R.recty+2)/(float)R.recty; - - for(v=0; v>8]; - } - else ver++; - - wco= ver->ho[3]; - ver->flag= 0; - if( ver->ho[1] > maxy*wco) ver->flag |= 64; - else if( ver->ho[1]< miny*wco) ver->flag |= 128; - } - - for(v=0; v>8]; - } - else vlr++; - - if(vlr->v4) - clipval= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag; - else - clipval= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag; - - if(clipval==64 || clipval==128) - vlr->raycount= 0; - else - vlr->raycount= 1; - } -} - - -static void zbuffer_abuf() +static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, unsigned int lay, short layflag) { ZSpan zspan; Material *ma=0; VlakRen *vlr=NULL; float vec[3], hoco[4], mul, zval, fval; - int v, zvlnr; - int len; + int v, zvlnr, zsample; + unsigned short clipmask; - Zjitx= Zjity= -0.5; - Zmulx= ((float)R.rectx)/2.0; - Zmuly= ((float)R.recty)/2.0; - - /* clear APixstructs */ - len= sizeof(APixstr)*R.rectx*ABUFPART; - memset(APixbuf, 0, len); + zbuf_alloc_span(&zspan, pa->rectx, pa->recty); - zbuf_alloc_span(&zspan, R.recty); + /* needed for transform from hoco to zbuffer co */ + zspan.zmulx= ((float)R.winx)/2.0; + zspan.zmuly= ((float)R.winy)/2.0; + zspan.zofsx= -pa->disprect.xmin -0.5f; + zspan.zofsy= -pa->disprect.ymin -0.5f; - zbuffunc= zbufinvulAc; - zbuffunc4= zbufinvulAc4; - zbuflinefunc= zbuflineAc; - - set_faces_raycountflag(); + /* the buffers */ + zspan.arectz= RE_mallocN(sizeof(int)*pa->rectx*pa->recty, "Arectz"); + zspan.apixbuf= APixbuf; + zspan.apsmbase= apsmbase; - for(Zsample=0; Zsamplethread & 3)); + + for(zsample=0; zsampledisprect.xmin-R.jit[zsample][0]-0.5; + zspan.zofsy= -pa->disprect.ymin-R.jit[zsample][1]-0.5; } for(v=0; v>8]; - } else vlr++; - if(vlr->raycount) { - ma= vlr->mat; - - if(ma->mode & (MA_ZTRA)) { - - if(vlr->flag & R_VISIBLE) { - + ma= vlr->mat; + if(ma->mode & (MA_ZTRA)) { + if((vlr->flag & R_VISIBLE) && (vlr->lay & lay)) { + unsigned short partclip; + + /* partclipping doesn't need viewplane clipping */ + if(vlr->v4) partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag & vlr->v4->flag; + else partclip= vlr->v1->flag & vlr->v2->flag & vlr->v3->flag; + + if((partclip & clipmask)==0) { /* a little advantage for transp rendering (a z offset) */ if( ma->zoffs != 0.0) { mul= 0x7FFFFFFF; @@ -2644,16 +1968,16 @@ static void zbuffer_abuf() VECCOPY(vec, vlr->v1->co); /* z is negative, otherwise its being clipped */ vec[2]-= ma->zoffs; - RE_projectverto(vec, hoco); + projectverto(vec, R.winmat, hoco); fval= mul*(1.0+hoco[2]/hoco[3]); - Azvoordeel= (int) fabs(zval - fval ); + zspan.polygon_offset= (int) fabs(zval - fval ); } - else Azvoordeel= 0; + else zspan.polygon_offset= 0; zvlnr= v+1; - if(ma->mode & (MA_WIRE)) zbufclipwire(zvlnr, vlr); + if(ma->mode & (MA_WIRE)) zbufclipwire(&zspan, zvlnr, vlr); else { if(vlr->v4 && (vlr->flag & R_STRAND)) { zbufclip4(&zspan, zvlnr, vlr->v1->ho, vlr->v2->ho, vlr->v3->ho, vlr->v4->ho, vlr->v1->clip, vlr->v2->clip, vlr->v3->clip, vlr->v4->clip); @@ -2667,21 +1991,23 @@ static void zbuffer_abuf() } } } - if( (v & 255)==255) - if(RE_local_test_break()) - break; } + if( (v & 255)==255) + if(R.test_break()) + break; } } if((R.r.mode & R_OSA)==0) break; - if(RE_local_test_break()) break; + if(R.test_break()) break; } + RE_freeN(zspan.arectz); zbuf_free_span(&zspan); + } -int vergzvlak(const void *a1, const void *a2) +static int vergzvlak(const void *a1, const void *a2) { const int *x1=a1, *x2=a2; @@ -2693,22 +2019,23 @@ int vergzvlak(const void *a1, const void *a2) /** * Shade this face at this location in SCS. */ -static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *fcol) +static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, int mask, float *fcol) { + float rco[3]; if( (facenr & 0x7FFFFF) > R.totvlak) { printf("error in shadetrapixel nr: %d\n", (facenr & 0x7FFFFF)); return; } if(R.r.mode & R_OSA) { - VlakRen *vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF); + VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & 0x7FFFFF); float accumcol[4]={0,0,0,0}, tot=0.0; int a; if(vlr->flag & R_FULL_OSA) { for(a=0; a>4]; - shadepixel(x, y, z, facenr, mask, fcol); + int b= R.samples->centmask[mask]; + x= x+R.samples->centLut[b & 15]; + y= y+R.samples->centLut[b>>4]; + shadepixel(pa, x, y, z, facenr, mask, fcol, rco); } } - else shadepixel(x, y, z, facenr, mask, fcol); + else shadepixel(pa, x, y, z, facenr, mask, fcol, rco); } static int addtosampcol(float *sampcol, float *fcol, int mask) @@ -2748,29 +2072,31 @@ static int addtosampcol(float *sampcol, float *fcol, int mask) return retval; } -/* - * renders when needed the Abuffer with faces stored in pixels, returns 1 scanline rendered - */ - #define MAX_ZROW 1000 -void abufsetrow(float *acolrow, int y) +/* main render call to fill in pass the full transparent layer */ + +void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short layflag) { - extern SDL_mutex *render_abuf_lock; // initrender.c + APixstr *APixbuf; /* Zbuffer: linked list of face samples */ APixstr *ap, *apn; - float *col, fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4]; - float ys, fac, alpha[32]; - int x, part, a, zrow[MAX_ZROW][3], totface, nr; + ListBase apsmbase={NULL, NULL}; + float col[4], fcol[4], tempcol[4], sampcol[16*4], *scol, accumcol[4]; + float fac, alpha[32]; + int x, y, a, zrow[MAX_ZROW][3], totface, nr; int sval; - if(y<0) return; + /* looks nicer for calling code */ + if(R.test_break()) + return; + + APixbuf= RE_callocN(pa->rectx*pa->recty*sizeof(APixstr), "APixbuf"); + if(R.osa>16) { printf("abufsetrow: osa too large\n"); G.afbreek= 1; return; } - - //R.flag &= ~R_LAMPHALO; - + /* alpha LUT */ if(R.r.mode & R_OSA ) { fac= (1.0/(float)R.osa); @@ -2778,146 +2104,165 @@ void abufsetrow(float *acolrow, int y) alpha[a]= (float)a*fac; } } + + /* fill the Apixbuf */ + zbuffer_abuf(pa, APixbuf, &apsmbase, lay, layflag); + + /* render tile */ + ap= APixbuf; + + for(y=pa->disprect.ymin; ydisprect.ymax; y++) { + for(x=pa->disprect.xmin; xdisprect.xmax; x++, ap++, pass+=4) { - if(R.r.mode & R_THREADS) { - /* lock thread if... */ - if(y>Aminy+2 && yAmaxy) { - part= (y/ABUFPART); - Aminy= part*ABUFPART; - Amaxy= Aminy+ABUFPART-1; - if(Amaxy>=R.recty) Amaxy= R.recty-1; - freepsA(); - zbuffer_abuf(); - } - - /* render row */ - col= acolrow; - memset(col, 0, 4*sizeof(float)*R.rectx); - ap= APixbuf + R.rectx*(y-Aminy); - ys= y; - - for(x=0; xp[0]) { - /* sort in z */ - totface= 0; - apn= ap; - while(apn) { - for(a=0; a<4; a++) { - if(apn->p[a]) { - zrow[totface][0]= apn->z[a]; - zrow[totface][1]= apn->p[a]; - zrow[totface][2]= apn->mask[a]; - totface++; - if(totface>=MAX_ZROW) totface= MAX_ZROW-1; + if(ap->p[0]) { + /* sort in z */ + totface= 0; + apn= ap; + while(apn) { + for(a=0; a<4; a++) { + if(apn->p[a]) { + zrow[totface][0]= apn->z[a]; + zrow[totface][1]= apn->p[a]; + zrow[totface][2]= apn->mask[a]; + totface++; + if(totface>=MAX_ZROW) totface= MAX_ZROW-1; + } + else break; } - else break; + apn= apn->next; } - apn= apn->next; - } - - if(totface==1) { - shadetrapixel((float)x, (float)y, zrow[0][0], zrow[0][1], zrow[0][2], fcol); - - nr= count_mask(zrow[0][2]); - if( (R.r.mode & R_OSA) && nr2 */ + qsort(zrow, totface, sizeof(int)*3, vergzvlak); } - - } - else { /* totface>2 */ - qsort(zrow, totface, sizeof(int)*3, vergzvlak); - } - - /* join when pixels are adjacent */ - - while(totface>0) { - totface--; - shadetrapixel((float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol); + /* join when pixels are adjacent */ - a= count_mask(zrow[totface][2]); - if( (R.r.mode & R_OSA ) && a0) { - memset(sampcol, 0, 4*sizeof(float)*R.osa); - sval= addtosampcol(sampcol, fcol, zrow[totface][2]); - - /* sval==0: alpha completely full */ - while( (sval != 0) && (totface>0) ) { - a= count_mask(zrow[totface-1][2]); - if(a==R.osa) break; - totface--; - - shadetrapixel((float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol); + while(totface>0) { + totface--; + + shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol); + + a= count_mask(zrow[totface][2]); + if( (R.r.mode & R_OSA ) && a0) { + memset(sampcol, 0, 4*sizeof(float)*R.osa); sval= addtosampcol(sampcol, fcol, zrow[totface][2]); + + /* sval==0: alpha completely full */ + while( (sval != 0) && (totface>0) ) { + a= count_mask(zrow[totface-1][2]); + if(a==R.osa) break; + totface--; + + shadetrapixel(pa, (float)x, (float)y, zrow[totface][0], zrow[totface][1], zrow[totface][2], fcol); + sval= addtosampcol(sampcol, fcol, zrow[totface][2]); + } + + scol= sampcol; + accumcol[0]= scol[0]; accumcol[1]= scol[1]; + accumcol[2]= scol[2]; accumcol[3]= scol[3]; + scol+= 4; + for(a=1; a=0.999) break; + } + else addAlphaUnderFloat(col, fcol); /* no osa or full pixel with same face? */ + + if(col[3]>=0.999) break; + } } + if(col[3]!=0.0) addAlphaOverFloat(pass, col); } } } - if(R.r.mode & R_THREADS) { - if(y>Aminy+2 && yrectz==NULL) return; + if(rl->rectz==NULL) { + printf("called convert zbuf wrong...\n"); + return; + } + rectzf= rl->rectz; + rectz= pa->rectz; + + for(a=pa->rectx*pa->recty; a>0; a--, rectz++, rectzf++) { + if(*rectz==0x7FFFFFFF) + *rectzf= 10e10; else { - if(render_abuf_lock) SDL_mutexV(render_abuf_lock); + /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */ + /* or: (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2] - R.winmat[2][3]*zco); */ + /* if ortho [2][3] is zero, else [3][3] is zero */ + + zco= ((float)*rectz)/2147483647.0f; + if(ortho) + *rectzf= (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]); + else + *rectzf= (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco); } } } + /* end of zbuf.c */ diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c deleted file mode 100644 index d237b7d64f4..00000000000 --- a/source/blender/render/intern/source/zbufferdatastruct.c +++ /dev/null @@ -1,310 +0,0 @@ -/** - * zbufferdatastruct.c - * - * $Id$ - * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. The Blender - * Foundation also sells licenses for use in proprietary software under - * the Blender License. See http://www.blender.org/BL/ for information - * about this. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** - * - * The z buffer consists of an array of lists. Each list holds the objects - * behind a pixel. These can be sorted for closest distance. Per object, - * we store: - * - object type - * - object index - * - minimum distance - * - maximum distance - * - oversample flags - * - * The buffer was created to fit the new unified renderpipeline. We might - * turn it into an object later on. - * - * The z buffer has an unlimited depth. The oversampling code chops at a - * certain number of faces. This number is defined in - * vanillaRenderPipe_types.h - * - * Version 1 of the z buffer inserted objects by means of linear - * search: we walk along the list until we find the right object or - * until we have to insert a new one. This is terribly inefficient - * when we are dealing with large numbers of objects. Can we find a - * better solution here? - * - * Because we treat halos as billboards, we optimize halo - * insertion. For this purpose the fillFlatObject() functions have - * been implemented. */ - -#include - -#include "MEM_guardedalloc.h" -#include "zbufferdatastruct.h" -#include "vanillaRenderPipe_types.h" -#include "render.h" - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* if defined: all jittersamples are stored individually. _very_ serious */ -/* performance hit ! also gives some buffer size problems in big scenes */ -#define RE_INDIVIDUAL_SUBPIXELS - -/* ------------------------------------------------------------------------- */ - -static RE_APixstrExtMain RE_apsemfirst; /* pixstr bookkeeping var */ -static short RE_apsemteller = 0; /* pixstr bookkeeping var */ -static int RE_zbufferwidth; /* width of the z-buffer (pixels) */ -RE_APixstrExt *APixbufExt; /* Zbuffer: linked list of face, halo indices */ - -/*-RE_APixstrExt------------------------------------------------------------ */ - -void initZbuffer(int width) -{ - APixbufExt = MEM_callocN(RE_ZBUFLEN * width * sizeof(RE_APixstrExt), - "APixbufExt"); - RE_zbufferwidth = width; - RE_apsemteller = 0; - RE_apsemfirst.next = NULL; - RE_apsemfirst.ps = NULL; -} /* end of RE_APixstrExt *initZbufferDataStruct() */ - -/* ------------------------------------------------------------------------- */ - -void freeZbuffer(void) -{ - if (APixbufExt) MEM_freeN(APixbufExt); - freepseA(); -} /* end of void freeZbuffer(void) */ - -/* ------------------------------------------------------------------------- */ - -void resetZbuffer(void) -{ - int len; - - freepseA(); - len = sizeof(RE_APixstrExt) * RE_zbufferwidth * RE_ZBUFLEN; - memset(APixbufExt, 0, len); -} /* end of void resetZbuffer(void) */ - -/* ------------------------------------------------------------------------- */ - -RE_APixstrExt *addpsemainA() -{ - RE_APixstrExtMain *psm; - - psm= &RE_apsemfirst; - - while(psm->next) { - psm= psm->next; - } - - psm->next= MEM_callocN(sizeof(RE_APixstrExtMain), "addpsemainA"); - - psm= psm->next; - - /* Initialise the new structure to safe values. Memory that is newly */ - /* allocated must be zero... Not sure if that happens everywhere now.*/ - psm->next=0; - psm->ps= MEM_callocN(4096*sizeof(RE_APixstrExt),"pixstrext"); - RE_apsemteller= 0; - - return psm->ps; -} /* End of RE_APixstrExt *addpsemainA() */ - -/* ------------------------------------------------------------------------- */ - -void freepseA() -{ - RE_APixstrExtMain *psm, *next; - - psm= &RE_apsemfirst; - - while(psm) { - next= psm->next; - if(psm->ps) { - MEM_freeN(psm->ps); - psm->ps= 0; - } - if(psm!= &RE_apsemfirst) MEM_freeN(psm); - psm= next; - } - - RE_apsemfirst.next= 0; - RE_apsemfirst.ps= 0; - RE_apsemteller= 0; -} /* End of void freepseA() */ - -/* ------------------------------------------------------------------------- */ - -RE_APixstrExt *addpseA(void) -{ - static RE_APixstrExt *prev; - - /* eerste PS maken */ - if((RE_apsemteller & 4095)==0) prev= addpsemainA(); - else prev++; - RE_apsemteller++; - - return prev; -} /* End of RE_APixstrExt *addpseA(void) */ - -/* ------------------------------------------------------------------------- */ - -void insertObject(int apteller, - int obindex, - int obtype, - int dist, - int mask) -{ - /* Guard the insertion if needed? */ - RE_APixstrExt* apn = &APixbufExt[apteller]; - int all_subpixels= 0; // not used now... (ton) - - while(apn) { - - if(apn->t[0] == RE_NONE) { - apn->p[0] = obindex; apn->t[0] = obtype; - apn->zmin[0] = dist; apn->zmax[0] = dist; - apn->mask[0] = mask; - break; - } - else if(all_subpixels==0) { - if((apn->p[0] == obindex) && (apn->t[0] & obtype)) { - if(dist < apn->zmin[0]) apn->zmin[0] = dist; - else if(dist > apn->zmax[0]) apn->zmax[0] = dist; - apn->mask[0]|= mask; - break; - } - } - - if(apn->t[1] == RE_NONE) { - apn->p[1] = obindex; apn->t[1] = obtype; - apn->zmin[1] = dist; apn->zmax[1] = dist; - apn->mask[1] = mask; - break; - } - else if(all_subpixels==0) { - if((apn->p[1] == obindex) && (apn->t[1] & obtype)) { - if(dist < apn->zmin[1]) apn->zmin[1] = dist; - else if(dist > apn->zmax[1]) apn->zmax[1] = dist; - apn->mask[1]|= mask; - break; - } - } - - if(apn->t[2] == RE_NONE) { - apn->p[2] = obindex; apn->t[2] = obtype; - apn->zmin[2] = dist; apn->zmax[2] = dist; - apn->mask[2] = mask; - break; - } - else if(all_subpixels==0) { - if((apn->p[2] == obindex) && (apn->t[2] & obtype)) { - if(dist < apn->zmin[2]) apn->zmin[2] = dist; - else if(dist > apn->zmax[2]) apn->zmax[2] = dist; - apn->mask[2]|= mask; - break; - } - } - - if(apn->t[3] == RE_NONE) { - apn->p[3] = obindex; apn->t[3] = obtype; - apn->zmin[3] = dist; apn->zmax[3] = dist; - apn->mask[3] = mask; - break; - } - else if(all_subpixels==0) { - if((apn->p[3] == obindex) && (apn->t[3] & obtype)) { - if(dist < apn->zmin[3]) apn->zmin[3] = dist; - else if(dist > apn->zmax[3]) apn->zmax[3] = dist; - apn->mask[3]|= mask; - break; - } - } - - if(apn->next==0) apn->next= addpseA(); - apn= apn->next; - } -} - -/* ------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------- */ - -/* This function might be helped by an end-of-list marker */ -void insertFlatObjectNoOsa(RE_APixstrExt *ap, - int obindex, - int obtype, - int dist, - int mask) -{ - int counter=0; - - while(ap) { - if(ap->t[0] == RE_NONE) { - ap->p[0] = obindex; ap->zmin[0] = dist; - ap->zmax[0] = dist; ap->mask[0] = mask; - ap->t[0] = obtype; - break; - } - else if(ap->t[0] & RE_SOLID) if( dist > ap->zmin[0] ) break; - - if(ap->t[1] == RE_NONE) { - ap->p[1] = obindex; ap->zmin[1] = dist; - ap->zmax[1] = dist; ap->mask[1] = mask; - ap->t[1] = obtype; - break; - } - else if(ap->t[1] & RE_SOLID) if( dist > ap->zmin[1] ) break; - - if(ap->t[2] == RE_NONE) { - ap->p[2] = obindex; ap->zmin[2] = dist; - ap->zmax[2] = dist; ap->mask[2] = mask; - ap->t[2] = obtype; - break; - } - else if(ap->t[2] & RE_SOLID) if( dist > ap->zmin[2] ) break; - - if(ap->t[3] == RE_NONE) { - ap->p[3] = obindex; ap->zmin[3] = dist; - ap->zmax[3] = dist; ap->mask[3] = mask; - ap->t[3] = obtype; - break; - } - else if(ap->t[3] & RE_SOLID) if( dist > ap->zmin[3] ) break; - - counter+= 4; - if(counter > RE_MAX_FACES_PER_PIXEL) break; - - if(ap->next==0) ap->next= addpseA(); - ap= ap->next; - }; -} - -/* ------------------------------------------------------------------------- */ - -/* EOF */ diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 8b81c9cc153..b11fa7439d8 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -53,6 +53,7 @@ #include "DNA_material_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" +#include "DNA_group_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -74,6 +75,7 @@ #include "BKE_DerivedMesh.h" #include "BKE_effect.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_key.h" #include "BKE_ipo.h" #include "BKE_lattice.h" @@ -312,6 +314,15 @@ void RE_make_stars(void (*initfunc)(void), /* ------------------------------------------------------------------------- */ +static VertRen *RE_duplicate_vertren(VertRen *ver) +{ + VertRen *v1= RE_findOrAddVert(R.totvert++); + int index= v1->index; + *v1= *ver; + v1->index= index; + return v1; +} + static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv) { int vLen = vsize-1+(!!cyclv); @@ -320,10 +331,9 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi for (v=0; vv2); if (cyclv) { - *vert = *vlr->v2; vlr->v2 = vert; if (v==vLen-1) { @@ -334,7 +344,6 @@ static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsi vlr->v1 = vert; } } else { - *vert = *vlr->v2; vlr->v2 = vert; if (vv1; - vlr->v1 = vert; + vlr->v1 = RE_duplicate_vertren(vlr->v1); } } } } -#if 0 -static void DBG_show_shared_render_faces(int firstvert, int firstface) -{ - int i; - - for (i=firstvert; in[0] = ver->n[1] = ver->n[2] = 0.0; - ver->sticky = 0; - } - - for (i=firstface; iv4) { - CalcCent4f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co); - VecAddf(vlr->v4->n, vlr->v4->n, cent); - vlr->v4->sticky = (float*) (((int) vlr->v4->sticky) + 1); - } else { - CalcCent3f(cent, vlr->v1->co, vlr->v2->co, vlr->v3->co); - } - - VecAddf(vlr->v1->n, vlr->v1->n, cent); - VecAddf(vlr->v2->n, vlr->v2->n, cent); - VecAddf(vlr->v3->n, vlr->v3->n, cent); - - vlr->v1->sticky = (float*) (((int) vlr->v1->sticky) + 1); - vlr->v2->sticky = (float*) (((int) vlr->v2->sticky) + 1); - vlr->v3->sticky = (float*) (((int) vlr->v3->sticky) + 1); - } - - for (i=firstvert; in, 1.f/(int) ver->sticky); - - VecLerpf(ver->co, ver->co, ver->n, 0.3); - ver->sticky = 0; - } - - calc_vertexnormals(firstvert, firstface); -} -#endif - /* ------------------------------------------------------------------------- */ static int contrpuntnormr(float *n, float *puno) @@ -410,7 +371,139 @@ static int contrpuntnormr(float *n, float *puno) /* ------------------------------------------------------------------------- */ -static void calc_vertexnormals(int startvert, int startvlak) +static void calc_edge_stress_add(float *accum, VertRen *v1, VertRen *v2) +{ + float len= VecLenf(v1->co, v2->co)/VecLenf(v1->orco, v2->orco); + float *acc; + + acc= accum + 2*v1->index; + acc[0]+= len; + acc[1]+= 1.0f; + + acc= accum + 2*v2->index; + acc[0]+= len; + acc[1]+= 1.0f; +} + +static void calc_edge_stress(Mesh *me, int startvert, int startvlak) +{ + float loc[3], size[3], *accum, *acc, *accumoffs, *stress; + int a; + + if(startvert==R.totvert) return; + + mesh_get_texspace(me, loc, NULL, size); + + accum= MEM_callocN(2*sizeof(float)*(R.totvert-startvert), "temp accum for stress"); + + /* de-normalize orco */ + for(a=startvert; aorco) { + ver->orco[0]= ver->orco[0]*size[0] +loc[0]; + ver->orco[1]= ver->orco[1]*size[1] +loc[1]; + ver->orco[2]= ver->orco[2]*size[2] +loc[2]; + } + } + + /* add stress values */ + accumoffs= accum - 2*startvert; /* so we can use vertex index */ + for(a=startvlak; av1->orco && vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v1, vlr->v2); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v3); + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v1); + if(vlr->v4) { + calc_edge_stress_add(accumoffs, vlr->v3, vlr->v4); + calc_edge_stress_add(accumoffs, vlr->v4, vlr->v1); + calc_edge_stress_add(accumoffs, vlr->v2, vlr->v4); + } + } + } + + for(a=startvert; aorco) { + /* find stress value */ + acc= accumoffs + 2*ver->index; + if(acc[1]!=0.0f) + acc[0]/= acc[1]; + stress= RE_vertren_get_stress(ver, 1); + *stress= *acc; + + /* restore orcos */ + ver->orco[0] = (ver->orco[0]-loc[0])/size[0]; + ver->orco[1] = (ver->orco[1]-loc[1])/size[1]; + ver->orco[2] = (ver->orco[2]-loc[2])/size[2]; + } + } + + MEM_freeN(accum); +} + +static void calc_tangent_vector(VlakRen *vlr, float fac1, float fac2, float fac3, float fac4) +{ + TFace *tface= vlr->tface; + + if(tface) { + VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4; + float *uv1= tface->uv[0], *uv2= tface->uv[1], *uv3= tface->uv[2], *uv4= tface->uv[3]; + float tang[3], *tav; + float s1, s2, t1, t2, det; + + /* we calculate quads as two triangles, so weight for diagonal gets halved */ + if(v4) { + fac1*= 0.5f; + fac3*= 0.5f; + } + + /* first tria, we use the V now */ + s1= uv2[0] - uv1[0]; + s2= uv3[0] - uv1[0]; + t1= uv2[1] - uv1[1]; + t2= uv3[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v2->co[0]) - t1 * (v1->co[0]-v3->co[0])); + tang[1]= (t2 * (v1->co[1]-v2->co[1]) - t1 * (v1->co[1]-v3->co[1])); + tang[2]= (t2 * (v1->co[2]-v2->co[2]) - t1 * (v1->co[2]-v3->co[2])); + + tav= RE_vertren_get_tangent(v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(v2, 1); + VECADDFAC(tav, tav, tang, fac2); + tav= RE_vertren_get_tangent(v3, 1); + VECADDFAC(tav, tav, tang, fac3); + + if(v4) { + /* 2nd tria, we use the V now */ + s1= uv3[0] - uv1[0]; + s2= uv4[0] - uv1[0]; + t1= uv3[1] - uv1[1]; + t2= uv4[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v3->co[0]) - t1 * (v1->co[0]-v4->co[0])); + tang[1]= (t2 * (v1->co[1]-v3->co[1]) - t1 * (v1->co[1]-v4->co[1])); + tang[2]= (t2 * (v1->co[2]-v3->co[2]) - t1 * (v1->co[2]-v4->co[2])); + + Normalise(tang); + + tav= RE_vertren_get_tangent(v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(v3, 1); + VECADDFAC(tav, tav, tang, fac3); + tav= RE_vertren_get_tangent(v4, 1); + VECADDFAC(tav, tav, tang, fac4); + } + } +} + +static void calc_vertexnormals(int startvert, int startvlak, int do_tangent) { int a; @@ -420,7 +513,8 @@ static void calc_vertexnormals(int startvert, int startvlak) ver->n[0]=ver->n[1]=ver->n[2]= 0.0; } - /* calculate cos of angles and point-masses */ + /* calculate cos of angles and point-masses, use as weight factor to + add face normal to vertex */ for(a=startvlak; aflag & ME_SMOOTH) { @@ -429,13 +523,13 @@ static void calc_vertexnormals(int startvert, int startvlak) VertRen *adrve3= vlr->v3; VertRen *adrve4= vlr->v4; float n1[3], n2[3], n3[3], n4[3]; - float fac1, fac2, fac3, fac4; + float fac1, fac2, fac3, fac4=0.0f; VecSubf(n1, adrve2->co, adrve1->co); Normalise(n1); VecSubf(n2, adrve3->co, adrve2->co); Normalise(n2); - if(adrve4==0) { + if(adrve4==NULL) { VecSubf(n3, adrve1->co, adrve3->co); Normalise(n3); @@ -480,6 +574,9 @@ static void calc_vertexnormals(int startvert, int startvlak) adrve3->n[0] +=fac3*vlr->n[0]; adrve3->n[1] +=fac3*vlr->n[1]; adrve3->n[2] +=fac3*vlr->n[2]; + + if(do_tangent) + calc_tangent_vector(vlr, fac1, fac2, fac3, fac4); } } @@ -504,6 +601,10 @@ static void calc_vertexnormals(int startvert, int startvlak) for(a=startvert; an); + if(do_tangent) { + float *tav= RE_vertren_get_tangent(ver, 0); + if(tav) Normalise(tav); + } } /* vertex normal (puno) switch flags for during render */ @@ -541,30 +642,21 @@ typedef struct ASface { VertRen *nver[4]; } ASface; -/* prototypes: */ -static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh); -static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh); - - -static void as_addvert(VertRen *v1, VlakRen *vlr) +static void as_addvert(ASvert *asv, VertRen *v1, VlakRen *vlr) { - ASvert *asv; ASface *asf; int a; if(v1 == NULL) return; - if(v1->svert==0) { - v1->svert= MEM_callocN(sizeof(ASvert), "asvert"); - asv= v1->svert; + if(asv->faces.first==NULL) { asf= MEM_callocN(sizeof(ASface), "asface"); BLI_addtail(&asv->faces, asf); } - asv= v1->svert; asf= asv->faces.last; for(a=0; a<4; a++) { - if(asf->vlr[a]==0) { + if(asf->vlr[a]==NULL) { asf->vlr[a]= vlr; asv->totface++; break; @@ -580,16 +672,6 @@ static void as_addvert(VertRen *v1, VlakRen *vlr) } } -static void as_freevert(VertRen *ver) -{ - ASvert *asv; - - asv= ver->svert; - BLI_freelistN(&asv->faces); - MEM_freeN(asv); - ver->svert= NULL; -} - static int as_testvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thresh) { /* return 1: vertex needs a copy */ @@ -641,37 +723,35 @@ static VertRen *as_findvertex(VlakRen *vlr, VertRen *ver, ASvert *asv, float thr static void autosmooth(int startvert, int startvlak, int degr) { - ASvert *asv; + ASvert *asv, *asverts, *asvertoffs; ASface *asf; VertRen *ver, *v1; VlakRen *vlr; float thresh; int a, b, totvert; - thresh= cos( M_PI*((float)degr)/180.0 ); + if(startvert==R.totvert) return; + asverts= MEM_callocN(sizeof(ASvert)*(R.totvert-startvert), "all smooth verts"); + asvertoffs= asverts-startvert; /* se we can use indices */ - /* initialize */ - for(a=startvert; asvert= 0; - } + thresh= cos( M_PI*((float)degr)/180.0 ); /* step one: construct listbase of all vertices and pointers to faces */ for(a=startvlak; av1, vlr); - as_addvert(vlr->v2, vlr); - as_addvert(vlr->v3, vlr); - as_addvert(vlr->v4, vlr); + as_addvert(asvertoffs+vlr->v1->index, vlr->v1, vlr); + as_addvert(asvertoffs+vlr->v2->index, vlr->v2, vlr); + as_addvert(asvertoffs+vlr->v3->index, vlr->v3, vlr); + if(vlr->v4) + as_addvert(asvertoffs+vlr->v4->index, vlr->v4, vlr); } /* we now test all vertices, when faces have a normal too much different: they get a new vertex */ totvert= R.totvert; - for(a=startvert; asvert; + for(a=startvert, asv=asverts; atotface>1) { + ver= RE_findOrAddVert(a); asf= asv->faces.first; while(asf) { @@ -683,11 +763,9 @@ static void autosmooth(int startvert, int startvlak, int degr) /* already made a new vertex within threshold? */ v1= as_findvertex(vlr, ver, asv, thresh); - if(v1==0) { + if(v1==NULL) { /* make a new vertex */ - v1= RE_findOrAddVert(R.totvert++); - *v1= *ver; - v1->svert= 0; + v1= RE_duplicate_vertren(ver); } asf->nver[b]= v1; if(vlr->v1==ver) vlr->v1= v1; @@ -702,11 +780,10 @@ static void autosmooth(int startvert, int startvlak, int degr) } /* free */ - for(a=startvert; asvert) as_freevert(ver); + for(a=0; akeys; @@ -823,12 +900,16 @@ static void render_particle_system(Object *ob, PartEff *paf) } ma= give_render_material(ob, paf->omat); - + MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat); MTC_Mat4Invert(ob->imat, mat); /* this is correct, for imat texture */ - MTC_Mat4Invert(mat, R.viewmat); /* particles do not have a ob transform anymore */ - MTC_Mat3CpyMat4(imat, mat); + /* enable duplicators to work */ + Mat4MulMat4(tmat, paf->imat, ob->obmat); + MTC_Mat4MulMat4(mat, tmat, R.viewmat); + + MTC_Mat4Invert(tmat, mat); + MTC_Mat3CpyMat4(imat, tmat); R.flag |= R_HALO; @@ -858,13 +939,13 @@ static void render_particle_system(Object *ob, PartEff *paf) /* watch it: also calculate the normal of a particle */ if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) { where_is_particle(paf, pa, stime, vec); - MTC_Mat4MulVecfl(R.viewmat, vec); + MTC_Mat4MulVecfl(mat, vec); where_is_particle(paf, pa, ptime, vec1); - MTC_Mat4MulVecfl(R.viewmat, vec1); + MTC_Mat4MulVecfl(mat, vec1); } else { where_is_particle(paf, pa, ctime, vec); - MTC_Mat4MulVecfl(R.viewmat, vec); + MTC_Mat4MulVecfl(mat, vec); } if(pa->mat_nr != mat_nr) { @@ -926,11 +1007,9 @@ static void render_particle_system(Object *ob, PartEff *paf) /* ------------------------------------------------------------------------- */ -/* when objects are duplicated, they are freed immediate, but still might be -in use for render... */ +/* old call... for when duplicators were using temporal objects */ static Object *vlr_set_ob(Object *ob) { - if(ob->flag & OB_FROMDUPLI) return (Object *)ob->id.newid; return ob; } @@ -1184,7 +1263,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf) } if((ma->mode & MA_TANGENT_STR)==0) - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, 0); } @@ -1254,13 +1333,6 @@ static Material *give_render_material(Object *ob, int nr) Object *temp; Material *ma; - if(ob->flag & OB_FROMDUPLI) { - temp= (Object *)ob->id.newid; - if(temp && temp->type==OB_FONT) { - ob= temp; - } - } - ma= give_current_material(ob, nr); if(ma==NULL) ma= &defmaterial; @@ -1540,7 +1612,7 @@ static void init_render_mesh(Object *ob) unsigned int *vertcol; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *orco=0; - int a, a1, ok, need_orco=0, totvlako, totverto, vertofs; + int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs; int end, do_autosmooth=0, totvert = 0, dm_needsfree; me= ob->data; @@ -1568,24 +1640,19 @@ static void init_render_mesh(Object *ob) for(a=1; a<=ob->totcol; a++) { ma= give_render_material(ob, a); if(ma) { - if(ma->texco & TEXCO_ORCO) { + if(ma->texco & (TEXCO_ORCO|TEXCO_STRESS)) need_orco= 1; - break; - } + if(ma->texco & TEXCO_STRESS) + need_stress= 1; + if(ma->mode & MA_TANGENT_V) + need_tangent= 1; } } if(need_orco) orco = get_object_orco(ob); - /* duplicators don't call modifier stack */ - if(ob->flag&OB_FROMDUPLI) { - dm= ob->derivedFinal; - dm_needsfree= 0; - } - else { - dm = mesh_create_derived_render(ob); - dm_needsfree= 1; - } + dm = mesh_create_derived_render(ob); + dm_needsfree= 1; if(dm==NULL) return; /* in case duplicated object fails? */ @@ -1613,7 +1680,9 @@ static void init_render_mesh(Object *ob) orco+=3; } if(ms) { - ver->sticky= (float *)ms; + float *sticky= RE_vertren_get_sticky(ver, 1); + sticky[0]= ms->co[0]; + sticky[1]= ms->co[1]; ms++; } } @@ -1789,7 +1858,7 @@ static void init_render_mesh(Object *ob) } if (test_for_displace( ob ) ) { - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, 0); do_displacement(ob, totvlako, R.totvlak-totvlako, totverto, R.totvert-totverto); } @@ -1797,8 +1866,11 @@ static void init_render_mesh(Object *ob) autosmooth(totverto, totvlako, me->smoothresh); } - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, need_tangent); + if(need_stress) + calc_edge_stress(me, totverto, totvlako); + if(dlm) displistmesh_free(dlm); if(dm_needsfree) dm->release(dm); } @@ -1835,24 +1907,11 @@ static void area_lamp_vectors(LampRen *lar) /* If lar takes more lamp data, the decoupling will be better. */ void RE_add_render_lamp(Object *ob, int actual_render) { - Lamp *la; - LampRen *lar, **temp; + Lamp *la= ob->data; + LampRen *lar; + GroupObject *go; float mat[4][4], hoek, xn, yn; int c; - static int rlalen=LAMPINITSIZE; /*number of currently allocated lampren pointers*/ - - if(R.totlamp>=rlalen) { /* Need more Lamp pointers....*/ - printf("Alocating %i more lamp groups, %i total.\n", - LAMPINITSIZE, rlalen+LAMPINITSIZE); - temp=R.la; - R.la=(LampRen**)MEM_callocN(sizeof(void*)*(rlalen+LAMPINITSIZE) , "renderlamparray"); - memcpy(R.la, temp, rlalen*sizeof(void*)); - memset(&(R.la[R.totlamp]), 0, LAMPINITSIZE*sizeof(void*)); - rlalen+=LAMPINITSIZE; - MEM_freeN(temp); - } - - la= ob->data; /* prevent only shadow from rendering light, but only return on render, not preview */ if(actual_render) { @@ -1860,9 +1919,13 @@ void RE_add_render_lamp(Object *ob, int actual_render) if((R.r.mode & R_SHADOW)==0) return; } - + + go= MEM_callocN(sizeof(GroupObject), "groupobject"); + BLI_addtail(&R.lights, go); + R.totlamp++; lar= (LampRen *)MEM_callocN(sizeof(LampRen),"lampren"); - R.la[R.totlamp++]= lar; + go->lampren= lar; + go->ob= ob; MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat); MTC_Mat4Invert(ob->imat, mat); @@ -2306,11 +2369,11 @@ static void init_render_curve(Object *ob) if(ver->co[2] < 0.0) { VECCOPY(ver->n, n); - ver->sticky = (float*) 1; + ver->flag = 1; } else { ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2]; - ver->sticky = (float*) 0; + ver->flag = 0; } if (orco) { @@ -2330,7 +2393,7 @@ static void init_render_curve(Object *ob) vlr->v3= RE_findOrAddVert(startvert+index[2]); vlr->v4= NULL; - if(vlr->v1->sticky) { + if(vlr->v1->flag) { VECCOPY(vlr->n, n); } else { @@ -2429,15 +2492,15 @@ static void init_render_curve(Object *ob) for(a=startvert; an); - if(len==0.0) ver->sticky= (float *)1; - else ver->sticky= 0; + if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */ + else ver->flag= 0; } for(a= startvlak; av1->sticky) VECCOPY(vlr->v1->n, vlr->n); - if(vlr->v2->sticky) VECCOPY(vlr->v2->n, vlr->n); - if(vlr->v3->sticky) VECCOPY(vlr->v3->n, vlr->n); - if(vlr->v4->sticky) VECCOPY(vlr->v4->n, vlr->n); + if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n); + if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n); + if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n); + if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n); } } @@ -2538,6 +2601,7 @@ void RE_freeRotateBlenderScene(void) { ShadBuf *shb; Object *ob = NULL; + GroupObject *go; unsigned long *ztile; int a, b, v; char *ctile; @@ -2546,10 +2610,11 @@ void RE_freeRotateBlenderScene(void) BLI_memarena_free(R.memArena); R.memArena = NULL; - - for(a=0; ashb) { - shb= R.la[a]->shb; + + for(go= R.lights.first; go; go= go->next) { + struct LampRen *lar= go->lampren; + if(lar->shb) { + shb= lar->shb; v= (shb->size*shb->size)/256; ztile= shb->zbuf; ctile= shb->cbuf; @@ -2559,20 +2624,17 @@ void RE_freeRotateBlenderScene(void) MEM_freeN(shb->zbuf); MEM_freeN(shb->cbuf); - MEM_freeN(R.la[a]->shb); + MEM_freeN(lar->shb); } - if(R.la[a]->jitter) MEM_freeN(R.la[a]->jitter); - MEM_freeN(R.la[a]); + if(lar->jitter) MEM_freeN(lar->jitter); + MEM_freeN(lar); } + + BLI_freelistN(&R.lights); /* note; these pointer arrays were allocated, with last element NULL to stop loop */ - a=0; - while(R.blove[a]) { - MEM_freeN(R.blove[a]); - R.blove[a]= NULL; - a++; - } - + RE_free_vertex_tables(); + a=0; while(R.blovl[a]) { MEM_freeN(R.blovl[a]); @@ -2602,9 +2664,9 @@ void RE_freeRotateBlenderScene(void) free_mesh_orco_hash(); - end_render_textures(); - end_render_materials(); end_radio_render(); + end_render_materials(); + if(R.wrld.aosphere) { MEM_freeN(R.wrld.aosphere); R.wrld.aosphere= NULL; @@ -2753,7 +2815,25 @@ static void check_non_flat_quads(void) } } - +static void set_material_lightgroups(void) +{ + GroupObject *go, *gol; + Material *ma; + + /* it's a bit too many loops in loops... but will survive */ + for(ma= G.main->mat.first; ma; ma=ma->id.next) { + if(ma->group) { + for(go= ma->group->gobject.first; go; go= go->next) { + for(gol= R.lights.first; gol; gol= gol->next) { + if(gol->ob==go->ob) { + go->lampren= gol->lampren; + break; + } + } + } + } + } +} extern int slurph_opt; /* key.c */ extern ListBase duplilist; @@ -2765,13 +2845,13 @@ void RE_rotateBlenderScene(void) unsigned int lay; float mat[4][4]; - if(G.scene->camera==0) return; + if(G.scene->camera==NULL) return; R.memArena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); - - slurph_opt= 0; - R.totvlak=R.totvert=R.totlamp=R.tothalo= 0; + R.lights.first= R.lights.last= NULL; + + slurph_opt= 0; /* in localview, lamps are using normal layers, objects only local bits */ if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000; @@ -2804,6 +2884,7 @@ void RE_rotateBlenderScene(void) } init_render_textures(); init_render_materials(); + set_node_shader_lamp_loop(shade_material_loop); /* imat objects, OB_DO_IMAT can be set in init_render_materials has to be done here, since displace can have texture using Object map-input */ @@ -2853,6 +2934,7 @@ void RE_rotateBlenderScene(void) if( (base->lay & lay) || (ob->type==OB_LAMP && (base->lay & G.scene->lay)) ) { if(ob->transflag & OB_DUPLI) { + /* exception: mballs! */ /* yafray: Include at least one copy of a dupliframe object for yafray in the renderlist. mballs comment above true as well for yafray, they are not included, only all other object types */ @@ -2870,28 +2952,17 @@ void RE_rotateBlenderScene(void) } } - make_duplilist(sce, ob); if(ob->type==OB_MBALL) { init_render_object(ob); } else { - obd= duplilist.first; - if(obd) { - /* exception, in background render it doesnt make the displist */ - if ELEM(obd->type, OB_CURVE, OB_SURF) { - Curve *cu; - - cu= obd->data; - if(cu->disp.first==NULL) { - obd->flag &= ~OB_FROMDUPLI; - makeDispListCurveTypes(obd, 0); - obd->flag |= OB_FROMDUPLI; - } - } - } - - obd= duplilist.first; - while(obd) { + DupliObject *dob; + ListBase *lb= object_duplilist(sce, ob); + + for(dob= lb->first; dob; dob= dob->next) { + Object *obd= dob->ob; + Mat4CpyMat4(obd->obmat, dob->mat); + if(obd->type!=OB_MBALL) { /* yafray: special handling of duplivert objects for yafray: only the matrix is stored, together with the source object name. @@ -2906,10 +2977,10 @@ void RE_rotateBlenderScene(void) } else init_render_object(obd); } - obd= obd->id.next; + Mat4CpyMat4(obd->obmat, dob->omat); } + BLI_freelistN(lb); } - free_duplilist(); } else { /* yafray: if there are linked data objects (except lamps, empties or armatures), @@ -2958,7 +3029,9 @@ void RE_rotateBlenderScene(void) } sort_halos(); - + + set_material_lightgroups(); + if(R.wrld.mode & WO_STARS) RE_make_stars(NULL, NULL, NULL); slurph_opt= 1; @@ -3073,8 +3146,13 @@ static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale) if ((texco & TEXCO_ORCO) && (vr->orco)) { VECCOPY(shi->lo, vr->orco); } - if ((texco & TEXCO_STICKY) && (vr->sticky)) { - VECCOPY(shi->sticky, vr->sticky); + if (texco & TEXCO_STICKY) { + float *sticky= RE_vertren_get_sticky(vr, 0); + if(sticky) { + shi->sticky[0]= sticky[0]; + shi->sticky[1]= sticky[1]; + shi->sticky[2]= 0.0f; + } } if (texco & TEXCO_GLOB) { VECCOPY(shi->gl, shi->co); @@ -3213,6 +3291,6 @@ static void do_displacement(Object *ob, int startface, int numface, int startver } /* Recalc vertex normals */ - calc_vertexnormals(startvert, startface); + calc_vertexnormals(startvert, startface, 0); } diff --git a/source/blender/src/Makefile b/source/blender/src/Makefile index f0728897d47..d3b1240a671 100644 --- a/source/blender/src/Makefile +++ b/source/blender/src/Makefile @@ -64,7 +64,6 @@ CPPFLAGS += -I$(NAN_SOUNDSYSTEM)/include $(NAN_SDLCFLAGS) # External interfaces of modules: CPPFLAGS += -I../render/extern/include -CPPFLAGS += -I../renderconverter CPPFLAGS += -I../blenkernel CPPFLAGS += -I../blenlib CPPFLAGS += -I../python @@ -112,6 +111,10 @@ ifeq ($(WITH_QUICKTIME),true) CPPFLAGS += -DWITH_QUICKTIME endif +ifeq ($(WITH_OPENEXR),true) + CPPFLAGS += -DWITH_OPENEXR +endif + ifeq ($(INTERNATIONAL), true) CPPFLAGS += -DINTERNATIONAL endif diff --git a/source/blender/src/SConscript b/source/blender/src/SConscript index e2deaa47544..bc5d9a3baa4 100644 --- a/source/blender/src/SConscript +++ b/source/blender/src/SConscript @@ -2,9 +2,11 @@ Import ('extra_includes') Import ('user_options_dict') Import ('library_env') +Import ('defines') src_env = library_env.Copy () src_env.Append (CCFLAGS = user_options_dict['SDL_CFLAGS']) +src_env.Append(CPPDEFINES = defines) source_files = ['B.blend.c', 'Bfont.c', @@ -39,6 +41,7 @@ source_files = ['B.blend.c', 'drawtext.c', 'drawtime.c', 'drawview.c', + 'drawnode.c', 'edit.c', 'editaction.c', 'editarmature.c', @@ -56,6 +59,7 @@ source_files = ['B.blend.c', 'editlattice.c', 'editmball.c', 'editmesh.c', + 'editnode.c', 'editmesh_add.c', 'editmesh_lib.c', 'editmesh_loop.c', @@ -92,11 +96,13 @@ source_files = ['B.blend.c', 'header_text.c', 'header_time.c', 'header_view3d.c', + 'header_node.c', 'imagepaint.c', 'imasel.c', 'interface.c', 'interface_panel.c', 'interface_draw.c', + 'interface_icons.c', 'keyval.c', 'lorem.c', 'mainqueue.c', @@ -105,9 +111,11 @@ source_files = ['B.blend.c', 'oops.c', 'outliner.c', 'splash.jpg.c', + 'parametrizer.c', 'playanim.c', 'poseobject.c', 'previewrender.c', + 'preview.blend.c', 'renderwin.c', 'resources.c', 'scrarea.c', @@ -143,7 +151,6 @@ src_env.Append (CPPPATH = ['#/intern/guardedalloc', '../imbuf', '../render/extern/include', '#/intern/bsp/extern', - '../renderconverter', '../radiosity/extern/include', '#/intern/decimation/extern', '../blenloader', diff --git a/source/blender/src/blenderbuttons.c b/source/blender/src/blenderbuttons.c index 4a72af7ffd0..78ec3eb4508 100644 --- a/source/blender/src/blenderbuttons.c +++ b/source/blender/src/blenderbuttons.c @@ -1,1542 +1,1905 @@ /* DataToC output of file */ -int datatoc_blenderbuttons_size= 49157; +int datatoc_blenderbuttons_size= 60777; char datatoc_blenderbuttons[]= { -137, 80, 78, 71, 13, - 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 2, 0, 0, 0, 74,242, 89, 48, 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,192,153,201, 12,156, -227, 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, 0,191,123, 73, 68, 65, 84,120,218, 98,244,137,169,101, 24, 5,163, 96, - 20,140,130, 81, 48,242, 0, 64, 0, 49,141, 6,193, 40, 24, 5,163, 96, 20,140, 76, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, - 20,140, 80, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, 20,140, 80, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, 20,140, 80, 0, - 16, 64,163, 21,192, 40, 24, 5,163, 96, 20,140, 80, 0, 16, 64, 44,112,150,175,173, 12,241,218, 54, 31,126,130,204, 29,213, 59, - 8,245,162,105,167,186,189, 7, 14, 28,112,112,112, 24, 13,231, 81,189,163,122, 7,185, 94, 60, 0, 32,128, 88,134, 71, 61,150, -158,158, 14,103,207,156, 57,115, 64,108,159, 49, 99, 6, 35, 35,227,176,111, 50,192,131, 58, 50, 50,114,205,154, 53, 16,118, 72, - 72,200,104, 99,106,248, 69, 52,253,179,210, 40,160, 51, 0, 8, 32, 22, 90,164,128,219,183,111,247,244,244, 64,216, 37, 37, 37, -170,170,170,116,240,201,255,255,255,129, 36,253,139, 96, 96, 40, 61,120,240, 0,200, 80, 80, 80, 24,144,234, 7,107, 45,136,213, - 37,192, 54, 59,126, 19,150, 47, 95,142,223,253, 64, 43, 86,173, 90, 5, 97,175, 95,191,222,213,213, 21,194, 6,214, 4,180,171, - 3,140,141,141,129,228,217,179,103,201,144, 29,153,224,222,189,123,157,157,157,112,110,121,121,185,146,146,210, 32,175, 54, 6, -208,205, 35, 25, 0, 4, 16, 11,158, 66, 28, 66,146, 90,124, 67,138,161,198, 85, 45, 60,178,252, 95, 30,127,172, 15,171, 25,216, - 98,145,214, 0,232, 53, 96,209,255, 0, 12,118,236,216, 65,255,118, 19, 36,192,103,130, 1,144,221,213,213, 5,228,150,149,149, - 97, 85, 28, 24, 24, 8, 97,252,249,243,247,215,239,159,191,126,254,130,128, 63,127,254,224,210,130,181,244, 71, 3,192,154,128, -166,117, 0,158,218, 11, 82, 1,140, 2, 92,237, 0, 32,128, 20,172,116, 72,150, 16,171,201,200, 2, 3,232,230, 17, 14, 0, 2, - 8,103, 5, 0,108,194,175,170,173, 10,107,110, 35, 41, 14,128, 17, 9, 41,250,129,236, 55,223,222, 50, 8, 51, 84,238,109,248, -116,239,125,122, 42,253,138, 69,204,196, 68,107,171,225,117,128,135,135, 7,144, 4,178,233,233,217,253,251,247, 3, 25,142,142, -142,104,117, 0, 30, 0, 44,238,127,253,250,253,235, 23, 74,233,127,230,204, 25, 19, 19, 19,130, 54,134,133,133, 65, 24,145,145, -145,187,119,239,134, 87, 0,100, 68, 16,145,161, 4,108,221, 3, 75,127, 55, 55, 55,100,193, 93,187,118, 1,251, 43, 16, 54,214, -169,136, 17, 94,250, 35,135, 45, 25,229, 50,217, 90,200,232, 7, 80,203,205,163,128, 12, 0, 16, 64, 44,184,154,255,106,106,106, -170, 60,124, 36,117, 2,224,165, 63,176,232,111,119,110,128, 8, 38,110,204, 98, 16, 99, 8,236, 10, 35, 24,151,152, 5, 55,121, -101,247,227,199,143,129,164,172,172, 44,156, 1, 49,153,186,135, 94,160,121, 7, 94, 7,252,254,253,103,198,140, 25,148, 55,130, -136,209,142, 86,250,195, 53, 98, 13, 73,148,210,255, 55,176,244,255,249, 19, 92, 9,192, 75,255,255,255,254, 19, 83,250, 3, 85, - 66,216,189,189,189,240, 38, 63,124, 50,128,120, 55,163, 57,155,120, 0, 47,250,129, 53,144,161,161,225,104, 30, 70, 30, 69,193, -154,120,224, 73, 2,168,128,224,184, 10,188, 67, 9, 73,195,112, 46, 49,205, 32,204,162,156, 96, 70, 64,115, 51,176, 73,193,200, -200,232,226,226, 66,146,155, 33, 32, 57, 57,121,238,220,185,163,201,128, 36, 0, 16, 64, 76,184,154,255, 45,225, 33, 63, 94,191, - 46,209,214,128,143,230,227, 7,144, 33, 35,120,233, 95, 82, 82, 2,140, 66, 32, 57,223,127, 26, 80, 92, 64, 93, 4,174, 6, 15, - 40,155,122, 11,136,178,123,174,199, 55, 95, 9,170,188, 64,170,103,158, 60,121,130,167, 74,160,110,233, 15, 44,235, 49,139,108, - 96, 29, 0, 44, 82,205,205,204, 72, 53, 13, 50,186, 2, 4,251, 97, 0,127, 33, 14, 47, 73, 29,193, 0, 51,195,227, 46,253,255, -130,138,253,159,160,193, 31,228,210,255,239,223,191, 95,191,127, 37,232, 84, 72, 47, 1,185,163,176, 6, 12,136, 28,252, 1,185, - 25,105, 36, 7,200, 38,232, 77,172,165, 63,176,232, 7,246,114, 32,165, 63, 43, 11,235,104, 54, 38, 56,108, 2, 17, 68, 30,100, -199, 95,148,147,215, 2,131, 40, 70, 46,253,113, 53,236,176,186, 25, 88,250, 3,211,210,234,213,171,247,236,217, 67,170,155,129, -165, 63, 11, 11, 11,144, 28, 77, 6, 36, 1,128, 0, 98,194,211,252,255,246,226,185,167,161, 17, 49, 5, 55,164,206, 0, 54,255, -129, 12, 72,233, 15,233, 52, 0, 73, 72, 29,240,228,211, 51,163, 50, 11,130,117,201,215,239,192, 98,232,239,243,183, 63,159,190, -254,241,248,229, 15, 34,139, 78, 72, 10,195, 85,250,211, 14, 96,214, 1, 64,240,227,215,207, 31, 63,126, 16,111, 8,164, 28,135, -140,173,139,138,138,194,155,198,248,115, 14,114, 59, 26,179,227,140, 39,223,130,198,253,129,197, 63,184,241, 15, 47,253,127,255, -254,253,245,235,215,207,159, 62,211,122,116, 98,213,170,213, 48, 30, 35, 24, 50, 0, 69,136,175, 3,224,165, 63,164,232,103, 98, - 98,226,224,224,224,230,225, 26,205,198, 52,234,215, 18,217,167,196, 90,121,160,141, 8, 17,163, 23,222,143, 4,214, 1, 36, 57, - 27, 82,250,131, 6, 52, 70,235, 0, 18, 1, 64, 0,118,205, 94, 7, 65, 24,136,227, 36,208,224,238, 32,239, 64,124,156,250, 8, -142, 60, 15,137, 3, 59, 60,150,176, 16,135,106, 75, 33, 90,130, 7, 37, 23, 98,180,158,137, 35, 55, 53, 13,133,210,143,223,221, -253,219,224, 45,202, 79,199,121, 16,155,242,108,147, 0, 74, 32, 96,195,127,203,125,172,196,242,118, 31,125,125,131,106,123,169, -205,173, 49, 87,101,132, 52,148, 31,120,185,252,131,193, 62, 22, 32,133, 20, 66,252,119,212,210, 52,197,131, 95, 84,252, 97,149, - 67,125,215,182,116, 7, 0, 77,178, 44, 43,171,138,249,254, 46,138,144,254, 73,146,196,113,236,216, 54,240, 69,120, 12,125,192, - 50, 47,113,159, 64,220, 39,254, 63, 70,250,247,150,254,224, 13,180,214, 74, 41, 41, 73, 14, 0, 37, 32,107,244,216, 63, 47,114, -111,240, 46,117, 61,206,154,157,179, 97, 24,125, 64, 81, 28, 56,167, 44,176, 37,253, 25, 99, 97, 24,110, 38, 35,246,124, 53,138, - 2,249, 9,220,116, 45,200,161, 8,185,141,115,110,209,255,211,109, 2,164,255, 76,180, 32,128,200,102,213,130,136,246, 20, 64, - 76, 88, 71,114, 76,148, 85,127,188,126, 13, 44,253,129,108, 59,112,179,148,152, 78,192,189, 43,119,144, 13, 65, 99,191,189,252, -130,160, 9,164,150,254,240,162, 31, 88, 13,200,202,202,194, 5,127,195, 0,176,232, 7,182,109,223,189,123, 71,221, 80,131, 88, -186, 99,199, 14,120, 63, 0, 82,250,235,233,233,253, 0,214, 0,223,191,195,107, 38,252, 89,110,234,180,169, 64, 71,202, 72, 75, -255,254,251, 23,173,244, 39,152,109, 32,117, 0,114,131, 11,178, 26, 21,107,191, 4,165, 2,248,245, 27, 82,250,159, 62,117,250, -219,247,239,192,210,243,227,199,143,192,128,122,255,254, 61,241, 33, 0, 25, 5, 34,126,232, 31,148, 0,222,188,125,251,246,205, -155,183,239, 64, 52,152, 9, 20,212,208,212,124, 7,102, 16,211,252, 7,146,192,210, 31,218,240,231,230,230,225,225,229,229,225, - 5, 50, 70,179, 49,174,210,156,248, 6, 56,100, 5, 1,156,129,139, 77,146,237,104, 35, 66, 4,117,185,184,184, 0,235, 0, 96, -233,239,234,234, 74,124,159, 3, 88,214, 3, 75,124, 56,119,180,244, 39, 9, 0, 4, 16, 19,102,243,127, 85,109, 21,144,241,237, -197,115,184, 32, 49, 51, 1, 37, 37, 37, 83, 83, 39, 50,128,103,125,129,138,225,171, 72,129,108,215,197, 1, 64,246,185,174, 19, - 64, 53,212,117, 61, 60,109, 61,121,242, 4,210,228,135,148,251,208,238,203,215,175,192,210, 13,216, 30,231,226,162,254, 40, 1, -208,234,140,140, 12,144,141,127,254, 92,187,118,237,252,185,115,250,122,250, 63,126,128, 59, 0,223,191, 47, 89,188, 24, 34,139, - 39,185,247,246,246,106,105,106, 1, 93, 11, 12,165, 63,191,127, 61,125,242,148,108,239, 51,192,102, 32, 24,192,219, 17,240,245, - 0,126,255,252,243, 23, 52,242,115,242,228,137,175,223,191,126,249,252, 9, 88,250,191, 7,149,254,239, 72,170, 38, 33,253, 0, -146, 90,106,135, 14, 29,250, 12, 2,159,192,228,103, 17, 97, 97, 96,233,127,227,250,245,131,135, 14, 17,163, 29,210,252,103, 97, - 97, 5,198, 38, 15,176,236, 7, 98, 30, 46, 78, 46,206, 23, 47, 94,140,102, 99, 8, 40, 47, 47,135,151,191,240,201, 85, 8, 3, - 34, 8, 81, 64,100,179, 29,255,184, 16,254,210,159,248,182, 63,154,155,129,117, 0,176,244, 39,201,205,200,117,192,104,233, 79, - 42, 0, 8, 32, 44, 67, 64,194,247, 31,188, 3, 15,254,192, 69,128,157,128, 30,134, 27,248, 13,130, 12,245,220, 56,123, 77, 64, - 93, 4, 88,226,247,196, 66, 43, 12, 72,233, 15,105,254, 19, 92, 77,180,174,221,128,188,246,248,245,235,215, 33, 41, 0,121, 52, -128, 21, 12, 94,191,126,237,229,229, 69,139,176,131,148,185,192,134,191,153,153,217,143,159, 63,191,255,248, 14,110,253,127, 7, - 49,126,252,152, 50,101, 10,174,156, 3, 89,169,249,247,239,223,179,103,207,177,178, 48, 67, 66,230,254,131, 7, 79,159, 62, 93, -190,124, 69,100,100, 4, 80, 4,222, 15,192,154,193,224,131, 78,104, 45, 56,130, 43, 80, 33,109,255,227,199,143,127,253,242, 13, - 82, 65,126,250,252,233,211,167,143,159, 62,125, 33,126, 32, 5,210,252,135,239, 4, 38,166, 26, 0, 42,134,179, 21, 21, 20,128, - 69, 63, 40,181, 92,191,126, 31,220,107, 65,150,197, 3, 44,173, 44,217,217,216, 57, 57, 57,129, 61, 0,118,118,118, 96,228, 82, -125,122,127, 72, 3,228,213, 50,240,197, 51,240,154, 0, 77, 1,254, 66, 28,235, 80, 62, 73, 61, 15, 34,171, 13,106,185, 25, 82, - 7,140,150,254,164, 2,128, 0, 98,193, 28,255,113, 94,178, 12,171, 82,130,235, 65, 33,205, 7,163, 50, 11, 97, 93, 9, 72,185, - 15, 31,252, 1, 54,255, 9,166, 6,242, 22,252, 66, 44,213,212,212,188,124,249, 50,188, 8,195, 28,244, 7, 42, 35,254,124, 12, - 82,109, 71, 22, 89,178,120, 9,176,244,135,236,176,194,186, 30, 31,121,157,254,191,127,127,245,244,141, 46, 94,188,116,253,218, - 53, 22, 86, 86, 96,201,248,228,233, 19, 96, 83,151,153,153, 57, 44, 44, 12, 88, 7, 48, 48,240, 99,154, 0,212, 14,201, 93, 16, -219,209,246, 1,224,119, 48,176,244, 63,122,244,232, 23, 32, 0,205,250,126, 2,151,254, 64,226,243,151,207, 95,190,126,251, 70, -208,179,192,162,255, 12, 24, 48, 96, 44, 3,197, 95, 13, 56, 56, 56, 32, 7, 20,164,220, 63,127,254, 60, 3, 17,219,143,141,193, - 0,200,224,225,226,225, 0, 21,254, 28,108,108,108, 76, 76, 76,163,165, 63,250, 24, 44, 82,185,185,122,245,106, 96,107,154, 1, -117, 66,149,152, 37,149,200,109, 11, 82, 87, 51,147, 49,238, 79, 21, 55,195,235,128,209, 52, 64, 42, 0, 8, 32, 22,180, 86, 60, -133,219, 46,224, 41, 0, 82, 13, 64,138,126, 6, 26,111,197,130, 88,170,171,171,123,250,244,105, 96,123, 31, 81,241,188, 5,205, - 72,199,198,198,210, 52, 4,145,189,246,255,255,255,152,216,152, 41, 83,166,130,199,217,255,240,243,243, 19,172,231,110,221,186, - 5,108,209, 66,244, 2,217,104,202,238,225,168,180,144,235, 0,200,108, 48,100, 73, 40,254,112,134, 44,159,183,182,182,166,196, -179,240, 53,160,164,158, 5, 4,212,123,224,192,129,229, 96,128,220, 51, 32, 50,109, 0,171,144,223,127,126,255,254,252,123,116, -202, 23, 23, 32,184, 98, 18,168,128,200,208,134,239, 3, 32, 47, 51, 18,175,145,138,110, 30, 5,100, 0,128, 0,162,254, 97,112, -192,216, 2, 13,253,119,209,245, 44, 32, 72,178, 51, 53, 53,221,182,109, 27,164,220,167,188,111, 65,222, 96, 20,124, 47, 46,214, -210,159, 42, 0,243,204, 6,200,178, 81,130, 77, 54,170,132, 3,220, 16, 96,105, 78,234,217, 15, 14, 96, 64,170,141,163,231,252, -144,209, 22,161,127,226, 39,207,198, 65,226,230, 17, 11, 0, 2,136, 38,167,129, 82,222,147, 32,187, 14,160,209,112, 63,237, 50, - 0,229,134,143,230,150, 81, 48,228,146,241, 40, 24, 36, 0, 32,128, 24,169,123, 64,194, 40, 24, 5,163, 96, 20,140,130,161, 2, - 0, 2,104,244, 70,176, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, - 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 47,133, 31,213, - 59,170,151,230,122,113, 45,207,165,181,222,209, 56, 26,213,139, 31, 0, 4,208,104, 15, 96, 20,140, 2,218, 2,200,233,246, 16, -146, 84, 64,204,145,250,163, 0, 43,184,121,243,230,104, 32, 16, 4, 0, 1, 52, 90, 1, 12, 36,184,118,237, 90, 58, 18, 0,114, - 7,191,222, 81, 64, 18,184,119,239, 30,228, 96, 3, 32,137,124,236, 1,241,165, 63,228, 88, 89,178,207,228,193, 37, 66, 69,189, -240, 59, 57,200, 3,180,168,222,128,165,127,127,127,255,104,242, 35, 8, 0, 2,136,101,248,121,233,240,225,195,182,182,182,131, -223,157,144,116,223,219,219, 11, 23, 41, 46, 46,102, 32,250, 50, 72, 32,249,111,165, 32,162, 38, 15,159, 72, 7,189,163,128, 84, -128,124,212, 1, 73,167, 26, 32,151,254, 64,146,145,145,145,248, 35, 22, 40,217, 45, 72,134, 94,200, 57,254,120,156, 7,236,253, - 64, 14,249,193,227, 89, 76,189, 4,117,225, 47,253,255,253,251, 55,107,214,172,165, 75,151, 70, 71, 71,143,166, 67, 92, 0, 32, -128,134, 97, 15, 96, 9,142,195,236, 6, 91,233,159,159,159,143, 92,250, 67, 42, 3,160, 32, 49, 13,174, 5,185,220,200, 37, 56, -164, 64, 7, 10,210, 84,239,199,143, 31, 51, 51, 51,225,183,208,188,120,241, 2,168,165,181,181,181,185,185,185,170,170, 10,114, - 94, 63, 46,192,246,241,171,110,230,124,158,253,247, 33,220, 63, 47,254, 92, 77,255,113,169,149,237, 72,179,224,230, 42,249,115, -187,164,135,107, 6, 35,227, 60,125,180,210, 31, 2, 72,234, 7,208,185, 7, 0, 57,199, 31,162,114, 15, 24,160,149,227,248,111, -248,130,235,197,212, 69, 70,231, 0, 94,250, 3,155, 83,192,210,255,200,145, 35,163,165, 60, 30, 0, 16, 64,195,173, 2, 0, 54, -255,129,109,165, 65, 30,235,144, 33, 23, 57, 57, 57,120,195, 31,210,246,135, 11,226, 25,147,129, 72,197,217,176,193, 26,239,239, -129, 8,194,134, 8,210, 72, 47, 16,156, 60,121,146,131,131,227,248,241,227,136,212,195,196, 84, 93, 93, 93, 91, 91, 27, 31, 31, -191,117,235, 86, 60,122, 37, 78, 94,251,207,193,202,117,252, 17, 92,132,145,233,191, 94,245, 47,155,218,247,230,241,175, 78,111, -149, 30,205,138,152,165, 63, 35, 12, 16, 89, 7, 32, 79, 24,164,163, 2, 6, 66,211, 9,148,232,133,215, 1,239,222,185,204,156, -249,158,164,210, 31,107,253, 1,215, 69,106,175, 20, 88,250,247,245,245, 1, 67, 12,152, 50,207,156, 57, 3, 44, 13, 70,147, 19, -126, 0, 16, 64, 76,248, 11, 83, 50, 66,144,194,241,101,160,141, 16,141,228, 69, 30,176,249, 63, 99,198, 52,178, 59, 1,244, 73, - 49, 19, 39, 78,132,183,253,129, 69,127, 47, 24,192,235, 0, 32, 27,168, 0,143, 94,120,251, 29, 88,124,223,222, 22, 11, 68,240, -114, 28, 40, 69,188, 94, 72,155,148, 72,189,192,210,231,216,177, 99,192,222,244,163, 71,143,158, 63,127,142, 38,245,240,225, 67, - 73, 73, 73, 6,220,154, 37,143, 93,121, 18,109,205,246,232, 35,227,115,248,161,211,144,171,220, 24,222, 61,100, 23,146,252, 62, -204,242,213,189,123,247,240, 20,181,120, 38, 3,208,218,254,104,247,202,225,175, 3,144,111,224,154,137, 10, 24, 8,221,207,133, - 44,251,127,149, 32, 50, 98, 32,241,110, 47, 72,185, 79, 82, 57,142, 92,127, 0, 17,121,165, 63,176,123, 58, 97,194, 4, 96,219, -191,160,160, 0, 88, 7, 64,218,130,211,167, 79, 31, 45,229,241, 0,128, 0, 98,193, 83, 20, 46, 93,186, 28,146,224,136, 31, 82, -135, 36,205,152,152, 24,136, 22,160, 33,144, 50,133,200,184, 4,170, 95,178,100, 9, 80, 59,184, 40, 95, 66,146,213,240,230, 63, - 36,159,144, 49, 19, 0,177,157, 84, 75, 41, 1,144,210, 31, 94,238, 35,115, 9, 87,221,224,210, 31,194, 6,213, 1, 94,139,209, - 6,118,240,235,133,199, 8,184, 14, 72, 39,168, 23, 88,196,255,250,245,203,216,216, 24,216,187, 2,118, 2,130,130,130, 64,117, -198,191,127,237,237,237, 95,190,124, 97,101,101, 5,102, 63, 92,122,133, 30, 62,101,250,245,231,131,177, 2,235,145,103, 44,199, - 95,254, 14, 82, 4,197,209,191,255,151,218,217,222,125,225,253,206,202,227,154,121,123, 56,101, 42,130,205,222,206,206, 78, 96, -121,135, 57,192,141, 89,178,195,155,255,152, 42, 7,225, 41, 94,233,233,130, 72, 53, 10,168, 97, 1, 12, 6,178,239,249, 32,181, -237, 15,204,245,240,187, 33,109,108,108,128,217,121,180,244, 39, 8, 0, 2,136, 5,119, 81,184,108,230, 76, 80,240,101,100,100, - 17, 89, 38, 66,198,181,181,180,180,224, 34,182, 96, 0,233, 19, 16,140, 81,120,233, 15,183,139,212,226, 24,232,230,152,152, 40, -112, 13, 20, 5,100,147, 90,121, 0,173,131,223,103, 48, 36,166,145,233, 9,142, 30, 61,106,110,110, 14, 44,143,128,228,134, 13, - 27, 2, 2, 2, 32, 67, 64,149,149,149, 12,224,171, 23,150, 47, 95, 14,148, 50, 53, 53,197,212, 43,127,244,204, 11,115, 77, 96, - 97,246,213, 92,150,121,195,243,223, 1,138,224, 33, 32, 6,189,202, 95, 64,173, 95,223,126,220,183, 92, 69,222,252,139,158,233, -147, 97, 16, 80,248, 47, 85,135,131,213, 96,128, 89,136, 35,223,169,130,235, 90,105,172, 23, 55, 14, 56, 0,214,103,152, 75, 93, - 33, 99, 59,164, 2, 50,116, 65,206, 12,103, 97, 97, 41, 44, 44, 60,115,230,204,232,208, 63,145, 0, 32,128,176, 87, 0,192,182, - 63,164, 36, 5,130,232,232, 72, 32,151, 96,129, 8, 25,234, 65, 46,253,225, 0, 34, 8, 84,128, 85, 22,169,248, 70, 41,253, 33, - 12,160, 32,145,101, 49, 48,202,129,197, 19, 68, 49,144, 4, 86, 0,196,119, 2,224,165, 63,114,238, 34,178,206,163,164,253,130, -220,234, 39,169,249, 15, 25,177, 1,182,250, 33,157, 0, 85, 82,154,255, 80,189,225,233,240,187,159, 8,234,253,253,251, 55, 48, - 83,241,242,242, 94,186,116,233,239,223,191,159, 62,125,186,126,253,186,176,176, 48, 92, 1,144,237,237,237, 61,109,218, 52,204, - 10,128,249,247,111,217, 51,151,217,120,165, 89, 47,189,253,248,151,247,243, 39,182,191,215,191, 48, 8,115,192, 21,112, 11,255, - 49,245,126,178,112,154,237,240,168, 0,128,161,138, 57,244,129,121,201, 34,164, 7,128,182, 97,135,164,181, 58,180,184,225,142, - 26,222,127, 15,233, 10, 32,247, 6,136,239, 64, 0,195,141,140,210,127,233,210,165,135, 14, 29,250,191, 74,144, 49,236,125,127, -127, 63,176,226, 4, 54, 77,102,204,152, 49, 90,190, 19, 4, 0, 1,196,130,181, 52, 4,134, 32,114, 65, 12,172, 0,128,197, 43, -176, 87,133,199,160,137, 19, 39, 66,134,110,176, 2,160, 20, 80, 1,158,244, 13, 25,124, 71, 43,115,193,229,248, 18, 98,202,113, -228, 46, 11, 4,196,198, 70, 47, 94,188,148,152,114, 28,185,244, 71,107, 97, 17,212,139,199,203,120, 0,176,159, 4, 47,238,225, -163,255,200,179, 2, 64, 5,120,244, 50,133, 67,135,242, 33,117, 0, 3,210,154, 78,166,240,247, 36,232, 13, 79, 39, 82,239,133, - 11, 23,228,228,228,128,109, 43, 8,119,209,162, 69,199,143, 31,247,241,241, 65, 86,243,242,229, 75, 14, 14, 14, 76,189, 10, 23, - 46,124,144,147, 60, 89,152, 4,225,178, 45,186,253,247,248, 71, 38, 31, 20,149, 31, 95,114,178,115,252, 30, 54,153, 10, 88,178, - 43, 41, 41,225,185,235,170,188,188,156,200,107, 14,145,135,128,112,117, 8, 6,109, 32,144,161, 30, 82,113,146,164,119,217,178, -165, 7, 14, 28, 96, 92, 3,106,142,236,170,225,117,107,249,108,103,103, 55,186,244,147, 72, 0, 16, 64, 44,152,165, 33,114,243, - 31,222, 9, 0, 22,166,200,181, 2, 86,128, 71, 22, 82,148, 19,108,254, 99, 45, 97, 9,118, 2, 32,110, 70, 46,253, 33,131,128, - 64, 7, 3,197,129, 89, 8, 79,213,133, 89,250,147, 84, 7,144, 55, 82, 4,233, 9, 61,122,244, 8,178,230, 7,185,225, 15, 20, -196,213,145, 66,214,187,232,200, 47,200,186, 29,228,198, 59, 80,144, 70,122,129,197, 61,178, 79,237,237,237,187,187,187,157,157, -157,255,253,251,215,214,214, 6, 36,191,127,255, 14, 12,103,172, 49,168,126,252,248, 37, 91, 7, 56,247,143,189,228,223,238,199, - 12,206, 98,255,255, 49, 92,106, 99,253,242,143,231,221,119,190,119,140, 66,126, 49, 23,135, 83,190, 2,150,239,248,167, 91, 73, - 41, 26, 87,129,200, 61, 97,196,244, 71,225,233, 22,235,106, 78, 60,247, 53, 34,235, 5,182,163, 73,210,139,217,138,135,220,225, - 76,159, 1, 55,208, 52, 53,164,244,191,244,103,254,254, 95,224,242,106,180,244, 39, 22, 0, 4, 16, 74, 5,144,145,145, 5,186, -213, 54, 38, 10,179, 37, 14, 25, 23, 2,162, 25, 51,166,209,200, 41, 88, 11, 83,130, 53, 7,220,205,184, 12, 4, 86, 93, 64,132, - 86, 61, 32, 87, 60,120, 50, 42, 48,121,209,104, 50, 0,158,217,200,216, 8, 6, 84,144,144,158,158, 48,249, 43,234,102,174,247, -180,211, 11,190,158, 30, 1,228,229,229,167, 76,153, 66,100, 89,182, 13, 85,239, 63,121, 30,206, 41,154, 64,134,246, 76, 86, 6, - 6, 96,171,255, 61, 24, 61, 28,174, 25, 12, 94, 16, 67, 24,116,184, 45, 14,107, 73, 13, 23, 33,184, 10,136, 12,189,152,173,120, - 34,251, 55,148,135, 45, 48, 25, 3,203,125, 32,123,193,254, 95, 43,142,253, 2, 22, 5,163,251, 25, 73, 2, 0, 1,132, 82, 1, -224, 41,220, 33,211,185, 4, 19, 31,217, 10,200,190,201, 22,127,133, 68,161,179,105,157, 93,175, 93,187, 6, 95,253, 9, 25,162, -193, 63, 77,130,166, 23,178,131,151,158,122, 71, 1,169,160,188,188, 28, 62, 22, 4,100,211,199, 82, 58,239, 4, 30, 88,224,222, -242,121,168, 56,117, 16, 2,128, 0, 98, 25, 13,130, 1, 4,192, 98,151,236, 36, 59, 80,122, 71, 1,169, 99, 65,144,147, 18,128, - 36,241,237, 98,148,213,159,176,193, 31, 92, 75, 66,113,141,231,224, 23,161,133, 94, 90, 84, 93,248, 1,176,243, 10, 12, 22, 63, -255, 52,104,119,115,251, 57, 8,195,203,211,104, 52,237, 17, 3, 0, 2,104,180, 2, 24, 5,163,128,182,192,197,197, 5, 88, 1, - 16, 63,177, 73,121,105, 59,176, 61, 0,250,214, 22,255, 33, 59, 10, 71, 1,121, 0, 32,128, 70, 47,133, 31,137,128,243,231,141, -239,236, 26,163,225, 48, 10, 70,193, 8, 7, 0, 1, 52,122, 28,244, 72, 4,163,165,255, 40, 24, 5,163, 0, 8, 0, 2,104,180, - 2, 24, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, - 96, 20,140,130, 17, 10, 0, 2,136, 38,151,194,223,191,122,156,129,233,135,164,140,244,231,239, 95,223,191,253,170,166,105, 67, -188,222, 35,231,238, 50,252, 99,127,249,244, 41, 55, 39,183,160, 16,183,185,137, 34,241,122, 41,113,243,191, 55, 83,120,121,190, -115,114, 51,179, 48, 51, 49,114, 48, 62,255,148, 79,188,222, 79,188, 65,130,194,130,252, 60,204, 12, 44, 12,239, 46,204,194,111, - 47,167,244, 13,226,221,252,253, 41,202, 96,189, 20,215, 75,226,245, 62,251, 38,142,162,247, 39, 9,246, 62, 67,157, 36,144,254, - 69,194,245,170, 79,217,212, 7,131, 94,109,108,225,220,217,185,186,188, 28,203, 81, 51, 87, 81,195,153, 83,230, 23, 9,113,244, -132, 13, 37,109, 72,147, 16, 71,155,159,162,196,209,143,159,220,196,235,229, 96,255,138, 98,148,223, 20,226,245,250,110,202, 65, -230, 22,191, 32,225,216,156, 94,137, 12, 26,229,193, 81,189, 52,210,139, 7, 0, 4, 16,190,101,160,169, 7,138, 24, 29,227,103, -253,215, 39,198,160,123, 87,118, 49, 50,252,227, 97,231,156, 63,115,217,194,133, 19,173, 93,172,255,124,253,166,165, 97,247,239, - 31, 67,118,217, 95, 45, 45,245, 59,119, 30,254,248,254,135, 87,210, 26, 83,239,209,243,175,254, 51, 48,126,249,249, 61,189,168, -165,113,146,251,179,171,103,129,201,123,219,197, 39, 76, 76, 12, 19, 27,106,110,221,186,169,160, 32,207,206,201, 34, 44,200,142, -197,222,117,211,216,216,216, 56, 57, 57,121,120,120, 68, 4, 56, 68, 89,121, 69, 37,185,249,217,121, 5,216,152, 88, 88, 88,254, -255,251,251,137,153,225,211,171, 79,135,121,117,113,185,252,227,221,169,188,156, 31,249, 4,216,120,184, 89,217, 56,153, 88,152, - 25,152,216, 88,212,165,103,255,254,207,124,239, 89, 18,126, 95,239,127,164, 44, 34, 34, 34,206,243,227,251,143,159, 76,236,156, - 12,191, 25,254,200,197,124,120,255, 78,228,243, 54,218, 85,218,179,102,205, 74, 75, 75, 27,109,188, 16, 4,184,138,123, 82,213, - 0,129, 4, 39,215,211,167, 79, 89, 57,216,255,113,113,209,211, 11,223,222, 93, 56,182,119, 5,178,136, 75,104,199,224, 12,237, -197,139, 22,177,179,177,253,251,247,143,155,135,199,215,207,111, 52,249, 13, 9, 0, 16, 64, 4,246, 1,252,223,187, 48,205,153, -112, 29, 16,234,167,242,211, 73,232,247,151, 15, 44,127,153,204,244,100,226,227,161,205,103, 96, 9,126,226,248, 2, 17, 57,233, -127, 95, 62,217,155,235, 62,123,246,126,207,249, 63,104,122,211,211,219, 24,216,248, 25,185,248,254, 51,255,191,120, 45,113,222, -138,157,208, 38,249, 63, 6, 15, 75, 75,134, 47, 47, 24, 24,120,239, 94,190,206, 42, 34, 96,109,161,195, 35, 32,134,197,122, 70, - 38, 32, 98,252,207,204,250, 11,104,204, 31,102,102,102, 86,102,102, 54, 86, 16,249,251, 47, 3,227,159,127, 32,119,224, 0, 47, - 46,182, 8,241, 51,240,113,113,137,138, 8,243,241,113,253,103,250,251,231,223,151,191, 12,127,121,120,184, 68, 36,100,148, 84, -143,236, 57,136,253, 28,161, 25,187,127,241,243,114,243, 11,124,254,241,141,237,235, 87, 14, 54,118, 14,214, 31,127, 65,237,193, -111, 63,190,126,251,254,232,189,206,171, 55,239, 62,189,126, 18,102,133,221,234,213,157,132,174, 73, 74,112, 17, 20, 23,196, 90, -250, 83,177, 14,168,234,238, 6,146,109,165,165,100,232,173,236,234, 2,146,237,101,101,196,107,185,242,244,233,173, 91,183,128, -140, 32, 71, 71, 34,181,204, 92, 5, 58, 9, 7,249, 86, 44, 32, 27, 66, 50,192,206, 71, 3,178,211,176, 29, 33, 9, 44,217,241, -151,239,196,148,254,138,130, 66,223,127,253, 4, 50,216, 56, 57,126,125,255,241,239,235,183, 55, 47,158, 75,234,234,226,209, 34, -169,172, 70,208, 95,252,242,154, 55,246,109, 36,168, 12, 88,250,219,184, 68,112, 8, 26, 16, 21, 88,161,239, 8, 42, 9, 11, 11, - 91, 21,186, 7,171,148,227,158,215,112,182,150, 0,168,100,120,245,227,223,247, 63,160, 16,254, 10, 38,103,154, 11,168,241,178, - 98,213,219,211,211, 83, 85, 80,226, 31, 20,248,227,199,247,137,253,125, 83,166, 76,201,201,201,161, 48,113,222,185,115,167, 27, -156, 62, 9,110, 44, 56,126,252,248,131, 7, 15,222,190,125,251,249,243,103, 94, 94, 94, 97, 97, 97, 5, 5, 5, 75, 96,233, 49, - 10,192, 96,203,146,102, 56, 27,109,221, 63, 64, 0,225,171, 0,102, 59,244, 5,159,104,253,119,108,107,154, 21, 3,254, 58,224, -231,151,119, 18, 42,206, 45,165, 65, 11,102, 30,128,136, 28, 60, 54,227,235,183,159, 94, 46,249, 86,214, 9, 17, 97, 78,156,156, -236,191,254,254,249,252,237,151,154, 5,230,161, 61, 15, 25,126, 49, 4, 69, 79, 79, 45,130,118, 45, 61,172, 28, 56, 56,216, 55, -236,219,185,237,232,241, 69,243,167,253,248,254,147,141,153,133,135,139,141,143,237,239,157, 71, 47,208,171, 40, 96, 17,240,255, - 31, 8, 49,253, 3,178,127,254, 98,103, 0, 86, 49,236, 12,255,127,253,253,203,204, 0, 44,202,255,254,250,247,231,239, 63,172, -206,190,123,170, 93, 70,244, 63, 31, 47,183,180,140,162,134,174, 10, 47, 15,231,199, 47,175, 95,188,126,241,254,227,203,223, 63, - 24,185,128,181,130,168,117,112,224,229,181,235,213,209, 52, 78, 95,250,248, 47, 47,239,119, 22, 6, 54, 14,182,239,223,216,126, -125, 99,251,193,193,206,194, 8,204, 37,204, 63,190,127,249,254,237,243,247,239, 95,191,127,250,248,249,197,195, 9, 19, 30, 43, - 27, 99,223,255,217,189,168, 27, 87,120,150,198, 97, 47,145,223,191,127,143,204, 22, 18, 18,130,148,134,130,130,130,119,239,222, - 93,189,122, 53, 73,181, 2,155, 56,116,252, 1,104,168, 32,185,105,107,214,234,213,217,217,217,191, 95,189, 34,166,244, 23, 19, - 19, 11,114,115,251,205,206,222,219,219, 27,236,228, 68,204,241,150, 64, 15,246, 52, 52, 64, 71, 42,234,235,123, 27, 27,177,178, -113,105, 71,174, 3,128, 12, 99, 99,227, 61,123,238,185,184, 40, 17, 89,250,107, 72, 72, 10,240,241, 65,146, 25, 55, 7,231,243, -215,175, 62,189,255,192, 35, 32,248,240,244, 25,121, 83, 19, 60, 26,253,210, 74, 98,130,125, 85, 21, 20, 32,220,250,222,201,112, -169,198,226, 92, 32,249,104,251, 94, 51, 53, 89,162,134,122,136, 44,253,161, 45, 11, 33, 66, 42, 8,239, 71,227,102, 97,188,216, -152,204,200, 39,242,247,222,197,159,247,174,222,122,247,213,100, 59,190,248,157, 49,115,102, 81,122,118, 92, 74,210,234,165, 43, -128, 37,111, 75,103, 23,111, 67, 11,252,210, 8, 74,138,126, 80, 94,192,219, 58, 1,150,248,187,118,237,250,253,251,183,178,178, -178,173,173, 45, 63, 63,255,135, 15, 31,158, 61,123,118,255,254,125, 32,233,230,230, 6,172, 15, 70, 75,127, 52, 46,114, 29, 0, - 16, 64,232, 21, 64,218,109,216,209, 58,224, 29,118,255,255,125, 97,248,245,243,247,129,101,105, 14, 12,132,250, 1,108, 90,154, -234, 76, 76, 7,110,125,120,203,192,112,253,227,211,219,192,254,242,198,173,147,190,189,249, 27,157, 88, 8,108,206,251,249, 90, -254,101,225,193,165,249,214,173,235, 64, 53, 94,250,192,102,157, 20, 3,131,252,143,159,191, 66, 60,220, 56, 4,152, 22, 45,219, - 1,108,190,175, 89,177,128,249,207,103, 77,121,246, 59,143,208, 53,254,251, 15,186,151, 10, 8,254,254,253,251,147,245,255,111, -198,223,191,126,253,250,198,245,131,225, 31, 7,211,255,191,127,217,254,127,249,245,227,215,247,111, 12,124, 88, 44, 21,229,249, -201,194,194, 9,108, 47,168,168,168,136, 75,152, 51, 48, 51,253,253,123,150,233,255,135, 31, 95,129, 85,198,215, 23,207,222,137, - 10,191, 17, 22,176,150,148, 93,204,192,128,210,226,227,252,241,231,255,207, 55, 12, 63,216,127, 49,253,254,202,198,242,133,147, -149,133,149,141,225, 31, 55, 35, 51,227,151,175,223,222,191,120,120,247,236,209,119,143, 30, 1, 93,197,244,159,153,200,120,154, - 55,125, 30,132,145,148,137,115,220, 9,249,158, 41, 32,187,168,168,232,209,163, 71,192, 34,146,188,189,151, 83,167, 78,125,249, -242,229,154, 53,107,188,237,236, 4,197,196, 72,213, 14,108,251,191, 7,151,140,144,131,225,210,195, 8, 28, 87, 9,108,251, 3, - 75,127, 80, 66, 97, 99, 83, 83, 83, 91,187,111, 31, 49, 93, 1,202,207, 64, 6,150,242,192, 66, 31,114, 97, 8,156, 12, 13, 13, - 37, 88,250,171,137,137, 3, 75,127,102, 38,166,172,152,232,239, 63,126,246,206,157,203,197,201,249, 3, 8,190,127,103, 98, 97, -126,124,254,188,172,161, 33, 46,189,144, 82,254,246,131, 7,200, 92, 50,128,185, 83,196,158,213, 21,174,126,201,255,217, 85,137, -212, 2, 63,203, 19,114,155, 35, 86, 17, 92, 0,216,240,127,248,229,239, 65, 87, 81,214,252,153,159,162, 21, 89, 4,197, 8,150, -254,123,247,238, 85,144,148, 74,201,202,168, 40, 44,155, 50,127,134,153,145,209,140,201, 51, 10,202, 74,150, 90,154, 95,190,124, - 89, 23,111, 87, 9,127,209, 15, 52, 25,200,197,175, 30, 88,250,139,138,138, 26, 26, 26, 50,129,123,249,192, 28,199,202,202, 10, -108, 24, 73, 72, 72, 0,235, 0,160,108,112,112,240,104,233,159, 86, 14, 29, 54,156,213, 89,129, 86, 7, 0, 4, 16, 74, 5,144, -122,172,242, 27, 51,199,191,191,255,254, 49, 50,243,254,255,206, 0,108, 6, 51, 48, 51, 72,171,177,254,250,250,127,207,188, 52, -151, 36,188,117,192, 63,102,102, 72, 97, 7, 44,107,101,248,165,213, 31,222, 92, 51,125,230,124,166,159, 92,110,142,214, 59,246, - 30,253,246,141,129, 75,136, 31, 83, 27, 39,151,250,247,111, 55,129,197, 55,124, 84,134,129,225, 25, 19,179, 67, 92,124,242, 63, -246,175, 91,182,206,243,243, 77,226,226,102,248,246, 22,152,136, 37, 48,181,255,102, 96,102, 5,151,254,191,255,252,253,249,233, -247,183,223,223, 62,112,178,252,254,198,250,147,229, 55,243,111, 70, 96, 65,254,233,251,159,175,159,127, 51,136,163,107,188,184, -191, 83, 73,130,145,153,153,145,145,137,253,239,223,255,127,190, 61,250,249,247,247,211, 23, 31,223,189,255,242,241,243, 95,166, - 31, 63,254, 48,188, 96,102,189, 32, 37,247,137,151,131, 19,211, 94,160, 87,255,127,254,241,253,243,179,191, 47, 63, 50, 43,203, - 0,211,223,223, 63, 63, 63,188,120,112,243,212,241,215, 15, 31,129,139, 45, 22, 38, 96,232, 50, 83,243, 12,119, 72, 3,127,214, -172, 89, 33, 33, 33, 6, 6, 6,236,236,236,125,125,125,228, 25, 5,105,254, 91,232,232,136,139,139, 3, 75,112, 31,123,123, 41, -210,235, 0, 65,112,185,207, 42, 38, 6, 52, 1, 72, 18,236, 7, 0,219,254,172, 63,127,174, 93,187, 22,185, 43, 64,252,112, 16, -217, 0, 82,238, 35, 95,201, 2,172, 62, 9, 86, 0, 95,191,125, 19, 21, 18, 74, 12, 9,249,240,241,211,235,119,111, 89, 89, 89, - 32, 0, 88,196,176,115,114,125,122,251,230,243,227, 39,188,178, 56,167,230,128,165,255,146,181,155,145, 43, 0, 72, 63,192,220, - 72,207,203,209,158, 8, 87,127,102, 96,224,229, 21, 54,112,241,227,222,189,105, 46,125, 70,255, 47, 45,156,240,115,199,124,177, -217,231,128, 53, 1, 51,159,208,159,247,175,128,165, 63,176, 67,240,245,207,127,102, 28,195,168,247,239,220,217,182,105,235,194, -217, 11, 39,205,157, 54,163,111,130,144,176, 80, 75, 91,203,162,101, 75,109, 45,172,231,205,157, 23, 20, 26,100,107,109, 75, 70, -233,191,105,211, 38, 96,191, 86, 82, 82, 18,237, 2,106,180,145, 31, 96,219,223,200,200,232,207,159, 63,192,174, 0, 7, 7, 7, -176, 2,184,113,227, 6,176,169,193,195,195, 3,236,237,189,120,241, 2,168,102,116, 44, 8, 81,128,148,119, 64,234, 0, 56, 0, - 8, 32,148, 10, 96,182, 85, 59, 84, 29,211,229,255,251,230, 51, 10, 75, 50,164, 76, 62,205,169,105,250,120,227,191, 89,181,204, - 71,150,167,217, 50,205,250,135,165, 74,223,180,239, 93,154,202, 39,255,248,252,226, 92, 96, 7,226, 29, 48,225, 50, 48,252,148, - 87, 55,226, 96,103,249,254,245, 39,195, 47, 80,197, 0,236,139,189,122,247, 30, 83,239,132,254, 34,208,221,241, 39,230, 50, 49, - 65,150, 49,128,134,107,254,125,191,250,227,231,111, 78, 30, 14, 6, 54, 80,197,240,249,211, 39, 49,164,251,167, 80, 60,240,239, -215,191,127, 44,192, 20,240,243,231,207, 47, 44,204, 44,191,152, 24,158,127,250,195,245,231, 47,219,191,255,172,204,223,152, 89, -254,124,253,246,229, 23,150, 69, 29,188, 60, 95,255,252, 97,252,249,235, 47, 48,123,223,186,243,232,201,243, 55,223,127,253,254, -244,229,221,151,207, 31,126,252,253,197, 8, 76,244,223, 62,126,250,118,255,225,211,143,111, 63,127,101, 96, 80, 65,211, 14,116, - 22, 36, 71,252,249,248,245,201,133,235, 47,175,223,255,244,249,206,231, 15, 31,254, 51,176,176, 50, 51,254,103,100,101, 98, 2, -245,161, 8, 30, 83, 82, 26, 87,138,103, 44, 8,139,127, 89,160, 81, 6,204, 30,192, 26, 23,249,176, 73, 82,155,255,192, 90, 4, - 52,198, 45, 42, 74,252, 41, 99,216,139,117,112,185, 15,172, 3,240,116, 2,174, 60,125,202, 0, 62,251, 26,216, 34,131,244, 3, - 64,197,205,165, 75, 64,114,221,254,253,248,235,128,226,250,122,200, 72, 23,144, 93,210,208, 0,239, 19,224, 25,249, 65, 6,192, -230, 63,218, 56, 50,228,208, 99,248, 88, 16, 86, 32,192,194,242,227,215, 79, 96, 8,223,184,119, 23,104,227,181, 91,183,127,253, -250,205,196,192, 8, 12,127,160, 99,128, 45,142,239, 95,191,237, 94,181, 50, 8,233, 48, 87, 52, 0, 47,253, 99,130,125,145,197, - 79,158,187,164,170, 40,207, 78,216,225,176,177, 11,118, 85, 96,209, 15,236, 7, 0,145,103, 96,242,111, 22, 85, 26,150, 16,239, -158,179,201,169,189,202,230, 96,119,138,252,123,102,199,223, 79,160, 73,133, 87,217, 86,242, 51,143,255,253,135,189, 41,163,174, -170,206,197,197, 61,105,206, 84, 71,123,123,115, 75,139, 93,219,118,222,184,115, 11,216, 49,231, 96,103,183, 54,182,222,186,105, -235,155, 87,111, 2, 3, 3,137, 47,250,129,205,246,123,247, 64, 81,118,234,212,169,140,140, 12, 60,189,219, 7, 15, 30, 40, 43, - 43, 67, 24, 23, 47, 94,148,151,151, 87, 84, 84,124,255,254,253,153, 51,103,148,148,148,128,141, 12,160, 8, 80,106,180, 2,192, - 3, 0, 2, 8,203, 28, 64, 26,227,197,255, 7,151, 49, 50,179, 48,228,206,205,127, 32, 57,169,111, 33,176,176,156, 94,123, 51, -181, 77,157,121,207,172, 52, 89,205, 89,170, 89,192, 54, 55, 19, 19,202,224,134, 10,159,204,149, 75,235,192, 76, 96,193,248, 21, -124,212,251,111,134,223, 63, 89,254, 1,155, 14,160, 50,125,253,134, 93, 64,210,218, 19, 75, 25,177,227,242,127, 15, 67, 29,120, - 23, 22, 88,202, 49, 48,176, 50,176,114,252, 97,252,251, 15,124,210, 83,120, 52,232, 76,249,135,199,102, 97,234, 5,166,203, 63, -255,152,152,254,252, 97,250,245,243, 27,184, 27,248,157,153,153,251,207,247, 79,223,129,133, 48, 35,176,103,240,237, 47,195,183, - 95,127, 48,253,249,231,215,191, 31,172,204,255,190,253,249,243,239,227,231, 47,191,153, 25, 89,127,254,249,253,235,255, 47, 32, -193,192,246,143,137,145,129,145,253,223,199,239,127, 95,188,254,246,245, 39,250,196, 53, 19, 35,180,195, 2, 44,151, 32,103, 81, -253,254,241,253,227,187,119, 76,192, 80, 99,249,207,240,159,133,153,145,129,248,150,255,205,135, 55,213,229,213,241,140,252, 32, - 15,136,115,114,114,194,107, 2, 96, 62,129,148,254,192,106,128,159,159,255,227,199,143, 31,128, 53, 16, 17, 99, 38,144,230, 63, -176,155, 12,225,230,228,228, 76,158, 60,153,188, 78, 0,220, 4,200, 64, 16,254,209,127, 70, 94, 94,160,131,203,202,202,128,141, -232,223,239,223, 3,221, 92,145,147, 67,176, 31,128, 60,214,143,107, 62, 0, 83, 87, 39,161,105,246,179, 96, 0, 97, 99,158,136, -245,254,221, 59, 30, 94,222, 55,239,223,239, 63,121,146,133,137,249,231,239,223,223,190,127, 7, 54, 48, 33, 85, 17, 48,145,252, -250,249, 19,127, 80, 99, 14,251, 0, 69, 32,157, 0, 85, 5,133, 71,247,238,144, 20,194,192, 58,224,235,235,147,219,215,207, 37, -163, 31, 64,112,228, 7, 14, 46,172,154,109, 16, 95,200,174,168, 7,202, 32,111,158,223,122, 7, 90,105,202,110,233,243,232,239, - 31,174, 41, 39,177,106,249,244,233, 19, 59, 39,135,138,162,226,253, 39,143,223,190,126, 27, 30, 19,189,109,239,238,137, 29,189, -235,183,109, 82, 85, 84,141, 11,142, 61,126,238,232,250,181,107, 3,113, 15,197,192, 75,127, 96,209,239,234,234, 10,169,161,159, - 61,123, 6, 44,253,241,187,246,237,219,183,182,182,182,192, 60, 14, 44,229,143, 30, 61,170,165,165, 5, 76, 81,178,178,178,192, -206, 49, 19, 24, 0, 59, 16,240, 40, 30, 5, 88, 1, 64, 0,177, 96, 41,253,247, 45, 96, 96,103,103, 16,146,251, 38,107, 62,169, -101, 6,195,223,175, 12, 47, 62,213, 44, 63,152,225,159,193,176,103,225,163, 23,175, 25, 84, 25,254,253,253,131, 86, 1,220,249, -244, 73, 77,128,239,207, 79,134, 59, 7,150,168, 56,184,131,199, 72, 24,126,255,250,205,202,192,244,229, 7,104, 17,133,135,131, - 17,167,176, 52, 86, 71,120,232, 50,110,187,248,159, 21,216,220,151,115,255,245,232, 48,164, 19,192,202,198,254,155,225, 7, 15, - 39,232,238,192, 77,219,150,127,127,251,216, 66, 89, 0,203,192,211,191,127,108,191,190,255,102, 96, 3, 86, 2, 12, 63, 64, 89, - 20,216, 43,252, 9, 44,218, 89, 88, 25,126, 48,252,255, 7, 26, 26, 2,138, 96,230,128,111, 63,254, 49, 51, 51,254,254,243,251, -199,207,127,159, 62,255, 0,185,246,223,255, 95, 63,255, 1,107, 31,102,160,110, 14, 6,198,239,127,255,129,150, 16,125,255,252, - 29, 95, 8,130,186, 2,255, 24,254, 51, 50, 48, 49, 1, 75, 7,230,127,255, 25,129, 12, 80, 45,248,143, 9, 88, 49, 49,254, 99, -198,223,252, 39, 53,194,184, 96,203, 16,145, 75,127, 96,123, 7,216, 5, 6,118,131,224, 45,101, 98,154,255, 10, 34, 34, 16, 46, -144, 65, 97, 39,128,200,209,255,255,159, 63,215,214,214,254,124,251, 22,114,253,163, 10,184, 6, 98,253,249,211,215,215,247,233, -171, 87,210, 84, 93, 97, 9, 31,225,129, 79, 0,160, 1, 99, 99, 99,120, 15,224,234, 83,140,246,193,207, 95, 31,126,189,251,241, -227,135, 0, 63, 63, 7, 48, 41,254,253, 3, 12, 88, 96, 89,243, 11,216, 17,248,253,251,223,159,191,248,195,249,246,131, 7,240, - 25, 96,228,177, 32,228,153, 97, 82, 1,183,168, 57,176, 29, 69,134, 70,226,231, 0,236,119,191,126,165,176, 6,216, 9, 96, 84, -212,147,159,127,254,205,143,127,220, 44,140,191,142,108,184,121,239, 62,174, 4,242,253,207,175,179,199, 79, 77,232,233,183,114, -176,169,105,106,216,185,125,231,210, 69,139, 45,237,108,100, 21,228, 88,184, 88,247, 30,222,187,108,225,226,117, 27,214,110,221, -186,213,219,219, 27, 83, 59,228,158, 28,120,209, 15, 1,192,118, 12, 49,254, 2,166,121, 96,137, 15, 74,192, 10, 10,192,216, 4, -118,215,128,217, 31,216,234,103,103,103, 7, 54,134,128,130,188,188,188, 64, 53, 35,185,124, 7,182,108,182, 44,105, 70, 27,246, - 65, 6, 0, 1,132, 50,176, 7, 26,249, 57,188,148,129,147,227,193,167, 95, 12,223, 63,178,255,251,166,167,163,196,240,246, 27, -195,175, 63, 14,250,106,160,133,153,191,127, 48, 51,130,135,104,254,253,197, 48,234,195,173, 15,143, 88,216, 25, 60,252, 10,151, - 77, 2, 54, 82,126, 49,124,251,249,247, 59,195,134,253, 23,246,156, 6,221, 23, 47, 35,167, 8, 90, 99,143, 3,120,233, 51,254, -254,193,176,105,235, 14, 19,183, 92, 80,243,159,129,149,153,147, 33,204, 39,212,203,206, 31, 40,251,228,225,221,255,191,255, 98, -111,221, 0,155, 99,160,201,234,191, 63,127,129,166,127,127,254,248,254,237,219,183, 47, 95,190,124,254,244, 17, 24,247,159, 62, -127,249,241,229,203,247,239, 88,138,240,207, 95, 24,191,255,248, 11, 68, 95,191,253,254,252,229,231,251,207, 63, 63,124,250,245, -241,243,239, 15, 31, 64,228,187,183,127,222,189,255,243,238,227,159, 55,239,126,189,124,131,101, 4,137, 9, 88, 28, 0,179,214, - 95, 70, 70, 38, 96,153,255, 31,228,142,255,204,127,255, 65,195,243, 31, 56,187, 16, 51,255,171,105,169,121,116,219,209,157,251, -118, 66,234, 3, 96,111, 0,143, 98, 96, 18,103,129,133, 97, 23,120, 21,102, 69, 69, 5,228,148,121,228,101,145,196, 52,255,197, -197, 81,102, 69,178,179,179,183, 30, 58,244,140,136,197, 60, 88, 1,176,249,143,191, 10, 1, 54,243, 33,140,149, 43, 87,222,121, - 1, 90,202,181,229,192, 1,184,224,205,155, 55, 69, 69, 69,105,148, 7, 32,165, 60,242, 21,137, 16, 54,158,241, 31, 80, 69,203, -199,251,239,239,223, 79,239,222,191,121,243,230,237,135,247, 95,191,125, 3,162,207, 95,190,124,253,248,233,243,135, 15,192, 84, -246,235,199, 15, 96, 53,128, 75, 59,114, 41, 15, 47,253, 33,108,228, 21, 65,248,193,151,215, 39,247,172, 70,100,221,111,239, 46, -208,186,188,120, 30,174, 0, 44,247,129,165,255,207,131,107, 30, 38, 26, 2, 75,255,195,174,162,127, 62,190, 54,217,241,138, 5, - 71,244, 2, 91, 18,169,249,153,119,110,222, 60,126,224, 48, 63, 47,127,100,120,164,128,176,208,185, 83,103,120,216, 56,184,185, -185, 37, 21,164,150,175, 88, 94, 81, 93,245,133,184, 50, 29, 2,140,140,136, 58,205, 31, 88,190, 3, 11,122, 96, 75, 31,216,234, - 55, 51, 51,211,214,214, 22, 17, 17,225,224,224, 0, 22,253,250,250,250, 2, 2, 2,144, 85,161, 35,188,141,143,220,187,197,236, -233, 2, 4, 16,162, 7,144,118,107,218,255,215, 15,126,176,114,236,121,197, 5,140,107,133, 15,207,153,215,181,108, 79,111,238, -214, 82,145, 20,228,200,213,224,100,152,122,254,255,239, 95,143,153,193,227, 6, 88,202, 25, 30, 96,138, 5, 82, 23, 47,109,214, - 55,240,173,171, 89,180,113, 93,223,174,253,215, 29, 45,181, 89, 88,216,119, 31, 62,247,159,153,229,215,223,191,248,221,234, 97, -168,177,227,236, 13,134,222,142, 16, 95, 47, 31, 31,223,157,251,214, 3, 27,232,222,238,145, 76,127,127,179, 50, 99, 47, 78,129, - 69,255, 95, 80, 73,251,151, 5,216,210,255,207, 2,108, 2, 0, 27,194,160, 37, 1,192,134, 56, 35,168,127, 0,233, 37, 96,233, - 63,126,231,101, 98,126,207,198,206, 4,106, 53,255,253, 15,108,237,255,251, 15,236, 61, 0, 59, 1, 12, 76, 28,255, 25,153,129, -173,121,198,191, 76,140, 63,255,254,255,240,245, 63,159, 56,214, 1, 25,196, 89,228,144,240, 96, 97,254,207, 4,170, 16,152,225, -133, 33,168,110,192,221,252, 7,150,254,208, 86,234,130, 61, 64, 4,100, 0, 43, 3, 6, 47,124, 65,244, 15, 60, 20,187,102,205, - 26, 72,222, 83, 84, 84,132,120, 16,216, 44, 5,122,156, 96, 5, 0, 44,253, 33,205,127, 69,234, 21,184,172,224,129, 35,111,123, -156, 19,155, 86,186,186,189,189,189,192,102, 62,176,160, 7,246, 6, 2,192, 39,227,171,171,171,195, 5, 31, 62,124, 40,194,206, - 46, 1,235,145, 80,119, 14, 0, 8, 32, 87,178, 32, 95,123, 75,240,210,218,247,111, 62, 50, 50,252, 1,181, 40, 94,126, 99,227, -224, 0,109, 42, 4,247, 0,190,127,249,242,243,235, 87,208,132,211,135, 15, 30,184,239,158,133,148,242,144, 81, 32,115, 35,189, -147,231, 46,193,165,208,166, 4,112, 54,111, 95,159, 60,121, 96,189,179, 87, 4,180, 50,248,120,251,230,165,163,100, 52,252,137, - 31,255, 1,245,213,222,125,125,148, 98,250,255,254, 37,177,217,231,190,254,249,255, 41, 90,145,127,217,253, 79,137,194,192,210, -159, 9,119, 5,159,157,147, 83,219,209, 34, 38, 44,242,251,223,223,219,143,239, 69, 71, 70, 45, 90,178,100,227,134, 77, 81,209, - 81, 63,127,252, 60,124,230,216,247,239, 95,210, 18, 18,246, 30, 63,142,185,142, 3, 24, 35,119,238,220,113, 3,119, 16,145,251, - 1,111,223,190, 45, 45, 45,133, 79, 12, 96, 5,194,194,194,207,158, 61, 19, 20, 20,156, 49, 99,134,169,169,169,161,161, 33, 27, - 27, 27, 48,239,159, 56,113,194,194,194, 2,168, 0, 40, 43,140, 99,238,112,196,214, 1,104, 0, 32,128, 16, 21,192, 44,181, 44, -135,175, 51,111, 61,121,255,220, 23,220,232, 56, 89,241,127,203,116,169,151,247,251,237,131, 24, 62,188, 99,104, 91,240,255,233, -141,191,156,220, 31,222,129,186,239,140, 24, 91,171, 14, 30,216,104,239,224, 12,100,124,253,247,251,206,135, 71,192, 18, 89,133, - 79,209,209, 81, 79, 92, 68,226,237,199, 79,160, 14,194,175, 63,207, 63,124,213,196,230, 8, 25, 57,203, 39,143,142,131,211, 44, -139, 7,104, 37, 40,203,142,203,191,119,110, 89,243,242,205, 51, 97, 1, 80, 23, 79,128,141, 85, 82, 0,251, 18,210, 95, 12, 44, -108,160,150, 24, 51,176,209,205,244, 23,216, 71,249,243,151,149, 5, 82,250, 51,128, 23,137,130,182, 8, 96, 3, 1, 17, 21, 27, - 22,151,112,177,253,103, 97,133,245, 36,126, 51,252,249,207,240,227, 23,195,223,159,192,134, 61, 35, 35, 27, 35,208,220,175, 63, - 25,146, 19,186,208,182, 86,195,103,128,255, 49, 1,235, 13,208,248, 15,164, 13, 14,236, 1, 48, 49,131,170, 35,160,236,127,102, - 96,183, 0, 95, 39, 0, 94,250,163,177, 65,117, 0,174,225,166,191,127,129, 69, 15,176,248,134, 84, 0,107,192, 0,200, 85, 86, - 86, 6,218, 62,113,226, 68, 96,135,224,221, 59,124,187,129, 74,192, 96,199,142, 29, 95, 95,162,156, 88, 0,172, 15,238,223,191, -207,128,119, 83, 24,230,206, 47, 96,209, 15,172, 78,128, 65,231, 99,111, 47,141,123,254, 0, 88,178, 91,233,233,189,125,240, 0, - 88,202,223,130,173, 5, 82,149,148, 44, 42, 42, 58,122,244,168,154,154,154,142,180, 52,158,105, 15,228,113,127,226,231, 0,144, - 39, 3,202,203, 65,139, 62,239,221,131,182,253,225,219, 2,240, 44, 4,226,145, 22,251,254,252, 5, 48,101,125, 5, 54, 50,223, -188, 6, 38,174,255,255,255,253,248,241,227, 63, 24,220,191,118,253,247,175,159,120,150, 0,161,244,110, 29,237,129, 8,190, 36, -148,152, 33,160, 47,111, 78, 1, 75,127,144, 51,184,185, 55, 34,117, 2, 76,108, 3,105, 90, 82,152,108,127,117,198,147,193,192, -216,229, 85,182,149,196,180, 99,192,250, 64,144,141,241,237,187,247, 44,140,140, 44,120,199, 8,227,226,226,224,236,205,155, 55, -123,121,123,110,217,180,101,213,170, 85, 13,213,181,187, 14,236,101,102, 97,150,150,145, 6, 6, 36, 3, 27,150,133,124, 42, 42, - 42,152,213,192,238,221,187, 25, 8,109, 1, 3,182,244,239,221,187,167,165,165, 85, 80, 80,176, 98,197, 10,126,126,254, 27, 55, -110, 32,143, 13, 0,101, 21,200, 29,112, 27, 33, 0, 32,128, 80,230, 0, 14, 24,166, 51,192, 86, 54,111,121, 37,224, 35,202,248, -255,204,182,255,199, 55,129,234,126, 14,142, 31, 92,188,187, 5, 28, 94, 88,186,128,199, 34,208, 55, 4,222,188,245,235,200,137, - 54, 80,153,200,204, 1, 25,174,184,243,233,121, 93, 78,210,183,111, 63, 63,125, 7,205, 1,252, 98, 98,119,242, 8,193,234,136, -218,234,132, 29, 91,193,219,106,254, 66, 6, 91,254,120,232, 50, 70,100,245,113,113,177,243,129,231, 0, 88,255,253,144, 22,197, - 94,190,176,252,255,243,139, 17, 84, 7, 0,139,138,191,192, 60, 10,204,169,127,192,115,182,140, 76,192,238,192, 31, 72, 69,133, -163, 14,248,240, 93,224,251,207,183,108, 44, 32, 69, 64, 21,127,128,213,199,239,255,191,255,252,255,242,253, 31,168,249,207,192, -248,251, 31,116, 48, 7,189, 32, 6,141,238,255, 5,194,255,192, 98, 1, 60,254,195,200,128,110, 5, 68, 91, 94,161, 35,174,115, - 57,174, 31,191, 78,106,108, 1,211,244,247,239,223,117,117,117,149,148,148, 30, 60,120,176, 10,188, 75, 22, 82, 25, 64, 64, 71, - 71, 7,193, 58, 0, 8,176, 78,175, 5,199,199, 51, 16,177, 41, 12,178, 53, 23, 25,248, 58, 56, 16,156, 61,150,128, 53,196,144, -123, 3,192,134,191,137,186, 58,219,215,175,248,189, 76, 73,250, 70, 46,229,145,119, 81, 48, 16,177, 79,152, 83, 82,226,219,237, - 59,127,255,252,249,244,254, 3,184,119, 5,138,226,247, 47, 95,125,122,255, 30,232, 42, 60,205,127,180,201,128, 37,107, 55, 35, - 47,253, 68,158, 30,192, 14,190, 93, 60,177, 31,178,158,130, 97,227,106,208, 2, 80, 35,251, 8, 33, 49, 3, 90,150, 3,255, 81, -234, 0,134,217, 6, 25,117, 47,254,253,211, 95,112,234,148,135,184,246,150,151,192,210,159,151,149,216,131, 35,129,145,187,239, -192, 62, 39, 87,231, 77,107, 55, 52,119,118,148,127,252,248,255,223,191,149, 43,215,138,136,136, 60,250,132, 83, 23, 90, 53,192, - 64,104, 11, 24, 16, 88, 90, 90, 2,219,248,231,206,157, 51, 50, 50,114,118,118,222,191,127,191,156,156, 28,176,133,100,111,111, - 15,140, 32,160, 56, 43, 43,235, 8, 95, 2, 4,217, 7, 0,239, 1,160,113,129, 0, 32,128,112,238, 4, 6,246, 3,230, 94,222, -163,243,247,170, 4,235,199, 31,255, 89,110,255, 23, 96,126,253,233,133, 5,116, 27, 33, 19,182, 1, 25, 81, 33, 67,175,132,184, -191,255,225, 77,245,255, 95,190,126, 98,102,225,103, 96,226, 42,235, 33,176, 83,201,195, 91,103,195,212, 10, 6,166,111,240,130, -148,135,135,255,239,239,247, 12,255,191, 62, 60, 54,203, 68, 79, 14,231,224, 50,176,145, 13,206,154,127, 24,152,217,254,131,171, - 1,112,233, 15,106, 46, 51, 64, 9, 92, 32, 33,173,102,214,228,134, 63,191,223,177,128, 23, 57,131,250,248,127,254,255,248,205, -240,233, 51,176, 51,240,255,207,127, 38, 22, 86,198,214, 38, 44,139, 91, 82, 82, 64,195,199, 11, 23,220, 97,252, 13,106,254,131, -186, 25, 32, 10,220, 74,250,207,204, 8,154,139, 98, 41, 46,113,195, 99,117, 74,115,202,131,187, 15,200,136, 81, 96,250,126, 15, - 94, 63, 99,108,108,108,102,102,246,250,245,235,187,119,239,130, 22, 38,254,251,183,118,237, 90,130,117, 64, 78,124, 60,167,152, -152, 15,182,225,154, 28,112, 5,192,137,187, 40,135,100, 72, 52,189,210,226,226, 36,185, 31,216, 27,176, 6,247, 6,196, 56, 57, -117,172,172,104,154,250,209,202,119, 96,136,161,205, 6, 19,172, 3,132, 85, 85, 62,191,127,207,194,206,246,243,231,143,191,191, -255, 0, 3,153, 87, 80,240,227,187,119,192,210, 31,127,243, 31,190, 17, 12, 50, 1,112,242,220, 37, 96, 5, 0, 31,253,199,181, - 47, 76, 77,242,253,155,183,111, 86,173, 94, 14, 23, 9,139, 78,126,247,139,180,117,159,152, 99, 62, 24, 34,140, 4,251, 1, 12, -219,161, 7, 57,168,108,132,238,189,255,248,251, 47,241,110,112,114,112,186, 40,120,209,205,219, 35, 53, 54, 89, 79, 95,119,211, -198,205,199, 47,156, 77, 75, 75,123, 68,232,144, 50,120, 53,208, 13, 6, 4,119, 56, 2,107, 11, 96,143, 97,203,150, 45,192, 38, - 17,176,223, 0, 89, 11,119,245,234, 85, 96,219, 31, 88,250,195,235,146, 17, 14,208, 54, 3, 35, 3,128, 0,194,119, 20,196, 63, - 93,151, 75, 12, 46,151, 72,177, 73, 71,199,122,210,164, 69,121,249,145,210,242,192, 84,251,147,149,157,227,201,243, 79,246,190, -113,196,232, 53, 52, 84, 74, 72, 8, 91, 48,111, 29,195,191,135,192,150,253,159, 31,223,165, 37,249,229,248,254, 16,208,246,247, - 31, 11,211,191,223,140, 44,172,255,255, 64,171, 1, 32,241,255, 47,145,203, 90,210,114, 65, 67, 10,245,149,153,172, 44,140,144, -115,131,254,254,253,251,225, 51,176, 38, 96, 96,102,249, 55,109, 42,190,244, 23,159, 0,218, 28, 48,111,238, 77, 6,200,137, 52, - 76,192,238, 2,104,204,167,168,196,135,160,189, 31,191,124,196,122,212, 15, 65, 0, 44,131,128,157, 0,160, 35, 63,125,250,196, -204,204, 12,100, 72, 72, 72,252,254,253, 27, 57,171, 0,235, 0, 92,103, 66, 64,154,234,130,100, 45,247, 20,130, 4, 41,137, 37, - 62, 38, 16, 39,113, 88,150,236, 57, 0,180,146, 29,235, 90, 32,130,219,193, 20,204, 76,129,228,141,131, 7,127,124,251,254,239, -239, 95, 77, 99, 99, 93, 43, 59, 30,105,188, 1,248,159,241,225,253,187,160, 25, 23, 6,134,164, 32,232,148, 14, 80, 4,153,141, -117,139,200,173,231,192, 36, 33, 24, 30,157,242,240,241,139, 19,135,182, 0, 69, 86, 45,157,107,110,231,195, 43,110, 67, 76, 64, -133,129,246, 97, 16, 62,233,225, 47, 35,246, 77, 8,143, 2, 37,182, 63,251, 65,173, 66, 71, 31, 12,206,156, 57,179,247,196, 65, - 97, 17, 97,146, 14, 41,129, 84, 3,196,168,228,229,229, 13, 14, 14, 62,126,252, 56,176, 25,116,234,212,169,209,179,128, 48, 71, -255,209, 74,127,180,249, 0,128, 0,162,254,165,240,202, 26,166, 91,119,222, 9,240,230, 18,147,150,125,247,249,143,189,119, 44, -241,122, 45, 77, 53, 44, 77,171,210,211,235, 24, 24, 94, 10,242,178,200, 9,253, 35, 60,106,153, 88, 66,185,155, 27,219,167, 3, -201,252,130,156, 95,223,127,255, 3, 47,181,236,159,218, 79,164,222,164,100,208, 73, 65,243,230,220,248,247,159,185,178,194,159, - 14,145, 10, 58,242,232,231,207, 95,191,126, 65,138, 69, 72,129, 56, 92,207, 7, 37,120,194, 4,241,128,152, 83, 63,113, 1, 13, -123,123,226, 21, 63,191,119,211, 92, 85,134,108,187,222,254, 82,225, 17, 87,113, 9,181, 33, 85, 35,174, 83,222,144, 0,211, 31, - 70,246,239, 76,216,231,255,239,126,254,163,198,139,167, 64, 32,103,161,176,137,137, 9, 29, 18,137, 37, 24,140, 22,247,184,234, - 0, 60,178, 0, 1, 52,122, 41,252,144, 4,163,183,186,143,130, 81, 48, 10, 40, 7, 0, 1, 52,122, 35,216,144, 4,163,165,255, - 40, 24, 5,163,128,114, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, 20,140, 80, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, 20, -140, 80, 0, 16, 64,163, 21,192, 40, 24, 5,163, 96, 20,140, 80, 0, 16, 64, 52,185, 20,126, 84,239,168,222,193,169, 23,114, 26, -196,104, 88,141,234, 29, 81,122,241, 0,128, 0, 98, 65,203, 30,196,232,193,154,133, 40,209, 59, 10, 72, 5,184, 10,178, 81, 64, -106, 40, 17, 25,146,143, 30, 61,122,250,244, 41, 59, 59,187,136,136,136,156,156, 28,221,188, 0, 63,243,117, 48,231,160, 87,175, - 94, 61,125,250, 20,191, 26,105,105,105, 49,108,187, 79, 40,209, 59, 10, 40, 7, 0, 1,132,190,236,151,224,206,123, 60, 27,172, -208,244, 98, 30, 77, 76,211, 51,135,233, 95,184,224, 87, 80, 80, 80,160,169,169,137, 95,187, 52,234, 25, 56,200, 57, 33, 52, 52, -212,197,197, 5,143, 94,170,212, 1,238,238,238, 64,114,231,206,157,116,208,251,245,235,215,181,107,215, 66, 46,133, 15, 14, 14, - 54,196,125,159, 34,166,103, 9, 94, 10, 63, 99,198, 12,172,173, 13,252,161, 68, 76, 24, 2, 75,168,159, 63,127, 2,173,224,224, -224,248,241,227, 7,176, 38, 56,125,250,180,190,190,190,138,138, 10, 46, 45,214,214,214, 4,253,245,252,249,115,200,181, 39,248, - 1,176,244,135, 28,247, 77, 76, 88, 17,179, 23, 36, 44, 44, 12,127,186,130, 0,121,121,121, 6,240,121,203, 64,191, 67,226, 14, - 79,154, 4,166,219,162,162, 34, 60,150,190,127,255,222,220,220, 28,107, 80, 3,245,106,105,105,225,209,251,242,229,203,218,218, -218,209,230, 14, 37, 0,207,165,240, 0, 1,196, 50,108, 60, 73,255, 70,241,198, 25, 30,184,164, 2, 50,119, 16,212,190,127,255, -126,120,246,248,246,237, 27, 23, 23,215,235,215,175, 9,214, 46,123,246,236, 65,102, 35,103, 72, 32,119,245,234,213,196, 7,194, -229,203,151, 33,133, 56,154, 57, 36,129,140,140,140,236,236,108, 98,174,126,133,220, 4, 25, 23, 23, 7,244,111,111,111,175,130, -130,130,160, 32,225,189,208,192,146,119,251,246,237, 16,182,135,135,199,142, 29, 59,176,178,241,244, 56,225, 9, 3,200, 48, 54, - 54,158, 53,107, 22,164,160, 36, 38,193,124,252,248,145, 23, 12,128,165, 63, 39, 39, 39,176, 50,248,240,225, 3, 63, 63,255,169, - 83,167, 24,192, 27, 86,113,105,212,209,209, 1, 22,151,240,130, 27,185, 21, 15, 44,208,129,228,137, 19, 39,162,162,162,136, 9, - 97, 34, 75,127, 8,152, 48, 97, 2,229, 9,155,155,155,251,218,181,107,172,172,172,191,126,253, 2, 6,242,237,219,183, 43, 43, - 43, 9,234,122,137,116,188,160,173,173,237,225,195,135,225,220, 55,111,222, 16,169, 17, 19, 60,128, 29,162, 55, 10, 40, 47,253, - 25, 48, 46,133, 7, 8,192,222, 25,219, 48, 8, 3, 81, 52,146,171,204, 16, 15,225, 34, 61,131,120, 10,247, 46,211, 51,144,229, - 13, 34,121, 28,183,121,242, 33, 11,129, 2, 7,105, 40,242, 43, 64, 50, 58,225,227,223, 63, 23,247, 47, 90, 0, 74, 41, 74,133, -120,157,131,145,199,243, 53,137,154,119, 84, 46, 17,234, 23,121, 53,142,163, 70,199, 45,124,225, 33,238,148, 18, 44,185,152,116, -166, 65, 55,133, 23,111,200,163, 64,251,231,156,187, 41,252,238,151, 71,251,203,204, 72, 49,133,167, 6,104, 90,129,223, 77,225, - 9, 12,210,159,155,194,147, 39,176,243,110,192,236, 14,188,127,107,102, 9,104,127,154,140,123, 51,133,175,181, 26, 99,120,213, - 70, 1, 16,150,239, 26, 95,110, 79,128,133, 68,171,111, 2, 64, 8, 65, 46,122, 70,173,159,124, 3,194, 31,178,142, 49, 82, 3, - 72,140, 97, 24,148,236, 63, 7,236,239,189,159,215, 0,105, 35, 54, 18,233,244,230, 58,231,104,163, 41, 87, 50,203, 86, 96,173, - 37,193,248, 41,200,207, 63,251, 79,172,210,124,225,215,166,240, 31, 1,216, 59,155, 19, 6, 97, 56,138, 11,210, 13,114,235, 16, - 30, 29,160,189,101,129,220, 29, 35,251,184, 71,134,201, 49,217, 64,232,207,252,105, 16, 81, 19,219, 82, 40,244, 29,130, 40,228, -160,201,251,240,144,247, 73, 1, 96,155, 21,239, 84,130,205,134,181, 60,171, 1, 44,187,223,250, 57,158,217,255, 20,157, 9,133, -193,218,114,120,250,242, 52,208,122, 96,255,155,185, 20,229, 46,165,240,140, 53, 46,126,133, 91, 2, 83, 49, 3, 99,113, 6, 40, - 21,215,255, 90, 20,120, 7,155,165,240,197,208,195,215, 65, 0,134, 97, 32, 7,132, 16, 46,207, 86,120, 46, 80,130, 24,227,113, -114,130,253,179, 42,139, 0, 72, 14, 72, 77,100,181,121, 11,222,207,181,207, 95, 88,216,216,109,231,156,214, 26, 37, 80, 74,113, - 13,251, 35, 6,172,210,182,173,233, 55,154,217,223, 90, 43,155,113,149, 3,246, 48,142,227, 65, 8,240,222, 27, 99,246,158, 78, -211,116, 77,224,109, 75, 56,238,186,174,239,123, 49, 28,127,251,191,100,255,102,171, 20,254, 33, 0,123,215,110,195, 48, 8, 68, -163,140,132,216,129, 79,155, 53,178, 6, 27,100,141,136, 58, 29,107, 32,209,177,131, 27, 40,242,146, 83, 40,130, 13, 1, 81,230, - 10,203,182,140,125, 6,241,222,221, 67,226, 86, 18, 64, 45, 92,252,184, 50,188,138, 3,180,214,163,121, 64,215,195,238,171, 46, -215,199,253, 38, 38,126, 16,240,135,121, 85,123, 27, 99, 28,165,132,137,126, 46, 69,225,129,218,136,149, 48, 3, 39, 8,128,140, - 26,130, 3,142,250,138,212,255,211,167, 40,124,217, 59,158,138,194,211,205,198, 64, 75, 41,203,122,146, 82,170,228, 4, 13,229, -167,142, 66,234,162,240, 69, 11,218,181, 16,194,249,189,151, 56, 78,240, 69,239, 61,109,190, 68, 69,225, 95,181,166,183,205, 90, -219,128,242,130,254,200, 54,190,216,104, 72,213,193,195,228,240,104, 42, 48, 97, 41, 37,198,152,115,142,115,142, 81, 35,145, 13, -151, 66,136,156,115,183, 57, 16, 31, 71, 99,204,145, 22,180,220, 16,118, 32,161, 4,167,162, 91,224, 57,198,136,208, 31,124, 0, -183,255,208,223,181,167, 0,162,102, 5, 64,245, 73, 96, 50,234, 0, 96,115,146,164,126, 0, 36,107, 45, 93,186, 20, 77,124,219, -182,109, 64, 65, 34, 13, 57,113, 95,203, 66,241, 26,241, 35, 63,240, 6, 38,188,169, 8, 76,190,144,194,136,212,210, 31, 94,135, -145,212, 60,132, 52,255,209, 46,133, 39,175, 19, 0, 55, 1,207,165,240,240, 38, 63,176, 76, 1, 54,102, 85, 85, 85,129,141,104, -118,118,118,126,126,254,150,150, 22,130,253, 0,228,177,126, 92,243, 1,100, 84,237,192,130, 24,174, 6,243, 68, 44, 96, 3,159, -151,151, 23, 88,234, 29, 59,118, 12,216,248, 5,150, 44,223,145, 46,133, 7,221, 59, 77,232, 82,120,204, 97, 31,120, 91, 30, 24, -221,175, 72,188,125, 19, 24,191,144, 21, 65,100,244, 3, 8,142,252,192, 1, 48, 34, 74, 75, 75, 33, 57, 14,104,221,237,219,183, - 25, 64,199,244, 26, 2,235, 63, 98,214,225, 80, 82,214, 67, 42, 15, 50, 12, 4,198, 35, 48,118, 44, 45, 45,225, 7,207, 1, 93, - 11,236,187,140, 22,238, 12, 72,119, 2, 35, 15, 1, 33,167,118,128, 0, 26,236,147,192,244,169, 3,128,234, 33,253, 86,120, 71, -152,200,210, 31,216,252, 39,219,107,144,230, 63, 90,195,255,197,139, 23,180, 46,253,225,205,127, 29, 29, 29, 8, 23,200,160,176, - 19,128, 31,192, 71,255,185,185,185,107,107,107,129,165, 63, 68,220,192, 0,116,201, 9,176,220,247,245,245, 61,114,228, 8,144, -164,162,165,240, 48,129, 79, 0,160, 1, 96,179, 17,222, 3,192, 92, 55, 13, 44, 83,128,117,192,143, 31, 63,128,181, 20,176,174, -130, 92,183, 9,191, 20, 30,200,192, 95,250, 67, 42,117,204,177, 32,228,153, 97, 82, 1,217, 26,137,159, 3, 0,214,199,222,222, -222,192, 28,196,197,197,229,224,224, 0, 12, 1, 96,148, 1,107,232, 5, 11, 22, 48, 49,209,118,211, 40,176,172,135, 15, 31, 65, - 50, 32,241,213, 9,176, 65,243,232,209,163,240,240,112, 6,240,165,211,160,171,199, 70, 1, 90, 63, 24,199,189,240, 0, 1,200, - 59,131, 28,132, 65, 32,138,238, 61,141,186, 55,158,171, 27,238,194,198,112,136, 90, 57, 66, 87,156,130, 21, 97,107,244,153, 73, - 8,193, 90, 1, 99, 98,226, 95,145,118, 51,105, 50,111,102, 24,202,252,250,159,192, 29,157, 0, 84,159,188, 39, 88,164,186,181, -158,254,162,253,110,123,158, 46,167,105, 35,241,128,106,160,201, 84, 48, 52,142,163,236,227,227,126,117,137,225, 45,125,156, 14, -250, 75,250,255, 60, 20, 30, 27,228, 85,135,222, 14,133, 7, 34,178,192, 63,231,249, 49,220,220, 24,147, 30,126,117, 40,124, 58, -243, 83, 68,205,245,102, 59,233, 63,148,199, 66,239,189,244,234, 81,140, 49,132, 0, 95,168, 6,168, 0,174,175,199, 13,229,176, - 46,250,246,197,185,254,245, 40,146,155, 93,115,108,244, 67,105,173,225, 62,244,119,206, 89,107,161,191, 82,138,216, 60, 12, 67, - 77, 0, 56, 44,169, 41, 6,224,134,173,244,151, 77, 72,161, 63, 98,113,108,185,187,251, 79, 68, 5,144, 58, 1,185,238, 2,104, -144, 78, 2, 83, 82,250, 3,211, 16, 25,221,100,200, 88, 16,176, 43, 64,124,233, 15, 44,238,129,165, 63,116,148, 99,221,250,181, -224, 91,252,128,149, 1,131,147, 35, 3, 3,225,101,160,144, 85,137,144,177, 32, 96, 19, 21,114, 9, 42,176, 8, 38, 34,249,130, -138, 90,248,189,240,164,150,254,144,230, 63,214,198, 62,121,157, 0, 72,181,145,147,147,131, 51,160,130,131,145, 47,133,143,137, -137, 97,192,184, 20, 62, 54, 22,231,189, 17, 20,206, 1, 48,144,117, 41,188,176,176,240,219,183,111,129,237,253,215,175, 95, 3, -123, 0,240, 75,225,129,253, 54, 96,124, 1, 75,127, 96, 53,128, 54,184,143, 12, 32,165, 60,100, 20, 8,237, 38, 50, 60,186,208, - 74,127,200, 38, 0,100, 46, 25, 13,127,226,199,127,128,224,246,237,219,192,232, 0,122,208,210,210, 18, 72, 2, 3, 13, 88,158, -110,218,180,137,153,153,153,152, 10,128,146, 86, 60,178, 9, 36,233, 50, 6, 3, 32,227,220,185,115, 64, 55,219,216,216, 0,147, - 22,176,151,137,188, 96,122,196, 2,200, 42, 32,180, 73, 96,228, 85, 64, 0, 1,216,187,130, 20,134, 65, 32,248, 1,159, 32,248, - 12,207,130, 63,242,149,130, 79,240,228, 55,188,116,154,129,101, 91, 75,220,228, 80,122,232,158, 36, 36, 16, 54, 58, 51,113, 71, -246,119,139,192,223, 68,127,205, 1,151,180,255,199,241,147, 3,108, 19,151, 3, 8, 46,125,100,172,214,186,125,118,237, 11, 79, - 71,208,246,253,165, 41,252,170,161,104,164, 59,241,228,173, 39,191, 72, 39, 64, 70,160,191,108, 40,173,129,239, 24, 66, 96,255, -119, 16, 0,189, 64,250,162,110, 41,254,206,117,175,231, 0,236, 53, 0, 61, 9,145,147,156, 51, 16, 65,239,152,157,231,202,123, -223,123,103,231,181, 57, 39, 25, 72,154,194,179, 38,108, 52,243,228, 35, 68,191, 91,118,114, 4,238,113,179, 94, 68,183,237,164, -198,160,227,179,148, 2,249,159, 82, 2, 31, 56,231,198, 24, 70, 2, 16, 4,167,144,186, 87, 18,184,170,253,185,142,144,177,214, - 26, 6,128,254, 24, 35,242,134, 95,153,127, 29,120, 27, 15, 1,196,130,153,223,200, 54, 11, 45,117, 34,183, 95,144,155, 69,180, - 43,253,129,201,142,194,165,114, 36,105,127,252, 4,231,120, 61, 39, 39, 23, 65,237, 88, 7,166,137, 4,192, 2, 5, 88,226,239, -221,187, 23,126, 47, 60,124, 49, 40, 49,117, 24,214, 75,225, 33, 59,110, 8,110, 10,195,172,212,115,115,115,241,148,254, 16, 32, - 36, 36, 4, 25,226, 7,182,166,145, 27,254, 53, 53, 53,248,147, 28,133,251, 0,144, 67, 3,109,171, 4,193,250, 30,216, 21,219, -182,109,219,159, 63,127, 62,124,128, 92, 10, 15,114, 9,176, 67, 0,228, 2,217,196, 55,228,129,246, 34, 47,253, 68,158, 30,192, - 95,250, 51,144, 59,199, 67,121, 29, 80, 81, 81,113,240,224, 65, 96, 52,181,183,183, 3, 91, 12,192, 14, 16,100, 75, 4,193, 33, - 62, 50, 90,241,200,122, 73, 5,192,154,233,233,211,167,200,251, 0, 46, 94,188, 8,236,186, 1, 91, 21, 68,174, 91, 29, 9, 0, -109, 18, 24, 25, 0, 4, 16, 11,254, 66, 28, 87,223,150,214,128,140,210,159,206,249,164,165,165, 5,255,254, 70,130,149, 37, 37, - 67,186,144, 66, 19,178, 12, 31,200,128,236, 5,131,223, 11,143,167, 92,131, 92,236, 14, 44,188,144,231, 0, 32,205,219,178,178, - 50,252,165, 45, 86,189,164, 14, 25, 17,217,240,167, 86,151, 20, 57, 28, 48, 47,133,199, 95, 7, 0,131,197,219,219, 27,216,146, -101, 99, 99,251,249,243, 39,176, 14, 0,134,176,128,128, 0,176,192,194,115, 80, 7,114, 62,130, 79,255, 2,237, 5,170,135,231, - 29, 92,185, 12,146, 36,208,182, 13,147, 58,247,139, 57,230, 67,210, 40, 16,164, 14,128,111,254,202,202,202,130, 48,128, 61, 33, - 60, 90,158, 61,123,134,188,219,107,197,138, 21, 4, 79,248,193,165,151, 36,112, 1, 12,208, 4,159,128,193,104,185,207,128,116, - 39, 48,114,209,143,188, 10, 8, 32,128, 88,168, 88,190, 99,234,165, 79,109, 65,255,210, 31, 8, 68,193,128,108,237, 74, 96, 64, - 45,199,192,199,127,144,203, 62,172,151,125,146,125,228, 3,133,122,177,246, 6,136, 4,100,207, 1,160, 37, 9,172, 93, 46,130, -201, 6,216,173,188,123,247,238,254,253,251,191,127,255,254,247,239, 95, 3, 3,131,176,176, 48,130,113,119,226,196, 9,120, 55, - 2, 46,130,204,198,149, 42,224,141, 3, 72,205, 1,204, 65, 4, 43, 27, 56, 8,163,236,254,100,178,115,144,180,180,116, 96, 96, - 32,126, 53,205,205,205, 84,215, 59, 10, 72,170, 3, 48, 75,127, 32, 0, 8, 32, 22,106,149,161,163,167, 53, 13, 56, 64,139, 2, -226,143,132, 29, 66,158, 26, 16,163,148,193,128,120,245,192,254, 13,145,231,252,224,105, 28,144, 81,221, 82,171,134, 38, 21,136, -137,137,145, 29,182,148,232, 29, 5,196,215, 1,184,164, 0, 2,104,244, 82,248, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, -111, 4, 27, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5, -163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, 96, 20,140,130, 17, 10, 0, 2,136,134,151,194,143, 94,192, 61,170, -119,136,234,221,236, 55,133,120,189,190,155,114,168,165,119,163, 47, 9,122,253, 55,163,232,245,177, 1, 93, 47,202,200,200,248, -251,247,239,251,247,239,255,250,245,139,133,133,229,201,147, 39,145,252, 10, 59,207,156,249,174, 39,107, 97, 97,193,204,204, 12, - 89, 68,187,229,200, 83,106,133, 21,196, 94, 56,128,236, 80,185,122,245,170,148,148,212,187,119,239,128, 36, 39, 39, 39, 3,108, - 67, 31,154,189, 88,245, 62,190,178, 36,221,246,209,178, 51,106, 44, 98,110, 60,188,124,184,244,142,166,103,226,245,226, 1, 0, - 1, 68,194, 81, 16,248, 55, 37, 82,241, 2,110,137, 19,215,238,188,122,206,201,198,161,206,197,127,199, 78,135,110,149,225,144, -184,128,123,176,129,155, 55,111,246,247,247,247, 86,129,216, 27, 14,131,206, 0,192,163,248,193,147,199, 79,159, 60,185,121,227, -198,251,247,239,229,229,229,121,120,121, 61, 92,221,240,155, 15, 57, 34, 9, 2,112, 93, 94, 6, 20, 39, 62,166, 32,187,160,177, -222, 33,140, 15,132,190, 3, 83,255, 65, 7, 49,173, 22, 34, 65,163,113, 63,131, 82, 60, 56,121, 45, 96, 56, 91, 68,114,248,134, -188, 65,216,187, 70, 4,143, 66, 96,233,249,245,235,215, 93,187,118, 1,147,113, 40,171,176,132,172,232,143,175,223, 57,191,253, -177, 46, 73,181,243, 13,223, 50,119,198,230,189,123,221,220,220,232,144, 36,254,254,253, 11,116,131,190,190,190,154,154,218,185, -115,231,126,252,248,161,170,170,138,121, 56, 60, 86,240,231,207,159,139,103,206,203, 36, 27,150,153,105,159,216,213,179,246,178, -131,170,142, 19,145,122, 71, 1, 25, 0, 32,128,136,170, 0,136, 57,210,135, 42, 23,112,171,158,187, 43,248,246, 11, 35,195,255, - 95,127,153,127,191,251,242,228,205,199, 7, 83,206,242, 56,154,139,104,107,224,209,117,118,127,186, 6,116,149, 54,243,250, 93, -255, 14,159,254,159, 22,193, 0, 20, 41,106, 37,173, 40, 39,233, 2,110, 92, 53, 7,173,175,236, 96,128, 28, 99, 89,207,200,216, -132, 69, 10,148, 79,234, 25,195,174,135,210,103, 73, 56,172,244,255, 15, 46,253,237,142, 28, 57,130,167, 2,208,211,223,165,165, -101,178,122, 53,223,201,227,160,109, 80,183,110,220, 4,146, 41,137,235, 62,126,201,249,252, 1, 95, 53,239,234,234, 10,172, 6, -128,165,252,190,125,251,176,158,148, 71,252,166,127,204,148,156,145,158, 62,131,184,202, 3,249, 26,122, 18,128, 82, 60,226, 80, - 54, 50, 42, 0,152,239,240,156, 60, 10, 1,119,239,222, 61,176,106, 85,147, 75,152, 65,116, 22,155,184, 32, 3, 11, 19, 3, 3, - 19,195,191,255, 12,255, 88,255,253,252,239, 21,159,246,104, 82,199,177, 99,199,172,172,172,104, 93,152, 50, 49, 49, 25, 24, 24, - 28, 56,112, 0, 88, 7,152,153,153,189,120,241,226,226,197,139,122,122,122,196, 28, 51, 3,244,172,179,147,107,123,223,166,242, -132,203, 22, 30,153, 22,230,123, 74, 38, 63, 81, 51,141,195,170, 23, 18,155,248,171, 7,160, 44,201,149,253, 48, 2,104, 23, 2, - 35,250, 94,176,213,255, 0, 1,196, 66,100,134, 49,136,211,205,180,206, 33,190, 14, 32,227, 2,110,153,187, 47,141, 56, 5,217, - 36,249,255, 50,252,231,252,192,245,226,245,235, 23,159, 63, 42,178,243,220,216,121, 4, 24,189,162,184,235, 0, 96, 89,127,227, - 46,211,255,255, 28,127, 25,217, 3, 92,127, 7,186,125,103, 96,248, 7,107, 55,145,152, 91, 73, 44,187,225, 71, 54, 66, 14,162, -218,122,131,245,199,239,223,233,137, 38, 4,171, 1,130,117, 42,190,253,159,245,160,204, 0,185, 5, 9,171, 20, 49,224,246, 94, -190,158, 85,145, 16,118,113,232,114, 53,151, 79,100,148,254,125,125,125,192,220, 94,220, 6,189,248, 9, 79, 14,119,112,248,168, -166, 6,108,122,111,182,181,157, 4, 23,140,138, 98, 0,223,225, 54,101,249, 42,124,117, 0,164,244,135, 28,236, 21, 30, 30, 14, - 57,245,136, 96,129,136,181,237, 15, 57, 48, 3,238,206,140, 12, 98, 75,127, 50,129,113, 31, 3,236,162,118, 80, 5, 96,212,203, -112,174,152, 70, 86, 1,107,199,233,129,105,138, 78,174, 12,204, 63, 25, 89,153, 24, 89,152, 24,153, 89,255,255,103,252,247,245, -207,255,191,127,129, 77,170,212,248,172,172,186,252,187,226,226, 36,109,106, 35, 3, 0,243,130,164,164, 36, 48,156, 15, 30, 60, -120,227,198, 13, 96,253,109,105,105,121,242,228, 73,109,109,109,130,122,143,236, 93, 30,100,240,237,236,103,230,168,250, 47, 54, -134, 19,115, 10,194,123,202, 63,148,247, 44, 85, 50,140,194, 83,184,195,139, 23, 96, 20,163,137, 80,114, 30,229, 72, 0, 0, 1, -196, 66, 76, 33,181,108,199, 82,101, 21,229,244,166, 84, 98,234, 0,242, 46,224, 86,184,241, 76,157,141,155,237,255, 31,206,158, -210, 63,223,126,113, 20,183,242,179,113,252, 96,253,254,245,199,119, 78, 6,198,231, 7, 79,176,201, 72,242,243,243, 99,213,123, -227, 46,195,172, 21,192, 18,255, 27, 24, 49,216,154, 50, 5,186, 49,194,234, 0, 6, 96,111, 96,214, 10,162,194,130,212, 11,184, - 33,165, 63,164,232, 7,249,253,200,239,239,191, 64, 23,252, 58,151,239,238,236,116, 37,104,206,221,142,187,172,140,183,161,209, -192,248,148, 81, 68, 3,198,126, 37,154,136,111,115, 60,176,237,143,124,153, 9,138, 84,250,106,176, 20,190,230,255,155,203,146, - 53, 83,252,255, 51,252,111, 47,216, 96,238,160,182,108,218,225,222,213, 81, 12,171,255,215, 23, 77,147, 82, 39,182, 41,253,229, - 97,186, 52, 7,195,183,183, 87,129,141, 47, 94, 49, 61, 72,233, 63,125,250,116,172,138,121, 5,174,168,169, 1, 99,228, 24,176, -159,112,242, 36, 3,248,206, 62, 16,128,239,240,143, 12,155, 50, 99, 78, 53,211, 63, 89,172,218, 33,165, 63,176,237, 15, 44, 83, -240,220, 59, 70,176, 41, 3, 41,253,145,234,131,244, 25, 51,176, 39, 75,166,176,247,240,230, 3, 35, 24,255, 11, 69,149,101,132, -140,202,128, 40,111,212, 62, 15, 83,248,123,200,128, 13, 16,252,251,151, 80, 80, 80, 0, 17, 7, 50,128, 53, 1,147,106, 50,212, - 96,176, 26, 52,189, 44,225,232,246, 34,223,195, 8,146,197,109,239,143, 31, 63, 36,228, 21, 24,254,253, 98, 98,103, 96,100, 97, -254,243,249,227,143,123,247, 95, 63,121, 42, 99,229,192,200, 38,192,248,251, 23, 3, 51, 83,103,102,137,235,172,134,162,162, 34, -178,203, 11, 92, 71,140,192, 75,100, 96,122,248,254,253,187,144,144, 16,176,125, 0, 12,237,251,247,239, 47, 88,176, 64, 83, 83, -243,195,135, 15, 4, 59, 88, 64,189,242, 76, 39, 37,229, 60, 62, 28,188,252,241, 61,251,226, 45,127,182,157, 88,146, 23,202,201, -242, 13, 24,107, 81,216,251,187,163, 0, 47,192,140, 44,180, 62, 1, 64, 0,177,224, 47,250,129, 65,236, 88,101, 63,235,224,204, - 52,134,244, 11,139, 46, 51, 88, 19,182, 18, 82,238,127,251,182, 20, 24,167, 63,126,204, 19, 18,218, 67,204, 5,220, 98,207,223, -137,137,115,112,212,103,253,125,243,238,207,179, 55, 44,108,172, 92,140,204,220, 64,196,204, 34,196,202,241,254,243,135,231,251, -142,241, 7,122, 98,213,139, 86,190, 31, 62,253, 15, 92, 1, 48,244, 85, 51,254,103,100, 96,252, 79,108, 87,128,212, 11,184,145, - 75,127, 6, 22,230,123,207, 65,185,247,209,203, 31,114,226, 28,170, 9,155, 59, 59,125,241, 27, 2, 44,253,129,229, 62, 51,227, -155,191,255, 69,216,197, 24,185, 35,158,253,251,247,238,199,143,213,127,207,148, 81,210, 83, 33, 88,123, 85, 79,241,179, 20,170, -153,178, 33,153,135, 73, 14,200,205,202, 85,215, 55, 83, 90, 58,245, 96, 99, 95,246,204,153,196,118,150,129, 69, 80,122,225, 21, - 72,190,181,177,177, 1, 86, 0,184, 74,127, 80,141,232,240,150,129,225, 18, 3,195,149, 15, 47,121, 84,229, 24,102,207,254,178, -127, 63,131,170, 42,208,169,160,104, 2, 10,130,186,152,186,215, 47, 93,148,197, 90,250, 3,219,182,255,192,128, 1,124,159, 12, -169, 5, 22,156,141, 92,250, 51,128,166, 1,112,198, 14,176, 91, 0, 41,195,177,214,178,255, 96,229, 14,176,177, 3, 12,135,205, -135, 80, 38,220,166,207,152, 9,233, 95, 40, 40, 40, 0,179,207,196,137, 19, 33,226, 64, 6,176, 2,216,185,115, 39,252,220, 74, - 6, 12,189,144,238, 8, 80, 87,106,106, 42,150,241,113, 88,167,103,214,236,217, 64,123,183, 28,126,138, 86, 26,178,240,242, 50, -176, 50,255,253,246,225,250,182,189, 75, 87,173,153,246, 12,100,209,169, 70, 62, 85, 59,175,159,143, 30, 95,189,120,246,242,253, - 91, 31, 95,188,184,114, 5, 24,113, 18,100,148, 38,152,199,174, 97,150,224,207,158, 61,171,173,173,237,233,233,249,245,235, 23, - 51, 51, 51, 47, 47,239,215,175, 95, 79,157, 58,133, 63, 89, 66,244,126,120,114,180,113,254,163,185, 5, 82,239,190,178,177,177, - 48,201, 8,114,188,120,243, 43,189,235,143,190,137,177, 28,238, 94, 29,164, 26,128, 71, 52, 38, 99, 20,160,149,254,200,181, 2, - 64, 0, 49,225,202, 51,144,115,207, 17,189,117,143,104, 98, 44,128,220, 0,243,237,219, 50, 72,233,207,113,250,193,183,157, 42, - 12,132,110,134, 97, 57,112,150,255,221,231,127,108, 44,191,206, 94,253,121,253,222,143, 93,135, 25,190,255,100,251,255,159,139, -129,153,133,129,241,231,191, 63,239,126,254,152,182,123, 11, 46,237,125,213,160,102, 62, 98,136, 60, 2,214,190, 98,248,127,243, -206,255,162, 86, 18,154, 9,144, 11,184, 33,129,128,255,180, 78,160, 44,242,165, 34,145, 19,158,236, 61,251, 30, 88,250, 67,234, -128,219, 79,190, 51,184,172,194,111, 2,176,244, 7, 85, 3,159, 47,115,115,223, 97,231,248, 12, 44,253,127,255, 62,203,204,172, -244,235,235, 91,218,165,128,187,231,191, 0, 67, 6, 94,250, 63,191,249,223,200,151, 57,183,197,213,198, 21,216, 61,255, 15,150, - 37, 12,150, 45, 91, 86,220,198,200, 35,170, 11, 12, 89,143,192,204, 35, 71,142,224, 81,252,143,233,177,152, 24,180,244,255,252, - 22,116, 74,182,190, 62,168,244,143,139,131,150,254,159,223,114, 2,145, 16,215,115,172,218, 67, 66, 66, 28, 29, 29,157,156,156, -194,195,195,153, 81, 1, 92, 4,191,107,209, 82, 50,177, 53, 28, 82,217, 4, 1,152, 92, 70,108, 77, 11,184, 70, 55, 55, 55,180, -182, 54,176, 19, 0, 57,182, 15,230, 50,116,189, 27,102,206, 4,150,206, 16,195,225,222,132, 15,142,195,185, 88,237, 5,230, 23, - 38, 46,246,223, 47, 30,206,172,169, 89,240,245,195,123,123, 11,136,248,220, 37, 11, 26, 74, 82,212,138, 34,155, 46,239, 91,245, -254,190,171,159, 31,145, 29, 92, 96,113, 15,204, 5,231,207,159, 71,170, 50,103, 96, 29,229,131, 4,200,229,203,151, 15, 30, 60, - 24, 25, 25, 9,236,165,125,249,242, 5,114,128, 54,176, 95,194,195,195, 19, 22, 22,102,109,109,141,171,232, 7,233, 61,190,246, -214,206,162,162,202,222,205,245, 82,215,159,178,124,252,194,252,143,145,225,237,151, 95,255,133,149, 11,171, 90,125, 2, 98,112, - 86,213,192,106, 28,156, 97,103,130, 1, 86,198, 40,192, 85,250, 3, 1, 64, 0,177, 96, 45,250,201,232, 24,162,137, 0, 75,127, -180,110, 1,158, 11,184, 89,222,126,120,247,159,149,237,237, 59,142, 13,251, 24, 89,152, 24,126,252,250,255,249, 43,227,159, 63, -172, 12, 12,127,255,255,251,241,247,207,231, 63,191, 24,254,225, 28,243,133, 76,246,246, 85, 99, 73, 93,224,201, 97,146,189, 67, -204, 5,220, 40,205,127, 6,134,229, 57,146,112,182, 73,197, 61,214,255,111,126, 51,138, 16,188,194,155,227,203,126,161,166, 37, -175,139, 51,222,188,227,148,250,125,245,239, 95, 80,133,241,240,130, 4,237, 18, 65,215,140,226, 20,183,153,240,210, 31, 34,104, - 33, 88, 99,165, 29, 98, 41,116, 21, 40, 75, 48,207, 44, 93,186,244,208,161, 67,111,223, 58, 11, 11,239,229, 17,209, 1,166, 22, - 38, 38, 38, 60,243,108,143, 30, 1, 43,203, 43,144,113, 35,160,135,223,125,101, 48, 51, 3, 79, 66,220,102,152, 58,149,225,243, - 39,134,175, 95, 24,190,124,101,224, 22,196, 55, 9,129, 57,226,127,247,238, 93, 32,217,214,214, 6, 36,213,212,212,200, 27,205, -128, 71, 55, 30,101,249,249,249,240, 86, 60,114, 81,142,223,112, 69, 69, 69,248,232, 63, 28, 64, 58, 1, 64, 41, 68, 39, 0, 21, - 36, 75,171,221,186,122,237,169,160, 32, 48, 72,243,242,242, 38, 77,154, 68,188,189,182, 63, 5,254,255,251,146,210, 86,173, 27, - 18, 50,179,173, 13,126,127,203,204,219, 87,160, 61,227,195,135,119,239,222, 13,180, 26,156,193,191, 17, 44,253, 33, 93, 58, 96, -224, 0, 91,217, 6, 6, 6,192,154, 0,168, 49, 51, 51,243,241,103, 44, 85,236,147, 39, 79,252,253,253,129, 94,219,182,109, 27, -228,202, 76, 6,240,146, 30, 6,240, 61, 66,120,230,105,129,226,247,110, 94,104, 40, 75, 18, 86, 93,125,126,117,252,165,199,140, -143, 94,178, 48,252,103,250,249,235,247,187,255,194,217,201, 89,228, 45, 1,162,228, 94,147, 17, 5, 0, 2, 8,203, 16, 16,176, - 26, 71,230,126,120,250,158,152, 18, 19,222, 3, 0, 15, 1,129, 34, 12,216,252,103,191,242,244,175, 0,168,209,135,255, 2,238, -107, 79, 30,125, 99,231, 84,250,243, 71,134,147,135,139,149,141,241,247,111, 96, 55, 27,216,225,253,252,247,215,183,191,127,126, -254, 7,230,254,255,255, 9,197, 40,176, 26,128,212, 1,224, 41, 1,104,185,223, 87,205,220, 91,205, 88,220,250,135,212,112, 33, -166,149, 84,190, 26, 20, 50,157,161,130,144, 66, 31, 58,176,243,255, 13,176,222, 98,249,255,126, 81,138, 96, 36,222, 59,233, 88, - 95,158,254,203, 0, 26,253,232, 97,225,143,124,249,240, 76,151, 12,183,132,230,199,167, 79, 95, 60,120, 70,211, 40,215, 55, 83, -250, 10,142,210,111,156,215,184,190,107,173,107,252, 13, 17,183,118,209, 62,190,138,112,219, 63,208,238,208,134, 13, 46, 2,199, -247,244, 87, 51, 20,182,254,183,179,179,195,191,244, 83, 65, 70, 22,121,210,113,203, 22,208,220,239,178,101,192, 78,192,255, 9, - 19, 24,155,154,190,128, 42, 6, 6, 6, 85,117,193,226, 66,124, 86, 67, 26,191,192, 14,193,202,149, 43,225,237, 98, 15, 15, 15, -204, 82,146,248,106,158,160, 26, 96,137, 9, 44,178, 49, 43,128,190,190, 62,228,245,169,152,192,197,197, 5,126, 21, 59, 50, 0, - 10,246,247,247,227,234, 16, 31,186,246,168,170,169, 36,185,190,172,242,215, 47,160,165,152, 94, 3,218,187,103,207, 30,172,101, -162,157,150,220,188,185, 83,141,163,162, 26, 27, 27,177,214, 19, 64, 65,160,246,217,179,103, 19, 19, 56,192,210, 31, 50,197, 10, -172, 38,103,192, 0, 80, 4, 88, 19, 60,198,182,198,252,247,239,223, 91,182,108,113,118,118,190,125,251,246,215,175, 95,129, 92, - 96, 13,244,235,215, 47,200,181, 57,248, 75,240,159, 63,127,158, 93, 27,101, 23,212,180,243,224,221,251,207,153, 63,125,101, 2, -118,252,159,126,229,204,171,168, 38,168, 23, 50,181,131,127, 44,104, 20,224,106,254, 3, 1, 64, 0, 49,161,101, 9, 32,112, 0, -131,139, 48,112,239,244,195,143,223, 63, 10,155, 17,181,246, 25, 82,202,115,113, 69, 3, 75,127,214,135,111,129,165, 54, 91,242, - 91, 6, 66, 23,112,179,178, 49,255,253,207,240,228,235,135, 71, 31,223,189,254,244,254,227,143, 31,239,127,125,127,253,243,251, -243, 31,223,158,254,248,242,238,247,207,247,255,126,255, 66, 29,192, 69,105,251,152, 98,159, 18, 72, 9,231,249, 15,236, 25, 51, -176, 17,227,114, 50, 46,224,126,244,242,199,222,179,239,225, 69, 63,164,244,103,255,247, 16,136, 26,220, 89, 30, 1,155,190,120, -193,218,251,255, 68,123,161, 13,231,251, 95,255, 62,185,251,244,230,209,171, 47, 30,124,160,117, 82, 88, 54, 13, 84,193,127,122, -245, 31, 88,250, 59, 36,179, 4,213,179, 66, 80,239,170, 40, 70, 6, 70,252,153,205,223,230, 96,124,145,139,224,137,189,192, 92, -183,241,168, 3, 3,248,184,124,130, 54,170,105,168, 35, 85, 33, 12, 83,166, 48,220,185, 3,234, 7, 52, 54,254,135, 3, 65, 65, - 65,156,131, 72,224,168,255, 11, 6,192, 38, 63,176,237,127, 11, 12,128, 69, 97, 73, 73, 9,193,112,166, 4, 64,154,234,104,229, - 41,176, 79, 0,244, 62,174, 86, 60,188, 5,138,214,252,135, 0,172,130,112,112,152,253, 3, 35, 19,207,156,170, 86,158, 45,123, -128, 89, 6,126,166,116,186,170, 78,190,177, 21, 23, 23, 23,176,186,173,173,173, 5,122, 28,243, 22,173,185, 79,111, 61,215,214, -146,150,150, 6, 6, 23,102,141, 5,233,127, 16,223, 55,130, 47,176, 1, 54,249, 25, 96,155, 39,176, 94, 36, 7,241,172,172,172, - 44, 48, 34,128,157, 12, 21, 21, 21, 22, 22, 22, 72, 13,109, 97, 97, 65, 76, 83, 93, 89,195,112,214, 46,129, 75,219,234,109, 45, - 53,185, 57,152,184,185,254,114,178,255,244,244, 39,234,110, 3, 96,121, 5,113, 39,158,177,160, 81,128, 7, 0, 4, 16, 19,214, - 48, 5,130,124, 48, 0,114,155, 51,154,127,191,250,195,201,201, 65,100,104, 66,234,124, 46,247, 59,255,153,153,106,215,125, 99, - 32,226, 2,110, 77, 43,171, 63, 60, 92,239,255,255,189,246,245,253,149,143,111,175,126,122,115,245,211,187,107, 95,223,221,249, -246,254,237,207, 31, 95,254,252,121,246,237, 43,158, 27,248, 2,221, 24,129, 45,125, 32,250,207,192,252,159,145, 41, 45,130, 49, - 53,130, 45, 57, 92, 84, 89, 89,252, 31, 3, 43, 3, 3, 35, 49,165, 63,169, 23,112, 3, 21,131, 6,250, 25, 24,206,116,128,250, - 10, 59, 75, 65, 43,148,128, 13,127,230,255, 95,127, 50,201, 3,217,239,222,189, 35,230, 6, 87, 96,224, 0,243,243,178, 47, 95, -191,255, 98,138, 95, 49,231, 21, 7, 39,144, 65,187,248, 46, 9, 91,126,252, 93,235,178,197,208,166, 62,176,249,111, 33, 88, 3, - 97,183,102,111,153,129,123, 18, 24, 88, 40,244,215, 48, 36, 20, 57, 11,156,216,227,216,101,207,228,205,112,224,192, 1, 34,147, -132,188,188, 60,156,237,228,196, 32, 32, 0,236, 96, 49,152,235,243,114,176, 49, 51, 51, 65, 99,199,196,212, 20,103, 26,101, 98, -130,140,248, 3,139,126, 53, 36,208, 4, 6,207,158, 61, 35, 88,196, 32, 15,226,195, 65, 70, 6, 81, 45, 68, 96, 75, 31,237, 70, - 45, 96, 33,142,191,249,143, 60,247, 0,111,192, 66,216,255,112,183, 99,128,224, 23, 35,227,191,111, 63, 89, 37,228,211, 91, 90, - 18,184, 5, 4, 14, 28,135, 14, 13,197, 36, 52,244,204,185,221,183,188, 78,215, 41, 76, 80,113,247,166, 77,152, 13,148,128,140, -116,109, 29, 29,200, 4,245, 95, 24,128, 15,160, 33,115,177, 14,248, 0, 11,119,200, 28, 47,100,208, 31, 94,214, 3,155,252,144, -198, 53,176, 38, 0,178,113,249,148,149,149, 53, 32, 32,224,227,199,143,192,154,137,147,147, 83, 84, 84, 84, 64, 64, 0,255, 45, -146,112,189,236,236,236,193, 25,147, 22,156, 54,121,240,248,147, 56, 63,179,165, 58,163,158,226,127,110, 62,190,209,210,153,214, -205,127, 32, 0, 8, 32, 22,252, 29,100,120,163, 88,198, 94,138,200,182, 3,252, 2,110,182,228,213, 12,196, 93,192,253, 69, 95, -229,219,173, 91,223,254,252,252,244,245,219,221,223,191, 89,255,129,134,111, 62,254,254,241, 15,156,123,182,189,188,255,245,207, -111,188, 99, 50,140, 69,173,136,196, 13, 30, 8,250,247,151,225,231,245, 59,159,231,173,252, 68,100,233,207, 64,226, 5,220, 32, -247,116,134,177, 58, 79, 3, 50,223,190,133, 78,219,178,253,123,254,139, 73, 50, 91,247,214,243,231,160, 98, 2,127,249,152,177, -110, 22,188,106, 92, 13,187,175,118,197,229, 99, 52,221,195,165,234,252,137, 97,213,255,163,123,174, 2,217, 86,218,160, 93,181, -101, 5,245,199,174,106,247,172,138,170,154,234,141,223,193,192,182,191,144, 16,100, 84,235, 0,184,134,115,249,255,127, 53,184, - 96,253,191,122, 53,190, 11,114, 67,130,130,119,239,220,197, 0, 94,248,239,232,200,248,230, 49,255,215,247, 28,223, 63,177,173, - 88,200,152,159,255,255,225,171,207,230,150, 22,122,218, 58,248,231, 0, 32,131,254,192,116,197, 0,190, 68, 16, 34,254, 10, 12, -136, 25,231, 1,198, 44,176, 34, 65, 46,127,129, 77, 70, 98,118,129, 65, 6,205,225, 51, 1,144,222, 0,254,230, 63, 3,210,170, - 7,228,245, 60,248,151, 66, 64,234,170, 63,159, 63,179,138, 8, 49,115,241,104, 7,135, 52,185,185, 86, 65,150,114, 26, 26,253, -253,254,131, 85, 88, 92,215,194, 65, 65, 70,113,210,245,227, 58, 58, 58,207, 79,163,220, 72,154, 1, 74,186,160, 74, 46, 11, 88, -118,131, 87,139,254, 65, 42,241,129,141,114,160, 8,124,129,169, 55,106, 89, 0, 44,217,129,126,132,140,243, 0, 67, 12, 50,212, -131, 44,139,167,244,135, 56, 27, 88,220, 3,219,251, 55,110,220, 56,119,238, 28, 48,178,184,185,185,191,125,251, 70,228, 96,189, -184,184,184,191,191,255,137, 35,167, 38,172,222,205,199,200,166, 46,254,243,206, 27,110, 27,245,223,240, 26, 2,215,128, 62, 80, - 28,158, 97, 71,135,128,200, 3, 0, 1,196, 66,204, 56, 41, 48, 40,159, 28,124,198, 16, 69, 84,233, 15, 47,209,208,204,193, 95, - 7, 72,137,137, 95,254,241,224, 35,211,191, 23, 63,190, 48,252,254,253, 23, 24,235, 12, 12,215,191,124,120,250,237, 19,228, 2, -110,188, 21,192,127, 96,171,127,214, 10,104, 83,235,198, 93, 6, 13,229, 63,204, 12, 95, 73, 42,253, 25, 72,191,128, 27,188,102, - 52, 11,216, 7, 0, 54,246,129,253,223, 78, 87,134,242,221,118, 5, 58,199, 32,141, 68,130,205,127,228,142, 17, 50, 27, 82,198, -225,111, 52, 49,212, 51,154,204,186,135, 57, 87, 1,221, 9,188, 7,223,229, 80,109,217, 91,170,167,250, 30, 95,245,223, 82,232, -170,181,139,246,145,221, 87, 79,188,111, 97,100, 96,108,205,222, 12, 44, 90,241,216, 11, 44,253,129, 89, 46, 48, 48,112,246,236, - 79,144, 44,201, 8, 91,143, 18, 26,138,136,238,205,135, 45, 49,245,102,231,229, 78,157, 52, 25,216,252,255,245, 66,246,241, 7, -246,127,160,190, 19,131,228, 87,241,210,180,207,187, 79,168,107, 89,226,171,243, 32, 69, 63,228,150,215, 23, 47, 94, 64,250, 4, - 47, 95,190,100, 32,101,174, 15, 50,153,137, 54,122, 62, 3, 36,152,142,103, 61, 40, 60, 70,224, 51, 1,192,222, 0, 49,205,127, -228, 66,138,120,197,192, 38,243,139,135, 15, 20,149, 85,255,253,249,201,248,231, 47, 11, 47, 31,175,145, 9,143,161,233,191,175, -127,254,126,251,249,255,207, 95,134,191,255,202,167,247,132, 71,133, 99, 54,174,255,172, 16,196, 99, 50,154,172,255,102,116, 5, -192, 34, 30, 50,226,207,128,116, 15, 48,114, 29,128,223,131,234,234,234,147, 39, 79,126,253,250,181,171,171,235,153, 51,103,128, -165, 63, 80, 11,193, 59, 83, 33,122, 45,204,205, 51,146, 51,238, 63,185, 31,155,156,113,114,247,194,231,159,223,153,216,187,138, -203,168,161, 39,108,108, 25, 1, 94, 64, 97,238,255, 26,221, 8, 70, 12, 0, 8, 32, 22, 34, 51, 15,145,109,127,228, 18,141,164, - 11,184,127,218, 27,171, 49, 24, 63,157,185,128,129,147,227,253,255, 63,191,254,252,249,247,255,159, 48, 63,255,147,175, 31, 9, -222,137,138,182,208, 19, 54, 7,240,151,164,210,159,129,244, 83, 28, 32,251, 6, 76, 76, 64,251,126,133,132,132,158, 63,127, 94, -160,243, 28, 94,250, 19, 52, 10,235, 21,181, 68, 1,240,118, 95,228,221,118,104, 82,248,129,176,222,211, 25, 51,103,220,218,195, -215,187, 58,242,248, 42, 96,123,144,177, 36,108, 57,168,103,128,183,244,135, 68, 28,184,160,255, 4,206,123, 12,104, 37,219,130, -222,189, 64,146, 91, 14,152, 15,177, 76, 18, 2, 27,248, 64, 19, 68,196,118,253,253,124,134,145,153,225,219, 15, 78,198,207,127, - 88,152, 88,196,149, 53,221,228,188, 88,254,227,116, 54,176, 64, 81, 81, 81,161, 60,125, 66,134,137,129,117, 0,124,121, 12,188, - 31, 64,252, 76, 0,164, 24, 34,216,252, 39, 27, 56, 57, 57,101,175,154,213,244,249,131,129,189, 13,147,184, 32,200,186,223,255, - 65,199, 57, 48,176, 50, 50,179, 48,178, 49,207,158,209,199,231,108,162,172,172, 76,245, 61, 80,144,161,158,233,211,167, 3, 73, -125,125,125,146,244, 2,107,232,189,123,247, 50, 51, 51,219,218,218, 2,131, 23,109,232, 31,216, 33, 0, 22,244,104,193, 14, 7, -192, 30,195,162, 5, 11,217,152,217, 67, 34, 67,128,106,108,188, 82, 80,234,173, 63,127, 32,122, 71, 87,245,208, 98,252, 7, 8, - 0, 2,136,133, 90,214, 80,229, 2,110,199,244,132,123,119,239,157,219,190,243,235,207, 95,192, 14,172,178,153,145,135, 92, 36, -193,146,148,236,169, 30, 72, 9, 78,222, 5,220,112, 19, 32,107, 70,225,237,125, 32,131, 24,247, 64,236, 37,207,217, 97,215, 67, -193,190,198,226,206, 48, 66,189, 7, 56, 80,115,249, 52,211, 5,238, 78, 98,207,129, 0,151,242,140,241, 69,208,243,185, 32,185, - 18, 40, 8, 44,247,185,229, 66, 9,106,127,249,220,237, 37,131,219, 63,166,199,252,124, 31, 25,132, 24, 64,199, 63,252, 98, 96, - 33, 49,105, 81, 2, 32,117, 0, 25, 26,225, 51, 1, 36, 53,255,241,180, 94,177, 2, 96,201, 46,145,151, 55, 97,215,174,123,205, - 27, 66, 89,133, 5,192, 7,186,125,255,246, 39,191,164,146,153, 75,104,219,194,153, 23, 69, 24,221, 72, 57,204,231,239,223, 63, -196,204,129, 17, 57,212,131,203,119,183,110,221, 2,146, 26, 26, 26,111,223,190,101, 97, 97, 1,150,218,194,194,194, 12,176,243, -233,216,216,216, 32,157, 54,172,122, 79,157, 58,245,239, 15,163,149,181, 62,176,135, 7, 84,249,235,215, 47, 25, 25, 25,136,212, -199,143, 31,129, 29, 29,160, 33,236,236,236,120,218,157,144,186, 1,153, 49, 58, 4, 68, 60, 0, 8, 32, 22, 26,153, 75,126,161, -172,172,164,148,147, 73, 55,255,147,125, 1, 55,102, 53, 64,134,189,228, 89,135,199,181,180, 62, 3, 14,220,192,103, 0, 31,198, -131, 44, 24, 74,146, 33, 76,255,100, 63,127,144, 29,168, 20, 79,222,209, 96,192, 86, 63,193, 17,124,172,128, 36, 93,192, 82,143, -139,139, 43, 48, 48, 16,114,164,243, 35,216,145,206, 71,247,238,134, 28,233,236,108,225,140, 75,239,236,247,237,169,130,149, 40, - 66,120, 79, 15,197, 85, 7,144,225, 71, 83, 83, 83,200,146,255,127,255,254, 1, 75,112, 32,227,245,235,215, 64,146,135, 7,180, -202, 25, 34,194,202,202,138,213,191, 62, 62, 62, 16, 5, 64,189, 63,126,128,247, 81,130,151,117, 65, 86,133, 65, 68,128, 21, 3, -214, 30,192,232, 34, 31, 98, 0,254, 91,223, 1, 2,104,244, 82,248, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70,111, 4, 27, - 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, 5,163, 96, 20, -140,130, 17, 10, 0, 2,136,101, 52, 8,134, 10, 48,196,113,185, 15, 30,112,126,116,130,103, 20,140,130, 81,128, 27, 0, 4, 16, - 13, 47,133,167,131, 94, 54,182, 93,156,236, 47, 88,217, 62,252,251, 7, 90,146,200,204,204,196,196,200, 12, 34, 65,235,134,153, -254, 51,178,128, 40,134, 63,155,183,178,254,255,255, 95, 79, 47, 97, 48,184,153, 18,189, 50,164, 44,123,120,130,186, 12,110,244, - 18,237, 81,189,163,122, 71,166, 94, 60, 0, 32,128,134,118, 15,224,208,145, 59,102, 38,191, 5, 5, 24,222,189,103, 60,127,145, -131,133,137,197,203,253,239,238,253,162,192, 98,159,145,137,137,131,151,193,201,236, 3, 3, 3,139,141,229,255, 83,103, 8,248, -116,255, 49,208,161,246,172,255,127,155,219, 58,125,124,249,232,242,237,135,127,191,253,160,207,205,186, 35, 13, 92,191,121,238, -215,143,111,188,188, 82, 36, 45,132,197,186,172,155,200,133,128,148,232,133, 0, 69, 69, 69,200, 81,254,144, 19,149, 73,242, 47, -242, 73,136,228,173, 37, 29, 5,163,128, 70, 0, 32,128,208,139,197,133,139,230,226,215, 16, 31,151,140, 75,138, 18,189,100,131, - 83,103, 88, 61, 92,255, 94,188,196,201,198,202,194,194,204,194,202,250,159,157,249, 55, 3, 11, 47, 11,195,119, 51,237, 63, 28, -108,236,255, 25, 24, 36,197, 25,252,188,254,221,188,135,175,244,191,115,253,150,138,150,178,148,180,192,147,135, 55, 88, 57, 69, -180, 52,212,182,111,220,184,103,207, 30, 90,215, 1,116,190, 80,126, 96,193,165,139,123, 20,100,126,234, 42,255,255,247,239,239, -199,143, 79,110, 92, 57,243,229,167,164,137,177, 45,145,218, 63,190,158,195,204, 12,221,179,118,103, 66,133, 65,211, 47,226,173, - 70, 46,181,215,174, 93, 91, 82, 82, 66,146,203,129,165,127, 65, 65, 1,176, 67,137,231, 48,103, 60,128,204, 11,229, 71, 6,192, -127, 84, 48, 3, 56,224,102, 97, 59,197, 26,126, 41, 60, 76,213,127,216,254, 68, 68,104,143,240, 75,225, 33, 0,249, 26, 72,180, -117,255, 0, 1, 68,191, 30, 0, 19, 3,245, 55,115,123,185,253,254,207,192,204,194,204,106,101,206, 40, 38,202,196,194,194,196, -206,202,172,161,198,244,240,241, 31, 51, 99, 38, 97, 33,142,237,251, 64,103, 10, 50,255,255,254,255,255, 63, 9,105,156,165,255, -165, 51,103, 20,164,100, 46, 29, 63,113,242,215,239,247,111,222,179,177,243,106, 26, 90,235, 91,187,237,223, 12,218, 33, 76,163, - 58, 0,237, 66,121,200, 89,140, 41, 41, 41,131,191, 26,184,112,126, 15, 59,203, 59, 22,166, 95, 63,126,252,253,248,149,211,198, -142,240,201,189,215,110,156,227,229,120,235,100,205,174, 32,175,204,199,199,255,251,207,159,215,175,223,136, 63,122,124,251,238, -189, 99, 71,223, 89, 89,251, 19, 99, 47,176,244,255,123,167,149,108,103,147,125,246, 6,228,118, 23,248, 89, 64,120,110,116, 25, -108, 0,216,130, 1,214,118, 40,199, 31,209,176, 52,132, 93,192, 74,170,182, 71,235, 24, 79,166,192, 10,113, 6,216,101,107, 8, -147, 82,102,124, 53, 11,159,140,181, 90,221,190,125, 59,132,237,225,225,177, 99,199, 14,172,236,209,210, 31,147, 11,175, 6, 0, - 2, 8,123, 5,112,244,200, 73,107, 27,115,234,186,227, 31,161,155,185,136,188,161, 9,165, 82, 97, 97,126,255,142, 69, 66,140, - 85, 66,140,237,203, 23, 86, 14, 86,150,191, 44,236, 70,186,140, 6,122,204, 76,140,172,160, 77,228,172,108,172, 76, 63, 25, 57, -216,254,124,195, 89,250, 31,217,183, 87, 81, 82,244,202,197, 43,213,205, 13,112,241,214,198, 54, 38,102, 70, 35, 99,163,237, 59, -246, 18,172, 0,254,253,251, 7, 44,196,239,220,185,195,201,201,169,171,171, 75,240,236, 26, 6,140, 11,229,225,183,173,206,153, - 51,103,160,234,128,243,231,207, 27, 26, 26,226, 87,115,229,218,185,255, 63, 31,200, 75,254,224,231, 99,103, 98,226,250,254,253, -207,219,119,223, 15,238,153,192,193,103,100,110,102,135, 71, 35, 7,243,107, 53,197,255,218,218,154,207, 95,188, 63,123,254,220, -151, 47, 95,249,249,121,149,148,228,153,152, 89,255,254,125,116,254,194, 17, 67, 3,155, 65,155,133,128,205,127,248,237, 46,192, -126, 0,176, 14, 32,242, 90, 21,140,134, 44,189,123, 0,144,164,187,102,205, 26,242,238,213, 34, 30,192, 27,227, 51,103,206, 32, -213, 30, 38,249, 96,136,222, 83,237, 60,104,141, 68, 9, 1, 38,105, 33,166,193, 19,158, 67, 23,192, 75,124,180,250, 0, 32,128, -112,246, 0,128,117, 0,144, 36,181, 26, 56,146,119, 27,171,184,205, 36, 85,226,115, 8,164, 7, 71, 76, 53,176,231,128, 24, 43, - 11,171,172,212,151,207,159, 89,207, 94,145, 5, 93,153,202,200,204,198,250, 71, 91,245,155,186, 42, 51, 35, 3, 19, 27, 43, 59, - 27, 51,163,177,222, 47, 33,193,127,135, 78, 99, 55, 68, 83, 81,252,225,221, 87,200,165, 63, 16, 84,215, 87,181, 53,119, 73, 90, -234, 9, 10,240,226,119,195,247,239,223,129, 37,194,195,135, 15, 33, 92, 96,211,195,203,203,203,223,159, 64,147, 22,237, 70, 73, -100,208,219,219, 91, 92, 92, 76,231,109,238,192,210, 31,126,165, 6, 30,240,243,235, 83, 69,233,239, 34,194,220, 50,210, 18, 92, -220, 92, 15, 31, 62,253,251,247,159,180, 20,239,213,235,199, 47,112,114, 27,232, 98,191,248,225,242,229, 35,122,106,191,228,228, - 20,175, 93,127,120,246,236,245,215,111, 62, 3,227, 89, 80,144,243,219,183, 47,134,134,218, 31, 62,124,124,122,246,252,197,203, -156,250,186,198,131, 48,231,160, 93,238, 72,240, 90, 71,228,145, 13,180,163,140,129,108,248,112, 7, 25,227, 72,205,205,205,190, -190,190,164,158,214, 0,172, 3,128,246,174, 90,181, 10,215,113,108, 12,224,179,148,209,122, 6,144, 43, 33,129,226,104,109, 2, - 96, 65,143,121,118, 0,252,120, 37,160,127,211,211, 51, 72,234,100, 32,235, 53,171,252,114,186,157, 7, 94,244,143,150,218,212, -106,254, 35, 71, 25, 90,244, 1, 4, 16,129, 80, 6, 86, 3,144,154,128, 72,128,181,160, 39,178,244,135,128,131, 7, 15, 62, 5, - 3, 98,206,114, 98,254,255,157,133,241, 7, 27, 43,235,249, 43,162,204, 44, 44,188,108,223,248, 56,190,243,242,255,125,250,148, -151,157,141,131,157,157, 61,212,239,143,159, 39,147,180, 20, 59, 23, 39,246,187, 41,190,125,120,252,226,221,151,226,186, 58, 76, -169, 15, 31,223,189,127,253,130,145, 80,199,101,245,234,213,240,210, 31, 2,182,109,219,118,253,250,117,252,205,127,228,243,159, - 33,205,255,143, 48, 0,100,215,215,215,147,125, 84, 28,217,165, 63, 65,101,192,230, 63, 7,203,115, 78, 78, 86, 14,118, 54, 69, - 69, 5, 19, 51, 51, 65, 65, 65, 22, 22,102, 54, 54,102, 33, 65,142,167,143, 31,224,210,200,242,255, 41, 47, 15,231,183,239,127, -174, 92,185,253,236,197,199, 71, 79, 62,221,186,247,235,249,139,207,175, 95,127,184,125,235,158,138,178,178,180, 20,223,219,215, -143, 6,103, 22,130,140,254, 35,139, 0,123, 3, 40,119,187,227,105,219,130,151,163, 97,189, 80,158,188, 14, 4,176, 80,134,119, - 22,137, 4,123,247,238, 5, 38, 81,130, 87, 51, 34, 95,254,142,124, 33, 48,178,117,184,172,134, 24, 11,185, 59,140,188, 94,209, -170, 66,110,228, 86, 63,164,244, 7,182,253,165, 64,205,127,124,193,229,225,225,225,233,233, 9, 25,231,129, 48, 32,108, 15, 24, - 24,173, 3,240, 3,128, 0, 34,106, 14,128,188,222, 0,217,224,246,109, 80, 55, 2, 88, 7, 72, 75, 75,227,111,147,178,176,176, -176, 50,179,178,178, 50,218, 89, 51,124,251,250,243,254, 93, 54, 96,135,128,229, 47,139,133,249,127, 96,173,192,204,204,196,240, -159,241,221,123,134,211,231, 88, 64, 55,129, 96,171,236,206,157,191,251,229, 11,150,185,196,142,250,122,118,118,142,239,223, 63, -254,253, 71,224, 62,225,115,231,206, 97, 10,158, 61,123, 86, 83, 83,147,200,230, 63,114,155,110,243,230,205,112, 53, 52,234, 4, -160, 13,245,192, 75,127,130, 25,248,253,187, 87, 34,188,140,127,254,254,251,245,251,207,235, 55,239, 88,217, 56,126,254,252,253, -251,207,223, 63,127,254,253,249,251,255,195,251, 55,184, 52,178,177,126,229,224,148,121,251,246,227,167,207,223,222,189,255,206, - 39,172,111,165,167,119,234,232, 14,169, 95,127, 62,126,250,168,174,174,204,206,198,242,245,243,187,193,217,252, 7,150, 80,104, -151, 41, 2,123, 0, 68,206, 4, 0,107, 14,204, 59, 32,225,199, 74,227, 2,240,203, 21, 50, 50,132,156,157, 17,167,191, 1,115, - 4,144,220,180,105,211,155, 55,111,136,156,151,218,179,103, 15,164,244,135,168, 95,187,118, 45,174, 82, 24,185,255,135,121, 33, - 48, 68, 28,114, 45, 48, 86, 19, 32,199,136, 2, 73, 72,191, 1,171, 7,113,165,103,160,243, 66, 44,247,172,100, 96, 8,239,255, -106, 90,249, 5,171, 94,179,112,236, 30, 68, 30,235,199, 53, 31, 48, 90,202, 35,143,252,160,245, 0, 0, 2,136,250,253, 44,180, -246, 62, 73,205,127, 72,251, 23, 94, 13, 0, 51, 15,254,126, 0, 51, 51,139,133,217, 63,102, 38,150,211,103, 56,110,222,230,240, -118,103,240,241,100,240,245, 96,148, 20,103,227, 96, 99, 7, 34, 78, 14,118,105, 73, 32,131, 3,200,198,106, 66,109,117, 77,103, -123, 19,102,182, 81, 86,148,231, 23,224,230,248,247,235,203,183,223,180,136,143, 35, 96, 0, 47,244,225, 0,200,125,251,246, 45, -176,167, 79,187,198, 62,114,179, 14,194,133,244,196, 9,142, 45,252,253,203,240,245,219,239,175, 95,127,125,250,244,243,229,203, -247,207,158,189,249,252,249,231,151, 47,191,129, 53,232,215,175,191, 63,126,248,136,115,224,232,231,159, 31, 63,254,254,254,253, -139,151,151, 77, 86,154,143,139, 27,212,220, 83, 82, 86,144,145,226,227,231,227,248,255,255,239,239, 63,255,126,254,252, 58, 56, -155,255, 69, 69, 69, 88, 75,118,130,157, 0,204,187, 36, 33, 0, 40,184,135,184, 83,187,193, 35, 42, 8, 0, 41,124,129,213, 0, -176, 76, 39,166,127, 12,108,251,175, 89,179, 6, 94,250, 3,201,144,144, 16, 92,197, 55,208,112,204, 43, 33, 33,109, 2,184, 56, -208, 61,132, 14,211,254,143, 54,144,139, 60,252,133, 75,143,136,136, 8, 35,172,157, 79,170,222, 81, 64, 82,233,207,128, 49, 7, - 0, 16, 64, 68,245, 0,232,214,246,135, 21, 52,127, 33,151, 74, 19,118,152,217, 63, 49, 81,246, 79,159, 88,216, 89,254,176,179, - 49, 31, 56,201,230,237,200, 10,108,251,127,250,196,122,244, 12, 55, 31, 7,232, 42, 9, 15,151, 95,254,222,255,153,152,254, 47, - 88, 75,148,237,192,204,201,204,197,241,142, 85,132,235,247,147, 59, 79,255, 59, 57,216,225, 87, 15,108, 77, 31, 59,118, 12, 77, -144,224, 53,200,144, 75,189, 23, 44, 88,144,144,144, 0, 17,129,223, 43, 9, 20,193,127,205, 33, 37, 0,210,246,135, 52,211,224, - 43,228, 48,135,122,177, 2, 65, 33,209,103,247,175, 0,195,249,215,239,127, 63,126, 62,121,252,228,237,187,247,159,222,189,251, -246,246,221,119, 32, 18, 16, 82,192,165,241,229,155,255, 47, 94,190,209,212, 84,254,240,254, 61, 43, 11,211,167,207, 79,190,126, -248,167,165,242, 85, 92, 84,148,139,139,139,157,157,243,249,139,207,140,204,130,131, 51,243, 96,189,198, 29, 50, 19,128, 95, 35, -164,127, 0,191, 75, 18, 94,115, 48,144,114,165, 76, 88, 88, 24,188, 69, 12,185,181, 2, 24,107,193,193,193,192,234, 7,255,102, - 31,180,182, 63, 4, 32,247, 39,144, 1,174, 43, 33, 33,226,192,212, 2,185,123, 29, 34,254, 24,155,189, 64, 53, 89, 89,153,144, -219,117,192,213,198,127, 72,145, 14,212, 5,113, 63,158,154, 3,168,119,170,163, 96,248,132,111,104, 99, 65, 64, 17,136,222, 36, - 71,214,209, 66,156, 18,144, 86,222, 1,103,207,234,172, 0,214, 1,240,126, 0, 64, 0,177,208,162,232, 7,182,250, 33,179,193, - 36, 53,255,145,218,245,204,200, 99,124,120,238, 17, 19, 17, 97,102, 98,100, 22, 21, 97, 86, 85,254,255,236, 25, 11, 19, 51, 35, - 43, 11, 11, 43, 11,235,165,203,220, 66,220,172, 64,115,172,205,255,114,114,178,255,251,247,159,225,255, 95, 98,172, 6,102, 27, - 30,113,217,151, 95,254,127,189,115,128,133,145,185,180,190,154,152, 44,250, 24, 12,144,221,140,103,252,135, 1,188,222, 31, 82, -220, 67, 74,127, 96,123, 31, 88, 19, 64,164, 62,125,250, 4, 44,253,183,108,217, 66,204,133,242,228, 1,200,197, 79,192, 32,133, - 76, 81, 18,211,246,135, 0,125, 93,227,235, 87,206,254,127,250,233,219,247,223,239,217,127,252,103,120,255,227,199, 31, 96,111, -224,213,155,111,207,158,127,177,117,148,199,165,241,251, 47,145,123,247, 95, 43, 41,202, 41, 42,202,188,125,251, 70, 80,224,175, -170, 42,191,152,168, 18, 7, 39,231,135, 15, 95,206,158,187,241,228,233, 39, 9, 25,237,193,147, 97,254,131,111,187,132, 20,188, -240,242, 23,235, 90,126, 44,163, 21, 72, 43, 24,129,157, 0,248, 93,146, 16,208,215,215,183,107,215, 46, 92,122, 33, 49,146,158, - 46, 8,179,238, 63,114,145, 13,169, 0,128,173,120, 60,227, 63, 72,195, 71,123, 73,186,221, 8,215,149,144, 16,113, 72,241,141, -171, 16,135, 44, 49,154, 54,109, 58,100,134,195,192, 64, 31, 62,112, 15,107,209,227,188,105, 0,162,151, 41,236, 61, 68,111,168, -147, 2, 60, 96,194,250,175, 49, 48, 48,224,111,253, 3,243, 26,124,129,147,167,167, 39, 60,118, 70, 71,126,136, 4, 0, 1,196, - 50, 72, 90,253, 16, 16, 17, 17, 65,146,122, 96, 3,159,153, 25,132, 52,213,152, 12,117,255,178,179,113,128, 42, 0, 86, 86, 43, -115, 6,118,118, 6, 86,102,118, 17, 17, 14,102,230,175,127,255,254,251,247,143,168,145,156,111,239, 94,112,200,104,220,223,179, - 68,148,133, 41,182,186,138, 24, 45,156,156,156, 85, 85, 85, 36, 45, 3,133,220, 62,159,147,147, 3,225, 66,218,251,192,162,255, -219,183,111, 73, 73, 73, 64,246,180,105,211,104,183, 10, 8,114,249, 31,252, 14, 85,146, 86,149,200,200,171,159, 57,177, 83, 76, - 4,216,112,103, 1,143,237,252,253,244,249,215,187,247,223,101, 21,181,109,172,236,113,233,242,242, 10,222,181,125,254,137, 83, - 87,109,173,245,229,229,229,127,255,250, 97,104,160,199,205,207,255,240,222,163,167,207, 62, 28, 61,126,253,253,103,254, 64, 75, -251,193,147, 43, 50, 51, 32, 3, 44,140,153,192, 2, 17, 92,160,255, 67, 42,247,153,152, 24,241, 92,176, 14,186,156,253, 63,188, - 0,100, 4,166, 60,120, 39, 0,200, 0,150, 86, 30, 30,238,176, 74,134,193, 59,186, 22,115,172, 3, 87,169, 13,148,197, 95,250, - 35, 3,160, 74, 92,237,125, 60,169, 2,243, 74, 72,184, 56,158,203,194,224, 53, 7,176,252, 5, 55,255, 25,145,235, 15,252,246, - 34,235, 93, 85,200, 3, 10, 23, 14,113,136,212,170,194, 71,144,202, 96,231,197,223,184, 2, 4,121,220,127,116, 14,128, 12, 0, - 16, 64,216, 43, 0, 43,107, 51, 10,199,221,200,107,251,195,163,141, 72,240,238, 61,163,164, 56, 19,228,224,135, 93,123, 65, 3, -253,236,236, 28,236,108,236,190,158,140, 64,138,147,131,241,221, 91,230, 83,103,121,255,254,251, 43, 43, 67,120,136, 25,216,252, -255,240,237,251,251, 51,219, 84,101, 89,175, 60, 37, 97, 72, 26, 88, 15,153,129, 1,241, 90,192, 23,202,119, 66, 70,123,128,189, - 1,115,115,115, 96,107,209,223,223, 31,200,142,141,141,165, 93,243, 31, 62, 16, 4,105,205, 17, 51,242,131, 18,173,224, 82,254, -214,141,107,207,238, 61, 4,150,131,127,255,254,231,224, 20, 82,211,212, 9, 12, 32,112, 41,152,152,180,222,137, 83, 59,128, 61, - 6, 93, 29, 37,105, 41,145, 71,143, 95,190,191,124,247,230,173, 71,123,247, 93,122,248,244,127, 74,106, 46,145, 14,184,191,229, - 51,217,190,126,240,224, 1,145, 42,255,173, 20, 36, 94,214,119, 19, 94,189,119,231,195, 59, 1,160, 81,163,123, 11,144, 21,160, -233,197,218, 33, 64, 46, 43, 73,242, 47,169, 89, 24,215,149,144,196, 92, 21, 9, 47,232,209,148, 17,211,188,248,247,112,237,154, - 9,113,160,238,139,147, 28,188,244, 7,113,189, 76,193,163,165, 23,112, 85, 0,163,251, 0,136, 4,179, 58, 43,144, 71,129,144, - 1, 64, 0,177, 80, 37,233, 80, 5,144,209,230, 61,115,142,157,131,141,205,215, 11, 88, 3, 48,154,153,252,185,124,133,147, 9, -124,133,244,135, 15, 76, 82, 18,204, 76,140,108, 23, 47,179,113,176, 51,252,250,253,235,225, 35, 78,130,165,255,221, 91,231,205, -157,125, 88, 68,204,239,222, 58,197,242, 98, 77, 89,105,101, 87,119, 59,141, 60,139,124,161,188,142,142,206,251,247,239,129,108, - 32,153,151,151, 71,159, 93, 96,164, 22,253,200,117, 0, 16, 93,184,124,246,229,139,151,220,220,220,120, 26,254, 40, 5,129,158, - 49, 16, 45, 93, 50,243,218,205,147,146,226, 60, 28, 28,172, 95,190,252,122,250,252, 19, 35,139,108, 74,106, 28,145, 86,243, 8, - 21,145,237, 95,200,114,254, 1, 0,231,138, 25,148, 19, 17, 11, 73,207,146,224, 5, 50,178, 97, 70,134, 16,172,218, 32,167,112, -196, 85, 94, 19, 44,199,201,187, 75, 18,238,205, 80, 75,118,144,131,191, 63, 7,161, 81, 64, 61,224, 19, 83, 11,153,245, 5,214, - 1,200,130,112, 54, 64, 0,161, 87, 0,148, 28,215, 67,139,163,126, 8,167, 30, 6,198,247,239, 25,185, 36, 24,133,133, 24, 77, -140,126,115,176, 49,179,179,253, 22, 22,226, 0,231, 1, 70, 11,147,191,167,206,177,130,186, 8,120,243, 18,176,244,215, 86,231, - 43,206,111,250,206, 38,179,110,207, 83,101, 53, 80, 91,158,231,244,150,226,146,202,222, 30, 26,214, 1,144, 11,229,129, 77,126, -120,183, 96,168, 92,115, 10,218,243,165, 75,178,174,232,152,244, 35,199, 14,190,126,251,250,251,139,111, 28, 28,194, 50,138,122, - 68,214, 31, 12,148, 93, 0, 75,149, 80,253,255,255, 31, 3,121,199,153,220, 91, 0, 93, 14,116,111, 33,173,227,133,164, 97,159, - 65, 2,220,124,194, 9,182,229,113,117,174, 71,231, 0,136,175, 3, 48, 75,127, 32, 0, 8,160, 33,127, 31,192,127, 6,208, 10, - 31, 70, 38, 96,204,255, 23, 18,248,127,240, 8, 11, 7,104,251, 47,139,159, 23, 48, 49,252, 19, 20,254,243,231, 47,227,191,127, -127,193,185, 23, 39,208, 83,248,226, 29, 28,250,133, 69, 85,140,135, 59, 42, 80,104,217,250,203,144, 58,224,247,223,117,180,118, - 63, 25, 23,202, 15,105, 64,124,137, 63,144, 93,230,247, 29,105,130, 21, 40, 66,171,133,200,215, 11,108,245,159, 45, 98, 24, 5, - 56, 64, 72,246,148, 1,172,215, 71, 72, 29,128, 75, 10, 32,128, 70, 47,133, 31, 50, 96,244, 66,152, 81, 48, 10, 70, 1,117, 1, - 64, 0,141,222, 8, 54,100,192,104,105, 62, 10, 70,193, 40,160, 46, 0, 8,160,209, 19,151, 70,193, 40, 24, 5,163, 96,132, 2, -128, 0, 26,173, 0, 70,193, 40, 24, 5,163, 96,132, 2,128, 0, 26,173, 0, 70,193, 40, 24, 5,163, 96,132, 2,128, 0, 26,248, - 75,225,237,205,164,113,169,252,250,238, 5,132,193, 45, 36, 1, 97, 28, 60,245, 20, 89,193, 79, 81,113, 92,122,119,247, 67,247, -217,186, 22, 66,215, 24,176,191,126, 73,164,189,152,128,120,123, 49, 1,154,189, 38,134, 82,184, 84,190,185,127, 21,194, 16, 81, -132,158,139,112,230,252, 51,106,249,215, 99, 55,246, 3,232,249,165,164, 98, 97, 71, 1, 79, 17,135,154,191,195, 53,141, 90,241, -139,172,247,230,205,155,200,231,163, 21, 22, 22,170,171,171,211, 40, 93,141,234,165,138,222,203,151, 47, 67, 24,186,186,186,164, -234,197,188,226,105, 52,156, 7, 68, 47, 30, 0, 16, 64,216, 39,129,255,252,249,243,227,199, 15, 70,102,208,165, 90,127,255,252, -102, 99,101, 97,103,103, 39,181,110, 1, 26,194, 0, 62,177,153, 36, 93,192, 66, 31, 88,220, 67,138,126, 9, 89, 5, 32,249, 2, -247, 65,243,152,133, 32,176,248,131, 20,133, 83, 55,157, 2,146,217,126,102, 12,131, 27, 0, 11,125, 96,113, 15, 41,250,181, 77, -172,129,228,213, 51, 71,105,237,223,205, 95,190,236,252,250,213,157,155, 27, 72, 50,188,124,121,170,188, 12, 40,104,214,217, 69, - 83,159, 30, 56,112, 96,197,138, 21,192,116, 5, 23,225,224,224,136,136,136,112,112,112, 24,109,136, 13, 42, 0, 44,244,129,197, - 61,164,232, 39, 53, 77, 66, 78,238,130, 20,253, 36,165, 73,228,243, 77,201, 91,223, 73,198,149,130,163, 0, 32,128,176,148,206, -159, 62,127,145, 84, 51,181,215,213,224, 98,103,253,255,255,255,223,191,255,175,220,126,120,255,210, 97, 78,118, 86, 34, 15,233, - 4, 2, 30,142, 7,218,170,247,174,220, 82,250,250, 83,129,248,162, 31, 72,114,242, 11, 3, 25,144,162, 31,107,111, 0, 79,251, -215, 44,186, 2,200,128, 36, 59, 76, 89,172, 11, 94,145,141,101, 99, 99, 99, 0,239, 47, 7, 93, 30, 0, 62,148, 20,226, 30, 38, -102, 86,252,141,110, 32,144, 20, 3,181,157,127,125,250,240, 19, 92,237,125,249,243, 23,226, 30,126, 49, 25,252,237,125,126, 41, -101, 32, 3,146,205,176,245, 6, 4,169,235, 95, 32,200,121, 9,234, 25, 64, 74,127, 72,209, 15,106,155,239,218,141, 44,235,131, - 55,166, 62,114,191,121,203,243,250,195,219, 59, 98, 2,154, 50,111, 84,136,137, 92, 96,219,127,229,202,149,200,165, 63, 16, 0, -185,156,156,156,146,146,146,104,253,128,225, 13,246,236,217, 67,210, 45,211,120, 14, 67,164, 69,209, 15, 73,147, 64, 6,102,154, -132,245, 6, 4,241,148,191,192, 52, 9,100, 96,166, 73,136, 44,174, 52, 9,148, 61,116,252, 20, 51, 51,203,223,191,127, 62,126, -254, 18, 21,236,223,211,211, 67, 94,233, 79,231, 16, 27,228, 96, 11,182,181,227,200,177, 0, 16, 64,232, 21,192,215,239,191,156, -253,162,100,197,248,185, 56, 64,151,168,252,253,199,192,194,204, 40,196,175,161,173, 42,183,103,231,214,191,191,191, 18, 83, 7, -252,250,245, 75, 83,251,190,190,198,125,102,166,191, 7,206, 72,179,177, 18, 62,205, 21, 88, 16, 3,139, 90,126, 62,208,253,139, - 16, 18, 77, 22, 88, 37,224,234, 10, 0,203, 59, 96,178,139, 15, 15, 2,178, 33, 36,154, 44, 48, 57, 18,108,134, 0,253, 37, 35, - 35, 3, 36,129,142,255,250,245, 43,176,244,135,156,216, 76, 84,109,199,194, 60,111,194,122,118,126,134,151, 15, 24, 78,127,121, -250,250,197,157,197,253,149, 4, 27,254,192,108, 38, 35, 5, 26,218,130,144, 88,199,130,200,243, 47,158,115, 0,128,229, 59,176, -232,111,206,201, 6,178,155, 97, 69,255,146, 91,183, 16,165, 63,161, 67, 4, 30,252, 63,204, 96,246, 52, 66, 46,230,231, 63, 21, -246,127,255,175,191,217,123,126,247, 77,149,127, 89,248,253,219,223,223,255,253,251,119,228,227,175, 33,108,160, 32,176, 31, 64, -234, 41, 55,215,175, 95,159, 56,113, 34, 45,239, 55,167, 97,233,191,106,213,170,247,239, 93, 87,175, 14, 37, 70, 61,228,116,126, -250,148,104,192,242, 29,152, 38,111,157, 63, 6, 44,250,145,211,228,190,173,235,196,197,197,225, 99, 65,184,202, 95, 60,105, 18, - 84, 58,195,143, 87,197, 0,192,120,124,241,234,205,249, 43,215, 96,205,130,159, 93,147,103,165, 39, 68,142, 22,226,116, 0, 0, - 1,132, 50, 9,252,249,243,103, 27,183, 64, 13, 57, 97,118, 86, 38, 96,233,255,226,197,139,203, 23,207,255,250, 3,100,254, 23, -230,231,114,243,244,249,254,243, 15, 49,134,178,179,190, 82,150,123,193,192,204,168,165,250,152,157,229, 37, 73,165, 63, 74, 75, -243,211,103, 96,161, 15,148,194,236, 16, 96, 45, 13,145,193,194,149,235,128,133, 62, 80, 10,179, 49,130, 6,128, 13,127, 96,185, -207,199,199,119,239,222, 61, 96,161, 15,170,246,136, 46,253,129, 13,127, 96,233, 31,152,219,226, 25,101,181,229,202,211, 23,223, - 25, 72, 45,253,145,193,147,103, 47,128,125,109, 81, 65, 62,112,213,204, 76,134,127, 61,130,227, 65, 45, 52, 22, 86,130,165, 63, - 16,212, 78,153, 10, 68,144,210, 31,216, 27, 40,117, 3,183,251, 69,217,240,149, 71,252,219,220, 66,164, 18,229,179, 88,153,120, -184, 25,184,152, 24,152,165,197,173,109,130,157,239, 73,245,227, 31,252, 1,185,112,225, 66, 72,185,143, 70,194, 21, 16, 3,190, -125,251, 70, 80,132, 70, 32, 45, 45, 45, 52,116,245,210,165, 75, 41, 47,253,133,132,246, 16,169,101, 38, 24, 48, 50, 50, 34, 95, -217, 72,187,210,191,181,170,112,245,234,213,115, 38,247, 32,151,254, 64,145, 41, 83,166,224, 73,147,200,165, 63,102,154,244,180, - 6,159, 58,197,203,141, 75,111,239,228,233,144,210,255,213,155,183, 64, 4,236, 1,176,178,178, 76, 95,176,156,152, 75,111, 70, - 1, 49, 0,216,228, 71, 70,200, 82, 0, 1,132,168, 0,128,165,158,176,130,158,130,132,192,143,223,127,129,181,245,206,157, 59, - 22, 45, 92,112,233,226,197,210,162, 2,102,102, 38, 96, 95,128,143,139, 93, 65,207, 6,216,100,195,111,217,239,223,191,181, 85, - 31,242,241,124,155,183,240, 21, 19,227,127, 51,221,155, 64, 17,130, 78, 68, 43,253, 33, 69,255,247,143,111,225, 21, 3, 80, 4, -151, 94,180,148, 7, 73,118,167,150,118,192, 19, 37, 80, 4,143,213,202,202,202,194,194,194,159, 62,125, 2,214, 4, 76, 76, 76, - 64, 15, 2, 75,127, 72, 71,135,224,105, 92,107, 55,172, 47,152,176,107,253,228, 26, 96, 77,192,197, 45,244,248,239, 83, 96,233, -207, 3,206, 39,204,120,245,162,149,254,144,162,255,227,179,187, 26, 50, 98,159,191,253, 96,231, 98,103,248,251,151, 84,255, 86, -206,222,114,245,220,113, 29, 37,173,143,127,113,214,211,144,210, 31,216,234, 7, 22,253, 16, 17, 96,209, 15, 68,247,210, 27,119, - 93,187,164,109,166,196,240, 22,103,100, 93,100,219, 98,237, 32, 42,202,173,249,253,255,103,134,159,175,216,126,190,251,249,247, -243,143,127,223,255,177,241, 72,219,154,172,185,208,134, 75, 35,100,232, 31,114,173, 21, 60,219,195,217, 64, 41,160, 2, 98,210, -241,155, 55,111,138,138,138,128,109,255, 27, 55,110, 0,185,135, 15, 31,110,107,107,171,169,169,161, 79, 46, 2, 22,220, 84,105, -251, 3, 75,255,170, 42,162, 78, 26,135, 23,250,200,247, 50,210, 14, 0,211, 36,228,234,224,179,103,207, 2,203,125, 96,154,132, -148,254, 12,224, 91, 27,201, 75,147, 93, 9, 62, 87,238, 62,150, 80,146,100,248, 74,160,158, 6, 22,253,191,127,255, 1, 23, 32, -127,128,232,241,195, 7, 36, 57, 30,185,187, 48,218,117, 32, 30, 0, 4, 16, 98, 8,232,231,207,159,134, 26, 26, 92,156,172,192, -246,254,223,127, 12, 71, 15, 31,105,108,110,249,247,159,225,246,157, 59,151, 46, 94,208,209,209,103,102,102, 84, 87,146,185,119, -238, 15, 39,222,131, 53,217, 88, 94,169, 41, 60, 99, 96, 97,124,252,252, 55,144,212,211,120,120,234,242,171,255, 12,196, 46,185, -129,143,243,160,245, 9,128,149, 1,120, 45,208, 83, 60,122,225,227, 60,104,237, 17, 96, 66, 4,173,141,121,141,189, 47,242,231, -207, 31, 46, 46, 46, 96,209, 47, 40, 40, 8,108, 78,126,253, 10, 58, 8, 90, 84, 84,244,237,219,183, 4,207,168,250,241,158,193, -140,147,179,116,242, 97, 87,125,134,135,231, 25, 78,131, 5,129,220, 73,133,142,127,255, 17,117, 5, 13,124,122,205,217, 88,131, -133,151,105,231,129,107,134, 26,178,124, 60,236, 7,207,220, 17, 81,212,126,128,186, 10, 8,151,127, 55, 93,251,207,240,156,193, -207,153,113,246,150,123,194,130,138, 65,214,140,120,252, 11, 25,243,217,249, 21,122,222,245,255,134,126, 6,233,143,140,169,245, -255, 27,155, 25,152,190, 51,158,106,155, 34, 46,142,245, 84,238, 31, 26, 15,229, 5,188, 62,253,253,242,243,253,157,197,143,150, - 29,241,123,175,149,226,232,150,203,195, 41,168,206,193, 34,200,226,247,241,244,186,211,166, 38,166, 56, 59,155, 76, 76,240,240, - 68,102, 19, 15, 68, 68, 68,242,243,243,143, 28, 57,178,115,231, 78, 80,213,181,115,167,166,166,102, 96, 96, 32,125,178, 74, 64, -192, 47,106,149,254,242,242,242, 68, 22,106,240,114, 31,210, 9, 32,251, 12, 87, 34,129,147,119, 16,176, 31, 12,172, 0,128,229, -190, 49,152,193, 0,190,222,206,195,222, 4,146, 38,117,117,117, 31,224, 93, 97, 2, 79,147,207, 55,116,240,106,115,240,168, 22, -172,234, 72,209,215,145, 80,247,105, 1,122, 7,235,234, 20, 96,219,142,131, 3,180,198, 4,216,240,255,246,237, 7,217,142, 31, - 45,247,113, 1, 60,135,193, 1, 4, 16,162, 2,248,247,239, 31, 23, 59,219,175, 63,255,153, 24, 25,128,168,190,169, 5, 88, 13, -124,253,250,229,197,139,231,226,226, 18,255,255,255,251,243,135,129,131,149,133,153, 21,223, 16, 1,176, 48,213, 82,126, 34, 34, -248, 9, 52,228, 7,190,232,147,145,241,191,145,246,237,147,151,196,137, 89, 14, 4,105,230, 99, 14, 7,225,105,254, 35, 55, 58, - 48,139,126,130,205,127, 72,187, 82, 76, 76, 12,178,204, 9,216, 89,129,204,253,242,243,243,179,178,178, 62,126,252, 24,255,244, -197,252, 61, 7, 83,124,236, 29,192,236, 91,127, 64,227, 63, 64,134,131, 26, 3, 95,203,254,194, 18, 43,130,110, 6, 54,178,128, -164,156,152,208,251,159, 63, 89,248,152,127,188,254, 6, 44, 26, 37,229,101,118,237, 59, 77,164,127,227,139, 91,239, 31,221,203, -242,130,225,131, 56, 3,176, 18,179, 80, 80,116,178,199,183, 68, 21,121,196,127, 73,120,202,218,159, 55, 25, 84,126, 48,156,100, - 97,224, 97, 97,240, 53,150,241,141,199,215, 85,146, 22,250,245,235, 29,235,159,223,192,210,255,120, 2,191, 93,160,191,134,152, -230,149, 93, 7, 12, 67,191,178,254,250,250, 71,227,223,235,151,248, 38,234, 33, 37, 62,100, 14, 0,153, 77, 18, 0,150,248,220, -220,220,215,175, 95,231, 2,131,232,232,104, 90, 15,251, 0, 75,109, 96,209, 31, 13, 6,244, 44,253,209,198,124, 32, 23,167,208, -161,140,243, 8,142, 81, 82, 82, 2, 86, 0,144,210, 31,216,246, 23,151,148, 36, 41, 77,166,249,218,157,120,246,138, 87,159,247, -233,206,187, 12, 28,236,193,185,113, 66, 50, 62,120, 11,141,191, 79,159,191, 4,150,254,144, 30, 0, 16,144,218,252,199, 28, 44, - 26,173, 12,240, 84, 6,200,117, 0, 64, 0,161,204, 1,252,135,172,129,249,207, 0, 44,250,153, 64,101, 55,195,186,181,107, 2, -131, 66, 68, 68,197, 32,153,246, 63,161, 67,198,153,153, 94,105,171, 64, 47, 71,212,211,225, 2, 55, 93, 24,140,180,238, 1,197, -137,113, 28,242,152, 15,154, 56,124, 43, 0, 46,128, 60,230,131, 38, 14, 95, 26,143, 21,124,250,244,233,243,231,207,192, 14, 16, -176, 10,124,253,250, 53,100,252, 7,216, 21,248,242,229, 11,193, 33,160,245,147,107, 14, 92, 97,248,248,128,225,247,119,134, 73, -229,142,144,241,159,115,231, 25, 46, 60, 63, 74,204,122,169,143,207,238, 10,241,115, 11, 11,113,171,171,105,222,187,255,250,214, -211,183,114,194,252, 63, 95,190,250,243,251, 15,124, 43, 0, 30,255, 90, 57,248,219, 56, 70,174,223,188,106,255,161, 85,203,250, -138,131,139,219, 46,253,102,120,253,246, 21, 30,255,194, 71,252, 19,173,204,163,181,228, 87,173,223,119,233,210,131,190,203,103, - 87,184,198, 49,204, 61,246,244,233,107,248, 86, 0, 44, 67, 4, 63,216,255,254,122,243,235, 23,232,242,119,113,105, 89, 13, 77, -205, 79,156,160,153,146,239,255,190, 49,253,252,202,249,149,249,229,115,236, 21, 0, 36, 24,127,128, 1,124,216, 7,109, 69, 16, -145, 0, 24, 47, 75,150, 44, 1, 86, 3, 5, 5, 5,192,154, 27,210, 21, 24,180,195, 62,100,151,254,200,205,127,200,220, 3,188, - 19, 64,235, 2, 2,152, 38,209, 68,224,105, 18,190, 21, 0, 79,154,180, 53, 85,119,177, 86,107,109,234,233,157,176,173,110,201, -190, 12, 39,147, 23, 27,183,125,124,255, 9, 87,137, 12, 20, 15,245,243,128, 12,251,192, 43, 0, 32,104,171,175, 36,190, 16, 31, - 45,238,241, 3,180,209,127,228, 14, 1, 64, 0, 49, 33,247,208, 63,126,249,198,204,196, 8,172,144,255,253,255,255,231, 31,104, -210,254,226,133,243, 78,206,160, 27,236,254,254,255,207,204,196,252,249,219,175, 63,191,126,226,172,201,255,254, 85,148,126, 46, - 42,244, 17, 82,153, 88,153,241, 64, 46, 87, 5,118, 2, 12, 53,239,252,249,251,151,152,230, 63,214,169, 96, 98,155,195,216,166, -161, 8,234, 21, 20, 20, 4,150,251,192, 30, 0,176, 26, 16, 21, 21,133, 76, 8, 3,139,167, 15, 31, 62, 16,172, 0,210, 90, 87, - 0,203,125,126, 5, 6, 96, 53,144,215,185, 31, 88,250, 7,229,183, 63,249,247, 98,105, 95, 25, 48, 36,137,105,254, 27, 27,171, -137, 42, 41,136,137,138,176, 1, 67,158,241,255,235,175,223,223,127,254, 65,164,127,123, 59, 54, 4,104, 42,242,241, 9,115,137, - 74,253,126,247,254,252,150,229, 31,222, 61, 34, 50, 77,204,235,200, 97, 40,116, 97,249,243, 75,225, 43,195, 43,230, 79,147,158, -159,102, 96,227, 35, 48,222,117,247,211, 27,166,239,143,216,190,153,168, 56,106,197,241,220, 19, 60, 32, 42,122, 94,214,226,222, - 71,166,207, 63,255,127,255,182,228, 31, 7, 15, 47,158,182, 63, 85,192,195,135, 15,129, 36,176, 49, 46, 34, 34, 18, 24, 24, 8, -105,165,210, 14,164,167, 11, 98,142,252, 16, 63, 27, 76,118,233,143, 92,208,195, 43, 33,200,141,237, 52,245, 47, 48, 77, 30, 63, -126, 28, 50,238,111,108,108,204, 0,190,136,120,229,166,109,196,167,201,141,235, 27,220,203,115,189,188,156, 69,216,153, 63, 51, -254,223,121,235,241,241, 43, 79, 9, 22,223,153, 9,145,247,238,220, 1, 54,252, 33, 8, 88,250, 99,109,215,143, 2,242,138,126, - 92,227, 63, 64, 0, 16, 64,136, 97, 25, 96, 9,120,251,218, 37, 5, 41, 33, 78, 86,150,191,127,255,129,175,104,102, 72, 75,207, - 6,118, 9,254,130,119, 3,124,251,241,227,250,173,123,108,108, 56, 7, 69,254,252,126,103,168,117, 31,158,233,179, 10,239,175, - 93,162, 10,233, 51,152,232,220, 61,113, 81,147,133, 89,148, 96,243, 31,173,232, 7, 10, 50, 32,237, 4,198,223,252, 71, 75,142, - 64, 65, 6,164,157,177,184,192,223,191,127, 37, 36, 36,128, 61,128,151, 47, 95, 2,217,192,146,229,237,219,183, 64, 18,114, 75, - 53,126,189,175, 95,220,169,105,217, 15,236, 1,116, 23,219,126,249,243,183,168,115,245,196,242,208,226,190, 45, 44,160, 59,104, - 8, 55,181, 36, 69, 4, 88, 25, 88,255, 50, 48, 62,191,127,245,225,171,143,202,162, 66, 23,223, 61, 59,119,247, 41, 49,205,255, -224,164, 34, 86, 33, 6, 38,102,134, 5,219,238,175,157, 86,154,212, 49,179,200, 87, 63,219, 89,158,160,127,129,205,255, 94,191, - 48,134, 15, 28, 12,140,172, 12,189, 61, 33,167, 15,239,114,206,100,108,207,101, 60, 81,134,167,249, 15, 4, 23, 95,136,216,124, -255,248,133,147,249, 27, 7,135,114, 48, 43,176,208,255,200,196,250,135, 65,237,255,223,111,191,223, 60, 63, 58,249, 99,116,148, - 50,141,210, 49,124, 48, 90, 19, 12, 32,130,182, 96, 64,211,252,131,117,193, 62,145,221, 2,178, 75,127, 6,212,209,127,180, 5, -163, 52,157, 9,184,117,254, 24, 60,168,179,146,194,118,192,198,130,182, 43, 41, 17,220,187, 0, 76,147,225, 46,230,252,255, 4, -191, 49,176,174,237,207,157,182,229, 66,169,135, 77, 66,223,178,144,182,197, 4,235, 45,248,222, 49, 52,238,232,138,126, 90, 3, -128, 0, 66,244, 0,128, 45,223, 15,207,239,220,125,252,150,133,149, 25,216, 7,248,253,231,239,185,115,103, 23, 45,154,255,235, -239,255,223,127,255,177,177, 48,189,122,255,229,233,245,227,156, 56,166,128,129, 69,167,166,242, 67,104,243, 31,220,239, 95,187, - 68, 13, 52, 0,196,244, 31,136,152,152,254, 89,232, 95,255,139,187, 19,128,214,252,135,175, 2, 2, 22,253, 4, 75,127,180,230, - 63,124, 5, 2,176, 40, 36, 88, 26,130,243,243,251, 47, 95,190,176,178,178, 66,154,255,255,254,253,131,144,196, 84, 0,139,251, - 43,207, 61, 61,200, 35, 1,154,248,229,101, 97, 6,214, 7,124,236,172, 31,222, 61, 1, 54,255, 89,152,152, 8, 54,255,101,133, -120,175,221,187,255,231,215, 47,118, 22,182, 47, 95,126, 92,188,255, 12, 88,244, 19, 44,253, 33,254,245,207,105, 94, 58,105,226, -183,127, 12,178,202, 50, 87,174,158, 0,150,254, 68,250, 23, 8,138,148, 77, 54,223,222,199,240,241, 15, 3,135,200,238, 83,215, -128,165, 63,176,232,199, 95,250, 3,129,254, 47,159,163,187, 79, 49,252,250,252,133,241,243,123,166, 47, 31, 89,126,255,254,251, -137,253,199, 55,142,103,247, 87, 84,221, 86, 48, 80,195, 51, 3, 12, 4,240,148,195, 1, 6,104,130,248,193,108, 48, 24,192,124, - 2,105,245, 3,203,116, 6,240,108, 48,193, 9, 97, 74, 74,127, 96, 17,255, 31,247,146,121,218, 45, 7, 2,166, 73,248,154,159, -154,218, 66, 96,154, 20, 23, 23,135,172, 11,130,136, 19, 76,147, 41, 14,122, 5, 61, 19, 63,191,124, 37,202, 39,118,245,218, 35, - 96,233, 15, 89,198, 74,100,157, 7, 7,200,163, 58,163,253, 0, 74,192,150, 37,205, 91,240,222, 35, 2, 16, 64, 40, 19,179,188, -188,188,103, 15,108,248,255,223, 79, 65, 74,152,151,139, 93, 75,199, 64, 75, 91,159,133,137,225,203,247,191,143,158,191, 59,117, - 96, 43, 15, 55, 23, 46,131,190,126,251,166, 38,255,252,199, 79,142,255,144,107,243,254, 51,112,114,252, 0, 38,227,119, 31,216, -129, 2,188,220,127,116,213, 30, 28, 62, 99, 8,180, 2,127,243, 31,222,234, 7,114, 89,255,255,102,248, 3, 93, 61,246,151,133, -139, 96,243, 31,222,234,135,112, 63,190,130, 46, 57,192,179, 29, 23, 94, 7, 0, 73, 96, 63, 0, 72,190,123,247,142,143,143, 15, - 50,254, 67,204,165,172,224, 85,255,237,153,161,246, 12,147, 14, 79,171,246, 14, 41,158,184,172, 35, 27,216, 3, 96, 99,231, 32, -216,252,191,246,232,149,138,172,200,222, 61, 39, 24,192,219, 47,129,228,239,159,208,190, 54, 43,110,237,144,230,127, 75,146,115, - 94,253, 2, 89, 37, 70,146,252, 11,105,254,187,173,159,183, 43, 58,146, 81,198,130, 1,188, 37,152, 1,124, 56, 4, 68,129, 47, - 15, 15, 30,103,235,253, 44,187,184,125,203, 15,245, 99, 10,170, 58,159, 56, 25,238, 51, 60,252,252,224,245,235,182,191, 95,222, -203, 20,198, 21,227, 15,168,233,211,167, 3,139,251,239,223,191,195,139, 48, 32, 23, 40, 56, 36, 50, 18,164,213,255, 18,188, 77, -154,152,217, 96, 96,123,153,188,210,159, 1,118,249, 59,158,130,143,212,189,196, 68, 2, 96,154,108,109,168, 89,183,121,187,187, -141, 17, 60, 77, 2,145,241,189,123, 30,193, 49,143,222,126,147, 19,230,194,223,252, 47,152,181,185, 42,217, 77, 74,194, 1, 82, -139, 64,156,138,167, 47, 69,100,183, 96,180, 31, 64,197,250, 0, 77, 4, 32,128,208, 87,230,240,241,242,156, 59,176,225,190,140, -186,146,170, 38, 31, 55,231,191,255, 12,223,127,254,186,119,239,222,235,123, 23,120,121,184,153,112,183,106, 57, 57, 56, 86,237, -176,199,211,198, 7,234,229,230, 38,208,220,131,172, 1, 5, 54,249,255,253,253, 13, 42,253,193,224, 55, 35, 43,174,195, 24,144, - 1,100,253, 25,176, 9, 12, 47, 7,137, 44,253,225,117, 0,124,243, 23,176, 14,192, 25, 64, 56,234,128,197,176,141, 80,179,219, - 96,123, 98,127,127,193,127, 13, 57,176,249,127,234,205,135, 11,183, 65, 3, 62,240,114,159, 96,233, 15, 1,192,230,255, 90, 35, -238,156, 64, 13, 50,252, 11,108,254, 23,111, 90,197,216, 90,191, 93,220,124,194,151, 43,112,113, 67, 22, 86, 25, 14,194, 39, 62, - 1,251, 1,219, 55,253,120,242,254,238,235,183,207, 95,222,226, 97,254,203,103,173,103,235, 24,231, 72,211,132, 59,224,155,126, -201, 88, 3,154,158, 46, 72, 70,233,207, 48,160, 83,154,192, 52,105,105,105,137,150, 38,129,165, 63, 3,104, 42,152, 11,191, 94, - 96,243,223,117,207,201,232,250, 69,118,118,118,226,168,189, 73,178,171, 43, 72, 29, 64, 48, 64, 48, 43,203,209, 58, 3, 79,185, -143, 60, 19, 0, 16, 64, 88,202, 55, 96,251,247,231,187,199,231, 14,128,150,139, 64, 46, 92,102,103,103,199,156,155, 69, 3,172, -172,172,252, 68, 28,249,128, 7, 64, 6,124,152,129, 77,254, 63,223,152,145,138,126, 98, 78,172,134, 12,248, 0,139, 66,228,210, -144,152,162,159, 95, 84,234, 23,238,105,109,252, 32,186,121,241,237, 27, 87,201,246,239,169, 91,143, 33,217, 12,185,244, 39, 88, -244, 67, 64,156, 17, 55,121,254, 5,197,105,127, 25,164,232,135,151,254, 68, 22,253,112,224,169, 24,194, 0,169,220,136, 91, 35, - 3, 44,190, 33,155,126,129,237,125,248,238, 95, 32, 3,210,252, 7, 50, 6,255,161, 14,100,172, 1,165, 69, 35,157,214, 0,107, -154, 36, 88,244, 67,128,107,205,108, 42, 22,253, 36, 85,135,163,101, 61, 46,128,118, 35, 60, 3,198, 60, 48, 64, 0, 97,111,224, -178,176,176,224, 26,171,161, 5,128,140,242, 67,138,126, 6, 18,139,126,200,168, 55,121, 69, 33, 3,104,229,210, 63, 98,186, 23, - 88,193,171,119, 31,137,183, 8, 25, 64, 70,249,201, 43,250, 41,241, 47,100,148,127,243,151, 47,100, 23,253,163, 96,184, 2,200, - 18,207, 71,111,191,145, 81,244, 67,202, 95,248,104,207,208,173,255,134,107, 29,128, 71, 22, 32,128, 70, 47,133, 31, 5,163, 96, - 20,140,130, 17, 10, 0, 2,104,244, 70,176, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24, -161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, - 6,254, 82,248,145,166,247,199,139,199,196,235,229,144,144, 29, 13,231, 81,189,163,122, 71,245,210,232, 82,120,128, 0, 26,212, - 61, 0, 82,119,129,223,187,119,111, 15, 12, 0,217,163,213, 59, 30,240,241,227,199, 71,143, 30, 29, 63,126,252,220,185,115, 64, - 6,121,134, 80,241,148,183, 81, 48,200,193,205,155, 55, 73, 82,156,145,145, 65,182, 69,100,235, 29, 5,164, 2,128, 0, 98, 25, -180, 46, 35,181, 4, 7,170,239,232,232, 8, 11, 11, 67,214,174,164,164, 68,188,118, 32, 88,189,122,117,104,104,168, 18, 24,224, - 87,159,150,150, 70,208, 76,160, 99,176,174,134,222,189,123, 62, 49,122,223,191,231,166, 81,216,190,122,245,234,231,207,159,140, -140,140, 28, 28, 28, 63,126,252, 0, 86, 0,167, 79,159,214,215,215, 87, 81, 81, 33,201, 28, 98,142,202, 0, 87,228,153,196, 40, -155, 57,115, 58,181,245,166,227, 80,140,126,244, 24,193,116,197, 80,207,200,216,132, 81,249,213, 51,134, 93, 15,101, 96,215, 32, -232, 60,119,119,208,145,186,228, 29, 94, 13, 57, 11, 58, 61, 93,144,146,149,245,192, 82,181,191,191,159,224,134,187,212,212, 52, -160,183, 48, 99,181,164,164,152, 24,237,240, 84, 49, 97,194, 4,123,123,123, 96, 57,190,108,217,178, 79,159, 62, 17,180, 20,165, - 72, 98, 97,142,176, 98, 75,207, 72,239,218,209, 93,226, 90, 2, 17,156, 61,123, 22, 86,189, 49, 49,160, 93,202,220,220, 88,114, - 10,228,102,167,132,132,132,209, 29, 9,200, 0,178, 47, 12,190,250, 31, 32,128,176, 87, 0,152,135,141,208,232,248, 17, 42, 86, - 0,240,210, 31,232, 78,200,158, 20,160, 9, 68, 86, 0,144, 76, 14, 41,206, 32,231, 94,149,151,151, 19,214,187, 90,136,144,193, - 56, 67,236,171, 47,129, 91,212, 25,136, 56, 36,141,188,123, 48,128,109,127, 49, 49,232, 5, 15,156,156,156,192,202,224,195,135, - 15,252,252,252,167, 78,129, 46, 79, 38,166, 14, 0, 6, 47, 36,148,128, 33, 22, 28, 28, 12, 12,112,130, 53,193,166, 77, 27, 32, - 12, 63,191, 0, 92,108, 92,122,191, 31,203,129, 6,137,213, 20, 56, 27,153, 11,100,224,210,187, 99, 7,202,229,102,135, 14, 29, -106,107,107, 67, 14,168, 37, 75,150,224, 79, 24,157,157,157, 29,236,157,224,130, 56, 20, 37, 11,212, 51,146,154,164,233,159,137, -144, 75,127,160,151,129, 49,190,116,233,210, 35, 71,142,120, 69, 85,227, 82,124, 12,227, 10,237,245,171, 65,165,255,191,127,255, -102,205,154, 5,212,206, 39,103,143,181,208,135,119, 7,111,220,184, 1,228, 70, 70, 70, 2,217, 81, 81, 81,196, 84, 27, 61,187, -161,183, 16,191,216,249, 28,168,119, 89, 62, 23,208,200,114,143, 50, 6,112,236, 45, 95,184, 44,195, 30, 95,159,192,216,216,152, -248,166,222,104,233,143, 12, 0, 2,136, 9,107,177, 2,204,222,192,200, 70,203,240, 68, 14,200, 80, 50,246,130,172, 23,210, 24, - 39, 94, 47,208,193, 46, 96, 0,169, 3, 72, 74, 16,144,210, 31,104, 29,232,122, 10,176,165, 68,250,130, 49,236, 61, 4,225, 17, -193, 5,120,182, 76,135, 32, 60, 34, 4, 75,255,255, 96, 64,252,104,204,251,247,239,129,101, 61,176, 2, 72, 74, 74,138,142,142, -102, 99, 99, 3,214, 1,192,126, 0,208,251,204,204,204, 4,143,215,191,118,237, 26,208,222, 53,107,214, 64,130, 11,104,233,218, -181,107,129, 13, 61,160, 56,157,147, 50, 90,101, 64,163, 38, 8,176,244, 7, 38,137,240, 27, 97,160,150, 62,106,224, 87,252, 44, - 71,235, 19,224, 2,192,240, 41, 45, 45, 85, 84, 84, 36,195, 13, 64,189,192,182,191,176,240, 94,202,219,254,240,210,159, 36,237, -240,210,191,184,184, 24,143,118,228,228, 7,108,254,219,217,217, 1, 25,192, 58, 0,216, 15, 32, 88,110,160,233, 13,183, 4,181, - 74,151,229,115, 2,251, 1,101,238,165,248,245, 2,219,254, 64,187,128,221,113, 23, 12, 0,145, 26,109,254,227, 41,253,129, 0, - 32,128,152,176,117, 57,161, 23, 67, 67,218,209,240,230, 30, 49,197, 49, 36,207, 80,146,223,200, 27,192,193, 90,166,147,170, 5, - 94,121, 0,155,255, 4,207,191, 29, 88, 0, 47,253,129,228,211,167,208, 11, 55,158, 60,121,130, 63,179, 1,219,254,223,190,125, - 99, 98, 98, 2,250, 17,200,126,246,236, 25, 43, 43, 43, 11, 24, 0, 25,144,163, 58,209, 54,244,163,101,212,137, 19, 39, 2,139, -254,144,144, 16, 96,129, 2, 52, 4, 88, 56, 2,217, 64,169, 73,147, 38, 13,179,220, 2, 47,253,129,108, 96,217, 13,111, 91, 64, - 2, 31,222, 65, 36,178,124, 1, 42, 3,134, 24, 48, 81,145, 55,107, 82, 89, 89, 9,212,139, 39,106,240,148,254,125,125,125,192, - 40, 3, 86, 36,192,226,251,240,225,195, 12,224, 19,153,136, 47,253, 33,218,129,105,230,204,153, 51, 16,237, 4,109, 4,170,143, -136,136,128,112,129,117,128,131,131, 3,208,246,141, 27, 55, 18, 28, 72, 4, 54,255, 25, 24, 25,150,230, 65,207,159, 0,246, 3, - 34,173,217, 65,253, 0,188, 0, 79, 41, 49,218, 45, 64, 43,253,211,202,209, 75, 69,128, 0, 98,193,154, 88,225, 23, 67,223, 67, -186, 24,154, 96, 90,167, 86,233, 79,149, 10,128, 18, 0,172, 60,200,246, 8,221, 0,176, 40, 1, 22,253, 47, 94, 64,111, 97, 68, -102,227, 2,175, 95,191, 6,230,100, 96, 75,255,206,157, 59, 64,237,192,188,250,235,215, 47, 96,246, 3, 86, 0, 64,242,239,223, -191,192,234, 97,253,250,245,184, 34,122,239, 94, 80, 59, 20, 88,226, 35, 43,128,176, 33,197, 19,158, 20,130, 60,194,131,139,141, -167,177,143,107, 44, 8,207,224, 15,218,200, 15,164, 77, 74, 82, 26,232, 96,239,100, 68,173, 80, 33,227,254,247,136, 25, 30, 68, -106,194, 67,234, 72, 72, 73, 7, 12, 67,226,219,164, 16,189,170,170,170, 12, 68, 79,183, 32,131,204,204, 76,248, 96, 23,144, 13, - 44,190,129,134, 16, 95,250,219, 91,131,142,100, 4,182,253, 75, 74, 74,128, 13,115,136,118, 95,191, 84,252, 23,251,193,155,255, -112, 0, 25, 11,218,182,109,155,134,134, 6,176,201,142, 95,111,184, 37,202,193, 92,224,177, 32,134,229,203,206,223,148,184,137, - 95,239, 40, 32,163,244, 7, 2,128, 0,194, 62, 7, 0,236, 82, 65, 26,254,240,139,161, 73, 42,253,177,182, 67,241, 12, 79,227, -210,139, 44, 78,187, 3,255,128, 62,133, 31, 59,142,236, 6,242, 70,108,255,175, 18, 36,219, 37, 95,124, 8, 79,120,194, 29,137, - 86, 34,200,200,200, 32, 43,192, 26, 92,239,222,189,227,229,229, 5,146,199,142, 29, 3, 86, 3,192,210, 31,216,228,135, 92,125, - 3, 44,218,126,255,254,253,243,231, 79, 60, 77, 84, 72,175, 8, 51, 76,128, 34,107,214,172, 1,202,226, 9, 46,202,231, 0,128, -101, 61,114,113, 15, 97, 19, 89, 13, 0,139, 36,146,235, 0,240, 16, 63, 36,229, 35, 38,147,192,130,196,207, 45, 33,215,145, 12, -176,139,221,201, 27,148, 0,118, 2, 32,179, 23,196,107, 7, 70, 37,124,252,221,198,198, 6, 88,130,147,212,246, 7,106,255,243, -231, 15,178,246,131, 71,255,246,116,102, 16,108,254, 67, 74,124, 76,208,223,223,239, 29, 93,131, 75, 47,210,232, 63,106,255,128, - 8,189,163,128,108, 0, 16, 64, 44,120, 82, 45,164,249, 79,231,182, 63,242, 72, 20,125,150,114, 34,143,246, 32,175, 15,193, 95, -162,225,236,207,194, 70,255,201,168, 9,224,163,255,248,107,130,232,232,104,110,110,110, 30, 30, 30, 96,105,206,207,207, 47, 40, - 40, 8,108, 94,197,198,198, 66,100, 57, 56, 56,220,220,220,128,190,192, 60,230, 15, 88,226, 3, 75,255, 31, 63,126, 0,117,177, -179,179, 3,179,247,127,208,101,159,127,129,226,192,210, 31,200, 32, 56, 64,129,107, 24, 16,216, 80,165,195,160, 25,174,217, 96, - 98, 0,164, 14, 32, 33, 30,155,176,120, 54,236,122, 40,120,106,138, 88, 67,144,155,255,240,106,155,200,134, 5,114,243, 31,107, -149,143, 31, 44, 91,182, 12, 98, 8,176, 14, 32, 99,232, 31,210,242, 3,118, 13, 11, 11, 11,207,156, 57, 3,211, 78, 32,121, 76, -156, 56, 17,237,146,206, 21, 43, 86, 28, 60,120, 16,152,174, 32, 45, 18, 60,235,211, 39, 76,156, 16, 97,129,210,252,143,158,244, -109,197,177,223, 64,189,134, 81,134, 25,246, 25,196,175,109, 31, 5, 68, 54,255,129, 0, 32,128,152,240,180,139, 33,137, 0, 62, - 25,128,127, 24,174,188,188,156, 60,247,225,210,171, 4,190,143,148,248, 86, 60, 26,128,172, 8, 34,117,216,148,152,197,157,131, - 1,204,154, 53,171,175,175, 15,206,133,148,254,126, 96, 0,100, 0,179, 28, 86, 93,192, 10, 3, 88,202,191,127,255,254,205,155, - 55, 64,242, 27, 24,124,249,242,229,211,167, 79, 31, 63,126, 4,246, 6,128, 61, 0, 60, 87,250, 0, 11, 32, 96, 75,159, 96, 37, - 58,168,192, 33, 36, 0, 23, 4,122, 31,206,198, 51,174,141, 60,238,143,220,150, 39,169, 89,128,166, 24, 88, 28, 3,195,144,236, -153, 0,160, 94, 98,146, 52,176,196, 7,166, 1,200,196, 47,176, 14,128,248,157,248, 75, 23,170,203,237,129,218,255,173, 20, 0, -106, 7, 54,189, 33,218, 15, 29,251, 7,107,142,227,108,254,195, 7,124, 64,227, 54,203,151,102,102,102, 2,205, 41, 40, 40, 32, -104, 53,168,249,207,192,184, 20,214,252,143,154,248,141, 57,226,227,242, 99,191,128,122, 59,119,116,141, 22,226, 52, 42,253,129, - 0, 32,128, 88,112,149, 47,240,161,127,248,100, 0,254,194, 17, 82,142, 67,218,242,164, 14,215,160,233,133,244, 9,128,130,228, - 13,251,192,151,129,210, 19, 64, 26,254,228,141,255, 64, 26,254,196,140,255,192,179, 55,132,209,216,216, 56,127,254,124,216, 16, -138, 31,132, 1,108,254,227,170, 0,132,133,133,223,190,125, 11,108,239,191,126,253, 26,216, 3, 0,182,239, 32, 61,128,175, 95, -191, 2,107, 2, 96,233, 15,172, 6,202,202,112,206,185, 65,154,249, 88,151, 8, 67,100,241,184,153, 42,115, 0, 68,138, 35, 3, -200,176, 9,122, 1, 87, 93,221,218,218, 42, 34, 34, 66,211, 36,129,217,252,135, 3,130, 51, 1,152,205,127,146,218,254,192, 62, - 98, 76, 76, 12, 48,114,129,222,175,170,170, 2,246,126,136,191,208,166,166,194,254,192,129, 3,140,107, 64,247,179,238,170,225, -117,107,249, 12,212,222,218, 9,106,197,227,239,130, 64,214,254,131, 91,253,203, 14, 30, 60,252,159,241,127, 97, 65,161,186,186, - 58, 49,150, 2,245, 70, 88,177, 34, 90,253, 12, 32,189,226,110, 18,100,204,124,140, 2, 44,229,121,103, 5,102,197, 0, 25, 33, - 0, 8, 32, 22, 60,109,127, 96,233,143, 60, 25, 64,176,235,138, 92,142,147,215, 15,128,232,165,112,228, 7,226,102, 50,203,241, - 65,159,224, 32,131, 84,240,171,186, 19, 19, 19,209,198,103,128,130,144,124,136, 9,100,100,100,238,220,185, 3, 44,241,129, 77, -254,223,191,127, 67,134,254,127,252,248, 1, 89, 75, 10,153, 19, 86, 86, 86,198, 83,179, 2, 13,135,116, 2,224, 41, 1, 24,212, -104, 34, 88, 1, 45,230, 0,144, 71,132,112,133, 21, 86,113, 96, 0, 2,235,128,240,240,240,149, 43, 87, 18, 63, 80,137,198,238, -232,232, 72,123,154, 30, 6, 76,105,216, 54,130,185,187,187,223,191,127, 31,109, 23, 2, 4, 0,197, 25,240,110, 10, 11, 13, 93, - 29, 26,234,236,234,122, 15,115,178,225,237, 91,103, 6,134,247,233,233, 56,115, 34,252, 42, 68, 72, 39, 99,215,174, 93, 12,164, - 92,103,198,196,196, 8,106,196, 64, 74,255, 75,127,230,239, 7, 93,132, 9, 44,253,137,201, 26,144,228, 4,108,245, 3,201,194, -162, 66,117, 53,117, 34, 45, 45, 45, 43, 1,235,101, 0,182,250, 33,122, 37,220, 36, 65,163, 77,163,133, 63,237, 1, 64, 0,177, -224,234,206,195, 39,126,225,203, 60,136, 25, 19,167,202, 88, 16,169, 59, 0, 70, 32,128, 15,185,192,203, 56,200,238, 13,100, 65, -172, 99,166,192,186, 97,219,182,109,127,254,252,249,240,225, 3,100, 14,128, 1,188, 58, 8,200, 5,178, 9,198, 93,126,126,254, -196,137, 19, 33,213, 0,242,184, 63, 80,156,214,117, 39,176,184, 39,166,208,199, 90, 26, 98, 86, 12,192, 38, 54,145,165, 63,102, - 41,140, 60, 33, 76,176, 19,128, 41,248,224,193, 3, 6, 34,150, 24,192, 7, 96, 81, 93,238, 66,140,127,129,253, 60, 96,209,143, - 60,248, 78, 12, 0,106,255,183, 82, 16, 88,238, 3,217, 11,246,255, 90,113,236, 23, 80,251,225,227, 36,140, 86, 29, 58,116,168, -160,160,128,200, 86, 63, 28, 64, 18,225,202,227,191,129,122, 37,220, 37, 97,245, 9, 81,122, 33,219,125, 33,211,251,104,209, 52, -186, 19,152, 1,219,117, 96,104, 59,129, 1, 2,136, 5,107,246,128,108,170, 66,110,250, 17, 28, 2, 66,207, 30,228,214, 1,148, - 27, 2, 63, 13,130, 72, 0,172,108,176, 14, 97, 19, 83, 9, 97,142,249, 16, 63, 10,132, 57,230, 67,228, 40, 16,124,166, 26, 57, -111, 99, 21,196,218, 76,243,246,246, 94,186,116, 41, 27, 27,219,207,159, 63,129,117,192,191,127,255, 4, 4, 4,222,191,127, 79, -204,230,103, 45, 45, 45,160,249,187,119,239,134, 44,251,129,236, 9, 24,114, 25,108,223,190,125,192, 64,216,178,101, 11, 25,165, - 63,188,172,188, 87, 94,142,167,171, 90, 90, 90,202,128, 99,249, 92, 89, 89, 25,254, 57,128,244,116, 65, 92,122,129,109,127, 98, -202,113,130,125, 32, 60,192,189,229, 51,156, 77, 82,233, 63,109,218, 52,242,162,163,167,187, 23,212,228,167, 0, 96,173, 44,225, -183, 79,143, 2, 60, 0, 32,128,112, 46, 3, 37, 40, 66, 83, 64,207, 29, 0,152,115,125, 68, 87, 51,100, 22,124, 32,189,156,100, -186, 22, 50,186, 5,169,156,208, 70,186,144, 5,241,251, 40, 58, 58,250,238,221,187,251,247,239,255,254,253,251,223,191,127,125, -125,125,129, 69, 57,241, 97,238, 10, 6,144,182, 27,145, 13,127,106,205, 1,224, 98,227, 41, 13,209,214,165, 16,179,155,137, 1, -126,212,207,189, 80,228, 96, 1,230,130,180,167,233,140,176,141, 96, 16, 41,172, 61, 45, 60,225,239,236,236, 76, 48, 65,146, 33, - 5,247, 47, 48, 70, 2, 3, 3, 33,167, 15,145, 10,152,194,223, 3,181,251,249,167, 65,218, 10,144, 69,159,200,199, 60,208, 2, - 24,199, 24,145,173, 23,216,192,199, 85,207, 65,164, 70, 1,126, 0, 16, 64,131,241, 48, 56, 50,154, 45,244,111,132, 82, 98, 35, - 37,167,188, 81,203,167,202, 96,128, 38,248,235,215, 47,102, 48,160,118,132, 78, 31, 32,189, 88, 18, 18,228,248, 48,194,160, 30, -122, 48, 20,114,239, 16, 88,250, 67, 42,218,193,185,197,148,194,189, 50, 96,237,132,135,222,169,190, 28, 19,255, 57, 63,180,171, - 44, 71, 7,133,128, 0, 32,128, 70, 47,133, 31, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,244, 70,176, 81, 48, 10, 70,193, 40, - 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 88, 70,131, 96, 20,140,130, 81,128, 12, 24, 49, 89, -255,225,196, 40, 24, 86, 0, 32,128, 70,123, 0, 35, 20, 96, 61, 28,124, 20,140, 2, 70, 48,102, 4,157, 1,205,136, 1, 70,247, -102, 13, 55, 0, 16, 64,163,151,194,143, 80,189,190,182, 51,135,183,127,227,252,116, 17,205, 28, 38, 38,200,114, 85,248,138,198, -255, 48, 0, 81,176,104,211,101,100,189, 31, 30,236,231,224,224,128,168,135, 28,160,141,172, 23,114,106,222,191,127,255,128,236, -223,191,127,243,202,218,141,128,116,197,200,204,194,254,255,223,159,127,255,254,108, 57,242, 4,121, 81, 40, 46,189,192, 32,122, -249,242,165,132,132, 4, 25,246, 82,162,119, 52,239, 51,144,178, 82, 11, 32,128,134,252, 16, 80,117, 53,226, 10,187,214, 86, 51, -250,233, 61, 5,186, 84,175,213,172, 21,206, 32,213,229,184,246,169,226, 18, 39,213,156,225,214, 87,253,245,149,229,237,125,213, - 31,151,164,255, 60,190,245, 95,241, 9,175,214, 55, 62,121, 54,110, 94, 92,234,143, 28, 57, 98, 99, 99, 3, 41,250, 33,133, 56, -164, 17, 11, 47,196,255,193,192,195,135, 15,209,244,158, 59,119,206,216,216,152,147,147,147,133,133, 5,168, 17,174, 29, 82,238, -255,133,129,159, 63,127,158, 61,123,214, 65,214,110,240,135, 30,208,229,111,223,190, 61,126,252,184,128,128, 0,218,198, 8,194, -125, 2, 70, 38,118, 14, 33, 1, 65,245,175, 95,158,126,249,252, 24,212, 13, 96,252,207,240, 31,223,136, 16, 48,148,214,172, 89, -115,235,214, 45, 32, 27, 24,140,197,197,197,196, 91, 7,209,123,239,238, 29, 96,152,179,177,179, 23, 20, 20,210,116, 23,194, 8, - 7, 0, 1, 52,136, 42, 0, 92, 39, 77, 50,224, 61,104, 12, 82,112, 35, 23,229,196, 3, 74,244, 14, 39, 64,225,222, 81, 58,148, - 94,159, 31, 94,255,120,104,213,183,111, 63, 21,204,153, 56,101, 24, 85, 31, 93, 50,101,184,248,254, 39,207, 5,174,184, 55,140, -210, 88, 53, 93,187,118, 13, 88,130, 0, 11, 59, 22, 24,128, 84, 6,144,134,255,159, 63,127,128, 37, 56,176,253, 14, 44,253,247, -237,219,199, 44,108,130,172,247,219,183,111,231,207,159,183,176,176, 96, 99, 99,131, 95,154, 6,212, 14, 44,155,254,128, 1, 80, -227,247,239,223,129,106,190,124,249, 50,152, 99,182,170,170, 10, 57, 19,125,254,252,217,192,192,128, 12,189,139,151,157,229,228, - 20, 3, 22,200,160, 10,128,145,225, 63,100,183, 0,238, 98,249,217,179,103,192,144,137,138,138, 82, 82, 82,130,156, 75, 33, 36, - 36,100, 98, 98,130, 85,113,130, 59,202,206,184,203, 55,110, 28,224,229, 42,234,111, 50, 52,210,121,254,228,213,174,109, 7, 20, -116, 12, 63,125,250, 56, 90, 88,147, 13,208,198,123,145,151,254, 3, 4, 16, 11,214,178, 0, 82, 10,224, 98,211,168,244,207,202, -194,126, 79,250,251,247,239,151, 47, 95,142,167, 14,128,148,224,164, 54,225, 41,212, 11,111,251,147,209,252, 71,187,121, 6,151, - 2, 26,133, 54,164,199, 0, 39, 33,130,239,222,129,118,205, 8, 9,237, 25,132,201,247,215,227,107,236,199, 22,255,252,246, 47, - 72,133, 89, 93,244,207, 63,161,255,172, 66,204,159,223,178,113,126,254,174,121,113,202, 89,181,140,111, 92,242,216,218,173,140, -215,175, 95, 7,150,224, 78, 78, 78,144,114, 28, 8,128,133, 56,228,234, 27, 96, 33, 14,108,191, 63,126,252,120,255,254,253,192, -154, 0,109,231, 27, 80, 25, 80,205,197,139, 23,129,245, 7,176, 1,203,206,206, 14,209, 11,169, 0,128, 26,129,165,219,229,203, -151,127,252,248, 65,112,211,220,131, 7, 15,128,182, 0, 75, 94,160, 27,196,197,197, 85, 85, 85, 33,131, 75,196, 0, 74,244, 2, -157, 90, 83, 83, 3, 63, 12, 21, 88,154, 3,107, 68, 49, 49, 49, 97, 97, 97, 34, 75,255,121, 73, 73, 94,134,134, 64,182, 68,110, - 46, 39,151,248,151, 79,143, 62,125,188,251,255,255, 95,208,129,113,255, 8,220, 65, 13, 44,238, 69, 68, 68, 22, 45, 90, 20, 31, - 31,191,105,211, 38, 32,247,208,161, 67,191,126,253, 98, 96,144,195,170,254,109,123, 17,156,205,243,235,183,212,159, 31, 5,165, -245,253, 61,141,221, 61,211,164,153,254, 78,235,233,115,138,136,194,165,119, 20,144, 84,250, 51, 32, 29, 5, 10, 4, 0, 1,132, -189, 7,128,124, 4, 10, 46, 54,213, 1,253,207,112,166,194, 0, 20,172, 14, 32, 9,192,235,212,249,129,139, 48,101, 19,215,199, -209,180, 25, 14, 49, 28,153, 36,120,109,247, 0,130, 31, 31,222,168,221,223,250,138,249,175, 10, 63,131,188,220,127,102, 61, 54, - 22, 37, 37,182,159, 63,126, 30,125,252,243, 35, 11,243, 63,214, 31,123, 22, 51,121,229,255, 99, 65, 31, 11,130, 95,126, 41, 40, - 40,232,232,232, 8, 44, 58,129,197, 40,176, 33, 15,105,248, 3,203,110, 96, 43,245,224,193,131, 76, 96,128, 85, 47, 80,229,213, -171, 87,109,108,108,248,248,248,128,218,129, 34,192,210, 31, 88,138,125,250,244,233,244,233,211,192,106, 0,104, 26,100, 38, 0, - 23,184,116,233,210,177, 99,199,238,223,191, 15,212, 2,180, 93, 66, 66, 2,216, 10,182,178,178,226,230, 38,188, 21,156,108,189, - 64, 39, 65,110,254, 65, 22,132,156, 11, 13,108, 69, 17, 83,133, 48, 49,179, 33,115, 95, 76,158, 44, 17, 32,211,221, 61,241,247, -239,175,224,192, 97,252, 7, 44,253,255,131,186, 0,255,113,143,191,157, 60,121,178,162,162, 2, 24,104, 65, 65, 65,178,178,178, -192,138,118,219,182,109,230,238,132, 54,253, 50, 50, 46,185,243,124,237,237,167,155, 54, 46,100,102,102, 44,202,141,213,151, 16, -153, 85, 80, 63,155, 24,189,163, 0, 71,233,143,220,228, 71,171, 15, 0, 2,136,132, 85, 64,180, 62,238, 81, 9, 55,160, 69, 19, -158, 66,189, 12,100,141,251, 83,189, 45, 15,191,204,146,248, 66, 28,171, 74, 96,219,159,200,230, 63,176, 16, 4, 22,127,152, 92, -100, 65, 76, 0, 87, 3,191,101, 16,147,139, 21,188,187,122,238,217,211, 79, 98,188, 44, 74,188,255, 89, 68,254,177, 88,122,112, -235, 47,230, 52,234,101,231,231,100,251,242,253,219,183,191,114,204,223,222, 95, 58,134,165, 20, 99, 98,130, 92,118,127,251,246, -109, 96,107, 29, 88,136, 11,131, 1,176,101, 42, 32, 32,240,241,227, 71, 96,155, 20, 88, 60, 65, 70,249,209,244, 66,196,129,197, - 46,176, 14,184,117,235, 22, 23, 23, 23, 80, 23,176,249, 44, 42, 42,202,195,195, 3, 20, 1, 86, 33,144,161, 33,204,202, 3,185, -253,190,123,247,238,187,119,239, 42, 42, 42,186,187,187,155,153,153,125,251,246,109,223,190,125,192,142, 5,176,250, 33,216,246, -223,189,103,239,189,231, 31,121, 85, 44,212,220,147,165,205,252,222,255,100, 2,138, 16,212, 11, 44,253,129, 21, 6,176,242, 0, - 22,193,122,122,122,240, 97, 28, 8,131, 96,233, 15, 44,250,185,121,164,132,132,117,150,174,184,148, 52,111,222,182,243,231,129, - 8,216, 3, 96, 0, 77,119,127,133,170, 97, 4, 34,124,235,129,128, 5, 61,176,213,159,147,147,195,203,203, 11, 12,186,181,107, -215, 2, 29,243,230,205, 27, 53, 53, 53,130,169,107,226,249,219, 61, 39,174,204,238,169,100, 97,254,206,244,247,115,215,132,121, - 43, 15,157,125,198,196, 66,234, 9,163,163,128, 72, 0, 16, 64, 44,196, 23,244,131,121, 42,102,196, 86, 3,144,161, 27,146, 70, -111, 48,187, 23,240,126, 0,193,158,199,231,207,159,129,205, 82, 96,179,218,212,212, 20,141,123,234,212, 41,136, 32, 86, 0,145, - 5,146,192,150, 41,176, 25, 11, 44, 26, 32,130,200, 92,172,128,239,199,219,109,143,126, 72,191,103, 54,228, 99, 20,125,205,160, -194,194,207,196, 40,252,255,199,203,175, 47, 25,175, 62,250,247,226,235, 15, 96, 25,204,240,239, 22,131,145, 59,174, 10,128,157, -157, 29, 88, 10, 75, 75, 75,187,186,186, 2, 75,118, 96, 17,249,246,237, 91, 96,145, 4,148, 2, 22,241,144,227,143,254, 97,232, -133,104, 7, 42, 0, 38,123, 96,199, 87, 69, 69,133,159,159,255,203,151, 47,231,207,159, 7,214, 10, 64, 51,127,130, 1,158, 86, - 17,176,122,123,242,228,137,190,190,190,131,131,131,140,140,204,215,175, 95,129,245, 7,176,155,123,252,248,113,130,131, 57, 64, -189, 47,223,125, 20, 82,179, 80,178, 13, 23,144, 81,251,249,245,195,163,147, 91,111,239, 93, 72, 80, 47,100,246, 2,216,185, 17, - 23, 23, 7, 22,184,192,154, 0, 82,244, 67,198,130,128,108,172, 55,228, 64,171, 61, 22, 14, 1, 65,117, 1, 33,117, 38, 38, 86, - 96,113, 63,119,254,254,164, 68, 71,136,222,212,212, 84,160,227, 33,122,193, 94, 6, 23, 5,216,166, 1,128, 1,187,121,243,230, -172,172, 44, 73, 73,208, 1,159,123,247,238, 5, 86,102,156, 96,224,237,237,125,236,218,119, 60,190, 94,118,243,113,239,233, 27, -115, 58,202,101,212,229,191,126,121,191,113,251,233, 75,151,111, 10,252,255,199,246,226,165,119, 78,244,209,171,223, 71,203,107, - 82, 1,218, 73, 63,152, 29, 2,128, 0, 98,193, 44, 11,224,135,220,226, 98, 15, 42, 64,118,193, 77,161, 94,178,199,127, 40,111, -245, 19, 35,133,167, 40, 39,123,213, 16, 48, 39, 3,139,251,247,239,223, 99,229, 18, 9,128,181, 5,176,252, 5, 22,250, 10, 10, - 10,152, 92, 76,240,250,205,227, 99,207,191,123,115,113, 29,126,252, 79,202,136, 93,241,231,217,247,215,178,214,119, 93,250,247, -224,227,151, 95,255,159,126,254,203,201,194,244,231,227, 11,126,108,237, 24,120, 29, 0, 44, 49, 31, 62,124,120,227,198, 13,109, -109,109,160,131, 79,156, 56, 1, 25,217,199, 53,136, 15,212, 11,233, 4, 64,244, 2,235,128,199,143, 31,235,234,234, 2,139,111, - 96,253, 1, 20, 1,138, 67, 86, 7,225,233, 1, 60,122,244, 8,104,190,177,177, 49,176,244, 7, 42, 6,118, 65,204,205,205,129, - 86, 3,197,129, 53, 7,254, 80, 2,170,249,199,196, 38,109,224, 2, 44,253,153,152, 89, 57,249, 68,229,204,189, 31,158,216,132, - 95, 47,208,157, 31, 62,124,120,250,244,169,156,156,156,181,181, 53,208, 82,200,200, 79,124,124, 60, 68, 1,176, 14,195, 99, 41, - 7,135,176,176,168,254,175,159, 31,223,188, 61,255,243,231,251,223,191, 65,243,219, 16,189, 47, 95,188,128,235, 5,181,254,113, -212,122,207,159, 63, 95,186,116,105,116,116, 52, 48,172, 24,192,215,209, 0,123, 3,149,149,149,192,218, 8,166, 4,231,242,196, - 91,159,190,149, 31,188,208, 81,146,110,235,227,242,245,203,155, 85,235, 14,206,156,187,118,123, 81,130,210,171, 39,157,159, 94, - 8, 9, 9,227,209, 59, 10,136, 28, 11,194,172, 18, 0, 2,136, 5,235, 80, 12, 65,246, 32, 7,148,175,209, 36, 6,180,152,182, -208,255, 6, 49,228,178, 27,173, 50,160,198, 97,144, 56,193,205,155, 55, 97,243,120, 88,184, 36, 1, 96, 17,188,123,247,110,200, - 37, 30,200, 92,172,221,252,139,239,190,127,252,245,239,226,235, 63,207, 62,252, 17, 63,193,162,183,234,206,195, 7, 87,111,158, -252,245,135,133,249,215, 63,134, 31,191,254,191,255,255, 79, 84,240, 63,214, 66, 28,190, 0, 20,178,140,231,229,203,151,242,242, -242,192,122, 11, 50,236, 3, 36, 17, 27,156, 8, 1,248,166, 1, 8, 57, 56,111,142, 3, 86, 78,144, 91, 80, 20, 21, 21,145, 43, -182, 51,103,206, 0, 73, 96,240, 66, 46,221,195,117,237, 15, 48,180,128,228,247,111, 47,191,124,126,252,247,239, 15,100,189,155, -192, 85, 53,176, 27, 4,210,251, 31,251,216, 63, 48, 30, 39, 79,158, 12,108,230,219,216,216, 0,185, 71,143, 30,221,176, 97, 67, -118,118, 54, 82,233,143, 19, 60,255,246, 51,118,219,137,130, 48,239,144,216,224,111, 63, 62,173,223,116, 96,194,180,101,139,220, - 76,129,165,255,104,217, 77,245,154, 0,185, 14, 0, 8, 32,106,238, 4, 70, 30,137,198,197, 30, 78, 96, 48,148, 2,144,177,123, -226,199,127,240,204, 25,224,143, 35, 96,241,225,234,234, 42, 40, 40,136,149, 75, 18, 0,234, 2,234,133, 23,247,104, 92, 52,240, -253, 47,223,111, 70,134, 51,111,126,190,250,251,119,239,189, 31,171, 86,255,216,247, 68,244, 14, 27,255,147,143,191, 31,127,254, -247,245, 15,195,183, 63,255,217,133, 37,112, 21,217,144,149,254,127,255,254,253,243,231,143,176,176, 48, 15, 15, 15,176, 14,248, -253,251, 55, 68, 4,109, 59, 24,178, 94,200, 74,127,160,154,239,223,191, 3,185,178,178,178,192,150,181,164,164, 36,176,218, 0, -182,193,129, 53, 31,196,100, 60,227,162,192,102, 56,176,175,112,246,236,217, 39, 79,158, 64,174,225, 60,121,242,228,151, 47, 95, -128,226,192,206, 7,254, 32, 2,170, 97,250,247,235,233,249, 61, 31,158,220,250,247,247,247,247, 79,175, 31,157,220,250,235,235, -123,252,122,225,142,249,246,237, 27,124,118, 26,216, 9,184,122,245, 42,176, 28,135, 92,218,254,241, 35,206,245,148, 64,191,254, -249,253,133,147, 91,130,131, 83, 8,178, 35, 24, 89,239,236,217,179, 33,122,255,161, 6, 24,176, 3,183,104,209, 34, 96,235,161, -169,169,201,207,207,207,199,199, 7,210, 21,216,188,121,115,105,105, 41,176,203,133,199,155, 64,189,139, 23, 47,142,200,202,113, - 90,115,176, 36, 46, 40,175, 44,243,199,175, 47,247,239, 62,158, 57,115,213, 6, 95, 43, 7, 89, 49,226, 19, 21,176,178, 25, 45, -220,241,143, 5,193,203,125,228,121, 96,128, 0,162,254, 81, 16,152,183,167, 98,178,169,220,222,199, 88,200,143,220,228,199,223, -252,199,212,123, 10, 40, 84, 93,141,201, 38,102, 8,136,120,189,212,234, 13,192, 23,243, 16,223,252,127,247,206, 5, 62,115, 64, - 82, 7, 66, 65, 65,193,215,215, 23,216, 12,196,202, 37, 18, 0,213, 3,117,193, 7,124,208,184, 88,212,171,170,168,114, 51,243, - 50, 50,252,254,255,255,250,251, 95, 75,239,252, 92,126,236,217,233,187,239,158,125,103,120,251,227,239,221, 47,255,159,255,252, - 47,171,172,130,181, 52,132,172,218, 4, 22,214,192, 66, 28, 88,118,235,232,232,128,171, 76, 33, 51, 51, 51, 72, 33, 14, 41,199, - 49, 11,113, 72,225, 14,172, 39,128, 10,128,213,188,178,178,242,135, 15, 31, 30, 63,126,252,238,221, 59,160, 83,129,189, 10,160, - 56,208, 4,136, 50, 92, 46, 55, 53, 53,149,145,145, 1, 22,160, 59,118,236,216, 2, 6,135, 15, 31, 6, 54,204, 45, 45, 45,241, -204,121,192,245,138, 11,241,191,189,119,225,230,238,249, 87,183, 78,191,190,117,230,195,227, 27,216,153,254,225,215, 11,172,156, -128,205,109, 62, 62,190,139, 23, 47, 2,107, 29,228,106, 0,210,150, 95,186,116, 41,158, 18,249,215,207,143, 31, 63,220, 97,101, -229, 22, 16,210,224,230,145, 6, 50, 32,125, 2, 32,120,118,114,234,254, 69,121,174, 26, 95,192, 21, 0, 3,116, 27, 24, 56,216, -182,110,221,202,201,201, 9, 52, 22, 24, 50, 22, 22, 22,240,174, 64, 76, 76, 12,176, 35,130,223,155,219,182,109,229,227,227,177, -179, 55, 55, 48,210, 11,204, 74,250,198,248,231,245,171,119, 25,185,205,157, 38, 42, 70, 98, 36,180, 45,128,165,127, 87, 87,215, -104, 29, 64, 76, 53,128, 38, 2, 16, 64,116,218, 8, 54, 32,141,101,242,198,232,205, 90, 91,145,203,110, 32,151,234,122,225,109, -237,196,245,113,120, 20,208,122, 79, 22,220, 22,228,157, 1,248,181, 0, 75, 31,103,103,103, 96, 25,138,201, 5,150,170,248, 66, - 6, 44, 11, 36, 13, 13, 13,129,229, 20, 92, 16,153,139, 21, 72,171,105,233, 94, 61, 43,255,254,227,155,191,255, 62,253,248,195, - 14, 44,173,127,254,145,227, 97,121,255,231,207,211,175,160, 21, 68,222,170,226,220, 10, 90, 95,176,141,135,192, 87,124,234,234, -234,234,235,235, 3, 11, 38,200,194, 77,160,179,129, 69,213,250,245,235, 33, 27, 2,128, 34,140, 24,122, 33,187,189,128,233, 86, - 77, 77, 13, 88,127,188,126,253, 26,178,132, 20,104, 26, 80,228,213,171, 87, 16,189, 64, 17, 60,245, 37,176,103, 3, 89,202, 9, - 44,145,225, 75, 57,129, 46, 33,184, 26, 7,164,215,197, 25,164,247,238,201,103,231,119, 67,245, 90, 59, 17,212, 11, 44,253,141, -140,140,142, 30, 61, 10,212, 43, 45, 45, 13, 52,135,155,155,187,170,170,106,210,164, 73,192,174, 15,208,246,190,190, 62, 92,119, -196, 3,171,188,143,239,239, 0,139,117,126, 33, 53, 9, 41,203,239,223,223,124,249,244,176,187,103, 82, 99, 67,149,148, 12,195, -242,124, 46,198,176,247,142,113, 12,144, 26, 19,190, 17,248,214,173, 91,192, 52, 96, 99, 99, 3, 52, 31, 88,229, 0,229,166, 76, -153, 18, 30, 30, 14,169,110,241,131,155, 55,111,133, 4,251, 71, 68,248,233,232,170,191,253,252,241,203,199, 55,105,121,205,205, -129,206,206,255,190,145, 84,250, 79,152, 48, 1, 24, 41,192, 90, 39, 55, 55, 55, 32, 32, 96,180,160, 71, 30,240,193, 90,238,195, - 1, 64, 0,177,208,167,160, 39,184,130, 40, 36, 36,132,188,157,192,184, 0,242, 70, 45,242,234, 0, 82, 75,127,226,245,226, 95, -117, 67,235,163, 29,224,227, 69,112, 91,144,247, 4, 16, 4,192,114, 16,121,181, 15,156,139,103, 9, 16, 92, 22, 77, 13,126, 45, - 16, 32,165,168,252,195,204,246,207,169,109, 15, 62, 50,240, 48,178,202,243, 48, 61,253,203,200,204,206,114,232,213,223, 31,255, - 24, 68,217,153,149, 77,236,190, 8, 42, 96, 43,206, 64, 77,120, 96,139, 27,216, 14, 5,150,137,159, 62,125, 2,150,221,144, 10, - 0,216,126, 7, 86, 90,192, 50,107,243,230,205,144,225, 32,180,108, 0, 20,129,108, 27,214,212,212,132,140,222, 0,245, 66,210, - 54,164,223, 0, 20, 7,246, 6,190,124,249,130, 63, 97,235,233,233, 1, 75,100,242, 54,115,145,167, 23,232,108, 41, 41, 41,119, -119,119, 96,173,115,227,198,141, 71,143, 30, 1,107, 59, 1, 1, 1, 96, 85, 52,103,206, 28, 92,123,113,145, 70,129,190,125,120, -127,243,199,143,119, 2,130,106, 60,188,178,188,124,114, 95, 63, 63,237,232,156, 27, 25,225, 2,172, 0, 96, 1,251, 31,185, 6, -240,242,242,218,182,109, 27,176,195, 1, 12, 16, 63, 63,191,133, 11, 23, 2,235,117, 13, 13, 13, 98,252,232,237,237,181,126,253, -230, 79, 31,222, 62,121,246, 60, 63, 59,174,180,162, 45,208,201,202,230,231, 39, 6, 86, 98,203, 37, 96,233,223,208,208, 0,233, -134, 2, 59,106,192,126, 64, 89, 89,217,104, 29,128,191, 62, 64, 6, 0, 1, 68,205, 10,128,194, 21, 68,100,148,242, 16,240,230, -205,220,234, 83, 27,177, 14,248, 16,156,254, 5,234, 61, 85,189, 17,173,193,142, 60,140,131,167, 28,127, 51,247,205,169,141,213, -228,233, 29, 40, 48, 20, 79, 13, 82,176,114,188,244,243,207,235,125,123, 89,255,124,191,244,249,255,158,207,127,216, 24, 25,133, -255,255,119,148, 20,176,119,115, 22, 50,118,192,209,158, 5,245, 0,128, 77, 96, 96,121, 4,108,194, 3, 11,122, 96, 49, 10, 41, -196, 33,141,119, 81, 81, 81,107,107,235,157, 59,119, 98, 14,227, 0, 69,128, 85, 5,176,185, 13, 84, 15,108,213, 66,186, 17, 12, -176,121, 5, 32, 23,168, 0,216,171, 56,113,226, 4,193,105,112, 5, 48, 32,211,227,100,233, 5,214, 1,192, 18, 31,232, 60, 96, - 15, 0,216,233, 1,246, 93,128,130, 79,159, 62,245,244,244, 4, 54,255, 9,106,255,251,247,231,215, 47, 79,127,253,250,200,249, -233, 1,159,128, 50, 23,143, 20, 16,237,218,251,146,209, 89, 28,214,152, 3,147, 48,245, 86, 86, 86,192,128, 5,150,254,192,154, - 64, 88, 88, 56, 46, 46,238,192,129, 3, 68, 58,213,210,210,138,157,157,157,239,218,217,236,236,100, 25, 53,213,174,130,228, 5, -211, 22, 78, 97,254, 65,124,233, 95, 94, 94, 14,244,236,179,103,207, 56, 57, 57,129,145, 2,236,238,180,182,182, 86, 87, 87,143, -214, 1,240, 49, 31, 96,161,143,231, 40, 8,128, 0,162,114, 15, 96, 64, 86, 16, 97, 45,212,136,108,254, 99,234, 69,110,191, 67, -198,115,112,149,227,148,232,197, 83, 22,147, 90, 70, 15,251,147,224,128, 37,154,129,179,187,176,148,204,235,235, 87,152, 31,222, - 83,249,253,156, 87, 88,220, 74, 87, 67,219, 88,231,187, 4,206,253, 65,192,146, 26,216,246, 7, 54,243, 33,131,245,192,174, 0, -144, 1, 57,206, 1, 62, 58, 36, 43, 43, 11,172, 3, 48, 11, 44, 96,105, 98, 96, 96, 0,172, 3,128,229, 59, 68, 37,124, 81, 13, -252, 36, 56,160, 81,134,134,134,103,207,158, 29,156,129, 6,116,188, 24, 24,168,171,171, 3,253, 11,172,198,128,222, 7,134, 70, - 53, 81,243, 82,255,127,255,250,252,251,215,151,239,223, 95,179,179, 11,178,178,241, 50, 49,177, 44, 89,186, 53, 38,218, 27, 90, - 11,162,170,134,116, 44,122,123,123,129, 21, 45,144,161,166,166, 70,252,181,210, 70, 70,198,204,166,166, 73, 13, 16,189,255,213, -212,212,213, 2, 2,240,143, 10, 34,131,206,206,206,209, 82,158,152, 58, 0,107,233, 15, 4, 0, 1, 52,108, 47,132, 33,123,233, - 39,114,145, 77,106, 19,158, 18,189,163, 0, 63,144,213,212, 6, 34, 32, 3,126,246, 38,254,125, 65,161,161,161,130,130,130,144, -165, 62,192, 18, 16, 50,164, 3,233, 1, 64, 38,126, 33, 7,130, 42, 43, 43, 3, 5,143, 92,249,138,172,119,194,132, 9,171, 87, -175,134, 40, 0,157, 20,132,227, 56,104, 96,203,151,224,160,202, 32,169, 65,121,192,128,196,230, 2,164, 26,248, 12, 44,253,129, -102, 0,131, 13,162, 23,215,152, 23,228,200, 79, 72, 80,147,228, 60, 96, 48, 23, 22, 22,146,161,119,180,153, 79,124, 29,128, 75, - 10, 32,128, 70, 47,133, 31, 5,163, 96, 20, 96,148, 11, 12, 12,232,135, 61,252, 31,189, 17,108, 24, 2,128, 0, 26,189, 18,114, - 20,140,130, 81,128,209,248,103, 24,189, 1,114, 68, 0,128, 0, 26,189, 18,114, 20,140,130, 81, 48, 10, 70, 40, 0, 8,160,209, - 10, 96, 20,140,130, 81, 48, 10, 70, 40, 0, 8,160,209, 10, 96, 20,140,130, 81, 48, 10, 70, 40, 0, 8,160,209, 75,225, 71,245, -142,234, 37,172, 55, 61, 61,221, 63, 32,125,227, 6, 44, 71,110,140,134,213,128,235,109,133,173,184,195,181,200,117,244, 82,120, - 92, 0, 32,128, 88,208, 82, 57,166, 10, 34,215,141, 13, 42,189, 68,106, 31, 40, 55, 15, 30, 64,246,153, 19,212, 61,136, 20, 15, -128, 92, 57,112,240,224, 65, 32,219,222,222, 30,255,229, 1,180, 11, 37, 96,233,239,229,105, 4, 57, 70,111,216,111,188, 24, 90, - 0, 88,250,251,250, 42,195,217,213,213,213,163, 97, 66, 60, 0, 8, 32,244, 85, 64,255, 87,161,156,193,196, 24, 70,194,105,239, -104, 25,131,164, 19, 64, 41,209,139,230,102,146,156, 61, 80,110,134,128,119,175,239,188,126,253,252,229,155, 47, 31, 63,254,230, -231,103, 21, 23,225, 17, 21,149, 20, 18, 37,234,120,181,115,199,167,221,187,123,235,238,131, 31,143,159,255,151,149,100, 84, 86, -224, 80, 82, 86, 51,178,204,162,127,181, 1, 57, 91,148, 70,197,226,229,203,151, 13, 12,118,204,152,241,237,192, 1,134,250,250, - 93,143, 31, 63,150,144,144,224,224,224, 16, 21, 21, 85, 82, 82, 34,163, 50, 56,124,248,176,184,184,184,188,188, 60,193, 35, 57, -145, 1,176,244, 79, 75, 75, 99, 96,152,181,113,244,192,177,193, 7,126,253, 42,223,185, 51,205,221,125,150,175,111, 39,164, 55, - 48, 90, 13, 32, 3, 60, 27,193, 0, 2,104,152, 44, 3,133,151,248,140,140, 12,255, 86, 10, 14,126, 7,255,254,245,245,241,163, -203,191,126,253, 86, 81, 20,112,176,145, 19,224,103,127,255,225,199,211,231, 95,110,223,123,254,225,227, 27, 89, 57, 93, 86, 54, -156, 87,191,190,127,115,235,216,193,217,204, 12,159,194,189, 25,172,141, 25,148,229, 25,238, 60,248,127,228,204,247,109,251, 47, -110, 93, 91,106,101,159, 42, 40,162, 70,164, 51,200,110,251, 35,107,132, 28, 36, 71,163, 58,224,221,187,119,121,121,223, 68, 69, - 25, 66, 67, 25, 58, 58, 64, 23,114,253,249,243, 7, 88, 1,136,137,137, 1, 43, 0, 96,159, 64, 74, 74,138,160, 33, 47, 94,188, -120,245,234,213,203,151, 47, 93, 93, 93,151, 44, 89,194, 0,222,235, 27, 21, 21,133,255, 0, 59,100,176,109,251, 57, 96,233, 15, - 38, 71,193,224,106,254, 3,201,224,224,181, 59,119,130,200,180,180,187,144,222,192,104, 87, 0,179,232,135,139, 32,215, 1, 0, - 1, 52, 76, 42, 0, 96, 39, 0, 82, 7, 12,137,210, 31, 8,158, 60,186, 44, 46,194, 97,106,168, 8,190, 95,137,241,223,191,255, -124, 60,236,220,202,108, 10,178,252,215,110,190, 1,202, 42,170, 88,224,210, 11, 44,253,109,141, 63, 21, 36, 50, 48, 51,131, 42, -188,223,127, 24,184,185, 24, 52, 85, 24, 44, 12, 24,182,236,255, 4,148,245, 14,238,166,233, 16, 16,214, 75, 37,105,116,229,131, -144,144,208,150, 45,156,178,178,223,129, 61,128,247,239, 89, 84,192,224,203,151, 47,247,238,221, 59,112,224,192,167, 79,159,128, -229, 56,254,126,192,245,235,215,207,157, 59,199,202,202,138, 44,248,253,251,247,185,115,231, 2, 13,137,136,136, 32,198, 25, 27, - 55, 0,189,156, 14, 38, 73, 0,240,123,146, 33,199,222,161,113,241,196, 8, 3,210,137,129,120,184, 56,219, 67,255,255,139,188, -125,171,244,224,129,240,211,167, 79,196,196, 30, 41, 41,125, 20, 19,251, 79,244,137,188, 64,119, 18,115, 78, 31, 30, 45,248,185, -212,210, 11, 31,252, 73, 75,219, 9,100, 64, 72,136, 20,144, 49, 90, 7, 96,109,245, 67,142, 6,130,139, 0, 4,208,176, 90, 5, -196, 56, 68,220,249,238,245,157,223,191,127,155, 25, 73,194, 69,152,152, 24,217,216,152, 57, 57, 88, 88, 89,153,148, 21, 5,129, - 61, 3,160, 26, 92, 35, 63,192,182,127, 97, 18,195,143,159, 12,247, 31, 51,188,255,200,240,225, 19,195,178, 77, 12,185, 13, 12, - 85, 61, 12, 86, 70, 12, 76,255, 63, 1,213, 12,155, 56,213,213,213,221,184, 81, 83, 76,140, 33, 42,138, 69, 66,194, 20, 88, 94, -251,250,250,250,248,248,184,187,187,139,139,139, 3, 75,246,149, 43, 87,222,189,123, 23,215, 69,137,151, 46, 93,186,112,225, 2, - 90,233, 15, 7,251,247,239,191,122,245, 42,158,178,248,208,161, 67,240,210, 22, 82,250, 67,216, 64,113, 98, 42,188, 83, 48,128, -149, 75,100,253,138,159,139,181,244, 87,186,113,195,118,207, 30,217, 91,119,216, 62,125,146,188,117, 67,103,203,102,209,139, 23, - 25,136,190,211, 27,232, 66, 96,177, 11,236, 51, 17, 31, 77, 16, 45,120,184,248,245, 34, 23,247,120,184,184, 0,164,220,135,144, -191,124, 85, 24, 70, 1, 82,209,143,255,172, 7,128, 0, 26, 44, 61, 0,170,180, 31,255, 83,195, 94,242,134, 50,224, 55,109, 17, - 51,198,242,250,205,115,117,101, 33, 72,185,143, 38,197,193,206,242,225,227, 79, 53,101,161, 91,247,158, 99,157, 12,184,119,247, - 86, 56,232, 72, 46,134, 29,135, 24,166, 46,102,112,179,101,240,114, 96,184,113,135,225,252,213,255,156, 28,140,134,218, 12,238, -246, 12,235,118,222, 50,178,164,213, 16, 16,214, 32,162,221,141,111,192,214, 61,176,189, 15,100, 0, 91,250,214,214,214,112, 65, - 65, 65, 65, 77, 77, 22, 63, 63, 96, 31,232,204,173, 91,223, 24, 24,128,129,194,142, 57,242,115,249,242,101, 92,165, 63,188, 14, -192,117, 71, 74,116,116,244, 82, 48, 0, 50,224,254, 5, 22,253, 64, 17,136, 44,125,242, 2,126, 46, 38,224,123,249, 82,241,228, -201, 95, 76, 76,172,140, 12,127,254,253,255,247,251,239,191, 63,127, 68, 15, 31,250, 40, 34,242, 83,134,216,149, 36,192, 98,247, -202,149, 43,134,134,134, 6, 6, 6,196,107, 65,238,220,160,113,137,236, 70,144, 90,250, 99, 22,247, 59,145,250, 1,163,128, 32, - 0, 8, 32,244, 10, 0,115,250,148,200, 66, 13, 87, 97, 74,140, 94, 90,140, 29, 19,185, 76, 5,235, 4, 50,145,122,209,148, 17, - 63, 23,253,242,245, 23, 71,107, 57, 96,131,236,240,241,199,223,190,255, 6,138, 24,233, 75,136, 10,115, 62,126,250,249,206,253, -247, 44, 44, 76,170, 74,130, 71, 79,126, 85,215,196,162,247,238,131, 31,214,198, 12, 63,127, 51,108, 63,200,176,255,248,127, 41, -113, 70, 37, 57, 6,103, 27, 6, 13,101, 70, 22,102,208, 57,234, 22, 6, 12,221, 51,127,224, 31,240, 33,200,192,211,106,128,143, -248,163,141, 75,208,110,109,204,163, 71,143, 24,192,231,227, 35, 11, 62,120,240, 64, 75,235, 85, 85, 21, 40,224,219,218,110, 61, -120,160,205,192,134,126, 50, 40, 80, 13,254,210, 31,162, 6,151,148, 29, 24, 64, 74,124, 72,161, 15,175, 24,224, 23, 26, 83, 29, - 80,216,252, 7, 2,129,235, 55,126,253,254,205,196,196,244,159,153, 25,116, 41, 2,228, 64,187,191,255,216, 47, 93, 34,190, 2, - 96, 0,223, 43,121,244,232, 81, 96, 87, 85, 90, 90,154,152,137, 22, 10,235, 0,242,218,254,192,226,222,125,150,123,240, 90,134, -180,157, 32, 6,144, 11,169, 21,216, 54,223, 25, 45,220,209, 0,214,123,225, 1, 2,136,240, 42, 32,226,215, 5, 97,182, 10,137, -108, 39, 98,173, 39,136,175,120,176,186, 28,207,229,233,184,138,105,248, 4, 50,145,122,177, 42,131,152, 6,108,216,255, 91,133, -115, 54, 2,188,230, 7,212, 92,125,252,236,211,247,239,160,107,173, 84,148, 4,129, 21,192,197,171,175,110,222,126,199,193,193, -172,172, 40,240,254, 35,246,131,230, 31, 63,255,175, 44, 15, 50,223,195,142,193, 64,139,145,157,141,225,207, 31, 80, 63, 64,128, -151,225,222, 35, 6,119, 59, 6,121, 25,144, 26,154,166, 36,120,185, 79,228,144,244, 64, 1,172,131, 24,164, 58, 21, 82,214,195, - 43, 0,154,150,254,112,128,235,234,118, 60, 87,186,195, 1,235,221, 59, 63,127,255, 98,100,102,249,251,255, 63, 48,157,252,249, -251,239, 55,176, 35,240,247, 47,227,237,155, 12, 12, 94,164,186, 4,216, 15, 0,118,164,184,185,185,249,249,249,137,175, 3,136, - 28,252,161,176,244,175,174,174,110,109,109, 5,150,254,240,202, 0, 72, 2,171, 1, 96,233,191,121,243, 93,200, 4, 0,100,150, - 88,207, 46,126,180,244,199, 44,253,129, 0, 32,128, 6,203, 16, 16,214,194,148,200,130,152,164,181,170,216, 77,160,210,218, 33, -160, 75,136, 49,138,159,159,245,253,135, 31, 34, 66, 92,161,126, 26,192,252,201,206,206,204, 12,108,175,253,255,239,227,166,236, -237,170, 12, 52,225,237,251,239, 64, 53, 88,245,202, 74, 50,222,125,248, 95, 67,153,193,201, 18, 52,228,117,227, 14,131,158, 6, -131, 32, 31,131,167, 3,195,191,127, 12,192, 78,192,173,251, 32, 53,248, 3,153, 32,131,248,141, 36,148,140,155, 17, 3,128,237, - 87, 96, 11,244,238,221,187,192,150,184,173,173, 45, 15, 15, 15,228,196, 96, 5, 5,133, 83,167,196, 26, 27,159, 50, 50, 50,190, -122,165,166,166,166,112,237, 25, 22,189,104, 34,171, 86,173, 66,105, 52,252,255, 31, 30, 30, 78,124, 29, 64,183,210,159,140,186, - 1, 14,222,201, 72,179,221,184,249,159,149,129,237, 31,104,222,247,247,223, 63,191,254,255,253,246,231,207,119, 21, 13, 50, 28, -163,163,163, 3, 12,127, 34, 75,127, 6,240, 53,159,192, 38, 63,188,248, 70,227,226, 2,144, 94, 2, 92, 25, 26,151, 32, 0, 54, -255, 33, 69, 63,144, 68,110,251, 67,102,137,129,149,193,104,233,143,181,244, 7, 2,128, 0, 26, 14,171,128, 8,246, 60, 8,130, -255,255, 25,152,194,223, 83, 94, 7, 64, 22, 35, 49,133,189,199,211,252, 7, 2,113, 17,158,199, 79, 63, 3, 43,128,190,233,167, -237,172,100,141,244,196, 25, 89, 25, 33,203,129, 32, 43, 53,128,178, 64, 53, 88,245, 42, 43,112, 28, 61,251, 29, 88, 1,136, 24, - 51, 84,100, 50,228, 39, 48,240,243,130, 70,126, 26, 39, 49, 52,228,131, 20, 28, 61, 11, 82, 67,210, 64, 25,229,139, 65,105,183, - 12,244,205,155, 55,144,123, 16,183,110,221,250,232,209, 35, 15, 15, 15, 69, 69,197,207,159, 63,191,127,255,254,250,245, 63, 7, - 14, 0, 11, 11, 19, 71, 71, 71, 25, 25,153,107,207, 94,163,233, 5,182, 91,241,223,216,245,231,207,159,193,150,152,225,165, 63, -158,106, 0,127, 29,240, 73, 75,155,253,210,165,127,255,255,115, 51,177, 48, 51, 51,254, 1,150,254,191,127,127,254,245,235,183, -190, 62, 73, 46,225,226,226, 34,105, 14, 0, 94,220,227,226,210,162, 14, 0, 54,243,211,192,109,124,228,210, 31,222,252, 31, 5, -248, 75,127, 32, 0, 8,160,209,227,160, 97,173, 69, 42,173, 31,133,214, 1,120,171, 19, 81, 81,201, 59,247,159,233,107,139, 85, -228, 91, 44, 88,126,153,147,131,197, 64, 71, 12,126,157,242,191,127,255,239,220,127, 47, 46,134,125,212, 85, 73, 89,109,235,190, -139, 9,193, 12,255,239, 49, 88, 4, 49, 40,201, 50, 44,221, 8,147,203,103,248,251,151, 97,235, 62,144, 26,218, 5, 20,214,254, - 25,237,150,129,222,184,113, 67, 83,243,254,252,249, 64,230,223,166,166, 75,235,214,125, 83, 87, 87, 7, 86, 0,247,238,221,123, -249,242,165,145,145, 17,176, 9,143,107, 25,168,146,146,210,233,211,167,241,220, 49, 66,228,245,188,240, 33, 32, 32, 73,235, 30, - 0,176,100,135, 20,253,184,134,128,112, 73, 33,106, 53, 25,153,183,182,118,127,247, 31,248,197,198,202,243,159,229,199,191,127, - 31,127,253,250,236,228,252, 95, 78,142,232, 14, 49, 35,176,252, 37,126,232, 31,174, 5, 94,220,163,113, 73,170, 3,112,173,157, -197, 3,208, 74,127,248,200,207,232,108, 48,254,210, 31, 8, 0, 2,104,180, 2,160, 38,128, 78, 0, 16, 26, 5, 18, 18, 85,249, -240,241,205,201,179,207,204,141,165, 60, 93,148,118,236,189,183,117, 23, 40,213,214, 20, 91, 1, 75,127,160, 56, 59, 59, 27,174, -253,192, 70,150, 89, 91,215,150,246,207, 3,173, 4,157,209, 2, 90,253,233, 98, 13, 90, 9,218, 95, 11, 42,253,251,231, 49,252, -101,224, 35,126, 63, 48,169,109,118, 92, 61, 6,218,173, 2,250,250,245,171,161,225, 15, 72, 73, 98, 98,242,127,199,142,123,183, -110,221,130,108, 4,115,112,112,176,183,183,199,179, 9, 64, 89, 89,249,242,229,203,184, 58, 1,192,230,191,177,177, 49, 49,110, -128, 44, 6,133, 44, 10, 2,178,137,175, 3,208, 54,154, 17,185,239, 12, 94, 7,224,146, 37,160,159,137,233,151,185,249, 27, 41, -169, 47,151, 46,241, 60,122,244, 67, 81,241,171,182,246, 95, 89, 89, 6,162, 47,219, 34,175,236, 70,214,130,198,197,239,113,100, - 89, 52,123, 73,117, 6, 4, 32,151,251,144,222, 0,169, 67,154,195, 12,224, 89,211, 1, 16, 64,163, 21, 0,150,213, 59,116, 48, - 74, 86, 78,247,241,163,203,107,183,220, 84, 81, 20,244,118, 83, 22, 20,224,120,255,225,199,249,203, 47,129,109,127, 96,233, 15, -148,197,163,215,202, 62,245,240,193,217,199,206,126,242,118, 98,152,221, 14,218, 9,124,247, 33,195,220, 85,160,182, 63,176,244, - 7,202, 82, 94,160,147, 81,250,211,104, 14, 64, 66, 66,226,193, 3,145, 51,103, 64,195, 59,183,110,241,153,154,106, 9, 11, 11, -195,119, 2, 19, 60, 10,194,194,194,226,224,193,131,140, 24,123,160,128,165,191,138,138, 10,176,134, 32,166,244, 71, 30,253,135, -116, 5,136,172, 3,200, 46,206,112,149,242,132, 75,127, 88, 29,240, 79, 94,254, 27, 16,145, 21,230,100, 20,187,248,125,138,223, - 64, 74,244,226, 47,253, 65,139, 68, 71,252, 4, 0, 3,182,253,192,240, 42, 1, 32,128, 8, 47, 3, 37,126,138,149,152,101,160, -196,235, 37, 94, 59, 37,246, 98,245, 29,121,246,146, 52, 23,205,202,198,173,164, 98,241,238,245,157,123, 15,158, 31, 63,243, 4, -126, 22,144,184,152, 20,193,179,128, 4, 69,212,188,131,187,207, 29,159,182,114,235,173,182,169,116, 61, 11,136,206,165, 63, 16, -168,171,171, 95,188,232,149,152,120, 6,220, 3, 48, 9, 11,211,231,226,226, 34,169,254, 8, 15, 15,191,121,243,230,153, 51,103, -152, 65,115,237, 76,192,162,159,141,141, 13,216,246, 7,154, 76,106,233, 79, 70, 29, 48, 10,104, 13, 64,107,129,210, 90,221,103, -185, 99,221, 19, 48, 58, 25,128, 31, 0, 4, 16, 11, 37, 3, 2, 52,213, 75,164,129,131,202,205,164, 2, 96, 89, 15, 68,234,100, -233, 5,150,245, 68,238,246,162,150, 47,232,182,135, 3, 25, 0,139,123, 75, 48,160,176, 22, 33,166,184,199, 4,152,101, 61,144, - 13,217, 22, 48, 90, 1, 12,170, 58,128,225, 33, 22,113,147,106,147, 17, 30, 50, 4,175,124, 7, 8,160,209, 75,225, 71,193, 40, - 24, 5,163, 96,132, 2,128, 0, 26,189, 17,108, 20,140,130, 81, 48, 10, 70, 40, 0, 8,160,209, 10, 96, 20,140,130, 81, 48, 10, - 70, 40, 0, 8,160,209, 10, 96, 20,140,130, 81, 48, 10, 70, 40, 0, 8,160,209, 10, 96, 20,140,130, 81, 48, 10, 70, 40, 0, 8, -160,209, 75,225,169,163, 23,207,177,104, 52,213,123, 15, 12, 86,175, 94, 77,134,222,251,247,239,223,189,123,151, 60,189,163,105, - 99, 84,239,168,222,161,162, 23, 15, 0, 8, 32,156, 27,193,136, 60, 5,147,234,122,169, 14,210, 66, 63, 50,176,177,205, 90,202, -137, 71, 13,176, 12,197,179,247, 18,191,155,225,122,123,123,123,139,139,139, 73,186, 45, 29,174,247,202, 84, 62,157,236, 79,100, -220,180,174, 39, 60,229,255,155,191, 64,198,172, 89,179,192,151,214,146, 0,204,212, 87,252,249,244,137,147,147, 19, 88, 7,132, -134,134,210, 46, 10,136,220, 87,129,213,191, 3,165, 23,151,105,244, 73,192,140,140,140, 76, 96, 0,217,194,246,235,215, 47,102, -240,217,206,255,255,255,103, 24, 5,163,128,122, 0, 32,128, 88,112,165,117,172, 73,141,145,208,173,114,144, 76, 66,158, 94, 98, - 90,196,100,131,221,187,119, 51,112,104,226, 41,133,203,203,203,197,196,196,208,164,128, 5, 58,126, 99, 33,122, 33, 69,255,137, - 19, 39, 32,213, 0, 73,122,255, 93,171, 99,210,106, 90,180, 15,116, 92, 1,144, 13,145, 2,138, 16,244, 17,223,167,162,127,255, - 25, 86,236, 0,105,244,180,103,213, 86,185, 10,172, 3, 64, 21, 30, 17,213,128,176,220,169,215,183, 95, 28,190, 38,255,245, 39, -183,167,251, 7,105, 9,198, 51,103,142,125,250,244,195,201,201,137, 70,233,140,166,141, 6, 60,122, 9,150,152,196, 39, 75, 82, - 1, 48,126,187,186,186, 74, 75, 75,137,217,111,140, 12,128,101, 61, 11, 24, 64,118,174, 1, 19, 9,208,144,191,127,255,254, 1, - 3, 32,131, 70, 14,222,186,117, 43,254,192,241,242, 34,124,154,244,182,109,219, 72, 82, 63, 10,232, 6, 32,251,129,209,214,253, - 3, 4, 16, 11, 73,165,191,177,177,241,217,179,103, 9,102, 66,172,153, 10,143, 94, 52,115,128,101, 49,100, 88,131,236, 3, 38, -211,124,103, 49,112,170,205, 90,229, 0,106, 26,175,230, 7,149,254,132, 74,112,204,179,227,129, 37, 56,254, 83, 89,224,122,129, -108, 96, 11,218, 2, 12, 72,210, 11, 41,241, 33,100, 7,108,183, 54,176,244, 47, 11,230,232, 90,251, 3,143, 7,249,191, 23,235, -168, 49,127,253,254,191, 40,150,227,196,213, 63,223,191,254,255,246,139,193,209,224,234,213, 91,127, 9,118, 5,238, 61,238, 63, -119,154,155,151,143, 81, 66, 82, 92, 84, 92,229,225,221, 95, 10, 90,191, 89, 57, 94,237, 89,255,102,253,250,245,129,129,129,163, - 89,133, 42, 0, 24,191,190,190,190,192, 58, 0, 45, 13, 27, 25, 25, 53, 54, 54, 2,165,176,183,200, 88, 88,216, 96,224,241,227, -199,170,170,170,192,106,128,151,151,247,206,157, 59, 60, 60, 60,167, 79,159, 62,126,252,120,118,118, 54,206,148, 15,142,122,120, -254,133,231, 68,136, 8,144, 11,105, 37, 96, 5,155, 54,109,194,212, 2, 23, 1,114,137, 41,208, 55,110,220, 72,146,122,170,128, - 23, 47, 94, 72, 72, 72,140, 38, 57, 60,229, 62, 46, 0, 16, 64, 44, 36,149,254,248,109,194,115, 80, 9,254, 35,206,209, 74,255, -142,142,142,138,138, 10,184, 8,241,117, 64,154,241, 44, 6, 97,181, 89,187, 28,224,173,126, 87, 87, 87, 32, 3, 66, 98,142,139, - 33,151,224, 88, 75,127,204, 62, 1,166,167,224, 45,125, 96,141,133, 28, 20,196,232,197,218,210, 7,150,254,248,189, 41,242,189, - 72, 85,158,153,147,157, 81, 94,138,249,205,251,127,191,255, 48,191,253,240,255,227,151,255,119,158,252, 99, 96, 98, 16,225,186, - 4,244,151,146,146, 18, 86,189,255,254,175,214, 84, 86, 58,254,226,165,162,156,168,142,158, 18, 51,187,144,188,226,251,247,223, -127,188,122,241,247,201,203, 31, 92, 44, 64,173,250,184,244,210,110, 68,136,248, 40, 38, 79, 47,102,139,132,214, 99, 41,192,112, - 4, 90,170,165,165,181,121,243,102,228,232, 0,102, 34, 60,165, 63, 16,176,178,178,114,112,112,188,121,243, 70, 77, 77,205,208, -208, 16, 88, 31, 76,154, 52, 9,216,234,215,213,213, 93,183,110, 29,176, 2,184,116,233, 18,176, 74,192,213, 15,240,247,247,135, -248, 23, 87, 46,198, 83, 40, 3,203,110, 72,200, 96,109,192, 1,197, 95,190,124, 73, 76, 5, 64,146,122, 72,241,189,127,255,126, -172, 82,142,142,142,196,148,236, 64,237, 82, 82, 82,234,234,234,163,213, 0,169, 0, 32,128, 88, 48,115, 23,174,246, 59,125, 28, - 4,204, 45,192,210,159,200, 10, 3,231,104, 15, 67, 26,144, 92, 61,203,140,129,237, 59,158,209,127,180, 18, 28,173, 50,195, 95, -130, 67, 0,188,242, 56,113,226, 4,114,243,159, 24,189,203, 74,121, 48,115,105,116,207, 87,252,186,254,253,251,199,206,197,200, -196,196,192,197,201,240,225,211,191,159,255,255,115,115, 50,254,248,199,240,253,231,127, 25, 81,166,127,127, 24,110, 63,254,187, -103,207, 30,172,157,128, 79, 31, 79, 8, 8,112,179,177,253, 79, 77, 48,255,251,247,255,139, 87,191, 30, 61,253,192,192,250,152, - 83,240,231,243, 87, 15,152,216, 62, 94,187,246,225,233,203, 61,164,206, 37, 80, 56, 34,132,124,179, 24, 49, 0,249,196, 61,204, -251, 59,113,129,119,239, 92,224,108, 33,161, 61,184,138, 72,130,245, 13,178, 8,158,186, 7,152,180,124,124,124, 32,229,254,213, -171, 87, 33, 12, 72,219, 31, 40,142,199, 70,118,118,246,175, 95,191,106,106,106, 2,203, 62, 96, 66, 74, 78, 78, 6, 10,254,254, -253,123,193,130, 5,192, 14,244,185,115,231, 86,174, 92,249,253,251,119,204,187,110, 32,192,219,219,155,236, 72,153, 59,119, 46, -254, 74,148,152, 22, 61,220, 16, 34,213, 51,128,207,107, 2, 22,223,207,158,161, 95,232, 3, 20, 36,190, 64,127, 6, 6,163,213, - 0, 38,128,143,249, 96,237, 10, 0, 4, 16, 11, 49,173,120, 74,138, 99, 82, 1,114, 59,154,168, 86,255,172,116, 6, 73,134, 89, -190,160,172, 56,235,108, 26,124,180, 7,220,234,255,136,220, 15,192, 95,130,191,122,245, 10, 94,106, 19, 89,130,227, 7,144,122, - 5, 88, 94,224, 58,108, 3, 79, 1, 4, 25,255,193,212, 11,212,242,230, 90,145, 36,120,240, 7, 34,242,253,239,255, 31,191, 24, -126,131,185,191,255,252,255,207, 4, 98, 92,190,116, 22, 88,143, 50, 48,176,161, 25,251,241,227, 85, 86,118, 65, 17, 33,129, 15, -239,190,125,248,248,225,196,153, 23, 79, 95,254,103,227,254, 38,173,242,229,251,183, 55,170,122,191, 21, 52,127,174,156,125,246, -206,157, 59, 12, 12, 28,163, 57,135,194,230, 63, 16, 0,155,255,192,226,126,203,150, 45,218,218,218,161,161,161, 4, 75,127, 72, - 5,240,250,245,107, 46, 46, 46, 59, 59,187,158,158, 30, 96,135, 0,152, 12, 22, 46, 92, 8, 44,253,129,141,140,189,123,247, 94, -190,124, 89, 68, 68, 4,207, 85, 54,192,250, 27,215, 16,208,236,217,179,241, 88, 77,149, 33, 32,160, 33,100, 12, 1, 1, 75,109, -204, 10,128,140,227,155, 70,171, 1, 82, 1, 64, 0, 13,174,227,160, 49,239, 21, 33,114,112, 0,212,222,175,184,207,192,204,150, -230,166,192, 32,160, 48, 11,124,241, 31,254,209,127,170, 12, 98, 64, 38,126,225,109,127,100, 0,153, 21,192,236, 94, 16,217, 98, - 93, 90,194,141,217, 27,224,253, 84,252,224,215,255, 23,111,128,173, 63, 38, 30, 46, 80, 87, 29, 88,232,255,248,201, 0,172, 3, -128,228,175,223, 12, 63,190, 51,252,250, 9,107,129,162, 86, 30, 60,127,138,158, 62,146,147, 85,228,249,207,202,242,230,251,247, -253, 7, 31, 95,187,243,244,221,187, 47,218,198,127,191,254,248,243,227,231,223,239,223,254,189,120,196,240,253, 43, 67,119,119, -247,232, 9, 81, 88,123, 42, 68, 38, 72, 72,243, 95, 75, 75, 11,216,240, 7, 86, 6,192, 10, 0,210, 9, 32, 88,250, 67,134,128, - 12, 12, 12, 56, 56, 56,128,133,126, 82, 82, 82,123,123, 59,176, 36, 61,121,242,228,193,131, 7, 47, 93,186,244,241,227, 71, 85, - 85,213, 79,159, 62,225,185,229, 38, 32, 32, 0,179,109, 1,233,241,224,239, 31, 12,212, 16, 16,214, 78, 0, 73,205,255,209,106, -128,108, 0, 16, 64,131,162, 2,128, 12,253, 67,186,201,200,117, 0, 60,179, 65, 6,235,137, 31, 41,134,148,251,192,134, 63,120, - 20,136,109,214, 82,234,187, 25,178,242,199,197,197,101,207,158, 61,184,186, 50,184,122, 51, 88, 11,119, 98,198,130,226, 43,191, - 74,137, 51, 69,249,178, 1,139,123,126, 94, 70, 38, 70,112,195,159,225,255,143,111, 12, 95,127,253, 7,118, 11,190,254,248,255, -239, 63,246,155, 63,226,243,191,234,234,223,147,208,120,183,123,251,171,119,239,126, 24, 88,126,210, 19,250,194,192,250,243,199, -183,127,175,158,254,255,250,149,241,207, 31, 70, 33, 17, 70, 6,198,127,163,185,130, 42, 0,146,158,145, 39, 84,128, 53, 1,114, -209,140,117, 38, 0, 88,178,151,149,149,177,176,176, 44, 90,180,104,254,252,249,137,137,137, 29, 29, 29,192, 18,249,193,131, 7, -223,191,127, 7,102, 19, 96,219, 63, 35, 35, 3,207,226, 37,178,167, 94, 7,106, 8, 8,107, 39,128,188,211, 91, 71, 1,169, 0, - 32,128, 6, 75, 15, 0,121,216, 26,179,160,199, 85,200, 34,131, 89,103,211, 96, 69,255,237,213,147,238,131, 87, 1, 33,234, 3, - 60,163, 64,148,140,240, 0, 29, 6,111,254, 67,122, 3,112, 54,176, 7, 0,217, 99,133, 57,249, 76,176,244,135,172, 2,194,212, -251,231, 47,195,215,111,255,127,254, 2, 77,249, 2, 73, 22,118,168, 32,176, 2,248,254,251,255,219,119,255, 95,191,255,127,238, -218,159,127,255, 64, 67,121, 87,159,162,152,249,231, 15,195,179,199,191, 30,223,125,127,228,248,123, 96, 35,239,218,141,127, 62, - 81,127,216, 88,254,191,126,201,112,100, 23,195,167, 79,255,255,255, 99,176,113, 98,228,224, 96,240,244,244,199,191,210,112,195, -130,244,128, 4,138, 86,232, 82,114,131, 24, 73,247, 46,192,129,144,208, 30,186, 37,102,180, 4, 12,228, 26, 25, 25,157, 59,119, -110,243,230,205,200,226,184,166,130,129,109, 11, 1, 1, 1, 72, 35,122,222,188,121,192,126, 0,176, 38,128,212, 28, 64,169, 15, - 31, 62, 0,123, 0,223,190,225,187,235, 37, 53, 53, 21,121,232, 6,210,252,199, 63,254, 51,176, 67, 64,104,157, 0, 74,154,255, - 16,237,163,109,127, 34, 1, 64, 0, 13,150, 10,224,236,217,179,184,214,174, 0,197, 9,172, 31,101,231, 94,173,112,136,225,207, - 89, 6, 69,238,180, 86,197, 89, 7,128, 29,237, 89,176,202,192,149,248, 81, 32,228,149,160,152,171, 66, 49,115, 56,176, 20,131, -148,254,200, 51,192,144,182, 63,132,139,181, 7, 0,215, 75, 94,201,114,251,246,237, 71, 87, 38,253, 19,253,199,196,194,192,202, - 4,202,105,191,255,253, 7, 22,238,159, 63,255,255,245,155,225,207,111, 80,125, 80, 88, 4,234, 78, 93,125,250, 4, 83,239,195, - 91, 19,181,181,255, 29, 62,248,151,145,137,225,245, 11, 70, 14, 78,134,131, 59, 24,126,125, 7,150, 16, 12,122, 70,172,207, 30, -253,179,183,247, 6,230, 91, 60, 59, 9,129,165,127, 87, 54, 67,217, 84,242,235, 0, 74, 46, 16, 38, 79, 47,174, 97, 13,250, 0, -200,202, 31, 31, 31, 31, 72,212, 67,186,179,192,102, 62, 86,197,255,254,253, 59,127,254,188,173,173, 45, 92, 4, 88, 7, 64,202, -226,223,191,127,255,253,251, 23, 24,137,162,162,162,184, 38,129,225,163, 64,100,180,223, 7,112, 8, 8,173, 19, 64,118,243,127, -180,232, 39, 21, 0, 4, 16,105, 21, 0,176, 32,166,197, 78, 72, 72, 99, 25,152, 43,128, 12, 23, 23, 23,180,182, 63,164, 24, 37, -126,171, 42,124, 21, 16,132, 75, 76,219, 31,121, 6, 24, 2, 32, 92,200, 98, 80,252,122,225,165, 63,218,124, 0, 49,122,113, 1, - 96,243, 31,151, 94, 85, 85,213,249,115,126, 59, 91,176, 2, 11,128,223,191,254,177,179,129,242,234,231,175,255,127,254,254, 15, - 44,250,207, 94,249,251,247,223,127, 92,235, 56,129,122, 23, 47,252, 99,239,192, 28, 24,205,252,229,243,255,207, 31, 25,190,126, -102, 84, 84,253,255,247, 55, 35, 11, 19,199,135,119,255,158, 61,249, 85, 82,232,131,191,237, 63, 33,159, 65, 77,142, 97,114, 17, - 67,110, 31, 69,117, 0,217,125, 2,242,244, 82,190,238,147,188,148, 15, 44,253, 27, 26, 26,144, 27,251, 93, 93, 93, 64, 46,174, -221, 97,191,126,253, 2, 22, 97, 63,126,252, 96,102,102,134,220,125,182,118,237,218,224,224,224,239,223,191, 3, 5,127,254,252, -201,195,195, 3,172, 6,240,123,135,188,181, 64, 3, 59, 4, 4,239, 4, 64, 24,163, 69, 63,125, 0, 64, 0,145, 80, 1, 80, 88, -250,227,209, 14, 44,244, 33,165, 60,100,220, 28,190,228, 20,185,225,143, 86, 49,160, 0,102, 70, 6, 54, 38, 6, 78,102, 6, 30, - 22,134,159,159, 87,183,179, 50,112,158, 74, 11, 81,100,224, 20,154,181,152,168,134, 63,214, 53, 63,144, 18, 28,255,162,120,228, -210, 31,121, 62,128, 24,189,248, 75,127, 60,122,219, 58,103, 20,229,103,112,112, 0, 91,139, 12,186,234,204,208,176,186,252,247, -247,223,255,127,255, 49,151,148,148,224, 49,188,169,101, 70, 73, 73, 6,176,199,240,235,247,255,191,127, 24,128, 93, 8, 7,111, -134,207, 31, 24,111, 92, 4, 22, 48, 76,126,190, 65,248, 75,255,134,100, 6, 21,240,145, 36,202,210, 12, 20,246, 3, 70, 2,192, -220,243, 5, 90,217, 5, 6,184,180, 0, 43, 0, 96, 89, 15,218,142,161,175,255,231,207, 31, 86, 86, 86, 96,155, 26,216,136, 1, -150,254,223,190,125, 3, 54,255, 5, 5, 5,241, 44, 3,133, 3,248,128, 42, 49,131, 63,131, 97, 8, 8,222, 9, 32, 35,156,137, -220, 46, 48, 10, 48, 1, 64, 0, 17, 91, 1,208,168,237,143,181,107,143, 57,224, 67,182,213, 4, 71,255, 41, 41,253, 25, 80,103, -122,225,117, 24, 3,120, 53, 45, 65,189,184,102, 2,136,209,219, 55,113, 6, 48,184,152,152, 24,142,156, 5,141,248, 67,102,125, -193, 67,255, 37, 4,245,246,244,204,200,200, 4,111,248, 96, 2,105, 57,117,136,225,235,151,127,255,255, 49,248,249,121,187,187, -187,227, 41,253,203, 99, 24, 4,120, 24,158,189, 97,224,100,103,248,247,159,129,155,131,161, 53,157,161,122,230, 48,175, 3,112, -117, 47,136, 73,147,104,165,127, 70, 70, 6,164,232,223,188,121, 51,176,148,196, 90, 13, 0, 43, 0, 38, 38, 38, 96,123,246,243, -231,207,103,206,156, 49, 52, 52, 4, 86, 3, 31, 63,126,188,120,241,162,162,162,162,176,176, 48,176,244, 7,138, 16,236,208, 64, -118,132,145,212, 33, 24,240, 33, 32,242,218,254,100,235, 26, 5, 64, 0, 16, 64,232, 21, 0,174, 37,255, 68,174,126,163,164, 7, - 13, 84,128,121, 40, 27,193,210,112, 86,218, 76,208,104,207, 45, 6, 16, 66,128,143, 96,116,159,108, 55, 19, 83, 10,195,125, 4, - 44, 35, 32,251, 9,128,213, 6,169, 87, 25, 3,245, 46, 45,225,134,212, 7,164,222,208, 11, 15, 46,200,172, 47,241, 29,142, 25, -211, 17,122,191,124, 2, 21, 16,126,126,126,132,195,106, 9,245,139, 81, 90,235, 29,192,161,127, 6,212,105, 94, 96,128, 3,203, -196, 45, 91,182, 96, 74,161, 85, 0, 64,101,192, 6, 62,144, 33, 39, 39,247,225,195,135,218,218, 90, 96, 5, 32, 45, 45,253,229, -203, 23,160, 32,100, 38,128,160,213,100,140, 2,189,120,241,130,114, 47, 83,197,144, 81, 64, 55, 0, 16, 64,131,226, 82,120, 56, - 0, 22, 97,100,152, 67,246, 10, 31, 42,246,105, 8, 30,253, 70, 70, 87,128,152,224,194,202, 38, 85, 47, 49,165, 63, 37,205,252, -129, 74, 87, 84,137, 95,242, 12,129, 31,231, 9, 63,209, 83, 83, 83,115,222,188,121,255,192, 0, 79,251, 29,210,186, 7,170, 1, - 22,244,144,195,224,192, 21,252, 63, 58, 28, 6, 55, 10,134, 55,192,186,185, 7, 32,128, 70, 47,133, 31, 5,163, 96, 20,140,130, - 17, 10, 0, 2,104,244, 70,176, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32, -128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70, 43,128, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128,176, 92, 10, -143,124, 36, 3,242,125, 44,200,226,195,248,146,101,228,165,168,112,191,143, 94, 72, 61,180,194,138, 36,141,248,237,109,109,109, -133, 48,170,171,171, 71, 90,252, 82, 61,168, 71,243,209,128,232,197, 3, 0, 2,136,106,103, 1, 65, 78,244, 36, 78, 45, 27,166, - 94, 56, 27,237, 52, 80, 34,239,223,160, 16,192,175, 5,134, 20,103,240,251,243,232, 80, 3,223,186,117, 11,126, 39, 65, 81, 81, -209,224, 63, 4, 17, 45,172,174, 95,191,206, 0, 94,227, 72, 83, 75,129,201,192, 63, 32,125,227,134,153,104,201, 96,219,246,115, - 64, 65,172, 9, 3, 40,133,213, 40, 47, 79, 35,226,237, 5,150,254,190,190,202,112, 54,174, 58, 0, 23,248,252,229,243,189,103, -247,190,253,255,198,192,200,192,246,143, 85, 78, 84, 94, 84, 88,148,160,174, 99,199,142, 33,115,173,172,172, 70, 27,170,163,128, - 70, 0, 32,128,168,121, 24, 28,145,151,168, 92,125,250, 1, 83, 16,173,204, 69,222,142,136,191, 56, 38,114,151, 16,158,202, 3, - 98, 2,164, 68,195, 92,160, 13,145,197,186, 88, 22,217,106,105, 69, 89, 32,249,242,199,143, 63,223,193,231,241,127,248,196, 0, - 62,191, 8,223, 9, 22, 96,128,124, 33,101, 95, 95, 31, 49, 23,160, 51, 49,130, 54,226, 66, 72, 32,192,202,152, 62,131, 38,149, - 37,114, 88, 65,138,126,226,195,138,236,250, 27, 82,250,131, 11,110, 80, 29, 64,188, 81,144, 10, 3,163, 2, 32,205, 25,191,126, -149,239,220,153,230,238, 62,203,215,183, 19,210, 27, 32,178, 26, 56,114,245,136,188,161,108,114,112,130, 32,151,224,191, 63,127, -127,252,255,185,227,228,174,125, 7,247, 90, 41, 89,115,112,112,224, 41,253, 51, 51, 51,145, 69,166, 79,159, 62, 90, 7,140, 2, - 74, 0,242, 93, 96,104,217, 19, 32,128,168,124, 26, 40,218,185,152,100, 0, 50,142,236, 34,184, 45, 30, 79, 91, 30,126, 11, 49, -144, 13, 33,209,100,137, 58, 72, 82,128,239,210,189, 21,156, 12, 50,127, 25,142,190,154,115,238,226,221,183, 65, 29,243,105, 23, -157,151, 46, 95,209,211,213, 1,150,245, 87,174,128, 24, 64, 17, 8, 3, 46,242, 15,111,120,224,191,241, 17,207,165,225,144,176, - 74, 72, 72, 0,178, 33, 36,122,233, 15, 12, 40,108,113, 1,148,114,118,222,158,158,238, 73,118, 29, 0, 44,253,193,206,158,181, -113, 3,225, 34, 30,174,133,212,178, 30,179,249, 15, 36,131,131,215,238,220, 9, 34,211,210,238, 66,122, 3, 4,187, 2,192, 52, -179,255,230,190,236,156, 76, 19, 81, 67, 78,126,254,255,191,254,252,251,255,151,153,133, 77,197, 69,229,134,241,205,142, 89,157, -230, 34, 22,144,131,222,176,130, 55,111,222,192,217,222,182,220,230,249, 71, 35, 58,127,192, 69,156,156,156,136,247,194,134, 13, - 27, 48, 79, 6,165,131, 94,170, 0, 50,174,122,135,236, 67, 30, 61, 25, 2, 87,233, 15,225, 34,215, 1, 0, 1,196,130,220,181, - 39,133,205,134,105,211,171, 87,175,224, 39, 33,227,169, 33, 24,216, 53,240,148,209,140, 24, 69, 54, 49, 67, 49,120,138, 45, 60, -119, 9, 0, 11, 38, 96, 35, 29,179,220,135, 92, 74, 12,175, 24,240, 0, 96,195,255,233,251,143,235, 50,130,133, 25,173,239,206, - 46, 81, 10, 84,218, 77,227,210, 31, 8, 32,133, 62, 16,232,232,232,192, 69, 32,125, 2,184, 8, 37,109,124,172,197, 52, 36,172, - 48,203,253, 5, 11, 22, 0,195,202,211,218,112,251,209,243, 12,188,220, 12,159,190,208,194,203,224,241,156, 89,184, 70,117,240, -131,128, 79, 85,216, 11, 56,190, 54, 98, 6,127,210,210,118, 2, 25, 16, 18, 34, 5,100,224,175, 3,206,220, 56,147,156,146,104, -171,234,240,247,231,207, 63,127,255, 48,178, 0, 19, 48,243,127,134,127, 47, 95, 63,211, 20,213,168,202,168,106,233,106,113,214, -193,217, 53,188,112,225, 2,162, 2,144, 90,128, 86,232,239,219,183,143,200, 58, 0, 88,130,111,171,221,238,213,204, 64, 70, 57, - 14,212,219,213,213, 85, 86, 86, 54, 32,117, 0,176, 28,191,121,243,230,179,103,207, 34, 35, 35, 73,210, 8,212, 53, 90, 1, 96, -111,246,149,131,138,178, 89,157, 21,104,226, 0, 1,132,168, 0,224, 19,188,104,231,242, 99, 21, 71, 59,107, 30,185,122,128, 28, -163,134, 60, 28,132,124,224, 26,176,134,192, 28, 34,192,188, 64,131,152,161, 27,170,128, 85,171, 86, 97, 22,253,144, 81, 14, 72, -233, 15, 20,193,163,253,201,189, 71, 95,215,215,241, 36, 77, 4,214, 4,226,194,156,247,214,223, 3,149,254, 2,124,160, 33, 32, - 86,102, 98, 28, 0, 12, 46,248, 40, 16,145,231, 73, 0,203,122, 57,110,134, 41, 49, 12, 41, 11, 24, 68,185, 24,174,127, 64, 23, -185, 74,196,141, 41,152,213, 42,193,142, 84, 83, 83, 19,102,209, 15,100,116, 37,248, 76,222,113, 66, 66, 73,242,197,195,151,184, -154,255, 64, 6,158, 78, 0,193, 81, 29,112, 75, 63, 29,173,189, 15,169, 15,136, 73, 33, 93,203,176,120, 77, 45,131,168, 20, 2, - 41,247, 33,228, 47, 95, 21,182,205,119,240,171,255,246,253, 27,151, 26,167,133,164,249,207,175, 95, 89,216,217, 89, 88,160, 89, -236,222,157, 59,155, 54,110, 76, 74, 76, 80, 96,151, 51,180, 55,120,114,229,137,140, 36,225,105,189,214,109, 9, 7, 15, 30, 12, - 9, 97, 64,238, 1, 16, 83, 7, 64, 74,127, 6,133,254,109,181,133,164,214, 1, 64,189, 19, 38, 76, 80, 83, 83,155, 60,121,114, -110,110, 46, 61,235, 0,120,209, 79,158, 94,136, 70, 50,186, 14,195,187,249, 15, 41,253, 33, 12, 96, 29,128,220, 9, 0, 8, 32, -106, 14, 1, 1, 11,119,200,232, 48,176, 38, 64,174, 0,224, 92,252,183,172,224,154, 10, 38,152,201,195,194,194, 40,119, 60,188, - 64, 68,107,248, 67,174,162,196, 53,171,254,157,225,209,151, 64,243,255,188, 37, 12, 46,181, 95, 24,150, 51,204, 1, 21, 73,255, - 87,151,176,198, 77,254,243,135,168,187, 21,129,217,140,212, 74,238,213, 60,134,198, 25, 12,178, 50, 12, 47,183,176, 45,156,251, - 43, 97, 5, 22, 17,202,199,205,240, 0,248,148,239,243, 13, 29,188,218, 28, 60,170, 5,171, 58, 82,244,117, 36,212,125, 90,240, -132, 21,158,120,199, 63, 64, 4, 73, 12,240,210, 31,200,133,204,253, 18, 91,156,241,181, 17, 89,214,163, 1, 96,113,143, 38,178, - 19,169, 31,128, 11, 60,127,245,220, 45,212,141,151, 79,240, 47,227,159,195, 7, 15,125,254,242,197,215,207,239,245,171, 87,107, -214,174, 75, 78, 76, 96,231, 96,103,250,207,234,110,228, 62,105,255,100, 98, 42, 0, 32,120,255,158,228, 27,208,224,165, 63,136, - 67, 98, 29, 0,212,219,208,208,160,162, 2,242,187,178,178, 50,221,250, 1,148, 20,253,200,205,127, 8, 99,180, 2, 32, 18, 0, - 4, 16,149,231, 0,128, 5, 61,228,118, 23,228,139, 18, 33, 39, 36, 19, 51, 55,128, 57, 21, 76,204, 16, 16,174,171,119,137, 7, -144,102, 62,230,152, 15,254,230, 63, 16,236,168,108,240,109,239,251,227, 98, 13, 12, 71,158,227,119,118,223,125, 11, 20,252,227, -146,251,251,178, 8,163,104, 22, 49,101, 31,254,206, 16, 86,240, 54, 96,121,110,226,227, 91, 25,101, 95,247,254,146, 16,193, 46, - 66, 70, 15,128,200, 90, 1,216,240, 7, 53, 37,124,237, 78, 60,123,197,171,207,251,116,231, 93, 6, 14,246,224,220, 56, 33, 25, - 31,218, 37, 83,204,149, 63,228,117, 16,177, 14, 34,225, 90, 23, 4, 44,238,221,103,185, 7,175,101, 72,219, 9, 98, 0,185,196, -116, 2,190,252,248, 44,194, 41,252,231,199,183,255, 76,255, 77,205,204,214,175, 95, 63,161,175,239,223,255,255,209, 49,209, 66, -194, 66,223,190,124,249,243,247, 15, 47, 43,223,111,166,223, 68,186,249,195,135, 15,240,117, 65,196,204, 6,163,148,254, 16, 64, -116, 29, 0,212, 11,204, 5,102,102,102,112, 17, 29, 29, 29,200,120, 23,237,234, 0,202,139,126,228,230, 63, 3,248, 82,248,209, - 78, 0,145, 0, 32,128, 88,240, 20, 70,120,196,241, 28, 33, 7, 25, 38,130,204, 6, 67,102, 5, 32,221, 2,160, 56,242,116, 2, - 45,138, 6,178, 1,174, 17,127,130, 55,209, 7,205, 88,251,223, 79,241,165,165,145, 48,131, 53,103,240,228, 63,207, 95, 51, 8, -240,177,188, 93,190,101,194, 89, 6,102,102, 98, 28, 79,198, 89,199, 23,139, 34, 77, 12, 24,148,114,175,104,243, 36,222,148, 15, -101,152, 82,134, 41, 66,187, 30, 0, 48, 76,108, 77,213, 93,172,213,124,117,203,122, 39, 76,191,118,246,105,134,147,201,139,141, -219, 62,190,255, 68, 70, 92,160, 13, 16,225, 74, 87, 88,155,252,228, 69, 61,166, 57, 88,231,138,129, 69, 30,176,224, 3,150,254, -240,202, 0, 72, 2,171, 1, 96,233,191,121,243, 93,200, 4, 0,100,150, 88,207, 46, 30,173,110, 5, 29,222,249,143,225,255,191, - 63,236,156, 28, 49,177,177,141,245,245,226,226,226,210, 18, 18, 63,190,126,249,251, 31, 40,254, 23,207,117, 46,192, 34,126,205, -154, 53,111,223,190,253,244,233, 19,188,170,134,175, 11, 34,184, 34, 8, 88,130,247,166, 92,101,224, 80, 97,120, 49, 21, 69,130, - 67, 5, 40, 94, 60, 7, 95, 29, 0,212,235,239,239, 15, 44,241,129,182, 35,139,203,201,201, 1,197, 7,124, 78,152,200,230,255, -104, 39,128, 36, 0, 16, 64, 44,152,217,137,140,141, 96, 16, 0,185,181, 17,185, 19, 0, 41,241,129, 34,240,101,227, 64,169,239, - 68, 55, 75,137,153,254,165,124, 25, 40,164,153,143,117, 42,152,160,177,119,187,211, 88,131, 39,127,127,118,139,229,248,228,223, -107,115, 25,189,122, 54,101,133, 60,220,116,223,183,107, 17, 3, 11,173,238, 91, 46, 91,205,176,179,107,189,246, 67,119,134, 55, - 95, 75, 93,203,176,138,144,209, 3, 32,190,249,191,113,125, 3,179,180, 22, 15,131,218,163,131,179, 62, 51,254, 63,117,235,177, -203,149,167,120, 67,254, 17,108,176,110, 38,188,196, 7,130,189,123, 61,209,100,177,166, 43, 92, 3, 62,100, 44, 45, 37, 99,105, - 16,176,249, 15, 41,250,129, 36,114,219, 31, 50, 75, 12,172, 12,208,212,243,114,242, 62,251,248,204, 76,193,252,251,207, 31, 12, -223,127,252,249,245,187,170,188,156,145,137,225,219,215, 47,192,122,225,207,223,255,236, 44,172,175,191,188,102,253,203,134,203, -198, 16,216,144, 63,176,225, 15,201, 83,240,117, 65,207,159, 63,199,239, 90, 96, 25, 13, 44,229,129,101,189,166, 34,138,249,215, -239,255, 42,158,163,141,191, 4, 7,202, 2, 75,121, 96,243, 31, 88,226, 35,139, 95,185,114,101,227,198,141,180, 43,253, 37,192, -128, 42,163,255,112, 48,218, 9, 32, 18, 0, 4, 16, 53, 11, 41,120,245, 0, 44,250,129, 21, 0,100,240, 7,179, 86,216,127,254, - 3, 49,101, 52,241,121,155,146,101,160,240,230, 63, 90,209, 15,169,174, 8,186,225,226,221,183,191, 47, 55,190,100, 56, 42,225, -213,195,240,241,211,221, 89, 37,202,153,253, 47,230,151, 48,176,178, 64,175,233,162, 1,120,244,149, 65, 83, 44, 16,191, 8,141, -122, 0,192, 96, 9,119, 49,231,255, 39,248,141,129,117,109,127,238,180, 45, 23, 74, 61,108, 18,250,150,133,180, 45,166,209,116, - 61,164,130,135,237, 3, 32,173,214, 39,105,192, 7,107, 39, 32, 13,220,198, 71, 46,253,225,205,127, 92, 64, 74, 76,106,199,225, -157, 86,178, 86, 92,220, 60,255,254,253,103,250,255,231, 31, 35, 35, 48,180,129,109,255, 63,255,254,255,249,243,231,251,199,175, - 91, 79,111,149, 23,147, 39,198, 13,200, 43,130,170,115,173,189,165,238,205, 58,205, 64,106, 29, 64, 76,233, 15,215, 11,244, 93, - 87, 87,151,164,164, 36,180,137,115,247, 46, 48,210,233,208,246,167,164, 26, 64,107,254,143,118, 2,136, 7, 0, 1, 68,171,141, - 96,144,226, 30,185, 86, 32,242,198, 18,180,188, 77,100,177, 66,222, 50, 80,204,230, 63,241, 69, 63,116, 8,168, 99,254, 58, 6, - 6,143,118,239,255,171, 75, 24,195,122,129,245, 1,163,144,224,157, 39,159, 64,205,127,102,102, 26,197, 25,230,170,127,146,246, - 1,224,169, 20,241,215, 10,144,230,127,138,131, 94, 65,207,196,202,170,114, 81, 62,177,171,215, 30, 37, 92, 91, 70,235,149, 90, -152,165, 54,124,232,140,184,229, 67,132, 7,124,240, 0,180,210, 31, 62,242,131,107, 54,152,131,131,131,229, 1,235,254,135, 7, - 66,117, 67, 62,253,248,196, 8,106, 6, 0,241,191,191,127,255,255,251,243,135,155,157,247,216,199,243,183,143,223,113, 53, 34, -253, 22,163,187,169, 12,196, 45, 3, 69,212, 1,146,143,174, 63,151, 35,178,244,135,235, 45, 43, 43,155, 60,121,178,128,128,192, -219,183,111, 27, 26, 26,232, 57,242, 67, 70, 53,128,217,252, 31,237, 4, 16, 15, 0, 2,136,154,251, 0, 48,123, 3,200,219, 92, - 33,157, 0,146, 26,167,116, 56,140, 1,222,252, 71, 94, 0, 10,244, 38,188,218, 32,184,149, 23, 82, 7, 4,182,207,251,191,150, - 65, 36, 97,230,129,130, 16,155,206,165, 12,172,172,220, 28,108, 52,114, 51,124,177, 63, 26,131,164,125, 0,100,244, 0, 32,205, -255,130, 89,155,171,146,221,164, 36, 28,224,131,126,196,135, 21,172,236,246,116,118,222, 14, 27,255, 33, 97,236, 14,185, 69, 15, - 63, 25,130,186, 3, 62, 4, 1,114,185, 15,233, 13, 96, 14, 91, 25,106, 24,110, 94,182,249,111,248, 31,123, 89,123, 97, 94,225, - 31,191,127, 0, 67,155,141,133,237,195,247,111, 39,158,236, 93,176,100,161,163,150, 35, 25, 86,183,110, 75, 88,184,112, 97, 73, - 9, 81,155, 0, 96,117, 0, 3, 73,165, 63, 92,111,110,110,238, 0,238, 3,128, 87, 3, 68, 42, 38,117,187,192,200, 1, 62, 49, -181, 91,150, 52,207,234,172, 64,222, 7,128, 60,211, 6, 16, 64,212,220, 7,128,214, 27,192, 44,238, 73,189,182,144, 72, 64,249, - 50, 80, 72, 77, 3,185,101, 23, 94,201, 41,129, 1,145,253, 0, 6,216,230, 47,251,170, 25, 16,198, 87,218,196, 40,229,205,109, - 74,170, 85, 96,243,223,117,207,201,232,250, 69, 64,103, 32,119,173,136, 15, 43,106,245, 3, 72,221, 20, 70,225,112, 16,102,233, - 15, 90, 36,138, 49, 1, 0, 7,142,122, 78, 7,215, 28, 62, 46,119,194,218,220, 90,154, 87,154,225,223,255,215, 63,222, 30, 59, -119,236,197,213, 23, 78,154, 78,236,236,236,116,200,252,144, 58,128,188, 18, 28,210, 15, 24,216, 89,223,209,198, 59, 21, 1,230, - 22, 48, 8, 0, 8, 32,106, 14, 1, 97,238, 99,194,186, 64,147,224, 37,148,164,150, 80, 20, 46, 3,133, 44,245,217, 3, 6, 36, - 21,103,144,190, 2, 37, 86, 99,142,101, 83,114,102, 14, 29,170, 16,215,154,217,228,133, 21,102, 39,128,120,103,224, 42,235,129, -157, 0,184, 44, 49, 69, 57, 25,195, 65,160,181, 64,105,173,238,179,220,177,238, 9,192, 63, 25, 96,166,109,246,237,219,183,147, - 27, 79,126,249, 5,106, 12,176, 51,177,201,137,203,107, 26,144,112,106,158,149,149,213,218,181,107,145, 87, 4,253,254,253,155, -164,160,166,164, 4, 31,204,107,126, 70, 1,169,157, 0, 92,197, 47, 64, 0,177,208,191, 88,193,191, 81,136,212,226,137,242, 75, -195,201, 46,206, 40,111,246,210, 97,244, 28,235,240, 15,236,196, 13,250,133, 21, 37, 30, 39,181,157, 78,221,225, 32, 80, 41,255, - 16,139,184, 73,181, 9, 65,189, 92, 92, 92, 58,170,186,148, 56, 59, 56, 56,120,180, 8, 27, 5,148,215, 1,184,164, 0, 2,104, -244, 82,248, 81, 48, 10, 70,193, 40, 24,161, 0, 32,128, 70,111, 4, 27, 5,163, 96, 20,140,130, 17, 10, 0, 2,104,180, 2, 24, - 5,163, 96, 20,140,130, 17, 10, 0, 2, 12, 0, 2,134, 38,117,179,129,211,232, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +137, 80, 78, 71, 13, 10, 26, 10, 0, + 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 0, 0, 0, 1, 0, 8, 6, 0, 0, 0,197,144,206,103, 0, 0, 0, 9,112, 72, 89,115, + 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 10, 77,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,119, 88,147,247, 22, 62,223,247,101, 15, 86, 66,216,240,177,151, +108,129, 0, 34, 35,172, 8,200, 16, 89,162, 16,146, 0, 97,132, 16, 18, 64,197,133,136, 10, 86, 20, 21, 17,156, 72, 85,196,130, +213, 10, 72,157,136,226,160, 40,184,103, 65,138,136, 90,139, 85, 92, 56,238, 31,220,167,181,125,122,239,237,237,251,215,251,188, +231,156,231,252,206,121,207, 15,128, 17, 18, 38,145,230,162,106, 0, 57, 82,133, 60, 58,216, 31,143, 79, 72,196,201,189,128, 2, + 21, 72,224, 4, 32, 16,230,203,194,103, 5,197, 0, 0,240, 3,121,120,126,116,176, 63,252, 1,175,111, 0, 2, 0,112,213, 46, + 36, 18,199,225,255,131,186, 80, 38, 87, 0, 32,145, 0,224, 34, 18,231, 11, 1,144, 82, 0,200, 46, 84,200, 20, 0,200, 24, 0, +176, 83,179,100, 10, 0,148, 0, 0,108,121,124, 66, 34, 0,170, 13, 0,236,244, 73, 62, 5, 0,216,169,147,220, 23, 0,216,162, + 28,169, 8, 0,141, 1, 0,153, 40, 71, 36, 2, 64,187, 0, 96, 85,129, 82, 44, 2,192,194, 0,160,172, 64, 34, 46, 4,192,174, + 1,128, 89,182, 50, 71, 2,128,189, 5, 0,118,142, 88,144, 15, 64, 96, 0,128,153, 66, 44,204, 0, 32, 56, 2, 0, 67, 30, 19, +205, 3, 32, 76, 3,160, 48,210,191,224,169, 95,112,133,184, 72, 1, 0,192,203,149,205,151, 75,210, 51, 20,184,149,208, 26,119, +242,240,224,226, 33,226,194,108,177, 66, 97, 23, 41, 16,102, 9,228, 34,156,151,155, 35, 19, 72,231, 3, 76,206, 12, 0, 0, 26, +249,209,193,254, 56, 63,144,231,230,228,225,230,102,231,108,239,244,197,162,254,107,240,111, 34, 62, 33,241,223,254,188,140, 2, + 4, 0, 16, 78,207,239,218, 95,229,229,214, 3,112,199, 1,176,117,191,107,169, 91, 0,218, 86, 0,104,223,249, 93, 51,219, 9, +160, 90, 10,208,122,249,139,121, 56,252, 64, 30,158,161, 80,200, 60, 29, 28, 10, 11, 11,237, 37, 98,161,189, 48,227,139, 62,255, + 51,225,111,224,139,126,246,252, 64, 30,254,219,122,240, 0,113,154, 64,153,173,192,163,131,253,113, 97,110,118,174, 82,142,231, +203, 4, 66, 49,110,247,231, 35,254,199,133,127,253,142, 41,209,226, 52,177, 92, 44, 21,138,241, 88,137,184, 80, 34, 77,199,121, +185, 82,145, 68, 33,201,149,226, 18,233,127, 50,241, 31,150,253, 9,147,119, 13, 0,172,134, 79,192, 78,182, 7,181,203,108,192, +126,238, 1, 2,139, 14, 88,210,118, 0, 64,126,243, 45,140, 26, 11,145, 0, 16,103, 52, 50,121,247, 0, 0,147,191,249,143, 64, + 43, 1, 0,205,151,164,227, 0, 0,188,232, 24, 92,168,148, 23, 76,198, 8, 0, 0, 68,160,129, 42,176, 65, 7, 12,193, 20,172, +192, 14,156,193, 29,188,192, 23, 2, 97, 6, 68, 64, 12, 36,192, 60, 16, 66, 6,228,128, 28, 10,161, 24,150, 65, 25, 84,192, 58, +216, 4,181,176, 3, 26,160, 17,154,225, 16,180,193, 49, 56, 13,231,224, 18, 92,129,235,112, 23, 6, 96, 24,158,194, 24,188,134, + 9, 4, 65,200, 8, 19, 97, 33, 58,136, 17, 98,142,216, 34,206, 8, 23,153,142, 4, 34, 97, 72, 52,146,128,164, 32,233,136, 20, + 81, 34,197,200,114,164, 2,169, 66,106,145, 93, 72, 35,242, 45,114, 20, 57,141, 92, 64,250,144,219,200, 32, 50,138,252,138,188, + 71, 49,148,129,178, 81, 3,212, 2,117, 64,185,168, 31, 26,138,198,160,115,209,116, 52, 15, 93,128,150,162,107,209, 26,180, 30, + 61,128,182,162,167,209, 75,232,117,116, 0,125,138,142, 99,128,209, 49, 14,102,140,217, 97, 92,140,135, 69, 96,137, 88, 26, 38, +199, 22, 99,229, 88, 53, 86,143, 53, 99, 29, 88, 55,118, 21, 27,192,158, 97,239, 8, 36, 2,139,128, 19,236, 8, 94,132, 16,194, +108,130,144,144, 71, 88, 76, 88, 67,168, 37,236, 35,180, 18,186, 8, 87, 9,131,132, 49,194, 39, 34,147,168, 79,180, 37,122, 18, +249,196,120, 98, 58,177,144, 88, 70,172, 38,238, 33, 30, 33,158, 37, 94, 39, 14, 19, 95,147, 72, 36, 14,201,146,228, 78, 10, 33, + 37,144, 50, 73, 11, 73,107, 72,219, 72, 45,164, 83,164, 62,210, 16,105,156, 76, 38,235,144,109,201,222,228, 8,178,128,172, 32, +151,145,183,144, 15,144, 79,146,251,201,195,228,183, 20, 58,197,136,226, 76, 9,162, 36, 82,164,148, 18, 74, 53,101, 63,229, 4, +165,159, 50, 66,153,160,170, 81,205,169,158,212, 8,170,136, 58,159, 90, 73,109,160,118, 80, 47, 83,135,169, 19, 52,117,154, 37, +205,155, 22, 67,203,164, 45,163,213,208,154,105,103,105,247,104, 47,233,116,186, 9,221,131, 30, 69,151,208,151,210,107,232, 7, +233,231,233,131,244,119, 12, 13,134, 13,131,199, 72, 98, 40, 25,107, 25,123, 25,167, 24,183, 25, 47,153, 76,166, 5,211,151,153, +200, 84, 48,215, 50, 27,153,103,152, 15,152,111, 85, 88, 42,246, 42,124, 21,145,202, 18,149, 58,149, 86,149,126,149,231,170, 84, + 85,115, 85, 63,213,121,170, 11, 84,171, 85, 15,171, 94, 86,125,166, 70, 85,179, 80,227,169, 9,212, 22,171,213,169, 29, 85,187, +169, 54,174,206, 82,119, 82,143, 80,207, 81, 95,163,190, 95,253,130,250, 99, 13,178,134,133, 70,160,134, 72,163, 84, 99,183,198, + 25,141, 33, 22,198, 50,101,241, 88, 66,214,114, 86, 3,235, 44,107,152, 77, 98, 91,178,249,236, 76,118, 5,251, 27,118, 47,123, + 76, 83, 67,115,170,102,172,102,145,102,157,230,113,205, 1, 14,198,177,224,240, 57,217,156, 74,206, 33,206, 13,206,123, 45, 3, + 45, 63, 45,177,214,106,173,102,173,126,173, 55,218,122,218,190,218, 98,237,114,237, 22,237,235,218,239,117,112,157, 64,157, 44, +157,245, 58,109, 58,247,117, 9,186, 54,186, 81,186,133,186,219,117,207,234, 62,211, 99,235,121,233, 9,245,202,245, 14,233,221, +209, 71,245,109,244,163,245, 23,234,239,214,239,209, 31, 55, 48, 52, 8, 54,144, 25,108, 49, 56, 99,240,204,144, 99,232,107,152, +105,184,209,240,132,225,168, 17,203,104,186,145,196,104,163,209, 73,163, 39,184, 38,238,135,103,227, 53,120, 23, 62,102,172,111, + 28, 98,172, 52,222,101,220,107, 60, 97, 98,105, 50,219,164,196,164,197,228,190, 41,205,148,107,154,102,186,209,180,211,116,204, +204,200, 44,220,172,216,172,201,236,142, 57,213,156,107,158, 97,190,217,188,219,252,141,133,165, 69,156,197, 74,139, 54,139,199, +150,218,150,124,203, 5,150, 77,150,247,172,152, 86, 62, 86,121, 86,245, 86,215,172, 73,214, 92,235, 44,235,109,214, 87,108, 80, + 27, 87,155, 12,155, 58,155,203,182,168,173,155,173,196,118,155,109,223, 20,226, 20,143, 41,210, 41,245, 83,110,218, 49,236,252, +236, 10,236,154,236, 6,237, 57,246, 97,246, 37,246,109,246,207, 29,204, 28, 18, 29,214, 59,116, 59,124,114,116,117,204,118,108, +112,188,235,164,225, 52,195,169,196,169,195,233, 87,103, 27,103,161,115,157,243, 53, 23,166, 75,144,203, 18,151,118,151, 23, 83, +109,167,138,167,110,159,122,203,149,229, 26,238,186,210,181,211,245,163,155,187,155,220,173,217,109,212,221,204, 61,197,125,171, +251, 77, 46,155, 27,201, 93,195, 61,239, 65,244,240,247, 88,226,113,204,227,157,167,155,167,194,243,144,231, 47, 94,118, 94, 89, + 94,251,189, 30, 79,179,156, 38,158,214, 48,109,200,219,196, 91,224,189,203,123, 96, 58, 62, 61,101,250,206,233, 3, 62,198, 62, + 2,159,122,159,135,190,166,190, 34,223, 61,190, 35,126,214,126,153,126, 7,252,158,251, 59,250,203,253,143,248,191,225,121,242, + 22,241, 78, 5, 96, 1,193, 1,229, 1,189,129, 26,129,179, 3,107, 3, 31, 4,153, 4,165, 7, 53, 5,141, 5,187, 6, 47, 12, + 62, 21, 66, 12, 9, 13, 89, 31,114,147,111,192, 23,242, 27,249, 99, 51,220,103, 44,154,209, 21,202, 8,157, 21, 90, 27,250, 48, +204, 38, 76, 30,214, 17,142,134,207, 8,223, 16,126,111,166,249, 76,233,204,182, 8,136,224, 71,108,136,184, 31,105, 25,153, 23, +249,125, 20, 41, 42, 50,170, 46,234, 81,180, 83,116,113,116,247, 44,214,172,228, 89,251,103,189,142,241,143,169,140,185, 59,219, +106,182,114,118,103,172,106,108, 82,108, 99,236,155,184,128,184,170,184,129,120,135,248, 69,241,151, 18,116, 19, 36, 9,237,137, +228,196,216,196, 61,137,227,115, 2,231,108,154, 51,156,228,154, 84,150,116, 99,174,229,220,162,185, 23,230,233,206,203,158,119, + 60, 89, 53, 89,144,124, 56,133,152, 18,151,178, 63,229,131, 32, 66, 80, 47, 24, 79,229,167,110, 77, 29, 19,242,132,155,133, 79, + 69,190,162,141,162, 81,177,183,184, 74, 60,146,230,157, 86,149,246, 56,221, 59,125, 67,250,104,134, 79, 70,117,198, 51, 9, 79, + 82, 43,121,145, 25,146,185, 35,243, 77, 86, 68,214,222,172,207,217,113,217, 45, 57,148,156,148,156,163, 82, 13,105,150,180, 43, +215, 48,183, 40,183, 79,102, 43, 43,147, 13,228,121,230,109,202, 27,147,135,202,247,228, 35,249,115,243,219, 21,108,133, 76,209, +163,180, 82,174, 80, 14, 22, 76, 47,168, 43,120, 91, 24, 91,120,184, 72,189, 72, 90,212, 51,223,102,254,234,249, 35, 11,130, 22, +124,189,144,176, 80,184,176,179,216,184,120, 89,241,224, 34,191, 69,187, 22, 35,139, 83, 23,119, 46, 49, 93, 82,186,100,120,105, +240,210,125,203,104,203,178,150,253, 80,226, 88, 82, 85,242,106,121,220,242,142, 82,131,210,165,165, 67, 43,130, 87, 52,149,169, +148,201,203,110,174,244, 90,185, 99, 21, 97,149,100, 85,239,106,151,213, 91, 86,127, 42, 23,149, 95,172,112,172,168,174,248,176, + 70,184,230,226, 87, 78, 95,213,124,245,121,109,218,218,222, 74,183,202,237,235, 72,235,164,235,110,172,247, 89,191,175, 74,189, +106, 65,213,208,134,240, 13,173, 27,241,141,229, 27, 95,109, 74,222,116,161,122,106,245,142,205,180,205,202,205, 3, 53, 97, 53, +237, 91,204,182,172,219,242,161, 54,163,246,122,157,127, 93,203, 86,253,173,171,183,190,217, 38,218,214,191,221,119,123,243, 14, +131, 29, 21, 59,222,239,148,236,188,181, 43,120, 87,107,189, 69,125,245,110,210,238,130,221,143, 26, 98, 27,186,191,230,126,221, +184, 71,119, 79,197,158,143,123,165,123, 7,246, 69,239,235,106,116,111,108,220,175,191,191,178, 9,109, 82, 54,141, 30, 72, 58, +112,229,155,128,111,218,155,237,154,119,181,112, 90, 42, 14,194, 65,229,193, 39,223,166,124,123,227, 80,232,161,206,195,220,195, +205,223,153,127,183,245, 8,235, 72,121, 43,210, 58,191,117,172, 45,163,109,160, 61,161,189,239,232,140,163,157, 29, 94, 29, 71, +190,183,255,126,239, 49,227, 99,117,199, 53,143, 87,158,160,157, 40, 61,241,249,228,130,147,227,167,100,167,158,157, 78, 63, 61, +212,153,220,121,247, 76,252,153,107, 93, 81, 93,189,103, 67,207,158, 63, 23,116,238, 76,183, 95,247,201,243,222,231,143, 93,240, +188,112,244, 34,247, 98,219, 37,183, 75,173, 61,174, 61, 71,126,112,253,225, 72,175, 91,111,235,101,247,203,237, 87, 60,174,116, +244, 77,235, 59,209,239,211,127,250,106,192,213,115,215,248,215, 46, 93,159,121,189,239,198,236, 27,183,110, 38,221, 28,184, 37, +186,245,248,118,246,237, 23,119, 10,238, 76,220, 93,122,143,120,175,252,190,218,253,234, 7,250, 15,234,127,180,254,177,101,192, +109,224,248, 96,192, 96,207,195, 89, 15,239, 14, 9,135,158,254,148,255,211,135,225,210, 71,204, 71,213, 35, 70, 35,141,143,157, + 31, 31, 27, 13, 26,189,242,100,206,147,225,167,178,167, 19,207,202,126, 86,255,121,235,115,171,231,223,253,226,251, 75,207, 88, +252,216,240, 11,249,139,207,191,174,121,169,243,114,239,171,169,175, 58,199, 35,199, 31,188,206,121, 61,241,166,252,173,206,219, +125,239,184,239,186,223,199,189, 31,153, 40,252, 64,254, 80,243,209,250, 99,199,167,208, 79,247, 62,231,124,254,252, 47,247,132, +243,251, 37,210,159, 51, 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, 0,226,134, 73, 68, 65, 84,120,218,236, 93,119,124, 83, 85,251,255,222,155,217, 77, 91,202, 30,165,200, 94,133, 86, +246, 72, 32, 5, 68, 1,209, 22, 20, 20,121, 81,155,162,168, 12, 21,231, 15, 39, 10,175, 21, 84,148, 6, 95, 21,149,161,180,136, +160, 32, 35,144, 84, 70, 25, 5,145, 61, 75, 41, 20, 74, 87,186,178,147,123,126,127,164, 55,164, 37,109,110,210, 66,139,222,239, +199, 74,238,200,147,115,207, 61,231,124,159,231, 57,207,121, 14, 21, 29, 29, 77,192,131, 7, 15, 30, 60,120,240,248, 87,129,230, +171,128, 7, 15, 30, 60,120,240,248,247,224,232, 95,106, 94, 1,224,193,131, 7, 15, 30, 60,254,109,232,215, 87,193, 43, 0, 60, +120,240,224,193,131,199,191, 21,188, 2,192,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60,120,240,224,193,227,223, 0,161,235, +193,172, 89,179, 40, 95, 5,173, 88,177,226,182,213, 4,188, 60, 94, 94, 45, 32, 43, 86,172,104,176,242,105,181, 90, 34,147,201, + 40,254,125,240,242,120,121,141, 86, 30,234, 32, 15,255,118,121, 94, 43, 0,255,102, 40,149,202, 42, 13, 80,165, 82, 81,141,185, +156, 41, 41, 41,160, 40,138,226,223,156,111,239,248,241,199, 31, 71, 90, 90,154,243, 56, 62, 62,158,175, 75, 30,119,181, 45, 54, +214, 49,134,199,191,212, 3,112, 55, 26,235,214,173, 91,101,155, 54,109,210,176,199, 19, 39, 78,148,143, 27, 55, 78,219, 24, 42, +131, 16, 7, 31, 52, 86, 94, 85, 42,149, 36, 59, 59, 27, 0, 16, 25, 25, 9, 0,247,196, 32, 82, 93,185,170, 84,176,106,180,204, +185,202, 93,183,110, 29,103, 69, 77,169, 84,146,245,235,215, 59,143, 55,110,220,136,184,184, 56,231,113, 90, 90, 26,105, 40, 37, + 32, 38, 38,134, 0,192,145, 35, 71,168,250,184,143, 71,253, 64,173, 86,203, 82, 83, 83, 53,174,231, 18, 18, 18,228, 10,133, 66, +219,152,250, 86,125,141, 1,247,194,243,242,184,203, 10,192,214,173, 91,101,236,191,117, 37,106,150, 8,222, 93,255, 1, 2,219, +134,160,226,106, 41, 22, 78,126, 75,179,105,211, 38,240,218,176,103,168, 84, 42, 42, 50, 50,146,100,103,103, 35, 59, 59, 27,219, +182,109,107,180,150, 4,251,174, 85, 42, 21,165, 82,169, 68, 74,165,210,186,100,201,146,195, 0,240,234,171,175,222, 95,219,119, + 39, 77,154,228,252,108,179,217, 97,177,154, 97, 49, 91, 96,177, 56,254,108, 54, 27, 94,125,245, 85,175,202,226, 74,254,238, 16, + 23, 23,215,160, 74, 0, 23,229, 39, 38, 38,134,239, 4, 13,168,180, 2, 64,106,106,170, 38, 53, 53,181, 81,140, 87,108, 25,235, + 99, 12,184, 23,158,151, 71, 3, 40, 0,155, 54,109,210,172,127,251, 13, 76,126,127,145,102,220,184,113, 84, 93, 26, 24, 75,252, + 0, 80,104, 40, 2,194,129,215,119,189,131,178, 44, 29,148,207, 54, 46, 34,171,169, 67, 52,116, 25, 93,149,128,177, 99,199, 34, + 59, 59, 27,145,145,145,141,174,238, 52, 26,135, 33, 33,151,203,137, 74,165,162, 85, 42, 85,107,165, 82,153,187,100,201,146, 35, + 92,229,216,108, 54, 88, 44, 86, 39,241,187,146,127,102,102, 38, 98, 99, 99,189, 42,215,228,201,147,157,159, 31,127,252,113,236, +220,185,179,138, 2, 80, 31,109,197,151,247,112,228,200, 17, 74,171,213,146,209,163, 71,223,118,109,199,142, 29, 88,183,110,157, +243,184,182,184, 5, 30,245,223,247,171,191,207,250, 32,221,250,148, 81, 31,158,128, 59,253,188, 60,238, 81, 5, 96,235,214,173, +178,206,157, 59,163, 83, 96, 48,234,226, 5,112, 37,255, 66, 67, 17, 62, 26,245,142,243,218,127, 54, 61, 7, 52, 3, 38, 45,153, +236, 85, 35,171,137,160,235,139,164,175, 94,189, 10, 0,104,219,182,109,149,207,236,239, 70, 71, 71,223,181,193,168,250,243,184, + 42, 1, 86,171, 13, 41, 41, 41,119,204, 10,240, 86,102, 53,242,119,253,254,117,149, 74, 21,170, 84, 42,117,156,201,223,106,133, +197, 98,134,217, 98,129,181, 26,249, 19,198,187, 12,214,147, 39, 79, 70,102,102,166,243, 56, 57, 57, 25,241,241,241,206,227,180, +180,180, 58, 43, 59, 46, 10, 79,157,219,159, 43,241, 63,254,248,227,232,219,183, 47, 63, 90,221, 5,168,213,106, 89,109,109, 95, +165, 82, 81,108, 63, 81,171,213, 50,111,220,227,174, 94, 49,182,191,186,158,243,214, 16,168,137,184,189, 25, 11,220, 61,239,206, +157, 59, 9, 69, 81, 80, 40, 20, 84, 93,158,151,197,211, 79, 63, 77,190,249,230, 27, 94,121,104,132,160, 61, 89,255, 31, 76,137, +135,169,160, 0, 47,247,232, 10,215,185,123,174, 96,167, 16, 92,201,127,226,196,137,114,149, 74, 69, 77,156, 56, 81,254,221,196, +175, 0, 0, 77,186, 52,173,114, 63, 23,188,250,229,121,188,250,229,121, 60,255,201, 25, 60,245,254, 73, 60,242,250,177, 58, 87, +200,181,107,215, 56, 41, 6,119,139,252,179,179,179,107, 36,230,200,200, 72, 88, 45, 22, 12,232,223,191,206,191,195,186,201,215, +175, 95, 15,141, 70,227,252,171, 77,209,170,137, 12,229,114,121,117,242,103, 81,194,101, 96,178,217,236, 14,203,223,236,112,253, + 87, 39,127,187,221, 14,189, 81,239,213, 51,178, 30,131,234, 94,131,180,180, 52,164,165,165, 85, 81, 6,188,122, 94,109,213,241, + 80,163,213,122, 85,103,181,145,255,227,143, 63,142, 37, 75,150, 56,201, 95, 36, 20,241, 35,214, 29, 6, 59, 7, 94, 91, 59,101, +175, 85,159, 47,231, 74,220,245,101,172,176,223,173, 78,254,158, 12,164,218,158,119,231,206,157, 36, 45, 45, 13,169,169,169, 80, +171,213,164,174,207,251,244,211, 79, 19,161, 80,136,167,159,126,154,223,115,230, 94, 82, 0, 92,173,127, 67,222, 13, 60,208,183, +159,215, 4,205, 42, 17,239,174,255, 0, 0,156,228,207,122, 17,198,141, 27,167,101,149,128,107,101,215,209,239,213,129, 94, 41, + 25,122,163, 29,122,163, 29, 55,138,204,200, 45, 48,225,234, 77,147, 79,196,199,118, 22, 79,228,223, 80,168, 73, 9, 0, 0,147, +197, 12,147,201,228,179,108,150,180,217, 57,242,136,136, 8, 87,107, 22, 92, 7,147,234,150,112, 77,174, 68, 46,131,158,197,106, +118, 88,254,102, 11, 44,214,170,228,111,181, 90,161,215,235, 81, 94, 86,222,160,239,196,161, 48,165,186,156,161,216,255,176,126, +125,170,207, 74,128, 43,249,179,196, 79,211, 52,164, 82, 41, 2, 2,253,249, 17,235, 30, 69,109, 86,121,117,107,222, 87,133,194, +221,180,128,183,242, 92, 61, 97,169,169,169,117,122,102,150,252, 1,128, 87, 2, 26, 39,132,181, 17,247,215,137, 79,223, 34,219, +107, 87,241,114,143,174,248,100,211, 38,175, 99, 1, 88,235,159, 37,125,215,107,227,198,141,211,110,218,180, 9, 0, 16,222,171, +133, 87,133,175, 48,218, 81,110,176,161, 76,111, 67,105,133, 13, 37,229, 54,175, 43,192, 93,228,191,171,149,239,250, 57, 43, 43, + 11, 37, 37, 37,119,237,229,164,164,164, 32, 50, 50, 18,108,208,159,235, 92,191, 82,169, 36, 41, 41, 41, 48, 25,141, 62, 43, 0, + 74,165,146,124,247,221,119,184,150,155, 11,145, 64,128,230, 45, 90, 84, 33,255, 81,163, 70, 97,242,228,201,156, 6, 39,149, 74, + 69,201,229,242, 42, 74, 64,117, 79, 6,215, 88, 5,139,217, 2,139,217, 12,171,213, 2,155,205,238, 36,127,179,217, 12,131,193, +128,138,138, 10,148,151,123,175, 0,184, 78, 1,176,240,213,242, 95,159,186, 30, 32, 64, 97,126,190,163, 29, 57, 26, 17, 40, 66, + 28, 74, 64,106, 42, 38, 39, 36,120, 61, 29, 80,157,252, 69, 34, 17, 36, 18, 9,164, 82, 41,164, 82,169, 79,207,205,163, 97,137, +159, 43, 65,251, 58, 29, 80,147, 34,225,139,156,132,132, 4, 39,241,251,210, 55,220,145,191,147,108,132, 66,216,108, 54,126, 58, +160,177,123, 0, 88, 43, 63,182, 99, 39,152, 10, 10,160,191,230, 32,193,225,149,214,161,183, 94,128,172,147, 23,111,147,237,238, +184,232, 68,158, 87,133,175, 43,249,187, 18, 63, 33, 4,109,219,182,173,114,205,106,181, 58,255, 74, 74, 74,160,215,235, 81, 92, + 92,124,215, 94, 14,187,206,127,219,182,109, 85, 60, 1, 44,249,247,238,221, 27, 38,147, 17, 70,163,145,125, 6,175,220,245, 95, +126,245, 37,172, 86, 43,218,180,110, 13,171,221,238,150,252,189, 25, 72, 42,149,128,219,172, 18,118,233, 98,109,158,140,219, 20, + 0,139,213, 73,254,135, 15, 29,134,193,104, 68,121,121, 57, 74, 75, 75, 81, 82, 82, 2,157, 78,231,115,189,178,211, 0,190,206, +251, 3, 64, 81, 97, 17,138,138, 10, 81, 88, 84,140,194,162, 34, 20, 21, 21,161,168,176, 16, 0,208,181, 91, 55, 20, 87,126,246, +214,250, 7,128,190,125,251,222,178,250, 3, 2, 16, 24, 24,132,160,192, 32,148,151,151,203,249, 33,171, 97,200,219, 87,171,186, +114, 21, 12,229,250,217,211,113, 93,202,233,110, 90,192, 27, 57, 10,133,130, 74, 72, 72, 64,124,124, 60,226,226,226,124,246, 76, +124,243,205, 55,148,205, 86,117, 76,182,217,108,224,201,255, 30, 80, 0,216,200,127, 0, 48,228,221,168,114,205,219, 88,128,137, + 19, 39,202,191,124,246, 51, 0,142,128,191, 77,155, 54,105, 92,151, 22,110,218,180, 73, 19,247,227,195, 0,128,163, 75, 14, 96, +226,196,137,119,109,144,115,237, 36,215,174, 93,115, 90,251, 44,233, 59,189, 31,122, 61,202,203,203, 97, 50,153,224,239,127,119, +221,176, 42,149,138, 74, 74, 74,114,148,203,102,195,233,211,167,241,215,209,163,232,211,187, 15, 76, 38, 19,140, 70, 19, 76, 70, + 35, 86,255,248, 35,216,251,184,116,244,228,228,100,116,239,214, 29, 86,171, 21, 23, 46, 92,128,205,106, 65,238,181,220,122,173, + 83,246,184, 50,103, 1, 34, 35, 35, 57, 13, 76, 22,171, 25, 54,187,195,237,127,240,224, 1,232,141,122, 84,148,151,161,180,180, + 20,186,146, 18,232,116,197,117, 82,196, 88, 79, 64, 93, 44,156, 63,255,252, 19,229,229,229, 40, 47, 47,171,252,183, 28, 77,195, +195,209,181, 91, 55,156, 61,115, 6,233,127,254,233,181, 76,214,250, 23, 10, 69,240,247,247, 71, 96, 96, 32,130, 2, 3, 17, 24, +232,143, 98, 93,177, 28,128,150, 31,178,238, 44, 18, 18, 18,228,174,164,234, 26, 36,199,126,102,175,177,247,250, 98,157, 87,239, +143,245,177,162,192, 23,203,223,221,243, 42, 20, 10, 42, 46, 46,142,170,203,243, 86, 87, 2,120,242,191,135, 20, 0, 0, 8,191, +156,141,226, 19,199,157,214, 63,139,225, 46,115,196, 92,192,186,252,207, 30, 57, 13, 0,136,251,241, 97,108,218,180, 73,163, 84, + 42,137, 43,249,179,214,191, 55,171, 12,126,249, 40, 26,234,207, 99,113,248,219,129,184,144, 58, 20, 23, 82,135,250,236, 5,168, +168,168, 64, 73, 73, 9, 74, 74, 74,144,151,151, 87,229,207,100, 50, 65, 36, 18,161,160,160, 0,247,223,127,255, 93,127, 73, 44, +137,238, 82,171, 29,164,111, 54,195, 80,105,249, 27,141, 70,199,103,147, 9,203,151, 47,247,104,161, 40,149, 74,178,100,201, 18, +216,237,118, 28, 57,114, 20,182, 74,101, 39, 50,178, 3, 44, 54, 43,114,115,115,177,110,221, 79,216,181,107, 23,187,126,222,163, +188,202,223, 20, 1,160, 92,227, 42, 92, 93,154, 92,201,223, 49, 88, 56, 44,255,140,140, 12,232, 43, 12, 40, 47, 45, 71,137,174, + 20, 58,157, 14,186,226, 34, 20, 23,151,160,164,164,212,103,235,223,213, 3,224,139, 23,224,241,199, 31,175,114,220, 33, 50, 18, + 15, 60,240,128,147,252, 47, 87,122, 60,170,223,199, 5,131, 6, 15, 66, 64,128,131,252, 3, 3, 3,225, 31, 16,128,130,130, 66, +158,252,239, 18,220, 68,185,107,106,248, 12, 95, 34,226,235, 99,158,190, 62,101,221,233,231,101,149, 0,158,252, 27, 39,110,139, + 1, 96,173,243, 81,171,215,214,250, 69,111,150, 4,178,218,111,191, 87, 7, 34,188, 87, 11,176,164,207,162,232, 68, 30,142, 46, + 57,224,149,230, 90, 95,107, 82,217,178,117,235,214, 13, 39, 78,156,168, 50,199, 90, 82, 82,114, 9, 64, 71,119,223,113,151,187, +250, 78, 43, 1,238, 58,248,234, 31, 87,195,100, 50,193,108, 49,195, 98,177, 96,201,146, 37, 30,201,159, 5,195,216, 33,245, 11, +132,209,104,194,153,211,167, 33, 20,137, 96,181, 88,224, 31,224,143,117,235,214, 65, 32, 16,176,107,231,107,125,214, 37, 75,150, +108, 83, 42,149, 22,149, 74,213,140, 45,103,181, 60, 0, 94,185, 54, 95,125,245, 85,236,219,183, 15, 21, 21, 21,168,208,235, 81, + 94, 86,134,178,242, 50,148,149,149,161,188,172, 28, 21,229, 21,208, 27, 12, 94,213, 93,108,108, 44,201,204,204,116, 90,255,238, +150, 1,114, 77, 2, 36,147,201,110,123, 23, 44,233,255,245,215, 95, 78,107,158,235, 51,199,196,196, 16, 54,201, 79,160,127, 32, +164,126, 82,148,151,151,203,217,169, 29,158,252,239, 30, 92, 45,126,192, 17, 8,167, 80, 40,156,159,171,223,235, 13, 41,186,198, +239,212,213,242,119, 55, 38,248, 34,235, 78, 62,175,171, 18,192,183,172,123, 68, 1, 24, 55,110,156,182, 46, 9,127,184, 52, 86, + 86, 17, 96,137,191, 62, 9,189, 46,101,235,213,171, 23, 14, 31, 62,140,130,130, 2,246, 82, 71, 0, 40, 42,114, 4, 48, 62,249, +228,147, 13,250,178,170,215, 17, 33,132, 60,241,228, 19, 88,190,252,203,202, 57,115, 27, 66, 66, 66, 40,174,223,103,225,231, 39, +101,229, 1, 0, 12,122,131,235,119, 0,184,223,172,195, 5,221,150, 44, 89,114, 65,169, 84,230,171, 84, 42,129,107, 64, 96,229, +178, 64,206, 3, 29,187,246,125,200,144, 33,245, 94,119,177,177,177,213,247, 2,112, 94,247, 54, 3,160, 74,165,162,180, 90, 45, + 89,183,110, 93,149, 68, 61,172,108, 95,218,179, 76, 38,163,172, 54, 43,172,229, 86,126,100,106, 32,120,179,212, 45, 53, 53, 85, +163, 80, 40, 40, 95,199,155,250, 24,243,234, 42,235,110, 60, 47,143,123, 72, 1,184,211, 4,182,117,235, 86,217,166, 37,141,111, + 47, 0,182, 35,221,127,255,253,216,186,117,171,169,146,244, 25, 0,254,119,194,243, 80, 31,160, 40,138, 82,169, 84, 78,203,190, + 54,242,191,147,120,245,213, 87,219,187,234, 37,236, 7,118, 25,161, 55,214,206,157,172, 95, 87,217, 90,173,182,206,105,127,101, + 50, 25, 37,147,201,234, 92, 46, 62,183,127,227, 1,151,245,255,247, 82,153,255,137,207,203,227, 30, 85, 0,238,164,135,161, 62, +149,128,113,227,198, 73,255, 41,131,214, 93,250,109, 54, 67,141,141, 85, 0,248,193,131, 71, 13,227,141,141,175, 6,190,127,240, +104, 36, 70,100,116,116, 52,159,156,129, 7, 15, 30, 60,120,240,248,151,129,230,171,128, 7, 15, 30, 60,120,240,224, 21, 0, 30, + 60,120,240,224,193,131, 7,175, 0,240,224,193,131, 7, 15, 30, 60,120, 5,128, 7, 15, 30, 60,120,240,224,241,143, 64,149, 85, + 0,179,102,205,242, 57, 50,213,221, 58,113, 94, 30, 47,175, 49,200, 75, 76, 76,244, 74,214,202,149, 43,249,250,187,203,242, 60, + 45, 19,109,104,121,252,251,109, 16,121,168,131, 60,252,219,229,241, 30, 0, 30, 60,120,212, 43,204,102,243,200, 3, 7, 14, 60, +252,203, 47,191, 36,105,181,218,215,202,203,203,235,156, 29,139,221,119,158,253,183,174,112,151, 31,159, 71,227,194,230,205,155, +101,124, 45, 52, 50, 15, 0,143,127, 23,210,210,210,100, 59,119,238,172,146, 9, 44, 46, 46, 78, 30, 31, 31,175,253, 39,202,227, +225, 59,172, 86,171,236,208,161, 67,154, 83,167, 78, 57,207, 21, 22, 22,226,252,249,243,104,217,178,229, 15, 50,153, 76, 30, 20, + 20,228,245,123, 81,171,213, 50, 54,229,108,229,191, 62,165,155,173, 78,254,132, 16, 80, 20, 85,231,141,118,220,125,215, 87,153, +245, 33,175,174, 91, 6,251,226, 45,185, 19,228,191,117,235, 86,205,132, 9, 19,248, 92, 8,188, 2,208, 56,177,103,207, 30, 50, +108,216,176,127,108, 3,101, 7,146,228,228,228, 42, 59,124,205,159, 63, 95,179,115,231, 78,175, 7, 24, 86, 30,243,115,104,149, +243,244,148,157, 13, 46,111,229,202,149,124,131,174, 3,244,122,189,108,243,230,205, 26,215,125, 50, 92,113,227,198, 13,164,165, +165,105,186,117,235, 38, 31, 56,112,160, 87,228, 93, 61, 21,109, 93,210,205,186,146,127,125, 40, 1, 53,125,199, 87,178,172, 15, +121, 9, 9, 9, 72, 77, 77,229,244, 76,106,181,154,112,173,203,218,228,121, 35,135, 43,249, 51, 12,131,149, 43, 87, 98,205,154, + 53,100,218,180,105,188, 34,208, 64,224,167, 0,106,192,106, 15,155, 33,221,235,228,255,210, 75, 47,221, 70,254,172, 66,240,210, + 75, 47,121,229, 62, 85, 42,149,100,213, 11, 1,183,145, 53, 75,224,171, 94, 8,104, 80,121,165,165,165,178, 89,179,102, 17,141, + 70,227,252,206,177, 99,199,100, 74,165,146,124,248,225,135,228,253,247,223, 39,111,188,241, 6,217,177, 99, 7, 39,153,226, 82, +189,172,215,172,239, 72,222,215, 59,101,236, 57, 91,158, 77,118, 74,105, 34,199, 63, 20,147,189,239,135,146,223,222,104, 79,190, + 89,156, 47,251, 39,180, 23,181, 90,125, 27,249,103,102,102, 98,234,212,169,174, 30, 2,156, 61,123, 86, 99, 48, 24,188,218, 50, +214,117,163, 40,111, 55,141,170,141,252, 89,176,199,190, 76, 7,212,182,125,111, 93,202, 88, 23,121, 10,133,130, 74, 72, 72,112, +126, 79,173, 86, 19,119, 83, 39,106,181,154, 84,223,204,167, 54,165,162,166,114,176,114,234, 99, 58,197,149,252,231,207,159,143, + 53,107,214,144,189,123,247,242,100,195, 43, 0,141,207,250,167, 40, 10,123,247,238,253,199,205, 33,166,165,165,201, 0,160, 93, +187,118,114, 87,171,127,254,252,249, 78, 75,140,189,198,222,203, 69,222,244,161, 98, 23, 43, 93, 7,122,138,206,121,204, 94,107, + 8,121, 0,112,240,224, 65,141, 84, 42, 69, 70, 70, 70,213,198, 79,211,120,243,205, 55,169,183,223,126,155, 26, 56,112,160,124, +203,150, 45,156,234,176,197,193,211, 26, 34, 21,161,119,129,184,138,245, 74,209, 4,189,223,180, 80, 67,223,214, 81,145, 99, 79, +200,109,215, 31,210,220,235,237,101,255,254,253,178,155, 55,111,114,186,215, 98,177,224,196,137, 19,187, 27,202,155,197, 90,252, +236,159, 47, 74, 64,245,248,129,234,219, 91,187,187,126, 55,229,185, 42, 1,197,197, 10,168, 84, 58,212,133,252,107, 83, 42, 92, +229,212,117,138, 96,243,230,205,178, 45, 91,182,104, 40,138, 2, 77,211,200,204,204,196,158, 61,123,120,178,185, 23, 20,128, 61, +123,246,144, 61,123,246,212,153, 12,211,210,210,100,213, 27, 63,215, 65,188,182,178,177,178,234,163,140,172,245,159,146,242, 21, + 85,159, 94,128,250, 42, 91, 93,177,115,231, 78,141,171,229, 63,127,254,124, 77,114,114,178, 60, 57, 57, 89,238,170, 4, 36, 39, + 39,203,171,207,191,215, 36,207,213, 82,167,167,232,112, 97,235,147,184,176,245,201, 42,164,205,252, 28, 10, 95,229,177,150,161, + 47,242, 8, 33,178,253,251,247, 99,218,180,105,200,201,201,193,209,163, 71,101,238,238,145, 74,165,154,150, 45, 91,122,174, 64, + 66,100, 45,247,159,196,181,105, 67, 32,206, 41, 5,117,195,224, 34,143,170,188, 5, 50,145,169,157, 38,172,165,241,158, 31, 32, +236,118,187, 87, 74,204,229,203,151,111, 85, 68,205, 30, 5, 25, 23,226,172,190, 85, 45, 87,203,191,186, 23,192, 27, 37,192,213, + 27,225,234,149,112,253,115,119, 31, 87,121,100,125,232,109,127,222,200,171,165, 78,235, 68,218,213,149, 10,149, 74,135,250, 34, +255, 89,179,102,145, 63,254,248, 67,195, 48, 12,230,204,153, 3,138,162,176,103,207, 30, 80, 20,133, 21, 43, 86,240,238,255, 6, +132,199, 24,128, 61,123,246,144, 53,107,214,177, 29,200,231,121,113,182,227, 61,241,196, 19, 96,101,236,217,179,135,172, 94,189, +218,167, 57, 98,151,239,227,137, 39,158,168, 36,238,213,117, 42,163,171,245,207, 14, 26,245, 17, 11,192,150,179,174,101,171,111, +176,228,239, 74,250,213,207,121,165, 77, 86,146, 63,139, 11, 91,159, 4, 61,238, 71,183,174,124,174,242, 92,219,133, 67, 9, 80, + 18,111,228,165,167,167,195, 98,177, 32, 38, 38, 70,190,119,239, 94, 77,118,118,182,166, 95,191,126, 20, 0, 48, 12,131,143, 62, +250,136, 84, 84, 84, 64, 36, 18,225,145, 71, 30,241,248,220,166,140,195,160, 45, 54,148,196, 68,202, 69,123,175,107, 46,126,151, +142,142,111, 60,224,104, 47, 12,193,241,143,196,164,184, 34, 8, 70, 81, 32,226,102, 93,144,223,235, 3, 68, 69, 69,133,243,115, +102,102,102,149,107,243,230,205,195,188,121,243, 0, 0,177,177,177,174,247, 75,106, 35, 42,174,214, 41, 27, 31, 80,211,252,115, + 77,100,238,106,253,215,244,189,232,232,232,123,126,240, 86, 42, 67,171, 41, 27,186,202,122,171,191, 32,193,250,176,252, 9, 33, +176,217,110,237, 1, 53,116,232, 80,236,217,179,135, 39,255,198,174, 0, 56,136,107, 45, 84, 42,199,139, 74, 74,122,142,248, 66, + 98, 74,165,146,184,139,222, 30, 54,108, 24, 53,108,216, 48,167,103,192,155,198,230, 74,254, 46,229,169, 51,209,174, 94,189, 22, + 79, 60,225,152,219,124,226,137,169, 88,189,122, 45,134, 13, 27, 86,103,242,103,119, 26,108,108, 74,192, 63, 29,185,185,185,154, + 1, 3, 6,128,162, 40,237,128, 1, 3,240,235,175,191,226,225,135, 31,150,181,104,209, 66, 67,211, 52, 94,127,253,117, 10, 0, +138,138,138,100,235,214,173,211,152,205,102,220,127,255,253, 53,190,159, 65,151,175,107,242, 6,116, 3, 40, 74,123,170,185, 93, +222,227, 88,152,198,196, 64, 14, 0, 20, 13,244,126,221, 66, 1, 69,208, 23,149,202,118,175,187, 79,163, 15, 58, 36,127,236,169, + 96,237,189, 90,127, 34,145,200,249,249,211, 79, 63,173, 66,254,174,199, 44,196, 98, 49,224,178, 37,116,109,132,237,233,184, 82, + 9, 64,106,106,106,141,132,237,210,175,106,180,254,107,187,255, 94,133, 66,161,160,106, 90, 54,201,186,243,235,138,250,144, 83, + 81, 81,161, 1, 0,161, 80,136,185,115,231, 34, 51, 51, 19,252,188,255, 61,162, 0,172, 89,179,206, 73,134, 0, 48,109,218,227, + 88,179,102,157, 87,132,200,186,248,107, 91,186, 21, 31, 31,175,221,185,115, 39,210,210,210,100, 92,151,120,185, 33,127,246, 51, + 89,189,122,181, 79,164,189,119,239, 94, 66, 81,148, 83,230,176, 97,195,168,213,171,215, 18, 95,189, 0,174,228, 95,109,240,241, + 73,137,170,111, 77,189,186,197, 95, 23,235, 31,112,184,229,233,113, 63, 58,189, 0,157,234, 96,253, 59,229, 77,185,165, 24, 42, +149,222, 89,255, 86,171,149,100,102,102, 34, 40, 40, 8,199,143, 31, 39,118,187, 29,101,101,101, 56,115,230,140, 38, 60, 60,188, +202,189,225,225,225,218,238,221,187,203,215,175, 95,175,185,255,254,251,221,202, 19, 88,173,164,109,230, 9,136,131, 90, 67,116, +188,136, 52,183, 7,161,188,140,134,253, 76, 5, 16, 94,117, 7,233,128,112,155,182, 93,236, 17,249,182, 13, 83, 52,192, 31,247, +172,194,119,237,218,181,253, 0, 6, 3,192,218,181,107,171, 40, 0,213,207, 1, 64, 88, 88, 24, 0,152,107,106,163, 53,185,168, +171, 27, 0,108,123, 79, 72, 72,128, 66,161,160,220, 37,138,169, 75, 52,190, 59,121,247, 34, 88,171, 95,169, 12,189,205, 35,224, +171, 87, 33, 53, 53,181, 94,200,127,205,154, 53,228,207, 63,255, 4, 89, 31, 10,106,178, 14, 75,151, 46, 5, 33, 4, 52, 77, 35, + 37, 37,133, 55,130, 26,179, 2,176,103,207, 30, 66, 8,185,141, 96,215,172, 89, 71,246,238,221, 75,134, 14, 29,202,233, 5,238, +220,185, 83,195,186,232,107,195, 19, 79, 60,129,213,171, 87,107,226,227,227, 61,202,101,231,211,221,145,168,131,180, 87,123, 77, +218,213,189, 29, 44,158,124,114, 26,126,252,113,141,215, 94,133,234,228,239,198, 2,241, 74, 30,151, 58,228,130,184,184,184, 42, +164,239, 58,247, 95, 61, 54, 32, 46, 46, 78,206, 69, 30, 61,229,214,188, 61,171, 4,176,159, 89,208, 83,116,240, 89,222,148,219, +151, 4,114,145,119,236,216, 49,180,107,215, 14,115,231,206,117,214,243, 15, 63,252, 64, 50, 50, 50,240,208, 67, 15,221,118,191, +191,191,191, 70, 42,149,214, 40, 47,242,216, 49,148,180,107,137,131,115,103, 58,229,157,123,229, 23, 89,135,140, 82, 13,253,144, +244,182,178,228,156,183, 64, 34,181,222,211, 3, 68, 66, 66,194,133,159,127,254,121,176,171, 11,183, 54, 72,165,210,153,158, 44, + 87, 0,178,234,203,255,106,248,109,185, 47, 57, 1,170, 79, 1,120,242, 10,252, 83, 80,215,165,122,236,247, 83, 83, 83, 73, 93, +229,173, 93,187,134,104,181, 90, 80,105, 14, 69,123,199, 91, 65, 24,253, 65, 57,134, 15, 31, 14,126,217, 95, 35, 87, 0,216,121, +127, 87,235,223,213, 11,240,227,143,107, 64, 8,225, 76, 96, 92,238, 99,137,219, 27,235,223,131, 50,193,217, 11,192, 62,111,117, +242, 7,128,161, 67,135, 82,132, 16,178,102,205, 58, 80, 20,197, 73,241,169,137,252,235,162, 4,212,215,180, 1,235,109,201,201, +201,209,176,209,254,213,173,254,156,156, 28,141, 39,175, 77,117,121, 63,236,181, 56,163,243,171, 91,233, 63,236,181,160, 33,228, +101,100,100,220,214, 6, 34, 35, 35,229,235,215,175,215, 68, 69, 69,201, 25,134,209, 44, 90,180,136, 48, 12, 3,163,209, 8,138, +162, 16, 27, 27, 91,163, 82,209, 37, 35, 3, 63,133, 55,147, 7,187,156,235, 54,123, 52,244,255,189, 10,140,106, 6,194, 0,199, + 23,137, 72, 5, 19,136, 98, 99, 48,116, 84, 95,244, 25,182, 89, 14,248,223,179, 3, 68, 64, 64, 64,162, 80, 40, 28,106,179,217, + 58,186,158,255,244,211, 79,111,179,254,219,183,111, 15,133, 66,177,138, 3,209,104, 61,145, 75,157,231,176, 21,235, 29,255,170, + 39,123,105, 1, 59, 60, 17,158,162,242, 93,239,171,173,172,213,229, 81,147,117,168,139,188,154, 44,246,152,152,152, 70,211,102, +148, 74, 37, 33,235, 67, 1,150,252,143,219,240,157,198, 82,201, 31, 60,249, 55,106, 5, 32, 41,233, 57, 66, 8,193, 19, 79, 76, +173,209,194, 6, 64,214,172, 89,135, 53,107,214,145,148,148,175, 26,228,133,214, 70,136,222, 40, 19,174,207,235,225,183,200,143, + 63,174,193,143, 63,174, 33,238, 20,133,234, 10, 10,151,232, 96,165, 82, 73,234, 18, 95,224,187,219,208, 57, 32,105,220, 37, 2, +242,118, 0, 86,169, 84,212, 12,165,146,204,248, 66,239, 38,113,143, 14, 13, 37,239,197, 23, 95,188,237,158,225,195,135,107,135, + 15, 31, 78, 1,192,200,145, 35,189,106,187, 91, 95,124,145, 10,174,118,142,105, 31,168,245, 91,222,141, 2,128, 30, 42, 17, 5, + 88, 1,232, 42,255,174,224, 94, 38,255, 74, 88,166, 79,159, 62,112,253,250,245,199,245,122,125, 75,171,213, 90,105,225, 85, 37, +255,238,221,187, 99,224,192,129, 15,161,134,249,255,218,200,162,250,231,187,153,149,174, 38,197,163, 54, 50,118, 61,239,205, 42, +128,250,144, 87,147,197, 30, 21, 21,213,104,200,159,249, 57, 20, 59,142, 59, 60, 70,171, 52, 22,252,180,223, 2, 66, 72,131,190, + 87, 30, 28, 21, 0, 46,132,206, 6,239,121,211,161,234,243, 94, 46,247,113,149,197, 85,129,185, 19,207,220,208, 3, 93, 90, 90, +154,204,117,233, 31,224,123,170, 93, 86, 30, 61,101,103,163,148,199,163, 78, 40,156, 60,121,114,199,242,242,242, 15,143, 28, 57, + 50, 55, 55, 55, 23,122,189, 30, 98,177, 24, 45, 91,182, 68, 68, 68,196,195,253,250,245,219,228,139,224,132,132, 4,185,235,116, + 64, 66, 66, 66,163, 89, 57,209, 24, 51, 1,222, 43, 24,243, 65,249, 63,254, 25,255,145, 10, 0,143,127, 15,226,227,227,181, 92, + 98, 46,254, 41,242,120,212, 9,198,160,160,160,121, 50,153,108, 94,125, 10,101,231,248,217,192, 51, 95,247, 1,184,109,233,159, +139,235,223,211,178,192,218,172,217,198,182, 23, 64, 67, 42, 62, 92, 65, 79,209,129,162, 40, 76,152,120,107, 23,206,173,127, 28, +117,122,122,198, 61,208,143,239,211,188, 2,192,131, 7, 15, 30, 14, 87,118,106,106,170,207,249,230,239, 20,121,222, 43, 30,128, +198,167, 60, 16, 2, 80, 60,201,223, 3,160,162,163,163,249, 45, 51,121,240,224,193,131, 7,143,127, 25,248,189, 0,120,240,224, +193,131, 7, 15, 94, 1,224,193,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60,120,240,224,193,131, 87, 0,120,240,224,193,131, + 7, 15, 30,255, 12, 84, 89, 5, 48,107,214, 44,159, 35, 55,221,229,214,118, 39,239,183,159,191,150,245,236,125,159,166,101,155, +214,242,114,163, 94,147,174,201,144,199, 79,121, 78,235,171,188,229,223,110,144, 69,247, 30,160,185,153,155,139, 0,191, 0, 92, +189,118, 73,254,236,204,137, 62,203,171,239,231, 61,145, 62, 75, 54,112, 64,148,198, 47, 64, 0,161,128, 6, 37,165,112,163,236, + 37,202, 87,121, 71,111,246,150,221, 63,224,126, 77, 72,160, 0, 16, 2,197,199, 86, 82, 92,203,215,105, 76, 39,159,159,247,194, +246, 11,183,201,235,223,191,191,207,242, 14, 29, 58,116,187,188, 78,190,151,239,208,133,219,203, 55,160,115,103,159,229, 29, 60, +127,254,158,147, 55,166,150,247,187,120,113, 42, 89,176, 32,161,198,235,219,221,188,223, 78, 99,199,248,222, 94,182,109,191,189, + 61,143,241,189,189, 44,222, 89, 68,130,153, 75, 85,206, 53,237,244,152,207,242, 10, 47,252,116, 91,249,254,122,227,138,207, 3, +105,223, 69,237,111, 59,183,180,105,174,207,242,230, 22,182, 70, 67,140, 87,141, 76, 30,234, 32, 15,255,118,121, 94, 43, 0, 53, +193,180, 78,217, 9, 64, 20, 0, 59,128, 75,210,199, 85,151,185,254,192,134, 31, 23,203, 40, 48,136,104, 18,134,140,244,163,154, +239,191,255, 12, 67, 20, 67, 96,211, 27, 52,221,187, 14, 7,195, 64,115,170,195,247,242,190,125,123,227,226,197, 43, 40, 45,209, +163,215,160,105,218,154,228,173, 92,173,145, 17, 80,104,127, 95,148, 70, 57,239, 3, 20,125,190, 1, 63,126,253, 21, 0, 41,182, +254,125, 13, 52, 13,205,103,239,188,133,243,231,207, 33, 50,178, 61, 36,126, 66, 92,191,118,190,198,228, 34, 89,191,124, 69,196, + 98, 49,252,252,252,112,233,210, 37,180,106, 22,140,166,194, 64,180,106,215, 4,161,126, 33, 8,160,236,160,105, 26,132,177,195, + 32, 17,162,244,102, 41,242, 99, 61,175, 77, 47,189,244, 37, 9,242, 43,197,160,251, 59, 34, 48, 64, 8,177, 31, 13,161, 0,160, +197, 66,116,105,253, 53,177, 18, 1,178,174,207,228,220, 97,150,255, 97,146,181,110,221, 26, 67, 6,183,209, 24, 77,102,208, 18, + 63,192, 10, 28,175,232, 39, 51, 26,244, 24,208,236,156,182,161,180,200,149, 43, 87,146,196,196, 68,126,217, 79, 35,128, 39,162, +175,227,253, 1, 0,238,111,225,231,255, 97,110,110,110, 87,145, 84, 2,198,223,255, 99, 0, 43, 0, 84, 52,150, 58,184,116,234, + 15,217,229,211,233,183,237, 53,160, 72,248,248,159,210, 70,169, 31,127,248,225,172, 68, 44,246, 99, 24, 38, 36, 32, 48, 48,112, +252,132, 9,254, 0, 44,240, 50, 19,227, 93, 4,235,109,102,248, 94,218, 72, 61, 0, 53,144,191, 32, 64, 34,188,255,201,161, 29, + 63, 97, 8, 49,237, 57,119,243,243, 51,235,148, 59,164,143,171, 78,123,250,110,194,132,251,200,132,145,139, 97,173, 40,129,208, + 78,227,228,233,115,120,234,169,151,110,181, 8, 26, 56,144,177, 10, 77,219,181,214, 48, 21,101,176, 48, 20,118,239,206,144, 95, + 51,186,151,167, 84, 46, 34, 16,135,128,242, 15,198,209,211, 57,248,251,244,127,240,237, 79,219,157,215, 25, 6, 24, 59,104, 16, + 80,145, 7, 32, 8,151, 78,156,129,168,105, 19, 12, 25,216, 83, 83, 98,168, 69,103,161,104,128,162, 17,221,187, 31, 90, 4,136, +209,170,169, 20,193,225, 97, 8,149, 4, 33, 84, 42,128, 72, 32,128,213,110, 71,137,141,193,225,194, 35, 30, 43, 53,239,239, 15, + 72, 88, 8, 16,236,239,143,136,166,225, 8, 14,246, 7,161,237,176, 49, 21,176,195,142,192, 64,127, 52,109,209, 6, 81,157,246, + 18,117,122,237,123, 11,164,236,180,144,144,160, 0, 68,117,104,134,136,166,225,142, 12,108, 18, 41, 68, 38, 59, 0,160, 67,100, +123, 77,177,174, 4, 63,103,100,203,115,174, 93,135, 46,239, 10, 22, 61,215,175, 86,101, 32,117,113, 42,231, 65, 66, 49, 67, 33, + 15,109, 30,170,173,141,252,239,134, 18,240,198,127,255, 75, 0, 96,209, 43,175,212,203,111,188,190,100, 9, 1,128,143, 94,125, +213,103,121,191,239,219,247,148,197, 98, 89, 5, 0,143,200,229,180, 47,131,175,106,253,122, 71,142,120,151,101,211,132, 16, 80, + 20,229,252,151, 61,199,222,151,152, 80, 51, 97, 47, 88,144, 64,113, 37,117, 47,201,191,123,128,213,182, 33,168, 73, 72, 87, 0, + 16,251, 73, 97, 49,154,192,232, 13, 75,246,255,153,254,206,136, 71, 31,237, 6, 32,199,147, 16,179, 64, 76, 0,216, 42,255,232, + 74, 66, 16,214, 52, 22,245, 25,241, 0,206,238,222,228,213, 59,186,124, 58, 93,115, 95, 79,153, 60,178,219, 88,239,149,226,132, + 98,175,110,159, 60,121, 50,214, 39,168,107,189, 71,174, 46,168, 90,145, 77, 28,143,154,111, 98, 96,180, 57,222,171,190,242, 95, +213,128, 38,232, 28, 36,170, 85,222, 39,159,124,162,125, 99,206,203,205, 38, 62, 50, 41,208,100, 50,226,179,165,159,210,203,151, + 47, 55,205,158, 61,187, 53,128,235,245,221,247,182,109,219,166,216,184,113,227, 78,192,187,156, 3, 25, 25, 25, 36, 59, 59, 27, + 69, 69, 69, 40, 47, 47, 71, 80, 80, 16,194,195,195, 17, 25, 25,137, 65,131, 6,241, 6,195, 29,198,177, 99,199,170, 28,187,219, + 82, 91, 88, 3,233,183, 5,208, 17,128, 0,128, 93,111,182, 93,205,184,144,191,108, 80,167,102, 47,141,236,222,242,157, 22, 33, +126,173, 52,235,148,235, 0,156,147, 62,174, 50,212,216,217, 43,138,209,226,190, 81,248,224,149, 71,176, 74,117,171, 47,166,239, + 79,129,222, 96,198, 56,197, 75, 24, 60,100, 6, 30,155, 60, 18,126,126, 18, 88,236, 54,148, 27, 44,154,206, 3,239,171,161,113, + 92, 1, 44,192, 35,211, 86,224,217,121, 73,206,179, 99, 7,203, 32,149, 74,240,235,238,237,216,186, 47, 3, 63,124,247, 21, 76, + 70, 51,196, 2, 33, 2,253,197,208, 23, 93,147,151, 92,131,219,221,199, 8, 33, 0, 97, 28,127, 52, 3, 66, 8,204, 22,137, 99, +120,146, 0,196, 98,135, 93, 0,216, 97,135,221,194,192,102,175, 93,129,189,116,232, 35,210, 38,130, 32, 56, 40, 0,173,219,116, + 64,215, 94,247, 33, 40,208, 15,165, 21, 5,200, 43,200,131,174,244, 38,172, 38, 10,254,254,254,136,136, 24,130, 71, 39,157, 32, + 27, 54,118,113,239,198, 95,115,149,216,131,130, 96, 20, 2, 98,169, 24, 70,131, 24, 22,131, 24, 38,169, 4, 66,202, 6, 2, 1, + 76,198, 10, 24, 13,229,104,211,166,149, 70, 44, 16,162, 24,101, 88,182,236, 79, 72, 36,181, 55,142,255,254,240, 95,143, 13,232, +149,233,175,212,122, 93,167,211,145,106,199, 49, 97, 97, 97,231, 41,138, 50, 17, 66,132,161,161,161,254,151, 46, 93, 10, 79, 77, + 77,213, 38, 38, 38,182,242,181, 33,139,155, 55,127,220,249, 27,128, 44, 20,168, 55,111,199,202,212, 84,242,252,243,207,203,173, +249,249, 94,201,252,125,223, 62,101,255,254,253, 23, 13,141,142,134, 85, 34, 65,114,114, 50,243,232,200,145,113,132, 16,181, 87, +166, 28, 69,225,147,119,222,113, 30,207, 95,184, 16,201,239,190, 91,235,177, 39, 84, 87, 2, 22, 47, 78, 37, 49, 49, 49, 80,171, +179,136, 66, 17,213, 3, 64,214,226,197,169, 70, 47,201, 63,163, 87,143, 30,193,108,159, 9,144,250,225, 70, 65, 62,202,116, 37, +232,215,127,128,255,239,223,126,167,126,104,230,127,122,192,177, 25, 66,109,176,189,184,104,185,240,137, 71,199, 11, 59, 69, 70, + 50,172,101,184, 48,249,139, 42, 55,189, 59,255, 5,135,226, 55,103,182,124,250,132, 56,175,223,171, 79,228,239,212,144,195,188, +184, 89,225,149,232, 0, 33,133,191,223,125, 26, 84,112, 83,216,179,254,134, 57,235, 20,206, 23,235, 17,251, 71, 62,167,239,167, +168, 84,123,230, 41,159,111, 63,253,153,153, 77, 82,215,252,196, 68, 70, 70,210, 31, 44, 94,130,160,119, 62,192,175,191,254,154, +251,240,195, 15,251,164,136,214, 64,252,113, 27, 55,110,220,193, 30, 79,154, 52,105, 52,151,239,149,151,151,203,118,236,216,161, +177, 90,173,232,216,177, 35,134, 13, 27,134,144,144, 16,148,148,148,224,250,245,235,184,124,249, 50,174, 95,191, 78, 70,143, 30, + 45, 15, 10, 10,106, 48,207,229,191,137,252,217,115,213,149, 0,161, 27,242, 15,143,237, 16, 62, 61,186,125,216, 52,138,162, 68, +132, 16, 43,227,248,179,216,173, 38,163,152,102, 90,245,106, 33,125,165,105,112,199,251, 54, 30,190,252,147,105,157,114,143,244, +113,213,141, 90,134,111,116,239,214, 5, 52,173,197,249,146, 34, 0,103, 80,154,123, 1, 34,169, 4,155,182,124, 14, 67,161, 29, +211,254, 51, 23, 12, 3, 76, 24, 63, 8,118, 97,160,199,135, 59,127,254, 12, 24, 6, 24,215,135, 2,208, 10, 64,123,152,204, 22, +196,143, 29, 13,105, 19, 26, 63,172,221, 6,154, 6,210,126, 90,133,220,172, 83,242,135,101,157,180,231,254,114, 47,139, 33, 0, +195, 48, 96, 24, 6,118,187, 29,102, 17,129,149,178,194, 98,177,192,224,111, 2, 24, 41,104, 98,135, 93, 76, 80, 97, 49, 65, 95, + 86, 90,107,217, 34, 2,205, 16, 10,253, 16, 30, 30,142,251,238,187, 15,205, 91, 12, 0, 4, 52,236,246, 35,160, 73, 9, 76,122, + 27,236,140, 30,121,215,139, 17, 17, 94,136,240, 38, 67,160, 43,127, 93,230,110,211, 24, 63,147, 13,196, 92, 8,152, 36,176,208, + 86,232,197, 66, 84,248,137, 32, 20,137, 1, 38, 0,148,128, 66,133,222, 0, 93,222, 21, 92, 58,178, 15,197, 57, 57, 96, 24, 6, + 52, 17,248,212,104,190, 93,241,173,243,243,204, 89, 51, 61,143,147,149,251,186,179, 77, 39, 53, 53,117,193,188,121,243,146,114, +114,114,104,138,162, 34, 84, 42,213, 79, 0, 58,161,110, 59,226,136,190,252,242,203,181, 55,111,222, 68, 90, 90, 26, 98,187,116, + 17,132,246,234, 85,231, 14,242,209,171,175, 82, 58, 64, 70, 8,209, 44, 95,190, 92, 3, 0,202,201,147, 57, 91, 37, 22,139, 37, +101,104,101,103, 18,139,197,232,220,185, 51, 54,236,222,189,179,210, 27,192, 89,206,157,218,170,118,193,130, 4, 74,173,206, 34, + 71,142, 56, 60, 86, 46,255,158, 26, 49, 98, 68,238,130, 5, 9, 33, 92, 57, 43,192,106,219,208,171, 71,143, 96, 1, 77,227,185, + 39,166,193,104, 50, 35,249,155,111,224,239,231, 7,147,201, 4,147,209,136, 62,125,163, 59,109, 95,179,230,249, 49,211,166, 45, +243,228,117,124,119,254, 11, 12, 0,250, 66,118, 54, 93,157,240,171,119, 79, 95,158,189,109,215,225,114,117,234,107, 36,110,194, +211,114, 34,233,228, 19,193,184,238,218, 71,214,135,122, 60,239, 81,131,106, 34,196,149, 10, 59,210,227, 34, 32,122, 73,133,178, +105, 29, 32, 12,109,230, 21,249,239,218,181, 43, 47,178,101,171,235,207, 60,151,212,246,181,185,175, 98,249,119, 41,167,251,247, +235, 23,149,242, 69,138,255,156, 87, 95,198,154, 65, 3,176,118,237,218, 39,167, 78,157,250, 67, 29,137, 95,182,113,227, 70,167, +193,164, 82,169, 46, 1,120, 17,192, 46, 46,223,223,177, 99,135, 38, 34, 34, 2,125,251,246,181,209, 52, 45,116,120,103, 25,136, + 68, 34,132,133,133,161, 69,139, 22,184,124,249, 50,118,236,216,161,121,244,209, 71,121, 79,192, 29, 34,255,196, 5, 31,223, 50, +116, 22,191,230, 86, 9,112,231, 1,160,133, 2, 90,104, 99, 72,185,141,177,155,252, 68,194, 54,129, 98,186, 27, 24, 27,208,105, + 4,208,226, 62,224,230, 5,180, 60,183,111,210,147, 67, 58, 68,110, 58,118, 67, 90,188, 78,185, 9,136,174,161, 56, 12, 4, 2, +150,144,130, 1,180, 65, 72,235, 46,184,114, 46, 13, 43, 84,223,129, 54,251, 99,180,124, 8,182,237,218, 7,131, 1,240, 15,171, +121, 92,242,243,239, 2,163,225, 28,236,118,187,171,195, 29,192,117,208, 2, 25,166, 63,245, 52, 24,137, 30,191,111,249, 22, 19, +198,207,132,127, 0,160,175,184, 81,201, 65,238, 97,133, 0,162, 74,242,183,218,236, 48,151, 89, 97,176, 26, 80,226, 39,132,213, + 32,130, 89,104,133,192, 74,193,102,103, 80,102,180,161,184,194, 86, 35,155,253,173, 89, 76,162, 90, 80, 16, 8, 40, 80,180, 4, +118, 59,129,205,144, 3,179,221,138,220,188, 82, 20,235, 42, 80, 90,110, 7,109, 50,193,134, 60, 8, 68,199,208,170, 93, 25, 6, +244,139,209,252,180,250,140, 91,153, 2, 0,164,220, 4, 99,249,117,216,111,150, 66,208,177, 13,104,154,134,221,102, 70, 73, 94, + 54,206, 29,202, 64,193,149,156, 74, 34, 17,130, 22, 2, 16,220,157,105, 64,214,229,191,114,229, 74,115,124,124,124,183,232,232, +104,155, 68, 34,209,127,250,233,167,253, 1,172, 4,208, 25,117, 92,105, 34,110,222,124, 62, 0, 12,236,217, 19,205,155, 55,207, + 95,190,124,185, 26,128,188,111,175, 94,117,182, 28, 66, 1,173,114,242,100, 74,212,172,153,108,249,242,229, 26, 81,179,102, 50, +111, 60, 1, 86,137, 4, 34,179, 25, 27, 54,108, 64,179,102,205,240,200,232,209,172, 55,128,120,163, 4,220, 41,176,164,175, 82, +169,156,231,148, 74, 37,210,211,211, 91, 15, 28,152, 48, 30,192, 26, 14, 98,238,111, 18, 26,218, 85, 64,211,248, 79,124, 60, 74, + 74,203, 80, 80, 92, 4,145, 72, 8,161,208,241, 39, 18,137, 32,241,243, 71,199,200,200,165, 23, 51,143,252,125, 95,108,140,198, +147,208, 11,217,217, 88,189,225,183,219, 44,126,214, 19, 48,160, 95,111,140,147,143,240,242,137,203,101, 64,144,182, 75,175,113, +218, 46,157, 59,201,119,110,254, 70, 3, 52,142,185,255,227,223, 47,131,121,219,119,104,246,245, 81,116,111, 34,132, 32, 56, 12, + 54, 93, 62, 98,255,200, 71,128,144,130,222, 70, 32,240,208, 83, 46, 95,188, 88,180,117,243,150, 46,223,127,253, 61, 62,255,230, +171, 43, 41,159, 46, 91, 24, 22, 30, 86,242,193,162, 15,118,253,176,118, 13,134, 13, 28,130,213,169,235,190,111,219,190,237,247, +195,134,248,182,125,120,117,242,223,188,121, 51,218,180,105,211,241,240,225,195,211, 0,108,227,226,246,183, 90,173,232,215,175, + 31, 99,179,217,132,229,229,229,144, 74,165, 96, 24, 6,103,207,158,197,249,243,231, 17, 24, 24,136,152,152, 24,228,229,229, 33, + 35, 35,131,240,211, 1,119, 97,172, 94,240,177, 83, 9,168, 66,246,213, 79, 72, 31, 87, 21, 28,184, 88,144,178,234,207,139,115, +207,230,150,238,160, 65,132, 0, 1, 30,122, 31, 7, 98, 62,197,135,186,120,236,238,177, 4, 24,243, 58,130, 68, 76,223,177,209, +145,211, 42,167, 11,110,195,230,221,197, 20, 80,134,137, 79,189, 4,134, 1,128, 98, 0, 65, 0,172,104,223,165, 31,164, 18, 33, +236, 54, 51,136,197,177,117,100, 80, 80, 16,138,138,117, 53, 62,196,178,165,243, 40, 0, 56,125,224, 27,208,116, 85, 35,129, 49, +158,130,201,108,133, 64, 36, 5, 37,118,204,161,149,151,149, 97,208,160, 65,181,155, 35,140, 5, 12,195,192,102,179,193,108, 54, +163,130,177,161,212, 98, 69,217,141, 50,148, 94, 47, 69, 89, 94, 49,138,203, 74,144,103, 50,160, 76, 95,130, 18,115,205,177, 78, + 65,129,122,216,108, 12,204, 22, 59, 74, 74,203,112,254, 98, 14, 14, 29, 57,142, 3,135,142,227,204,217, 75,184,118,181, 16, 21, +122, 11,202, 43,204,184,145, 91,138, 19,167, 46, 35, 35,227, 47, 92,187,145, 87,163, 76, 87, 85,199, 86,170,199,181, 99,103,112, +242,143,221,216,249,221, 82,236, 94,247, 29,174, 93,186, 8,134, 88,193, 80,148,147,248,189,233, 77,158,220,252,158, 32, 20, 10, + 1,224, 38,128,155,161,161,161,215,130,130,130,204, 11, 22, 44, 56, 12, 71,192, 24, 13,192, 4,224,188,175,242,191,252,242,203, +143,226,227,227, 1, 0, 29, 34, 34,154, 85,206,137, 11,234,179,115,176,164,207,122, 2, 56,184,255, 21, 0,144,156,156,140, 11, + 55,110,224,145,209,163,193,122, 3,142, 31, 63, 14, 0,248, 69,163, 33, 92, 95,197,252,133, 11,241,242, 59,239, 56,221,251,236, +103,246,152,253,204,197,253,207, 66,173,206, 34,213,201,223,245, 88,173,206, 90,205, 69, 78, 19,161,240, 67,147,197, 12,129, 64, +128,179, 89,151,144,117,237, 42, 14, 30,251, 27, 22,139, 21, 52, 40, 8,133, 66, 80, 20, 5,198,110,135, 81,111,192,241,116,237, +110, 14, 98,105, 87,242,127,226,209,241,183, 89,252, 7,143, 30,135,171,135,128, 27, 92,220,201,146, 78, 90,150,248,213,169,175, + 17,145,237,130,172, 65, 71,224,226, 27, 16,183,235,140,252,231, 7,227,248,247,203, 32,108,218,210,121, 41,255,249,193,104, 42, +165, 17, 44,172,189,185,116,233,212,165,149,191,127,128,255,231,255,251,210, 36, 31, 49, 66, 60, 96,208,192, 53,151, 47, 94,102, +206, 94, 60, 15, 48, 4, 82,137, 4, 67, 98,134, 96,203,230, 45,216,184,113,163, 87, 86,192,182,109,219,100, 74,165,146,176,228, +191, 99,199, 14,164,164,164, 88, 0,224,208,161, 67, 22,165, 82, 57,149,203,212, 66,118,118, 54, 42,183, 38,166,179,179,179,177, +115,231, 78, 28, 63,126, 28,122,189, 30, 58,157, 14,153,153,153,200,201,201,193,213,171, 87,209,190,125,123,100,103,103,243,236, +220,128,112, 55, 5,208, 28, 64,199, 73,177,237,158,107, 27, 30, 48, 13, 86, 35,208, 37, 14, 71, 35, 38, 97,228,236,111, 97, 44, + 44,129, 32, 56, 8,154,207,166, 99, 88,247, 3, 8, 59,190,115, 56,128,118, 53,253,192,125,193,109,112,242,248, 47, 46,250,134, + 30,142,105, 66, 43, 96, 53, 67,200, 8, 64, 87,246,251,141,191, 58,166,155,134, 60, 48,185,230,134,122,130, 96,108,223,158,174, +206,186,202,199, 16, 1, 34, 41,108,148, 29, 76,229,184, 59,101,218,139, 0,160,185,178,127,101,141, 61,203,206, 16,216, 24, 26, +180,205, 6,218, 98,134,161, 82,179, 48, 10, 4, 8,176, 25, 81,102, 36,160, 68, 20,236,118, 59, 12,118, 32, 95,111, 65, 77,147, +217, 54, 11, 3,147, 72, 0,198, 96,131,141, 41, 69,121,133, 21, 2, 74, 4,179,205, 10, 11,177,192,102,181, 0, 98, 6, 52, 5, + 80, 18, 6,165, 70, 59,242, 10, 12,208,155,109,110,157, 49, 52,101,119, 42, 0, 20,117,139, 79,172, 38, 35, 74,139,139, 65, 83, + 2, 8,133, 4, 32, 66, 8, 40,223, 39,254,206, 93, 57,103,233,210,190,139,152,139,219,191,138,155,148,162,224,231,231, 7, 0, + 70, 0, 22,161, 80,136,172,172, 44, 44, 94,188,120, 60,128,171, 11, 22, 44,232, 27, 18, 18,210,164,180,180,244, 74, 73, 73,137, +215,238,110,113,243,230, 51, 1,160, 69,139, 22,206,115,179,103,207, 46,249,226,139, 47,212, 0, 20,125,123,245,218, 85, 95, 29, + 97,246,236,217,114, 46, 10,192,239,251,246,201,250,247,239,223,122,104,116, 52,168,160, 32, 44, 94,188, 24,175,190,250, 42, 68, + 34, 17,172, 58, 29, 66, 66, 66,240,218,236,217,206,184, 0, 46,193,129,213,231,248, 61,197, 4,212,132,197, 94, 4,119, 30, 57, +114, 4, 71,142, 28,113,222,239, 46, 64, 8, 0,116,197,197, 93, 3,131,130, 80,168,211, 65,115,240, 32,132,180, 0,102,171, 21, + 6,163, 17, 12,195, 56,131, 21,109, 86, 11, 44,102, 51,151,119,204, 0,160, 43,167, 1, 24,151,134,111,170, 60,143,133,201, 95, +136, 1,160, 83,100,100,254,229,211, 39,235,244, 94, 21, 9, 31, 83,103,143,166,201,254,216,248,141,166, 62, 60, 1,222,184,253, +171,184,101,215,127,141,232,167,230, 66,210,161,183, 99,172, 40,188,129,243,197,122,135,174, 50,232, 33,228,216,109,240, 95,126, +176, 86, 25,101,101,101, 77, 36,126, 82,220,215,161,131,244,242,181,171, 45,139, 10,138, 48,229,137,105,154,173,187,118,226,179, +143,147,211, 54,110,221, 28,223,169, 67, 39, 76,127,244, 73,100, 28,221,135,141, 27, 54,144, 73, 28, 92,236,174, 86,255,142, 29, + 59, 16, 23, 23,199, 42,139,226,235,215,175, 35, 41, 41, 73,204, 62,190, 39, 89, 69, 69, 69, 24, 54,108, 24,236,118, 59,178,179, +179,177,111,223, 62,116,239,222, 29, 33, 33, 33,104,219,182, 45,162,163,163, 65,211, 52,104,154, 70,203,150, 45,157, 94, 42, 30, +141, 64, 1, 48,173, 83,118,106, 30,226, 55,244,129, 62,173,147,130,253, 68,253,109,118, 70, 39, 36,246, 96, 52,105, 41,184, 81, + 98,130,177,176, 20, 16, 11, 97, 47, 41,199, 53,157, 5, 8,111, 7,154,177, 72, 81,203,106,130,139,101,101,232,220, 36, 24, 54, + 51,112, 81,187, 26,247,201,198, 56, 13, 56,171,197, 10, 17,104, 84,152,204, 0,128,177,178,126,240, 11,111, 93,107,129,199,246, +162,176,245,111, 2,145, 20, 16,183, 27, 3, 75,206, 30,167,225, 32, 18, 75, 96,133, 9,129,126, 82,135, 7, 98,235, 58,156, 60, +164,149, 79, 27, 29, 83,243,104,196, 48, 16, 91,140,176, 66, 12,154,182, 1, 38,199,192,102,181, 90, 97, 54,137, 32, 16,138, 0, + 19, 64, 24,199, 20, 65,251,200, 14, 53,202, 50,152, 24, 8, 4, 20,172, 54, 43, 76,102, 6,101,229, 38,199,115, 50, 4, 22, 51, + 3, 8, 1,129, 72, 0,161, 20,160,140,118, 48,148, 13, 12,140, 40, 55, 86, 58,164, 61,192, 14,128,102, 0, 66, 1, 52,205,128, +162, 4, 96, 8, 5,154,174,140,165, 98,104, 48, 52, 13,138,225,102, 32,187, 88,255, 98, 95, 27,144,191,191, 63, 42,173,253,136, +172,172,172,252,197,139, 23,203, 1, 60,188, 96,193,130,209, 81, 81, 81,250,242,242,242, 34,155,205,230, 36, 10,111,248,255,203, + 47,191,252, 38, 62, 62, 30,145, 77,155, 58, 79, 70, 54,109,218,164,210, 11, 16,209, 16, 29,198, 98,177,104, 88,107,159,148,151, +227,237,183,223,134,185,168,200, 25,249,118, 95,165,178, 34, 50,155, 49,126,252,248,252,220,252,252,169,173,253,253,215,220,141, +178,185, 6,245,185,206,255,187, 67, 76, 76, 12, 20,138, 40,231,253,238,242, 0, 0,128,205,108, 65,137,165, 24, 38,147, 9, 77, + 66, 66, 32, 21, 75, 96,181,219, 64, 8,129,221,110,135,197, 98,129,213,106, 5, 99,179,115,125,191,204,133,236,108,186, 83,100, + 36,107, 17, 48, 23,178,179,233,213, 27,126,147,186,122, 4, 58, 69, 70,150,160,158,130,217,186,246,139,215, 94,187,148, 89, 47, +117,236,107, 12,192,136,157, 5,200,143, 76,131,184, 93,103, 80, 29,122,163,253,119,127,161,208,196, 32, 64, 72,193,178,247, 87, +156,203,186,236,113,255, 60,163,205,130, 35, 25,135,176,236,147,165, 24, 44, 27,138,183,222,123, 7,219,255,216,142, 53, 63,252, +136, 65,195,135,198,183,141,108, 7,161,191, 8,187,246,236,194,218,239,127,196, 47,191,110,192,150, 45, 91,200,131, 15, 62, 88, +163,100,165, 82, 73,170, 19, 63,139,146,146, 18,175,235,167,188,188, 28, 33, 33, 33, 7, 1, 12,136,140,140, 68, 76, 76, 12, 4, + 2, 1, 24,134, 65,251,246,237, 33,145, 72, 80, 90, 90,138,200,200, 72, 4, 5, 5, 93, 41, 47, 47,111,207,211,112,253, 34, 58, + 58, 26,199,142, 29,115,235,242,247, 52, 5, 16, 53, 41,182,221, 7,193,126,162,254, 5,101,166,237,251, 47, 20, 44,134, 64, 2, +156,219,131, 81,145, 4,175,191, 48, 30, 49, 61, 34,241,162,242, 1, 76,232,104, 1, 78,236, 0, 17,249,217, 80,107,176, 78, 9, +206,151,228, 64, 40, 1,198, 78,152,139,181,159,127, 12,192, 2, 24,204,176, 27,129, 95, 53,199,160, 62,236, 88, 81,216,166, 93, + 7,208, 66,207,228, 53,174, 15, 5,171, 9,216,188,101, 27, 98, 71,191,224,176,254, 33,130,192, 15,152,252, 80, 2,198, 13,159, + 8, 0,184,118,229, 18,108, 38, 75,237, 26, 61, 33,176, 81, 14,130, 55, 91, 28,193,127,102,147, 17, 6,131, 1, 21, 21, 21, 40, + 47, 43, 69,121,121, 57,202,202, 43, 96,170,168,128,209,104,172,185,241, 87, 80, 48,154,236, 48,154,236,208, 27,172, 40,175, 48, + 67, 87,110, 70, 73,153, 5,165,229, 86,148,148, 56,254, 45, 46,178,161, 88,103, 67,113,169, 13,133,197, 22,220, 44,172,185,140, + 52, 33,176, 3,160,236, 20, 40,154, 1,161, 8, 64, 8, 8, 17,192,206,220,122,125, 76,229,232,225,173,111,188,219,160,110,216, +183,117, 31,182,239,222,238, 84, 10,206, 93, 57,199,233,187, 2,129, 0, 66,199,251,106, 13,160,227,146, 37, 75,254, 6,176,252, +181,215, 94,155, 19, 21, 21,101,115, 56, 9, 28, 5,243,146,252, 41,113,243,230, 27, 1,160,121,243,230,183, 93,124,254,249,231, +109,153,231,206,173,251,235,196,137,122,115,235, 46, 95,190, 92,195,117,223,120,171,203, 18,139,159,127,254, 25, 23,243, 28, 83, + 56,191,107,181, 85,174,157, 59,119,174, 89, 68, 68,132,174, 33, 6, 1,133, 34,138,174, 28,224,171, 15,248, 85,174,123, 84,240, +130,131,206, 50,118, 59,202,138,117, 40, 44, 44, 68, 81,137, 14,122,131, 1,122,131, 1,229, 21, 21,208,151,150,161,188,164, 4, + 38,163, 1, 22,147, 9,140,205,238,113,204,233, 20, 25,201,142, 25, 12, 0,139,235,116, 0, 0,172,222,240, 27, 22, 38,127,209, + 4, 64,115,111,159,251,204,209, 52,153, 58,245,181, 42,141,237,210,169, 63,100, 13, 61, 40,223,152, 18,137,246,223,253, 5,170, + 67,111,152,211,211,112,229, 63,125, 17, 32,164,176, 39, 46, 2,182,210, 2,196,110,203,135,135, 25, 0,196,199,199, 83,207,190, + 52, 11, 23,207,157, 67,134,118, 15, 66,130, 66,240,248,148,199,209, 36, 60, 12, 71, 15,101, 34, 80, 44, 69, 64, 64, 0, 90, 70, +182,194,186,159,214,225,181, 55,223, 64,133, 15, 36,206,162, 95,191,126, 94,127, 39, 40, 40, 8,165,165,165, 3,104,154,182,180, +109,219, 22,253,251,247, 71,143, 30, 61,208,180,105, 83, 72,165, 82, 68, 70, 70,162, 79,159, 62,104,210,164, 9,202,203,203,219, + 7, 5, 5,241,140,125,135,148,128,218,142,107,154, 2,144, 8,104, 42, 40,167, 72,191,230,215,204,156,100, 0, 77,238,143, 10, +191,232, 87,120,185,139,244,151,231,176,104,228,139, 88, 20,215, 31,168,184, 10,252,250, 46, 80,124, 13, 21,240, 63, 1,160,150, + 48,214, 64,176, 57, 66,254, 62,254, 27,250, 68,143,199,255,189,245, 3, 54,253,242, 41,118,104,206, 64, 62,168, 7,132, 66, 9, +118,238, 57, 10, 34, 16,194, 98,183,115,126,200,177,125,187, 98,219,145,179, 64,242,199,136, 31, 63, 14, 15, 61, 52, 30,219,119, +111,132,205,106,194,131, 99, 30, 7,109,183, 66, 34,170,125,156, 35,140, 29,118,199,106, 71, 8,109,118, 88,137,208, 25, 19, 64, +211,142,252, 0, 52,229,240, 20,176, 30,131, 26,221, 95,198, 32,208, 2, 29,196, 18,218, 97,241,218, 9,236, 12, 5,134, 48,176, + 90, 9, 44,102,128,150, 18, 80, 2, 10,148,128,130,157,166, 96,182, 19,148,232,137, 7, 87,123,213,233,100,246,110,161,128,128, +166,104, 48, 68, 80,197,122, 32,148,103,178,125,101,250, 43,232, 54,168,155,243, 88,189, 74, 13,245, 42,199, 10,182,125, 91,247, + 1,227,112, 25, 64, 7,143,230, 28,227,248,173,180,180,180,189,149,131, 84,255, 14, 29, 58, 68, 0,168, 96, 24, 70, 98,181, 90, +253,109, 54,155,141, 16, 82,230,206, 21, 92,131,235,127,225,151, 95,126, 57, 46, 62, 62, 30, 29, 34, 34,184,180,219, 58, 65,212, +172,153, 12, 0, 98,187,118,149,123,186,183, 83,139, 22,242,228,228,100,205,248,241,227,203,206,157, 59, 23,124,254,252,121, 60, +172,112, 44, 5,235,210,165, 11,146,147,147, 49,126,252,120,203,185,115,231,196, 87,174, 92, 1, 41, 43, 51,246,234,214,173, 86, +153,243, 23, 46,172,226, 33,121,249,157,119,170, 40, 76,222,204,253,187, 54,237, 17, 35, 70, 60,151,158,158,254,149, 82,169,132, + 74,165,114,146,127, 76, 76, 12, 39,119, 46, 0, 92, 56,123, 41, 51,162,105,147,193, 22,139, 25,166,155, 6,136,165, 82, 8,133, + 66,167, 7,192, 88, 81, 1,179, 94,239,136,159, 41, 41, 65, 95,133,194, 83, 29,218, 88, 23,255,187,243, 95, 40, 6, 32, 29,208, +175, 55, 14, 30, 61, 94,229, 38,151,184, 0,206, 56,125, 52, 77,118,253, 82,166,166, 79,255, 91,101,184,124,113,191,172,164, 32, + 75, 83,151,246,193, 90,253,190,186,255, 1,224,124,177, 30, 57,207,220, 15,114,249, 56,154,125,125, 20,122, 27, 65,217,180, 14, + 8, 89,123, 25,101,255, 9,135,144, 2,104, 14, 10,232,243,179,103, 83,111,127,252, 1,105, 22,222, 20, 86,198,142, 11, 87,179, + 48,237,241,169,248, 97,245,106,108,250,117, 51,166, 78,155, 10,179,201,140, 61,153,251, 97, 52, 86, 32,113,198,140,244, 93, 25, + 25, 53,190,107,149, 74, 69,109,219,182, 77, 54,122,244,104,141, 59, 79, 64, 81, 81, 17, 94,121,229, 21,252,247,191,255,229,244, +156,225,225,225,184,126,253, 58, 66, 67, 67,133, 41, 41, 41,184,255,254,251,209,183,111, 95,136,197, 98,208, 52,141, 3, 7, 14, + 96,224,192,129, 0,128,235,215,175, 35, 60, 60,156,103,235,187,164, 4,112, 25, 72, 47,173,219,127,121,118,177,222,124, 4,142, +192,173,150, 25, 23, 10, 86, 14,239,218,252, 77,225,229,131, 97,248,238, 73, 64, 18, 0,152,245, 0, 33,176, 10,164, 55,247,156, +186,241, 13,128, 75, 53,253,192,218, 53, 95,201,167, 78,155,174, 1, 0, 61, 99,197,197,146, 28, 0,118,220, 23,220, 1,114,121, +111, 52,111,218, 2, 69,165, 14,110, 40,177,216,112,163, 68,143,218,134,203, 54,237, 6,225, 90, 78, 70,101,207, 20, 98,108, 31, + 71, 12,192,182, 19, 86,108,255, 61, 13, 55, 11,175, 35,188,137, 99, 37, 65, 19,177, 8,189, 99,107,175, 4, 11,132, 16, 51, 54, +216, 33, 0, 67, 81,160,237, 12, 96,181,193, 46, 18, 58,201, 31,112, 44, 23, 4,169,125, 85,210,195,143,189, 70,253,250,227,203, +196, 95, 76, 32, 20,185,120, 24,172,128,141, 0, 38, 11, 96, 55,219, 65, 81, 20, 40, 49, 5,155, 29,208,155,129,167,103, 44,161, +220,165,194,180,187, 48, 36, 67, 51,160, 42,221,255, 14,165,128,130,157,161, 65, 11, 28, 86, 63, 13,128, 8, 8, 64,184,121, 1, + 92,201,223,221,241,190,173,251, 60,146,191,221,110,135,217,108, 70,124,124,124,143,180,180,180,165, 0,162,211,210,210,182,165, +165,165,237,137,143,143,159,221,177, 99, 71, 43, 69, 81,225,159,125,246,217,142,215, 94,123,109, 90,113,113,113,122, 45,222, 39, +103,155,124,249,229,151, 23,190,252,242,203,216,182,109, 27,244, 55,111,222,118, 67,135,136, 8, 92,190,124, 25, 0, 52, 92, 18, + 3,213,148,244, 71,212,172,153,236,203, 47,191,212, 16, 66, 16,219,165,139,188, 31,135,149, 5,189,186,117,211, 82, 52, 61,230, +236,225,195,145, 0, 36, 0, 62,103, 87, 3,116,106,217, 18,243,230,205,195,190,125,251, 22,119,238,220, 57,189,103,235,214, 30, + 99, 20,220,229, 1,240, 53, 6,192, 21,108, 30,128,129, 3, 19, 14, 31, 56,144,191, 79,169, 84,138, 43,167, 9, 6, 3,200,224, +154, 4, 40,178, 79,247, 55,140, 55,242, 70, 51, 54,123, 87,125,105, 41, 74, 11, 11, 64, 81, 52, 8, 97, 96, 50,153, 64, 8, 1, + 33, 4,151, 79,159,129,213, 98,198,125,177, 49, 90, 47,198,156, 38, 0,232,113,242, 17,204, 56,249,136, 42, 65,127,149, 83, 4, +156,113,246,216, 47,178,235,151, 50, 53, 0, 16,217,190, 61, 54, 85,243, 2, 68,180,235, 39,111,200,193, 56,246,143,124,100, 62, + 0, 68,199, 40,144,255,252, 96,180,248,106, 63,206, 23,235, 17, 42,166, 80, 84,172,131,144,162, 60,122, 0, 88, 76,159, 62,189, +202,157,191,253,246, 27, 25,247,224, 3,248,125,243,239, 88,191,126, 61,222,121,243,109,236,208,238,130, 64, 40, 64,235, 54,173, + 71,148,150,214,190,116,121,236,216,177,218,177, 99,199,186, 85, 4,118,238,220,137,139, 23, 47,154, 84, 42, 85, 75, 46,101,139, +140,140, 68, 86, 86, 22,186,119,239,110,155, 51,103,142,248,167,159,126, 66, 72, 72, 8,206,158, 61,123,155,231, 53, 43, 43, 11, +145, 94,190,103, 30,245,139, 42, 10,128,244,113,213,169,226,117,202,243,210,199, 85,236,148,102,206,201,117,202, 63,202, 77, 54, +253,128,251,154,142, 11,243, 23,220, 47, 48,155, 2,108,132, 46, 47, 42,183, 28,200,184,152,183, 61,183,216,144, 46,125, 92,117, + 3, 53,228, 34,174,208, 71,104,147,158,159, 37, 7,160, 97, 4,236, 52,159, 0, 23,203,110,224,255,102,207,132,193, 96, 70,153, +209, 17, 3, 96,161, 37, 24, 57,182,246, 52,187,111,191, 57,131,218,182, 37,214,209,185,237,172,235,220,134,177,189, 40, 60,246, +220,167,240,247,151, 32,216, 79, 42, 7,160,185,112,242,168,124, 80,207,218, 19,130, 8,137, 13, 22,202,161, 4,128,162, 96, 39, +196,161, 8,216,108,149, 35, 52, 13, 33,195,192,198, 46, 59,240,160, 4,148, 24,155,192,104, 46,130, 88, 72, 59,211,156,217, 24, +192,106, 37,176,218, 8, 42,140,140,195,250, 7, 5, 43,115,203,117,239,150, 96, 25, 26, 52,101, 7,101,167, 64,104,226,116,255, + 83, 53,204,184,176,146, 94,156, 43,167, 86,172, 56, 91,171,133,119, 38,227, 76, 93,219,142,133, 16, 2,163,209,136, 94,189,122, +221,136,138,138,154,148,157,157,221,105,253,250,245,135, 0, 76, 76, 75, 75,155,232,122,243,199, 31,127,172,125,237,181,215,228, +197,197,197,158, 8,194, 89, 33, 73, 73, 73, 53,222,244,232, 83, 79, 1,240, 46, 49, 16,155,117,175, 58,250,119,235,230,213,178, +194,158, 93,186,236,112,245,100, 36, 39, 39, 47, 31, 63,126,188,237,220,185,115,194, 43, 87,174, 32, 50, 60, 60,163,181,191, 63, +167, 0,197, 59,145, 7,160, 26,185,223, 76, 79, 79,119,141,241, 56, 81,169, 8,112,205, 24,168,247,107,217,226,209,179,187,118, +103, 52, 9, 8, 8, 46,211,149,192,102,179,129, 84,246, 3,221,205,124,148,233,116, 32,132,112,177,254, 29,157,245, 86,204, 9, + 93,185, 28,144,174, 92,246,231,244, 10, 93,200,206,230,174, 4, 24,254,150, 93,187,112,200,105,229,111, 74,117, 44,255,139,136, + 26, 34,239, 19, 51, 94,219,112,195, 43,185, 93, 9,192,215,136, 78,250, 63,228, 49, 12,250,172, 58,132, 67, 99,155,163,199,239, + 55, 33,164,128, 32,145,111, 43,102,199,143, 31, 79,237,214,238, 38, 35,227, 70, 97,243,134, 95,241,254,226,143,177,160,180, 20, +132, 97,240,243,207, 27,144,155,155,251, 16,128,223, 61,122, 84,221, 40, 2, 0, 48,105,210,164, 99, 0,202,185,148,101,208,160, + 65,212,245,235,215,201,209,163, 71,197,253,250,245,195,168, 81,163,160,209,104,208,174, 93, 59,152,205,102,140, 24, 49, 2,132, + 16,230,232,209,163,180, 72, 36,226, 51, 2,222, 1,176,121, 0, 92, 61, 0,238,206,185,117,165,186,144, 63,123,124,230,202, 58, +101,206,149,194,138, 12, 0, 45, 43, 59,175, 25, 64, 46,128, 44,233,227, 42,163,167, 2,245,235, 51, 65,123,234,120,142,220, 78, + 2, 53,174,157,163, 66, 95, 6,129, 48, 4,160,253,241,234, 39,220, 83, 76,142,125,176, 39,245,193,172,135,100,160, 13, 26, 87, + 46, 12, 12, 12,129,221,170, 3,136, 30, 87,246,175,164,166, 63, 54,214,163, 44, 43, 4, 0, 33, 14,162,134, 0, 98, 82,169, 8, + 84,146,191, 35, 7, 32, 0,142, 83, 19, 51, 18,223,162, 86,126,241, 14,177, 89,139, 33,172, 92,216, 75, 8,129,221, 70, 96,178, + 2,101,229, 54, 88, 65, 96, 35, 52,132, 34, 10, 31,190,183,188,198,231,126,230, 25, 71,144,214,247,171, 46, 18,202,234,176,254, + 9, 0, 66, 40,128, 84, 90, 12, 68, 0, 74,192,128, 97,132,152,255,242,104, 78,117,248,204,251,207,200,179, 47,101,215, 70,192, + 34, 56,150,106,212,198, 78, 12, 0,152,205,102,232,116, 58, 93, 72, 72, 8, 98, 98, 98,254,238,223,191,191,164,160,160, 0,151, + 46, 93,114, 44, 15, 99, 24,217,134, 13, 27, 52,149, 74,128,134,131, 18, 96, 77, 24, 59, 54, 33,178, 87, 47,251,253, 93,187,234, + 43,219,168, 25, 85, 87, 68, 34, 97,172,227,221, 70,114, 72, 10,244,202, 43,175,200, 1, 32,182, 75,151,219,174,197,244,233, 83, + 39,130,232,213,173,219, 87, 52, 77,219,207, 30, 62, 28,208,188,121,243,194,158,131, 7,127,223,144,157,223, 13,169,235, 99, 98, + 98, 92,163,173,157,235, 88,189, 80, 2, 78,247, 29, 53,114,192,230,255,125,179, 33,170, 67,100,119,179,217, 4,187,213, 6,134, + 97, 16, 20, 26,138,210,226, 98,244, 85, 40,228, 28,172,127, 0, 40,121,119,254, 11,205, 0, 88, 46,100,103,139,217,249,255,131, + 71,143, 99,156,124, 4,179, 48,249, 11, 79,201,129,156,232,220, 82, 71,206,158, 59, 43,223,189,125, 83, 21, 23,255,200, 49, 19, +229,116,240,160, 58,189,215,154,220,253,238,207,115,231,176,216, 63,242,129, 63,102, 59,143,239,219,116,107, 9,112,169,213,238, +115,121, 71,202, 70, 82, 63,228,252,240,192,232, 7,199,110,125,246,201,167,247,246,238,211,107,232,230, 77,191, 33,227,216, 17, + 36, 38, 38,110,241,102,179, 24, 23, 69,224,233,141, 27, 55,254,111,227,198,141, 3,199,142, 29,203,185,112,163, 71,143, 30,185, + 99,199,142,221,191,255,254, 59,162,162,162, 16, 23, 23,135,144,144,144,243,165,165,165,157, 79,157, 58,133,172,172, 44, 90, 36, + 18, 97,244,232,209, 10,240,184,227,138,128, 55, 83, 0,110, 33,125, 92,165, 7,112,188,242,207, 39, 60,249,228,108,109, 82,210, +107,242, 20,213,251,154,214,237, 59, 1, 48, 67, 36,145,226,218,141, 50,140, 24, 63,157,242, 94,222, 4,237,125, 93, 59, 99,213, +183,191, 0,204, 21, 0, 66,216, 76, 70,180,110, 25, 34,111, 23,108,227,222,249,237, 12,132, 52, 3, 43, 37,132,136,216,110, 41, + 2,176, 1,196, 14,174,129, 97,174, 72,124,225, 29, 10, 0, 22,190, 62,139,136,132, 14,107,223,198, 56, 92,230, 37,229, 4,118, + 27, 32, 16, 50,248,234, 75,110, 74,207, 83, 51, 28,169,145,191,253,230, 28, 1,155, 19,158, 6, 24,202,225,238,159,247,242, 67, + 94, 21,178,180,162, 84, 27,218, 60,180,174,237,139, 6, 28, 49, 17, 70,163, 17,118,187, 29,101,101,101, 16, 8, 4,176,219,237, +104,209,162, 5,172, 86, 43, 84, 42,149,166,154, 39, 64,227,105,207,128,190,189,122,165, 1, 64,125,100,252, 3,128, 48,138,210, + 2, 64, 88,159, 62,119,196,204,235,209,165, 75, 74, 93, 4,212,103, 12,128, 27, 50,215,215,182, 26,192,139,116,192,103, 39, 60, +243,116, 79, 0,130,179,233,233, 86,147,193, 8,198,110, 71,183,152, 24,121,203,206,221, 17,217,167, 59,183, 62, 71,168, 41,219, +255,216,226, 60, 28,220, 61,202,249,121,251, 31, 91,110, 59,174, 45, 52,254,252,141, 80,138, 14, 30,132, 81, 99, 40,249,233,179, +151,112,227,202, 9, 13, 0,236,222,190, 73,211,188,221, 37,121,175, 1, 79,120,173, 4, 76,158, 60, 25,222,166,247,181, 83,181, +231,221,206,153,212, 2,127, 92, 55,221,241, 1,127,250,244,233,127, 0,160, 51, 51, 51,153, 93, 7,210, 17,222, 52, 28,117,217, +159, 99,236,216,177,223,140, 29, 59,246, 7,120, 78,239, 92, 5, 65, 65, 65,154, 71, 31,125,148,202,200,200, 32,151, 46, 93,194, +161, 67,135, 80, 94, 94,222,153,223, 11,224,238,128, 93, 5,224,238,188, 79, 10, 0, 7,112,146, 51,254,145,167,180, 91,182, 95, +164, 30,126,208,159, 52,107,221, 22,197,229, 54,140,120,240, 73,159, 27,194,160,251,187, 82,131,238,127, 3, 74,229,255, 17,224, + 38, 66,131,132,104, 23,198,120,213,233, 99,255,243,242, 29,107,136,239,126,180,130, 2,128,151,230,204, 38, 22,163, 21, 12, 28, +203,230,150,126,185,212,167,223,156,249,180, 99,207,128,111,255,119,150, 48, 68,128,215, 95,155,216,144,157,200,233, 86, 38,132, +192,108, 54,195, 98,177, 56,137,140, 37, 48,126,151,192,218,225, 77,250, 97, 31, 97, 89,176, 32, 65, 82,233, 65,177,215, 81, 22, + 1, 96,235, 58, 98, 68,149, 50, 71,182,108,193, 89,128,132, 49,107,159, 26,239,189,225, 87,125, 43,224, 42,246,119,240, 64,109, +143,254, 3,209,163, 63,234, 92,151,158, 54,246,169,174, 3,219, 40, 9,140,116,237, 43, 82, 47,149,219,208, 57,136,203, 16, 89, + 47, 77,129,196,198,198,214,103,155,178,250,250,197, 65,131, 6, 81,158, 18,177,241,184,115, 74, 0, 23, 80,209,209,209,132,175, + 46, 30,117, 69,167, 78,157,112,225,194, 5,190, 34,120,240,224,193,227, 30, 1,205, 87, 1,143,250, 0, 79,254, 60,120,240,224, +193, 43, 0, 60,120,240,224,193,131, 7, 15, 94, 1,224,193,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60,120,240,224,193,163, +193, 81, 37, 52,117,214,172, 89, 62, 71,143,186,203,100,199,203,227,229,241,242, 26,135, 60,165, 82, 73, 84,170,154,151,157,242, +245,199,203,107,132,242, 80, 7,121,248,183,203,243, 90, 1, 96, 7, 10,111,133,212, 54,176,212,183, 60, 30,141, 19,158, 8,134, + 71,227,124, 15, 94,222, 31, 0,224,254,189,123,247,126, 40, 16, 8, 6, 75, 36, 18, 24, 12,134,253, 67,135, 14,125, 19,192, 33, + 0,134,198, 80, 7,106,181, 90,150,154,154,170,249, 39,142, 43, 39, 79,158,196,161, 67,135, 56,223,223,191,127,127,244,236,217, +243,174,201,227,113, 15,123, 0, 88,120,147,158,148, 75,162, 28,119,242,106,218, 30,214,151,196, 59,255,244, 1,157,235,189, 99, +198,140,145, 63,242,200, 35, 90,174, 50, 91,183,190,125,235,229,220,220,220, 42,199, 9, 9, 9, 80, 40, 20, 20, 23,121,119, 82, + 9, 24, 51,102, 12, 1,128,237,219,183, 83,141, 65,158, 94,175, 31,181, 97,195, 6,245,249,243,231, 1, 0, 81, 81, 81, 19,102, +206,156,249,155,175,239,215,181,221, 19, 66,156,253,131, 61,207,246, 21,138,162,144,146,146, 66,213,166, 60,115,125, 15, 94,190, +175,238, 39, 79,158,220, 80, 86, 86,214,181,125,251,246, 40, 44, 44,132,201,100, 2,128,193, 27, 54,108,208, 4, 4, 4,156, 29, + 59,118,236,195, 0,106,221, 74,114,200,144, 33, 94, 25, 4,251,246,237,147,131, 99,170,103, 22,169,169,169,154,132,132, 4,185, + 66,161,208,122,251, 62, 18, 19, 19,189, 42,223,228,201,147, 57,247, 15, 22,237,219, 59,118,192, 45, 47, 47,135,217,108,102,219, + 19,167,254,118,232,208, 33,252,248,227,143,156,202,166,211,233, 48, 96,192, 0,168, 84, 42,212, 38,111,218,180,105,156,228,221, +188,121, 19, 31,126,248, 97,173,242,120, 52, 30, 84, 79, 6,116, 39, 19, 1,241, 86,236, 29,196,166, 20,207, 41,141, 31,158,181, +205, 43,153, 26,205, 45, 3,233,252,249,243, 8, 8, 8,112, 14, 66, 46,245,193,197,218, 34,213,143,171, 15, 96,106,181,154,164, +166,166,250,108,129,173, 93,187, 86, 54,102,204,152, 26,229,215, 5, 73, 73, 73,100,248,240,225,242,169, 83,167,122, 69, 22, 27, + 54,108, 80, 55,107,214, 12,211,167, 79,135, 78,167, 99,146,147,147, 55,235,116,186,199, 66, 67, 67,127,246, 70, 14, 69, 81,248, +227,143, 63,156,199, 99,199,142,197,182,109,219,106, 61,246,132,234, 74,128, 82,169, 36, 49, 49, 49, 88,185,114, 37, 97, 19, 51, +121, 75,254,165,165,165, 25, 29, 59,118, 12, 6, 0,169, 84, 10, 63, 63, 63,228,231,231,163,164,164, 4, 33, 33, 33,200,207,207, +239,186,109,219,182, 67, 99,199,142,237, 2, 32,175, 54, 97, 61,123,246, 68, 66, 66, 2,162,162,110,101,253, 91,188,120,113,149, +123, 22, 44, 88, 0, 0, 56,112,224,128,102,234,212,169, 94,191,111, 95,200,159,197,178,101,203,106,186, 84,227, 14,150, 92, 17, + 16, 16,128,211,167, 79, 67, 36, 18,193, 98,177, 96,219,182,109,184,112,225, 2, 94,127,253,117,175,228,220,172,182, 73,214,176, + 97,195,176,103,207,158, 42,231, 10, 11, 11,125,146, 85, 19,178,179,179,121,146,184, 71,201,159, 61,231,113, 47,128,123, 21,223, +126,251,173,108,230,204,153,218,186,202,185, 87, 92,217,173, 99, 63,184,101,181,103,190,229,147, 12,157, 78, 7,131,193,224,180, + 64, 86,174, 92,233,106, 9,113,181,182,110, 59, 86, 40, 20,216,185,115, 39,161, 40,234,182,235,190,224,207, 63,255,212,188,242, +202, 43, 72, 75, 75, 67,124,124,124,189,212,223,246,237,219,169, 93,187,118, 17, 66, 8,210,211,211, 53,233,233,233, 94, 41, 40, +231,207,159,199,244,233,211, 25, 0,180, 88, 44,166, 59,119,238,140,228,228,228,159, 0,252, 20, 21, 21,245,224,204,153, 51,183, +114,145,115, 39, 54, 3, 98,149,128,149, 43, 87, 18, 54, 13, 48,251,175, 82,169, 36, 9, 9, 9,222, 60,107,128, 78,167,219, 32, +149, 74,131, 1,224,249,231,159,135,201,100, 66, 74, 74, 10,252,252,252, 96, 50,153, 96, 52, 26, 33, 16, 8, 80, 90, 90, 26, 12, + 32, 25,192, 19,181, 9,100,201, 61, 43, 43,235,182,115,245,129,132,132, 4,121,229,115,202,125, 85, 4,230,206,157,235,252,188, +116,233, 82,246, 35, 93,237, 60,103,133,128,245,154,188,245,214, 91, 8, 8, 8, 64, 90, 90, 26, 70,140, 24,225, 19,249, 87,199, +176, 97,195, 48,109,218,180,219,148, 0,214,187,192,161, 47,212,119,243,147, 61,248,224,131,154, 45, 91,182,184,243,222,200, 70, +142, 28,169,161, 40, 10,187,118,237,226,221,189,119,152,252, 19, 23,124, 12, 0, 88,185,248, 53,183, 74,192, 93, 81, 0, 86,174, + 92,233,238, 69,147,154,206,251,242, 27, 7, 15, 30,212, 0,144,215, 85, 9,152, 54,109,218,191,102, 62,219, 96, 48,220,102,245, +251, 66, 52, 44,177,196,199,199, 35, 46, 46,142, 2,128,180,180,180,122, 41,227,218,181,107,101,149, 22, 29,149,159,159, 47, 75, + 77, 77,213,228,231,231,203,188,181,216,221, 97,212,168, 81,212,168, 81,163,176,118,237, 90, 89,122,122,186,102,237,218,181, 94, +201,213,233,116,182,208,208, 80,241,134, 13, 27, 80,233, 13, 48,233,116, 58, 58, 57, 57,121,139, 78,167, 27, 29, 26, 26,186,179, + 33,223, 47, 75,250,174,109, 89,169, 84, 18, 86, 73,227,136,251, 47, 92,184,208,181, 87,175, 94,120,250,233,167, 81, 90, 90,138, +162,162, 34,136, 68, 34, 8,133, 66, 8,133, 66,136, 68, 34,248,249,249,161,184,184, 24,106,181,122,170, 66,161,120,193,147,208, +172,172,172, 42,202, 33,171, 0,176,158,128,152,152, 24,111,202,232,206,250,151,167,166,166,106,234,226,121,114,129,173,134,177, +146,179, 55, 32, 59, 59, 27,233,233,233,120,240,193, 7,209,190,125,123, 52,109,218, 20,233,233,233,120,253,245,215,157,222, 55, +129, 64,224,117,193,134, 13, 27,134, 55,223,124,211, 57,118,185,243, 4,112,232, 99,156,188, 0,185,185,185,120,236,177,199,184, + 25, 40,173, 91, 35, 49, 49, 81,147,149,149, 5,181, 90,205,214,191, 44, 49, 49, 81,195, 42,208, 60,238, 44, 88,242,103, 63,179, + 74,192, 93,247, 0,212, 52,143,237, 75,128,224,157, 86, 2,198,141, 27, 87,103, 79,128, 55,207,229,205,111, 60, 58,123, 59, 54, + 44, 31, 83, 47,117,197,118, 64,165, 82,233,118, 78,111,255,254,253,117, 86, 12,234,227,253,254,249,231,159, 26,214,234,159, 58, +117,170,246,207, 63,255, 68,179,102,205, 52,168,167,196,233,172,220,244,244,116,164,167,167,123,116, 55,235,245,250,113, 27, 54, +108,216, 2, 0,201,201,201,226,168,168, 40,204,156, 57,147,189, 44, 61,126,220,177, 95, 86,114,114,242,142,168,168,168,135,103, +206,156,185,201,211,239,143, 29, 59,182, 74, 76,204, 3, 15, 60, 80,197, 51,192,197,237,239, 70,233, 38,238,218, 23,251, 94, 92, +167, 3,106,195,182,109,219, 62,236,220,185, 51, 0,224,226,197,139, 32,132,224,220,185,115,206,125, 31,132, 66, 33, 40,138,130, +221,110,135,193, 96,192,198,141, 27,161, 80, 40, 60,238,186,228, 74,254, 9, 9, 9,110,149, 23,215, 41, 2, 95,148, 0,133, 66, + 65, 41,149, 74, 82, 87,111, 64,125,140,147, 86,171, 21,253,250,245,131, 86,171, 69,108,108, 44,244,122,189,115,106, 71,171,213, + 98,204,152, 49,176,177, 91,144,123, 65,254, 0,240,225,135, 31,222,118,222, 91, 37,160,158,161, 61,114,228, 8, 98, 98, 98, 16, + 21, 21,133,126,253,250,145,163, 71,143,202, 89,242,207,202,202,130, 86,171,229,173,255, 70,128,187,162, 0,220,205, 32,192,250, + 80, 2, 34, 35, 35,235,228, 9, 96, 7,217, 53,107,214,184,189,190,117,235, 86,172, 89,179,198, 39,203,228,192,229,238, 24,216, +225,180,207,110,127, 22,174,115,254,106,181, 26, 10,133,194,233,246,223,191,127, 63,218,182,109, 91, 47, 74, 95, 93,172, 47,214, +250, 47, 44, 44,116,238, 51, 47,147,201,228,245,233, 5, 96, 49, 98,196, 8,121,122,122,186,198,211,125, 27, 54,108,216,194,206, +253,235,245,122, 44, 94,188, 24, 21, 21, 21, 16,137, 68,144, 72, 36,184,124,249, 50, 62,248,224, 3,232,116, 58, 36, 39, 39,255, +170,211,233, 70,134,134,134,106, 60,144,108, 21,178,247, 20, 19, 80, 31,138,231,145, 35, 71,170,220, 95,211,230, 33, 97, 97, 97, +131,205,102, 51,108, 54, 27,246,239,223, 15,129, 64, 0,139,197, 2,163,209, 8,134, 97,156,253,216,106,181,194,108, 54,179,125, +218, 99,152,120, 77, 46,255, 5, 11, 22, 56,189, 0, 81, 81, 81,200,207,207,175,179, 34,202,174, 10,240, 34,118,164, 24, 64,152, +187, 11, 46,211, 1, 94, 33, 57, 57, 25,175,188,242, 10,250,246,237,235,244,128,176,233,179,251,246,237,139,115,231,206,161, 89, +179,102, 94,201,172,111,146,103, 21,138,250,248,173, 35, 71,142, 80, 71,142, 28,145, 37, 38, 38,106, 98, 99, 99, 17, 27, 27,171, + 1,128,115,231,206, 33, 61, 61,157, 39,255, 59, 8,118, 55,192,149,139, 95,187,109, 10,224, 31, 27, 3,208, 24,149,128,105,211, +166, 17,214, 61,231,234, 10,244,133,252, 31,157, 93,191,243,116,122,189,254,182, 32, 63,214,234, 23,137, 68,200,203,203,107, 80, +242,119,181,254, 93, 45,183,199, 30,123, 76,171,213,106,235,221, 11,224,141,231,100,250,244,233, 6, 0,254, 1, 1, 1,120,251, +237,183, 33, 18,137,156,215,103,204,152, 1, 0, 8, 13, 13,197,248,241,227,177,119,239,222,221,227,199,143,191, 43,229,116,173, +111,215,249,127,119,136,137,137,169,178, 83,163,187,117,216, 0, 96,177, 88, 80, 92, 92, 12,147,201,132,144,144, 16, 72, 36, 18, +216,108, 54, 16, 66, 96,183,219, 97,177, 88, 96,181, 90, 97,183,219, 93, 21,250, 90,163,207,178,178,178,170, 88,247,213,167, 3, +170, 7, 8,214, 21, 10,133, 66,235,101, 44,138,180,166, 11, 53,196, 6,120,196, 7, 31,124,128, 7, 31,124, 16,145,145,145,240, +247,247,135, 76, 38, 67,113,113, 49, 2, 2, 2,160,211,233,176,106,213, 42,208,116,195,230,101,219,179,103, 79,149, 41, 5,118, +172,170,131,162,161,253,249,231,159,229, 83,166, 76,209, 0,192,207, 63,255, 44, 47, 45, 45,213,130,199, 93,131, 59,183,191, 43, +254,145,153, 0, 7, 12, 24, 32,175,143,128, 64, 95,173,116,215, 1,217,213, 61,231, 43,249,179,232,215, 55, 26,187,118,107,176, +118,183,191, 83, 41, 56,112,185,123,157,158, 49, 38, 38, 6, 89, 89, 89, 72, 75, 75, 67,219,182,109,241,253,247,223,251, 96,117, + 17, 25,251, 41, 41, 41,169, 94,200,159,181,254,243,243,243,229,213,175, 13, 31, 62, 92,158,150,150,230,188,167, 62,144,158,158, +174,225,234,125,210,233,116,103,224,152, 23,102,126,254,249,103,172, 90,181, 10, 0,240,211, 79, 63, 65,167,211,177,183,217,206, +157, 59,135,136,136,136, 6,233, 3,174,209,254,238,148, 51,174,219, 52,103,101,101,237,183,219,237,208,233,116, 40, 44, 44,116, + 6,142, 26, 12, 6, 84, 84, 84,160,172,172, 12,165,165,165, 48, 26,141, 48,155,205,176,219,237, 0,144, 81,155,204,234,228,238, + 46,144,180,250,170, 0,174, 80,171,213,178,234,207,172, 86,171,189,109, 39,254,245,253, 62,190,255,254,123,200,100, 50,248,251, +251,227,244,233,211,208,106,181, 8, 8, 8,192,255,253,223,255, 97,239,222,189,120,253,245,215,189, 86, 0,134, 13, 27, 86,227, + 95, 93,148,128, 15, 63,252,176, 62,200, 31, 0,100, 44,249, 3,192,148, 41, 83, 52, 35, 70,140,224,119,159,189,155,227,192,130, +143,171,196, 2, 84,199, 63, 38, 8,176,190,201,191,114,189,107,157, 45, 55,118, 58, 96,218,180,105, 62,147,255,163,179,183,163, + 95,223, 91,174,155, 13,191,108,196,134, 95, 28,159,119,237,214, 0, 35,229, 0,188, 91, 6,168, 84, 42, 17, 19, 19, 3,192, 17, + 12,120,228,200, 17,236,220,233,136, 89, 59,113,226, 4, 70,140, 24,225,133, 52, 74, 11,220, 10,252,171,107,164,254,218,181,107, +101,238,172,255,234,168, 47, 47, 0,171, 72,200,100, 50,185,167,123,163,162,162, 70, 39, 39, 39,239, 24, 63,126, 60,206,157, 59, +135,243,231,207,227,131, 15, 62,176, 1, 16, 26, 12, 6, 36, 39, 39,163,242,154,240,202,149, 43,120,242,201, 39, 61,202,188, 19, + 49, 0,172, 37,157,154,154,234,244, 98,177,196,200,190,119, 46,232,220,185,115,166,193, 96, 24,108,177, 88, 80, 80, 80, 0,137, + 68, 2,161, 80,232,244, 0,232,245,122, 24, 12, 6,152,205,102,148,150,150,178,243,249,215,106,147,201,146, 59, 59, 13, 16, 19, + 19,131,234,222, 10,119,113, 1, 92,200,159,205, 1, 80,253, 92, 93,218, 7,107,245,187,177,248,109, 92,199,208, 11, 23, 46,224, +220,185,115, 48, 24, 12, 24, 52,104, 16, 12, 6, 3, 82, 83, 83, 49,101,202, 20,108,222,188, 25, 2,129,192,107, 5,224, 14, 88, +236, 85,228,214, 69, 78, 76, 76, 12, 97,219,217,209,163, 71,145,153,153, 41, 79, 76, 76,212,116,233,210, 5, 34,145,136,184, 4, + 6,242,168,103,176,171, 0,220, 5, 1, 54,200, 42,128,187, 21, 4,216,216,200,191,186, 18, 80, 23,203,191,182,227, 93,187, 53, +190,116,208, 91,230,142,191, 63,186,117,235, 86,229,250,193,131, 7,189,146, 23, 31, 31,239, 84, 0,210,210,210,144,150,150, 86, +101, 85,128, 55,207,255,253,247,223,107, 0, 96,219,182,109,110,201,115,234,212,169,218,239,191,255, 30, 0,183, 37, 76, 53, 37, +253, 97, 21, 13, 66, 8, 70,140, 24, 33,127,236,177,199, 60,182,157,153, 51,103,238, 44, 46, 46, 30,181,111,223,190, 93,157, 59, +119,198,249,243,231,161,211,233,132,161,161,161,152, 57,115, 38,138,139,139,175,236,219,183,175,125,231,206,157, 49,125,250,116, +143,207,235, 46, 15,128,175, 49, 0,213,251,150, 74,165,162, 20, 10, 5,212,106, 53,169, 62, 45,195,245,125, 12, 28, 56,240, 13, +173, 86,251,162,221,110, 71, 89, 89, 25,172, 86,171, 83, 89, 49,153, 76, 32,132, 84, 9, 12, 84, 40, 20,143, 87, 18, 35,103, 40, + 20, 10, 40, 20,138, 42,203, 2,189,157, 2,112, 37,122,133, 66,161,173, 62,182,184, 42, 5,245, 8,206,227, 39,187,212,111,254, +252,249,208,106,181,144,203,229,184,112,225, 2, 2, 3, 3,145,147,147,227,147, 2,224, 74,214,172,129, 81, 95,113, 1,117,181, +252,217,241, 37, 43, 43, 11,153,153,153, 84,165, 33, 40, 79, 76, 76,212, 68, 69, 69, 65, 38,147, 17, 62, 16,176,225, 33,172,105, + 80,170, 79,184, 11,248, 89,188,120,113,141,231, 27,146,252,167, 77,155,118, 71, 82,134,214, 69,230,213,107,158,231,227,253,252, +188,243, 90,214, 54, 63,236, 11, 20, 10,133, 60, 46, 46, 78,187,107,215, 46,178,126,253,250, 42,138, 64,117, 82,226, 42, 51, 41, + 41,169, 70,205,134, 77, 74,226, 77, 98,160,154, 20, 78,185, 92,206,137,252, 89,132,133,133, 57,231,245, 79,159, 62,253, 68,114, +114,242,143,172, 71,224,202,149, 43,237,223,122,235, 45, 57, 69, 81,156,228,221,137, 60, 0,213,235,217,221,252,183, 23, 74,169, +126,196,136, 17, 11,183,110,221,250,174,205,102, 67, 73, 73,137, 51, 6, 0, 0, 10, 10, 10, 80, 82, 82, 2, 66, 8,107,181,123, + 53,217,206,206,255, 87, 95,246, 87, 61, 78,128, 43,249,187,190,231,198,182,148,151, 85, 2, 94,123,237, 53,164,167,167, 99,252, +248,241,248,232,163,143,240,242,203, 47, 67, 40, 20, 66, 42,149,114,146,227, 50,205, 84, 47, 22,123,117,121,245,129,220,220, 92, +184,201, 3,160, 93,185,114,165,124,228,200,145, 26, 95,150, 60,242,240, 14,238,130, 0, 57, 41, 0,222, 36,229,240,149,176,235, + 27,245, 65,254,141,113,208,120,233,165,151,228,103,207,158,173, 87,153,149,214,144,166, 62,101,178,132,199,174,173, 7,224, 76, + 6,196, 48, 12, 54,108,216,192, 89, 9,120,229,149, 87,216,114,222, 22, 3, 64,211, 52, 24,134,193,171,175,190,170,225, 74,158, +181,201,171,235, 74,130,153, 51,103,174, 46, 46, 46, 46,216,183,111,223, 54,174, 86,255,157,246,182, 85,175, 95,119, 46,118,111, +148, 0,138,162,222,123,240,193, 7,211,214,172, 89,115, 74, 44, 22,131, 93, 21,192, 48, 12,154, 52,105, 2,157, 78,199,166,176, +245, 7, 96,231,106, 16,184, 6,255, 29, 57,114, 4, 10,133,162,202,120,226,105, 28,202,202,202, 34, 89, 89, 89,242,234, 46,254, + 58, 46,249, 3, 80,163,187,223,182,116,233, 82, 41, 0, 11, 28,241, 83,236,159, 87, 74,128,107,226,159,231,158,123,206,249,185, +172,172,140,147,140,235,215,175,223,150,228,231,167,159,126,186, 45,141, 55, 87,184,147, 87, 71,104,183,108,217, 82, 83,155,210, +238,222,189,155,183,252,239, 32,216, 85, 0,238,136,159,211, 42,128,250, 38,245,154,228, 53, 22,229,161,177,146, 63, 0,116,239, +222, 93,219,189,123,247,122,149, 89, 57, 56,222,241,103,117,117,255, 87, 39,169,154,150,157, 85,150,143, 75,217, 40, 47,158,247, +142, 62,107, 88, 88,216,246,186, 68,250,215,103, 12,128,187, 54, 92,155,183,199,139, 54,127,122,218,180,105,129, 59,118,236, 88, +148,147,147,243,162,209,104,132,221,110, 71,116,116, 52, 98, 99, 99,147, 21, 10,197, 2, 46,228, 15, 0, 7, 14, 28,112,126,118, +141, 53, 57,112,224,192,109,199,181, 33, 42, 42,138,170,244, 18,200, 1,104, 88,101,194,101, 42,192,235,119, 50,121,242,228,154, + 46, 9, 93,198, 75,113, 67,141, 43,253,251,247,199,164, 73,147, 56,223,255,194, 11, 47,220, 85,121, 60, 26,159, 18, 80, 19,249, +187, 85, 0,234,155, 4,249, 29,226,120,184,107, 3, 53, 45, 59,227,235,166, 81,255,134,126,244,232,209, 47, 1,120,201, 87, 1, +251,246,237,163,166, 78,157,122, 71, 20, 90, 95, 51, 7,222, 77,101,177,174,232,217,179,103,189,110,198, 83,223,242,120, 52, 46, + 37,192,163, 21, 21, 29, 29,205, 15,196, 60,120,240,224,193,131,199,191, 12, 52, 95, 5, 60,120,240,224,193,131, 7,175, 0,240, +224,193,131, 7, 15, 30, 60,120, 5,128, 7, 15, 30, 60,120,220,131,176, 1, 96,248,106,224, 81, 27,132,124, 21,240,224,193,131, + 7, 63,182,243,248,151, 55,146, 89,179,102,249, 28, 1,235, 46,170,187, 54,121,158,214, 31,123, 43,175,190,203,199,203,227,229, +253,219,229,253,245,198, 21,159, 7,150,190,139,218,227, 78,203, 59,242,186,239,242, 98, 62,186, 93, 94, 82, 82, 18, 5, 0, 20, + 69,201,172, 86, 43, 46, 95,190,172,177, 88, 44, 16, 10,133,184,118,237, 26, 30, 15,137,196,246,204, 76, 24,123,183,197,192,129, + 3,229, 2,129, 0,132, 16, 45, 0,164,164,164,220,241,247,193,150,207, 21, 20, 69,117, 7,208,236,212,169, 83, 91, 90,181,106, + 69, 23, 23, 23, 75, 91,181,106,245,129,159,159,223, 10, 0,215, 43,151,147,210, 41, 41, 41,246, 90,228, 5, 85,122, 11, 12, 20, + 69, 17, 0,184,122,114,245,215,202, 97, 57, 51,215,102,118,190, 44,108, 54,122, 96, 96, 80,112, 5, 0, 66, 8, 17, 2, 8, 77, + 73, 73,185,122, 23,218, 51,234, 32, 15,255,118,121,119, 84, 75,228,154,109,203,219,236,111,190,164,204, 45, 89,245,139, 76, 24, + 22,162,185,116,254,162,252, 62, 73, 32, 2, 94,152,166,109, 76, 90, 86, 77,249,200,249, 37,146, 13,143,205,155, 55,203,182,110, +221,170, 73,126,195,113,252,235,158, 97,152, 54,109, 26,167,247,178, 39, 99,191,140,166, 40,205,185,179,103,161,211,233,208,190, +125,123, 4, 6, 5, 97,108,220,104,206,239,117,231,206,157, 85, 6,190,180,180,180, 90,247, 82, 72, 75, 75,243,185,221,176, 27, + 53,165,164,164,212,173,221, 37, 20, 87,126, 32, 0, 40, 32, 53,204,119, 89, 49, 75,129,168,167, 28,159,179, 86, 1, 71,230,213, +253,165,198, 23, 86, 45, 95, 90, 83, 78, 95,163, 40,138,232,245,122,249,142, 29, 59, 52, 89, 89, 89, 72, 16,133,163, 69,219, 8, +152,244, 70,248, 25,108, 24,242,242,179, 24, 62,126, 10,126,255, 38, 5,191,237,218,165, 25, 61,122,180,188, 17, 52,225,243,118, +187,189,101, 86, 86, 22,211,167, 79, 31,113,231,206,157,113,244,232,209, 55, 76, 38,211,131,157, 58,117, 82, 80, 20, 85, 76, 8, +241, 52, 21, 80,238,122, 96,179,217,232,191, 51,255,234,212,230,233,190,120,181,127,143,136, 3, 59, 62, 89,191,225,132,236, 88, +167,158, 35, 63,170,148,119,173, 82, 97, 96,120, 79,195,191,204, 77,228,109,254,126,111,242,224,123, 75,254,246,181, 91,100,131, + 34,218,104,168,214, 81,184, 80, 81,130,150,173, 34, 53, 86,198,142,179,203,191, 71,126,251, 8,121,255,241,227, 56, 41, 2, 71, + 52, 74,210,181, 35,123, 36,192,198, 29, 12,246, 28, 38, 72,124, 12,232,218, 17,152,247, 97,221,136,155,221,160,164,174,217,201, +220, 41, 19,245, 37,183, 46, 72, 76, 76, 36, 88, 72,129,122,175,230,123, 8, 33,192, 66, 10,147,207, 36, 52,154,181,214,183,200, +159, 84,146,255,112,236,221,187, 23,211,166, 77,243,248,221,222,125,118,144,238,221, 99,145,154,122, 3, 7, 51, 28, 9,107,206, +159, 61, 7, 0,120,230, 63,191,144,115, 23,227,229, 1, 82,110,239, 37, 46, 46,142,217,185,115, 39,157,150,150,134,221,187,119, +215,186, 17,147,175, 41, 84,107,234,183, 73, 74, 37, 73,241, 65,161, 96,211,133,215, 57,149,113,212, 83, 85, 55,219,169, 15, 5, +192,165,158, 42,119, 39,228,132, 75,151, 46, 65,187,126,189,230, 61,197,100, 68, 79,123, 14,226,230,161,128,176, 50,217, 31, 67, + 0, 70, 4,198, 76, 48,238,169, 68,228,124,254, 49,246,239,223,175, 25, 60,120,176,156,245, 2, 52, 16,236, 52, 77, 55,107,218, +180, 41,180, 90,173,176, 79,159, 62,232,223,191, 63,157,151,151,215,247,239,191,255, 62,217,187,119,239,126, 20, 69,229, 85,146, + 53,205,177,238, 2, 71,141,140,139,250,232,211,205,244,130, 25, 39,130, 7,142,157, 37, 31, 56, 64, 61,236,229, 47,174, 61,212, +249,254,233, 49, 20, 69,149,195, 17, 99, 64,215,212,206, 92, 19, 91,121,106, 71,117, 86, 72,121, 84, 65,245, 4, 64,213,225,211, +102, 64,174, 3, 72,244,244, 94,152, 53,100, 54, 13,142, 59,247, 85, 87, 2,148, 74, 37,137,137,137,193,202,149, 43,137,235,182, +165, 94, 17,107,250, 17,217,212,190,131, 52, 98, 59, 3, 59, 8,252, 74,252,145, 87, 80,128,188,242, 82,116,144, 4,194,124,225, +186,230,224,111, 91,229, 3, 56, 40, 1, 93, 59, 2,103, 47,209, 32, 68, 10, 59, 37,193,195,113, 86, 76, 26,109,196,173, 24,154, +186,167, 74,168, 43, 73,179,196,191, 96,193, 2,100,102,102, 2, 0,182,156, 21,193,100,181,106,148,255,137,245, 74, 17,240, 70, +137,171, 76,241, 90,251,123, 89,232,184, 28, 19, 19, 83,115,254,246,133,190,245,241,223,191,186, 33,251,237,239,119,156, 10,207, +131,189, 22,202, 39,204,110, 85,231, 1,119,243,230,205,178, 45, 91,182,104,104,154,198,252, 69,112,230, 82,231,178, 15, 70,104, +232,159,178,129, 3,146, 0,252,134, 97,195, 62,175,114,109,234, 84, 96,220, 56, 96, 28,210, 52, 75, 63, 7, 39, 37,128, 37,127, +173,214,113,235,148, 41, 83,156, 27, 43,121, 67, 96,181, 89,254,108, 74,102,215,231, 75, 74,242,141,252,235, 13, 49,159, 2, 0, +150, 45, 91,118, 75, 1,232,151, 12, 28,157,223, 32,197,217,189,123, 55, 86, 76, 74, 68,135,145,113,128,192, 12, 74, 68,131, 18, +210,160, 4, 34, 16, 66,129,209,219, 64,236,118, 16,139, 29,207, 62,245, 28,158,251,191,151,112,169,121,115, 77,199,142, 29, 27, +210, 19, 64,101,102,102, 14,106,219,182,173, 56, 43, 43, 11,233,233,233, 56,123,246, 44,226,226,226, 48,104,208,160,150,223,126, +251,237,251,147, 39, 79,126,214, 11, 5, 64,176,119,215,186,239, 30,137, 54, 52, 63, 82, 46,192,212,133, 21, 24,218,247, 51,204, +158, 51, 69,248,201,130,146, 14, 11, 62, 89, 51, 53,170,239, 84, 21,106, 72,131,236, 74,232,174, 99,122, 82, 82, 18,113,119,190, +190, 55,132,227,113, 7, 60, 0,174, 47,105,237,182, 53, 37, 29,239,235,216, 68,249,222,179,204,172, 33,179, 57, 15, 30, 42,149, +138, 90,185,114, 37, 97,211,146,178,255, 42,149, 74,146,144,144,224,157, 85,189,109,191,108, 76,231, 30, 26,177,201, 6,191, 79, + 94,129,205, 96,129,116,254,135, 8, 17, 75, 97, 18, 25,161, 55, 25,225, 7, 10,230,171,249,154,210,210, 82,121, 72, 72, 72,173, +131,240,217, 75,192,202,159, 24, 0,134,202, 63, 96,216,253, 52, 38,141,166,224, 26, 72,155,248, 24,176,242, 39, 31, 60,166, 9, + 9,242,202,231,244,201, 90,103,201,159, 37,126, 0, 80,237,181,194,104,209, 3, 0, 70, 45,216,137,212,197,113, 26, 0,156,229, + 95,250,248, 18, 68,212,133, 91, 13,129,202, 5,213,180,171,203,113, 62, 34,254,195, 45, 69, 40,245,158,131,252,107,219, 99,158, + 82,166, 18,199, 61,220,172,255,163, 91,172,178,149,155, 95,208, 16, 16,124, 52,231, 87, 12,144,117,198,218,175,246,224,127, 59, +146, 52, 91,148, 4,179,158,120, 71, 30, 61,172,165, 79,138, 64,197, 21, 37, 25,217, 7, 72,253,225, 20, 8, 33, 8,106,214,219, + 73,254, 43, 86,172,168,181,124,122,147, 90,150,152,208, 82, 3,124, 9,224, 87, 28, 60, 8, 12, 24,112,235,250,251,239,223,250, + 60,247,197, 52, 77,202,255,186,200,105,166,109,173,229,100,201,127,196,136, 17, 96, 24, 6,203,151, 47,175,183, 14,174, 84, 42, +157,228, 95, 85, 41, 80,146,148,148,218,251, 28, 61, 89, 87, 69,253,165, 42,255,199, 36,184,185,143,170,188,145,114,124,232,211, +231,246, 57,118,122,138,206,233,149, 7, 0,134,153,129, 57,115,230, 56,175,207,153, 51, 7,203,150, 45, 3,221,233,233, 91,191, + 90,121,191, 59,121,194, 41,238,203,103,179,185,185,143, 67,249, 76, 38, 19, 90,180,143, 4, 24, 11,104, 9, 64, 9, 5,176,149, +151,194,148,117, 25, 5,215,114,209,102,176, 12,148,184, 9, 40,171, 5, 16,208, 88, 60,235,101,196,173,124, 7,243,230,205,171, +215, 65,217, 83,170,108, 23,178,165, 8, 33, 77,140, 70,227,224,176,176, 48,156, 59,119, 14, 12,195,224,242,229,203, 88,181,106, + 21,186,117,235,134,214,173, 91, 79, 7,240,108, 53,178,102,106, 34,111, 66, 72,211,246,244, 65, 89,203,118, 99,197, 37,233, 39, + 80,170,147,224,199,223,109,216,122, 96, 53, 94, 76,240, 19, 10, 13, 76, 12, 48,181,198,125, 16,238,196,230, 86, 60,188, 67, 77, +109,199,157,103, 64,200,149,248, 9, 33,144,191, 49, 2, 43,211, 85, 77, 18,161,196,177, 31, 78, 0, 67,156,221,138, 19, 88,210, + 55, 24,214, 0,160, 96, 50,125,139,176, 48, 53, 82, 83, 83,225, 77, 26,207,254,146, 96, 77, 51,147, 29,210,133,207,193, 94, 88, + 12,219,245, 66, 8,197, 34,248, 83, 2, 4, 80, 2, 4, 8,132, 8, 19, 73,161, 43, 47,193,141,221,251, 53, 33,147, 30,168,117, +160,115, 71,234,123, 14, 51,149, 10, 0,240,233,155, 20, 8, 5, 56,194, 99,188,111,224,149,164, 44, 79, 77, 77,213,164,166,166, +250, 52,133,224, 74,254, 16, 10,144,117,195, 49,248,229,220, 52,161, 93,115, 41, 58,205,248, 13,169,171,198,107,184,186,215, 69, +212, 5, 8,169, 92, 8,168, 66,216, 73, 83, 72,154, 81, 8,120,236, 58, 24,166, 24, 38, 83, 42,236,153,175,122,231,201,229,176, +115,155, 55, 91,188,170, 54,207,214, 12, 10,123, 11,203,127,125, 26,129,116, 59, 0,192,115, 47,116, 65,159,254, 81, 88,243,101, + 58, 86,172,126, 87,163, 26,230,155,235,144,162, 0,229,220,147,206, 65,111,232,208,161,216,179,103,143, 71,242, 7,128,105,143, +137, 52,192,110, 0, 39, 81,114, 51, 16,157,218, 1, 95,127, 93, 1,141, 6,232,212, 9,136,138,114,136, 40,185, 25,232,232,140, +189,206,104,142,255,221,150,170,141,252,119,239,222, 13,134, 97,156, 36,253,243,207, 63,215,153, 64, 92,143,171,147, 63, 0,120, + 34,127, 0, 72, 81,169, 40, 2,200, 40, 64,155,152,152, 88, 99,195,103, 92, 6,125,213,202,149,114,138, 2, 86,124,181,226,182, +152,151, 21, 41, 42, 87,255,138,140, 16,162,249,236,179,207,156, 39, 62,251,236, 51, 44, 91,182, 12, 41, 41, 41, 85,119,145,163, + 32,115, 39, 47,197,145,194, 86, 78, 8,209, 62,251,236,179, 53,150,207,230,226, 69, 89,249,245,215,114,138, 2, 82, 86,164,104, +220,145,151, 48, 40, 8, 16, 9, 96, 55,148,224,204,214, 93, 88,179, 62, 13, 95, 93,191, 12, 0, 56,244,110, 48, 58, 13, 31, 7, +115,206, 85,156,250,251, 8, 78, 92, 62,143,210,188, 60,156, 60,121,178,222, 54,214, 90,181,106,149,140, 91, 27,166, 66, 8, 33, + 93, 51, 51, 51, 63,121,251,237,183,123,124,242,201, 39, 98,139,197, 2,129, 64,128,160,160, 32,232,245,122, 28, 58,116, 8, 81, + 81, 81,236,190, 5,181, 89,255, 1, 20, 69, 49,132,144,176,146,107,251, 14,191,251, 93, 78,216, 55,115, 90,161, 88, 47,134, 88, + 72,163, 77,168, 20,121,133, 22, 40,151,216,208, 39, 54, 38,160,157, 7, 79, 66, 82, 82, 18, 97, 21, 1,215,182, 88,211,103, 30, +119, 30, 44,249, 87, 87, 14,104, 79,131, 8,187,223,119, 21, 55,231,216,105, 94, 23, 96,229,202,149,196, 65,254,107,157,228, 47, + 61,156, 13,195,246,251,170, 92,247,104,185,170,214,202, 66,138,203,193,136,133,176, 28, 57, 5,243,153, 44,152,118,236, 1,140, +102,136, 9,129, 63, 4, 16,130,130,153,177,161,216,108,194, 87, 59,127,247, 40,243,211, 55, 29,214,189, 43, 28,199,172,185, 66, +112,238, 34,193,188, 15,125,111,179, 10,133, 66,235,234,246, 82,171,213,156, 58,186, 90,173,118,238,173,205,226,241,101,215,176, +235,136, 14, 57, 55, 77, 78, 37,224,194, 53, 35,160, 88, 15,181, 90,205,201, 29, 41,164, 28, 59,135,137,202, 79, 32, 32,224, 34, + 36,210,114, 48, 76, 49,172,214, 35, 16, 8,162, 96,209, 23, 53, 88, 99,221,181,241,164, 12,160,170,144,255,141,115, 4,253,198, + 11,240,194, 7,113, 24, 26,215, 3, 0,169,188,207, 59,172, 93,187,150,204, 95, 68, 33, 48,162, 23, 8,128,177,147,102, 97,239, +222,189,156,190,203,208, 87, 73,179,102,199,157,228, 95, 94,228,216,130,185, 79, 31, 7,249,179, 27, 1, 58,174,249,161,188,200, + 15, 97,254, 55,106,149, 25, 31, 31, 15,185, 92,142,145, 35, 71, 98,202,148, 41, 16, 8, 4,183,253,185,158,231, 10,119,253,214, + 39,101,201,133,136, 41,138,114,254,213,116,142, 2,180, 32,208,214, 32,235, 86,255, 74, 76,212,184,179,156,231,204,153,131,196, +196,196,170,132, 90,131,188, 95, 85, 42,156, 60,121, 82, 67, 81,148, 12, 64,149, 58,115,250,179,171,157,171,173,124, 98, 66, 64, +251, 75, 96,205,187, 2,213, 91,111, 97,149,190, 4,186, 17, 3,157,215,191, 89,189, 10,239,188,252, 12, 58,207,123, 28,239,157, +216,141,245,186,203,136,155, 48, 1, 81, 81, 81, 94, 79, 1,172, 90,181, 74,166, 84, 42,201,183,223,126, 91,165, 13, 31, 56,112, + 64, 83,219, 52, 20, 69, 81, 34,138,162, 98, 79,156, 56,145,147,158,158,174,157, 63,127,254,192,229,203,151, 75, 43, 42, 42,156, +219, 52,155, 76, 38, 4, 6, 6, 94,152, 60,121,114,151, 33, 67,134,180,243,160, 72,208, 20, 69,181, 63,145,177, 33,255,252,246, +121,217,243, 94, 79,110,249,219,194, 86, 56,147, 43, 68,105,133, 0, 12, 5, 20, 85, 88, 64,194, 59,154,230,190,241, 97,143,135, + 30,126,194,227,116, 66, 74, 74, 10,197,142,117, 42,149,202,227,103, 30, 13, 67,254,110, 61, 0,174,196,207,101,156,241,198, 18, +185,229,106,251,214,173,119,160, 74,156, 65, 13,110,140, 30, 77,155,107,138,137, 21,226,162, 98, 72,127,221, 13, 74, 72, 3, 38, + 11, 72,185, 30,148,205, 6, 17, 0, 59, 97, 96,178,219, 80,110,179, 0,140,231, 57, 84, 54,200,239,211, 55,107, 30, 6, 29, 65, +130,117, 31, 80, 85, 42, 21,197,186,244,185, 88,235,183, 89,255, 0,214,205,110, 89,229, 56,246,181, 44,136, 72, 33,172, 84, 83, +164,166,166,238,230,234, 5,144, 86,104, 16,246,222,106, 20,204, 79, 66, 97,177, 31, 90, 89, 79,193,110,207, 2, 0, 92, 57,214, +162,193, 26,236,250,109, 95,104,158, 25,173,170, 66,254, 44, 6,134,190,133,193, 61,226, 49, 40,236, 20,214,111,251, 64, 51,106, + 18,247, 65,100,205,154, 53,228,207, 63,255, 68, 81,209, 40,132,135,239, 66, 96,211,158, 32,132,128,166,105, 78,129, 72, 57, 57, + 64, 86,214, 73,118, 34, 1,144, 86,160, 88, 15,244,239,239, 56,115,225, 2,240,229,151, 64,121, 25,160,175, 0, 42,244, 64, 64, + 40,183, 45, 94,107,154,235,191,116,233, 18, 0, 96,209,162, 69, 0,128,206,157, 59,215,155,155,217,181, 77,114,249,206, 75, 47, +189, 4, 87,139,189, 58,113,123, 1, 25,112,107,238,223, 21,172, 23,160,242, 30,109,109, 66,158,110,221, 25,231, 79,157, 70,110, +104,168,134,166,105,188,248,226,139,248,252,243,207,125, 46,223, 48,115, 19, 16,166, 2,207, 44,122, 19,189,226,227,161, 90,180, + 8, 52,125,139,231, 84, 23, 78,222,242, 16,238,217,131,157, 59,119,226,242,229,203, 94, 7, 1,174, 90,181, 74,150,145,145,161, + 1,128, 67,135, 14,105,104,154,150,207,152, 49, 67,251,237,183,223,202, 8, 33, 24, 52,104,144,220,104, 52,106,106, 80,236,172, + 7, 14, 28,232, 53,109,218,180,224, 14, 29, 58, 96,235,214,173,134,210,210, 82,161,209,104,116,120, 59, 42,231, 63,198,140, 25, +211,153,162, 40, 63, 66,136,209,141, 24,218, 69, 30,157,117,238,216,178,119, 94,157, 25, 24,222, 41, 21,127,165, 62,133,227, 87, + 41,228,220, 20, 2,132,134,217, 98, 69, 49, 9,207,125,254,233,231, 6, 82, 20,149, 75,234, 65,171,228, 18,103,195,227,238,160, +198, 41,128,244,244,244,219,206,149,228,234,188, 38, 59, 87, 15,128, 99, 10,192,209,126,164,135,179, 33, 57,153, 11,123, 19,135, + 21, 85,125, 14,185,166,221,226, 78, 95,203,129, 65,226,135, 40,155, 13,109,252, 2,225, 47, 18,131,178, 90, 1,134,192,102,183, +163,220,110,129,193,110,131,153,216, 97, 7, 1,241,162,177,205,251,240,150, 18,224,136, 11,184, 69,250,159,190, 41, 64,242,155, + 20,230,127,104,171,115,165, 43, 20, 10, 45,187,117, 41, 23, 44, 72,117,212,251,226,132, 80, 39,225, 59, 93,249,164, 16, 34, 0, + 66,162,195, 15,207,132,218, 30, 87,115,139,235, 16,221, 60, 12, 59, 28,110,234, 79,132, 33,120,252,230, 21,100, 46,105,131,128, + 22,221, 80,154,155,139,188,236,235, 13,218, 48,251,244,143,130,190,178,185, 25,252, 78,195,223,216, 29,191,188,107,117, 94, 31, +162,232,129,140,245,222, 89,254,147,134,255,137, 95,127, 85,160, 73,134, 26, 75,223, 4,230,126, 72, 48,124,248,112,206,203,254, + 34,219,180,165, 58,118,172,170, 5,254,254,187, 35,240,111,237, 90,160, 83, 39,130,101,203, 40,188,247, 94,133, 67, 65, 0,208, +169, 75, 40,230,207,229, 86, 70,214, 74,141,143,143,199,207, 63,255, 92,197,146, 29, 59,118,108,141,228,230,171, 34,234,165, 7, + 79,190,108,217, 50, 77, 77, 10,192,167,159,126,138,149, 43, 87,114,178,132,159,125,246, 89, 13, 27,249,239, 14,115,231,206,197, +210,165, 75, 53, 43, 87,174,172,181,140,127,158,206,193, 27,239,189,140,167, 23,190,138,215, 45, 22,124,246,217,103, 53,214,209, +167,159,126, 10,181, 90, 13,138,162,100, 53, 17,246,240,238,237,240,237, 55, 95, 34,102,234, 84,188,251,238,187,181, 42, 13,115, +230,204,193,167,159,126,138,175,191,254, 90,235,109,221,103,100,100,104,216, 96, 57,165, 82, 73, 14, 28, 56,160,153, 49, 99, 6, +117,240,224, 65, 13, 69, 81,152, 49, 99,134,182,182,117,221, 6,131,161,201,239,191,255,142, 81,163, 70,225,194,133, 11,254,122, +189, 30, 86,171, 21, 52, 77,195, 98,177, 32, 33, 33,129,170, 36,119, 35, 23,199,150,217,108, 22, 31,217, 48, 21,195, 31,121, 15, +219,211, 47,225,242, 13, 1,202,244, 52, 4, 66, 32, 87,239,135, 23, 95,123,115, 16,128,107, 92,185,159,141, 59, 1,184, 77, 7, +240,104, 24,235, 31,238,220, 56,172,107, 70, 38,147, 65, 38,147,225,239,191,255,118,254,101, 29,190,130, 82, 99, 41,194,251,123, +191,238,151, 37,119,127,255,105,144, 30,206,134,232, 74, 17, 8, 69, 65,252,116, 81,149,235, 30,137, 75, 44,128,157, 0,215,244, + 37,200, 41, 45, 70, 65,153, 14,165, 38, 19,116, 22, 35, 10,204, 70,220, 48, 25,144,107,170, 64,177,213, 12, 29, 99,133,133,241, +156, 13,115,216,253,110, 6, 60,151,184,128,103,166, 4,130, 64, 12,226,221, 54,224, 78, 23,126,245,198,206,213,253,239,180, 60, +111,154,176,235,136,174, 10,241,179,228, 47, 97,174, 64,194, 92,193, 59, 99,132,200,201,201,177,112,149,185,225, 50,131,136,228, + 20,231,241,101,189, 29,215, 46,229,226,220,190, 83,200,203, 46,105,240,134,187,246, 43,135, 2, 90,150, 79,224,111,236, 14,217, +211, 66, 60,178, 80,228,252, 75, 94, 63, 21, 20, 40,206, 3,210,196,161,233,120,106,158, 2,161, 7,118,129,162, 40,108,218,231, +120, 5, 92,201,159, 69,231,174, 93,170, 41, 22,192,242,229,192,197,139, 14, 79,192,187,239, 18,167,251,157, 16,130,208,208, 80, +207, 35,112,101, 27,181,219,237,176,219,237, 88,180,104, 17, 46, 93,186,132,243,231,207,227,252,249,243, 80,171,213,120,249,229, +151,145,147,147,211,144,175, 68, 91,147, 37,253,210, 75, 47,177, 86, 29, 39, 50,164, 40,202,173,245,207,162,182,107,174,216, 35, + 41, 1, 69, 7,226,127,111,124,136,192,223,213, 72, 76, 76,132,235, 86,195,202, 78, 61,241, 82,204, 96,248,251,251, 99,248,240, +225,120,251,237,183,161, 86,171, 53, 58,157,206,109,255,251, 38,247, 60,110,244,232,142,214,173, 91,203, 25,134,169,209,219,193, +122, 42,124,245,188,184, 70,202, 15, 26, 52, 72,206, 18, 37, 0, 12, 28, 56, 80,238,161,238, 70, 14, 31, 62, 60, 56, 39, 39, 7, +123,246,236,193,125,247,221, 7,161, 80,232, 84, 22, 91,183,110,205,117, 58,130,169,148, 71,117,236,218,119,193,202, 29, 77,112, +124,235, 66, 12, 27,212, 13, 1, 82, 26, 1,254,118,248, 73,204,120, 96,226,100, 6, 64,113,117, 93,213,147,114,201, 62, 31,151, +233, 0, 30, 13, 7,186,182,151,168, 82,169,130, 94,122,233, 37,188,244,210, 75, 0, 96,121, 63,233,125, 88,243,109,240,243,147, +250,148,140, 36, 33,193, 17, 62,236, 63,230, 34,136,128,198,219,191, 24,156,214, 63, 87,248,183,110, 45,183, 5,250, 67, 71,236, + 56,173,215,225,100,105, 17, 78,149, 21,226, 84, 89, 49, 78,235,139,113,209,160, 67,145,217,132, 10,155, 13,215, 13,122,231,111, +214,134, 73,163, 41,124,250,166, 0,159,190, 41, 0,129, 0,132,162,145,248, 24,133,103, 31, 19,227,233, 41, 17,232,216,177, 57, + 24,136, 0,120,247,200,172,171, 63, 33, 33, 65, 94,253,156, 23,117, 38,191,112,205,161,200,103,126,236, 8,162,219,254, 74,136, +195,125, 67,116, 16, 16, 61,204,180, 35,162,185,184,184,216, 63, 33, 33,193,171, 77,209, 99, 98, 98,160, 86,171,177,182, 66, 15, +163,133,198, 83, 63,253, 15,249, 82, 63, 24, 45, 13,183, 77,196,248, 62,239,200, 51,138, 63,196,218, 31,111,153,248,191,188,107, +197,192,208,183,110, 41,148, 15,125, 41, 79, 81,165,112,202, 45,177,244, 45, 96,198,188, 81,104,114, 64, 13,249,146, 17,160, 31, + 4,180, 90,173, 79,109,184,125,251,170,209,227, 35, 71, 2, 77,154, 0, 81, 81,192,128, 62, 65,144,138, 5, 16,208,183,196, 74, +253,252, 60, 14,200, 52, 77, 59,231,250, 47, 93,186,132,206,157, 59, 87,249,123,239,189,247,240,222,123,239,225,250,117,238, 94, + 25,119,243,245,174, 72, 74,242,222, 2, 91,185,114,165,124,233,210,165,110, 9,155,171,245,239,226,122,190, 45, 78,129, 61,102, + 24,110, 41,236, 45, 20, 5,198, 96,134,168, 69,123, 40, 63,248, 0, 51, 2,154,160,137, 54,195,121,253,233, 39,102,224,157, 79, +254,135, 11,159,174,195,255,245, 26,137,201,161, 29,176,115,243,102,100,101,101,185,237,127, 15, 39, 41,209,163,103, 79, 57, 27, +212,200, 42,100,174,211, 51,238,206,213, 98,125,145,164,164, 36,194, 6,246,177,243,253,174, 36, 63, 99,198, 12,237,192,129, 3, +229,172,235,127,198,140, 25, 90, 15,245,150, 46, 18,137,238,123,248,225,135, 47,149,150,150, 66,167,211,193,207,207, 15, 17, 17, + 17,104,210,164, 9,154, 52,105,226,169,242,152,106,242,236, 18,137,196,240,104,210,231,242, 85,135, 99,145,125,181, 12,205, 67, + 4, 24,212,133, 66,239, 14, 4, 1,193,193, 37, 0,236,181,240, 6,191,223,192, 61,106,253, 3,158,151, 1, 86,168, 84, 42, 9, +128, 0,165, 82,233,212, 2,219,140,104,229,147,230,171, 82,169, 40,133, 66, 1,181, 90, 77,196, 79,167, 86,113, 69,114,205, 3, + 16, 62, 97,148,182, 40,117, 43, 12, 54, 51,202,244, 6, 92,178, 90, 33, 98, 28,142,250, 82,171, 9, 12, 33, 32, 0,182,222,188, + 12,189,205, 10, 0, 28, 6, 38, 10,243, 62,172,218,198, 29, 83, 1, 12,236, 48,227,204,197,114,124,251,115,153, 87,207,235, 74, +244, 10,133, 66, 91,221, 11,224,170, 20,212, 6,133, 66,161, 77, 85, 78,134,104,212, 87, 0,162, 80, 84,116, 43, 56, 79,204,220, +128,133,110,137,231,123,157,199,141, 27,142,129, 88,165, 82,237,226, 34, 55,233,151,149, 85, 20,175,212,212, 84,176,147, 18, 63, +157,216,239,213,170,140,250,198, 67,207,181,212,254,166, 36,216,167, 62, 5, 0, 24,220,195,145, 25,239,213, 57, 11,177,255, 84, + 15,124,178,126, 42, 84,191, 63,167, 81,141,231, 70,224, 79,205, 83, 32, 44, 76,237,106,200,162,184, 88, 1, 66, 82, 43, 93,149, + 4,169,169, 9,156,100,197, 63,242, 40,181,115,251, 14, 2, 56, 92,255,114, 57,133,194,171, 33,208,235,164, 48,150,137,241,211, +247, 20, 94,122,137,224, 74,126, 57, 6, 12, 26,136,169, 83, 30,227,100, 21,219,237,118,231,124,191, 90,237, 40,171, 43,225,231, +231,231, 35, 63, 63,223,107,247,190, 82,169, 36, 52, 77,223, 70,170, 41, 41, 42,202,135, 36, 64, 90, 66, 72,149, 88, 0, 23,143, + 0,103, 87,184,171,107,191,122,244,190, 39,183,127,117, 37,199, 86, 94, 14, 81,211, 48, 8,252, 3,209,227,209,120,188, 55, 58, + 14,111,176,203,246,250,246,131,221,104,130, 40,188, 57,122, 13,148, 33,178, 77, 7,124,126, 38, 3, 61,123,246,148, 31, 62,124, +248, 54, 37, 32, 73,169, 4, 64,105, 0,224,185,164, 36,231,210, 65, 91, 53,178, 23, 10, 5, 0,185,181, 80,145, 2,208,199,205, + 32, 27, 29, 29, 77, 17, 66,156, 46,254, 67,135, 14, 57, 93,252,174,247, 85, 30,123, 36,255, 74,131,253,173, 38, 77,154,244, 24, + 56,112, 96,199,179,103,207,226,232,209,163,176,219,237, 8, 8, 8,128,193, 96,200, 15, 11, 11,203,246,198,232,163, 40,138,110, +222,188,249,206,137, 19, 39, 54, 63,176,247, 16,150,165,238, 68, 48, 37, 70,151,230,102, 92, 44, 12,192,208, 46,214,203, 0,172, +172,130, 86,169, 80,218,107,123, 39,174, 99, 29, 63, 5,208,184,193,101,190,216, 2,192,226, 74,212,215,210,175, 3, 83,189, 39, +127, 87,178,113, 55,104,113, 85, 2,202,138,117,114,171,191, 84, 83, 74, 51,200, 51, 85, 0, 86, 43,236,132,128, 2,112,166,162, + 4,185,134, 50, 16, 66,216, 36, 54, 28, 6, 38,130,196,199, 40,172,252,233, 86,155, 60,123, 9,232,218,209, 6, 1,244,117, 34, +127,215,198,238,171,203, 43, 33, 33, 65,158,154,250,156, 6,200, 68,113,113,177, 37, 39, 39, 71,184, 56, 14,244,130,157,195, 49, +167,231,126,167, 21,198, 85,169,112,231,117,169,126,204,146, 16, 87,107, 14, 11, 41,196,174,204, 34,128,251,229,126,206, 76,128, +106, 16, 46, 65,138, 73,227,191,146,171,126,123, 94,147,177,158, 96, 80,216, 41, 12, 81,244,192,222,157,167,112, 64,247, 1, 40, + 80, 80,142,255,146,243,179,134,133,169, 65, 81, 20, 38, 77,154,132,175,191, 46, 3,107, 20, 59,254, 37,149,117,156, 90,101, 64, +170, 45,181,246,136,145,114,121,250,110,141,102,228, 72,192,146,215, 22, 87, 75, 36, 96, 42,103, 91, 91,234,155,227,149,196,114, +236, 60,208, 5, 65,109,186,112, 42, 35, 75,252,215,174, 93, 3, 0,228,229,229, 57, 61, 3, 55,111,222,116, 14,172,190, 64,165, + 82, 81,108, 34,160,234,115,184, 41, 42, 21,197, 37, 31,128, 43,190,254,250,235, 42,177, 0, 75,151, 46,245,218,250,175, 78, 24, +190, 66, 42,149, 34,239, 74, 54, 58,116,236, 4,198,102, 6,101,179, 67, 24, 20,140,160,126,177, 8,236,123, 63, 24,189, 13,118, +131, 25,196,102, 7,236, 12, 22,172,248, 4, 83,166, 78,129, 84, 42,117, 43,207,246, 83, 40,167,223,117,119, 95,204, 71,238,239, + 29, 52,104,144,252,192,129, 3, 26,118, 12, 24, 50,100,136,219,186,226, 64,254,160, 40,138, 1,176,173, 75,151, 46,125,191,248, +226, 11, 75, 65, 65,129, 41, 46, 46,110, 98,102,102,230,255, 25, 12,134,162,166, 77,155, 42,187,119,239, 94,236, 69,221,139, 0, +180, 27, 56, 96, 64, 68,210,211, 73,184,124,237,114,241,147, 79, 39, 13, 59,184,243,251,228, 27,229,197,131, 99, 71,196, 49,205, +219,116,126,196,141,215,128,169,109, 44,112,229,138,154,146,255,240,137,128,238, 29, 5,160, 70,235,194, 23,242,103,201,134,205, + 9,224,139, 18,208, 65, 57, 77, 11,128,202, 85,173, 34,240,147, 66, 71,108,176,216,108, 96, 8,131,240,144, 16, 92,211,151,114, +203, 96, 87, 9,119,203,251,110,197, 0,120,151,137,205,157,139,191,174,233,122, 43,191, 59, 62, 54, 54,246,183, 5, 11, 22,136, +195,194,194,152, 27, 55,110, 96, 78,207, 27, 85,200,223,155,223,112, 87,255, 62,163, 50,203, 95,245, 36, 79,238,238,225,138,190, + 15, 9,180, 41, 15,165, 80,155,151, 95,151,109, 57,241,174, 38, 99, 61, 64,129,194,248, 62,239,200, 31,122,142,123, 2, 32,182, + 45, 57, 8,190,172,114,144, 2,220,241,206,170,100,135,243, 36,160, 93, 10, 5,172,168,113, 96,154, 58,229, 49,237,212, 41,143, + 81, 69,186, 47,100,246,242,114, 13, 37, 0, 12, 38, 63, 80,229, 54, 8,105, 33, 12,180, 84, 62,122,242, 51, 16, 18,202, 99, 57, +227,226,226,168,251,238,187,143,220,169,254,231,176,246, 83,168,164,164, 36,226, 26,209,238,234, 9,240, 82,156,150,181,252, 93, + 20, 10,109, 67, 12, 94, 35, 71,142,196,243,235, 87,226,189,242, 18, 68,143, 24, 10,186,121,168,163, 76, 86,226, 72,221, 11, 17, + 40,129, 16,148, 88,128,175, 83, 62, 69,240,168, 88,116,236,216,241,174,166,238,101,173,251,140,140, 12,205,128, 1, 3,228,211, +167, 79,175,211,111, 95,186,116, 73,177,107,215,174, 43, 2,129, 96,243,176, 97,195,222,167,105,186, 96,224,192,129,233, 78, 75, +198,197,163, 68, 81, 20,220,189,115, 23, 79,128,250,232,209,163,253,127, 88,245, 61, 45, 22, 72,174,198, 63, 30,223,135,166,105, +221,208,113,207, 60, 8, 32,164,146,248,203, 1, 16,155,205,230,148, 87, 77,105,227,183,148,111,132,224,226,254,247, 73, 1,168, + 15,133,161, 54,242,241,102,128,147, 43,103, 80,234,157,106, 25,115,238,130, 70,111,182,192,102,183,163, 99,255,126,232,108, 27, +224, 21, 25,214,103, 48, 10,155,244, 7,128,134,245,116,184, 76, 5, 80,117,144,251,187, 66,161, 16,170,213,234,121,139, 23, 47, + 94,226,162, 92,140, 84,169, 84, 94, 37, 34,169,244, 20,212, 91,242,146,201,103, 18, 42,235,177,230,231,155,172, 86,251,164,233, + 79,152,221, 74, 59, 1,117,127, 63, 14,114,167,240,212,188,145,206, 60,229,236, 56,182, 42,121, 23, 2,218,165, 80, 1,237, 18, +188,146,217, 36,248, 5,237,190, 43,160, 24,250,170,204,104,112,236, 3, 16, 32, 85,104, 67, 90,195,171, 21,163, 46,237, 79, 84, +169,113,214,251,188, 42,171, 4,212,135,172,202, 88, 0, 13,251,185,174,242,124, 93, 89,214,177, 99, 71,180,120,241, 69,249,178, + 29, 59, 52, 89,239,255,138, 4, 81, 56,154, 84,110,222, 99, 52,216,240,210,203,175, 67,224, 31,134,173,223,171,240,119, 83, 10, +163,235,144,183,223,110,183,193,219, 24,160,234, 74, 0, 23, 43,223, 67, 61, 81,231,207,159, 47, 32,132, 36,119,237,218,245,187, +162,162, 34,189, 80, 40,132,205,102, 35,225,225,225, 78,143,138, 94,175,135, 88, 44,118,122,145,106,145, 55,252,208,161, 67, 96, +108, 20, 6, 15,233,243,206,181,107,215,116,197,197,197, 8, 11, 11, 99,218,180,105,163, 99,223, 77,105,105, 41,164, 82, 41, 40, +138,130, 68, 34,225,100,244,177, 74, 66,245,207,213,189,162, 60,238, 49, 15,192,157, 82, 10,124, 38,198, 56,133, 22,113,138, 70, + 21, 77, 90,169, 4, 80,119, 96, 30,221,174, 80, 40,254,171, 80, 40,254, 91, 31,229,171,199,231,165,234,227,158, 59, 9,135, 85, + 15, 84,166,216,175,118, 45,161, 78,178,105,166,173, 54, 64,218,182, 62,138,105,189,147,117, 80,143,155,174,104,189,153,171,247, +160, 76,248, 44,135, 16, 66,249,251,251, 99,210,164, 73,168,220,190, 23, 57, 46,219,247,238,219,181,211,185,125,239,168,129,163, + 80,169,244,214,248,123, 95,235, 62,162,158, 13,125,253,118, 98,226,184,155, 32, 7, 37,160,206,184,255,254,251,205, 54,155, 45, + 29,128,158, 97, 24, 98,177, 56, 22,254, 20, 20, 20, 0, 0, 2, 3, 29, 75,123,217,243, 34,145,168,214,250,123,232,161,135, 88, + 25, 59, 24,134, 65,147, 38, 77,192, 48,140,115,197, 73,229, 42, 22,202,100, 50, 17, 0, 16,139,197,160, 40,138,190, 27, 99, 59, + 15,223,193, 37,149, 52, 0, 80,209,209,209,188, 38,198,131, 7, 15, 30,247, 14,108, 0, 76, 0,164,245,108,196,121,218, 48,136, +243,142,130, 60,238, 13,240, 47,147, 7, 15, 30, 60,238, 45, 8, 1, 4,114, 32,127, 3, 28, 65,220,245,197, 7, 12,248,101,127, +255,184,134,196,131, 7, 15, 30, 60,254,121,240,231,249,130, 7,239, 1,224,193,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60, +120,240,224,241,111, 71, 21,151,206,172, 89,179,124,142,224,116,183,121, 79, 99,151, 23,213, 79, 2, 63, 73, 30, 68,226, 18, 48, +140, 99, 89,152, 64, 64,131,166, 4,142,127,105, 10, 20, 69,131, 80, 66,199, 26, 88,216,240,219, 22, 17, 8, 33, 8,163,195,225, +101,249, 36, 0,154,194, 17,192, 83, 14,199,114, 47, 43, 42,231,212,238,197,250,227,229,241,242,120,121,188,188, 59, 40, 15,117, +144,135,127,187, 60,175, 21,128,127, 27,254,220,123, 17,253, 99,173, 8,109, 2, 20,235, 40,252,245,183, 20, 66, 90,136,113, 99, +236,216,169,137, 0, 69,209,160,104, 26,210, 32, 96,100,255, 18, 0, 66, 12, 29, 68,112, 40, 83,232,160,113, 14,208,236,223, 75, + 0, 64, 68,172, 24, 48,108,228,149,243,199, 15,155,243,203, 76,157,237, 6, 19, 20, 10, 69, 19, 0,165,188, 30,122,111, 35,237, +151, 31,101,157, 58,118,208, 20, 20,152,234,148,240,233, 30,130, 44, 49, 49,209, 53, 15, 64,157,158, 57, 49, 49,209,231,116,192, + 60,120,240,168, 39, 15, 0,139,239,127,248,134,243,210,192,167,166, 63,237,177,179,214,183,188,250,196,161, 76, 17,198,198,217, +241,247,113, 63,136, 69, 66, 8, 5, 66,136, 68, 4, 18,129, 21, 16, 6, 65, 8, 35,250,247,176, 65, 42,150,128, 0,104,217, 28, +152, 48,142,193,174,205,220,200,255,226,153,243,184,175,123, 71,180,106,221, 4,215,174,156,109, 31,210,162, 3,154,182,178,227, +143, 77,155,160, 86,171, 75, 26,122,125,188, 90,173, 30,151,154,154,186,133, 61, 78, 72, 72,120, 72,161, 80,108,225,187,134,103, + 28,255, 91, 77,108,166, 83,242,199, 38,116,212, 48, 76, 17, 74, 91, 25, 53,103, 79,174, 71,133,185, 37, 98, 99,134,253, 99, 73, + 44, 49, 49, 81, 51,103,206, 28, 80, 20,197,105,219, 94, 46, 96,147,197,212,195,118,243, 60,234,168,128,213, 10, 66,176,242,235, +175,107,124,223,108,130, 31,215,108,129,236, 30, 2, 46,123, 9, 56,223,179,235,206,136, 60,234, 23,108, 54, 64, 22,238,114, 3, + 52, 42, 15, 0,141,187,219, 14,198,141,182,130, 64, 0,161, 64,132,193, 3, 40, 52,139,160, 33, 20,210,144,136, 4,232,218,153, +198,149,171, 54,244,143,161, 17, 30, 38,197, 31,187,131, 1, 0, 2, 98,132, 35, 21,182,221, 35,249, 31,207,204, 68,100,171, 54, + 56,158,113, 0, 7, 45, 86,232, 10,117, 16, 75,130,208,173,239, 16,244, 25, 50, 26,154,223, 82, 1,112,203,141,127, 7,136,127, +100,106,106,234,174, 5, 11, 22, 32, 51, 51,147,109, 48, 37, 0, 94,124,230,153,103,126, 79, 72, 72, 80, 40, 20,138, 93,255,184, + 78,241,151,154, 72,132,197, 16,210, 22,152, 76,118,148,234,253, 48,116,248,100,175,234,127,125,218, 15,178, 96,191, 98, 60, 49, +165, 31, 34,219, 79,208, 4, 7,135,192,106,179,161,160,160, 16,205,115,174,226,194,165, 44,236,223, 87, 76, 6, 15,153,232,211, +123, 93,185,114, 37,113, 25,156, 27,219,224, 40, 3,110,109,135, 91,185, 59,160, 12, 13,148, 14,248, 46,246, 23,178, 97,195,134, +219,247, 83,104, 48,242, 34, 50, 10, 20, 72, 61,212, 59,201,249, 5,212,193,103, 92, 57,190, 50, 75,102,229,110, 72, 46,120, 38, + 69,143,254, 83,190,168, 85,145,251,227,143, 63,156,199, 99,199,142,197,182,109,219,106, 61,230,113,231,201,223,245,156,171, 34, + 80,171, 2,176,111,239, 65, 12, 25, 58,224,174, 21,154,241, 34,127,170,107, 42, 73, 95,179, 79,209, 66, 1,116,197, 66,180,104, + 38, 66,139,102, 98, 84, 84,136, 32, 21, 9, 97, 23, 74,208,175, 23,133,232,222, 2,208,148,200,145, 2, 83, 36,134,136, 54,131, +146,138, 97, 51, 0, 54,232,107, 37,255,189,187,119,161, 67,203, 8,156,252,251, 36,222,124,255,157, 42,229,251,240,221, 69,132, + 22, 80,232, 23,211, 15,127,108,219,229,213,206,123, 12,195,200, 50, 51, 51, 53, 23, 47, 94,132,159,159, 31,252,252,252,228, 99, +199,142,213,122, 57,152,201, 83, 83, 83,119,177,196,239,210, 56,154, 0, 24,253,191,255,253,175,240,153,103,158, 81, 3,136, 83, + 40, 20,234,198,216,192,191,253,246, 91,217,204,153, 51, 57, 63,247,186,159,191,151,245,236, 28,164,105,223,210,132,144, 96, 9, +104,218, 31, 70,163, 13, 69,197, 70,164,171,151, 17,105,112, 63, 12,232, 63,156, 83, 59, 18, 33, 15,147, 30,234,173,233,209,163, + 27,110,228,233,112,228,175,163,168,168,208, 35, 36, 36, 8, 81, 81,237, 65, 11, 68,176,219,115,240,215,177,189,164,111,244,208, +127,148,117,147,152,152,168,153, 59,119,174,243,120,206,156, 57, 88,186,116,169,230,235, 90,172, 66,175,200,168,145,122, 0, 42, +149,116,146,150,150, 6,119, 27, 43,221, 77,184, 90,217, 42, 85,138,156,144,186, 41, 1,116,251, 71,157,228,125,232,163, 64,183, +102, 88,139, 38, 52, 90,135,209,247,236,251,251,183,194,149,236,221, 41, 5, 30, 61, 0,251,246, 30, 4,128, 58, 43, 2,123, 95, +188, 80,235,245,161,159,119,242,121,176,160, 40,202,167,221,246,212,218,102, 16, 9, 69,104,219,170, 2,229,229, 34, 28, 57,217, + 22, 2,129, 0, 2, 74, 0,177,200,134, 30,157, 12,232,210, 73, 0, 10, 52,196, 34, 9,196, 2, 10, 49,189, 45, 8, 11,101,176, +246,187,218,101,119,235,208, 28, 87, 46,229,223, 70,254, 0,240,230,194, 55,168, 69,239, 47, 33, 45, 7,245, 70,104,147, 32,206, +229, 53, 26,141,178,165, 75,151,106,174, 92,185, 82, 69,223, 48,155,205,152, 56,145,187,181,153,154,154,186,219,149,252,221,160, +105,114,114,114,201,252,249,243,119, 54,244, 20, 69, 77,228,127,240,224, 65,205,204,153, 51, 57,151,173,115, 84,152,166,117,243, + 50, 52, 13, 15, 64,155,214, 45,224, 31,224,143, 43, 87,114, 97,183, 51,104,221, 42, 8,167,206,100, 96,213,185, 11,178, 25, 79, + 62, 93,235, 96,122,226,196, 94,242,200,248,110,104,215,174, 13, 78,159,185,130, 35, 71,206,160,160,176, 28,132, 0,161,161,126, + 48, 24, 42,208,183,111, 15,148,148,148, 34,247,200, 95,248, 97,245,121,217,244, 39,184, 43, 42,141, 28, 50,192,177,249, 20,139, +207, 62,251,140, 61,246,202, 11,144,152,152, 72, 92, 93,194,174, 22,164,171, 75,186, 62,166, 23,222,127,255,125,210,182,109,219, + 58,231,226, 87, 40, 20, 20, 69, 81,100,253,250,245,181,230,216,103,145,148,148, 68,220,121, 8, 86,173, 90, 37, 99, 55, 7,114, +167,196, 42,149, 74, 82, 83, 42, 87,215,253, 28, 8, 33, 80, 42,147, 52,117,241, 66, 84,151,215,255,245, 10, 28,254, 40,176, 10, +241,243,184, 55,173,255,234,109,168, 78, 83, 0,117, 85, 4,134,126,222,169, 70, 37,192, 23,242,103,145,158,158,142,220,220, 92, + 0, 64,235,214,173,137, 55, 74,128,128, 24, 33,164,236, 16,139, 68,248,235,100, 4, 4, 66, 33,130, 68,122, 71, 28, 64, 32,141, +220,220, 32,244,238,193,128,162, 40, 36, 76,176,129, 48, 52, 64, 73, 28,142, 55,148,215, 40,215, 80,114, 21,121,197, 21,152,255, +127,255, 87, 99, 89, 74, 74,139,161, 43,200,171,148,197,153,184,171,147, 63, 0, 96,235,214,173,176,219,237,178, 71, 30,121,196, +227, 0,167, 86,171, 71, 86,223,250,151,109, 48,165,165, 85,226, 17,155, 44, 92,184, 16,106,181,122, 84, 99,154, 10, 96,201,223, +155,239,172,251,249,123, 89,239,206,102,248,249, 53,129, 84, 34, 70,135, 14,145,104, 27, 25,137,178, 50, 45,138,139, 43, 32, 22, + 11, 16, 22, 42,133,208,175, 73,173,185,226, 1, 64, 72,114, 17, 20, 24, 14,131,209,134,147, 39, 47,224,122, 94, 41,110,228, 85, +192,104,150,162, 93,107, 27,164, 18, 1, 46,156,207,194,125, 29, 59,226,250,141, 50, 24,109,193, 30,101, 86, 18, 29,241,116,222, +219,233,128,154,100,250, 34,139,181,254,231,204,153,115,219,249,185,115,231,250, 20, 11,224,142, 68,171,207, 29,215,151, 87, 33, + 35, 35, 67,131, 58,110,200,179,107,215, 46,146,154,154,138,132,132, 4,184,155, 14,224,226,169, 98,201, 31, 0, 14, 29, 58,164, +161,105,186, 74,153, 86,173, 90, 37,227, 98,244, 12, 26, 52, 72,206,202,169, 15,143,203,250,185, 1,152,188, 84,239,150,248, 91, +135,209,149,163, 20,183,215, 59,118,236,216, 42, 94,146, 7, 30,120,160, 74, 93,241,110,255,198, 3,175, 99, 0,234,203, 35, 80, +159,184,112,193,161, 88,228,230,230,122,165, 4, 8,133, 66,136, 4, 34,136, 68, 20,134, 15, 1, 12,122, 51, 46, 95, 18, 67, 36, + 20, 65,104, 23, 98,224, 0, 2,177, 72, 4,129,128, 6, 8,133, 98, 29,112,248,168, 16, 12,195, 0, 40,168, 81,238,209,191, 46, +161,162,162,230, 12,156, 31, 47, 92, 72, 36, 18, 41,140,198, 82,216, 25, 27,231,231, 60,122,244,104,205, 74,135,193,192,137,104, +170,187,254,221,105,134,191,253,246,155,235,253,234,134,240, 2,184,115,241,187,146,255,160, 65,131, 56,239, 66,215,166,117,115, + 13, 77, 95,133,205,206,192, 98,181,161,160,176, 24, 34,177, 20,102,179, 21, 86,155, 29, 54, 27, 3,155,157,160, 68, 87,232, 81, +150, 88,164,135,212,175, 13,138,138, 74, 81, 86,110, 64,177,206,136,224,240, 62, 24,220,187, 55, 14,237,219,134, 86, 22, 27, 74, +203, 74,209,165, 75, 71, 72,196, 66,232,203,139,255, 41, 99,133,140, 16,226,156,251,119,197,178,101,203,124,138, 5,152, 51,103, + 78, 21,111, 66,245,107, 92, 21, 0,199, 86,207,172, 69, 27,134, 81,163, 70, 85,105,175,172,129,144,147,147,163, 81,171,213, 62, +109, 76,165, 86,171,157,228,207, 78, 7,108,216,176,193, 35,185, 86,247, 84,101,100,100,104,216,192, 55,165, 82, 73, 14, 28, 56, +160,153, 49, 99,134,243,250,129, 3, 7, 52, 20, 85,123,241, 6, 13, 26, 36,119,221,102, 56, 41, 41,137,212, 86, 87,158,198,195, +132,132, 4,196, 15, 82,227,103, 0, 83,150,234,113,255,235, 21,181,214,125,255, 41,181,215, 85,245, 57,126, 79, 49, 1, 60,238, +188, 55,160, 38, 15,192, 93,245,239,184,179,244,235, 98,253, 87,179, 88,113,225,194, 5, 44, 91,182,140,243, 86,147, 2,129, 16, + 3,251, 51, 16,208, 66, 28,206,148,226,220, 5, 41, 30, 28, 3, 60,244, 0, 48,126, 44,133,150,205,197,144,138, 37,144,138, 37, +240,147, 74,208,186,165, 4, 82,177, 20, 82,113,237, 91, 98,190,253,230, 91,212,226,143,222,163,106, 26, 72, 58,118,104,143,144, + 38, 1,144, 50, 22, 84, 24,172,119,189, 81,236,221,187,119,215,222,189,123,171, 16,190,235, 31, 0, 20, 21, 21, 97,252,248,241, + 13,102,229, 31, 58,116, 72,227,106, 13,177,231, 0, 96,192,128, 1, 94, 89,114,118, 59,160, 55, 88,161,215, 91, 80, 86,102,198, +205,155, 58, 92,191, 94,136,242,114, 51, 42, 42,172,168,168,176, 64,175,183,162,180,196,243,138, 76,179,217, 6,147,201, 14,171, +213,130,160, 32, 49,218,182, 14,134,127, 64, 0, 0, 32,170, 99, 36,218,180, 10, 70, 72,176, 20,132,216, 97,181, 49, 48,155,245, +255,136,129, 36, 49, 49, 81, 51,111,222,188, 90,201,156, 93, 26,200,209, 59, 33,175, 84, 26,220, 98,233,210,165,248,250,235,175, +189,222,106,216,225, 22, 87, 18,215, 63,150, 80,115,115,115,145,154,154,234,245, 86,180,187,118,237, 34,105,105,105,174,228, 15, +133, 66, 65,197,199,199,215,250,189, 89,179,102,129,162, 40,167, 85,255,237,183,223,202, 0, 96,224,192,129,114, 87, 37,214,245, + 58, 33,196,121,157,195,211, 86,177,226,221, 41, 14,158,148, 9, 0,104,218,180, 41, 40, 23,235,161,174,242,120, 52, 62,242,119, +119,236,147, 7,160, 49, 89,254,183, 6,120, 59, 4, 2,129,215,223, 27,210,159, 65,179, 8, 9,202,202,132,144, 8,109,144,136, + 5,208, 30, 20,227, 65,185, 8, 98,145, 8,101,101, 34,236,203, 12, 64,176,148, 2, 77,211, 24,171,176, 96,226,131, 4, 52, 77, +240,193, 49,239,203,169, 86,171,137,192, 95,138, 98, 81, 83,248, 91,175,225, 98, 46,193, 72,217,112,206,223,239,219,183, 47,246, +239,223,239,246,154,191,191, 63,231,193, 82,167,211,141,170, 28,120, 48, 99,198, 12,231,249,162,162, 34,231,231, 25, 51,102, 32, + 63, 63,191, 65,222,231,204,153, 51,181,135, 14, 29, 66, 70, 70,134,134, 97, 24, 57, 77,211, 96, 45,255,154,230, 77,107, 67,206, +213,235,242,136, 96,131, 70, 34, 22,192, 98,101, 96, 50, 95,195,213,107, 69, 40,214,149,161,184,216,128,162, 98, 35,138,138,141, +104, 18, 22,233, 81,214,205, 66,130,188,155,133,232,214,173, 35, 74,116, 58,136,132, 52,202,202,175, 65, 95,194,160,251,125,122, + 52,143,136,128,191,191, 63, 36, 18, 63,220,200, 43, 7, 37, 8,229, 74,176,148, 11, 57,214,203, 42,128,250, 94, 65, 80,147,181, + 14, 84,137, 5,224, 10, 45, 0,188,244,210, 75,183,121, 21, 92,166, 25,180,190,148,115,242,228,201, 85, 44,216,212,212, 84, 39, +121, 61,250,232,163,136,139,139,163,220, 37,158,225,104,249, 59, 81,221,211, 80, 29,209,209,209, 20, 33,196,105,229, 31, 58,116, + 72, 67, 81,148,115,107,224, 25, 51,102,104, 51, 50, 50,144,145,145,161,153, 49, 99, 6,117,240,224, 65,231,245,218, 18,187,100, +100,100,104,104,154,146, 31, 56,224,232, 19,179,102,205,194,177, 99,127,201, 89, 10, 63,112,224,128,134,125,126, 46,202,196,138, + 21, 43,240,165, 60, 20, 83,150, 25, 0, 56,166, 3, 92, 49,101,153,193, 89,159, 51,229, 34,158, 89,239, 21,165,125,193,199, 85, +149,238,197,175,225,216,177, 99,220, 87, 1,220, 9,226,119,141, 5,168,139,245, 95,213,146,175, 74,254, 99,199,142,133, 82,169, +244, 56, 21,208,180,169, 0, 52, 37, 64, 68, 83, 1, 58,117, 36,184,126, 93, 8, 90, 64, 65, 36, 20, 66, 36, 20,225,248,137, 0, +132, 5,136, 32, 16, 8, 48,100,128, 29,126,126, 18, 48, 12, 1,136,221, 39,242, 15,108,222, 22, 55, 43, 8,244, 23,181, 16, 82, + 2,188,178,240, 77,202,203,129, 77,126,245,234, 85,205,213,171, 87,111,123,222, 73,147, 38,113, 26, 44, 19, 18, 18,226,138,138, +138,118,178, 36, 15, 0,227,199,143,199,170, 85,171,156,247,148,149,149, 33, 63, 63, 31,191,255,254, 59, 18, 18, 18, 70, 54, 68, +227, 29, 56,112,160, 60, 35, 35, 67,115,232,208, 33, 13, 27, 44, 54,112,224, 64,159,230,112,167, 63, 49, 83,251,211,186,149, 32, +185,101, 48, 24,173,208, 73, 76, 32,208,193,100,178,161,172,204,140,252, 66, 3,174,223,168,192, 48,121,123,143,178,140,150,166, +200,186, 92,128,168, 14,237,208,161, 67, 27, 20, 21, 21, 34,180,137, 29,157, 58,133,160, 89, 68, 20,164,126,126, 40, 41,169,192, +145,163,103,113, 45,183, 12, 45,218,244,184,103, 7, 16, 2, 16,138,130,156,229, 82, 87, 82,173,109,221, 62,169, 12, 22,188,221, +124, 68,149, 85,101, 43, 87,174,148, 47, 91,182, 76, 83, 93, 1,248,244,211, 79,217, 4, 67,181,202, 35,132, 16,138,162, 40,165, + 50,212,165, 76,228, 54, 98, 78, 77,117, 76, 17,196,199,199,115,114,255, 87,157, 82,216,229,150,252,185, 98,208,160, 65,242, 3, + 7, 14,104, 88,175,195,144, 33, 67,228,238,174,179,193,120,158, 8,155,157, 91,223,183,111,191,134,162, 40, 80, 20,133,232,232, + 62,242,232,232,104,173,139,130, 80,121, 47,224,169,191,176,242,232,201, 58,176,242, 18, 70, 70, 86,121, 81,147,151,158,118,202, +227, 2, 62, 6,224,222,129, 71, 5,160, 49, 90,252, 44, 30,123,236,177, 58,125,159,166,105, 8, 4,142,191,110,157,105,244,237, +101,135, 68, 44,117, 40, 0, 34, 17, 6, 15, 0, 36, 18, 64, 36,144,160,105, 83, 41, 4, 2, 61,236,118, 6, 12,227,189,219,222, + 80,156, 7,105,155,174,184,172, 94,141, 8, 33,141, 39,223,124,195,235, 1,197,207,207, 79,251,198, 27,111,200,235,178, 12, 80, +161, 80,168,149, 74, 37,102,207,158,237, 60,199, 90,250,101,101,101, 48, 24, 12,152, 57,115, 38, 0,224,171,175,190,130, 74,165, +210, 52,196,187,157, 49, 99,134,150, 97, 24, 57,107,249,247,239,223,191, 78, 1, 92,109,218,119, 65,230,129,237,104,214,212, 31, +254,254,142,102,111, 54,219, 81, 86,110, 65,177,206,136,182, 29,122, 96,232,224, 17, 30,223,201,184,113,143, 82, 59,254,248,142, + 28, 56,116, 10,195,134,244, 65,251,246,237, 97,181,152,208, 55,186, 55, 2, 66, 66,112, 37, 43, 7,185,215, 75,176, 47,227, 12, +116,229, 33,152, 52,104,196, 61,235, 51,157,149,164, 4, 0, 13, 64, 97,150, 82,233, 36,112,166, 26,233,211, 52,229,208, 22, 42, +121,153, 2,208,199,205,124, 99,146, 82, 73, 64,224, 18,169, 66, 33, 49, 49,177,138, 23,224,165,151, 94, 2, 69, 81, 72, 74, 82, +106, 88,246, 7, 5,244,233, 19,237,142,188,156,238,120, 79, 36,199,149,252,171, 35, 62, 62, 30,163, 70,141,146,215,165, 29,163, +114,174,126,192,128, 1,242,233,211,167,107,107,186,238, 50,183, 95, 35,216,216, 1, 86,249,114, 76, 35, 80,218,234, 74, 5,215, +242, 85,151,183,126,110,160,163,210,165,205,157,247,172,159,155,227, 84, 8,182,255, 93,251,216,231, 46, 15, 0, 31, 3,112,143, + 42, 0,131,135,244,191, 35,115, 62,245,101,249,187, 54, 36, 95, 80,172,163,208,178, 57,237, 76,249,187, 99,151, 99,126, 95, 34, +145, 66, 34,150, 96,252, 3, 20,164, 18, 49,252,164, 20,138,139, 4, 56,116, 36, 8,118,198,142,182,109,188,155,215, 85,171,213, +164,196, 96,132, 46,115, 43, 58,181, 21,225,100,174,239,243,194, 52, 77,107,251,247,239, 79,245,239,223,223,103, 25, 9, 9, 9, +242,229,203,151,107, 88, 55,127, 81, 81,209,148, 1, 3, 6, 84,236,220,185,115,203,196,137, 19, 71, 23, 21, 21, 81, 79, 62,249, +228,246,132,132, 4,121, 67, 54,206, 74, 87,191,220,229,179,239,109,206, 65,238,228,252,217,211,184,158,117, 5, 52, 77,193,110, + 39,144,250,133,161,115,183,158,152,244,112, 2,231,134,126,189,128,145, 23, 23, 93,215,152, 76, 54,244,234, 25,133,214,173,154, + 34,231,234, 77,232, 78, 92,194,185,243, 57,216,181,251, 56,174,228, 18, 60,243,236, 11, 62,117,158,198,146,252,135,249, 57,212, +231,251,250, 46,226, 40,239,210,119, 88,182,108,153, 83, 1, 88,182,108, 25,144,181,234,182,123,221,201,171,193, 43,112,219,152, + 85,215,100, 61, 20, 69,213,169,237,177, 36, 95, 19,185,123,186,238,206,171, 80,237,187,238,228,113,127,207, 87, 54, 32,109,217, +116,199,216, 48,178, 93, 21,242, 7,128,132,113,247, 59, 62,232,142,121, 84, 0,248, 60, 0,141, 7, 43, 23,191,118,219, 52,128, + 87, 10, 64, 99, 14,248,240, 53,249,143, 43, 50,143, 74, 32, 21,139, 49,126, 28, 5,154,162,208, 63,214,134, 19, 39,253, 64, 83, +142, 57,255,146, 18, 26,173, 90, 8, 64, 83, 98,252,125, 66, 12,169, 4,176, 88, 45,184,146,227,231, 21,249, 95, 58,255, 23, 6, +140,122, 8,194,166, 3,112,233,252, 33, 8,243,210,240,234, 43,175,147, 37,255,253,168, 65, 42,184, 50, 95,189, 60, 54, 54, 86, +179, 96,193, 2,244,236,217, 51, 95,167,211, 33, 54, 54, 86,174,211,233,240,226,139, 47,106, 18, 18, 18, 26, 69, 94,251,186, 18, +127,117, 37, 96,232,224, 17, 88,245,227, 55,178,150, 45, 90,106, 2, 2, 2, 56, 89,253,183, 13,176,211,159,214, 2,160,214,172, + 86,145,211,231, 14,162,101,243, 64, 72,165, 34, 84, 84, 88,144,123,163, 12,148,176, 45,158,121,118, 58, 31, 45,197, 5, 71,231, + 3, 29,255,131, 42,203, 11,143,204,171, 11, 89,215,185, 72, 73, 73, 97, 46,138, 68,253, 16,154, 39, 82,246,134,180,235,154,207, +192, 93,157, 37, 12,146, 56,158,213,120,195,241,199,227,158, 69,116,116,180, 51,224,111,229,226,215,110,187,230, 81, 1,168,239, +124,252,119, 59,191,191, 87,141, 31, 20,116, 58, 10,254, 45, 40,132,135, 81,136,237,103,133, 84, 44,128, 68,108, 69,120,152,180, +114, 16,160, 48, 48,214,142, 67, 71, 69, 14,111, 1,199, 65, 70,173, 86,147, 30, 93,130, 49,255,165,247, 96, 20,183,193, 47,234, + 92,116,236,236,176,220, 3, 15,255,142,249, 47,191, 78,146, 63,105, 56, 37, 64,161, 80, 80,106,181, 90,182,120,241, 98,141,171, +119,160, 62,148,171,198,140,202,100, 63,117,126,198,105, 79, 40,169,189,251,211, 73, 65, 81, 1,140,121, 6, 72,165,225,104,211, +161,183, 79, 74,197,189, 6, 71, 58,236,122,122,204,172, 85,112,174, 8,200,250,190,193,159,205, 83,112,223, 63, 13,163, 31,154, +226,149,229,238,201,247,200,199, 0, 52, 46, 37,160, 38,242,247,232, 1,248, 55,128,192, 17,213, 79,209, 4, 4, 4, 97, 77, 8, +210,247, 10, 33, 21,139, 32, 17, 11, 49, 97, 28, 1, 33, 12, 66,195,109,176,217, 41, 48,140,189,114,240,243,140,222,145, 21,120, +240,209, 4, 84, 8, 59,161, 89, 96, 0,166, 78, 10,195,218,141, 39,156, 74,128,213,254, 75,131, 63, 63,171, 8,240, 93,198,119, +175,194, 63,245,217, 86,234, 62,166, 18, 67, 95,187,157, 25, 82,195,124,149,135,196,208,215,110,191,112,100, 94,157,172,126, 30, +117, 67,252,243,203,235,173, 13,255,211,141,135,123, 77, 9,240,104, 0, 71, 71, 71,243,147, 54, 60,120,240,224,193,131,199,191, + 12,124,162,103, 30, 60,120,240,224,193,131, 87, 0,120,240,224,193,131, 7, 15, 30,188, 2,192,131, 7, 15, 30, 60,120,240,224, + 21, 0, 30, 60,120,240,224,193,131,199, 63, 3, 85, 86, 1,204,154, 53,203,231, 8, 78,119,185,181,235, 91,222,180,153, 73, 30, +191,167, 47,206,115,126, 14, 8,107,225,252,188,230,219,148,219,238,141,144, 63,227, 81,222,206,165,183, 50,230,197,205, 93,238, +252, 92,160,249, 31,124, 41, 95, 77,240,181,124, 53,193, 93,249, 30,126, 82,233,241,123,153,154, 45,136,140,140, 68,118,118, 54, + 98,229, 15, 58,207,255,250,163,234,142,215,223, 51, 55,110,212,218, 94,204, 66,161,108,126,110,174,115,201,226,242,230,205,157, +247,255,175,101,203, 59,222,254,170,203,219,188,121,179,108,235,214,173, 85, 50, 37,142, 27, 55, 78, 62, 97,194, 4,109, 67,244, +143, 70, 46,143,154, 53,107, 22,254, 69,207,203, 73,222,218,181,107, 31,239,213,171,215,218, 19, 39, 78, 60, 58,117,234,212, 95, +234, 42,207,117,163, 35,215,136,252,123,180,254,234,210, 94,240,111,151,231,181, 2, 80, 29, 54,155, 77,102, 50,153, 64, 9, 68, +160, 40, 10,118,155, 21, 98,145, 16, 18,137, 68, 91, 87,205,195,102,179,201, 0, 64, 40, 20,214, 73,150,190, 56, 15, 1, 97, 45, +156,196,223,162,109, 36, 0, 32,239,106,182, 79,242,118, 46,157,141,184,185,203,157,196,245,229,230, 67, 0,128,231, 39,244,199, + 63, 17,153,154, 45,136,149, 63,136, 76,205, 22, 0,192,131,241,211, 0, 0,217,217, 13, 95,127,159,223,188, 41, 59, 15,104, 58, + 3,242,243,128, 99, 15,245, 5,175, 2, 0,250, 47, 94,210,160,245,166,213,106,201,214,173, 91, 97, 50,153,170,156,151, 74,165, +154,224,224, 96,200,100, 50,126, 57, 20, 15,119,132, 63,106,234,212,169,233,107,215,174,125, 6, 64,200, 99,255, 73,154, 9,128, + 57,113,226,196,116, 0,191, 2, 96,188,145,199,238,121,194, 18,127, 93,250, 91,245, 93, 18,235,107, 73, 95, 77, 74, 9,143, 70, +230, 1,112, 69, 89,121,133,172,101,231,251, 53, 35,122,117,133,191, 68, 4, 66, 8,236,118,130,147, 23,174,224,242,241, 61,114, + 63,137, 8, 2,129,192, 39,242, 14,148,102,203,122,116,202,210,156, 60, 31, 37,215,155, 35,125, 38,126, 0,240, 11, 9,135,190, + 56,207, 73,252,181,121, 4,184, 88,170,253,167,189,134,157, 75,103, 59, 59, 82, 77,247,213,182,198,178,250,111,138,197, 98, 0, +142, 52,153, 12,227,232,223,118,187,221, 89,126, 90, 32,226,108, 69, 3, 64,203,102,142, 84,157,150,178, 18,152,109, 54, 0, 64, +133,205, 33,175,195,232,167,113, 95,143,190,156,136, 31, 0,250, 12, 30,133, 76,205, 22, 39,241,215,116,223,221,172, 63, 0,152, +125,243, 38, 1,128, 49, 1, 1,216,174,215,107, 88,226, 7,128,115, 59,118,222,118, 95,116,203,150,156,202, 89, 26, 80, 40, 59, + 82,120, 24,185, 57,127,163, 83,251,129, 24, 40,149,121,221,134, 55,111,222, 60,241,143, 63,254, 96,201,223, 6,192, 4,192, 31, + 0, 99, 50,153,132,126,126,126, 40, 43, 43,147,185,243, 4,240,224, 6,181, 90, 77,234,146,159,130,203,102, 96,119, 17,244,218, +181,107,223, 5, 48,104,232,152,135,253,214,174, 93,219,252,177,255, 36, 5, 1,176, 3, 96, 27,110,151,202,251,134,115,125, 62, +182,191, 41,149, 74, 82, 83,127, 99,239,243,212,223,148, 74, 37,249, 51,227, 16, 4, 2, 33,236,118, 27, 74,203, 43, 48,245,209, +137,228,147, 79, 62,169, 83, 29, 86, 87, 42, 26,217,123,249, 71,194,221,182,191, 44, 56,101, 2,212, 27, 45,178, 81, 19,166,106, +218, 54, 11,129,191, 84, 8,134, 97, 96,103, 0,161,128, 66, 88, 72, 87,244,232,212, 78,163,222,190, 69,110,183,234,101,222, 42, + 1, 22,139, 69,214,173,199,101, 77,159,174,151, 33,160,237, 26,109,102,107,185, 88, 36,242, 74,134,190, 56, 15,126, 33,225, 8, + 9, 14, 2, 0,231,191,238,238,107,209, 54,210,163, 55, 96,231,210,217,232, 63,237, 53, 60, 53,229, 17, 0,112,254,235,238,190, + 47, 55, 31,242, 74,187, 22, 8, 4,104,211,166, 13, 4, 2, 1, 44, 22, 11,244,122, 61,236,118, 59,116, 58,157, 79, 47, 55, 80, + 40,192,183,203, 54, 66, 18, 2,220,204, 6, 14, 87,228,162, 32,239, 34,126, 92,250,186, 87, 86,127,159,193,163,208,166,149, 99, +138,164,141, 27,242,143,140,140,116, 78, 7, 0,192,181,107,215,234,165,254,184, 36, 87,157,125,243, 38, 25, 19, 16,128,247,103, + 63, 15, 0,120,223,133,248, 87,159, 63, 95,149,252,189,200,214,154,158,189, 90,214,254, 63, 66,205,107,237,158,128,153, 81, 64, +194, 16,156, 41,220,133,239,254,187, 94, 30,223, 91,197,181, 13, 10,183,110,221,250,171,209,104,196,170, 85,171, 76, 51,102,204, +144, 2, 8, 4,192,172, 90,181,202, 50, 99,198, 12,161,209,104,132, 84, 42,213, 76,152, 48,161, 78, 3,221, 47,191,252, 34,219, +177, 99,135,166,174,185,236,239, 69,242, 95,191,126, 61,116,186, 56,146,154,154,224,245,179,127,251,237,183,178, 70, 68, 54,212, +218,181,107,127, 28, 58,230,225,201,231,255,218, 47,108,211,170,133,237,177,255, 36, 85, 25,119,119,111,249, 5,189,122,245,234, +186,118,237,218, 7,122,245,234,181, 25, 0,246,238,221, 91, 43,169,114,233,111, 74,165,146,128,162, 0, 15, 89,254, 82, 82, 82, + 72, 94,126, 33,254, 58,121,218,121,206,100, 50, 99,201, 23, 43, 43,148, 51, 30,231, 9,251, 31,140,219,130, 0,203,203,203,101, + 67, 71, 79,210,116,109, 23, 14,137,136, 6,195, 48,200,203,203,195,137,191,255,130,197,198,128, 97, 8,194, 67,252, 49,250,129, +135, 52, 70,179,205,235, 31,148,136,242,209,177, 93, 30, 32,160,208,189,211, 85, 72,132, 55,189,182,252, 93,201,255, 54, 11,175, +172, 28,121, 87,179,225, 23, 18, 94,163, 87,160, 54,242,170,142,239,127,254, 5,207, 79,232,143,254,211, 94,171,209,170,117, 7, +177, 88, 12,129, 64,128,224,224, 96,100,101,101, 65,167,211, 57, 20, 41, 31,201,191,101,179,230, 8, 20, 10, 48,233,133, 15,240, +192,212,193,248,253,100, 46,242,140,168, 51,249, 87,199,181,235,121, 56,149,185, 15, 17,161,193, 14,242, 23, 10,234,165,254,198, + 62,250, 20, 0, 32, 84, 40,242,138,252, 1,224,237,229, 95,226,237,229, 95, 58,201,127,187, 94,143, 87, 70, 63,228,184, 24, 33, +230,244,220,223, 95,249, 88,246,236,252, 65,154,255,180,127, 14, 34, 58, 16, 1,240, 7, 13, 1, 90, 55, 31,130,217,239,207,211, +100,181, 90,202, 73,141,208,106,181, 86, 0,248,254,251,239, 13, 0,164,236, 54,202,171, 86,173, 98, 0,248,187,110,171,172,213, +106,125, 74,178,101, 48, 24,100,222,156,111, 8, 36, 38, 38,146,132,132, 84,178,102,205,154,122, 77, 36,230, 66,254, 8, 11, 83, +251, 36,227,208,161, 67, 26,149, 74, 69, 81, 20,229, 84, 6, 26, 10,107,215,174,157, 61,116,204,195, 15,125,248,198, 92, 97,106, +106, 42,254,247,197, 39,194, 74,143,145,147,252, 83, 83, 83,177,124,249,114,244,234,213,107,179,167,254, 86,157,252,107,234,111, + 15, 12,169,244, 2, 6, 5,120,148,151,252,197, 10, 39,249,231, 23, 22, 33,191,176, 8,165,229, 21, 16,137,132,129, 43, 86,173, + 51, 85,183,226,121,220, 27,136,142,142,190,237,175, 86, 5,192,110,183,147,240,200,222,136,108,209, 4, 38,171, 29, 20, 5,108, +223,190, 13, 63,124,191, 10,199,255,254, 27,175,204,155, 3,129,128, 6, 99,103, 16,236, 47, 65,100,239,161, 26,163,209,200,185, +131, 89,173, 86, 89,143, 78, 87, 52,193,129, 6,124,251,125, 62,104,138,160,127,175,115, 26,171,213,234, 85, 39,117, 71,254, 44, +241, 27, 75,139,170, 40, 8,165,101,229, 30,229,185,235, 76,108, 71, 58,180,230,227, 42, 4,247,253,207,220,210,247,118,236,216, + 17,225,225,225, 40, 43, 43,131, 88, 44, 6, 77,211, 48, 26,141,208,233,116, 16, 8, 28,157,220,155,141, 75, 54,252,186, 17,115, +150,237,192,198, 47,222, 66,203,102,205,225, 31, 16,134,171,246, 92,252,184,244,117, 4, 86, 14, 26, 2,142,242,220,145, 63, 75, +252,165,215, 47,161,107,155,102, 40, 55,152, 32,241,151, 0,118,187,199,120, 0, 79,245,247,250,215,191,227,212,209, 12,244,140, +234,142, 82,187,103,165,145, 37,255,115, 59,118,226,237,229, 95, 58,207,111,215,235,177, 93,175, 71,150,242, 93,236, 56,125, 28, + 61,250, 71, 1, 69,158,183,102, 94,123, 97,177,108,214,139,163, 52, 17, 1,221, 96, 36,229,128, 57, 31, 98,115, 49,204,246,114, +152, 24, 35, 24,113, 32, 90, 15,139, 69,218,177, 69,158, 6, 58,234,167,159,126,130,201,100,130, 82,169,244, 87, 42,149,128, 99, + 10, 0, 74,165, 18,149,199,149, 22,148, 9, 63,253,244,147,215,157,246,236,217,179,178,121,243,230,105, 62,251,236, 51, 66, 81, +148, 6, 0,246,236,217, 67, 22, 45, 90, 68,222,122,235, 45, 77, 99, 25, 92,116,186,184, 59,105,249, 35, 44, 76,141,105,211,166, +121,189, 27,165, 43,225,167,164,164, 80,236,118,210, 13,101,253, 3,144,181,105,213, 66,156,144,144, 0, 0, 56,114,228, 8,118, +111,249, 69,122,237,122, 30,195,146, 63, 0, 36, 36, 36, 56,251,219,137, 19, 39,150,214,165,191, 45,153,241, 16, 78, 94,186,138, + 22, 81, 45, 1,189,129,115, 97,243, 11,139, 96,181,218, 42,199,106, 27,172, 86, 27,174, 94,201,150,214,165, 2,170,123, 15,120, +111, 66,227, 66, 21, 87,148,217,108, 70,223,174, 93, 53,254,126, 34, 48, 12,129,157, 1,246,237,217,139,119,223,255, 0, 12, 1, + 46, 92,188,136,227,127, 31, 67,207,158,125, 32, 16, 80,232, 18,213, 6, 89, 71,109,240,227,184, 57,158, 88,152,143,206,145,215, + 1, 33,133,171, 55,172,128,144, 66,239,174, 87,112,232, 68, 62, 8, 90,251,244, 0,174,238,125,119,158, 1, 99,105, 81,149,213, + 0,158,224,234,222,119,167,105, 31, 90,243, 49,226,230, 46,119, 27,197,238, 10,155,205, 6,127,127,127,208, 52,141,208,208, 80, + 24, 12, 6,232,245,142,109,128, 35, 34, 34, 80, 84, 84,228,213, 6, 28, 38, 29,208,223,207, 15,175,124,177, 7,113,125,128, 43, +127, 1,135, 43,175,189,242,197, 30,124, 62, 87, 14, 59, 99,247,186,254, 78,101,238,115,126, 30, 21,211, 21,194, 32, 26,219,181, +167,209,183,107, 91, 4, 7, 74,240,125,154, 26,177,242, 7,113,205,205, 42, 0, 79,245,183,249, 52, 1,110, 0, 19, 70, 81,248, +250,247, 44,132,135,118,192, 35, 67, 40, 78,245,199,186,251,183,235,111,109,157, 76,222, 89, 10,180, 46, 5,245,236, 66,144,119, +223, 7,104, 35,168, 67,139,176,188,121,115,234,127,181, 76, 4,116,124, 52, 80,211,190, 73, 12,202,236, 21, 48,235, 46,226,199, +156,181,216, 59, 65,135,238,207,200, 49,250,133, 64,248,133,118,129, 84, 24, 10,225,132, 82, 28,254,229, 48,185, 63,246,254,154, + 6, 41,231,111,208, 52, 13, 66,136,165, 82,137, 54,209, 52,109, 32,132,132,193, 17,196,229,243,242,218,174, 93,187,106, 71,143, + 30, 45, 47, 42, 42,210,108,223,190,221,161,248,108,223,142,110,221,186,161,107,215,174,242,198, 50,112, 60,252,176,229,142,147, +255,240,225,195,181,190, 88,255,174, 83, 38,172, 23,160, 62,119,149,244, 2, 82, 0,221, 1, 8, 71, 62,248, 72, 73, 86, 86, 86, +147, 35, 71,142, 32, 53, 53, 21, 49, 89, 89,244,145, 35, 71, 0, 0, 49, 49, 49, 24, 59, 34, 22,193,129, 18, 44,255,110, 99,254, +212,169, 83,223, 88,177, 98,197, 92,111,251,219,141, 95, 63, 70, 80, 15, 41, 2, 59,205,193,250,143,159, 65,159,158, 45,208,229, +161, 15,160, 82,169, 40,119, 81,246,174,198,147, 84, 42, 1, 0,136, 68, 66, 24, 12,166,122,173, 4,158,244, 27, 6, 94,111, 6, +196, 48, 12,252, 37, 98, 88,108, 4, 52, 5,208, 20,176,240,189, 15, 96,103, 0,189,190, 2,121,121, 55,208,188,121, 11, 16,194, +192,102, 3,164, 34, 33, 4, 34,110, 46, 88,155,205, 38,235,222,241,154,166,105,104, 25, 64, 81, 14,221,152, 2, 40,138,160, 95, +143, 11,154,131,199,155,203,189, 93, 17,192, 90,247, 53, 77, 9,112,177,254,171,107,209, 53, 17,191, 55,214, 63, 0, 20, 22, 22, +162, 89,179,102,144, 72, 36,172,247,195, 25,248, 23, 18, 18, 2,145, 72,132,171, 87,175, 66,196, 81,222,119,234,116, 60,243,208, + 8,176,230,205,121,155,195,253, 15, 0,178,206, 64,240, 7, 26,204,125,121, 48, 66,189,120,222,107,215, 29,193,138,237,154,133, + 65,103, 54, 67, 24, 44,128,169,192, 0,208, 52, 90,182,111,131, 29,187, 15,251, 84,127, 79,205,255, 16,151,247,237,130, 48, 15, + 40,105, 14,248,211, 52, 6, 70,118,192,200, 17,205, 57,201,169, 62,215,191,122,202, 51,216, 96, 62, 7,220,103, 2, 14, 10,129, + 64, 33, 48, 62, 6,109,198, 63,197,205, 27,211, 58, 12, 22, 75, 49, 68, 54, 43,126,204, 89,139,140, 25, 33, 24, 62,105, 34,186, + 54,235, 38, 63,185, 67,171,233,155,160,135,200,162,135,173, 43,131,130,155,220,130, 70, 43,149, 55,211,140, 25, 51, 2, 1,232, + 8, 33, 34, 0,152, 49, 99, 70,157,115,107, 60,242,200, 35,218,189,123,247,202,207,156, 57,163,241,247,247,135,191,191, 63,166, + 77,155,214,160,131,104, 98, 98, 34,209,233,226,240,240,195, 22, 76,155, 54,141,170,207,242,212, 23,249,187,115,247,167,164,164, + 80, 74,165,146,204,156, 57,179, 33,234,175, 21,128,200, 74,165,208,127,236,163, 79,152,162,162,162,164,169,169,169, 96,201, 63, + 33, 33, 1,205, 91,182,116,237,111,191,195,101,138,128, 75,127, 75, 28, 63, 28, 7,174,231, 35,168, 79, 16,114,183, 95, 2,164, + 18, 60,250,194,116,132,181,121,136,227,216,108, 71,238,141,155, 54,145, 72, 40,100, 61, 0, 0,112,245, 74,118,157, 30,190,166, +169, 3, 94, 33,104, 56,133,160,186, 18, 64,187, 51,113, 8, 33, 96, 8, 96,103, 28, 74, 0, 69, 1,191,108, 72,195,164, 71,226, +209, 52,162,153,115, 0, 36, 94,236,149, 45,160,243,209,227,190,171,206,227,222, 61,253,157, 78,178,126,221,179, 32,160,243,189, +126,160,234,238,126,119,215,189,177,254,171,187,251,221, 93,119, 93,203, 94, 27,202,202,202, 80, 94, 94, 14,179,217, 12,134, 97, + 80, 80, 80,224,116,255, 27, 12, 6, 84, 84, 84,120, 53, 5,176,241,139,183,160, 61, 9,148,102, 3, 86, 35,240,249, 2,185,211, +253,127,244, 47,224,216,141,125, 16,120, 89,127,165,215, 47, 33, 44, 36, 0,225, 97, 1,232,210,185, 27,178, 46, 23,224,124,110, + 17,218,133,135,192,124, 51, 31, 23, 47, 92,172,146, 11,128, 75,253, 13,150, 77,196, 80,249,227,216,248,219,122,104,254, 92,143, +181,159,206,199,163,243, 23,225,184, 21, 40, 40,202,231, 84,127,174,115,253,255, 25, 60, 0,211,186,183,199,250,141,187,113,252, +120, 54, 62, 61,113, 4, 63,197, 77, 7,190,217,143,220,220,130, 42,185, 0,106, 66, 27,147, 4,118, 75, 33, 44,150, 82, 0, 64, +243,214,109,209,181, 91, 55,121,153,159, 35, 22,195,200, 24, 64,155,245,240,211, 11,112,243, 70,237, 10, 0,251,206, 76, 38, 19, + 76, 38,147, 20,128, 5, 64,144,201,100, 10,174,190, 36,208, 87, 24, 12, 6,217,159,127,254,169,233,214,173, 27,158,120,226, 9, +121, 97, 97, 33,182,111,223,222,160,243,176,119,194,229, 95,159,228, 95,221,250,103, 99, 20, 92,189, 0, 13, 80,109,226,202, 63, + 26,128,176,244,250, 37,183,238,116,182,191,253,117,244,175,203, 83,167, 78, 77,244,166,191, 13,187,191, 11, 20, 67, 58,227,195, +247, 62, 65,242,178,173,248,191,213,187,145, 52, 50, 22,121,155,182,162, 84, 87,230,145,108, 85, 42, 21,149, 48, 97, 44,172, 86, +219, 95, 86,171,205,230,170, 0, 0,192,162,133,175,251, 76,216, 60,209, 55, 44,220,205,253, 87,247, 10, 84, 81, 0,104,154, 70, +105,133, 1, 2,154,130,205,102, 7, 67, 8,108,140, 35,136,244,239, 99,127, 97,228,168, 49, 0, 0, 59, 33, 16,208, 2,148, 27, + 44,176, 89,204,158, 53, 76,187, 93,214,161,245, 13, 77, 68, 88,169, 83,203, 24,220, 63,208,161,109, 80, 20, 40,138,160,111,183, +139, 26,155,221,206,185,147,178,214,125,109,193,128, 62, 89,175,181, 4,215,120,131,208,208, 80, 20, 20, 20, 64, 34,145,160,188, +188, 28, 17, 17, 17,206,160, 64,147,201,132,146,146, 18,175, 20,128,196, 15,127,194,231, 11,228, 8,137, 4,180, 39,129, 23, 23, +107, 16, 40, 20,224,145,151, 62,194, 53, 38, 15,107, 62,125, 21, 2,154,187, 60,214,250,143,137,233,140,136,168, 72, 52,139,104, + 10, 49, 77,193, 70, 17, 20,232,141,208,149,155,124,170,191,228,143,127,197,195,221, 58, 32, 56, 56, 28,254, 17,173, 96, 45,214, +225,175,223,215,161,164, 56,199,167, 70,252,237,199,179,129,185, 10, 8,109, 22, 68,234,129,124, 65, 25, 62,191,113, 24, 16, 7, +115,150,113,244,183, 3,242, 66,218,136, 28,177, 1,177,247,201,209,125,122, 32,178, 66,181,154,136,136,191, 52,109, 7,102,161, +148, 46,135,153, 24, 97, 88,205, 64, 26, 24,196,197,242,119, 29,224,217, 85, 0,226,250,234,184,219,182,109, 3, 0, 76,155, 54, + 77,222,181,107, 87,237,164, 73,147,156, 22, 99, 67, 65,169, 12,173,209,237,239,107, 64, 96,125,146,127,117,130,119, 85, 88, 82, + 82, 82,168, 67,135, 14, 53, 68, 44,192, 53, 0, 37, 0,232,107,215,243,144,145,145,225,156,243,143,137,137, 1, 0,164,166,166, +226,231,205, 91,161, 43, 55, 25, 0, 44,130, 99,105, 32,231,254,182,105,227, 59, 24,179,224, 5,140, 27, 55, 10, 77, 37, 2,148, + 83, 4,219,207, 95, 69,198,201, 92,175,136,122,214,140,199,239,207,186,120, 81,120,245, 74, 54,216,191, 69, 11, 95,175,213,146, +231,209,184,137,191,250, 57,119,168, 50, 5, 32,145, 72,112,225,244,113,121,100,171, 48,141,159, 72, 8,187,157, 1, 69, 81,160, + 40, 32, 81,249, 60, 8, 97, 96,175,204, 7, 96, 48,153,112,230,124, 22,196, 98,207, 78,108,155,181, 24,125,187, 95,118, 29, 69, +241,220,220,203,216,176,186,147,115, 86, 53,182,231, 37, 28,248,187, 27,132,130, 8,175,172,127,119,196,111, 44, 45, 2, 0,159, +172,127,119, 29,237,208,154,143, 1,128,179,245, 15, 56,214,249,183,104,209, 2,102,179, 25, 55,111,222,132,221,110, 71,211,166, + 77, 81, 84, 84,132,166, 77,155, 86,214, 43,119,194, 46,200,187,136,183, 62,208,160, 52, 27,248,239,252, 97,168,176,217, 49,111, +113, 42, 62, 91,144,128,249,159,254, 14, 33, 69,193, 11,254, 71,233,245, 75,104,217,180, 9, 68, 16,193, 14, 10, 55, 46,159,194, +149,252, 82,116,140, 8,195,166,163,251,113,230, 52,188,182,254, 31,157, 57, 15,162, 48,128, 22, 0,171,182, 94,198,134,175, 94, +193,204,143, 85,152, 55,190, 15,158, 31,213,222,171,250,219,174,215, 35,121,194,100,160, 68, 10, 80, 34, 32,249, 19,196, 31,222, +131, 29,163,102,129,250,232, 5, 80, 7, 94,229,100,253, 3,192,177, 27,225, 24, 96, 44, 69,133,159, 0, 6,169, 20, 29, 31, 21, +193, 76,140, 40,165, 69,176,161, 51,136,221, 0,107,225, 13,236,251,162, 20,211,166,118,108,144, 78,123,228,200, 17, 82, 73, 12, +212, 35,143, 60,162,117,248,198, 28, 24, 54,108, 24, 53,108,216,176, 6, 29, 84,106, 91,147,239,139,119,160, 62,201,191,186,245, +239, 32,214,219,151, 15, 54, 64, 44, 64, 57,128,203, 0, 98,206,255,181, 31,174,115,254,207,205,156,140,109, 81, 81, 96,167, 3, +254,136,138,242,159, 58,117,234,119,222,244,183, 41,138, 1, 8, 97, 66, 97,128, 8, 27,150,190,128,175,126, 63,134, 87,198, 14, +197,140, 79,215, 34,126,209,143, 94, 89,224,174,201,132,220,157,227,215,239,255, 51, 81,197, 3, 32, 16, 8,168,146, 27, 23,113, +233,106, 17,132, 34, 1,108,118, 6, 86,155, 29, 71,143, 30,193, 15, 63,124, 7,139,157,192,106,103, 32, 22,210,200,215, 85, 32, +247, 76,134,220,207,207, 79,235,129, 8,101,221, 58, 94,185,101,253, 59, 28,169,216,176,186,179, 99,140,163, 9, 64, 19,208, 52, +131,129,125,206,104,236, 28,188, 0,238,172,127,215, 85, 0, 1, 97, 45,188, 34,127,119,214,191,107, 84,109,220,220,229, 94,145, +151, 99, 80,212,161,162,162, 2, 34,145,200,105,253, 51, 12,227,252,215, 91, 5,224,199,165,175,227,104,110, 58, 2, 91, 56,130, +254,130,132, 2, 20,228, 93, 68,176, 68,132,146,226,107, 16,208, 20,132, 52,183,233,103,214,250,111, 27, 22,132,211, 89,151, 97, +179, 88, 32, 17,138, 81, 81, 97,194, 38,205,126,196,202, 31,244,138,252,217,250,155, 56,251,125,172,249,252, 51, 24, 24,160,109, +199, 54, 56,121,234, 0,230,141,239,227, 83,253, 1,192,188,142,177,248,237,194,110,160,212, 6, 72,155, 98,231,161,211,160, 62, +122, 1,203,155, 55,167,184,146, 63, 0, 76,237,180, 64,187,111,231, 33,192, 82,142, 10,170, 28, 58,186, 2,165, 66, 43,172,246, + 50, 72, 76, 6, 72,175, 95,198, 79,111, 92, 64,100,116,103,212, 18, 0, 88, 5,126, 46,145,175, 82,169, 20, 82,169,212,237, 53, +174,248,250,235,175,241,245,215, 95,223, 19,131, 6,107,241,171,213,106, 2, 56, 2, 2,189, 9, 10,172,111,242,255,246,219,111, +101,196,243, 90,247,134, 90, 17, 96,187,118, 61,175, 74,180,255, 91,111,207,133, 68, 40, 70,243,230,205,193,174, 14,168,188, 30, +224, 77,127,123, 70,214, 27,115, 62,249, 12,229, 55,243, 17, 17,220, 12,167, 78,231, 96,198,167,107,161, 82,169, 40, 95,200,154, +253,158,235,247, 93,229,240,158,128,123, 3,199,142, 29,171, 53, 25, 80,141, 30, 0, 0, 8, 10, 10,210, 30,209,254, 42, 39,100, +130, 38,178, 85, 56,130,252, 37,232,222, 51, 26,221,123,244,129,144, 6, 42,140,118,228,220, 40,198, 33,237, 22,121, 96,128,191, +199, 31,208, 27, 12,232,220,254, 6, 76,102, 41, 8,107,212, 16,192, 79,106, 2, 33, 64,113,137, 4,160,128,160, 0, 27,122,117, +206,198,158,204,190, 8, 10, 10,226,108,253,187, 90,252,126, 33,225, 16, 17, 43, 96,187,181,244,197, 46,244, 92, 70, 87,235,223, +213,226,103,207, 93, 60,245,151,243, 94, 46, 89,246, 92,149, 0, 0,104,209,194,161,140, 20, 23, 23, 35, 56, 56,216,233,254,247, + 70, 1, 96,149, 0,224, 35,204, 74, 24, 1,124,190, 7, 95,189,249, 32,226,231,127,134,181, 31, 63, 15, 33, 69, 65, 44,225,182, + 98,135,181,254, 79,231,228,227,190,182, 77,241,205,255,126, 66,100,100, 36, 66, 90,117, 68,159, 86, 29, 97, 53,223,114,255,139, + 56,200,100,173,255, 15,102,142,194,139, 11, 87,161,109, 20, 85,167,250, 99,173,255,209, 27,191,197,142,105,143,131,106, 51, 16, +128, 35, 43, 32,224, 72, 17,204,222,251, 98,243,230,156,136,163,183,249, 85,106,237, 39,139,101, 29, 31, 41,215, 68,118,234,137, + 50, 63,224, 50,174,160, 60,187, 0, 5,139,236,168,208,181,193,220,233,243, 57,191,144, 21, 43, 86, 80,126,126,126,196,104, 52, +194,197,242, 36,126,126,126, 88,177, 98,133, 23,233,137,238, 61,176, 22,255,205,155,142, 28, 30,222, 6, 4, 42, 20, 10, 74,167, +139, 35,245, 65,254, 0,192, 18, 59, 23,130,170,107,134, 65, 31, 32, 44,189,126, 9, 31,190,243, 22,126,249,237, 15,140, 25,218, + 15,187,212, 7, 28, 6, 76,171,142, 8,105,213, 17, 49, 89, 89, 24,251,232, 19,133, 57, 69,134,209,237,194,253,211,184, 90,255, +115, 86,254,134, 55,158, 30,141, 86, 45,100, 78,229,130,125, 70, 46,158, 27, 95,188, 3,188, 39,224,222, 85, 10, 56, 41, 0, 0, + 16, 28, 20,168, 61,170,253, 85,126,185, 77, 23, 68,117,234,166, 9, 14,240, 3, 67, 0,163,217,130,172,172, 44, 20,100, 29,147, + 7, 5, 6,128,166,105,143, 29,215, 79, 42,197,250,109, 35,228,108, 4,124,173,238, 8,154, 70, 64, 0,119,235,137, 93, 2, 24, + 16,214, 2,140,221,234, 32,255, 74, 88, 41,145,199, 20,187,213,193, 46,169,137,155,187,188, 10,105,249, 66,254,174, 74,128,107, +226,159,226,226, 98,207, 47,192,131, 18,240,163,203, 42,225,175, 23, 61,119,235,192, 90,129, 64,142,114,218,134, 5, 97,125,230, + 49,156, 60,123, 14,177,242, 7,171,144,190, 55,228,207, 98,226,236,247,177,161, 95, 0,102, 79,234, 90, 47,245, 55,175, 99, 44, +230,111, 94, 15,234,195,133,248,163,249, 0, 44,171, 56, 89,229,250, 35, 33, 77,208, 70,234,221,158, 20, 83, 59, 45,208,254,177, + 57, 13,215,116,151, 80, 80,116, 3, 55,207, 7, 66, 96, 15,198,144,222,195, 32,159, 46,111,208, 65,237, 94,202,246, 87, 31, 75, + 0,149,202,208,122, 33,255,234, 86,106, 35,196, 25, 0, 49,109,195,130, 48,104,208, 32, 28,187,144,139,166, 29,122, 84,233,111, + 99, 31,125,194, 0,224, 11, 46,228,207,226, 25, 89,111,196,169, 15, 98,218,194, 31, 48,124,248,112, 52,111,222,220,173,162, 85, + 95, 15,193, 42, 1,222,212,117, 77, 10, 25,175, 68, 52, 28,233,115, 74, 5, 12, 0,193,193,193, 90,115,241, 85,217, 81,237,121, + 57,224,136,164, 37,132, 64, 34,145, 32, 36, 56,136,115,167, 21,137, 68,218, 16,145,168,222, 31,142,117,245, 11,108, 6,192,102, +112, 70,192,179,196,239,237, 90, 44,214,213,127,241,212, 95,184,120,234, 47, 68, 68, 68,160,160,160,192, 39,226, 15,137,104, 5, + 11,135,224, 72,174,152,246,254,143,216,191, 71, 91,111,242,178,179,179,157,187,253, 89,205,166,219,200,223, 27,226,103, 49,189, + 95, 64,189,213, 31, 0, 80, 75, 95,117, 18, 63, 75,254,151,245,122,249, 35, 33, 77, 48,158,163,213,239, 14, 15,116,136,167,208, +161,242,192,135,192,246,148,148, 20,138,205,246,183, 98,197, 10,202, 53,243,223,170, 85,171, 40,118, 87,174, 85,171, 86, 81, 41, + 41, 41,255,200,129,165, 62,150, 0,222,101, 43,188, 33,177,247,196,137, 19, 67, 0,116,104,218,161,135,193,106, 54,249, 87,246, +183, 50, 0,165, 0,206,180, 11,247,159, 2, 71,176, 32,103,196,189,245,245, 93, 33,254,186, 40, 90, 60,201, 55, 12,162,163,163, + 57,145,191, 71, 3, 84, 40, 20,106, 61,185,227,239, 54,216,185,125,150,248, 81, 71,226,103,231,166, 75,243,175,161, 52,255, 26, + 34, 34, 34,234,100,241, 3,128,205,206,120,237,125,168, 13,249,197,165, 62,151,165, 58,216,185,253,250, 34,254,250,174, 63,118, +110,255,183,138, 10,226,106,245,247, 21,138,234, 68,252, 60,120, 52, 4,166, 78,157,170, 2,240, 67, 78,145,193, 96, 53,155, 92, +231, 35,131,219,133,251,135,194,203,221,255, 88, 82,117,117,243,255, 11,149, 42, 30, 28,148, 0, 78,134, 86,116,116, 52, 31,216, +193,131, 7, 15, 30, 60,120,252,203, 64,243, 85,192,131, 7, 15, 30, 60,120,240, 10, 0, 15, 30, 60,120,240,224,193,131, 87, 0, +120,240,224,193,131, 7, 15, 30,188, 2,192,131, 7, 15, 30, 60,120,240,248, 71,160,202, 42,128, 89,179,102,249, 28, 69,234,110, +187, 73, 94, 94,227,146,215,180,105,180,207,242, 10, 11,143, 53,244,243, 82,149, 10, 43, 3, 55, 73,118,248,247,203,203,227,229, +253,227,228,161, 14,242,240,111,151,247,175,244, 0,212, 53, 93,165, 90,173,150,169,213,106,226,242, 39,227,245,196,134, 67,105, +105,233,147,123,247,238,253, 36, 35, 35,131, 57,122,244,168,109,239,222,189, 47,195, 37, 79,126, 93,224, 41,125, 44, 15, 30,119, + 19,155, 55,111,150,213,225,187,242,164,164, 36, 82,143,101,153, 82, 41, 47,180,210, 80,228,151, 24,254,211, 61, 0,247, 58,234, + 74,214,106,181, 90,182,126,253,122,205,228,201,147, 93, 79,107,212,106,181, 92,161, 80,104,235, 80, 38, 77,106,106, 42,155,170, +211, 43, 89,137,137,137, 94,117,234,201,147, 39,215,186, 30,120,231,206,239,188,149, 39,215,233, 2,180, 13,240, 58,169,147, 39, + 79,254,183,172,172,236,233,246,237,219, 55, 41, 44, 44, 68,229,118,187, 75, 54,108,216,176, 36, 32, 32, 96,228,216,177, 99,235, +148,219,221,219, 84,204, 14, 5,115,150,215,131,172, 74,181,130,186,123,242,106, 87,128,107,218,244,197,155,254,129,133, 20,168, +247,106, 80,168, 22, 82,152,124, 38,193,235,122, 29, 51,102, 12, 1,128,237,219,183,215, 11,209,176, 91, 1, 43,149,161,245,190, + 62,126,243,230,205,178,173, 91,183,106,188,201,222,248,236,179,137,132, 16,199,214,234,238, 48,126,252, 67,242,173, 91,183,106, + 38, 76,152, 64,249,208,142, 71,254,241,199, 31,187, 70,140, 24,129,164,164, 36,178,118,237,218,184,178,178, 50,181, 55,101,115, +103,141, 62, 54, 88, 12,101,146,178,248,213,213, 11, 54,125,252,248,199, 19,217,107, 95,127,189,178,214, 50, 62,241,196, 19, 4, + 0, 2, 2,106,222,218, 64,175,215, 3, 0,102,204,152,193,231, 47,184, 75, 96,147, 3,185,230, 8, 16,122,232,240,110,243,102, + 55, 64, 62,109,174,168, 19, 33,184,146,191, 66,161,160, 92,146,109,104,124,209,128,217, 1,147, 37,154,202, 13, 63, 52,222, 42, + 1, 72, 13,243,226, 87, 21, 30,239,208,143,127,142,187, 56, 47,247,181,169,137,128,188,204, 10, 70,149,150,150,254,220,179,103, +207, 71, 1,208,132, 16,248,249,249, 33, 63, 63, 31, 37, 37, 37, 8, 9, 9, 65,126,126,254,238,109,219,182,201,199,142, 29,171, +245,242,157, 16,118, 99, 22,138,162,240,232,163,143, 66,161, 80,200, 41,138,226, 44,103,243,230, 95,157,159, 39, 76,120,216,227, +177, 39, 24,247,207,190, 85,221,131,151, 87, 57,174,126,206,111,176,231, 77,149,216,237,132, 93,241,231,159,127, 98,209,162, 69, +183,189,139,213,171, 87, 19,174,109, 57, 53, 53, 85,131,133, 84, 37,193, 38,220, 62,112, 47,164,234,108,129, 54,226,177,229,255, +217,251,238,240, 38,174,172,253,119, 70,178, 44,247, 6,166,152,106, 27, 7, 66, 51,205, 33, 84, 9, 12, 4, 92, 66, 0, 3, 9, +201,126,132,221,181, 96,247, 99, 83, 72, 48, 11,187,191,148,111, 33, 49, 27, 2,187,217, 77,176,179, 73, 72, 54, 78, 65, 38,152, +102,154, 64,162, 4, 8, 96,122, 7,155,106, 3, 6, 23,185,168,107,238,239, 15,121,132, 44, 84, 70,178,140, 13,153,247,121,252, + 88,186, 26, 29, 77,189,239,123,206,185,247, 92,171,167, 93, 88, 88,184, 59, 39, 39, 71, 74, 8, 65, 94, 94, 30,217,191,127, 63, +250,245,235,231,246,187, 7, 14, 59,110, 95, 47, 95,128,194,194, 66, 37,195, 48,200,205,205,133,187,101,149, 41,138,146, 16, 66, +172,247,235,134, 13, 27, 2, 41,138,194,139, 47,190,120, 23, 64,187,151, 94,122,105,231,234,213,171,105,120,176, 30,197, 71, 59, + 63,178,190,190,179,253, 54, 40,138,194,119,175, 5, 2,160,240,247,151,151, 63,223,166, 77, 27, 0,192,247, 95,127,135,185,163, +231,114,178, 57,104,208, 32,196,198,198,242,204,219,138,200,223, 30,180,171,142, 92, 46,151, 35, 55, 55,151, 56,234, 64,189, 9, +181,251, 58,156,110,111,207,198,203,246, 10,185,185,185, 84,114,114, 50,197,118, 64, 13,255,165, 77, 17, 20, 20, 69, 33, 35, 35, + 3, 57, 57, 57,148,205,190,121, 44, 84,168,233, 85,214, 63, 46,237,238, 16,188,249, 51,235, 31,151,118, 79,200,159, 16, 98, 13, +175,123, 17,102,167,171,170,170,190, 9, 11, 11,155, 10,128,158, 51,103, 14,102,205,154, 5,145, 72,132,128,128, 0,136,197, 98, + 80, 20, 5,129, 64, 0,181, 90,205,249, 60,230,231,231, 75,100, 50, 25,201,207,207, 7,123, 77, 8, 33, 88,183,110, 29,230,206, +157,171,204,207,207,151,180,198, 7,215,145, 32,104,137,200,154, 92, 46, 87,230,228,228, 80, 51, 46, 76,119,232,225,203,100, 50, + 50,253,124,134,212, 81,100,192, 29,230,206,157, 75,222,126,251,109,116,239,222,221, 39,251, 59,119,238, 92, 34,147, 69, 32, 42, +106,151, 79,207, 67, 65, 65,193, 88,133, 66,177,187,127,255,254,212,167,159,126,170, 98,201,191, 41, 88, 47, 95,128,149, 43, 87, +130, 97, 24, 44, 88,176, 0, 92,108,218,146, 63, 0,108,221,186,117,211,168, 81,163, 0, 32,226,197, 23, 95, 52,141, 30, 61, 26, + 50,153,140,225,234,180,216, 63,163,171, 86,173,194,140,103, 45,190,225,119,175, 5, 96,230, 48, 17, 22, 78,120,155,243, 49, 5, + 5, 5, 97,212,168, 81,200,204,204,180,246,167,246,127,236, 54,188,247,223,114,228,239, 82, 0,176,100, 85, 84, 84,100, 45, 59, +105,235, 61,121, 74,180, 86, 15,194,199,157,146, 3, 49, 32,245,229,201, 91,187,118,109,147,247,217, 86, 80,100,100,100, 72,217, +115,248, 36,193,150,252, 1,160,180,180,212,250,217,173, 91,183, 56, 11, 70,181, 90,253,129, 70,163,121,153,166,105,250,165,151, + 94,130, 90,173, 70, 89, 89, 25,252,252,252, 32, 20, 10, 33, 20, 10,225,231,231,135,128,128, 0,104,181, 90,135, 37, 81, 29,116, +112,146,157, 59,119, 42, 41,138,194,180,105,211,176,122,245,106, 42, 57, 57,153,202,201,201,161,166, 77,155,198,222, 63, 74,190, +171,112, 77,254, 13,231, 82,106, 43,146,217,107,159,145,145, 97,141,106,121,211,169, 39, 39, 39, 83,171, 87,175,166,228,114, 57, + 8, 33, 62, 17, 99,127,254,243,159, 33,151,203, 57,221, 35,238,240,211, 79, 63,141, 59,122,244,168,162, 91,183,110,168,171,171, + 35, 65, 65, 65,100,223,190,125, 0,192,174,254,232, 21,249,127,252,241,199,160, 40, 10, 52, 77,227,232,209,163, 96,109,122, 16, +145,120,158,162, 40,204,156, 57,211,212,208,100,120,241,197, 23,107, 36, 18, 9,230,206,157,203,108,216,176,193,237,177,219,166, +194,238,108,191, 13, 80, 64,222,159, 30, 84, 45,254,238,181, 64,188, 56,220, 31, 89,207, 45,228,188, 95, 92, 60,127, 62, 58,240, +232,200, 63, 51,235, 67,135,159, 11, 93, 61,144, 37, 37, 37,164,168,168, 8,114,185, 28,236,107, 54,180,227,201, 67,222,220,228, +111,235, 85,123,155,171,127, 84,176, 77, 9, 60,105, 32,132,160,180,180, 20,119,238,220,177,182,217,191,119, 3,193,193,131, 7, + 39, 37, 36, 36, 64, 32, 16,224,202,149, 43, 32,132,224,226,197,139, 48, 24, 12,160, 40, 10, 66,161, 16, 20, 69,193,108, 54, 67, +163,209, 96,253,250,245, 72, 78,118,157,246,216,181,107,151, 18, 0,166, 77,155,246,208,125,219,240,158,176, 68,193,229,190,182, + 15,235,187,123,207,197,203,103,225, 44, 29,192, 37,244,111,143,189,123,247,162,193, 51,108,154, 0,126,135, 2,101, 35,224, 88, + 1,203,230,252, 21, 54,228,239,141,183,206,138, 48,150,140,118,237,218,165,244,214, 51,100,237,245,232,209,227, 33,114,243, 6, +159,125,246, 25,206,159, 63, 79,218,182,109,139,152,152, 24,235,178,207,215,174, 93,131, 64, 32,192,191,255,253,111,175,126, 96, +244,112,203,242,101, 12,195,224,173,183,222,194,170, 85,171,176,111,223, 62, 80, 20,133,180,244,223,227,250,181, 95, 56,217,217, +186,117,107, 65,195, 53,214,193, 50, 67,134, 1,128, 23, 95,124,177, 26, 64,120, 97, 97, 33, 40,138,226, 44,168, 44,222,255,195, +235,152, 88,210, 1,192,247,223, 29,199, 70,181,247,131, 21,121,180, 30,242,119, 41, 0, 0, 32, 51, 51,147, 98,189,126,150,252, + 29,230,254, 60, 32,107, 87,158, 32,151, 60,177, 59,123,246,159,183,212,138, 84, 10,133,130,200,100,178,135,246,145,109,243, 85, +174,147,172,141,240,233,126,215,165,122, 54, 21,197,246,216, 28,117,182,157, 58,117,122,104, 91, 23,215, 36, 60, 50, 50,178,143, + 94,175, 71,101,101, 37, 14, 28, 56, 0,129, 64, 0,131,193, 0,173, 86, 11,134, 97,172,171, 82, 26,141, 70,232,245,122, 78, 41, + 6,150,176,156,157,239,228,228,100, 42, 63, 63,159,200,229,114,183, 98,194,226,117, 21, 52, 34,123, 95,141, 1, 8, 24,246,175, +135,136,158,125,239,141, 16, 24, 53,106, 84,211, 69,128, 93,206, 95,161, 80, 72,172,100,255, 32,231,239,213, 24, 25,251, 8, 25, + 96, 89,109, 81, 38,147, 17, 46,215,129,107, 20,160, 97,236,131,199,207, 27, 59,181, 42, 38, 38, 6,161,161,161,148,189,216,237, +211,167,143,215,158, 63, 33, 4, 38,147,201,218, 54, 98,196, 8,236,219,183, 15,123,126, 54,227,163,108,110, 57,246,141, 27, 55, + 78,104,200,253,159, 3,208, 6,128,237, 98, 67,101, 0,194, 1,160,176,176, 80,217,191,127,127,183,246, 26,231,254, 29, 68, 10, + 26,254,115,181,199,163,245, 67,200,229,225,100,189,127, 79, 61,255,146,146, 18,226,203,112,183, 59,123, 13,105, 9, 95,134,114, +189,238,212,236,247, 51, 39, 39,167, 78, 38,147, 5,219,126,238,139, 78,206, 54,247,239, 11, 49, 96,155,251,231, 42, 6,102,205, +154,133,160,160, 32, 4, 7, 7, 35, 36, 36, 4, 97, 97, 97, 76, 68, 68, 4, 93, 88, 88,136, 87, 94,121,197,186,157, 88, 44,198, +248,241,227, 33,147,201,136,147,213,170,162, 12, 6, 3, 42, 43, 43,161,211,233, 16, 22, 22, 6,127,127,127,152, 76, 38, 16, 66, + 96, 54,155, 97, 48, 24, 96, 52, 26, 97, 54,155, 61, 26, 95,224, 46,101, 53,109,218, 52,180,134,212,140,187, 1,129,158,130, 21, + 1, 94,223, 95,239, 59, 63,119,211,207,103, 52,140,187,241,206,182,189,247,111, 43, 36,189, 17,200,246,222,191, 43, 97,202,149, +252, 5, 2, 1, 9, 13, 13, 5, 44, 3,234, 40, 0,196,104, 52, 66,173, 86, 35, 58, 58,218,171,227,102,157, 41,161, 80,136, 55, +222,120, 3, 71,143, 30,197,131,188, 63,247,123,122,219,182,109,219, 70,142, 28, 9, 0, 33,176,164,115, 53, 0,240,195, 15, 63, + 68,239,217,179, 39,148, 16, 98, 21,219,142,230,217, 63,228,253,255, 99, 21,102, 14,125,216,251,159,245, 79, 13,126, 56, 96, 4, + 33, 4, 3, 94, 26,128,185,163,231, 82, 92,236,241,104,221,222, 63,192,161, 14,128, 66,161,176,134,254,109,199, 3,112, 65,108, +108, 44,149,145,145,225,179,156, 60, 7,123, 94,231,215,237,230,254,179,127, 12, 59, 43,160,169,121,196,204,204,204,224, 39,249, +134,203,205,205,197,199, 31,127,220,232,190, 98,201, 63, 61, 61, 29,233,233,233, 0,128, 61,123,246,184, 50, 19, 89, 82, 82,162, + 51,155,205,168,170,170,194,253,251,247, 81, 85, 85, 5,141, 70, 3,141, 70,131,186,186, 58,212,212,212, 64,173, 86, 67,171,213, + 66,175,215,195,108, 54,187, 39, 49,138, 66,126,126,190, 71,130,237,113,198,222,189,123, 27,253,217,226,194,133, 11, 18,219,247, + 92,114,206,246, 57,127,123,207,189, 41,145, 44, 71,223, 93,189,122, 53,149,159,159,239,211,177, 0,249,249,249,156,159, 97,150, +252,105,154, 38, 13,247,151, 53,244,207, 48, 12,238,222,189,139, 30, 61,122, 80,222, 20,110, 89,146, 53, 26,123,246,236, 1,243, + 99, 56, 8, 33, 88,185,114,165,245, 26,237, 61,192,121,220, 30, 54,110,220, 56, 25, 0, 94,124,241,197,210, 6, 1,160,255,254, +251,188,232,121,243,230, 69,239,217,179, 7, 19, 39, 78, 28,231,201, 52,197, 59,219,111,131, 2,133, 60, 27,239,255,165,127,104, + 32,152,169,198,247, 7, 12,120,253,245,215,145,189,109, 57,207,172, 79, 16,249,187,141, 0,228,230,230, 54,202,251,219,142, 7, +200,204,204,164, 56, 62,224,170, 6, 98, 86, 54,120,194, 77, 10,123, 59,178,199,134,253,147,147,147, 85,190, 26, 85,154,156,156, +124, 70,161, 80,244,105,141, 23,152,245,250,125, 21,254,103,189,126, 79,195,255, 44,242,242,242,172,175,223,123,239, 61,124,245, +213, 87, 0, 96, 0, 32, 98,137, 31, 0,198,143, 31,239, 78, 0,104, 19, 18, 18,160,209,104, 96, 48, 24,112,239,222, 61,248,251, +251, 67, 40, 20, 90, 35, 0,245,245,245,208,104, 52,208,235,245, 80,171,213,152, 58,117,170, 91,129,201,122,247,174,166,181,178, +219,113, 65,115,142, 1,240,230,115,123,176,211,253, 28, 97,229,202,149,202, 55,222,120, 67,218,179,103, 79, 85, 75,222,195,206, +188,127, 91,120, 50, 22,192,153,247,239,173,231, 79,211, 52, 97, 24,134, 2,240, 46,123,107,155,205,230,119,130,130,130,208,169, + 83, 39,175,250,152,191, 44, 26, 13,149, 74, 5, 42, 63, 10, 0,176,227, 47, 33, 24,255,183, 90,140, 26, 53, 10, 75,179,247,128, + 16,194, 57, 90,177,117,235,214,245,163, 71,143, 6,128,123, 63,252,240, 93,204,158, 61,251,194, 9, 69, 48,105,226,164,244,244, +244,244, 77,158,116, 39,128, 37,247, 63,115,152, 95, 99,143, 31, 4,111,188,254, 6,218,141,111,143, 39,117,220,210, 19,237,148, +101, 47,114, 42, 16,216, 8,172,144,139,231, 63,104,208,160,135,198, 3,120, 18,162,179, 39,109, 31,144,179,189, 61,159,143,224, +206,204,204,236,163, 80, 40,124,102,239, 73,125,128,216,194, 50,108,152, 88, 46,151,227,213, 87, 95, 5, 0, 17,187,141,237,103, + 13,157,150, 51,156, 29, 58,116,232, 43, 42,149, 74,110, 54,155, 81, 83, 83, 3,163,209,104,205,251,235,116, 58,235, 20, 67,118, + 96,224,248,241,227, 85, 28,238, 23, 74, 46,151,147,134, 40, 64,163,251, 86,161, 80,176,237, 72, 78, 78,230, 20,173,122,212, 99, + 0,236,211, 2,238,174,135,171,207,101, 50, 25, 89,185,114,165,114,198,140, 25,248,241,199, 31,189,141,150, 73, 28,189, 95,187, +118,173, 50,179, 84,134,233,110, 60,237, 9, 19, 38,144,171, 87,175, 98,219,182,109, 78,207,247,213,171, 87, 1, 0,219,183,111, +119,187, 63, 25, 25,114,146,145, 49, 22,227,198,149,160,164,164,196,225,232,242,138,138,177, 0,170, 32,147, 57,239,183, 88,242, + 55, 24, 12, 68, 36, 18,177,219,188,219, 32, 8,222,185,126,253, 58,186,118,237,234,149,231, 79,211,148, 69,176,179,228,127,202, +132,175,148, 6, 0,192,210,236, 61, 30,247, 17,236, 51, 49,111,222,188, 68, 66, 8, 82, 82, 83,166,166,165,166,253,228, 77,215, + 52,249,133,231,207, 81, 20,245, 52, 33,128, 96,166, 26,132, 16,188,241,230, 27,104, 63,190,195,131,196,135,247, 96,163,204, 4, +158,228, 55,120, 60, 18, 56, 21, 0,182,211,253,236, 66,125, 68, 46,151,123,156,195,102, 73,219, 87, 59,110,107,175,169,243,255, +121, 52, 29,182, 33,116, 91, 18, 98,235, 73,216,127,230, 36,135,104, 2,176,110,244,232,209,243, 11, 11, 11, 63, 49,153, 76,168, +174,174,182,142, 1, 0,128,123,247,238,161,186,186, 26,132, 16,120,146, 94, 26, 55,110,156,116,231,206,157, 74,185, 92,142,252, +252,124, 98,159,243, 31, 55,110,156, 71,197,128,154, 3,218, 3,255,235, 49,225, 59, 34,120, 87, 34, 32, 39, 39,135,154, 59,119, + 46,241,134,252, 27, 13, 0,180,185,238, 54,131, 2, 61,141, 2, 56, 21,238,215,174, 93,179, 10, 52,174,142,134,109,170,242,225, +227,230,214, 87,169,213,106, 18, 22, 22,102, 75,254,239,232,245,122,148,149,149,161,123,247,238, 94,145,191, 76, 38, 35,204,143, + 17,216,113,202, 50,232,111,141,210,128, 31, 14, 24, 64, 8,193,190,131,222,115,226,222,189,123, 49,113,226, 68,105,122,122,122, + 83,238, 91,154, 97, 24, 63, 0,248,241,160, 17,175,191,254, 58,218, 79,232, 96, 23, 31,240, 12,108,149,191, 81,163, 70, 17,192, +241,116, 63,155, 74,128,132,175, 5,224, 91, 56, 25, 95,229, 89, 37,192,156,156, 28, 42, 55, 55,151, 56,154, 54,229, 73, 10,192, + 1,105,251, 12,118,246,124, 58,255,223,174, 28,176,199,200,200,200, 0,135, 1,139,156,225, 44,220,239,109, 26,192, 89,184,223, +155, 52,128,109,121, 89,123,242,113,245,153,179, 67,165, 40,234, 95, 41, 41, 41,171,243,242,242,140, 34,145, 8,122,189, 30, 38, +147, 9, 12,195, 32, 60, 60, 28, 85, 85, 85,200,240,112,234,217,180,105,211, 84,211,166, 77,163,118,238,220, 73,242,243,243, 33, +151,203,193,214, 5,248, 53,117, 64,187,119,239, 38, 41, 41, 41,216,188,121,115,147,201,223,158,228, 20, 22, 65,230, 54, 26,247, +246,219,111, 63,228, 92,216, 99,225,194,133,132,235, 32, 79,153, 44,194,173, 61,153,140, 91,254, 63, 32,192, 90,250,146, 16, 66, +160,209,104, 80, 86, 86,230,117,206,191, 81,228,227,111,181,141,222, 55,133,252, 63,253,244, 83, 95,221,179,204,198, 13,155,122, +216, 86, 2,244, 21, 92, 9,178, 53,107,214,240, 76,221,154, 35, 0,128,101, 26,160, 39,237, 45,137,214, 54,255,191, 97,224,148, +143,132, 72,178,207,246,107,250,244,233, 82, 79,203,251,186, 33, 6, 98, 43,104, 28, 13,180,178,255,140, 35,225,154,102,205,154, + 69,237,216,177, 67,114,227,198, 13,165, 86,171,133,217,108,198,211, 79, 63, 45, 29, 60,120,176,215,215,123,220,184,113,212,184, +113,227,216, 30,222,171,212, 76,115,143, 1,112,247,158,139,199,217, 48, 58,188, 49,225,120, 88,100,134, 61, 71,120,135, 34, 10, +100, 60,228, 15,102,102,102,146,204, 82, 25,168,198,133,128, 40, 0,184,124,249, 50,113,245,108,184,251,221,177, 99,199, 82,158, + 60,107,190,216, 6, 0, 42, 43, 43, 17, 16, 16, 64, 40,138, 66,215,174, 93, 65, 81, 20,213,163, 71, 15, 52,149,252,233, 25, 85, +160, 40, 10,233,207,103, 90, 28,107,138,178, 78,247, 99,195,249, 45, 4,102,208,203, 3,125,106,112,246,236,217,172,248, 15,134, + 37,170,103,130, 37,252,207,216,108,195,167, 3, 90,187, 0,120, 92,224,139,185,254,173,213, 11,244,245,126,249,122, 97,159,230, + 62,111, 13, 57,126,135,191, 97, 48, 24, 32, 16, 8, 32, 16, 8, 30,225,189,246, 25,213,186,237, 57,127, 22, 94,126,249,101,207, + 13,190,243, 96, 29, 11,185, 92,222,168,211,206, 44,149,217,122,222,170, 39,161, 47,105,223,190, 61,245,224, 89,177, 12,182,109, + 42,249, 91,174,137,171,165,128, 30,198,103,159,253,242,200, 8,114,238,232,185,212,163,238, 19,248,176,255,163,135,163,212, 0, +149,152,152,200, 43, 49, 30, 60,120,240,224,193,227, 87, 6,154, 63, 5, 60,120,240,224,193,131, 7, 47, 0,120,240,224,193,131, + 7, 15, 30,188, 0,224,193,131, 7, 15, 30, 60,120,240, 2,128, 7,143, 71, 12, 87,107, 89,243,224,193,131, 7, 15,239,209,104, + 22,192,188,121,243,188, 30,153,233,168,176, 11,111,143,183,199,219,123,116,246, 22, 47, 94,220, 88,221,211,180,117,154,163,237, + 84, 51,182,154,162,237,212, 51, 71,229,131,131,131,131, 33, 22,139,173,223,167,105,218, 58,227,194,214, 30,187, 48, 19,195, 88, +102,121,177,139,229,240,215,215, 19,123,148, 68, 32,244, 7, 97, 76, 96, 24,147,202, 27,123,132, 16,233,201,147, 39,133,137,137, +137, 10,216, 85,221,243,210,158,228,228,201,147, 72, 76, 76, 84,181,208,249, 67, 19,236,225,215,110,207, 99, 1,240,107,196,146, + 37,135, 27,221,120, 75,151, 38, 81,173,202,222,225, 37, 4, 0,150, 38, 45,165,108, 95, 55,245,184,221, 85,140,115,247,121, 83, +237,243,120, 24,180,161, 94,114,239,204, 1,140,138,184,167,140, 49,221,196, 37,210, 29, 71,235, 35,165,161, 9,207, 64, 20, 20, +162,114,247,253,253,251,247, 99,196,136, 17, 86,226,103, 9,155,162,168,135, 8,155, 97, 24,235,223,245,235,215, 29,218, 59,118, +236, 24, 6, 13, 26,132,128,128, 0, 8,133, 66, 8, 4,130, 70, 54, 89,210, 55,155,205,214, 63,189, 94,143,162,162, 34,196,199, +199, 63,137,151,136,178,240, 34,145, 92,188,120, 17,151, 47, 95, 86,134,135,135, 99,228,200,145, 77,186,207, 41,138,150,248,139, + 35, 17, 30,241,148,178,190,174, 84, 90, 87,123, 83,226,169, 13,134, 97, 36,249,249,249,187, 47, 93,186,132,205,155, 55, 35, 32, + 32, 0, 11, 22, 44, 16,192,102,238,189, 23,246,148, 37,197, 87,176,115,199,118,136,252,253,241,250,235,111,140, 33,132, 40,249, + 39,245, 9,141, 0, 60, 78,200,207,207,119, 59,125,113,218,180,105,110, 31, 76,150,160,237,137,219, 91,248,218, 30,143,135,133, +133,237,251, 39, 66,100, 16, 34, 57,183,127, 7, 66,175, 30, 84,106, 52,122, 24,159,161, 17,208,137, 66,143, 27,167, 48, 36,132, + 40,171,238, 29,193,137,192,223, 72,239, 83, 49, 46, 69,192,185,115,231, 32, 16, 8, 48,114,228, 72, 8,133, 66,235, 31, 43, 8, + 88,175,223,100, 50,193,108, 54,195,104, 52,226,250,245,235,216,189,123,183, 67,123, 26,141, 6,199,143, 31,199,208,161, 67, 33, + 18,137,224,231,231,215,200, 38,195, 48, 48,153, 76, 48,153, 76, 48, 26,141,208,106,181, 56,126,252, 56,234,234,234, 90,133,158, +106, 32,108, 26, 15, 10,209,120,205,209,139, 23, 47,102,236,250, 22,212,214,214, 34, 42, 42,202,171, 10,164,139, 23, 47,110,180, + 63,255,253,174, 8, 1, 1,209, 16, 8, 68,202,186,218,155, 30,219, 60,124,248, 48,234,234,234, 48,116,232,208,235,201,201,201, + 29, 42, 42, 42,176, 99,199, 14,115,100,100, 36, 6, 15, 30,236,242, 25,153, 61, 97,236, 67,231,230,244,133, 11, 80,133, 4,226, +205,149,239,223, 28, 48,176, 79,231,219,183,202,177,163, 80,181,187, 91,159, 1,201, 53, 53,234, 93,124, 79,212,250,225, 40,125, +106, 95, 11, 64,232,170,147,101, 59, 87,119,239, 91,130,252,255,240,135, 63,184,220,166,170,170, 10,223,127,255, 61,225, 34, 2, + 88,178,110,170,183,222, 28,246,108, 61,127, 95,120,255,182, 4,106, 79,166,238,238,131, 71, 77,244,108, 25, 97,219,114,194, 0, + 80, 89,105,169,140, 24, 25,169,120, 34, 30,212,107,191, 40, 16,127, 83,169,188,169, 97, 48, 37, 94,128,167,218,154,192, 68, 18, +248, 69, 10, 80, 91, 33, 66, 64,173, 22,189, 78,254, 75, 89,148, 48, 87,170, 9,236,170,114,238, 73, 82, 56,127,254, 60, 68, 34, + 17,198,140, 25, 99, 37,109, 63, 63, 63,208, 52, 13, 66, 8,140, 70, 35, 76, 38, 19,244,122, 61,110,222,188, 9,165, 82,233,116, + 73,101,154,166, 97, 52, 26,113,242,228, 73,140, 28, 57, 18, 1, 1, 1,240,247,247,183,218, 99, 5,128, 94,175, 71, 93, 93, 29, + 78,159, 62, 13,157, 78,231, 81, 97, 38,149, 74, 37, 17, 8, 4,202,218,218, 90,136, 68, 34,148,151,151,255,239,148, 41, 83,106, +197, 98,241,127,189, 33,109,149, 74, 53, 93, 32, 16,252,104, 99,239,210,148, 41, 83, 46,138,197,226,105,176,172, 80,233,177, 39, +252,151,191,252, 69,185,108,217,178,114, 0,209, 13,228,141,115,231,206, 33, 58, 58,218,105,221,117,119,228,255,229,156, 57,152, + 52, 96, 0, 0,160,253,252,249, 8, 8,108,135,186,154, 27,168, 81, 23, 75, 9, 49,171, 60,181,217,175, 95, 63,148,151,151, 99, +255,254,253, 93,105,154,198,233,211,167, 17, 25, 25,137,189,123,247,194, 96, 48,184, 61,143, 21, 31,188,217,232,125,176,193,136, +142, 38, 29, 94,127,251,157,206, 43, 63,122, 15,127,255,232, 83,196,208,102,124,250,209,199,138, 49, 51, 95,226,217,245, 49, 36, +127,182,157,211, 90, 0,192,195,245,191,221,189,127,148,240,229, 74,125,143, 3,108, 69, 64, 83, 96, 43,226,190,122,225, 27,167, +219,189,186,254, 55, 45,234, 93,179,191,109,255,223,157,104,121,220,160,171,190, 47, 25,165, 63,174, 44, 23,152, 17, 31, 6,116, +237, 66, 32,232, 39,130, 48, 54, 22, 34,189, 14,250,159,111, 66,175, 22, 66,192,248, 65,167,248,175,146,158,244,154,148, 17, 58, + 78, 7,176,225,249, 43, 87,174, 32, 34, 34, 2, 82,169, 20, 98,177, 24, 34,145, 8, 66,161,208,234,245,235,116, 58,148,149,149, + 97,207,158, 61,160,105, 26, 52, 77,195,149, 61,179,217,140,179,103,207, 98,196,136, 17, 8, 13, 13,133, 88, 44,134, 64, 32,128, +201,100,130,193, 96, 64, 77, 77, 13,142, 28, 57, 2,189, 94, 15,161, 80,104, 29, 11,224, 14,223,126,251,173,164,174,174, 78,121, +245,234, 85,212,212,212, 64, 36, 18,161,125,251,246,255,218,183,111, 31,134, 13, 27, 38, 12, 10, 10,250,202, 19, 17,240,237,183, +223,190, 80, 87, 87,247,163,157,189,132,125,251,246, 37, 12, 27, 54,236,251,160,160,160,105, 92,237, 49, 12, 35, 49, 24, 12,168, +172,172, 84,218, 68, 20, 0, 0,203,150, 45, 43, 93,188,120,113,204,180,105,211,198,136,197, 98,143,250, 63, 90, 32,146,216,183, +221,249,228, 19,180,159,220, 9,127,255,251, 63,164, 70, 99,189, 87,253,233,254,253,251,149,191,252,242, 11, 22, 45, 90, 84, 35, + 16, 8, 66,197, 98, 49,134, 13, 27, 6,165, 82,137,194,194, 66,196,196,196,120, 16,239,160,240,237,149,219, 88,119,185, 20, 27, + 55,124, 13,129,128,194,155,243, 95, 97,250,183,111, 67,231,190,254, 14, 62,247,212, 30,143, 22, 33,127,123,113,234, 72, 20,120, + 61, 11,160,165,151,183,141,141,141,149,186,251,123,212,222,122,115,216,243,133,215,255,168, 61,119,150,164,109, 95, 55, 37, 82, + 97,143,200, 72,133, 87,222,191,201,100,146, 28, 57,114,132, 56,107,179,255,204, 25,108,183, 55,153, 76, 18,251,207,236,219, 92, +161,242,236, 49,101, 89,105, 13,162, 67,132,136, 13, 33, 16,182, 97, 32,124,246, 57, 4,245,255, 47, 2, 6,174,128,127, 88, 0, + 68,117, 90,104, 52,102,116, 17,104,176, 55, 47,199, 57,185,208, 52,132, 66, 33,252,252,252,112,249,242,101,156, 62,125, 26,161, +161,161,136,138,138, 66, 84, 84, 20,218,180,105,131,240,240,112,168,213,106,236,221,187, 23, 2,129,192,154,219,119, 4,246,115, +145, 72, 4,179,217,140, 75,151, 46, 33, 48, 48, 16,109,218,180, 65,116,116, 52,218,182,109,139,224,224, 96, 92,186,116, 9, 70, +163,209,154, 34,112, 38, 40,236, 61,255,187,119,239, 42,139,139,139,209,189,123,119, 76,152, 48, 1, 73, 73, 73,208,104, 52,216, +189,123, 55, 78,158, 60,249,133, 78,167,227, 92,187, 88,165, 82, 73,239,150,223,251,169,228,182, 26, 33,241, 67,145, 48,225,183, +136, 73, 74, 71,149,158,198, 78,197, 46,156, 60,121,114,138, 78,167,251, 61, 87,242,175,169,169,193,169, 83,167,148,251,247,239, + 71,191,126,253,176,120,241,226, 54,104,200,167, 47, 94,188, 56, 6, 0, 60, 33,127, 90, 32,146, 4, 5,119,148, 68, 70,245, 81, +230,253,112, 10,115,190,252, 18,133,199,143,163,240,248,113,180,159, 63, 31, 0, 96, 52,214,239,241,230, 89, 41, 44, 44, 36, 27, + 55,110,196,212,169, 83,175,135,132,132,208,129,129,129, 69,135, 15, 31,198,254,253,251,113,255,254,125, 36, 36, 36,120,100,239, + 31,199, 47,227,163, 67,103,240,249, 71,127, 62, 37, 20,104, 65,155,107,177,124,213,151,244,143,123,139, 80, 70, 11,241,212, 83, + 79,241, 44,251,132,128,246,150,224, 91,112,241,138,230,241,176,151, 28, 38,190,204,219,251,218,222,227, 36, 4, 42, 43,147,173, +127, 77,141, 0, 56,106,183,143, 10,112, 65,109,109,173,100,215,174, 93,202,195,135, 15, 59,109,179,253,204, 21,108,183,223,181, +107,151,178,182,182, 86, 98,251,153,125,155, 43,132,234, 42, 80,120, 67,135,173, 87, 25,220,172,162,112,247, 30, 64, 11,195, 64, + 83, 81,160,116,254,168,191, 75,225,212, 13, 6,167,111,232, 80, 81,107, 68,223, 72,127, 37, 23, 1,224,239,239,143,226,226, 98, + 92,184,112, 1,145,145,145,136,136,136, 64, 68, 68, 4, 52, 26, 13,246,239,223, 15, 63, 63, 63,136, 68, 34,151,107, 41,176,209, + 1, 86, 4, 16, 66, 80, 82, 82,130,200,200, 72,116,234,212, 9,109,219,182, 69, 73, 73, 9,204,102, 51,252,253,253, 33, 18,137, + 26,205, 60,112,212,173,176, 47,238,221,187,167,188,117,235, 22,122,247,238,141,231,158,123, 14,169,169,169,210,212,212, 84,233, +200,145, 35, 97, 54,155,113,240,224, 65,148,148,148, 12, 5,192, 41,159,112,239,222,189,221,119, 43,213,136,140,235,143,132,228, +217,232,157, 50, 15,189, 82,230,162,235,179, 47,192, 64, 4,172, 61, 78,215,183, 97,236,131,242,242,229,203,236,177, 74, 27,136, +159, 94,188,120, 49,150, 45, 91,134,101,203,150, 93,176, 31, 23,224, 12, 2,161, 88, 18, 17,217, 75,217, 62,102,132, 50, 34,170, + 23, 40, 90,136, 47,190, 82, 98,206,151, 95, 98,206,151, 95, 98,217,178,101,184,119,239, 30,184,218,179,243,252,201,166, 77,155, + 48,108,216, 48, 12, 28, 56,176, 43, 0,241,174, 93,187, 6, 93,187,118, 13,103,207,158,133, 86,171, 69, 74, 74,202, 24,174,246, +190,187,120, 19, 43,142, 92,192,234,165,111, 87,118,122,170,107, 63, 77, 93, 21,190,251,105, 23, 78,157,190,136,189, 91,118, 66, +125,231, 46, 82, 82, 38, 37,131, 71,171, 69, 98, 98,162, 83,239,159,211, 24,128,156,156, 28, 74,161, 80, 72,184,190,127,156,225, + 75, 79,189, 57,236, 1,190, 11,255, 55,151,199,239,233, 54, 92,136,219,151,179, 8, 84, 42,149,164,172,172, 76,201, 46,238,226, +172,205, 27, 92,185,114, 5, 21, 21, 21,202,142, 29, 59, 74, 37, 18,137,202, 89,155, 83,226,186,127, 19, 7,110,107,145, 18, 24, +136,125, 55, 25,116, 28,232,143,238,250, 34, 84,157,251, 3,214, 47, 63, 5,230,154, 26,117, 6,130,210, 90, 51, 2,132, 52, 76, +234, 59, 8,115, 33,218,109, 69,128, 88, 44,198,245,235,215,113,225,194, 5,244,238,221, 27, 85, 85, 85, 56,116,232,144, 53,151, +239, 46, 95, 79, 81,148, 53, 10,192,218, 35,132,224,230,205,155,232,219,183, 47, 20, 10, 5, 24,134,129, 88, 44,134,159,159,159, +117,150, 0,151, 8,192,141, 27, 55,160,211,233, 48,104,208, 32,116,234,212, 73, 42, 16, 8, 16, 26, 26,138,103,158,121, 70,122, +232,208, 33,229,141, 27, 55, 80, 83, 83,115, 26, 28, 67,246, 55,110,220, 0, 67,139, 16,147,152,140,240, 78, 9,160, 5,126, 8, + 8,109,139, 46,207,164,224,250,161,141,104,176,119,205,157, 29, 66,136,164,186,186, 90, 89, 90, 90,138, 46, 93,186, 96,248,240, +225, 82,129, 64,160, 26, 49, 98, 4,181,120,241, 98, 50,116,232, 80, 83, 67,191,153, 16, 22, 22,134, 6,129, 98,118,101, 83, 44, +142, 66, 84,219,254, 48,232,213,184, 95,113, 28,122,125,213, 88,163,177, 46, 9,192, 7, 67,135, 14, 5, 0,220,189,115, 7, 13, +246,252, 0, 24,185, 28,243,177, 99,199,166,229,229,229, 97,214,172, 89, 24, 49, 98, 4, 0, 48, 59,118,236, 16, 22, 22, 22, 98, +206,156, 57,227,251,245,235,183,211,147,123,249, 82,141, 6, 89,123, 78,224,195,183,100, 24,153,154, 28, 89, 95,119, 31,107,127, +218,131,156, 47,214, 97,235,155,179, 17, 91,126, 11,217, 53,119, 16, 25, 25,197, 15, 2,124, 76, 96, 27,246,119, 52, 94,197,233, + 24, 0,251,220,190,187,247, 79, 34,154,107, 10,158,167,248,219,144,191, 73, 41,138,106,149,231,219,158,164, 29, 9,130,230, 24, + 75,192,213,230,198,141, 27, 37,119,239,222, 85, 26, 12, 6,151,109, 77, 65, 85, 85, 21,234,235,235,149, 53, 53, 53, 82, 71,109, +233,233,233, 78,175,221,201, 74, 45,212, 6, 6, 39,239,153, 80, 86,109, 66,187, 67, 66,244, 91,123, 5,215,175,157,197,197, 95, + 12, 48, 9, 5, 48, 48,128,206, 64, 80, 69, 24,180,141, 32, 46, 9,219,118,250, 31, 59, 98,255,238,221,187,232,218,181, 43,174, + 93,187,102, 13,249, 11,133, 66,235,246,158,166,243,108,107, 8,176,255,155, 41, 37, 88,141,166,141,222,127,200, 25,119,183, 1, +195, 48,168,175,175,183,116,142, 66,161, 84, 32, 16,168,236, 34, 73,194,141, 27, 55, 34, 61, 61,157,206,202,202,186,155,157,157, +109,202,202,202,114,121,240, 20,101, 17, 68, 90,205, 93,212,213,222,148,154,205, 58, 21,128,189, 0, 62,168,173,173,197,198,141, + 27,173, 98, 50, 62, 62,222,224,206, 94,195,253,149,158,159,159, 47, 79, 73, 73,177,146,255,207, 63,255, 76, 23, 20, 20, 64, 34, +145,164,122, 74,254,183, 53,122,188, 82,120, 8,175, 79, 79,193,180, 87,166, 66,163,171,193,250,141, 42,172,250,244, 59,124, 51, +126, 8, 98,203,111,241,108,250, 4,136, 1,123, 17,240, 72, 42, 1,218,231,130,221,189,231,241, 80,199,254, 88,137, 45, 54, 71, +239,237, 40,125, 46, 99, 8,184,222, 47,233,233,233,170, 30, 61,122, 72, 35, 34, 34, 92,182, 53, 5, 17, 17, 17,232,209,163, 71, + 35,162,119,212,230, 8, 90,115, 40,140, 20,112,244,190, 30,229,102, 51,118,149,232,176, 86,174,195,238, 91,109,113, 69, 20,134, + 91,106, 35,110,214, 50,168, 55, 1, 26, 19,129,127, 84,123,183,196,204,206,239, 55,155,205, 48,153, 76,136,138,138, 66,112,112, + 48,186,118,237, 10,163,209,104,109,119, 84, 16,200,222, 30, 59,191,223,100, 50, 65,171,213,130, 16,130,206,157, 59,163,180,180, + 20, 29, 58,116,128, 80, 40,132, 94,175,135,193, 96,176,254, 46,151,244, 96,151, 46, 93, 32, 22,139, 81, 84, 84,132, 91,183,110, + 41,205,102, 51,106,106,106,168, 95,126,249, 69, 89, 87, 87,135, 46, 93,186, 32, 52, 52,244, 57,174,125, 84,151, 46, 93, 64, 51, + 6,148, 30, 87,160,250,214, 37, 48,102, 35,180, 53,247,112,227,151, 45, 48,212, 87,177,246,186,113, 17, 55, 44,162,162,162,148, + 12,195, 88, 35,157,203,150, 45,163,206,158, 61,139, 6,210,102, 0,180,115, 84,240,200, 30, 38,147, 22, 38, 99, 29, 2,130,218, + 67, 28, 16, 9,128,146, 0, 48, 45, 91,182, 44,202,198, 30, 62,255,252,115,182,128,146,195, 99,174,168,168, 32,223,124,243, 13, +201,201,201, 33,239,191,255,254,134,244,244,116,164,166,166,178,209,128,154, 77,155, 54, 97,218,180,105,233,211,167, 79,223,194, +229,156, 85, 84, 84,144,255,254,247,191,100,230, 31,254, 23, 99,242,247,224,173,223, 76,193,159, 22,206,131,206, 80,135,171,197, + 55,145,147,179, 22, 5,105,195, 32,233, 28,237,245,179, 81, 80, 80,192,247,235, 45, 8,251,116,128,253, 64,192, 71, 90, 10,216, + 62,109,224,238,253, 35,243,244,157,228,234,237,189,125,174,222,191, 51,123,135,151, 44, 33,135,151, 60, 8,231,219,191,119, 23, +137,240,149,189,230,142, 8,216,230,232,189,245,254,221,141, 33,240,196,174, 68, 34, 81,165,165,165, 73,109,139,211, 56,106,243, + 6,241,241,241, 72, 75, 75,107, 20,234,119,212,230,244,251, 61,226,209, 35, 72,128, 16, 10, 48, 18,130,243, 85, 6,228, 93,209, +227,251, 3,101, 56, 82, 92,137, 50, 45, 80,161, 51,163,184,142,224,182,158,160,206, 96,148,186, 34, 47,118,106,158,193, 96,128, + 86,171, 69,135, 14, 29,208,167, 79,159, 6, 97, 22,137,164,164, 36, 43, 97,179,164,237,140,176, 89, 66, 55, 26,141, 48, 24, 12, +160, 40, 10,113,113,113,168,174,174,198,205,155, 55, 81, 89, 89,137,110,221,186,129,166,105, 24, 12, 6,232,245,122,235,119,220, +161,109,219,182,210, 78,157, 58,225,236,217,179,216,182,109, 27, 54,111,222,172,220,188,121,243,238,125,251,246, 65, 32, 16,224, +217,103,159, 69,108,108,172, 22, 28, 11,217,180,109,219, 54,189, 93,100, 24, 42, 74, 78,224,226,206,175,112,118,203,103, 56,191, + 37, 7,215, 15, 22,192,159,102, 88,123,165,238,236, 8,133, 66, 85,187,118,237,164,161,161,161, 56,121,242, 36,110,221,186,165, +212,104, 52, 18, 91, 33,208, 16, 9,160,243,242,242,208,187,119,111,183,251,102,208,171,161,174,190, 2, 63,191, 32,132, 71,246, + 84, 6, 5,199,192,207, 47, 72, 66, 81,244, 80,118,155,144,106, 5,148,223,252, 9,227,122,214, 1, 54, 99, 37,108,177,101,203, + 22, 4, 4, 4,160,119,239,222,232,214,173, 27, 26,210, 7,166,170,170,170,186,252,252,252,240,196,196,196,244, 49, 99,198,108, +226,122,239, 22, 22,110, 65,104,104, 48, 70,141,126, 70,147, 56,176, 31, 94,248,195, 28,104, 40, 19,238,149, 87, 98,238,252,255, + 67,246,224,120, 12,140,246, 94, 36, 23, 20, 20,144,229,203,151,243, 34,160,149, 8, 1,135,247,123, 43,242,114, 91,237,201,243, + 85, 14, 62,105,233, 82,202,158,164,147,150,122,159, 82,240,198,158,173,231,252,234,250,223,112,242,196, 91,186,216,142,237,126, +216,215, 7,224,106, 35, 36, 36, 68, 53,118,236, 88,105,100,100,164,210, 89, 91, 82, 82, 18,183,243,222,176, 93, 82, 82, 18, 6, + 12, 24, 32, 21, 10,133, 42,219,207,236,219, 92,122,135,254, 65,210,190, 29,218, 40,187, 86,169,113,223,204,160, 70,103,130, 63, + 33, 32,122, 19,186, 4, 11, 81,101, 50,161,180,222, 4, 0, 72,233,209, 14,221,134,140,118,106,139,245,250,217,169,126,125,251, +246, 69,255,254,253, 81, 85, 85,101,157,158, 23, 18, 18,130,161, 67,135, 98,253,250,245,214,154, 0,206, 8,155, 21, 19, 70,163, + 17, 20, 69, 33, 33, 33, 1, 90,173, 22,247,238,221,179, 78, 43,212,233,116, 72, 72, 72, 64,121,121,185,213,158,179,186, 2,246, +162,236,214,173, 91,210,160,160, 32,229,213,171, 87,113,242,228, 73,118,218, 30, 6, 15, 30,140,254,253,251,111, 17,139,197,111, +130, 99, 10, 64, 34,145,108,186,117,235,214,203, 65,129,117,223, 94, 45,254, 5,101,199,119, 62,176, 55,124, 12,250,247,239, 63, + 91, 44, 22,111,228, 98, 43, 52, 52, 20, 3, 7, 14,196,207, 63,255,140, 3, 7, 14, 32, 38, 38, 70,217,173, 91, 55, 4, 5, 5, + 73, 23, 47, 94, 44,253,231, 63,255,169,236,218,181, 43, 6, 15, 30,140,143, 63,254, 24,179,102,205,114,105,143, 97,140, 42,117, +213, 21, 41, 8,148, 97,145, 9,104,223,241, 89,165, 86,123, 31,117, 53,215,241,247,143,254,153,246,222,187,139, 55,117,236, 4, +124,255, 90, 32,168,233, 85,144,254,198,177,232,185,116,233, 18,198,142, 29,139, 17, 35, 70, 48, 52, 77,211, 26,141, 6,132, 16, +252,235, 95,255, 10,238,217,179,231,228,153, 51,103,110,242,228,185,186,120,241, 18,166, 77,125, 30, 51,103,166, 7,246,233,251, + 20, 42,106,213,168, 83,223, 71,230,159,254, 15,255,247,194, 88,140,101, 52, 77, 34,255, 85,171, 86, 33, 33, 33, 1,159,124,242, + 9,230,207,159, 79, 38, 79,158,204, 87, 6,125, 4,112, 54,224,175, 69, 5,128, 47,103, 21, 76,155, 54,141,242, 85, 37, 64,119, +176, 47,196,227, 43, 17,208, 84,242,247,214,158,237,124,250,230, 44, 5,220, 84,216,166, 15,108,247,195,155, 25, 0,182,222,221, +144, 33, 67, 40,103,109,246,159, 57,131,171,237,185,218, 96,241,172,100,140,170, 68, 72, 96, 58, 92,136,107,106, 32,152,242, 67, +215, 96, 26,165,102, 10, 2,127, 33,246,150,155,161, 99,128,182,254, 2,196, 13, 30, 5,113,143,193, 42, 87, 2,192,104, 52, 66, + 32, 16,160,123,247,238, 24, 56,112, 32,106,106,106,160,211,233,172, 2,192, 96, 48, 32, 50, 50, 18, 35, 70,140,192,166, 77,155, +172, 41, 1, 71, 48,155,205,214, 81,253,189,122,245, 66, 67,152, 30, 58,157,206,250, 60,179,145,132, 94,189,122,161,178,178, 18, +117,117,117,174,158,229, 70, 31,188,252,242,203, 42,149, 74, 53,166,119,239,222,187,109, 10,247, 84,143, 28, 57,114,183, 88, 44, +158, 5, 64,231,201,185,124,249,229,151,243, 84, 42, 85, 77,239,222,189, 55,218,216,187, 63,114,228,200,127,137,197,226,175,185, +218,161,105, 90,213,177, 99, 71,233,132, 9, 19,112,245,234, 85,229,133, 11, 23,112,227,198, 13,132,132,132, 40,195,195,195, 49, +110,220, 56,252,231, 63,255,193,224,193,131, 57,239,155,201,164, 81, 85, 87, 93,148,234,116,149, 8,143, 72, 80, 6,135,116, 70, + 72,104, 23,212,215,150,110,250, 48,251, 11,188, 56, 51, 25,223,191, 22,232,240, 60,177,152, 52,105, 18, 10, 11, 11,113,235,214, + 45,186,178,178, 18, 58,157, 14,123,247,238, 21, 38, 37, 37, 97,236,216,177, 53,158, 62, 15, 41, 41,147,176,126,253, 38,212, 84, + 87,224, 86,217,109,188,246,199,223, 24,222, 94,180, 76,244,194,152, 97, 24,161,175, 1,252,188,163,135,130,130, 2,242,238,187, +239, 90,203, 65,199,197,197, 97,249,242,229, 88,184,112, 33, 47, 2, 90, 88, 20,180,136, 0,104,142, 89, 5,190, 32,119, 22,247, +239,127,129, 37,135, 55,184,172,182,231,201,224,191,251,247,191,192,225, 37, 27, 28,122,229,246, 33,123, 46,164,125,255,139,251, + 56,188, 97,137,207,236,181,118,252,218,214, 16,232, 54, 76, 42, 61,165, 55, 41,239,237,222, 5, 63,147, 22,167,106, 9, 20,181, + 38,136, 40, 10, 81,132, 64,218, 33, 28, 17,237,219, 74, 59, 61, 35,113,227,105, 90, 34, 0,221,186,117, 67, 82, 82, 18,180, 90, + 45,140, 70, 35, 68, 34,145,149,176, 89, 47,189,109,219,182, 24, 62,124, 56,182,111,223,238, 50, 2, 32, 20, 10,209,191,127,127, + 80, 20, 5,141, 70, 99,141, 46,176,162,157,173, 46,200, 48, 12,250,246,237,139, 67,135, 14,193,147,193,149, 18,137, 68, 9, 75, +200,155, 2, 16, 12, 75,181,189, 27,224, 56, 18,222, 81, 36,192,198, 86, 36,128, 74, 0, 30,215, 38,166,105, 90, 21, 30, 30,142, +190,125,251, 74,253,252,252,216,233,143, 74, 0, 40, 45, 45,197,196,137, 19,241,241,199, 31,123,100,211,108,214,171,234,235, 74, + 37, 6,131, 90, 26, 80,115, 77, 25, 26, 30,135,192,224,142, 8, 12,238,136, 29,187,238,130, 26,219,206,229,247,135, 13, 27, 70, +137, 68, 34, 82, 89, 89,137, 73,147, 38, 25,162,162,162, 68, 12,195,224,198,141, 27,128, 23,131, 37,159,125,118, 24,229,239,239, + 79, 66,207, 21,225,143,127,252, 45, 58, 37,244, 16, 45,127,253,183,204,154, 79,191,166,255, 37,208,121,117, 47, 23, 20, 20,144, +172,172, 44,132,135,135,163,172,172, 12, 1, 1, 1, 96, 24, 6, 65, 65, 65, 88,186,116, 41,150, 44, 89,194,139,128,102, 70, 98, + 98, 34, 78,156, 56,225,125, 41,224,230, 64,107,158, 85,224,138,112,188,241,254,157,217,179,247,212,217,240,189, 59,210,246,181, + 61, 46, 36,219, 84, 18,230, 23, 2,242,140,108, 18,199, 78,160, 42,235,181,146, 48,147, 94, 41,184, 94,130,120,227,109,132, 68, +181,195,176,190, 61, 17, 21,211, 70, 26,150, 56,218,237,243, 65, 8, 65,247,238,221, 49, 98,196, 8,107, 62, 94, 32, 16, 64,175, +215, 91, 75,247,218,166, 9, 58,119,238,140,225,195,135, 67,165,114,108, 58, 32, 32, 0,137,137,137, 16, 10,133, 48, 24, 12,214, +239,217, 78, 29,180, 93, 8,136,166,105, 12, 24, 48, 0, 69, 69, 69,222,156, 6, 2,160,182,225,207, 23,168,243,134,248, 29, 69, +141,250,244,233,195,142,163,160, 24,134,145,104, 52, 26,232,245,122,244,236,217, 19, 43, 87,174,244,112,113, 28,162, 50, 26,106, + 97, 52,212, 73,181,218,123,240,247,143,128,159, 40, 68, 73,211, 66,124,155,183, 69,250,242,172, 20,151,246, 26,234,250, 83, 43, + 86,172, 96,180, 90, 45, 0, 32, 33, 33,193,163,242,203,182, 24, 56,112, 16, 37, 24, 50,100,226,156,119, 87, 20, 90,236, 17, 58, + 33,225, 41, 36, 76,158,252,178, 80, 40,204,243,198,102,118,118, 54,255, 80,183, 18, 17,224,138,252, 31,169, 0,120, 92,225,203, +105,127,246,196,220, 84,111,221,215,246,120,180, 44,198,164, 79, 86, 53,120,175, 24,229,197,247, 51, 50, 50, 16, 17, 17, 97, 29, +225,207, 48,140, 53,132,207, 70, 0,216, 65,127,236,138,128,113,113,113,160, 40, 10, 63,252,240,195, 67,246, 86,173, 90, 5,185, + 92,110,221,214,108, 54,187, 93, 14, 88, 36, 18, 97,240,224,193,224, 50, 58,254,113, 21,107,193,193,193, 8, 14, 14, 70, 84, 84, + 84, 19,132, 46, 43, 4,106, 65,211, 66, 88,198, 99, 51, 74,142,246,200,130, 5, 11,168,134,235, 73,104,154,110,210,115,111, 54, + 51, 91,223,120,227, 13, 10, 0,205, 48,140,153,166,233, 0,120,152,126, 97,193,123,247,173, 75, 4,184, 3,149,152,152,200,143, +208,228,193,131, 7, 15, 30, 60,126,101,160,249, 83,192,131, 7, 15, 30, 60,120,240, 2,128, 7, 15, 30, 60,120,240,224,193, 11, + 0, 30, 60,120,240,224,193,131, 7, 47, 0,120,240,224,193,131, 7, 15, 30, 79, 4, 26,205, 2,152, 55,111,158,215, 35, 56, 63, +251,236,179,135, 6, 19,242,246,120,123,188,189, 39,207,158, 76, 38, 35,207, 79,150, 97, 67, 65, 14,114,114,114,104, 56,152,131, +206,159, 63,222,222,210,165, 75,173,219, 44, 89,178,132,242,194, 30,154,176,127,248,181,219,243, 88, 0,176, 15,183,179,141,189, +153,242,242, 56,219,243,198,102,107, 63, 94, 7, 16, 1, 8, 5, 16,216,112, 63, 48, 0,238,195, 7,115,168,125, 9, 95,150, 37, +126, 84, 43, 22,114, 65,109,109,173,228,192,129, 3,202, 61,123,246, 0, 0, 70,143, 30,141, 97,195,134, 73, 67, 66, 66, 84,173, +209, 99, 96,201,127,210,196,129, 38, 64, 38,148,201,100, 12, 95,243,129,135, 61,150, 46, 93, 74,210,210,226, 26,189,119, 39, 2, +120,180,112, 4,128, 5, 89,251,240, 2, 16,212,116,239,215, 77,119,212, 65, 52,101,245, 63, 95,219,115,116,188, 77, 57,230,214, +126,188, 44,241,159, 61,181,239,171,179,103, 79,142,109, 31, 19,215, 78,173, 54, 34, 44,204, 15,119, 74,139,153,222,189,251, 87, +246,238, 55, 50, 9,192, 85, 79, 12, 30, 59,248, 41, 41, 41,190,132,226,107, 58,220,188, 77,208,185, 3,133,184,110, 98,196,198, + 37, 96,224,179,127,104, 21, 15,191, 35, 33,193,174, 58,216, 18, 68,118,250,244,105,101, 98,226, 54,172, 94,173,129, 74, 5,188, +243,206, 14,220,188,121, 83,217,190,125,123,136,197, 98,148,149,149, 73, 95,120,225, 5,248, 66, 16,236,219,183,143,168,213,106, +233,184,113,227,224,239,239,239,141, 61, 26, 0, 38, 77, 28,200,100,102,102, 10,129, 92,108, 40,176, 60, 42,240,237,178,189, 60, +158, 0, 24, 12, 89,216,190, 61, 19, 19, 38,228, 34, 45, 45,219, 26, 17,224,133,192,163, 1, 95, 8,200, 3,216,146, 61, 69, 1, +204,143, 17, 79,236,177, 26, 13,245,175,108,223,246,227,226,248,248, 30, 61,167, 76, 30,141,206, 49,161, 8, 15,243, 71, 85,181, + 14,165,183, 59,211,151, 75,170,218,108,222,248,165,114,194,115, 51, 86,248,137,130, 62,113,103,239,220,233, 61,146,171,151, 54, + 43, 5,168,193,140, 20, 96,248, 32, 32,174, 43,112,229, 26,193,254,163, 90, 20, 42, 79, 98,203,186,183, 73,247,132, 84,233,211, +125,221, 87,180,107,174,104,135,179, 40, 2,187,184, 80, 75,136,128,202,202, 74,252,233, 79, 26,180,109, 11,100,100, 0, 31,126, + 88,135,227,199,143,195,100, 50, 65, 44, 22, 35, 58, 58, 90,185,121,243,102,244,232,209, 67, 58,120,240, 96,149,135, 29,128,228, +204,153, 51,104,215,174,157,114,220,184,113,212,183,223,126, 11, 0, 74,133, 66,129,151, 94,122, 9, 73, 73, 73,158, 30,171, 8, + 0, 10,183, 30,163,129, 92,198,242,223,162,161,249, 30,132,135,173,183, 15, 0, 83,167,174,195,246,237,150,255,153,153,197, 96, + 35, 2,124, 52,224,209, 18,191,109,123,139,149, 2,110,237, 32,107, 35,172, 34,224, 73, 38,127, 0,194,157,219,215,254, 69, 58, +106, 96,194,144, 1, 29, 64, 81,150,170,110, 12, 67, 16, 26,236,143,160, 56, 17,186,117, 14, 67, 76,251,224,174, 59,183,175,253, +203,164,180, 87,229, 0,238,184, 50,120,245,210,102,229,200, 65, 53,120,253, 85, 64, 32,176, 8, 40,163, 9, 8, 10, 4,122,197, + 3, 67, 19,129,205,202, 26, 28, 58,185, 89,249,116,223,209, 94, 61,248,190, 74, 1, 56,251, 62, 43, 2, 30,245,197,136,140,140, +196,230,205, 1,232,220, 89, 11,149, 10,168,170, 18, 34, 62, 62, 30,241,241,241,168,171,171, 67, 73, 73, 9, 84, 42, 21,106,106, +106,148, 79, 61,245, 20,231,212,192, 79, 63,253, 36,209,106,181, 74,145, 72,132,170,170,198,145, 44,173, 86,139, 47,190,248, 2, + 37, 37, 37,100,230,204,153,158,156, 79, 6, 0, 54, 20,228, 0,144,209,150,255,222,227,200,145, 35,214,243,205, 46,162,228,168, +141,203,125, 97,123,109,185,182,185,117, 10, 8,145,224,226, 69, 36,213,213, 41,163, 74, 75,113, 43, 58, 26,199, 66, 67,165,126, + 79, 63, 13, 66, 81, 42,111,143,217,211, 5,163,184,216,224,218,214,220,246,108, 67,255,153,153,219,145,150, 22,103,253,207, 34, + 45, 45,142, 23, 1,143, 0,246,100,207,174, 15, 96,219,206,207, 2,176,127,232,159,240,227, 59,123,106,223,135,241,241,241, 9, + 73, 3, 59, 52,106,167,105, 10, 34,145, 0, 1, 98, 33,252,252,104,196,117,143, 64, 92, 92,124,244,217, 83,251, 54,187, 18,138, +199, 14,126, 74, 4,168,193, 27,115, 0,157, 30,184,122, 19,168, 82, 3,213, 53,192,119, 27,129,249,239, 2,139, 63, 2,134, 13, + 4,104, 82,131, 99, 7, 63,229,189, 69, 27,244,237,219, 87,186, 97, 67, 47, 68, 71, 3, 47,189, 36, 68,251,246, 67, 48,122,244, +104,105, 90, 90, 26,149,154,154, 42,157, 48, 97, 2,218,181,107,135, 99,199,142,225,199, 31,127, 84,238,216,177, 67,162,215,235, + 37,174,108,126,251,237,183, 18,189, 94,175,244,243,243,115,249,219, 74,165, 18,107,215,174,149,112, 33,217,189,123,247, 18, 0, +134,156,156, 28,209, 3, 17,240,128, 76,247,238,221, 75, 60, 21, 80,135, 15, 31,182,254,185,106,243, 70,212,113,109,115, 69,254, +177, 23, 46, 40, 95, 56,113, 66,217,249,210, 21,136,106,106,208,225,210, 5, 72, 14, 29, 84,182, 61,121, 82, 9, 66, 36,222, 92, +239,195,135, 15,227,200,145, 35,228,204,153, 51, 18,111,239, 25,214, 6,151, 54,174,246,236,137,158, 75,155, 59,176,164,207,254, + 55,164,197,243, 15,252, 35, 34,126, 46,101,128, 31,219, 8, 64,115,122,106,164, 25,247,207, 87, 33,102,214,190,179,223,113,245, + 27,103,207,157,156, 56,125,138,212, 74,250,142, 32,246, 23,162, 90,173, 71, 66, 92, 36,228,235,149,113,189,251,141, 12,115,102, +175,164,248, 18,102,164, 88, 94,111,219, 11,252,251,191,192,248,145,192, 36, 9,112,225, 10,112,252, 44, 65,128,152,194,128,222, +192,132,209,192, 79,219, 47, 97,224,179,190,243,220,189, 57,119,205, 52,166,194, 43,132,132,132,168,234,234, 44,227, 45, 95,122, +233, 37, 12, 31, 62,156,178,253,172,178,178, 82,218,171,151, 80,153,158, 14, 80,212, 81,148,151,107,148,183,110,197,185, 10,255, + 73, 40,138, 82,114, 93, 28,166,188,188, 92,233, 78,247,206,154, 53, 11,121,121,121,200,203,203, 35,179,102,205,106,116, 45,246, +238,221, 75,242,242,242,172,219,181,150,254,128,107,155, 51,232,207,156, 65,247,162, 34, 24,104, 26,126, 20, 96, 98, 8, 24,163, + 25,140,201,132,182,251,246,226, 10, 33, 8, 29, 48,192,107, 2, 15, 12, 12, 84, 30, 61,122, 84, 58,123,246,108,149,183, 54, 0, + 52,242,200, 29,181,121, 19, 93,104, 42,249, 59, 35,250,237,118,145, 0, 30, 45, 15,135, 2,192,217,224, 55,111, 8,199, 29, 33, +122,106,239, 81,231,104,189, 25, 49,238,106, 80,161, 55,246, 28,125,199,203,129,139,194,246, 29,227,158,238,216, 62, 24,132, 0, +251, 14,222,132, 70,107, 89,117,117, 96,255,246,104, 27, 21,128,155,165,181,204,149,171, 85,180, 80, 72,163, 71,108, 4, 58,118, +140, 15,135,101,137, 86,135, 40,190,166,195,240, 65,128,222, 8,108,221, 3, 40, 15, 18,116,108, 71, 33,182, 11, 48,118, 4,208, + 51,142,130, 80, 96, 89, 90,124,104, 34,240,247, 28, 29,167,243,109, 27,146,231,242,154,139,226,181,205,245,219,158,119, 95,206, + 48,240, 6, 13,203,185,162, 95,191,126, 82,251,207, 4, 2,129,242,233,167,203,177,120,177, 69,158, 46, 91,118, 9,215,174,245, +118,106, 75,167,211,185,245,252,109,113,237,218, 53,183,219,140, 26, 53,138, 26, 53,106,148,149,236,243,242,242,136,189, 64, 24, + 53,106, 84,139,156,187,230,240,254, 1,160,199,253, 10,165,193,104, 4, 77,211, 32, 2, 1, 24,134,129,145, 97,192,152,205, 48, +155, 25,116,186,125, 91, 89, 51, 96,128,215,199,172,209,104, 0, 64,121,228,200, 17, 80, 20,229,241,248,142,230, 16, 1,190,242, +252,183,103,110,199,132,220, 9,152,186, 14,200,220,110,121,189, 61,115,187, 85, 28,136, 54, 93,225,153,247, 17,194,118, 76, 0, +167, 49, 0,206,102, 1,120, 59, 59,192,153,199,229,141, 39,230, 74, 52,120, 43, 80, 92, 29,183,253,119,185,122, 17,206, 6, 21, +122, 99,207,213,119,216,223,161, 0, 48,107,221,142, 93, 96, 44,163,253,253, 1, 0, 55,203,106,160,213,154, 0, 0,241,177, 17, +104, 27, 21,128,147,103,203,233,139,151, 43, 33, 22, 11, 16,215, 61, 28, 85,106, 3, 0, 56, 53,124,243, 54, 65, 92, 87,203,239, + 63, 55, 10, 72,124,154,130,191, 8, 48,153, 44,145,128,240, 16,160,228, 6, 48, 97, 20,208,181,147,101,251,150,132, 45,233,123, +147, 23,110,237, 40, 47, 47,111,182, 40, 74, 3,201, 91, 61,254,150, 38,127, 91,100,103,103,147,172,172, 44,202,219,207,237,225, + 87,124, 5,122,163, 1,148, 64, 8, 51, 33,160, 0,152,204, 12,140, 38, 6,196,108, 6,117,249, 34,128, 73, 77,222,239, 51,103, +206,160, 77,155, 54, 74,181, 90, 45, 13, 11, 11,243, 90, 4,184,107,123, 84,228,191,100,201, 18,106,233,210,165,100,234,186,198, +130, 0, 0, 38,228, 78,128,104,211, 21,108,218, 84,108,157, 9,192, 14, 24,140,140,140,228,153,250, 17,147,191, 83, 1,208,218, +225,138, 16,189, 33,216,166, 76,113,116,105,183,153,103, 19, 80,211,171, 60,253, 13, 42, 44,204, 15, 85,213, 58,180,137, 12, 68, + 70,122, 79,152,204, 12,252,253, 5, 16,208, 52, 8, 33, 72, 29, 31,135,148,113,113,160, 40,160,162, 74,139,176, 48, 63, 0,168, +116,102,176,115, 7, 10,197,215, 9,122,198, 1, 99,158,181,244, 58, 23,174, 0,253,122, 2, 17,161,192, 68, 9,192, 48,128, 80, + 0, 92,186,106,217,158,235,181,245,228,181,163, 66, 34,158, 70,122, 90, 66, 4, 48, 12, 35,137,137,137, 65,113,113, 49,246,238, +221,171, 28, 57,114,164, 52, 56, 56, 24, 52, 77,171, 0,192,108, 54, 75,207,157,139, 86,190,247, 94, 41, 40,138, 66,121,121, 2, + 18, 18,186,225,210,165, 75,206,236, 57,108, 95,187,118,237,195, 81, 36, 66, 48, 99,198, 12,143,142,217, 86, 4,180, 38,242,247, +133, 72,176, 69,101,167, 24,136, 46, 92, 4,241, 3, 68, 12,177, 12,108, 53,155, 96, 32,102,104, 76, 38,104,227,123,250,100,223, +251,244,233, 3,138,162,188, 34,127, 0, 72, 74, 74,194,144, 33, 67,168,195,135, 15, 19, 87,109,238,208, 16, 49,104, 68,248,142, +218, 60, 65,230,246, 7,196, 15,224, 33,207,159, 29, 48,184,105, 83, 49,207,212, 45, 64,254,143,173, 0,104,110, 65,225, 43, 66, + 32, 4,160,103, 84, 53,155, 8, 96,103, 46,208,211,171,184,120,255, 0, 32,188, 83, 90,124,255,102,105,167, 54,109, 34, 3,241, +241,103, 71, 48,106, 88,103, 12,236,215, 14,148, 31,101,157, 17,208,176,116, 60,110,150,214,226, 78,105,241, 85, 0, 78,221,202, +184,110, 98,252, 92,164, 69,207, 56,160,205, 32, 96,209, 60,224,181,217, 64, 88,136, 37,236,255,222, 63,129,119, 95,179,108,251, +115,145,101,123,111, 9,218, 87,158,122,107,170, 5,112,238,220, 57,136,197,150,115,178,101,203, 22,220,184,113, 67,249,212, 83, + 79, 73,199,140, 25,131,218,218, 90, 73,100,100,164,114,255,126, 19, 84, 42, 96,200,144,193,232,210,165,139,180, 83,167, 78, 0, +160,116,100, 47, 40, 40, 8, 6,131,129,211,111,155, 76,166,199,254,217,181, 37,127, 46, 66,128,171, 8, 40,110, 27, 45,245, 63, +117, 74,201, 16,130, 32, 90, 8,129,128,130,137,152,161, 49, 26, 81,107, 48,160,172, 99, 71,105,155, 38,236,119, 96, 96, 32, 40, +138,146, 14, 25, 50, 68,229,173, 13,150,232,221,181, 61,106, 17,176,100,201, 18, 42,179,193,179,183, 39,127, 91,239,159, 71,203, +146, 63, 47, 0, 30,133,135,215,204, 83, 10,173, 34,128,155,208, 48,245,238,221,191,236,202,213,170, 54,253,123, 71, 99,209,107, + 67,177,230,251,211, 8, 16, 11,145,216, 39, 26, 20, 69,217,120,146, 4, 87,174, 86,161,119,239,254,103, 0,212, 58, 51, 24, 27, +151,128, 45,187, 79, 98,246, 84,128,148, 0, 67,167, 0,177,157,129,188, 13, 54, 27,189, 6,152,205,192,150,221,150,237, 91, 10, +174, 34, 69, 45, 53, 13,176,178,178, 82,217,171,215, 85,124,245, 21, 0,152,241,254,251,167,112,252,184, 70,169,209,104, 80, 91, + 91,139,146,146, 18,220,189,123, 23, 3, 7, 14,196,140, 25, 51,220, 78, 3, 36,132, 72, 25,134, 81,210,180,251, 9, 62,172,240, +240, 20,108, 10, 32, 47, 47, 15,163, 70,141,106,209,231, 43, 43, 43,139, 98,137,223, 93, 10,192,221, 54,182,136, 24, 48, 0, 21, + 6, 3,204, 74, 21, 12, 34, 63, 4, 19, 33,116, 12, 3,181,193,128,218, 49, 99,209,102,208, 32, 47,163,130, 20,134, 12, 25,226, +117,222,223,214,134, 45,209, 59,106,107,138, 8, 56,114,228,136,203, 54, 46,112, 68,254,172,231, 15,128, 31, 16,216,194,228,207, + 11,128,199, 28,214,252, 63,247, 52,128,185,119,191,145, 99, 54,111,252,114,255, 47, 69, 33, 61,159, 25,212, 17, 19,147, 99,177, +109, 87, 9,182,236,176, 60,156,127, 89, 48, 12, 12, 67,240, 75, 81, 25,138,139,175, 92, 79, 77,159,243,191, 0,140,206, 12, 14, +124,246, 15,212,150,117,111,147,149, 95, 90,166, 2,174,254,155,101,234, 95,242,112,203, 84,192,149,127,181,144,255,202, 47, 1, + 51, 66,189,174, 8,216, 84,207,220, 93, 4,161,165,102, 1,212,215,215, 99,192, 0, 29,134, 12,177,188, 31, 60,152, 96,219,182, + 18, 92,186,116,137, 45, 4, 4,137, 68,130, 30, 61,122,112,170, 1, 48,126,252,120, 85, 65, 65,129,219, 40,128,201,100, 66,120, +120,184,212,211,253,109,152, 14,104,157, 25,176,119,239, 94,226,109, 26, 32, 41, 41,137, 83,155, 39, 34,192,221,118,156,141,210, +180,202,240,204, 51,210,243,126,126,232,124,251,182, 50,248,198, 13,232,186,119,199,181,232,104,105,228,192,129, 64, 67,138,198, + 11,130,245, 5, 73, 63,100,195, 81, 27,215,115,105,191, 29, 75,248,238,218,188,129, 61,233,179, 17,129,166,166,240,120, 60, 12, + 46, 3,163,121, 1,208,140,158,121, 43,253,141,138, 9,207,205, 88,181,125,219,143,111,223,186, 93, 27, 23,223, 61, 2, 41,227, +227, 16, 17, 46, 70, 85,181, 14,199, 79,223,197,149,171, 85, 40, 46,190,114, 96,194,115, 51,126, 2,112,211,157,193,238, 9,169, +210,125, 69,155,149, 7,138,106,144, 50, 6,248,252, 3, 75, 37,192,226,235,192, 23,107, 45,158,191, 25,161,232,158,144, 42,245, +246, 88,155,146, 2,224, 74,254, 45, 49, 6,224,246,237,219,210,136,136, 54,202,163, 71,239, 1, 0, 46, 93, 10,197,144, 33, 79, + 35, 42, 42, 10, 98,177, 24,183,111,223,150,166,166,166,122, 84, 10,184, 91,183,110,210,139, 23, 47, 42,109, 35, 58,246,228, 31, + 31, 31,143,164,164, 36,143, 72,140,157, 5, 96,147,251,103, 7, 4,122, 37, 2, 28, 17,161,183,228,232,142,220, 61, 34,127, 27, + 17, 16, 53,120, 48, 52, 0,165,105,104,106,234, 80,181,166,146,191, 39,231,141,235,111,249,218, 30, 87,242, 55,164,197, 3,124, +254,255,145, 68, 2,156, 9, 3,143,166, 1,122, 59, 88,206,211,105,128,222,218,243,214,166,175,247,207,213,121,242,213,254, 53, +101,224,162,159, 40, 40, 39, 53,125,206, 15,103, 79,237,251,116,253,134, 61,177,237, 99,226,134,218,172, 5,112,168,119,239,254, +135, 83,211,231, 44, 6, 80,207,197,222,211,125, 71,171,158,238, 59,154, 58,118,240, 83,242,227,150, 75, 88,246,239,214,183, 22, + 64,107, 36,127, 0,152, 57,115, 38, 78,158, 60,137, 87, 95, 61,218, 16, 1, 24,140,233,211,251, 75, 3, 3, 3, 85,222,218, 76, + 76, 76, 84, 37, 38, 38, 82, 27, 55,110,148,212,214,214, 42, 5, 2, 1,104,154,134,201,100,130, 72, 36, 66,112,112,176,212, 7, +228,239, 19, 17,192,227,201,196,146, 37, 75,168,165,153, 75, 73,199,249, 29,165,232,230,120,155,178,204,237, 74,126, 60, 64,203, + 66,200,181,163,244,117,199,219, 28,246,188,249,173,199,249,120,155, 8,117,239,126, 35, 95,238,221,111, 36, 91, 49, 38, 24, 64, + 27, 0,183, 1,104,209, 80,246,213, 19, 12,124,246, 15,148, 55, 69,126,154,251, 60,180,166,186, 18,246, 8, 12, 12, 84, 61,251, +236,179,212,179,207,250,254,196,165,167,167,171,224,163,226,150,108,222,223,158,228, 71,141, 26, 69,229,229,229,145,214, 48, 30, +128, 71,235, 19, 1,174, 55, 0, 79,254,205, 0,174, 85, 0, 1,128, 74, 76, 76,228,115, 47, 60,120,240,224,193,131,199,175, 12, +252, 90, 0, 60,120,240,224,193,131, 7, 47, 0,120,240,224,193,131, 7, 15, 30,188, 0,224,193,131, 7, 15, 30, 60,120,240, 2, +128, 7, 15, 30, 60,120,240,224,241,100,160,209, 44,128,121,243,230,121, 61, 42,211, 81, 33, 7,222, 94,243,216,227,178,136, 77, + 75,218, 83, 40, 20, 18, 0, 74,185, 92,238, 19,123,187,119,239,150, 48, 12,227, 51,123,252,253,215, 98,246,102, 0, 88,219,204, +251,231, 7, 64, 12, 75,209, 26, 29, 44,179, 89, 8,236,138,216,240,215,227,177,176,135, 38,216,195,175,221,158,199, 2,192, 29, + 57, 56,131, 39, 83,169,124,109,239, 81, 34, 51, 67, 77, 32, 18, 33, 55, 47,128,211,254, 41, 20, 10,137, 92, 46, 87,250,234,120, +109,237,173, 88,177, 66,186, 96,193, 2,165, 55,203, 11, 59,178,119,230,223,161,232,243,199, 26, 52,197, 30,139,201, 67, 10,149, + 39, 47,154, 1, 0,185,185,185, 36, 51, 51,179, 73,215, 51,161,221,143,208,154, 34, 17, 16, 16, 0,185, 92, 78, 50, 50, 50, 90, +236,254,240,166,142,131,171,243,215,218,237,185,251, 29, 15,191,123,176,185,174, 11, 69, 81,147,104,154,126,154,166,105, 9, 69, + 81, 9, 0, 2, 13, 6,195,118,129, 64, 16,206, 48, 76, 57, 33,228,175, 0, 42,224,131,106,118, 60,120, 60,145, 17, 0, 71, 15, + 57, 33,196,213, 67,231,113,135,225, 43,123,158,122,176,190,196,206,157, 59,221,118, 34, 44,185,102,101,101, 33, 58, 58,218, 97, + 5,188, 5, 11, 22, 40,185,254, 38,107,143, 37,254, 67,135, 14, 89,133, 64, 83,236, 49,231,254, 31,232,167,223,199, 55,187, 45, +165, 99,153,115,255,207,186, 13,253,244,251, 30,157,151,208,154, 55, 9, 67,128, 31,182, 89,108, 77, 28,237,135,222,241,103,145, +155,155, 75, 0,192, 83, 33,160, 54,253, 32,169,190, 86, 1, 45, 53, 90, 89,175, 15,194,196, 9,213,136,105, 79,225,232,209, 3, +164,166, 70,135, 49, 99,198,180,154, 53,232, 91,147,128,118,245,140,249,234,153,243, 18, 6,219,251, 47, 63, 63, 95, 57,101,202, + 20,233,248,241,227, 85, 77, 49, 42, 16, 8, 38, 10,133,194, 81, 66,161,112,166, 64, 32,136,160,105, 58, 56, 59, 59,155,126,251, +237,183,231,152,205,102,152, 44,152,105, 54,155,211, 0,252,220, 32, 2, 12, 13,253, 95,179,167, 65,183,108,217, 66,184,158,251, + 73,147, 38,121,116, 65, 10, 11, 11, 73, 83,190,207,227,201, 7, 91, 17,208,163,229,128,185,144,255,160, 65,131, 80, 84, 84,228, + 81,135,229,170,195,225, 98,207,145,253,172,172, 44,148,148,148, 64, 46,151,251,116, 89,215,204,180, 92,130,128, 4,228,174,149, + 80, 0,144, 43, 15,163, 60, 33,255, 21, 43, 86, 72,203,203,203,149,206,200, 63, 43, 43, 11,217,217,217, 30,145, 63, 0,100,100, +100, 96,232,208,161,210,161, 67,135, 54,201, 30, 75,246,236,255, 15,255, 15,141,200,127,225, 84, 49,150,175,211,113, 58, 87, 97, +218, 5,164, 79,130, 0,245, 90,130, 55, 95, 17,227,208, 89, 19,180,245, 4, 26, 3, 32, 77, 60,139,179,151,204, 30, 69, 3, 74, +110,174, 36,213,119,130, 16, 18, 42, 66,251, 14,193,104,219, 46, 30,215,139, 13,232,246,180, 17,126,226,114, 40,214,223,199,250, +245,235,201, 11, 47,188,192,119,120,143, 15,172,203, 15,202,229,114,101, 90, 90, 26,214,173, 91,167, 28, 63,126,252, 67,215,112, +224,192,129,228,189,247,222, 67, 90, 90,154,203,235, 43, 20, 10,199,136, 68,162, 62, 34,145,104,190, 72, 36, 10,188,121,243, 38, +122,244,232, 1,129, 64,128,144,144, 16, 92,185,114, 5,193,193,193,194, 35, 71,142,132, 31, 60,120,112,223, 31,255,248,199,110, + 0,174, 3, 16,193, 73,177,171,204,204,204,135,156, 21,219,126,139,109,167, 40, 10,185,185,185,110,239,191,141, 27, 55, 58,181, + 97,219, 78, 8,193,164, 73,147, 60, 58,161, 27, 54,108,104,210,247,155,153,120, 36,137,137,137, 42,254,182,111, 57,210,247, 42, + 2,192,149,252,185, 34, 43, 43,203,237, 54, 92,136,203, 25,249,127,248,225,135, 88,180,104, 81,163,118,111, 69, 64,230,160, 92, +130,168, 4,228,238,144, 80,182, 30,255,184,113,227, 40, 0, 96,255, 95,185,114,133,112, 33,107, 87,228,223, 16, 25,112,235,181, +179, 97,122, 91, 15,223, 62,181,224,141, 61, 87, 30,254,194,169,220, 87,138,107,163,125,147,244,232, 42, 64,128, 63,133,174, 29, + 5,184, 95,197,192,104, 18,160,162,154, 64, 93, 71,112,229, 22, 3,208, 64,155,192, 83, 80, 40, 20,146,228,228,100,151,157,194, +245, 27, 31, 75,122,197,199,225,224,157,187,232,222,165, 45,250,244,139,133,192, 63, 18, 93,187, 87,161, 74,171, 67,249, 29, 51, +110,221,213, 33, 80, 88, 2,133, 34,196,173,189,230,134, 51,175,220,219,123,208, 87,246,156,137,109, 79, 34, 4, 62, 6,195, 62, + 35, 20, 69, 65, 44, 22, 75, 1, 40,237,239,137, 65,131, 6,113, 34,127, 0,240,243,243, 11, 23,139,197,179,239,223,191, 31,152, +144,144,128, 1, 3, 6, 64, 40, 20,226,159,255,252, 39,204,102, 51,250,246,237,139,159,126,250, 9, 71,142, 28,193,169, 83,167, + 32, 16, 8, 62, 53,155,205,207,187,178,249,252,243,207, 91,207,159,187,126,144, 11,225,230,228,228, 72,219,183,111,175, 36,132, +184,116,128,238,220,185,227,241, 90, 25,172,109,111,191,207, 18,245,249,243,231, 93,246, 27,189,122,245,146,122, 74,230,231,207, +159, 87,170,213,106,132,133,133, 73,121, 33,208, 58, 33,116,214,249,184,243,212, 91, 11, 74, 74, 74,176,104,209, 34,175, 4,132, + 43, 88, 60,253, 76,106,231,206,157, 68,158,155, 4,136,180,132, 75,238,223, 17, 89,219,147,178,171,180,128, 51,216, 10,138, 67, +135, 14, 41,135, 14, 29,218, 40,244,239,169,189,239,222, 14,118,218,185,205,250,168,158,179, 29,134, 97, 36,254,129, 20,104, 26, + 8, 12, 0,170,107, 24,232, 9, 65, 80, 0, 5, 29, 3,104,245, 4,157,218,210, 96, 76,192,229,155,102,148,148,148, 40,225,162, + 60,237,185,179,249,146, 62,125,122, 42, 69, 34,130,223,207,126, 6,102, 51,193,157,114, 3,110,148, 86, 3,126, 55, 17, 16,161, +199,237,242,107,160, 69,106,156, 59, 87,141,176, 8,215,246, 30, 21,236,201, 89, 38,147,145,166,172, 48,104,191,208, 19, 53,189, +202,171,252,126,101,101,114,163,247,145,145, 10,183,196,230,137, 40,177,111,119, 35, 82,204,236, 51,146,154,154,138,228,228,100, +149, 92, 46,135, 86,171,181, 94, 67,214,243, 79, 77, 77,229,116, 77,253,253,253,135,213,215,215,247,236,213,171, 23,164, 82, 41, + 22, 44, 88,128,223,254,246,183, 0, 0,163,209,136, 53,107,214,160,168,168, 8,199,142, 29,195,143, 63,254, 8,173, 86, 27,207, + 48,204, 68, 87, 54, 83, 82, 82,124,122, 63,109,217,178,133, 83,106,142,162, 40,165,167, 33,124, 91,219,222,124, 31,176,172, 29, +161, 86,171, 81, 86, 86,230,240,243,142, 29, 59,194, 91, 2, 47, 43, 43, 67, 89, 89, 25, 47, 4, 30, 49,108,195,253,174,162, 1, + 66, 79, 61,118, 95, 19,109, 83, 33,151,203,155,244,253,204, 92, 25, 65, 7, 32, 55,205,210,113,229, 22,101, 54, 10,243, 91, 60, +126, 53,177,143, 4,112, 37,235,242,242,242, 70,228,236, 13, 89,115, 5, 43, 58,100, 50, 25,113, 87, 15,154, 11, 1,176,225,127, +103,246, 8, 33,228,254,185, 55,209,161, 33,244,207, 66,107, 38,208, 25, 0, 99, 67,155,209, 68, 64,104,203,235,211,167,138,216, + 89, 2, 14, 17, 18,162, 86,214,107,105,180,137, 12, 71,117,165, 6,213,234,106, 28, 58,122, 7,165,119, 9, 68, 65, 26,196,196, +215, 65,171,185,143, 30,253,140,232,214, 75,143, 31, 63, 47,194,182,109,219, 36,252, 35,255,120,128,245,254, 41,138,194,166, 77, +155, 72,106,106, 42, 54,111,222,140,128,128, 0, 73, 86, 86,150,210, 19,242, 7,224, 95, 93, 93,253, 63, 70,163,145, 14, 12, 12, +196,168, 81,163,240,209, 71, 31,193,207,207, 15, 50,153, 12, 95,127,253, 53,138,138,138,112,232,208, 33,236,218,181, 11,167, 79, +159, 70,155, 54,109,218,152, 76,166,174,112,179,214, 69,102,102, 38,113,151, 2,248,252,243,207, 57,237,103,115,166, 0, 54,110, +220,232,147, 20, 64, 88, 88,152,180,172,172, 76,233,236,179,166, 94,119, 94, 8, 60, 38, 17,128,199, 9, 57, 57, 57,148, 47, 70, +173,179,228, 46, 95,116, 21, 16,136,144, 57,190, 27, 16,222, 13,185, 13, 19,150,184,230,254,125, 13,219, 99, 99, 7,253,217,122, +254,246, 96,199, 6, 56, 27, 12,232,141, 7,153,247, 86,144,211,136, 64, 72,205, 2, 92, 51, 16,220,185,207, 0,160, 17, 28,104, + 9,113, 26, 77, 4, 58, 61,160, 51, 0, 58, 61, 96, 48, 2, 58, 45, 96,208, 63,136,146, 56, 18, 20,193,166, 55, 73,233,141, 46, +232,220, 61, 24,196, 79,136,251, 90, 45,148,123,110,226,220,149, 82, 84, 86,214,161,247, 32, 51,234,117, 38,232,244,102,104, 53, + 12,238,220, 0,180,245,192,250,245,235,149,158, 44,128,193,195, 55, 17, 14, 47,158, 53,194,122,255, 98,177, 88,154,156,156,172, + 98,167,140,106,181, 90,101, 81, 81, 17,149,154,154,202,213,150, 9, 64, 60, 0, 38, 49, 49,145, 17,139,197,244,215, 95,127,141, + 57,115,230,224,131, 15, 62, 0, 33, 4,191,252,242, 11,246,236,217,131, 83,167, 78, 65,173, 86,163, 71,143, 30,168,169,169, 9, +164,105, 58,218,157,241,201,147, 39, 59, 21,201,108, 4, 37, 37, 37,133,235,185,107,213, 41, 0, 87, 81,128,166,120,255,188, 16, +224, 5, 64,179,144, 98, 70, 70,134,148,205, 25,218,139, 0,219, 14,137,205,199,123,155,139,101, 73,127,220,184,113,148, 37, 13, + 32, 66,110,222,163, 61, 94,118,212,127,114,114, 50,165, 80, 40,136,187,104,136,187,105,135,174, 8,221, 17, 92,109,251, 63,127, +174, 71,199,118, 52, 94, 74, 19, 65,167, 7,194, 66, 40,208, 84,131,215, 15, 2,157, 6,168, 55, 16,212,107, 9,234,117, 4, 12, + 1,104, 23, 99,174,255,231,181,122,244,237, 95,130,246, 61, 43,177,115,107, 57, 42, 43,117, 72,124,182, 6,253, 34,235, 0, 63, + 61,116, 26, 6,229,165, 4,245,245, 20, 76, 38, 10,145,109, 40,128, 98,248,167,248,241,129,245,254,101,159, 95, 54, 13,192, 98, +243,230,205, 15,141, 63,114, 48, 22,128,189,232,241, 0, 78, 44, 92,184,112,152, 80, 40, 12,254,230,155,111,240,213, 87, 95,225, +213, 87, 95,197,135, 31,126, 8,138,162,112,237,218, 53,104,181, 90,100,101,101,193,100, 50, 97,238,220,185, 12, 69, 81,110, 31, + 0, 95,142,166,111,237, 41, 0, 87, 81, 0, 95,120,255, 60,120, 1,224, 83,216,231,145,157, 17,124,195,118,156,145, 91,100, 25, +161,110, 33,254,203,144,255,243, 42, 44,179, 0, 26,139, 2, 46,105, 0, 95,129,245,230, 21, 10, 5,177,245,254,217,136,128,237, +251,140,140, 12,176,197,114, 28, 21,214,112, 71,232,246, 96,103, 1, 56,179,103, 50, 3,245, 26, 2,189,193, 50,216, 79,111, 32, + 16,250, 63,248, 76,167, 1,180, 70,130,138, 74,130,123, 85, 4,199,206,153,192, 48, 64, 70, 70,134,244,242,229,203, 15, 93, 27, +147, 9, 40,187,105,192,205,226, 42,236, 63, 88, 5, 66, 40,156,187,192, 32,245, 37, 19, 68, 66,130,123,119,129,253, 59,128,154, + 26, 2,194, 0, 35,198, 80, 16,139,129,137, 19,159,199,245,235,215, 57, 29, 83,193, 26, 25,153, 60,219,247, 83, 69,155,146,239, +119, 72, 6,211,171,124, 98, 39, 50, 82,209,170, 35, 9,108,219,192,129, 3,201,177, 99,199,176,105,211,166,135,190,147,150,150, +230,200, 20, 13,224, 12,128, 19, 43, 86,172,232, 31, 30, 30, 30, 12, 88,194,224, 95,126,249, 37,230,204,153,131,175,190,250,202, +234,197,175, 88,177, 2,213,213,213,168,169,169,169,211,104, 52, 37, 13, 17, 4,145,171,125,253,253,239,127,223,104, 60, 20,235, +193, 19, 66, 56,135,255,129,199, 35, 5,224, 40, 10,224,107,239,159,181,201,123,254,188, 0,104, 18,138,138,138,220,142, 38, 87, + 40, 20, 18,206, 83, 10,253,131, 32,239,182, 23, 48, 21, 17,116, 15, 66,230,210,238,200, 85,165, 82, 64, 46,121, 32, 8,198,121, +157, 6,176,159, 10,232,108,106,160,179,206, 82, 38,147, 89,201,223,126, 0, 96,131,231,111,109,115, 21, 1,176,181,231,171,206, +188,176,176, 80, 82,122,123,171,146,105,203,128, 22, 2,126,180,165, 51, 50, 50, 4, 38, 19, 80, 91, 75, 96, 48, 2, 38,163, 69, + 20, 60, 63,217, 18,189,185,124,249,178, 83,123,250,251,133,202,222,189, 25,236,219, 99, 6, 69, 3,247,238, 80, 16, 7, 0,123, +182, 1, 6, 45, 5,138, 0,253, 6,250,161,236, 6,131,209,163, 83, 48,105,210, 36,167,130,199,158,252,151,255, 17, 88,248,111, +223,138, 0,103,169,168,150,182,231, 46,228,220, 2,112,184, 51,236,168,255,212,212, 84,235, 61,202, 70,239,166, 78,157,234,202, + 3,173, 3,112,245,248,241,227,117, 35, 71,142,108, 11,155, 57,253, 95,126,249,165,149,100,141, 70, 35,204,102, 51, 46, 95,190, +140,182,109,219,222,103, 24,134,147, 90,156, 60,121,178, 51, 79,221, 35,162,125, 28, 82, 0,142,162, 0,190,244,254,121,226,127, + 2, 5, 64, 81, 81,209, 35,175,218,199,122,185, 44,209, 37, 39, 39, 83, 14,200,159,176, 97,197,140,140, 12,175,126,199,118, 22, + 0,219,230,169,231,111, 63, 0,176, 1,214,182, 5, 11, 22, 40, 51, 50, 50, 56, 63,100,182,228,239,104, 76,128,167,246,220, 97, +249, 58, 29,220,217,155, 52,105,146,106,113,214, 70,140, 29,234, 7, 6,128,209,192,192, 95,100, 57, 77,181,245, 4,122, 35,129, +201, 12, 20,157, 49,195,204, 16,184,155,178, 55,105,210, 36,213,255,251,203, 70,140,150, 8,240,194, 44, 1,234,106, 9,106,213, + 64,125, 45,133,238, 61, 8,204, 70, 10, 66, 90,140,234, 74, 6,101,183, 12,120,235, 13,110, 3,198, 10,214,200,200,170,215,128, +132, 46,192, 39,111, 2,243, 63,246,189, 8,240,101,100,192, 87,246,154,107,202,159,151,207, 61,227,136,252,223,125,247,221,135, +194,252,249,249,249,202,180,180, 52, 56, 41, 18,196, 18,189, 1,192,137,167,158,122,170, 88,167,211,197, 8, 4, 2,113, 96, 96, + 32, 0, 96,221,186,117,152, 58,117, 42,180, 90, 45,116, 58, 29,244,122, 61,130,131,131,117,102,179,121, 3, 33,228, 14,151,157, +245,213,108,128,199, 37, 5, 96, 27, 5, 96, 95,243,196,207, 11,128, 71, 70,254, 92,108, 38, 39, 39, 83,114,185,156, 52,120,187, +144,203,229,196,118, 90,162,189,215,239, 72, 32, 60, 4, 1, 5,136,104, 32, 64, 0, 4, 11, 1,125, 45,228, 31,248, 1, 1,135, + 73,230,180,238, 64, 64, 36,114,255,235,185,215,239,106,180, 63, 75,214, 92,231,176,219,147,191,253,152, 0, 79,237,113, 37,127, + 46,246,150,101,175,166,222,124,109, 46, 17,139, 1,134, 1,250, 62, 37,120,112, 61, 78,155, 97, 52, 19,152, 25, 1,166, 76,153, +194, 73,156,188,255,183,213,212, 91,111,205, 37, 38, 19, 96, 48, 18,152, 77, 0, 77, 1,146, 20,160,182,154,194,133,147, 90,104, +117, 52,210,211,166,112, 58,150,130, 53, 50,242,238,111,129,248, 78,150,247,113, 49, 64,115, 68, 2,120,120, 6,103,197,126,100, + 50, 25, 73, 77, 77,229, 50, 27, 64, 16, 30, 30,126, 66,171,213,126, 91, 82, 82,210,173,127,255,254,177, 38,147, 73,232,231,231, +135, 13, 27, 54, 96,220,184,113,208,233,116,208,104, 52,184,124,249,114, 77, 68, 68,196,110,173, 86,251, 13,195, 48,245,224, 88, + 1,144, 45, 10,196,138, 41, 79, 66,255, 44, 30,151, 20,128,109, 20,192, 23,215,215,155,218, 1, 60, 30, 3, 1,208, 18,158,191, +189,247, 97,235, 9, 57, 11,245,251,114, 31, 61,201,253,251,154,252,109,196,142,109, 33, 32, 86, 4, 41, 27, 34, 29, 30,217,115, + 55, 22,192, 83,123, 31,255, 99, 53, 37,147,201, 8, 77, 3,251,139, 44,185,126,118,192,159, 37,239, 63,197, 35,123, 31,125,180, +154,154, 59,175,161, 38, 5,109,177,113,120, 47, 80, 95,199,128, 48, 64,122,122, 10, 38, 76,152,224,246,122, 20,172,145,145,172, +151,129,240, 96,160,236, 62, 16,224, 15, 48, 4, 8, 18, 3, 75,101,192,146, 28, 94, 4,112,133,187,232,131,167,207,155, 35,242, +159, 59,119, 46, 97,103, 2,108,218,180,137, 80, 20,229, 74, 8, 4, 27, 12,134, 58,154,166, 21, 29, 59,118,236, 84, 91, 91,251, +199,163, 71,143,118, 24, 48, 96, 0, 99, 50,153, 52,106,181,250,238,201,147, 39,175,117,239,222,189, 56, 42, 42,170, 68,171,213, +174, 51,153, 76,119, 9, 33,156, 5, 0, 91, 20,200, 38, 42,224, 77,127, 37,109,198,190,208,231,182,125, 69,218, 60,249, 63,166, + 2,192,221, 92,127, 79, 31,116,174,181, 3, 60,177,155,147,147, 67, 57, 91,108,199, 19,242,202,205,204,177,132,249, 47, 1,184, +100,255,169,186,225,239, 42,188, 56, 94,165,175,200,213,246,188,200,100, 50,194,214, 25, 88,176, 96,129, 87, 51, 28,236,237,229, +189, 21,100, 21, 5, 77, 17, 77,246,215,132, 29,240,231,109, 84, 98,245,103,141,237,213,213, 88, 58,224,244,244,116,207,238,191, +111, 31, 45, 17,182,180,189, 86,150,247,111,228,177,219,190,177, 39,127,133, 66, 33, 33,132, 96,243,230,205,182,219,184,178,119, +195, 96, 48,248, 19, 66,106, 25,134,201, 49, 24, 12,191,116,233,210,165, 77,117,117, 53,245,215,191,254,181, 70,173, 86, 87,196, +196,196,212,214,213,213,213, 27, 12,134, 26,163,209,168, 55,155,205, 90, 79,118,216, 71,105,128,230, 36, 66,158,100,121,248, 78, + 0,248,218,179,111,206, 72, 65,114,114,178,138, 83,136,223, 13,124, 57,170,255, 81, 68, 70, 60, 89,244,199, 23,209, 0, 79,175, +137,237,180,174,166,166, 36,236,237,121, 74,254,190,246,238, 91,251,243,209,156,247,159, 15,108, 83, 13, 2,133,208, 52, 13,246, +143, 21, 44, 41, 41, 41,152, 56,113, 34, 24,134, 1,195, 48, 32,132,184,251, 61,202,100, 50, 5, 18, 66,204, 12,195,232,141, 70, +227, 94,129, 64, 64,209, 52,237, 15,192,159, 97, 24,152,205,102,129,201,100, 18,153, 76,166, 14,102,179,249,188,205,119,155,125, + 17, 32, 30, 60, 90, 3, 92,213, 72,161, 18, 19, 19,249,229, 49,121,240,224,241,184, 66, 99, 67,232,140,141, 99, 35,180,105,191, + 13, 32, 12,128,152, 39,126, 30, 60, 92, 68, 0,120,240,224,193,227, 49,130,184, 65, 4, 48, 54,196, 79,227,193,202,131, 66, 0, + 29, 26, 94,243, 85,163,120,240,224, 5, 0, 15, 30, 60,158, 16,208, 0,130,109,222,179,196, 47,178, 33,125,166, 97, 59,222,251, +231,193,131, 23, 0, 60,120,240,248,149,244,105, 60,233,243,224,225, 66, 61,243,224,193,131, 7, 15, 30, 60,126,205,106,121,222, +188,121,182, 11,233, 16,219, 17,246, 50,153,140,216, 45,180,115, 35, 57, 57,185, 11,251,222, 81, 41, 86, 91,123,158,226, 73,180, +103, 63,109,209,246,124,242,231,143,191, 30,173,221,222,210,165, 75,173,219, 44, 89,178,132,242,194, 30,224,164, 28, 48,127, 63, +187,183,249, 43,188,255,154,114,238,240,107,183,231,177, 0,240, 16,109,185,108,196,174,222,231, 43,197, 98, 63,103,218,209,106, +128,142,182,105, 9,117,197, 18, 76, 70, 70,134,148, 37, 26,182, 2, 88,107,153,171,189,121,243,102,201,166, 77,155,172, 36,152, +146,146, 34, 77, 79, 79, 87, 61,137,106,215,209,245, 56,127,222, 50, 51,172, 87,175, 94, 45,186,111, 50,153,140, 60, 63, 89,134, + 13, 5, 57, 14,239,217,194,173,199,200,134,130, 28,151,247,114,225,214, 99, 46,103,244, 76,154, 56,208,235,155,110,233,210,165, + 36, 45, 45,174,209,123,119, 34,192, 29,106,235,106, 37, 27,119,108, 68,108,239, 88, 37, 40,224,252,241,115,210,103, 19,135,161, +215, 83,189, 60,186,255, 14, 28, 56,240,208,113, 15, 27, 54,140, 47,238,196,131, 71, 51, 10, 0, 17,215, 13,135, 14, 29,234,177, +113, 71,139,197,176,112, 68,162,246, 11,109,112, 37, 90,111,138,176,112, 17, 20,172,221,172,172, 44,100,103,103, 43,157,213,100, +103,183,115, 53, 87,211,126, 31, 99,186,119, 6, 0,220,213,233, 96,210,234, 45,141,213, 53, 0, 44,107, 31,120, 82, 27,193,150, +252, 1, 75,109,113, 79,230,218,203,100, 50, 66, 83,150,234,122,236,127,192,245,235,207, 86, 63,122, 65,102,127, 61, 88,226,247, +246,122,248, 82, 84,178,228, 63,105,226, 64, 29, 32, 19,111, 40,200,241,250, 55, 88, 1,225, 88, 0,228, 52,105, 63, 13,134, 44, +108,223,158,137, 9, 19,114,145,150,150,109,141, 8,120, 35, 4,246,159,221, 79,186, 14,232,140,149, 57, 31, 33, 34, 48, 2,140, +201, 12, 29,209, 43,183,253,178, 99,194,238, 61,187,200,176,216,225, 82,177, 88,236, 86, 8, 28, 56,112,128, 56,242,156, 62,251, +236, 51,194,139, 0, 30,191,102,156, 56,113,162,209,123, 71,125, 90, 83, 4,128, 71,227, 7, 28,173, 98,231, 11, 16, 64,210,100, + 27, 30, 44,152,194,197,115,151,201,100, 36, 43, 43, 11, 31,126,248, 33, 0, 88,255, 59,218,206,227, 21,219,194, 67,113,170,228, + 7, 4,160, 19,204,248, 25,229,255, 57,134,147,197, 21,152,242,225, 87, 45,118,163,157, 58,125, 6,253,250,246, 1, 67,128, 51, +103, 44,175,129, 7,175,109,219, 25,142,167,218,182, 6,187, 43,228,230,230, 82, 92,175,199,236,217,179, 1,192,250,223, 33,249, + 83, 20,224,226,126,144,201,100,100,236,216,173,144,201, 38,250, 84, 4, 76,154, 56, 80,147,153,153, 25, 8,228, 98, 67,129,103, +196,110,235,225, 55,149,228,157,121,255, 0, 48,117,234, 58,108,223,110,249,159,153, 89, 12, 54, 34,224, 73, 52,128, 16, 34, 81, + 94,220,173,252,227,255,206,195,224,182, 3, 16, 16, 22, 6, 98, 48,129, 33,102, 8,132, 34,196, 39,199,111,191, 48,232, 34, 62, +204,205, 86, 62,211,102,168, 52, 48, 48,208,173, 8,184,127,255,126,163,247, 41, 35,131,240,204,107, 63, 99,102,182,174,209,133, + 28, 51,102,140,215,215,171,160,160,128, 76,158, 60,217,103,215,219,215,246,154,153, 72, 36, 77, 45,235,123,226,196, 9, 73, 3, + 9,169,192,227,145,147, 63,219,102, 47, 2, 26, 9,128,146,146, 18, 82, 82, 82, 2, 0,136,141,141,133,237, 98, 51, 0, 26,189, +119,244,185, 51,148,151,151, 43,229,114, 57,231, 72,128,253, 90,247,174, 72,152,106, 40,133,105, 79,162,158,134,216,115,115,115, +221,110,163, 80,184, 95, 91,189, 33,229,225,148,244, 23, 45, 90,132,236,236,108,216, 10, 4, 46,136,233,222, 25,165, 85,106,252, + 52,119, 42,162,168,225, 40,254,252, 45,196,190, 16,139,157, 45, 76,254, 0,172,132, 15, 0,125,250,244,105,212,206, 70, 6,108, +219,125,237,217,187, 34, 98,246,122, 56, 35,253, 53,107,214, 32, 59, 59, 27, 19,135, 15,192,214,159,143, 3, 33, 65, 64, 77,221, + 35, 63,135,133, 91,143, 5, 2,185, 40,220,122,204, 39,246, 38,215, 44,118,249,108, 22,132, 46,227,244,128,216,134,254, 51, 51, +183, 35, 45, 45,206,250,159, 69, 90, 90, 28,103, 17,240,249,247,159,227,131,127,255, 13, 35,123, 72, 96,214,235, 97, 50,155, 64, + 9, 41, 0, 2, 16, 48,184,123,175, 12,189,218,246,196,226,185,139,241,183,229,127, 83,142,237,227, 62,154,101,223,217,165,116, + 92,227,144,240,119,239,222, 77,188, 17, 1, 5, 5, 5,164,240,175, 91, 49,233,255,224, 19,210, 46, 40, 40, 32,203,151, 47,199, +194,133, 11, 91,181, 8, 56,113,226,132, 68,173, 86, 43,203,202,202,144,152,152,216,164,253, 84,171,213,202, 7, 93, 54,143, 71, +133,204, 44, 11,199,228,102, 47,114,248,121, 35, 1, 16, 27, 27, 75,197,198,198, 90,201,222, 54,148, 44,151,203, 27,189,183,255, +252,242,229,203, 78, 59, 28, 86, 84, 44, 88,176, 64,153,149,149, 5,251,133,114,236, 23,207,145,203,229, 78, 67,176,142, 58,123, +251,182,150, 92,168, 8, 0,214,174, 93,235,148,248, 1, 52, 34,255, 69,139, 22,113,178,121,171,228, 6,234,215,255, 63, 4,207, +249, 7, 98,186,119, 70,187,168, 0,148,172, 47,177,144,127,120,168, 37, 5,224, 39,240,120, 95,211,210,210,164,182,105,128,180, +180, 52,143,163, 52, 12, 1,186, 4, 1,255,122, 25,248,221, 26,160,109, 32,112,190,218,113,251,217, 42,207,108, 59, 19,114,158, + 68,109,222,127,255,125,167,196, 15, 0,203,103,167,226,147,109,135,208, 62,182, 3,238, 92,191,235,214,251, 7, 0, 46, 81, 0, + 79,194,248, 22, 15, 95,230,208,211,103,115,251,158,222,215,203,191,115,126,142, 18,230,194,139,123, 37,174,209,127, 67, 90, 60, + 68,155,174,112,254,190, 70,171,193,240, 25,195,148, 67, 59, 60, 3,125,125, 61,132,254,254, 16, 10, 31,116, 65, 37, 87,174, 96, +227,134, 13,165,115, 94,157, 29,211,205,191, 11, 6,140, 78, 76,254,101,251, 47,146,103, 6, 63,227,145,215,184,180,112, 54,246, +236,217,131,105,211, 26,183,143, 25, 51,134,242, 84, 4,176,228,143,110, 43, 81,248,215, 55,154, 44, 2, 10, 10, 10,200,170, 85, +171,144,144,144,128, 79, 62,249, 4,243,231,207,111,117, 34,192,150,248,125,101,143,181,229,139,104, 2, 15,110,130,152, 37,127, +246,117,110,246,162,135,162, 0,143,164, 14,128, 92, 46,103,115,175, 40, 41, 41, 65,116,116,244, 67, 2,129,109, 43, 47, 47,231, + 84,231,222,221, 96, 64, 79, 58,204,233,211,167, 55,219,177,219, 18,152, 35,175, 63, 59, 59, 27, 57, 57, 57,148,163, 81,176,182, +208,226, 6,234, 94,120, 6, 36,228, 45, 32,249,175,168,195,247,192,127, 44,222, 34,145,191, 5,191,223,124, 2,147,201,243, 66, +103,169,169,169, 42, 14,203,174,186,142,240,124, 9,188,183, 26,232,220, 9,184,187, 89,132,175,191, 48, 96,246, 15,206,219, 61, +129,175,215,179,183, 29,236,119,187,224, 67,132,244, 22, 35,184,199,235, 88,251,225,239,208,191, 79,123, 60,149,250, 55, 78,215, +131,203,253,201, 53, 85,192,222,187,182,228,159,147,147, 67,177, 3,255,188, 34,154,208,101,148, 55, 36,239, 8,134,180,120,135, +237,219,237, 34, 1,238,112,187,252, 54,198,103,140, 71, 72,104, 4,204,148, 9,251,246,236, 69,109, 93, 29,210,210,211,113,175, +188, 28,249,235,126,194,111, 95,157, 29,227, 47,246, 7, 77,252, 48, 97,224, 4,197, 69,229, 39, 94,121,141, 85, 85, 85, 77, 62, +110, 91,242, 7,208,100, 17, 80, 80, 80, 64,222,125,247, 93,196,199, 91,206,103, 92, 92, 28, 90, 83, 36,192,215,196,239,192,251, +103, 95,243, 81,128, 86,130, 71, 86, 8, 40, 58, 58, 90,154,145,145,241, 80, 42,224,208,161, 67,202,134,197, 94, 60, 30, 35,224, +108, 48,160, 43,207,209,153, 64,105, 14,176,222,189,179,112, 63, 87,239, 31, 0,182,253,249, 93,164,125,240, 49, 76,201,195, 33, + 4, 16,124,240, 10,118, 22, 87, 0, 0, 76,201,243, 97, 60,221, 6, 84,219, 63,120, 76, 82, 92,163, 44,174, 80, 49,249,123,204, +127,245, 38, 46,205, 93,136,250, 93, 6,180,111,227,186,221, 23, 17, 0,111,196,193,154, 53,107, 44,106, 56,109, 20, 14,149,149, + 35,164,127, 8, 74,183, 23, 3, 98,127, 76,157,255, 27, 68,118, 74,109,177, 7,209,217,168,127, 95, 69,181, 92,205, 16,112, 55, + 59, 96,123,230,118, 76,200,157,128,169,235,128,204,237,150,215,219, 51,183,123, 28, 5,168,211,213,162, 77, 64, 20, 76, 58, 13, + 8, 77, 48, 36, 41, 9,235,215,175,215,173,250,248, 99, 49, 67, 8,102,189, 60, 11,145, 81,145,208,212,213,193,100, 54, 33,196, + 47, 20, 70,218,232,213,241, 86, 87, 87, 55,154, 29,224,233,128,192,135,200,159,133,151, 34,160,160,160,128,100,101,101, 33, 41, + 41,169, 81,123,159, 62,125,176,116,233, 82, 44, 89,178,164,197, 68, 64,115, 17,191,189,247, 15, 0,101,101,101,124, 20,160,181, + 10, 0,123, 66, 96,215,156,231,242,185,171, 81,211, 44,216,244, 2, 59, 32,144, 29, 27,192, 70, 7, 98, 99, 99,149,108,186,160, +165, 58, 94, 95,194, 93,174,159,245,254,185,216,154,178,122, 29, 72,122,119,220,125,118, 32,162, 48, 28, 1, 83, 63,129,233,246, + 61, 32, 60, 20,194,138,239,177,121, 85, 17, 32, 16,120,124,236,190, 88,138,246,228,155, 47, 98,112, 34, 16, 59,255, 12,122, 7, +191,138,139, 93, 51,128,127, 45,116,218,222, 82, 17,128,236,236,108,140, 28,242, 20,146,135, 39, 32,173,239, 66,172, 88,245, 25, +206, 21,149, 98,238,152,193,184,179,161, 16,234,170, 26,159,220, 15,142, 82, 5,238,158, 15, 87,222,190,175,238, 81,103,246, 93, + 13, 28, 92,178,100, 9,181,116,233, 82, 50,117, 93, 99, 65, 0, 0, 19,114, 39, 64,180,233, 10, 54,109, 42,182,206, 4, 96, 7, + 12, 70, 70, 70, 58,146,115, 96, 24, 6,102, 6, 32,140, 9,254, 1, 98,188,252,202, 43,226,247,222,121, 7,237,218,181, 99, 98, +218,183,167,117,245,117, 48, 19,128, 48,102, 48,140,251,136,214,176, 97,195,168,252,252,124, 82, 81, 81,129,154,154,154, 70,194, +209,118,118,128, 39,179, 2, 10, 10, 10,200,138,223,157, 5,196,241,192,157,127, 63,188,129, 56, 30, 43,126,119, 22, 11,254,195, + 77, 4, 20, 20, 20,144,231,159,127, 94,218,167, 79, 31,101, 69, 69,197, 67,159,119,233,210, 5,207, 63,255,188,244,113, 26, 24, +232,141,247,207, 71, 1, 90,185, 0,176, 43,244,227,174, 16, 80,163,207, 93,133, 76, 51, 50, 50, 28, 70, 1, 88,178,143,142,142, +150,102,101,101, 41,217,156,108, 70, 70,134,203,105,128,174,188, 67, 79, 7,255, 53,215, 52, 64,214,187,119, 53, 24,208, 19, 20, +255, 61, 19,126, 83, 63,129,182,236, 18,132, 7, 63,129,113,221,124, 80,147, 62,194,198, 63, 76,195,245,141, 87,145,182,252, 27, + 64,216, 50,149,157, 23,202,129,237,203,215,163,247,245, 9,192,253,122,188, 61,110,161,203,118, 95, 68, 0,188,245,254, 55,172, +127, 23,130,152,167, 17,140, 4,220,216,147,139, 90,138,224,240,165,155, 72, 62, 83,202,241,186,223,176,190,159, 62, 61,167, 17, +217, 3,192,174, 93, 19, 29,110,231,234,249,112, 23,234,247,197,180, 67, 95,204, 16,200,220,254,128,248, 1, 60,228,249,179, 3, + 6, 55,109, 42,118,248,253,144,128, 16,148,169,203,144,212,237, 25,104,245, 58, 64,171,131,201, 96,196,226,172, 44, 80, 52,104, + 77,125, 29, 24,198, 12,147,153,192, 95,232,135,123,117,247,224,103,118, 63,219,120,218,180,105,214,115,115,224,192, 1,194,246, + 55,182,179, 3,110,223,190,205,249, 56, 39, 79,158, 76, 45,248, 15,200,138,223,157, 69,175,238, 15,255,254,249,171, 6, 44,248, + 79,111,112, 37,235,201,147, 39, 83, 5, 5, 5, 36, 41, 41, 9, 93,186,116,121,232,243, 51,103,206, 96,195,134, 13,202,150, 34, +255, 6,111,156,106,206,220,191, 45,248, 40, 64, 43, 21, 0,205, 5,214,243, 7,128,161, 67,135, 74,229,114,185,146, 13,253, 59, + 17, 7,210,203,151, 47, 43, 61, 37, 97,111, 59, 73, 95, 79, 3,180,245,254, 29, 17, 63, 43,116, 60,217,223,147,197, 21, 48,158, +126, 15,119,241, 51,218, 79,250, 8, 80,215,160, 56,247, 45,196,205, 91,137, 59, 95,189, 5,248, 9, 1,186,101, 42, 59,223,168, + 7,122, 69,191,192,185,189, 37, 34, 0,217,217,217,117, 51,146,159,185, 29,198, 68,116,214,192, 79,188,110,229,124,124,186,249, + 4,222,126,110, 4,102,127,252, 29,166, 45,251,111,139, 12, 30,101, 5,104, 67, 29, 0,170,169,226,180, 41,161,126, 87, 81,128, +204, 6,207,222,158,252,109,189,127,119,232, 24,221, 17,219,246,109,199,176,206,195, 16, 24, 20, 12,134, 33,160,137, 9, 12, 69, +129, 16, 2, 51, 1, 76, 12,129,201,100,130, 86, 93,143, 45, 71,182, 64,100, 22,121, 60, 40,213,126, 86,192,146,249,195,145,210, +177, 4,185, 71,184,219,112, 38, 2, 60, 37,127, 91,123, 75,150, 44, 33,203,151, 47, 71,135, 14, 29, 30, 8,251,226, 98,100,103, +103,163, 53,120,254,190, 22, 2,142,188,127, 62, 10,240, 43, 20, 0,246,163,254, 51, 50, 50,172,121,119, 91,113, 96,251,186, 41, + 30,188, 55, 29,185,175,166, 1, 58,243,254,189, 37,126, 22, 83, 62,252, 10, 63, 1,120,238,131, 20, 16,249, 91,160,166,175,192, +201,226, 10, 80,145, 17,184,114,171,198,226,253, 11, 4, 45,114, 19, 57,155,239,223,148, 58, 0, 92, 4, 23, 87,113,176,102,205, + 26, 3,128,218,223, 73,250,213,188,254,209, 63, 12,127, 94,156,165,107, 27, 26, 93,113,246,220,141,118,179,207,125, 23,220,210, +179, 70,156,145,179,109,138,198,243, 25, 5,142,126,163,105, 17, 0, 71,228,207,122,254, 0,220, 14, 8, 20,139,197,212,185,141, +231,211,149,195, 85, 27, 50,250, 78, 67,141,174, 6, 20, 13, 88, 74,138, 48, 48,155, 9, 24,147, 9, 65,254, 33, 56,160, 62,142, +203, 7,175, 96,220,192,113, 77,247, 18,139,127, 15,192,243,105,128,141, 68, 64,135, 27, 56,127,187,139, 87,228,111,107,111,225, +194,133,228,147, 79, 62, 65,120,120, 56, 42, 42, 42,240,238,187,239,162,181,133,253,125, 33, 4,156,121,255,124, 20,160, 21, 11, +128,230,170, 3,224, 44, 34,176, 98,197, 10,169,189, 80,200,200,200, 80,122,106,207,150, 8, 90, 67,137, 93, 91,239,223,126,250, + 95, 73, 73, 73,163,243,230, 73,213, 62, 86, 4,188,240,193,151, 32,235,128, 54,179,115,160,122,125, 26, 70,100,231, 1,126,126, + 8, 18,139, 90,228,120,109,231,248, 59,122,237,101, 29, 0, 19, 0,186,225,218,210, 77,188, 30,119,103, 36, 63, 83,246,122,238, +166,238,139,127, 59, 62,180, 99,123,137, 1,192,169,140,140,140, 48, 0,193,222, 94,143, 7, 36, 61,145,140, 29,187,213, 38,252, +239,217,247, 93,121,240,182,229,129,185, 10,137,230, 40, 6,228, 12,246,164,207, 70, 4,156,165, 60,254,103,250,255,108,220,244, +221, 38,152,103,152, 78,141,238, 60,186, 95, 84, 72, 20,116, 70, 29, 8, 33, 16, 9, 69,168,214,106,112,232,214, 46,172,249,246, +107, 72,159,150,250,164,112,216,210,194,217,248,250,235,175,241,214, 91,158,215, 0,120, 32, 2,208, 36,242,183,181, 55,127,254, +124,182, 14, 0, 90,115,206,223, 86, 8,120,243,221,166,214, 14,224,225,245,117,195,137, 19, 39,144,155,189,232,161, 58, 0, 46, + 11, 1, 53, 87, 29, 0, 71, 17, 1,103, 68,239, 77, 20,160,169,104,174,105,128,172, 24,201,201,201,129, 66,161, 96, 74, 74, 74, +108,137, 76,154,156,156,236,177,250,157,242,225, 87,128, 77,225,159,209,139, 87, 91, 95,215,183,192,205,214, 92,222, 51, 69, 81, +171, 0, 84, 2,120, 26,192,203, 77, 52,119,231,119,146,126,250,113,138, 95, 66,103,189,243, 13,114,114,114, 68, 10,133,162, 3, + 26,151,179,246,234,122, 52,119, 36,192, 93,125,127,119,104,142,148,128, 51,242, 55,164,197, 3, 78,242,255,182,144,246, 27, 67, +237,201,223, 71, 14,118, 57,132,225,207, 12, 71, 76, 72, 12,192, 16,220,211, 85,224,192,177, 3,184,115,246, 14,198,244, 26, 35, +245,247,247,111, 21,222, 33, 43, 2,124, 69,214,108, 36,224,113, 25,240,199,123,233,143, 47,156, 21, 0,114, 40, 0,154, 11, 11, + 22, 44,112, 72,246,182, 43,177,217, 65,201,101, 86,129,175,188,254,230,152, 6,216, 48,194,223,164, 80, 40,132, 13,169, 3,150, +252,199, 36, 39, 39,123, 20,229,104, 88, 76, 73,233,235,125,116,150, 99,246,117,173,123, 15,225, 15, 64,152,147,147,243,215,134, +247,102, 0,175, 52,213,230,184,191,124, 94,148,147,147, 51, 74,161, 80, 64,161, 80,232, 0,136, 27,254,154, 76,252,108, 20,192, +219,115,230,142,228,159,159, 44,107,180,157,167,196,237,139,148,192,146, 37, 75,168,165,153, 75, 73,199,249, 29,165,232,230,120, +155,178,204,237, 74,174,227, 1,146,122, 39, 81, 26,141, 70,242,213, 7, 95,161, 75,124, 87, 37, 0, 92, 60,115, 65,154, 58, 46, + 13,189, 18,123,121,125, 61,134, 13, 27, 70,173, 91,183,238,161, 89, 1, 70,163,177, 73, 55,144,175,201,250, 73, 27,237,207,163, +117, 70, 1,236,219, 56, 11, 0,119,158, 56, 87, 79,221,219, 78,145,107, 33,150,166, 18,149,175,137,142,181,167, 80, 40,136, 66, +161, 16,218,158,175,216,216, 88,175,126,171,129,160,124,222, 97,180,134,220,183, 3,132, 0,168,179, 20,228,167, 40, 0, 1, 0, +140, 62,184, 30,215, 20, 10, 5, 59,175,172, 38, 54, 54,182,109,108,108,172,127,107, 56,151, 77,245,196,221,217,246, 85, 74,192, + 45,185, 47,241,236, 30, 13, 12, 12, 84, 77,127,126, 6,216,123,123,104,239,161, 62,217,207,169, 83,167,242,228,202,131, 23, 1, + 28,156,104, 42, 49, 49,145,240,167,138, 7, 15, 30, 60,120,240,248,117,129,230, 79, 1, 15, 30, 60,120,240,224,193, 11, 0, 30, + 60,120,240,224,193,131,199,175, 0,255,127, 0, 59, 53, 64,122, 27,196,134,227, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, }; diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c index bb6dc671e14..e3f6a1d5515 100644 --- a/source/blender/src/butspace.c +++ b/source/blender/src/butspace.c @@ -41,6 +41,8 @@ #include "MEM_guardedalloc.h" +#include "DNA_color_types.h" +#include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -48,14 +50,17 @@ #include "DNA_space_types.h" #include "DNA_texture_types.h" +#include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_library.h" #include "BKE_utildefines.h" #include "BLI_blenlib.h" #include "BSE_drawview.h" // for do_viewbuttons.c .... hurms +#include "BSE_node.h" #include "BIF_gl.h" #include "BIF_graphics.h" @@ -107,7 +112,7 @@ void test_scriptpoin_but(char *name, ID **idpp) } id= id->next; } - *idpp= 0; + *idpp= NULL; } void test_actionpoin_but(char *name, ID **idpp) @@ -117,12 +122,13 @@ void test_actionpoin_but(char *name, ID **idpp) id= G.main->action.first; while(id) { if( strcmp(name, id->name+2)==0 ) { + id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ *idpp= id; return; } id= id->next; } - *idpp= 0; + *idpp= NULL; } @@ -140,11 +146,12 @@ void test_obpoin_but(char *name, ID **idpp) 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= 0; + *idpp= NULL; } void test_meshpoin_but(char *name, ID **idpp) @@ -162,7 +169,7 @@ void test_meshpoin_but(char *name, ID **idpp) } id= id->next; } - *idpp= 0; + *idpp= NULL; } void test_matpoin_but(char *name, ID **idpp) @@ -180,7 +187,7 @@ void test_matpoin_but(char *name, ID **idpp) } id= id->next; } - *idpp= 0; + *idpp= NULL; } void test_scenepoin_but(char *name, ID **idpp) @@ -198,12 +205,294 @@ void test_scenepoin_but(char *name, ID **idpp) } id= id->next; } - *idpp= 0; + *idpp= NULL; +} + +void test_grouppoin_but(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->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(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->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(char *name, ID **idpp) +{ + ID *id; + + if( *idpp ) (*idpp)->us--; + + id= G.main->image.first; + while(id) { + if( strcmp(name, id->name+2)==0 ) { + *idpp= id; + id_us_plus(id); + return; + } + id= id->next; + } + *idpp= NULL; +} + +/* ----------- custom button group ---------------------- */ + +static void curvemap_buttons_zoom_in(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(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; + + 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; + + 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(void *cumap_v, void *unused) +{ + CurveMapping *cumap = cumap_v; + + curvemapping_changed(cumap, 0); +} + +static void curvemap_buttons_delete(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(void *cumap_v) +{ + CurveMapping *cumap = cumap_v; + uiBlock *block; + uiBut *bt; + + block= uiNewBlock(&curarea->uiblocks, "curvemap_clipping_func", UI_EMBOSS, UI_HELV, curarea->win); + + /* 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); + + return block; +} + + +static void curvemap_tools_dofunc(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; + } + addqueue(curarea->win, REDRAW, 1); +} + +static uiBlock *curvemap_tools_func(void *cumap_v) +{ + uiBlock *block; + short yco= 0, menuwidth=120; + + block= uiNewBlock(&curarea->uiblocks, "curvemap_tools_func", UI_EMBOSSP, UI_HELV, curarea->win); + 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, "Reset Curve", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 50); + 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, redraw, 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, ""); + + } /* --------------------------------- */ +/* nodes have button callbacks, that can draw in butspace too. need separate handling */ +static void do_node_buts(unsigned short event) +{ + Material *ma; + + /* all operations default on active material layer here */ + /* but this also gets called for lamp and world... */ + ma= G.buts->lockpoin; + if(ma && GS(ma->id.name)==ID_MA) + ma = editnode_get_active_material(ma); + else + ma= NULL; + + if(event>=B_NODE_EXEC) { + if(ma) end_render_material(ma); /// temporal... 3d preview + BIF_preview_changed(ID_MA); + allqueue(REDRAWNODE, 0); + allqueue(REDRAWBUTSSHADING, 0); + } +} void do_butspace(unsigned short event) { @@ -300,6 +589,9 @@ void do_butspace(unsigned short event) extern void do_modifier_panels(unsigned short event); do_modifier_panels(event); } + else if(event<=B_NODE_BUTS) { + do_node_buts(event); + } else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too else if(event>REDRAWVIEW3D) allqueue(event, 0); } @@ -352,11 +644,12 @@ void redraw_test_buttons(Object *new) addqueue(sa->win, REDRAW, 1); buts->re_align= 1; - if(new) { - BIF_preview_changed(buts); + if(new && buts->mainb==CONTEXT_SHADING) { + /* does node previews too... */ + BIF_preview_changed(ID_TE); } } - // always to context switch + // always do context switch if(new) butspace_context_switch(buts, new); } diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 4c29b1698bd..e3fbb984761 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -49,11 +49,11 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" +#include "DNA_color_types.h" #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_image_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_lattice_types.h" @@ -76,6 +76,7 @@ #include "BKE_blender.h" #include "BKE_curve.h" +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_key.h" @@ -150,10 +151,9 @@ #include "BSE_headerbuttons.h" #include "BSE_trans_types.h" #include "BSE_view.h" -#include "BSE_buttons.h" #include "BSE_seqaudio.h" -#include "RE_renderconverter.h" // make_sticky +#include "RE_render_ext.h" // make_sticky #include "butspace.h" // own module @@ -1481,7 +1481,7 @@ static void editing_panel_shapes(Object *ob) } if(key->type && ob->shapenr!=1) uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", 10, 90, 150,19, &kb->vgroup, 0.0, 31.0, 0, 0, "Vertex Weight Group name, to blend with Basis Shape"); - + } /* *************************** FONT ******************************** */ @@ -2115,6 +2115,8 @@ void do_curvebuts(unsigned short event) DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSALL, 0); + allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ break; } @@ -2268,8 +2270,8 @@ static void editing_panel_curve_type(Object *ob, Curve *cu) } uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_MAKEDISP, "DefResolU:", 760,160,120,19, &cu->resolu, 1.0, 1024.0, 0, 0, "Default resolution"); - uiDefBut(block, BUT, B_SETRESOLU, "Set", 880,160,30,19, 0, 0, 0, 0, 0, "Set resolution for interpolation"); + uiDefButS(block, NUM, B_SETRESOLU, "DefResolU:", 760,160,150,19, &cu->resolu, 1.0, 1024.0, 0, 0, "Default resolution"); + //uiDefBut(block, BUT, B_SETRESOLU, "Set", 880,160,30,19, 0, 0, 0, 0, 0, "Set resolution for interpolation"); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MAKEDISP, "Width:", 760,90,150,19, &cu->width, 0.0, 2.0, 1, 0, "Make interpolated result thinner or fatter"); @@ -2742,51 +2744,79 @@ static void validate_posebonebutton_cb(void *bonev, void *namev) allqueue(REDRAWALL, 0); } +static void armature_layer_cb(void *lay_v, void *value_v) +{ + short *layer= lay_v; + int value= (int)value_v; + + if(*layer==0 || G.qual==0) *layer= value; + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); +} + static void editing_panel_armature_type(Object *ob, bArmature *arm) { - uiBlock *block; - + uiBlock *block; + uiBut *but; + int a; + block= uiNewBlock(&curarea->uiblocks, "editing_panel_armature_type", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Armature", "Editing", 320, 0, 318, 204)==0) return; uiDefBut(block, LABEL, 0, "Editing Options", 10,180,150,20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror Edit", 10, 160,150,20, &arm->flag, 0, 0, 0, 0, "Enable X-axis mirrored editing"); - uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", 160,160,150,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects"); - uiDefButBitI(block, TOG, ARM_AUTO_IK, B_DIFF, "Automatic IK", 10, 140,300,20, &arm->flag, 0, 0, 0, 0, "Adds temporal IK chains while grabbing Bones"); + uiDefButBitI(block, TOG, ARM_MIRROR_EDIT, B_DIFF, "X-Axis Mirror", 10, 160,100,20, &arm->flag, 0, 0, 0, 0, "Enable X-axis mirrored editing"); + uiDefButBitC(block, TOG, OB_DRAWXRAY,REDRAWVIEW3D, "X-Ray", 110,160,100,20, &ob->dtx, 0, 0, 0, 0, "Draw armature in front of solid objects"); + uiDefButBitI(block, TOG, ARM_AUTO_IK, B_DIFF, "Auto IK", 210,160,100,20, &arm->flag, 0, 0, 0, 0, "Adds temporal IK chains while grabbing Bones"); uiBlockEndAlign(block); - uiDefBut(block, LABEL, 0, "Display Options", 10,120,150,20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Display Options", 10,141,150,19, 0, 0, 0, 0, 0, ""); + + /* layers */ + uiBlockBeginAlign(block); + for(a=0; a<8; a++) { + short dx= 18; + but= uiDefButBitS(block, TOG, 1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &arm->layer, (void *)(1<drawtype, 0, ARM_OCTA, 0, 0, "Draw bones as octahedra"); uiDefButI(block, ROW, REDRAWVIEW3D, "Stick", 100, 100,55,20, &arm->drawtype, 0, ARM_LINE, 0, 0, "Draw bones as simple 2d lines with dots"); uiDefButI(block, ROW, REDRAWVIEW3D, "B-Bone", 155, 100,70,20, &arm->drawtype, 0, ARM_B_BONE, 0, 0, "Draw bones as boxes, showing subdivision and b-splines"); uiDefButI(block, ROW, REDRAWVIEW3D, "Envelope", 225, 100,85,20, &arm->drawtype, 0, ARM_ENVELOPE, 0, 0, "Draw bones as extruded spheres, showing deformation influence volume"); - uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 80,80,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); - uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 90,80,80,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); - uiDefButS(block, NUM, REDRAWVIEW3D, "Ghost: ", 170,80,80,20, &arm->ghostep, 0.0f, 30.0f, 0, 0, "Draw Ghosts around current frame, for current Action"); - uiDefButS(block, NUM, REDRAWVIEW3D, "Step: ", 250,80,60,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances"); + uiDefButBitI(block, TOG, ARM_DRAWAXES, REDRAWVIEW3D, "Draw Axes", 10, 80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes"); + uiDefButBitI(block, TOG, ARM_DRAWNAMES, REDRAWVIEW3D, "Draw Names", 160,80,150,20, &arm->flag, 0, 0, 0, 0, "Draw bone names"); + + uiDefButS(block, NUM, REDRAWVIEW3D, "Ghost: ", 10,60,150,20, &arm->ghostep, 0.0f, 30.0f, 0, 0, "Draw Ghosts around current frame, for current Action"); + uiDefButS(block, NUM, REDRAWVIEW3D, "Step: ", 160,60,150,20, &arm->ghostsize, 1.0f, 20.0f, 0, 0, "How many frames between Ghost instances"); uiBlockEndAlign(block); - uiDefBut(block, LABEL, 0, "Deform Options", 10,60,150,20, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Deform Options", 10,40,150,20, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 40,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)"); - uiDefButBitI(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 160,40,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)"); - uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,20,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible"); - uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160,20,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); + uiDefButBitS(block, TOG, ARM_DEF_VGROUP, B_ARM_RECALCDATA, "Vertex Groups", 10, 20,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable VertexGroups defining deform (not for Modifiers)"); + uiDefButBitS(block, TOG, ARM_DEF_ENVELOPE, B_ARM_RECALCDATA, "Envelopes", 160,20,150,20, &arm->deformflag, 0, 0, 0, 0, "Enable Bone Envelopes defining deform (not for Modifiers)"); + uiDefButBitI(block, TOG, ARM_RESTPOS, B_ARM_RECALCDATA,"Rest Position", 10,0,150,20, &arm->flag, 0, 0, 0, 0, "Show armature rest position, no posing possible"); + uiDefButBitI(block, TOG, ARM_DELAYDEFORM, REDRAWVIEW3D, "Delay Deform", 160,0,150,20, &arm->flag, 0, 0, 0, 0, "Don't deform children when manipulating bones in pose mode"); } - static void editing_panel_armature_bones(Object *ob, bArmature *arm) { uiBlock *block; uiBut *but; EditBone *curBone; char *boneString=NULL; - int bx=148, by=180; - int index; + int by=180; + int index, a; /* Draw the bone name block */ @@ -2798,23 +2828,23 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) uiNewPanelHeight(block, 204); - uiDefBut(block, LABEL, 0, "Selected Bones", bx,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode"); + uiDefBut(block, LABEL, 0, "Selected Bones", 0,by,158,18, 0, 0, 0, 0, 0, "Only show in Armature Editmode"); by-=20; for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++){ - if (curBone->flag & (BONE_SELECTED)) { + if ((curBone->flag & BONE_SELECTED) && (curBone->layer & arm->layer)) { /* Bone naming button */ - but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name"); + but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", -10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name"); uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL); uiButSetCompleteFunc(but, autocomplete_bone, (void *)OBACT); - uiDefBut(block, LABEL, 0, "child of", bx+107,by,73,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); + uiDefBut(block, LABEL, 0, "child of", 107,by,73,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); boneString = MEM_mallocN((BLI_countlist(&G.edbo) * 64)+64, "Bone str"); build_bonestring (boneString, curBone); curBone->parNr = editbone_to_parnr(curBone->parent); - but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, bx+180,by,120,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent"); + but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, 180,by,120,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent"); /* last arg NULL means button will put old string there */ uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL); @@ -2822,24 +2852,38 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) /* Connect to parent flag */ if (curBone->parent){ - but=uiDefButBitI(block, TOG, BONE_CONNECTED, B_ARM_RECALCDATA, "Con", bx+300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Connect this Bone to Parent"); + but=uiDefButBitI(block, TOG, BONE_CONNECTED, B_ARM_RECALCDATA, "Con", 300,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Connect this Bone to Parent"); uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL); } /* Segment, dist and weight buttons */ uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", bx-10,by-19,117,18, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones"); - uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", bx+110, by-19, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); - uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", bx+223, by-19,110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); + uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", -10,by-19,117,18, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", 110, by-19, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); /* bone types */ - uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", bx+75, by-38, 85, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); - uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", bx+160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); - uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", bx+245,by-38,88,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); + uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 75, by-38, 85, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); + uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); + uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 245,by-38,85,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); + + /* layers */ + uiBlockBeginAlign(block); + for(a=0; a<8; a++) { + short dx= 21; + but= uiDefButBitS(block, TOG, 1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<pose->chanbase.first, index=0; pchan; pchan=pchan->next, index++){ curBone= pchan->bone; - if (curBone->flag & (BONE_SELECTED)) { + if ((curBone->flag & BONE_SELECTED) && (curBone->layer & arm->layer)) { /* Bone naming button */ uiBlockBeginAlign(block); - but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx-10,by,117,18, &curBone->name, 0, 24, 0, 0, "Change the bone name"); + but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", -10,by,117,19, &curBone->name, 0, 24, 0, 0, "Change the bone name"); uiButSetFunc(but, validate_posebonebutton_cb, curBone, NULL); uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob); /* Dist and weight buttons */ - uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", bx+107, by, 105, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); - uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", bx+220, by, 110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "Dist:", 107, by, 105, 19, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 220, by, 110, 19, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); /* Segment, ease in/out buttons */ uiBlockBeginAlign(block); - uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", bx-10,by-19,117,19, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones"); - uiDefButF(block, NUM,B_ARM_RECALCDATA, "In:", bx+107, by-19,105, 19, &curBone->ease1, 0.0, 2.0, 10.0, 0.0, "First length of Bezier handle"); - uiDefButF(block, NUM,B_ARM_RECALCDATA, "Out:", bx+220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle"); + uiDefButS(block, NUM, B_ARM_RECALCDATA, "Segm: ", -10,by-19,117,19, &curBone->segments, 1.0, 32.0, 0.0, 0.0, "Subdivisions for B-bones"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "In:", 107, by-19,105, 19, &curBone->ease1, 0.0, 2.0, 10.0, 0.0, "First length of Bezier handle"); + uiDefButF(block, NUM,B_ARM_RECALCDATA, "Out:", 220, by-19, 110, 19, &curBone->ease2, 0.0, 2.0, 10.0, 0.0, "Second length of Bezier handle"); /* bone types */ - uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", bx-10,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", bx+75, by-38, 85, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); - uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", bx+160,by-38,85,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); - uiDefButBitI(block, TOG, BONE_HIDDEN_P, REDRAWVIEW3D, "Hide", bx+245,by-38,88,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Pose Mode"); + uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 70, by-38, 80, 19, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); + uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 150,by-38,80,19, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "OB:", 230,by-38,100,19, &pchan->custom, "Object that defines custom draw type for this Bone"); + + /* layers */ + uiBlockBeginAlign(block); + for(a=0; a<8; a++) { + short dx= 21; + but= uiDefButBitS(block, TOG, 1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<layer, 0, 0, 0, 0, ""); + uiButSetFunc(but, armature_layer_cb, &curBone->layer, (void *)(1<ikflag, 0.0, 0.0, 0.0, 0.0, "Disable X DoF for IK"); + uiDefButBitS(block, TOG, BONE_IK_NO_XDOF, B_ARM_RECALCDATA, "Lock X Rot", -10,by-60,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable X DoF for IK"); if ((pchan->ikflag & BONE_IK_NO_XDOF)==0) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff X:", bx-10, by-80, 114, 19, &pchan->stiffness[0], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for X axis"); - uiDefButBitS(block, TOG, BONE_IK_XLIMIT, B_ARM_RECALCDATA, "Limit X", bx-10,by-100,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over X axis"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff X:", -10, by-80, 114, 19, &pchan->stiffness[0], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for X axis"); + uiDefButBitS(block, TOG, BONE_IK_XLIMIT, B_ARM_RECALCDATA, "Limit X", -10,by-100,114,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over X axis"); if ((pchan->ikflag & BONE_IK_XLIMIT)) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min X:", bx-10, by-120, 114, 19, &pchan->limitmin[0], -180.0, 0.0, 1000, 1, "Minimum X limit"); - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max X:", bx-10, by-140, 114, 19, &pchan->limitmax[0], 0.0, 180.0f, 1000, 1, "Maximum X limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min X:", -10, by-120, 114, 19, &pchan->limitmin[0], -180.0, 0.0, 1000, 1, "Minimum X limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max X:", -10, by-140, 114, 19, &pchan->limitmax[0], 0.0, 180.0f, 1000, 1, "Maximum X limit"); zerolimit = 0; } zerodof = 0; @@ -2918,13 +2978,13 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, BONE_IK_NO_YDOF, B_ARM_RECALCDATA, "Lock Y Rot", bx+104,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Y DoF for IK"); + uiDefButBitS(block, TOG, BONE_IK_NO_YDOF, B_ARM_RECALCDATA, "Lock Y Rot", 104,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Y DoF for IK"); if ((pchan->ikflag & BONE_IK_NO_YDOF)==0) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Y:", bx+104, by-80, 114, 19, &pchan->stiffness[1], 0.0, 0.99, 1.0, 0.0, "Resistance to twisting over Y axis"); - uiDefButBitS(block, TOG, BONE_IK_YLIMIT, B_ARM_RECALCDATA, "Limit Y", bx+104,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Y axis"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Y:", 104, by-80, 114, 19, &pchan->stiffness[1], 0.0, 0.99, 1.0, 0.0, "Resistance to twisting over Y axis"); + uiDefButBitS(block, TOG, BONE_IK_YLIMIT, B_ARM_RECALCDATA, "Limit Y", 104,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Y axis"); if ((pchan->ikflag & BONE_IK_YLIMIT)) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Y:", bx+104, by-120, 113, 19, &pchan->limitmin[1], -180.0, 0.0, 1000, 1, "Minimum Y limit"); - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Y:", bx+104, by-140, 113, 19, &pchan->limitmax[1], 0.0, 180.0, 1000, 1, "Maximum Y limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Y:", 104, by-120, 113, 19, &pchan->limitmin[1], -180.0, 0.0, 1000, 1, "Minimum Y limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Y:", 104, by-140, 113, 19, &pchan->limitmax[1], 0.0, 180.0, 1000, 1, "Maximum Y limit"); zerolimit = 0; } zerodof = 0; @@ -2932,13 +2992,13 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, BONE_IK_NO_ZDOF, B_ARM_RECALCDATA, "Lock Z Rot", bx+217,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Z DoF for IK"); + uiDefButBitS(block, TOG, BONE_IK_NO_ZDOF, B_ARM_RECALCDATA, "Lock Z Rot", 217,by-60,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Disable Z DoF for IK"); if ((pchan->ikflag & BONE_IK_NO_ZDOF)==0) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Z:", bx+217, by-80, 114, 19, &pchan->stiffness[2], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Z axis"); - uiDefButBitS(block, TOG, BONE_IK_ZLIMIT, B_ARM_RECALCDATA, "Limit Z", bx+217,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Z axis"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stiff Z:", 217, by-80, 114, 19, &pchan->stiffness[2], 0.0, 0.99, 1.0, 0.0, "Resistance to bending for Z axis"); + uiDefButBitS(block, TOG, BONE_IK_ZLIMIT, B_ARM_RECALCDATA, "Limit Z", 217,by-100,113,19, &pchan->ikflag, 0.0, 0.0, 0.0, 0.0, "Limit rotation over Z axis"); if ((pchan->ikflag & BONE_IK_ZLIMIT)) { - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Z:", bx+217, by-120, 113, 19, &pchan->limitmin[2], -180.0, 0.0, 1000, 1, "Minimum Z limit"); - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Z:", bx+217, by-140, 113, 19, &pchan->limitmax[2], 0.0, 180.0, 1000, 1, "Maximum Z limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Min Z:", 217, by-120, 113, 19, &pchan->limitmin[2], -180.0, 0.0, 1000, 1, "Minimum Z limit"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Max Z:", 217, by-140, 113, 19, &pchan->limitmax[2], 0.0, 180.0, 1000, 1, "Maximum Z limit"); zerolimit = 0; } zerodof = 0; @@ -2947,15 +3007,15 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm) by -= (zerodof)? 82: (zerolimit)? 122: 162; - uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stretch:", bx-10, by, 113, 19, &pchan->ikstretch, 0.0, 1.0, 1.0, 0.0, "Allow scaling of the bone for IK"); + uiDefButF(block, NUM, B_ARM_RECALCDATA, "Stretch:", -10, by, 113, 19, &pchan->ikstretch, 0.0, 1.0, 1.0, 0.0, "Allow scaling of the bone for IK"); by -= 20; } else { - but= uiDefButBitS(block, TOG, POSE_STRIDE, B_ARM_STRIDE, "Stride Root", bx-10, by-60, 113, 19, &pchan->flag, 0.0, 0.0, 0, 0, "Set this PoseChannel to define the Stride distance"); + but= uiDefButBitS(block, TOG, POSE_STRIDE, B_ARM_STRIDE, "Stride Root", -10, by-60, 113, 19, &pchan->flag, 0.0, 0.0, 0, 0, "Set this PoseChannel to define the Stride distance"); uiButSetFunc(but, validate_stridebutton_cb, pchan, NULL); - uiDefBut(block, LABEL, 0, "(DoF only for IK chains)", bx+110,by-60, 190, 19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "(DoF only for IK chains)", 110,by-60, 190, 19, 0, 0, 0, 0, 0, ""); by -= 82; } @@ -3268,6 +3328,7 @@ static void editing_panel_mesh_tools1(Object *ob, Mesh *me) uiDefButBitI(block, TOG, G_DRAW_FACEAREA, REDRAWVIEW3D, "Face Area", 1125,44,150,19, &G.f, 0, 0, 0, 0, "Displays the area of selected faces"); uiBlockEndAlign(block); + uiDefButBitS(block, TOG, B_MESH_X_MIRROR, B_DIFF, "X-axis mirror",1125,0,150,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "While using transforms, mirrors the transformation"); } char *get_vertexgroup_menustr(Object *ob) @@ -3364,7 +3425,7 @@ static void editing_panel_links(Object *ob) local= B_LATTLOCAL; } uiBlockSetCol(block, TH_BUT_SETTING2); - xco= std_libbuttons(block, 143, 180, 0, NULL, browse, id, idfrom, &(G.buts->menunr), alone, local, 0, 0, B_KEEPDATA); + xco= std_libbuttons(block, 143, 180, 0, NULL, browse, GS(id->name), 0, id, idfrom, &(G.buts->menunr), alone, local, 0, 0, B_KEEPDATA); uiBlockSetCol(block, TH_AUTO); } if(ob) { @@ -3375,9 +3436,21 @@ static void editing_panel_links(Object *ob) /* to be sure */ - if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL); + if ELEM6(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_EMPTY); else return; + if (ob->type==OB_EMPTY) { + uiDefBut(block, LABEL,0,"Empty Display:", + xco, 154, 130,20, 0, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButC(block, MENU, REDRAWVIEW3D, "Empty Drawtype%t|Arrows%x1|Plain Axes%x2", + xco, 128, 140, 20, &ob->empty_drawtype, 0, 0, 0, 0, "Selects the Empty display type"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Size:", + xco, 108, 140, 21, &ob->empty_drawsize, 0.01, 10.0, 1, 0, "The size to display the Empty"); + uiBlockEndAlign(block); + return; + } if(ob->type==OB_MESH) poin= &( ((Mesh *)ob->data)->texflag ); else if(ob->type==OB_MBALL) poin= &( ((MetaBall *)ob->data)->texflag ); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 0b0ab827768..d4f4d182b8f 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -81,7 +81,6 @@ #include "BDR_editcurve.h" -#include "BSE_buttons.h" #include "BSE_headerbuttons.h" #include "BSE_filesel.h" diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 58c64248e91..33df6cce276 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -119,6 +119,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" +#include "BKE_group.h" #include "BKE_image.h" #include "BKE_ipo.h" #include "BKE_lattice.h" @@ -1133,118 +1134,6 @@ void do_constraintbuts(unsigned short event) allqueue (REDRAWBUTSOBJECT, 0); } -void object_panel_constraint(char *context) -{ - uiBlock *block; - Object *ob= OBACT; - ListBase *conlist; - bConstraint *curcon; - short xco, yco; - char str[64]; - - block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Constraints", context, 640, 0, 318, 204)==0) return; - - /* this is a variable height panel, newpanel doesnt force new size on existing panels */ - /* so first we make it default height */ - uiNewPanelHeight(block, 204); - - if(G.obedit==OBACT) return; // ?? - - conlist = get_active_constraints(OBACT); - - if (conlist) { - - uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint"); - - /* print active object or bone */ - str[0]= 0; - if (ob->flag & OB_POSEMODE){ - bPoseChannel *pchan= get_active_posechannel(ob); - if(pchan) sprintf(str, "To Bone: %s", pchan->name); - } - else { - sprintf(str, "To Object: %s", ob->id.name+2); - } - uiDefBut(block, LABEL, 1, str, 150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name"); - - /* Go through the list of constraints and draw them */ - xco = 10; - yco = 160; - - for (curcon = conlist->first; curcon; curcon=curcon->next) { - /* hrms, the temporal constraint should not draw! */ - if(curcon->type==CONSTRAINT_TYPE_KINEMATIC) { - bKinematicConstraint *data= curcon->data; - if(data->flag & CONSTRAINT_IK_TEMP) - continue; - } - /* Draw default constraint header */ - draw_constraint(block, conlist, curcon, &xco, &yco); - } - - if(yco < 0) uiNewPanelHeight(block, 204-yco); - - } -} - -static void object_panel_draw(Object *ob) -{ - uiBlock *block; - int xco, a, dx, dy; - - block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Draw", "Object", 320, 0, 318, 204)==0) return; - - /* LAYERS */ - xco= 120; - dx= 35; - dy= 30; - - uiDefBut(block, LABEL, 0, "Layers", 10,170,100,20, NULL, 0, 0, 0, 0, ""); - - uiBlockBeginAlign(block); - for(a=0; a<5; a++) - uiDefButBitI(block, TOG, 1<lay), 0, 0, 0, 0, ""); - for(a=0; a<5; a++) - uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "", (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); - - xco+= 7; - uiBlockBeginAlign(block); - for(a=5; a<10; a++) - uiDefButBitI(block, TOG, 1<lay), 0, 0, 0, 0, ""); - for(a=5; a<10; a++) - uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "", (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); - - uiBlockEndAlign(block); - - uiDefBut(block, LABEL, 0, "Drawtype", 10,120,100,20, NULL, 0, 0, 0, 0, ""); - - uiBlockBeginAlign(block); - uiDefButC(block, ROW, REDRAWVIEW3D, "Shaded", 10,100,100, 20, &ob->dt, 0, OB_SHADED, 0, 0, "Draw active object shaded or textured"); - uiDefButC(block, ROW, REDRAWVIEW3D, "Solid", 10,80,100, 20, &ob->dt, 0, OB_SOLID, 0, 0, "Draw active object in solid"); - uiDefButC(block, ROW, REDRAWVIEW3D, "Wire", 10,60, 100, 20, &ob->dt, 0, OB_WIRE, 0, 0, "Draw active object in wireframe"); - uiDefButC(block, ROW, REDRAWVIEW3D, "Bounds", 10,40, 100, 20, &ob->dt, 0, OB_BOUNDBOX, 0, 0, "Only draw object with bounding box"); - uiBlockEndAlign(block); - - uiDefBut(block, LABEL, 0, "Draw Extra", 120,120,90,20, NULL, 0, 0, 0, 0, ""); - - uiBlockBeginAlign(block); - uiDefButBitC(block, TOG, OB_BOUNDBOX, REDRAWVIEW3D, "Bounds", 120, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds"); - uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name", 210, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name"); - - uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4", - 120, 80, 90, 20, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type"); - uiDefButBitC(block, TOG, OB_AXIS, REDRAWVIEW3D, "Axis", 210, 80, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's centre and axis"); - - uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 120, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space"); - uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 210, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Adds the active object's wireframe over solid drawing"); - - uiDefButBitC(block, TOG, OB_DRAWTRANSP, REDRAWVIEW3D, "Transp", 120, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Enables transparent materials for the active object (Mesh only)"); - uiDefButBitC(block, TOG, OB_DRAWXRAY, REDRAWVIEW3D, "X-ray", 210, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Makes the active object draw in front of others"); - -} - static void softbody_bake(Object *ob) { SoftBody *sb= ob->soft; @@ -1451,6 +1340,10 @@ void do_object_panels(unsigned short event) allqueue(REDRAWVIEW3D, 0); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); break; + case B_GROUP_RELINK: + group_relink_nla_objects(OBACT); + allqueue(REDRAWVIEW3D, 0); + break; default: if(event>=B_SELEFFECT && eventgroup, event), ob); + + ob->flag |= OB_FROMGROUP; + BASACT->flag |= OB_FROMGROUP; + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } +} + +static uiBlock *add_groupmenu(void *arg_unused) +{ + uiBlock *block; + Group *group; + short yco= 0; + char str[32]; + + block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win); + uiBlockSetButmFunc(block, do_add_groupmenu, NULL); + + uiDefBut(block, BUTM, B_NOP, "ADD NEW", 0, 20, 160, 19, NULL, 0.0, 0.0, 1, -1, ""); + for(group= G.main->group.first; group; group= group->id.next, yco++) { + if(group->id.lib) strcpy(str, "L "); + else strcpy(str, " "); + strcat(str, group->id.name+2); + uiDefBut(block, BUTM, B_NOP, str, 0, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, yco, ""); + } + + uiTextBoundsBlock(block, 50); + uiBlockSetDirection(block, UI_DOWN); + + return block; +} + +static void group_ob_rem(void *gr_v, void *ob_v) +{ + Object *ob= OBACT; + + rem_from_group(gr_v, ob); + if(find_group(ob)==NULL) { + ob->flag &= ~OB_FROMGROUP; + BASACT->flag &= ~OB_FROMGROUP; + } + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + +} + +static void group_local(void *gr_v, void *unused) +{ + Group *group= gr_v; + + group->id.lib= NULL; + + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + +} + +static void object_panel_object(Object *ob) +{ + uiBlock *block; + uiBut *but; + Group *group; + int a=0, xco; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_object", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Object and Links", "Object", 0, 0, 318, 204)==0) return; + + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + + /* object name */ + uiBlockSetCol(block, TH_BUT_SETTING2); + xco= std_libbuttons(block, 10, 180, 0, NULL, 0, ID_OB, 0, &ob->id, NULL, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0, B_KEEPDATA); + uiBlockSetCol(block, TH_AUTO); + + /* parent */ + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", xco+5, 180, 305-xco, 20, &ob->parent, "Parent Object"); + + uiDefBlockBut(block, add_groupmenu, NULL, "Add to Group", 10,150,150,20, "Add Object to a new Group"); + + /* all groups */ + uiBlockBeginAlign(block); + for(group= G.main->group.first; group; group= group->id.next) { + if(object_in_group(ob, group)) { + xco= 160; + + but = uiDefBut(block, TEX, B_IDNAME, "GR:", 10, 120-a, 150, 20, group->id.name+2, 0.0, 19.0, 0, 0, "Displays Group name. Click to change."); + uiButSetFunc(but, test_idbutton_cb, group->id.name, NULL); + + if(group->id.lib) { + but= uiDefIconBut(block, BUT, B_NOP, ICON_PARLIB, 160, 120-a, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Make Group local"); + uiButSetFunc(but, group_local, group, NULL); + xco= 180; + } + but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-a, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership"); + uiButSetFunc(but, group_ob_rem, group, ob); + + a+= 20; + } + } +} + static void object_panel_anim(Object *ob) { uiBlock *block; char str[32]; block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return; + if(uiNewPanel(curarea, block, "Anim settings", "Object", 320, 0, 318, 204)==0) return; + + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); uiBlockBeginAlign(block); - uiDefButS(block, ROW,B_TRACKBUTS,"TrackX", 24,190,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object"); - uiDefButS(block, ROW,B_TRACKBUTS,"Y", 85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object"); - uiDefButS(block, ROW,B_TRACKBUTS,"Z", 104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object"); - uiDefButS(block, ROW,B_TRACKBUTS,"-X", 124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object"); - uiDefButS(block, ROW,B_TRACKBUTS,"-Y", 150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object"); - uiDefButS(block, ROW,B_TRACKBUTS,"-Z", 178,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"TrackX", 24,180,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"Y", 85,180,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"Z", 104,180,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"-X", 124,180,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"-Y", 150,180,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object"); + uiDefButS(block, ROW,B_TRACKBUTS,"-Z", 178,180,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object"); uiBlockBeginAlign(block); - uiDefButS(block, ROW,REDRAWVIEW3D,"UpX", 226,190,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up"); - uiDefButS(block, ROW,REDRAWVIEW3D,"Y", 274,190,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up"); - uiDefButS(block, ROW,REDRAWVIEW3D,"Z", 298,190,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up"); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, OB_DRAWKEY, REDRAWVIEW3D, "Draw Key", 24,160,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position"); - uiDefButBitS(block, TOG, OB_DRAWKEYSEL, REDRAWVIEW3D, "Draw Key Sel", 97,160,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys"); - uiDefButBitS(block, TOG, OB_POWERTRACK, REDRAWVIEW3D, "Powertrack", 180,160,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off"); - uiDefButBitS(block, TOG, PARSLOW, 0, "SlowPar", 260,160,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship"); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, OB_DUPLIFRAMES, REDRAWVIEW3D, "DupliFrames", 24,128,89,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame"); - uiDefButBitS(block, TOG, OB_DUPLIVERTS, REDRAWVIEW3D, "DupliVerts", 114,128,82,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices"); - uiDefButBitS(block, TOG, OB_DUPLIROT, REDRAWVIEW3D, "Rot", 200,128,31,19, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal"); - uiDefButBitS(block, TOG, OB_DUPLINOSPEED, REDRAWVIEW3D, "No Speed", 234,128,82,19, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame"); - uiBlockBeginAlign(block); - uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:", 24,105,141,19, &ob->dupsta, 1.0, (MAXFRAMEF - 1.0f), 0, 0, "Specify startframe for Dupliframes"); - uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:", 170,105,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, ""); - uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd", 24,82,140,19, &ob->dupend, 1.0, MAXFRAMEF, 0, 0, "Specify endframe for Dupliframes"); - uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff", 171,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "Offs Ob", 24,51,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo"); - uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "Offs Par", 82,51,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent"); - uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "Offs Particle", 140,51,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect"); + uiDefButS(block, ROW,REDRAWVIEW3D,"UpX", 226,180,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up"); + uiDefButS(block, ROW,REDRAWVIEW3D,"Y", 274,180,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up"); + uiDefButS(block, ROW,REDRAWVIEW3D,"Z", 298,180,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,17,115,30, &ob->sf, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify an offset in frames"); - uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 139,17,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames"); - uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 248,17,67,31, 0, 0, 0, 0, 0, "Print objectspeed"); + uiDefButBitS(block, TOG, OB_DRAWKEY, REDRAWVIEW3D, "Draw Key", 24,155,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position"); + uiDefButBitS(block, TOG, OB_DRAWKEYSEL, REDRAWVIEW3D, "Draw Key Sel", 97,155,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys"); + uiDefButBitS(block, TOG, OB_POWERTRACK, REDRAWVIEW3D, "Powertrack", 180,155,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off"); + uiDefButBitS(block, TOG, PARSLOW, 0, "SlowPar", 260,155,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship"); + uiBlockBeginAlign(block); + + uiDefButBitS(block, TOG, OB_DUPLIFRAMES, REDRAWVIEW3D, "DupliFrames", 24,130,89,20, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame"); + uiDefButBitS(block, TOG, OB_DUPLIVERTS, REDRAWVIEW3D, "DupliVerts", 114,130,82,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices"); + uiDefButBitS(block, TOG, OB_DUPLIROT, REDRAWVIEW3D, "Rot", 200,130,31,20, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal"); + uiDefButBitS(block, TOG, OB_DUPLINOSPEED, REDRAWVIEW3D, "No Speed", 234,130,82,20, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame"); + + uiDefButBitS(block, TOG, OB_DUPLIGROUP, REDRAWVIEW3D, "DupliGroup", 24,110,150,20, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame"); + uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_GROUP_RELINK, "GR:", 174,110,142,20, &ob->dup_group, "Duplicate this entire Group"); + + uiBlockBeginAlign(block); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:", 24,85,141,19, &ob->dupsta, 1.0, (MAXFRAMEF - 1.0f), 0, 0, "Specify startframe for Dupliframes"); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:", 170,85,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, ""); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd", 24,65,140,19, &ob->dupend, 1.0, MAXFRAMEF, 0, 0, "Specify endframe for Dupliframes"); + uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff", 171,65,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "Offs Ob", 24,35,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo"); + uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "Offs Par", 82,35,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent"); + uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "Offs Particle", 140,35,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect"); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, REDRAWALL, "TimeOffset:", 24,10,115,20, &ob->sf, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify an offset in frames"); + uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time", 139,10,104,20, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames"); + uiDefBut(block, BUT, B_PRINTSPEED, "PrSpeed", 248,10,67,20, 0, 0, 0, 0, 0, "Print objectspeed"); uiBlockEndAlign(block); sprintf(str, "%.4f", prspeed); - uiDefBut(block, LABEL, 0, str, 247,40,63,31, NULL, 1.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, str, 247,35,63,31, NULL, 1.0, 0, 0, 0, ""); } +static void object_panel_draw(Object *ob) +{ + uiBlock *block; + int xco, a, dx, dy; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Draw", "Object", 640, 0, 318, 204)==0) return; + + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + + /* LAYERS */ + xco= 120; + dx= 35; + dy= 30; + + uiDefBut(block, LABEL, 0, "Layers", 10,170,100,20, NULL, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + for(a=0; a<5; a++) + uiDefButBitI(block, TOG, 1<lay), 0, 0, 0, 0, ""); + for(a=0; a<5; a++) + uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "", (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); + + xco+= 7; + uiBlockBeginAlign(block); + for(a=5; a<10; a++) + uiDefButBitI(block, TOG, 1<lay), 0, 0, 0, 0, ""); + for(a=5; a<10; a++) + uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "", (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, ""); + + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Drawtype", 10,120,100,20, NULL, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButC(block, ROW, REDRAWVIEW3D, "Shaded", 10,100,100, 20, &ob->dt, 0, OB_SHADED, 0, 0, "Draw active object shaded or textured"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Solid", 10,80,100, 20, &ob->dt, 0, OB_SOLID, 0, 0, "Draw active object in solid"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Wire", 10,60, 100, 20, &ob->dt, 0, OB_WIRE, 0, 0, "Draw active object in wireframe"); + uiDefButC(block, ROW, REDRAWVIEW3D, "Bounds", 10,40, 100, 20, &ob->dt, 0, OB_BOUNDBOX, 0, 0, "Only draw object with bounding box"); + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Draw Extra", 120,120,90,20, NULL, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButBitC(block, TOG, OB_BOUNDBOX, REDRAWVIEW3D, "Bounds", 120, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds"); + uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name", 210, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name"); + + uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4", + 120, 80, 90, 20, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type"); + uiDefButBitC(block, TOG, OB_AXIS, REDRAWVIEW3D, "Axis", 210, 80, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's centre and axis"); + + uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 120, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space"); + uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 210, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Adds the active object's wireframe over solid drawing"); + + uiDefButBitC(block, TOG, OB_DRAWTRANSP, REDRAWVIEW3D, "Transp", 120, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Enables transparent materials for the active object (Mesh only)"); + uiDefButBitC(block, TOG, OB_DRAWXRAY, REDRAWVIEW3D, "X-ray", 210, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Makes the active object draw in front of others"); + +} + +void object_panel_constraint(char *context) +{ + uiBlock *block; + Object *ob= OBACT; + ListBase *conlist; + bConstraint *curcon; + short xco, yco; + char str[64]; + + block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win); + if(uiNewPanel(curarea, block, "Constraints", context, 960, 0, 318, 204)==0) return; + + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + + /* this is a variable height panel, newpanel doesnt force new size on existing panels */ + /* so first we make it default height */ + uiNewPanelHeight(block, 204); + + if(G.obedit==OBACT) return; // ?? + + conlist = get_active_constraints(OBACT); + + if (conlist) { + + uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint"); + + /* print active object or bone */ + str[0]= 0; + if (ob->flag & OB_POSEMODE){ + bPoseChannel *pchan= get_active_posechannel(ob); + if(pchan) sprintf(str, "To Bone: %s", pchan->name); + } + else { + sprintf(str, "To Object: %s", ob->id.name+2); + } + uiDefBut(block, LABEL, 1, str, 150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name"); + + /* Go through the list of constraints and draw them */ + xco = 10; + yco = 160; + + for (curcon = conlist->first; curcon; curcon=curcon->next) { + /* hrms, the temporal constraint should not draw! */ + if(curcon->type==CONSTRAINT_TYPE_KINEMATIC) { + bKinematicConstraint *data= curcon->data; + if(data->flag & CONSTRAINT_IK_TEMP) + continue; + } + /* Draw default constraint header */ + draw_constraint(block, conlist, curcon, &xco, &yco); + } + + if(yco < 0) uiNewPanelHeight(block, 204-yco); + + } +} + void do_effects_panels(unsigned short event) { Object *ob; @@ -1706,6 +1836,8 @@ static void object_panel_fields(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Fields and Deflection", "Physics", 0, 0, 318, 204)==0) return; + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + /* should become button, option? */ if(ob->pd==NULL) { ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect"); @@ -1815,6 +1947,8 @@ static void object_softbodies(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Soft Body", "Physics", 640, 0, 318, 204)==0) return; + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + /* do not allow to combine with force fields */ /* if(ob->pd && ob->pd->deflect) { */ /* no reason for that any more BM */ @@ -1933,6 +2067,8 @@ static void object_panel_particles_motion(Object *ob) uiNewPanelTabbed("Particles ", "Physics"); if(uiNewPanel(curarea, block, "Particle Motion", "Physics", 320, 0, 318, 204)==0) return; + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + /* top row */ uiBlockBeginAlign(block); uiDefButI(block, NUM, B_CALCEFFECT, "Keys:", 0,180,75,20, &paf->totkey, 1.0, 100.0, 0, 0, "Specify the number of key positions"); @@ -1961,6 +2097,8 @@ static void object_panel_particles_motion(Object *ob) uiDefButS(block, NUM, B_CALCEFFECT, "Tex:", 75,10,75,20, &paf->timetex, 1.0, 10.0, 0, 0, "Specify texture used for the texture emission"); /* right collumn */ + uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_CALCEFFECT, "GR:", 160, 155, 150, 20, &paf->group, "Limit Force Fields to this Group"); + uiBlockBeginAlign(block); uiDefBut(block, LABEL, 0, "Force:", 160,130,75,20, NULL, 0.0, 0, 0, 0, ""); uiDefButF(block, NUM, B_CALCEFFECT, "X:", 235,130,75,20, paf->force, -1.0, 1.0, 1, 2, "Specify the X axis of a continues force"); @@ -1992,6 +2130,8 @@ static void object_panel_particles(Object *ob) block= uiNewBlock(&curarea->uiblocks, "object_panel_particles", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Particles ", "Physics", 320, 0, 318, 204)==0) return; + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + if (ob->type == OB_MESH) { uiBlockBeginAlign(block); if(paf==NULL) @@ -2078,6 +2218,8 @@ static void object_panel_fluidsim(Object *ob) uiNewPanelTabbed("Soft Body", "Physics"); if(uiNewPanel(curarea, block, "Fluid Simulation", "Physics", 1060, 0, 318, 204)==0) return; + if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); + if(ob->type==OB_MESH) { uiDefButBitS(block, TOG, OB_FLUIDSIM_ENABLE, REDRAWBUTSOBJECT, "Enable", 0,yline, 75,objHeight, &ob->fluidsimFlag, 0, 0, 0, 0, "Sets object to participate in fluid simulation"); @@ -2232,8 +2374,7 @@ void object_panels() /* check context here */ ob= OBACT; if(ob) { - if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); - + object_panel_object(ob); object_panel_anim(ob); object_panel_draw(ob); object_panel_constraint("Object"); @@ -2249,7 +2390,6 @@ void physics_panels() /* check context here */ ob= OBACT; if(ob) { - if(ob->id.lib) uiSetButLock(1, "Can't edit library data"); object_panel_fields(ob); object_panel_particles(ob); object_panel_particles_motion(ob); diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index ff83a457d33..63acf639913 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -36,6 +36,7 @@ #include #include "MEM_guardedalloc.h" +#include "DNA_node_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" @@ -45,7 +46,9 @@ #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_library.h" +#include "BKE_scene.h" #include "BKE_sound.h" #include "BKE_packedFile.h" #include "BKE_utildefines.h" @@ -74,7 +77,6 @@ /* -----includes for this file specific----- */ -#include "render.h" #include "DNA_image_types.h" #include "BKE_writeavi.h" #include "BKE_image.h" @@ -83,6 +85,7 @@ #include "BIF_editsound.h" #include "BSE_seqaudio.h" #include "BSE_headerbuttons.h" + #include "butspace.h" // own module #ifdef WITH_QUICKTIME @@ -347,7 +350,7 @@ static void sound_panel_sound(bSound *sound) // warning: abuse of texnr here! (ton didnt code!) buttons_active_id(&id, &idfrom); - std_libbuttons(block, 10, 160, 0, NULL, B_SOUNDBROWSE2, id, idfrom, &(G.buts->texnr), 1, 0, 0, 0, 0); + std_libbuttons(block, 10, 160, 0, NULL, B_SOUNDBROWSE2, ID_SO, 0, id, idfrom, &(G.buts->texnr), 1, 0, 0, 0, 0); if (sound) { @@ -509,7 +512,8 @@ static void run_playanim(char *file) { char str[FILE_MAXDIR+FILE_MAXFILE]; int pos[2], size[2]; - calc_renderwin_rectangle(G.winpos, pos, size); + /* image size not so relevant for now */ + calc_renderwin_rectangle(640, 480, G.winpos, pos, size); sprintf(str, "%s -a -p %d %d \"%s\"", bprogname, pos[0], pos[1], file); system(str); @@ -524,12 +528,12 @@ void playback_anim(void) makeqtstring(file); else #endif - makeavistring(file); + makeavistring(&G.scene->r, file); if(BLI_exist(file)) { run_playanim(file); } else { - makepicstring(file, G.scene->r.sfra); + BKE_makepicstring(file, G.scene->r.sfra); if(BLI_exist(file)) { run_playanim(file); } @@ -598,7 +602,7 @@ void do_render_panels(unsigned short event) G.scene->r.size= 100; G.scene->r.frs_sec= 25; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); BIF_undo_push("Set PAL"); @@ -641,7 +645,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 1; G.scene->r.size= 100; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); BIF_undo_push("Set FULL"); @@ -655,7 +659,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 1; G.scene->r.size= 50; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); allqueue(REDRAWVIEWCAM, 0); @@ -668,7 +672,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 1; G.scene->r.size= 100; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.15, 0.85, 0.15, 0.85); allqueue(REDRAWVIEWCAM, 0); @@ -682,7 +686,7 @@ void do_render_panels(unsigned short event) G.scene->r.size= 100; G.scene->r.frs_sec= 25; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); BIF_undo_push("Set PAL 16/9"); @@ -696,7 +700,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 1; G.scene->r.size= 50; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); allqueue(REDRAWVIEWCAM, 0); @@ -709,7 +713,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 100; G.scene->r.size= 100; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); allqueue(REDRAWVIEWCAM, 0); @@ -722,7 +726,7 @@ void do_render_panels(unsigned short event) G.scene->r.yasp= 100; G.scene->r.size= 100; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.0, 1.0, 0.0, 1.0); BIF_undo_push("Set PC"); @@ -737,7 +741,7 @@ void do_render_panels(unsigned short event) G.scene->r.size= 100; G.scene->r.mode= R_OSA+R_SHADOW+R_FIELDS; G.scene->r.imtype= R_TARGA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 4; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); BIF_undo_push("Set Default"); @@ -767,7 +771,7 @@ void do_render_panels(unsigned short event) G.scene->r.size= 100; G.scene->r.frs_sec= 30; G.scene->r.mode &= ~R_PANORAMA; - G.scene->r.xparts= G.scene->r.yparts= 1; + G.scene->r.xparts= G.scene->r.yparts= 2; BLI_init_rctf(&G.scene->r.safety, 0.1, 0.9, 0.1, 0.9); BIF_undo_push("Set NTSC"); @@ -793,19 +797,19 @@ void do_render_panels(unsigned short event) scene_change_set(G.scene, NULL); break; case B_FBUF_REDO: - if(R.rectftot) { +// if(R.rectftot) { /* copy is needed... not so nice, but how better? */ - R.r.postgamma= G.scene->r.postgamma; - R.r.postigamma= 1.0/R.r.postgamma; - R.r.postadd= G.scene->r.postadd; - R.r.postmul= G.scene->r.postmul; - R.r.posthue= G.scene->r.posthue; - R.r.postsat= G.scene->r.postsat; - R.r.dither_intensity= G.scene->r.dither_intensity; +// R.r.postgamma= G.scene->r.postgamma; +// R.r.postigamma= 1.0/R.r.postgamma; +// R.r.postadd= G.scene->r.postadd; +// R.r.postmul= G.scene->r.postmul; +// R.r.posthue= G.scene->r.posthue; +// R.r.postsat= G.scene->r.postsat; +// R.r.dither_intensity= G.scene->r.dither_intensity; - RE_floatbuffer_to_output(); - BIF_redraw_render_rect(); - } +// _floatbuffer_to_output(); +// BIF_redraw_render_rect(); +// } break; case B_SET_EDGE: G.scene->r.mode &= ~R_ZBLUR; @@ -815,6 +819,13 @@ void do_render_panels(unsigned short event) G.scene->r.mode &= ~R_EDGE; allqueue(REDRAWBUTSSCENE, 0); break; + case B_ADD_RENDERLAYER: + if(G.scene->r.actlay==32767) { + scene_add_render_layer(G.scene); + G.scene->r.actlay= BLI_countlist(&G.scene->r.layers) - 1; + } + allqueue(REDRAWBUTSSCENE, 0); + allqueue(REDRAWNODE, 0); } } @@ -957,7 +968,7 @@ static char *imagetype_pup(void) char formatstring[1024]; char appendstring[1024]; - strcpy(formatstring, "Save image as: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d"); + strcpy(formatstring, "Save image as: %%t|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d|%s %%x%d"); #ifdef __sgi strcat(formatstring, "|%s %%x%d"); // add space for Movie @@ -994,11 +1005,10 @@ static char *imagetype_pup(void) "HamX", R_HAMX, "Iris", R_IRIS, "Iris + Zbuffer", R_IRIZ, - "Radiance HDR", R_RADHDR, + "Radiance HDR", R_RADHDR #ifdef __sgi - "Movie", R_MOVIE, + ,"Movie", R_MOVIE #endif - "Ftype", R_FTYPE ); } else { sprintf(string, formatstring, @@ -1015,14 +1025,19 @@ static char *imagetype_pup(void) "HamX", R_HAMX, "Iris", R_IRIS, "Iris + Zbuffer", R_IRIZ, - "Radiance HDR", R_RADHDR, + "Radiance HDR", R_RADHDR #ifdef __sgi - "Movie", R_MOVIE, + ,"Movie", R_MOVIE #endif - "Ftype", R_FTYPE ); } +#ifdef WITH_OPENEXR + strcpy(formatstring, "|%s %%x%d"); + sprintf(appendstring, formatstring, "OpenEXR", R_OPENEXR); + strcat(string, appendstring); +#endif + if (G.have_libtiff) { strcpy(formatstring, "|%s %%x%d"); sprintf(appendstring, formatstring, "TIFF", R_TIFF); @@ -1108,10 +1123,10 @@ static void render_panel_output(void) /* postprocess render buttons */ uiBlockBeginAlign(block); - if(R.rectftot) - uiDefIconTextButBitI(block, TOG, R_FBUF, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available"); - else - uiDefButBitI(block, TOG, R_FBUF, 0,"Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now"); +// if(R.rectftot) +// uiDefIconTextButBitI(block, TOG, R_FBUF, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available"); +// else +// uiDefButBitI(block, TOG, R_FBUF, 0,"Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now"); uiDefBlockBut(block, post_render_menu, NULL, "Post process", 170, 68, 140, 20, "Applies on RGBA floats while render or with Fbuf available"); uiBlockEndAlign(block); @@ -1151,8 +1166,8 @@ static void render_panel_render(void) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButS(block, NUM,B_DIFF,"Xparts:", 369,46,95,29,&G.scene->r.xparts,1.0, 64.0, 0, 0, "Sets the number of horizontal parts to render image in (For panorama sets number of camera slices)"); - uiDefButS(block, NUM,B_DIFF,"Yparts:", 465,46,95,29,&G.scene->r.yparts,1.0, 64.0, 0, 0, "Sets the number of vertical parts to render image in"); + uiDefButS(block, NUM,B_DIFF,"Xparts:", 369,46,95,29,&G.scene->r.xparts,2.0, 64.0, 0, 0, "Sets the number of horizontal parts to render image in (For panorama sets number of camera slices)"); + uiDefButS(block, NUM,B_DIFF,"Yparts:", 465,46,95,29,&G.scene->r.yparts,2.0, 64.0, 0, 0, "Sets the number of vertical parts to render image in"); uiBlockEndAlign(block); uiBlockBeginAlign(block); @@ -1207,8 +1222,8 @@ static void render_panel_anim(void) uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, R_DOSEQ, 0, "Do Sequence",692,114,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)"); - uiDefButBitS(block, TOG, R_BG_RENDER, 0, "Render Daemon",692,90,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Let external network render current scene"); + uiDefButBitS(block, TOG, R_DOSEQ, B_NOP, "Do Sequence",692,114,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)"); + uiDefButBitS(block, TOG, R_DOCOMP, B_NOP, "Do Composit",692,90,192,20, &G.scene->r.scemode, 0, 0, 0, 0, "Uses compositing nodes for output rendering"); uiBlockEndAlign(block); uiBlockSetCol(block, TH_AUTO); @@ -1249,12 +1264,13 @@ static void render_panel_format(void) #ifdef __sgi yofs = 76; - uiDefButS(block, NUM,B_DIFF,"MaxSize:", 892,32,165,20, &G.scene->r.maximsize, 0.0, 500.0, 0, 0, "Maximum size per frame to save in an SGI movie"); - uiDefButBitI(block, TOG, R_COSMO, 0,"Cosmo", 1059,32,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Attempt to save SGI movies using Cosmo hardware"); + uiDefButS(block, NUM,B_DIFF,"MaxSize:", 892,32,165,20, &G.scene->r.maximsize, 0.0, 500.0, 0, 0, "Maximum size per frame to save in an SGI movie"); + uiDefButBitI(block, TOG, R_COSMO, 0,"Cosmo", 1059,32,60,20, &G.scene->r.mode, 0, 0, 0, 0, "Attempt to save SGI movies using Cosmo hardware"); #endif + uiDefButS(block, MENU,B_FILETYPEMENU,imagetype_pup(), 892,yofs,174,20, &G.scene->r.imtype, 0, 0, 0, 0, "Images are saved in this file format"); - uiDefButBitI(block, TOG, R_MOVIECROP, B_DIFF, "Crop", 1068,yofs,51,20, &G.scene->r.mode, 0, 0, 0, 0, "Exclude border rendering from total image"); + uiDefButBitI(block, TOG, R_MOVIECROP, B_DIFF, "Crop", 1068,yofs,51,20, &G.scene->r.mode, 0, 0, 0, 0, "Exclude border rendering from total image"); yofs -= 22; @@ -1288,7 +1304,23 @@ static void render_panel_format(void) #endif uiDefBut(block, BUT,B_SELECTCODEC, "Set codec", 892,yofs,112,20, 0, 0, 0, 0, 0, "Set codec settings for AVI"); } +#ifdef WITH_OPENEXR + } + else if (G.scene->r.imtype == R_OPENEXR ) { + if (G.scene->r.quality > 5) G.scene->r.quality = 0; + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, R_OPENEXR_HALF, B_NOP,"Half", 892,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Use 16 bits float 'Half' type"); + uiDefButBitS(block, TOG, R_OPENEXR_ZBUF, B_NOP,"Zbuf", 952,yofs+44,60,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save the zbuffer as 32 bits unsigned int"); + uiBlockEndAlign(block); + + uiDefButS(block, MENU,B_NOP, "Codec %t|None %x0|Pxr24 (lossy) %x1|ZIP (lossless) %x2|PIZ (lossless) %x3|RLE (lossless) %x4", + 892,yofs,112,20, &G.scene->r.quality, 0, 0, 0, 0, "Set codec settings for OpenEXR"); + +#endif } else { + if(G.scene->r.quality < 5) G.scene->r.quality = 90; /* restore from openexr */ + uiDefButS(block, NUM,B_DIFF, "Quality:", 892,yofs,112,20, &G.scene->r.quality, 10.0, 100.0, 0, 0, "Quality setting for JPEG images, AVI Jpeg and SGI movies"); } uiDefButS(block, NUM,B_FRAMEMAP,"Frs/sec:", 1006,yofs,113,20, &G.scene->r.frs_sec, 1.0, 120.0, 100.0, 0, "Frames per second"); @@ -1453,12 +1485,152 @@ static void render_panel_sfx(void) } #endif +static void layer_copy_func(void *lay_v, void *lay_p) +{ + unsigned int *lay= lay_p; + int laybit= (int)lay_v; + + if(G.qual & LR_SHIFTKEY) { + if(*lay==0) *lay= 1<r.layers)>1) { + BLI_remlink(&G.scene->r.layers, srl_v); + MEM_freeN(srl_v); + G.scene->r.actlay= 0; + + allqueue(REDRAWBUTSSCENE, 0); + allqueue(REDRAWNODE, 0); + } +} + +static void rename_scene_layer_func(void *srl_v, void *unused_v) +{ + if(G.scene->nodetree) { + SceneRenderLayer *srl= srl_v; + bNode *node; + for(node= G.scene->nodetree->nodes.first; node; node= node->next) { + if(node->type==CMP_NODE_R_RESULT) { + if(node->custom1==G.scene->r.actlay) + BLI_strncpy(node->name, srl->name, NODE_MAXSTR); + } + } + } + allqueue(REDRAWNODE, 0); +} + +static char *scene_layer_menu(void) +{ + SceneRenderLayer *srl; + int len= 32 + 32*BLI_countlist(&G.scene->r.layers); + short a, nr; + char *str= MEM_callocN(len, "menu layers"); + + strcpy(str, "ADD NEW %x32767"); + a= strlen(str); + for(nr=0, srl= G.scene->r.layers.first; srl; srl= srl->next, nr++) { + a+= sprintf(str+a, "|%s %%x%d", srl->name, nr); + } + + return str; +} + +static void draw_3d_layer_buttons(uiBlock *block, unsigned int *poin, short xco, short yco, short dx, short dy, int event) +{ + uiBut *bt; + long a; + + uiBlockBeginAlign(block); + for(a=0; a<5; a++) { + bt= uiDefButBitI(block, TOG, 1<r.layers, G.scene->r.actlay); + char *strp; + + block= uiNewBlock(&curarea->uiblocks, "render_panel_layers", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Output", "Render"); + if(uiNewPanel(curarea, block, "Render Layers", "Render", 320, 0, 318, 204)==0) return; + + /* first, as reminder, the scene layers */ + uiDefBut(block, LABEL, 0, "Scene:", 10,170,100,20, NULL, 0, 0, 0, 0, ""); + + draw_3d_layer_buttons(block, &G.scene->lay, 130, 170, 35, 30, B_LAY); + + /* layer menu, name, delete button */ + uiBlockBeginAlign(block); + strp= scene_layer_menu(); + uiDefButS(block, MENU, B_ADD_RENDERLAYER, strp, 10,130,23,20, &(G.scene->r.actlay), 0, 0, 0, 0, "Choose Active Render Layer"); + MEM_freeN(strp); + + bt= uiDefBut(block, TEX, REDRAWNODE, "", 33,130,252,20, srl->name, 0.0, 31.0, 0, 0, ""); + uiButSetFunc(bt, rename_scene_layer_func, srl, NULL); + bt=uiDefIconBut(block, BUT, B_NOP, ICON_X, 285, 130, 25, 20, 0, 0, 0, 0, 0, "Deletes current Render Layer"); + uiButSetFunc(bt, delete_scene_layer_func, srl, NULL); + uiBlockEndAlign(block); + + /* RenderLayer visible-layers */ + uiDefBut(block, LABEL, 0, "Layer:", 10,95,100,20, NULL, 0, 0, 0, 0, ""); + draw_3d_layer_buttons(block, &srl->lay, 130, 95, 35, 30, B_NOP); + + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, SCE_LAY_SOLID, B_NOP,"Solid", 10, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Solid faces in this Layer"); + uiDefButBitS(block, TOG, SCE_LAY_ZTRA, B_NOP,"Ztra", 85, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Z-Transparent faces in this Layer"); + uiDefButBitS(block, TOG, SCE_LAY_HALO, B_NOP,"Halo", 160, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Halos in this Layer"); + uiDefButBitS(block, TOG, SCE_LAY_STRAND, B_NOP,"Strand", 235, 70, 75, 20, &srl->layflag, 0, 0, 0, 0, "Render Particle Strands in this Layer"); + uiBlockEndAlign(block); + + uiDefBut(block, LABEL, 0, "Passes:", 10,30,150,20, NULL, 0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, SCE_PASS_COMBINED, B_NOP,"Combined", 130, 30, 155, 20, &srl->passflag, 0, 0, 0, 0, "Deliver full combined RGBA buffer"); + uiDefButBitS(block, TOG, SCE_PASS_Z, B_NOP,"Z", 285, 30, 25, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Z values pass"); + + uiDefButBitS(block, TOG, SCE_PASS_DIFFUSE, B_NOP,"Diff",10, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_SPEC, B_NOP,"Spec", 55, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_SHADOW, B_NOP,"Shad", 100, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_AO, B_NOP,"AO", 145, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_MIRROR, B_NOP,"Mirr", 185, 10, 45, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_NORMAL, B_NOP,"Nor", 230, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); + uiDefButBitS(block, TOG, SCE_PASS_VECTOR, B_NOP,"Vec", 270, 10, 40, 20, &srl->passflag, 0, 0, 0, 0, "Deliver Diffuse pass"); +} void render_panels() { render_panel_output(); // render_panel_sfx(); + render_panel_layers(); render_panel_render(); render_panel_anim(); render_panel_format(); diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 15a80f5d0f8..a34d9d8406e 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -49,6 +49,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" +#include "DNA_node_types.h" #include "DNA_packedFile_types.h" #include "DNA_radio_types.h" #include "DNA_screen_types.h" @@ -64,6 +65,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_material.h" #include "BKE_utildefines.h" #include "BKE_texture.h" @@ -77,6 +79,7 @@ #include "BSE_filesel.h" #include "BSE_headerbuttons.h" +#include "BSE_node.h" #include "BIF_gl.h" #include "BIF_graphics.h" @@ -98,7 +101,6 @@ #include "mydevice.h" #include "blendef.h" #include "radio.h" -#include "render.h" /* -----includes for this file specific----- */ @@ -107,16 +109,12 @@ /* ---------function prototypes ------------- */ void load_tex_image(char *); void load_plugin_tex(char *); -int vergcband(const void *, const void *); + void save_env(char *); -void drawcolorband(ColorBand *, float , float , float , float ); - -static MTex mtexcopybuf; static MTex emptytex; static int packdummy = 0; - static char *mapto_blendtype_pup(void) { static char string[1024]; @@ -216,7 +214,7 @@ void load_tex_image(char *str) /* called from fileselect */ BIF_undo_push("Load image"); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } } @@ -233,20 +231,9 @@ void load_plugin_tex(char *str) /* called from fileselect */ tex->plugin= add_plugin_tex(str); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } -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; -} - - - void save_env(char *name) { Tex *tex; @@ -267,273 +254,18 @@ void save_env(char *name) } -void drawcolorband(ColorBand *coba, float x1, float y1, float sizex, float sizey) +static int vergcband(const void *a1, const void *a2) { - CBData *cbd; - float dx, v3[2], v1[2], v2[2]; - int a; + const CBData *x1=a1, *x2=a2; - if(coba==NULL) return; - - /* first background, to show tranparency */ - dx= sizex/12.0; - v1[0]= x1; - for(a=0; a<12; a++) { - if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8); - glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey); - if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3); - glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey); - v1[0]+= dx; - } - - glShadeModel(GL_SMOOTH); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - cbd= coba->data; - - v1[0]= v2[0]= x1; - v1[1]= y1; - v2[1]= y1+sizey; - - glBegin(GL_QUAD_STRIP); - - glColor4fv( &cbd->r ); - glVertex2fv(v1); glVertex2fv(v2); - - for(a=0; atot; a++, cbd++) { - - v1[0]=v2[0]= x1+ cbd->pos*sizex; - - glColor4fv( &cbd->r ); - glVertex2fv(v1); glVertex2fv(v2); - } - - v1[0]=v2[0]= x1+ sizex; - glVertex2fv(v1); glVertex2fv(v2); - - glEnd(); - glShadeModel(GL_FLAT); - glDisable(GL_BLEND); - - /* outline */ - v1[0]= x1; v1[1]= y1; - - cpack(0x0); - glBegin(GL_LINE_LOOP); - glVertex2fv(v1); - v1[0]+= sizex; - glVertex2fv(v1); - v1[1]+= sizey; - glVertex2fv(v1); - v1[0]-= sizex; - glVertex2fv(v1); - glEnd(); - - - /* help lines */ - - v1[0]= v2[0]=v3[0]= x1; - v1[1]= y1; - v2[1]= y1+0.5*sizey; - v3[1]= y1+sizey; - - cbd= coba->data; - glBegin(GL_LINES); - for(a=0; atot; a++, cbd++) { - v1[0]=v2[0]=v3[0]= x1+ cbd->pos*sizex; - - glColor3ub(0, 0, 0); - glVertex2fv(v1); - glVertex2fv(v2); - - if(a==coba->cur) { - glVertex2f(v1[0]-1, v1[1]); - glVertex2f(v2[0]-1, v2[1]); - glVertex2f(v1[0]+1, v1[1]); - glVertex2f(v2[0]+1, v2[1]); - } - - glColor3ub(255, 255, 255); - glVertex2fv(v2); - glVertex2fv(v3); - - if(a==coba->cur) { - if(cbd->pos>0.01) { - glVertex2f(v2[0]-1, v2[1]); - glVertex2f(v3[0]-1, v3[1]); - } - if(cbd->pos<0.99) { - glVertex2f(v2[0]+1, v2[1]); - glVertex2f(v3[0]+1, v3[1]); - } - } - } - glEnd(); - - - glFlush(); -} - -static void drawcolorband_cb(void) -{ - ID *id, *idfrom; - - buttons_active_id(&id, &idfrom); - if( GS(id->name)==ID_TE) { - Tex *tex= (Tex *)id; - drawcolorband(tex->coba, 10,145,300,30); - } - else if( GS(id->name)==ID_MA) { - Material *ma= (Material *)id; - if(ma->ramp_show==0) - drawcolorband(ma->ramp_col, 10,110,300,30); - else - drawcolorband(ma->ramp_spec, 10,110,300,30); - } -} - -static void do_colorbandbuts(ColorBand *coba, unsigned short event) -{ - int a; - - if(coba==NULL) return; - - switch(event) { - case B_ADDCOLORBAND: - - if(coba->tot < MAXCOLORBAND-1) coba->tot++; - coba->cur= coba->tot-1; - - do_colorbandbuts(coba, B_CALCCBAND); - BIF_undo_push("Add colorband"); - - break; - - case B_DELCOLORBAND: - 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--; - - BIF_undo_push("Delete colorband"); - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); - break; - - case B_CALCCBAND: - case B_CALCCBAND2: - 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) { - if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ - coba->cur= a; - break; - } - } - if(event==B_CALCCBAND2) return; - - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); - - break; - - case B_DOCOLORBAND: - - break; - } -} - -/* callback for label button... the size of the button (300) still hardcoded! */ -static void do_colorband_cb(void *namev, void *arg2_unused) -{ - ColorBand *coba= namev; - CBData *cbd; - uiBlock *block; - float dx; - int a; - short mval[2], mvalo[2]; - - /* weak; find panel where colorband is */ - block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Colors"); - if(block==NULL) block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Ramps"); - - if(coba && block) { - int mindist= 12, xco; - uiGetMouse(mywinget(), mvalo); - - if(G.qual & LR_CTRLKEY) { - /* insert new key on mouse location */ - if(coba->tot < MAXCOLORBAND-1) { - float pos= ((float)(mvalo[0] - 12))/300.0f; - float col[4]; - - do_colorband(coba, pos, col); - - coba->tot++; - coba->cur= coba->tot-1; - - coba->data[coba->cur].r= col[0]; - coba->data[coba->cur].g= col[1]; - coba->data[coba->cur].b= col[2]; - coba->data[coba->cur].a= col[3]; - coba->data[coba->cur].pos= pos; - - do_colorbandbuts(coba, B_CALCCBAND); - BIF_undo_push("Add colorband"); - } - } - else { - - /* first, activate new key when mouse is close */ - for(a=0, cbd= coba->data; atot; a++, cbd++) { - xco= 12 + (cbd->pos*300.0); - xco= ABS(xco-mvalo[0]); - if(a==coba->cur) xco+= 5; // selected one disadvantage - if(xcocur= a; - mindist= xco; - } - } - - cbd= coba->data + coba->cur; - - while(get_mbut() & L_MOUSE) { - uiGetMouse(mywinget(), mval); - if(mval[0]!=mvalo[0]) { - dx= mval[0]-mvalo[0]; - dx/= 300.0; - cbd->pos+= dx; - CLAMP(cbd->pos, 0.0, 1.0); - - glDrawBuffer(GL_FRONT); - drawcolorband_cb(); - glDrawBuffer(GL_BACK); - - do_colorbandbuts(coba, B_CALCCBAND2); - cbd= coba->data + coba->cur; /* because qsort */ - - mvalo[0]= mval[0]; - } - BIF_wait_for_statechange(); - } - } - allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); - shade_buttons_change_3d(); - } + if( x1->pos > x2->pos ) return 1; + else if( x1->pos < x2->pos) return -1; + return 0; } void do_texbuts(unsigned short event) { Tex *tex; - Material *ma; ImBuf *ibuf; ScrArea *sa; ID *id; @@ -545,21 +277,21 @@ void do_texbuts(unsigned short event) switch(event) { case B_TEXCHANNEL: scrarea_queue_headredraw(curarea); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); allqueue(REDRAWBUTSSHADING, 0); break; case B_TEXTYPE: if(tex==0) return; tex->stype= 0; allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); break; case B_DEFTEXVAR: if(tex==0) return; default_tex(tex); BIF_undo_push("Default texture vars"); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); break; case B_LOADTEXIMA: if(tex==0) return; @@ -600,12 +332,9 @@ void do_texbuts(unsigned short event) load_tex_image(str); } break; - case B_TEXPRV: - BIF_all_preview_changed(); - break; case B_TEXREDR_PRV: allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); shade_buttons_change_3d(); break; case B_TEXIMABROWSE: @@ -624,7 +353,7 @@ void do_texbuts(unsigned short event) BIF_undo_push("Browse image"); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } } } @@ -646,7 +375,7 @@ void do_texbuts(unsigned short event) IMB_freeImBuf(ibuf); tex->ima->ibuf= 0; tex->ima->ok= 1; - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } } } @@ -671,11 +400,11 @@ void do_texbuts(unsigned short event) tex->ima->ok= 1; if(tex->env) - RE_free_envmapdata(tex->env); + BKE_free_envmapdata(tex->env); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWIMAGE, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } allqueue(REDRAWBUTSSHADING, 0); // redraw buttons @@ -685,7 +414,7 @@ void do_texbuts(unsigned short event) tex->ima->id.us--; tex->ima= NULL; allqueue(REDRAWBUTSSHADING, 0); // redraw buttons - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } break; case B_TEXSETFRAMES: @@ -740,49 +469,29 @@ void do_texbuts(unsigned short event) tex->stype= 0; tex->plugin= add_plugin_tex(str); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); break; case B_COLORBAND: if(tex==0) return; - if(tex->coba==0) tex->coba= add_colorband(); + if(tex->coba==0) tex->coba= add_colorband(0); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); // also ramps, so we do this + BIF_preview_changed(ID_TE); // also ramps, so we do this break; - case B_ADDCOLORBAND: - case B_DELCOLORBAND: - case B_CALCCBAND: - case B_CALCCBAND2: - case B_DOCOLORBAND: - /* these events can be called from material subcontext too */ - id= G.buts->lockpoin; - if(id) { - if( GS(id->name)==ID_TE) { - tex= (Tex *)id; - do_colorbandbuts(tex->coba, event); - } - else { - ma= (Material *)id; - if(ma->ramp_show==0) do_colorbandbuts(ma->ramp_col, event); - else do_colorbandbuts(ma->ramp_spec, event); - } - } - break; - case B_ENV_DELETE: if(tex->env) { - RE_free_envmap(tex->env); + BKE_free_envmap(tex->env); tex->env= 0; allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } break; case B_ENV_FREE: if(tex->env) { - RE_free_envmapdata(tex->env); + BKE_free_envmapdata(tex->env); allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); } break; case B_ENV_FREE_ALL: @@ -790,13 +499,13 @@ void do_texbuts(unsigned short event) while(tex) { if(tex->id.us && tex->type==TEX_ENVMAP) { if(tex->env) { - if(tex->env->stype!=ENV_LOAD) RE_free_envmapdata(tex->env); + if(tex->env->stype!=ENV_LOAD) BKE_free_envmapdata(tex->env); } } tex= tex->id.next; } allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); break; case B_ENV_SAVE: if(tex->env && tex->env->ok) { @@ -808,7 +517,7 @@ void do_texbuts(unsigned short event) break; case B_ENV_OB: if(tex->env && tex->env->object) { - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); if ELEM(tex->env->object->type, OB_CAMERA, OB_LAMP) { error("Camera or Lamp not allowed"); tex->env->object= NULL; @@ -821,7 +530,7 @@ void do_texbuts(unsigned short event) PluginTex *pit= tex->plugin; if(pit && pit->callback) { pit->callback(event - B_PLUGBUT); - BIF_all_preview_changed(); + BIF_preview_changed(ID_TE); allqueue(REDRAWBUTSSHADING, 0); } } @@ -1147,7 +856,7 @@ static void texture_panel_envmap(Tex *tex) uiSetButLock(tex->id.lib!=0, "Can't edit library data"); if(tex->env==NULL) { - tex->env= RE_add_envmap(); + tex->env= BKE_add_envmap(); tex->env->object= OBACT; } if(tex->env) { @@ -1352,39 +1061,113 @@ static void texture_panel_image(Tex *tex) } -static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int offs, int redraw) +static void colorband_pos_cb(void *coba_v, void *unused_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) { + if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ + coba->cur= a; + break; + } + } +} + +static void colorband_add_cb(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(coba, NULL); + BIF_undo_push("Add colorband"); + +} + +static void colorband_del_cb(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(coba->cur) coba->cur--; + coba->tot--; + + BIF_undo_push("Delete colorband"); + BIF_preview_changed(ID_TE); +} + + +/* offset aligns from bottom, standard width 300, height 115 */ +static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int xoffs, int yoffs, int redraw) { CBData *cbd; uiBut *bt; - + if(coba==NULL) return; - uiDefBut(block, BUT, B_ADDCOLORBAND, "Add", 90,180+offs,37,20, 0, 0, 0, 0, 0, "Adds a new colour position to the colorband"); - uiDefButS(block, NUM, B_REDR, "Cur:", 127,180+offs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active colour from the colorband"); - uiDefBut(block, BUT, B_DELCOLORBAND, "Del", 209,180+offs,37,20, 0, 0, 0, 0, 0, "Deletes the active position"); - uiDefButS(block, ROW, redraw, "E", 246,180+offs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); - uiDefButS(block, ROW, B_TEXREDR_PRV, "C", 262,180+offs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); - uiDefButS(block, ROW, B_TEXREDR_PRV, "L", 278,180+offs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); - uiDefButS(block, ROW, B_TEXREDR_PRV, "S", 294,180+offs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + bt= uiDefBut(block, BUT, redraw, "Add", 80+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Adds a new colour position to the colorband"); + uiButSetFunc(bt, colorband_add_cb, coba, NULL); + uiDefButS(block, NUM, redraw, "Cur:", 117+xoffs,95+yoffs,81,20, &coba->cur, 0.0, (float)(coba->tot-1), 0, 0, "Displays the active colour from the colorband"); + bt= uiDefBut(block, BUT, redraw, "Del", 199+xoffs,95+yoffs,37,20, 0, 0, 0, 0, 0, "Deletes the active position"); + uiButSetFunc(bt, colorband_del_cb, coba, NULL); + uiDefButS(block, ROW, redraw, "E", 236+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); + uiDefButS(block, ROW, redraw, "C", 252+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); + uiDefButS(block, ROW, redraw, "L", 268+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); + uiDefButS(block, ROW, redraw, "S", 284+xoffs,95+yoffs,16,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); - bt=uiDefBut(block, LABEL, B_DOCOLORBAND, "", 10,150+offs,300,30, 0, 0, 0, 0, 0, "Colorband"); /* only for event! */ - uiButSetFunc(bt, do_colorband_cb, coba, NULL); - - uiBlockSetDrawExtraFunc(block, drawcolorband_cb); + uiDefBut(block, BUT_COLORBAND, redraw, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, ""); + cbd= coba->data + coba->cur; uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_CALCCBAND, "Pos", 10,125+offs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour"); - uiDefButF(block, COL, B_TEXREDR_PRV, "", 10,105+offs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "A ", 10,85+offs,110,20, &cbd->a, 0.0, 1.0, 0, 0, "Sets the alpha value for this position"); + bt= uiDefButF(block, NUM, redraw, "Pos", xoffs,40+yoffs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour"); + uiButSetFunc(bt, colorband_pos_cb, coba, NULL); + uiDefButF(block, COL, redraw, "", xoffs,20+yoffs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); + uiDefButF(block, NUMSLI, redraw, "A ", xoffs,yoffs,110,20, &cbd->a, 0.0, 1.0, 10, 0, "Sets the alpha value for this position"); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "R ", 125,125+offs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active colour"); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "G ", 125,105+offs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active colour"); - uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "B ", 125,85+offs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active colour"); + uiDefButF(block, NUMSLI, redraw, "R ", 115+xoffs,40+yoffs,185,20, &cbd->r, 0.0, 1.0, B_BANDCOL, 0, "Sets the red value for the active colour"); + uiDefButF(block, NUMSLI, redraw, "G ", 115+xoffs,20+yoffs,185,20, &cbd->g, 0.0, 1.0, B_BANDCOL, 0, "Sets the green value for the active colour"); + uiDefButF(block, NUMSLI, redraw, "B ", 115+xoffs,yoffs,185,20, &cbd->b, 0.0, 1.0, B_BANDCOL, 0, "Sets the blue value for the active colour"); uiBlockEndAlign(block); } +void draw_colorband_buts_small(uiBlock *block, ColorBand *coba, rctf *butr, int event) +{ + CBData *cbd; + uiBut *bt; + float unit= (butr->xmax-butr->xmin)/12.0f; + float xs= butr->xmin; + + cbd= coba->data + coba->cur; + + uiBlockBeginAlign(block); + uiDefButF(block, COL, event, "", xs,butr->ymin+20.0f,2.0f*unit,20, &(cbd->r), 0, 0, 0, B_BANDCOL, ""); + uiDefButF(block, NUM, event, "A:", xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20, &(cbd->a), 0.0f, 1.0f, 10, 2, ""); + bt= uiDefBut(block, BUT, event, "Del", xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Deletes the active position"); + uiButSetFunc(bt, colorband_del_cb, coba, NULL); + uiDefButS(block, ROW, event, "E", xs+8.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 1.0, 0, 0, "Sets interpolation type 'Ease' (quadratic) "); + uiDefButS(block, ROW, event, "C", xs+9.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 3.0, 0, 0, "Sets interpolation type Cardinal"); + uiDefButS(block, ROW, event, "L", xs+10.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 0.0, 0, 0, "Sets interpolation type Linear"); + uiDefButS(block, ROW, event, "S", xs+11.0f*unit,butr->ymin+20.0f,unit,20, &coba->ipotype, 5.0, 2.0, 0, 0, "Sets interpolation type B-Spline"); + + uiDefBut(block, BUT_COLORBAND, event, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, ""); + uiBlockEndAlign(block); + +} + static void texture_panel_colors(Tex *tex) { uiBlock *block; @@ -1399,7 +1182,7 @@ static void texture_panel_colors(Tex *tex) uiDefButBitS(block, TOG, TEX_COLORBAND, B_COLORBAND, "Colorband",10,180,80,20, &tex->flag, 0, 0, 0, 0, "Toggles colorband operations"); if(tex->flag & TEX_COLORBAND) { - draw_colorband_buts(block, tex->coba, 0, B_TEXREDR_PRV); + draw_colorband_buts(block, tex->coba, 10, 85, B_TEXREDR_PRV); } /* RGB-BRICON */ @@ -1416,11 +1199,11 @@ static void texture_panel_colors(Tex *tex) } -static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la) +static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *la, bNode *node) { MTex *mt=NULL; uiBlock *block; - ID *id, *idfrom; + ID *id=NULL, *idfrom; int a, yco, loos; char str[32]; @@ -1429,56 +1212,68 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l if(uiNewPanel(curarea, block, "Texture", "Texture", 320, 0, 318, 204)==0) return; /* first do the browse but */ - buttons_active_id(&id, &idfrom); - + if(mtex) + id= (ID *)mtex->tex; + else if(node) + id= node->id; + + if(ma) idfrom= &ma->id; + else if(wrld) idfrom= &wrld->id; + else if(la) idfrom= &la->id; + else idfrom= NULL; + uiBlockSetCol(block, TH_BUT_SETTING2); if(ma) { - std_libbuttons(block, 10, 180, 0, NULL, B_TEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); + std_libbuttons(block, 10, 180, 0, NULL, B_TEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); } else if(wrld) { - std_libbuttons(block, 10, 180, 0, NULL, B_WTEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); + std_libbuttons(block, 10, 180, 0, NULL, B_WTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); } else if(la) { - std_libbuttons(block, 10, 180, 0, NULL, B_LTEXBROWSE, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); + std_libbuttons(block, 10, 180, 0, NULL, B_LTEXBROWSE, ID_TE, 0, id, idfrom, &(G.buts->texnr), B_TEXALONE, B_TEXLOCAL, B_TEXDELETE, B_AUTOTEXNAME, B_KEEPDATA); + } + else if(node) { + } uiBlockSetCol(block, TH_BUT_NEUTRAL); /* From button: removed */ /* CHANNELS */ - uiBlockBeginAlign(block); - yco= 150; - for(a= 0; amtex[a]; - else if(wrld) mt= wrld->mtex[a]; - else if(la) mt= la->mtex[a]; - - if(mt && mt->tex) splitIDname(mt->tex->id.name+2, str, &loos); - else strcpy(str, ""); - str[14]= 0; + if(node==NULL) { + uiBlockBeginAlign(block); + yco= 150; + for(a= 0; amtex[a]; + else if(wrld) mt= wrld->mtex[a]; + else if(la) mt= la->mtex[a]; + + if(mt && mt->tex) splitIDname(mt->tex->id.name+2, str, &loos); + else strcpy(str, ""); + str[14]= 0; - if(ma) { - uiDefButC(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(ma->texact), 0.0, (float)a, 0, 0, "Click to select texture channel"); - yco-= 20; + if(ma) { + uiDefButC(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(ma->texact), 0.0, (float)a, 0, 0, "Click to select texture channel"); + yco-= 20; + } + else if(wrld) { + uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(wrld->texact), 0.0, (float)a, 0, 0, ""); + yco-= 20; + } + else if(la) { + uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(la->texact), 0.0, (float)a, 0, 0, ""); + yco-= 20; + } } - else if(wrld) { - uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(wrld->texact), 0.0, (float)a, 0, 0, ""); - yco-= 20; - } - else if(la) { - uiDefButS(block, ROW, B_TEXCHANNEL, str, 10,yco,140,19, &(la->texact), 0.0, (float)a, 0, 0, ""); - yco-= 20; - } - } - uiBlockEndAlign(block); - + uiBlockEndAlign(block); + } uiBlockSetCol(block, TH_AUTO); /* TYPES */ - if(mtex && mtex->tex) { + if(id) { char textypes[512]; - Tex *tex= mtex->tex; + Tex *tex= (Tex *)id; uiSetButLock(tex->id.lib!=0, "Can't edit library data"); @@ -1594,7 +1389,7 @@ void do_radiobuts(unsigned short event) case B_RAD_FAC: set_radglobal(); if(phase & RAD_PHASE_FACES) make_face_tab(); - else make_node_display(); + else make_node_display(); /* radio solver also uses nodes, different ones :) */ allqueue(REDRAWVIEW3D, 0); break; case B_RAD_NODELIM: @@ -1730,6 +1525,8 @@ static void radio_panel_render(Radio *rad) void do_worldbuts(unsigned short event) { + static short mtexcopied=0; + static MTex mtexcopybuf; World *wrld; MTex *mtex; @@ -1744,7 +1541,36 @@ void do_worldbuts(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWOOPS, 0); BIF_undo_push("Unlink world texture"); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_WO); + } + break; + case B_WMTEXCOPY: + wrld= G.buts->lockpoin; + if(wrld && wrld->mtex[(int)wrld->texact] ) { + mtex= wrld->mtex[(int)wrld->texact]; + if(mtex->tex==0) { + error("No texture available"); + } + else { + memcpy(&mtexcopybuf, wrld->mtex[(int)wrld->texact], sizeof(MTex)); + mtexcopied= 1; + } + } + break; + case B_WMTEXPASTE: + wrld= G.buts->lockpoin; + if(wrld && mtexcopied && mtexcopybuf.tex) { + if(wrld->mtex[(int)wrld->texact]==0 ) + wrld->mtex[(int)wrld->texact]= MEM_mallocN(sizeof(MTex), "mtex"); + else if(wrld->mtex[(int)wrld->texact]->tex) + wrld->mtex[(int)wrld->texact]->tex->id.us--; + + memcpy(wrld->mtex[(int)wrld->texact], &mtexcopybuf, sizeof(MTex)); + + id_us_plus((ID *)mtexcopybuf.tex); + BIF_undo_push("Paste mapping settings"); + BIF_preview_changed(ID_WO); + scrarea_queue_winredraw(curarea); } break; } @@ -1770,35 +1596,35 @@ static void world_panel_mapto(World *wrld) /* TEXTURE OUTPUT */ uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, MTEX_STENCIL, B_MATPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode"); - uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_MATPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect"); - uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_MATPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values"); + uiDefButBitS(block, TOG, MTEX_STENCIL, B_WORLDPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode"); + uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_WORLDPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect"); + uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_WORLDPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); - uiDefButF(block, NUMSLI, B_MATPRV, "R ", 10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); - uiDefButF(block, NUMSLI, B_MATPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); - uiDefButF(block, NUMSLI, B_MATPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, COL, B_WORLDPRV, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); + uiDefButF(block, NUMSLI, B_WORLDPRV, "R ", 10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); uiBlockEndAlign(block); - uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value for textures to mix with values (not RGB)"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value for textures to mix with values (not RGB)"); /* MAP TO */ uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, WOMAP_BLEND, B_MATPRV, "Blend", 10,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour progression of the background"); - uiDefButBitS(block, TOG, WOMAP_HORIZ, B_MATPRV, "Hori", 85,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the horizon"); - uiDefButBitS(block, TOG, WOMAP_ZENUP, B_MATPRV, "ZenUp", 160,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith above"); - uiDefButBitS(block, TOG, WOMAP_ZENDOWN, B_MATPRV, "ZenDo", 235,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith below"); + uiDefButBitS(block, TOG, WOMAP_BLEND, B_WORLDPRV, "Blend", 10,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour progression of the background"); + uiDefButBitS(block, TOG, WOMAP_HORIZ, B_WORLDPRV, "Hori", 85,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the horizon"); + uiDefButBitS(block, TOG, WOMAP_ZENUP, B_WORLDPRV, "ZenUp", 160,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith above"); + uiDefButBitS(block, TOG, WOMAP_ZENDOWN, B_WORLDPRV, "ZenDo", 235,180,75,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the colour of the zenith below"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButS(block, MENU, B_MATPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode"); + uiDefButS(block, MENU, B_WORLDPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values"); - uiDefButF(block, NUMSLI, B_MATPRV, "Nor ", 155,80,155,19, &(mtex->norfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects normal values"); - uiDefButF(block, NUMSLI, B_MATPRV, "Var ", 155,60,155,19, &(mtex->varfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects other values"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "Col ", 155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "Nor ", 155,80,155,19, &(mtex->norfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects normal values"); + uiDefButF(block, NUMSLI, B_WORLDPRV, "Var ", 155,60,155,19, &(mtex->varfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects other values"); } @@ -1845,7 +1671,7 @@ static void world_panel_texture(World *wrld) uiDefBut(block, TEX, B_IDNAME, "TE:", 100,160,200,19, id->name+2, 0.0, 18.0, 0, 0, "Displays name of the texture block: click to change"); sprintf(str, "%d", id->us); uiDefBut(block, BUT, 0, str, 196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user"); - uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 279,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture"); + uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 220,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture"); if(id->lib) { if(wrld->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, ""); else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, ""); @@ -1858,24 +1684,31 @@ static void world_panel_texture(World *wrld) uiBlockSetCol(block, TH_AUTO); - + /* copy/paste */ + uiBlockBeginAlign(block); + uiDefIconBut(block, BUT, B_WMTEXCOPY, ICON_COPYUP, 250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer"); + uiDefIconBut(block, BUT, B_WMTEXPASTE, ICON_PASTEUP,275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer"); + /* TEXCO */ uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_MATPRV, "View", 100,110,45,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses global coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "AngMap", 145,110,55,20, &(mtex->texco), 4.0, (float)TEXCO_ANGMAP, 0, 0, "Uses 360 degree angular coordinates, e.g. for spherical light probes"); - uiDefButS(block, ROW, B_MATPRV, "Sphere", 200,110,55,20, &(mtex->texco), 4.0, (float)TEXCO_H_SPHEREMAP, 0, 0, "For 360 degree panorama sky, spherical mapped, only top half"); - uiDefButS(block, ROW, B_MATPRV, "Tube", 255,110,45,20, &(mtex->texco), 4.0, (float)TEXCO_H_TUBEMAP, 0, 0, "For 360 degree panorama sky, cylindrical mapped, only top half"); - uiDefButS(block, ROW, B_MATPRV, "Object", 100,90,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "", 170,90,130,20, &(mtex->object), ""); + uiDefButS(block, ROW, B_WORLDPRV, "View", 100,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view vector for the texture coordinates"); + uiDefButS(block, ROW, B_WORLDPRV, "Global", 200,110,100,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates (interior mist)"); + + uiDefButS(block, ROW, B_WORLDPRV, "AngMap", 100,90,70,20, &(mtex->texco), 4.0, (float)TEXCO_ANGMAP, 0, 0, "Uses 360 degree angular coordinates, e.g. for spherical light probes"); + uiDefButS(block, ROW, B_WORLDPRV, "Sphere", 170,90,65,20, &(mtex->texco), 4.0, (float)TEXCO_H_SPHEREMAP, 0, 0, "For 360 degree panorama sky, spherical mapped, only top half"); + uiDefButS(block, ROW, B_WORLDPRV, "Tube", 235,90,65,20, &(mtex->texco), 4.0, (float)TEXCO_H_TUBEMAP, 0, 0, "For 360 degree panorama sky, cylindrical mapped, only top half"); + + uiDefButS(block, ROW, B_WORLDPRV, "Object", 100,70,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_WORLDPRV, "", 170,70,130,20, &(mtex->object), ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "dX", 100,50,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate"); - uiDefButF(block, NUM, B_MATPRV, "dY", 100,30,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate"); - uiDefButF(block, NUM, B_MATPRV, "dZ", 100,10,100,19, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate"); + uiDefButF(block, NUM, B_WORLDPRV, "dX", 100,40,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate"); + uiDefButF(block, NUM, B_WORLDPRV, "dY", 100,20,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate"); + uiDefButF(block, NUM, B_WORLDPRV, "dZ", 100, 0,100,19, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "sizeX", 200,50,100,19, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size"); - uiDefButF(block, NUM, B_MATPRV, "sizeY", 200,30,100,19, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size"); - uiDefButF(block, NUM, B_MATPRV, "sizeZ", 200,10,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size"); + uiDefButF(block, NUM, B_WORLDPRV, "sizeX", 200,40,100,19, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size"); + uiDefButF(block, NUM, B_WORLDPRV, "sizeY", 200,20,100,19, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size"); + uiDefButF(block, NUM, B_WORLDPRV, "sizeZ", 200, 0,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size"); } @@ -1981,44 +1814,40 @@ static void world_panel_amb_occ(World *wrld) static void world_panel_world(World *wrld) { uiBlock *block; - ID *id, *idfrom; block= uiNewBlock(&curarea->uiblocks, "world_panel_world", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "World", "World", 320, 0, 318, 204)==0) return; - /* first do the browse but */ - buttons_active_id(&id, &idfrom); - uiBlockSetCol(block, TH_BUT_SETTING2); - std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, id, idfrom, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA); + std_libbuttons(block, 10, 180, 0, NULL, B_WORLDBROWSE, ID_WO, 0, (ID *)wrld, (ID *)G.scene, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA); if(wrld==NULL) return; uiSetButLock(wrld->id.lib!=0, "Can't edit library data"); uiBlockSetCol(block, TH_AUTO); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, ""); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, ""); + uiDefButF(block, COL, B_WORLDPRV, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, ""); + uiDefButF(block, COL, B_WORLDPRV, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI,B_MATPRV,"HoR ", 10,130,145,19, &(wrld->horr), 0.0, 1.0, B_COLHOR,0, "Sets the amount of red colour at the horizon"); - uiDefButF(block, NUMSLI,B_MATPRV,"HoG ", 10,110,145,19, &(wrld->horg), 0.0, 1.0, B_COLHOR,0, "Sets the amount of green colour at the horizon"); - uiDefButF(block, NUMSLI,B_MATPRV,"HoB ", 10,90,145,19, &(wrld->horb), 0.0, 1.0, B_COLHOR,0, "Sets the amount of blue colour at the horizon"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"HoR ", 10,130,145,19, &(wrld->horr), 0.0, 1.0, B_COLHOR,0, "Sets the amount of red colour at the horizon"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"HoG ", 10,110,145,19, &(wrld->horg), 0.0, 1.0, B_COLHOR,0, "Sets the amount of green colour at the horizon"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"HoB ", 10,90,145,19, &(wrld->horb), 0.0, 1.0, B_COLHOR,0, "Sets the amount of blue colour at the horizon"); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI,B_MATPRV,"ZeR ", 160,130,145,19, &(wrld->zenr), 0.0, 1.0, B_COLZEN,0, "Sets the amount of red colour at the zenith"); - uiDefButF(block, NUMSLI,B_MATPRV,"ZeG ", 160,110,145,19, &(wrld->zeng), 0.0, 1.0, B_COLZEN,0, "Sets the amount of green colour at the zenith"); - uiDefButF(block, NUMSLI,B_MATPRV,"ZeB ", 160,90,145,19, &(wrld->zenb), 0.0, 1.0, B_COLZEN,0, "Sets the amount of blue colour at the zenith"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeR ", 160,130,145,19, &(wrld->zenr), 0.0, 1.0, B_COLZEN,0, "Sets the amount of red colour at the zenith"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeG ", 160,110,145,19, &(wrld->zeng), 0.0, 1.0, B_COLZEN,0, "Sets the amount of green colour at the zenith"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"ZeB ", 160,90,145,19, &(wrld->zenb), 0.0, 1.0, B_COLZEN,0, "Sets the amount of blue colour at the zenith"); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI,B_MATPRV,"AmbR ", 10,50,145,19, &(wrld->ambr), 0.0, 1.0 ,0,0, "Sets the amount of red ambient colour"); - uiDefButF(block, NUMSLI,B_MATPRV,"AmbG ", 10,30,145,19, &(wrld->ambg), 0.0, 1.0 ,0,0, "Sets the amount of green ambient colour"); - uiDefButF(block, NUMSLI,B_MATPRV,"AmbB ", 10,10,145,19, &(wrld->ambb), 0.0, 1.0 ,0,0, "Sets the amount of blue ambient colour"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbR ", 10,50,145,19, &(wrld->ambr), 0.0, 1.0 ,0,0, "Sets the amount of red ambient colour"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbG ", 10,30,145,19, &(wrld->ambg), 0.0, 1.0 ,0,0, "Sets the amount of green ambient colour"); + uiDefButF(block, NUMSLI,B_WORLDPRV,"AmbB ", 10,10,145,19, &(wrld->ambb), 0.0, 1.0 ,0,0, "Sets the amount of blue ambient colour"); uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButF(block, NUMSLI,B_MATPRV, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light"); - uiDefButF(block, NUMSLI,B_MATPRV, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0"); + uiDefButF(block, NUMSLI,B_WORLDPRV, "Exp ", 160,30,145,19, &(wrld->exp), 0.0, 1.0, 0, 2, "Sets amount of exponential color correction for light"); + uiDefButF(block, NUMSLI,B_WORLDPRV, "Range ", 160,10,145,19, &(wrld->range), 0.2, 5.0, 0, 2, "Sets the color amount that will be mapped on color 1.0"); } @@ -2041,9 +1870,9 @@ static void world_panel_preview(World *wrld) uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, WO_SKYREAL, B_MATPRV,"Real", 200,175,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with a real horizon"); - uiDefButBitS(block, TOG, WO_SKYBLEND, B_MATPRV,"Blend",200,150,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with natural progression from horizon to zenith"); - uiDefButBitS(block, TOG,WO_SKYPAPER, B_MATPRV,"Paper",200,125,80,25, &wrld->skytype, 0, 0, 0, 0, "Flattens blend or texture coordinates"); + uiDefButBitS(block, TOG, WO_SKYREAL, B_WORLDPRV,"Real", 200,175,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with a real horizon"); + uiDefButBitS(block, TOG, WO_SKYBLEND, B_WORLDPRV,"Blend",200,150,80,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with natural progression from horizon to zenith"); + uiDefButBitS(block, TOG,WO_SKYPAPER, B_WORLDPRV,"Paper",200,125,80,25, &wrld->skytype, 0, 0, 0, 0, "Flattens blend or texture coordinates"); uiBlockEndAlign(block); } @@ -2052,12 +1881,14 @@ static void world_panel_preview(World *wrld) void do_lampbuts(unsigned short event) { + static short mtexcopied=0; + static MTex mtexcopybuf; Lamp *la; MTex *mtex; switch(event) { case B_LAMPREDRAW: - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_LA); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSSHADING, 0); break; @@ -2071,7 +1902,7 @@ void do_lampbuts(unsigned short event) BIF_undo_push("Unlink world texture"); allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_LA); } break; case B_SBUFF: @@ -2095,6 +1926,36 @@ void do_lampbuts(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWVIEW3D, 0); break; + case B_LMTEXCOPY: + la= G.buts->lockpoin; + if(la && la->mtex[(int)la->texact] ) { + mtex= la->mtex[(int)la->texact]; + if(mtex->tex==0) { + error("No texture available"); + } + else { + memcpy(&mtexcopybuf, la->mtex[(int)la->texact], sizeof(MTex)); + mtexcopied= 1; + } + } + break; + case B_LMTEXPASTE: + la= G.buts->lockpoin; + if(la && mtexcopied && mtexcopybuf.tex) { + if(la->mtex[(int)la->texact]==0 ) + la->mtex[(int)la->texact]= MEM_mallocN(sizeof(MTex), "mtex"); + else if(la->mtex[(int)la->texact]->tex) + la->mtex[(int)la->texact]->tex->id.us--; + + memcpy(la->mtex[(int)la->texact], &mtexcopybuf, sizeof(MTex)); + + id_us_plus((ID *)mtexcopybuf.tex); + BIF_undo_push("Paste mapping settings"); + BIF_preview_changed(ID_LA); + scrarea_queue_winredraw(curarea); + } + break; + } if(event) freefastshade(); @@ -2121,27 +1982,27 @@ static void lamp_panel_mapto(Object *ob, Lamp *la) /* TEXTURE OUTPUT */ uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, MTEX_STENCIL, B_MATPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode"); - uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_MATPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect"); - uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_MATPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values"); + uiDefButBitS(block, TOG, MTEX_STENCIL, B_LAMPPRV, "Stencil", 10,125,45,19, &(mtex->texflag), 0, 0, 0, 0, "Sets the texture mapping to stencil mode"); + uiDefButBitS(block, TOG, MTEX_NEGATIVE, B_LAMPPRV, "Neg", 55,125,30,19, &(mtex->texflag), 0, 0, 0, 0, "Inverts the values of the texture to reverse its effect"); + uiDefButBitS(block, TOG, MTEX_RGBTOINT, B_LAMPPRV, "No RGB", 85,125,60,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values"); uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); - uiDefButF(block, NUMSLI, B_MATPRV, "R ", 10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); - uiDefButF(block, NUMSLI, B_MATPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); - uiDefButF(block, NUMSLI, B_MATPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, COL, B_LAMPPRV, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); + uiDefButF(block, NUMSLI, B_LAMPPRV, "R ", 10,80,135,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, NUMSLI, B_LAMPPRV, "G ", 10,60,135,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); + uiDefButF(block, NUMSLI, B_LAMPPRV, "B ", 10,40,135,19, &(mtex->b), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB"); uiBlockEndAlign(block); - uiDefButF(block, NUMSLI, B_MATPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value the textures uses to mix with"); + uiDefButF(block, NUMSLI, B_LAMPPRV, "DVar ", 10,10,135,19, &(mtex->def_var), 0.0, 1.0, 0, 0, "The default value the textures uses to mix with"); /* MAP TO */ - uiDefButBitS(block, TOG, MAP_COL, B_MATPRV, "Col", 10,180,135,19, &(mtex->mapto), 0, 0, 0, 0, "Lets the texture affect the basic colour of the lamp"); + uiDefButBitS(block, TOG, MAP_COL, B_LAMPPRV, "Col", 10,180,135,19, &(mtex->mapto), 0, 0, 0, 0, "Lets the texture affect the basic colour of the lamp"); uiBlockBeginAlign(block); - uiDefButS(block, MENU, B_MATPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode"); + uiDefButS(block, MENU, B_LAMPPRV, mapto_blendtype_pup(),155,125,155,19, &(mtex->blendtype), 0, 0, 0, 0, "Texture blending mode"); uiBlockEndAlign(block); - uiDefButF(block, NUMSLI, B_MATPRV, "Col ", 155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values"); + uiDefButF(block, NUMSLI, B_LAMPPRV, "Col ", 155,100,155,19, &(mtex->colfac), 0.0, 1.0, 0, 0, "Sets the amount the texture affects colour values"); } @@ -2191,7 +2052,7 @@ static void lamp_panel_texture(Object *ob, Lamp *la) uiDefBut(block, TEX, B_IDNAME, "TE:", 100,160,200,19, id->name+2, 0.0, 18.0, 0, 0, "Displays name of the texture block: click to change"); sprintf(str, "%d", id->us); uiDefBut(block, BUT, 0, str, 196,140,21,19, 0, 0, 0, 0, 0, "Displays number of users of texture: click to make single user"); - uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 241,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture"); + uiDefIconBut(block, BUT, B_AUTOTEXNAME, ICON_AUTO, 221,140,21,19, 0, 0, 0, 0, 0, "Auto-assigns name to texture"); if(id->lib) { if(la->id.lib) uiDefIconBut(block, BUT, 0, ICON_DATALIB, 219,140,21,19, 0, 0, 0, 0, 0, ""); else uiDefIconBut(block, BUT, 0, ICON_PARLIB, 219,140,21,19, 0, 0, 0, 0, 0, ""); @@ -2202,22 +2063,27 @@ static void lamp_panel_texture(Object *ob, Lamp *la) else uiDefButS(block, TOG, B_LTEXBROWSE, "Add New" ,100, 160, 200, 19, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock"); + /* copy/paste */ + uiBlockBeginAlign(block); + uiDefIconBut(block, BUT, B_LMTEXCOPY, ICON_COPYUP, 250,140,25,19, 0, 0, 0, 0, 0, "Copies the mapping settings to the buffer"); + uiDefIconBut(block, BUT, B_LMTEXPASTE, ICON_PASTEUP, 275,140,25,19, 0, 0, 0, 0, 0, "Pastes the mapping settings from the buffer"); + /* TEXCO */ uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_MATPRV, "Glob", 100,110,60,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "View", 160,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Object", 230,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "", 100,90,200,20, &(mtex->object), ""); + uiDefButS(block, ROW, B_LAMPPRV, "Glob", 100,110,60,20, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_LAMPPRV, "View", 160,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_VIEW, 0, 0, "Uses view coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_LAMPPRV, "Object", 230,110,70,20, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_LAMPPRV, "", 100,90,200,20, &(mtex->object), ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "dX", 100,50,100,18, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate"); - uiDefButF(block, NUM, B_MATPRV, "dY", 100,30,100,18, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate"); - uiDefButF(block, NUM, B_MATPRV, "dZ", 100,10,100,18, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate"); + uiDefButF(block, NUM, B_LAMPPRV, "dX", 100,50,100,18, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate"); + uiDefButF(block, NUM, B_LAMPPRV, "dY", 100,30,100,18, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate"); + uiDefButF(block, NUM, B_LAMPPRV, "dZ", 100,10,100,18, mtex->ofs+2, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Z coordinate"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "sizeX", 200,50,100,18, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size"); - uiDefButF(block, NUM, B_MATPRV, "sizeY", 200,30,100,18, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size"); - uiDefButF(block, NUM, B_MATPRV, "sizeZ", 200,10,100,18, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size"); + uiDefButF(block, NUM, B_LAMPPRV, "sizeX", 200,50,100,18, mtex->size, -10.0, 10.0, 10, 0, "Sets scaling for the texture's X size"); + uiDefButF(block, NUM, B_LAMPPRV, "sizeY", 200,30,100,18, mtex->size+1, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Y size"); + uiDefButF(block, NUM, B_LAMPPRV, "sizeZ", 200,10,100,18, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size"); uiBlockEndAlign(block); } @@ -2387,7 +2253,6 @@ static void lamp_panel_yafray(Object *ob, Lamp *la) static void lamp_panel_lamp(Object *ob, Lamp *la) { uiBlock *block; - ID *id, *idfrom; float grid= 0.0; short xco; @@ -2399,11 +2264,8 @@ static void lamp_panel_lamp(Object *ob, Lamp *la) uiSetButLock(la->id.lib!=0, "Can't edit library data"); - /* first do the browse but */ - buttons_active_id(&id, &idfrom); - uiBlockSetCol(block, TH_BUT_SETTING2); - xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, id, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0); + xco= std_libbuttons(block, 8, 180, 0, NULL, B_LAMPBROWSE, ID_LA, 0, (ID *)la, (ID *)ob, &(G.buts->menunr), B_LAMPALONE, B_LAMPLOCAL, 0, 0, 0); uiBlockSetCol(block, TH_AUTO); uiDefButF(block, NUM,B_LAMPREDRAW,"Dist:", xco,180,300-xco,20,&la->dist, 0.01, 5000.0*grid, 100, 0, "Sets the distance value at which light intensity is half"); @@ -2424,33 +2286,33 @@ static void lamp_panel_lamp(Object *ob, Lamp *la) } else if ELEM(la->type, LA_LOCAL, LA_SPOT) { uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitS(block, TOG, LA_QUAD, B_MATPRV,"Quad", 10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation"); + uiDefButBitS(block, TOG, LA_QUAD, B_LAMPPRV,"Quad", 10,150,100,19,&la->mode, 0, 0, 0, 0, "Uses inverse quadratic proportion for light attenuation"); uiDefButBitS(block, TOG, LA_SPHERE, REDRAWVIEW3D,"Sphere", 10,130,100,19,&la->mode, 0, 0, 0, 0, "Sets light intensity to zero for objects beyond the distance value"); } uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); uiDefButBitS(block, TOG, LA_LAYER, 0,"Layer", 10,70,100,19,&la->mode, 0, 0, 0, 0, "Illuminates objects in the same layer as the lamp only"); - uiDefButBitS(block, TOG, LA_NEG, B_MATPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light"); + uiDefButBitS(block, TOG, LA_NEG, B_LAMPPRV,"Negative", 10,50,100,19,&la->mode, 0, 0, 0, 0, "Sets lamp to cast negative light"); uiDefButBitS(block, TOG, LA_NO_DIFF, 0,"No Diffuse", 10,30,100,19,&la->mode, 0, 0, 0, 0, "Disables diffuse shading of material illuminated by this lamp"); uiDefButBitS(block, TOG, LA_NO_SPEC, 0,"No Specular", 10,10,100,19,&la->mode, 0, 0, 0, 0, "Disables specular shading of material illuminated by this lamp"); uiBlockEndAlign(block); uiBlockSetCol(block, TH_AUTO); - uiDefButF(block, NUMSLI,B_MATPRV,"Energy ", 120,150,180,20, &(la->energy), 0.0, 10.0, 0, 0, "Sets the intensity of the light"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"Energy ", 120,150,180,20, &(la->energy), 0.0, 10.0, 0, 0, "Sets the intensity of the light"); uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI,B_MATPRV,"R ", 120,120,180,20,&la->r, 0.0, 1.0, B_COLLAMP, 0, "Sets the red component of the light"); - uiDefButF(block, NUMSLI,B_MATPRV,"G ", 120,100,180,20,&la->g, 0.0, 1.0, B_COLLAMP, 0, "Sets the green component of the light"); - uiDefButF(block, NUMSLI,B_MATPRV,"B ", 120,80,180,20,&la->b, 0.0, 1.0, B_COLLAMP, 0, "Sets the blue component of the light"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"R ", 120,120,180,20,&la->r, 0.0, 1.0, B_COLLAMP, 0, "Sets the red component of the light"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"G ", 120,100,180,20,&la->g, 0.0, 1.0, B_COLLAMP, 0, "Sets the green component of the light"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"B ", 120,80,180,20,&la->b, 0.0, 1.0, B_COLLAMP, 0, "Sets the blue component of the light"); uiBlockEndAlign(block); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, ""); + uiDefButF(block, COL, B_LAMPPRV, "", 120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, ""); uiBlockBeginAlign(block); if ELEM(la->type, LA_LOCAL, LA_SPOT) { - uiDefButF(block, NUMSLI,B_MATPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp"); - uiDefButF(block, NUMSLI,B_MATPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad1 ", 120,30,180,19,&la->att1, 0.0, 1.0, 0, 0, "Set the linear distance attenuatation for a quad lamp"); + uiDefButF(block, NUMSLI,B_LAMPPRV,"Quad2 ", 120,10,180,19,&la->att2, 0.0, 1.0, 0, 0, "Set the quadratic distance attenuatation for a quad lamp"); } else if(la->type==LA_AREA) { if(la->k==0.0) la->k= 1.0; @@ -2491,12 +2353,20 @@ static void lamp_panel_preview(Object *ob, Lamp *la) void do_matbuts(unsigned short event) { static short mtexcopied=0; + static MTex mtexcopybuf; Material *ma; MTex *mtex; + /* all operations default on active material layer here */ + /* but this also gets called for lamp and world... */ + ma= G.buts->lockpoin; + if(ma && GS(ma->id.name)==ID_MA) + ma = editnode_get_active_material(ma); + else + ma= NULL; + switch(event) { case B_MAT_YF_PRESET: { - ma = G.buts->lockpoin; switch (ma->YF_preset) { case 0: /* normal mode, no reflection/refraction */ @@ -2545,7 +2415,7 @@ void do_matbuts(unsigned short event) break; } } - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); allqueue(REDRAWBUTSSHADING, 0); shade_buttons_change_3d(); break; @@ -2555,7 +2425,7 @@ void do_matbuts(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); break; case B_MATFROM: scrarea_queue_headredraw(curarea); @@ -2564,41 +2434,47 @@ void do_matbuts(unsigned short event) // BIF_previewdraw(); push/pop! break; case B_MATPRV: - /* this event also used by lamp, tex and sky */ - BIF_preview_changed(G.buts); - shade_buttons_change_3d(); - break; - case B_MATPRV_DRAW: - BIF_preview_changed(G.buts); + if(ma) end_render_material(ma); /// temporal... 3d preview + BIF_preview_changed(ID_MA); allqueue(REDRAWBUTSSHADING, 0); shade_buttons_change_3d(); break; + case B_TEXPRV: + BIF_preview_changed(ID_TE); + allqueue(REDRAWBUTSSHADING, 0); + break; + case B_LAMPPRV: + BIF_preview_changed(ID_LA); + allqueue(REDRAWBUTSSHADING, 0); + break; + case B_WORLDPRV: + BIF_preview_changed(ID_WO); + allqueue(REDRAWBUTSSHADING, 0); + break; case B_MATHALO: /* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE */ /* same for 'xtreme alpha' which is 'only shadow' */ - ma= G.buts->lockpoin; if((ma->mode & MA_HALO)==0) { ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV); } - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); allqueue(REDRAWBUTSSHADING, 0); shade_buttons_change_3d(); break; case B_TEXCLEAR: - ma= G.buts->lockpoin; mtex= ma->mtex[(int) ma->texact ]; if(mtex) { if(mtex->tex) mtex->tex->id.us--; MEM_freeN(mtex); ma->mtex[ (int) ma->texact ]= 0; BIF_undo_push("Unlink material texture"); + if(ma) end_render_material(ma); /// temporal... 3d preview allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } break; case B_MTEXCOPY: - ma= G.buts->lockpoin; if(ma && ma->mtex[(int)ma->texact] ) { mtex= ma->mtex[(int)ma->texact]; if(mtex->tex==0) { @@ -2611,54 +2487,67 @@ void do_matbuts(unsigned short event) } break; case B_MTEXPASTE: - ma= G.buts->lockpoin; if(ma && mtexcopied && mtexcopybuf.tex) { - if(ma->mtex[(int)ma->texact]==0 ) ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); + if(ma->mtex[(int)ma->texact]==0 ) + ma->mtex[(int)ma->texact]= MEM_mallocN(sizeof(MTex), "mtex"); + else if(ma->mtex[(int)ma->texact]->tex) + ma->mtex[(int)ma->texact]->tex->id.us--; + memcpy(ma->mtex[(int)ma->texact], &mtexcopybuf, sizeof(MTex)); id_us_plus((ID *)mtexcopybuf.tex); BIF_undo_push("Paste mapping settings"); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); scrarea_queue_winredraw(curarea); } break; case B_MATLAY: - ma= G.buts->lockpoin; if(ma && ma->lay==0) { ma->lay= 1; scrarea_queue_winredraw(curarea); } break; case B_MATZTRANSP: - ma= G.buts->lockpoin; if(ma) { ma->mode &= ~MA_RAYTRANSP; + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); /// temporal... 3d preview allqueue(REDRAWBUTSSHADING, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } break; case B_MATRAYTRANSP: - ma= G.buts->lockpoin; if(ma) { ma->mode &= ~MA_ZTRA; + if(ma) end_render_material(ma); /// temporal... 3d preview allqueue(REDRAWBUTSSHADING, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } break; case B_MATCOLORBAND: - ma= G.buts->lockpoin; if(ma) { if(ma->mode & MA_RAMP_COL) - if(ma->ramp_col==NULL) ma->ramp_col= add_colorband(); + if(ma->ramp_col==NULL) ma->ramp_col= add_colorband(0); if(ma->mode & MA_RAMP_SPEC) - if(ma->ramp_spec==NULL) ma->ramp_spec= add_colorband(); + if(ma->ramp_spec==NULL) ma->ramp_spec= add_colorband(0); + if(ma) end_render_material(ma); /// temporal... 3d preview allqueue(REDRAWBUTSSHADING, 0); - BIF_all_preview_changed(); + BIF_preview_changed(ID_MA); shade_buttons_change_3d(); } break; - + case B_MAT_USENODES: + ma= G.buts->lockpoin; /* use base material instead */ + if(ma) { + if(ma->use_nodes && ma->nodetree==NULL) { + node_shader_default(ma); + } + if(ma) end_render_material(ma); /// temporal... 3d preview + BIF_preview_changed(ID_MA); + allqueue(REDRAWNODE, 0); + allqueue(REDRAWBUTSSHADING, 0); + } + break; } } @@ -2687,7 +2576,7 @@ static void material_panel_map_to(Material *ma) uiBlockEndAlign(block); uiBlockBeginAlign(block); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); + uiDefButF(block, COL, B_MATPRV, "", 10,100,135,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, ""); if(ma->colormodel==MA_HSV) { uiBlockSetCol(block, TH_BUT_SETTING1); @@ -2719,7 +2608,7 @@ static void material_panel_map_to(Material *ma) uiDefButBitS(block, TOG3, MAP_RAYMIRR, B_MATPRV, "RayMir", 60,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the ray-mirror value"); uiDefButBitS(block, TOG3, MAP_ALPHA, B_MATPRV, "Alpha", 110,160,50,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the alpha value"); uiDefButBitS(block, TOG3, MAP_EMIT, B_MATPRV, "Emit", 160,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the emit value"); - uiDefButBitS(block, TOG3, MAP_TRANSLU, B_MATPRV, "Translu", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the translucency value"); + uiDefButBitS(block, TOG3, MAP_LAYER, B_MATPRV, "Layer", 205,160,60,19, &(mtex->mapto), 0, 0, 0, 0, "Causes the texture to affect the layer blending value"); uiDefButBitS(block, TOG3, MAP_DISPLACE, B_MATPRV, "Disp", 265,160,45,19, &(mtex->mapto), 0, 0, 0, 0, "Let the texture displace the surface"); uiBlockEndAlign(block); @@ -2758,26 +2647,29 @@ static void material_panel_map_input(Object *ob, Material *ma) /* TEXCO */ uiBlockBeginAlign(block); - uiDefButS(block, ROW, B_MATPRV, "UV", 630,166,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Object", 670,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",745,166,163,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "Glob", 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",750,180,158,18, &(mtex->object), ""); - uiDefButS(block, ROW, B_MATPRV, "Glob", 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Orco", 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object"); if( give_parteff(ob) ) - uiDefButS(block, ROW, B_MATPRV, "Strand", 725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)"); + uiDefButS(block, ROW, B_MATPRV, "Strand", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)"); else - uiDefButS(block, ROW, B_MATPRV, "Stick", 725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Win", 775,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Nor", 820,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Refl", 864,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Stick", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Win", 775,160,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Nor", 820,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Refl", 864,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates"); + + uiDefButS(block, ROW, B_MATPRV, "Stress", 630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "Tangent", 700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses the optional tangent vector as texture coordinates"); /* COORDS */ uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_MATPRV, "Flat", 630,114,48,18, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly"); - uiDefButC(block, ROW, B_MATPRV, "Cube", 681,114,50,18, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector"); - uiDefButC(block, ROW, B_MATPRV, "Tube", 630,94,48,18, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)"); - uiDefButC(block, ROW, B_MATPRV, "Sphe", 681,94,50,18, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)"); + uiDefButC(block, ROW, B_MATPRV, "Flat", 630,115,48,19, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly"); + uiDefButC(block, ROW, B_MATPRV, "Cube", 681,115,50,19, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector"); + uiDefButC(block, ROW, B_MATPRV, "Tube", 630,95,48,19, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)"); + uiDefButC(block, ROW, B_MATPRV, "Sphe", 681,95,50,19, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)"); uiBlockBeginAlign(block); for(b=0; b<3; b++) { @@ -2793,13 +2685,13 @@ static void material_panel_map_input(Object *ob, Material *ma) } uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "ofsX", 778,114,130,18, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate"); - uiDefButF(block, NUM, B_MATPRV, "ofsY", 778,94,130,18, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate"); - uiDefButF(block, NUM, B_MATPRV, "ofsZ", 778,74,130,18, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsX", 778,115,130,19, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsY", 778,95,130,19, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsZ", 778,75,130,19, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "sizeX", 778,50,130,18, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size"); - uiDefButF(block, NUM, B_MATPRV, "sizeY", 778,30,130,18, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size"); - uiDefButF(block, NUM, B_MATPRV, "sizeZ", 778,10,130,18, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size"); + uiDefButF(block, NUM, B_MATPRV, "sizeX", 778,50,130,19, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size"); + uiDefButF(block, NUM, B_MATPRV, "sizeY", 778,30,130,19, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size"); + uiDefButF(block, NUM, B_MATPRV, "sizeZ", 778,10,130,19, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size"); uiBlockEndAlign(block); } @@ -2826,7 +2718,7 @@ static void material_panel_texture(Material *ma) if(mtex && mtex->tex) splitIDname(mtex->tex->id.name+2, str, &loos); else strcpy(str, ""); str[10]= 0; - uiDefButC(block, ROW, B_MATPRV_DRAW, str, 10, 180-18*a, 70, 20, &(ma->texact), 3.0, (float)a, 0, 0, ""); + uiDefButC(block, ROW, B_MATPRV, str, 10, 180-18*a, 70, 20, &(ma->texact), 3.0, (float)a, 0, 0, ""); } uiBlockEndAlign(block); @@ -2837,8 +2729,8 @@ static void material_panel_texture(Material *ma) mtex= ma->mtex[a]; if(mtex && mtex->tex) { if(ma->septex & (1<septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); - else uiDefIconButBitS(block, TOG, 1<septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); + uiDefButBitS(block, TOG, 1<septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); + else uiDefIconButBitS(block, TOG, 1<septex, 0.0, 0.0, 0, 0, "Click to disable or enable this texture channel"); } } @@ -2903,12 +2795,8 @@ static void material_panel_tramir(Material *ma) uiDefButF(block, NUMSLI, B_MATPRV, "Fac ", 170,140,140,20, &(ma->fresnel_mir_i), 1.0, 5.0, 10, 2, "Blending factor for Fresnel"); uiBlockBeginAlign(block); - if(ma->mode & MA_RAYTRANSP) - uiDefButF(block, NUM, B_MATPRV, "Filt:", 10,110,100,20, &(ma->filter), 0.0, 1.0, 10, 0, "Amount of filtering for transparent raytrace"); - else - uiDefButF(block, NUM, B_DIFF, "Zoffs:", 10,110,100,20, &(ma->zoffs), 0.0, 10.0, 100, 0, "Gives faces an artificial offset in the Z buffer for Ztransp option"); - uiDefButBitI(block, TOG, MA_ZTRA, B_MATZTRANSP,"ZTransp", 110,110,100,20, &(ma->mode), 0, 0, 0, 0, "Enables Z-Buffering of transparent faces"); - uiDefButBitI(block, TOG, MA_RAYTRANSP, B_MATRAYTRANSP,"Ray Transp",210,110,100,20, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for transparency rendering"); + uiDefButF(block, NUM, B_MATPRV, "Filt:", 10,110,150,20, &(ma->filter), 0.0, 1.0, 10, 0, "Amount of filtering for transparent raytrace"); + uiDefButBitI(block, TOG, MA_RAYTRANSP, B_MATRAYTRANSP,"Ray Transp",160,110,150,20, &(ma->mode), 0, 0, 0, 0, "Enables raytracing for transparency rendering"); uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MATPRV, "IOR ", 10,90,200,20, &(ma->ang), 1.0, 3.0, 100, 2, "Sets the angular index of refraction for raytrace"); @@ -2922,9 +2810,8 @@ static void material_panel_tramir(Material *ma) uiDefButF(block, NUMSLI, B_MATPRV, "Add ", 160,40,150,20, &(ma->add), 0.0, 1.0, 0, 0, "Sets a glow factor for transparant materials"); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_ONLYSHADOW, 0, "OnlyShadow", 10,10,100,20, &(ma->mode), 0, 0, 0, 0, "Renders shadows falling on material only"); - uiDefButBitI(block, TOG, MA_NOMIST, 0, "No Mist", 110,10,100,20, &(ma->mode), 0, 0, 0, 0, "Sets the material to ignore mist values"); - uiDefButBitI(block, TOG, MA_ENV, 0, "Env", 210,10,100,20, &(ma->mode), 0, 0, 0, 0, "Causes faces to render with alpha zero: allows sky/backdrop to show through"); + uiDefButBitI(block, TOG, MA_NOMIST, 0, "No Mist", 10,10,150,20, &(ma->mode), 0, 0, 0, 0, "Sets the material to ignore mist values"); + uiDefButBitI(block, TOG, MA_ENV, 0, "Env", 160,10,150,20, &(ma->mode), 0, 0, 0, 0, "Causes faces to render with alpha zero: allows sky/backdrop to show through"); uiBlockEndAlign(block); @@ -2968,7 +2855,7 @@ static void material_panel_tramir_yafray(Material *ma) /* absorption color */ uiDefBut(block, LABEL, 0, "Absorption Color", 10, 98, 150, 18, 0, 0.0, 0.0, 0, 0, ""); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 10, 38, 30, 58, &ma->YF_ar, 0, 0, 0, B_MATCOL, "transmit absorption color, white is no absorption"); + uiDefButF(block, COL, B_MATPRV, "", 10, 38, 30, 58, &ma->YF_ar, 0, 0, 0, B_MATCOL, "transmit absorption color, white is no absorption"); uiDefButF(block, NUMSLI, B_MATPRV, "aR ", 40, 78, 120, 18, &ma->YF_ar, 1e-7f, 1.0, B_MATCOL, 0, ""); uiDefButF(block, NUMSLI, B_MATPRV, "aG ", 40, 58, 120, 18, &ma->YF_ag, 1e-7f, 1.0, B_MATCOL, 0, ""); uiDefButF(block, NUMSLI, B_MATPRV, "aB ", 40, 38, 120, 18, &ma->YF_ab, 1e-7f, 1.0, B_MATCOL, 0, ""); @@ -2991,10 +2878,6 @@ static void material_panel_shading(Material *ma) block= uiNewBlock(&curarea->uiblocks, "material_panel_shading", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Shaders", "Material", 640, 0, 318, 204)==0) return; - uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitI(block, TOG, MA_HALO, B_MATHALO, "Halo", 245,180,65,18, &(ma->mode), 0, 0, 0, 0, "Renders material as a halo"); - uiBlockSetCol(block, TH_AUTO); - if(ma->mode & MA_HALO) { uiDefButF(block, NUM, B_MATPRV, "HaloSize: ", 10,155,190,18, &(ma->hasize), 0.0, 100.0, 10, 3, "Sets the dimension of the halo"); uiDefButS(block, NUMSLI, B_MATPRV, "Hard ", 10,135,190,18, &(ma->har), 1.0, 127.0, 0, 0, "Sets the hardness of the halo"); @@ -3014,7 +2897,7 @@ static void material_panel_shading(Material *ma) uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV_DRAW, "Flare",245,142,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare"); + uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV, "Flare",245,142,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare"); uiDefButBitI(block, TOG, MA_HALO_RINGS, B_MATPRV, "Rings", 245,123,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders rings over halo"); uiDefButBitI(block, TOG, MA_HALO_LINES, B_MATPRV, "Lines", 245,104,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders star shaped lines over halo"); uiDefButBitI(block, TOG, MA_STAR, B_MATPRV, "Star", 245,85,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders halo as a star"); @@ -3025,11 +2908,11 @@ static void material_panel_shading(Material *ma) uiBlockEndAlign(block); } else { - char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3"; + char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3|Fresnel %x4"; char *str2= "Specular Shader%t|CookTorr %x0|Phong %x1|Blinn %x2|Toon %x3|WardIso %x4"; /* diff shader buttons */ - uiDefButS(block, MENU, B_MATPRV_DRAW, str1, 9, 180,78,19, &(ma->diff_shader), 0.0, 0.0, 0, 0, "Creates a diffuse shader"); + uiDefButS(block, MENU, B_MATPRV, str1, 9, 180,78,19, &(ma->diff_shader), 0.0, 0.0, 0, 0, "Creates a diffuse shader"); uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MATPRV, "Ref ", 90,180,150,19, &(ma->ref), 0.0, 1.0, 0, 0, "Sets the amount of reflection"); @@ -3041,10 +2924,14 @@ static void material_panel_shading(Material *ma) } else if(ma->diff_shader==MA_DIFF_MINNAERT) uiDefButF(block, NUMSLI, B_MATPRV, "Dark:",90,160, 150,19, &(ma->darkness), 0.0, 2.0, 0, 0, "Sets Minnaert darkness"); + else if(ma->diff_shader==MA_DIFF_FRESNEL) { + uiDefButF(block, NUMSLI, B_MATPRV, "Fresnel:", 90, 160,150,19, &(ma->param[1]), 0.0, 5.0, 0, 0, "Power of Fresnel"); + uiDefButF(block, NUMSLI, B_MATPRV, "Fac:",90,140,150,19, &(ma->param[0]), 1.0, 5.0, 0, 0, "Blending factor"); + } uiBlockEndAlign(block); /* spec shader buttons */ - uiDefButS(block, MENU, B_MATPRV_DRAW, str2, 9,120,77,19, &(ma->spec_shader), 0.0, 0.0, 0, 0, "Creates a specular shader"); + uiDefButS(block, MENU, B_MATPRV, str2, 9,120,77,19, &(ma->spec_shader), 0.0, 0.0, 0, 0, "Creates a specular shader"); uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MATPRV, "Spec ", 90,120,150,19, &(ma->spec), 0.0, 2.0, 0, 0, "Sets the degree of specularity"); @@ -3061,26 +2948,25 @@ static void material_panel_shading(Material *ma) uiDefButF(block, NUMSLI, B_MATPRV, "rms:", 90, 100,150,19, &(ma->rms), 0.0, 0.4, 0, 0, "Sets the standard deviation of surface slope"); /* default shading variables */ uiBlockBeginAlign(block); - uiDefButF(block, NUMSLI, B_DIFF, "Translucency ", 9,30,301,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Amount of diffuse shading of the back side"); + uiDefButF(block, NUMSLI, B_MATPRV, "Tralu ", 9,30,150,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Translucency, amount of diffuse shading of the back side"); + uiDefButF(block, NUMSLI, B_MATPRV, "SBias ", 159,30,151,19, &(ma->sbias), 0.0, 0.25, 10, 2, "Shadow bias, to prevent terminator problems on shadow boundary"); uiDefButF(block, NUMSLI, B_MATPRV, "Amb ", 9,10,150,19, &(ma->amb), 0.0, 1.0, 0, 0, "Sets the amount of global ambient color the material receives"); - uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 160,10,150,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits"); + uiDefButF(block, NUMSLI, B_MATPRV, "Emit ", 159,10,151,19, &(ma->emit), 0.0, 1.0, 0, 0, "Sets the amount of light the material emits"); uiBlockEndAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_TRACEBLE, 0,"Traceable", 245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing"); - uiDefButBitI(block, TOG, MA_SHADBUF, 0, "Shadbuf", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers"); + uiDefButBitI(block, TOG, MA_TANGENT_V, B_MATPRV, "Tangent V", 245,180,65,19, &(ma->mode), 0, 0, 0, 0, "Use the tangent vector in V direction for shading"); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_SHADOW, 0, "Shadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows"); - uiDefButBitI(block, TOG, MA_SHADOW_TRA, 0, "TraShadow", 245,100,65,19, &(ma->mode), 0, 0, 0, 0, "Receives transparent shadows based at material color and alpha"); - uiDefButBitI(block, TOG, MA_RAYBIAS, 0, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); + uiDefButBitI(block, TOG, MA_SHADOW, B_MATPRV, "Shadow", 245,140,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows"); + uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_MATPRV, "TraShadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Recieves transparent shadows based at material color and alpha"); + uiDefButBitI(block, TOG, MA_ONLYSHADOW, B_MATPRV, "OnlyShad", 245,100,65,20, &(ma->mode), 0, 0, 0, 0, "Renders shadows on material as Alpha value"); + uiDefButBitI(block, TOG, MA_RAYBIAS, B_MATPRV, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); uiBlockEndAlign(block); - uiDefButBitI(block, TOG, MA_RADIO, 0, "Radio", 245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering"); + uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_MATPRV, "GR:", 9, 55, 150, 19, &ma->group, "Limit Lighting to Lamps in this Group"); } - } static void material_panel_ramps(Material *ma) @@ -3117,7 +3003,7 @@ static void material_panel_ramps(Material *ma) methodc= &ma->rampblend_spec; facp= &ma->rampfac_spec; } - draw_colorband_buts(block, coba, -35, B_MATPRV); // aligns with previous button + draw_colorband_buts(block, coba, 10, 50, B_MATPRV); // aligns with previous button uiDefBut(block, LABEL, 0, "Input",10,30,90,20, NULL, 0, 0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Method",100,30,90,20, NULL, 0, 0, 0, 0, ""); @@ -3152,63 +3038,20 @@ static uiBlock *strand_menu(void *mat_v) } -static void material_panel_material(Object *ob, Material *ma) +static void material_panel_material(Material *ma) { uiBlock *block; - ID *id, *idn, *idfrom; - uiBut *but; - float *colpoin = NULL, min; + float *colpoin = NULL; int rgbsel = 0; - char str[30]; block= uiNewBlock(&curarea->uiblocks, "material_panel_material", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Material", "Material", 320, 0, 318, 204)==0) return; - - /* first do the browse but */ - buttons_active_id(&id, &idfrom); - - uiBlockSetCol(block, TH_BUT_SETTING2); - std_libbuttons(block, 8, 200, 0, NULL, B_MATBROWSE, id, idfrom, &(G.buts->menunr), B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA); + + uiSetButLock(ma->id.lib!=NULL, "Can't edit library data"); uiDefIconBut(block, BUT, B_MATCOPY, ICON_COPYUP, 262,200,XIC,YIC, 0, 0, 0, 0, 0, "Copies Material to the buffer"); - uiSetButLock(id && id->lib, "Can't edit library data"); uiDefIconBut(block, BUT, B_MATPASTE, ICON_PASTEUP, 283,200,XIC,YIC, 0, 0, 0, 0, 0, "Pastes Material from the buffer"); - if(ob->actcol==0) ob->actcol= 1; /* because of TOG|BIT button */ - - uiBlockBeginAlign(block); - - /* id is the block from which the material is used */ - if( BTST(ob->colbits, ob->actcol-1) ) id= (ID *)ob; - else id= ob->data; - - /* indicate which one is linking a material */ - if(id) { - strncpy(str, id->name, 2); - str[2]= ':'; str[3]= 0; - but= uiDefBut(block, TEX, B_IDNAME, str, 8,174,115,20, id->name+2, 0.0, 18.0, 0, 0, "Shows the block the material is linked to"); - uiButSetFunc(but, test_idbutton_cb, id->name, NULL); - } - uiBlockSetCol(block, TH_BUT_ACTION); - uiDefButBitS(block, TOG, 1<<(ob->actcol-1), B_MATFROM, "OB", 125,174,32,20, &ob->colbits, 0, 0, 0, 0, "Links material to object"); - idn= ob->data; - strncpy(str, idn->name, 2); - str[2]= 0; - uiBlockSetCol(block, TH_BUT_SETTING); - uiDefButBitS(block, TOGN, 1<<(ob->actcol-1), B_MATFROM, str, 158,174,32,20, &ob->colbits, 0, 0, 0, 0, "Shows the block the material is linked to"); - uiBlockSetCol(block, TH_AUTO); - - sprintf(str, "%d Mat", ob->totcol); - if(ob->totcol) min= 1.0; else min= 0.0; - uiDefButC(block, NUM, B_ACTCOL, str, 191,174,112,20, &(ob->actcol), min, (float)ob->totcol, 0, 0, "Shows the number of materials on object and the active material"); - uiBlockEndAlign(block); - - if(ob->totcol==0) return; - uiSetButLock(id->lib!=0, "Can't edit library data"); - - ma= give_current_material(ob, ob->actcol); - if(ma==0) return; - if(ma->dynamode & MA_DRAW_DYNABUTS) { uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_DIFF, "Restitut ", 128,120,175,20, &ma->reflect, 0.0, 1.0, 0, 0, "Elasticity of collisions"); @@ -3223,21 +3066,17 @@ static void material_panel_material(Object *ob, Material *ma) if(!(ma->mode & MA_HALO)) { uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButBitI(block, TOG, MA_VERTEXCOL, B_REDR, "VCol Light", 8,146,74,20, &(ma->mode), 0, 0, 0, 0, "Adds vertex colours as extra light"); - uiDefButBitI(block, TOG, MA_VERTEXCOLP, B_REDR, "VCol Paint", 82,146,74,20, &(ma->mode), 0, 0, 0, 0, "Replaces material's colours with vertex colours"); - uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,146,74,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces"); - uiDefButBitI(block, TOG, MA_SHLESS, B_MATPRV, "Shadeless", 230,146,73,20, &(ma->mode), 0, 0, 0, 0, "Makes material insensitive to light or shadow"); - uiDefButBitI(block, TOG, MA_FULL_OSA, 0, "Full Osa", 8,127,74,19, &(ma->mode), 0.0, 10.0, 0, 0, "Forces to render all OSA samples, for shading and texture antialiasing"); - uiDefBlockBut(block, strand_menu, ma, "Strands", 82,127,74, 20, "Display strand settings for static particles"); - uiDefButBitI(block, TOG, MA_WIRE, 0, "Wire", 156,127,74,19, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe"); - uiDefButBitI(block, TOG, MA_ZINV, 0, "ZInvert", 230,127,73,19, &(ma->mode), 0, 0, 0, 0, "Renders material's faces with inverted Z Buffer"); + uiDefButBitI(block, TOG, MA_VERTEXCOL, B_REDR, "VCol Light", 8,166,74,20, &(ma->mode), 0, 0, 0, 0, "Adds vertex colours as extra light"); + uiDefButBitI(block, TOG, MA_VERTEXCOLP, B_REDR, "VCol Paint", 82,166,74,20, &(ma->mode), 0, 0, 0, 0, "Replaces material's colours with vertex colours"); + uiDefButBitI(block, TOG, MA_FACETEXTURE, B_REDR, "TexFace", 156,166,74,20, &(ma->mode), 0, 0, 0, 0, "Sets UV-Editor assigned texture as color and texture info for faces"); + uiDefButBitI(block, TOG, MA_SHLESS, B_MATPRV, "Shadeless", 230,166,73,20, &(ma->mode), 0, 0, 0, 0, "Makes material insensitive to light or shadow"); } uiBlockSetCol(block, TH_AUTO); uiBlockBeginAlign(block); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,97,72,20, &(ma->r), 0, 0, 0, B_MATCOL, ""); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,77,72,20, &(ma->specr), 0, 0, 0, B_SPECCOL, ""); - uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,57,72,20, &(ma->mirr), 0, 0, 0, B_MIRCOL, ""); + uiDefButF(block, COL, B_MATPRV, "", 8,97,72,20, &(ma->r), 0, 0, 0, B_MATCOL, ""); + uiDefButF(block, COL, B_MATPRV, "", 8,77,72,20, &(ma->specr), 0, 0, 0, B_SPECCOL, ""); + uiDefButF(block, COL, B_MATPRV, "", 8,57,72,20, &(ma->mirr), 0, 0, 0, B_MIRCOL, ""); uiBlockBeginAlign(block); if(ma->mode & MA_HALO) { @@ -3281,6 +3120,128 @@ static void material_panel_material(Object *ob, Material *ma) } +static void material_panel_nodes(Material *ma) +{ + bNode *node; + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, "material_panel_nodes", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Links and Pipeline", "Material"); + if(uiNewPanel(curarea, block, "Nodes", "Material", 640, 0, 318, 204)==0) return; + + node= editnode_get_active(ma->nodetree); + if(node==NULL) return; + /* we dont display the buttons here for the active material, is in links panel */ + if(node==editnode_get_active_idnode(ma->nodetree, ID_MA)) return; + + if(node->typeinfo->butfunc) { + rctf rct; + rct.xmin= 10.0f; + rct.xmax= rct.xmin+node->typeinfo->width; + rct.ymax= 155.0; + rct.ymin= rct.ymax - (float)node->typeinfo->butfunc(NULL, NULL, node, NULL); + node->typeinfo->butfunc(block, ma->nodetree, node, &rct); + } +} + +static void material_panel_links(Object *ob, Material *ma) +{ + uiBlock *block; + uiBut *but; + ID *id, *idn, *idfrom; + bNode *node=NULL; + float min; + short xco; + char str[30], *cp; + + block= uiNewBlock(&curarea->uiblocks, "material_panel_links", UI_EMBOSS, UI_HELV, curarea->win); + /* 310 makes sorting code to put it right after preview panel */ + if(uiNewPanel(curarea, block, "Links and Pipeline", "Material", 310, 0, 318, 204)==0) return; + + /* Links from object to material/nodes */ + uiDefBut(block, ROUNDBOX, 0, "", 5, 90, 310, 110, NULL, 7.0, 0.0, 15 , 20, ""); + uiDefBut(block, LABEL, B_DIFF, "Link to Object", 10, 180, 300, 20, 0, 0, 0, 0, 0, ""); + + /* the main material browse but */ + buttons_active_id(&id, &idfrom); /* base material! */ + + uiBlockSetCol(block, TH_BUT_SETTING2); + xco= std_libbuttons(block, 10, 160, 0, NULL, B_MATBROWSE, ID_MA, 0, id, idfrom, &(G.buts->menunr), B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA); + if(ma) cp= &ma->use_nodes; else cp= &G.buts->use_nodes; + uiDefButC(block, TOG, B_MAT_USENODES, "Nodes", xco+5,160,300-xco-5,20, cp, 0.0f, 0.0f, 0, 0, ""); + G.buts->use_nodes= *cp; + + if(ob->actcol==0) ob->actcol= 1; /* because of TOG|BIT button */ + + uiBlockBeginAlign(block); + + /* id is the block from which the material is used */ + if( BTST(ob->colbits, ob->actcol-1) ) id= (ID *)ob; + else id= ob->data; + + /* indicate which one is linking a material */ + if(id) { + strncpy(str, id->name, 2); + str[2]= ':'; str[3]= 0; + but= uiDefBut(block, TEX, B_IDNAME, str, 10,135,115,20, id->name+2, 0.0, 18.0, 0, 0, "Shows the block the material is linked to"); + uiButSetFunc(but, test_idbutton_cb, id->name, NULL); + } + uiBlockSetCol(block, TH_BUT_ACTION); + uiDefButBitS(block, TOG, 1<<(ob->actcol-1), B_MATFROM, "OB", 125,135,32,20, &ob->colbits, 0, 0, 0, 0, "Links material to object"); + idn= ob->data; + strncpy(str, idn->name, 2); + str[2]= 0; + uiBlockSetCol(block, TH_BUT_SETTING); + uiDefButBitS(block, TOGN, 1<<(ob->actcol-1), B_MATFROM, str, 158,135,32,20, &ob->colbits, 0, 0, 0, 0, "Shows the block the material is linked to"); + uiBlockSetCol(block, TH_AUTO); + + sprintf(str, "%d Mat", ob->totcol); + if(ob->totcol) min= 1.0; else min= 0.0; + uiDefButC(block, NUM, B_ACTCOL, str, 190,135,110,20, &(ob->actcol), min, (float)ob->totcol, 0, 0, "Shows the number of materials on object and the active material"); + uiBlockEndAlign(block); + + if(ma==NULL) return; + + /* Active material node */ + if(ma->use_nodes) { + uiDefBut(block, LABEL, B_DIFF, "Active Material Node", 10, 115, 300, 20, 0, 0, 0, 0, 0, ""); + + if(ma) node= editnode_get_active_idnode(ma->nodetree, ID_MA); + if(node==NULL) { + node= editnode_get_active(ma->nodetree); + if(node && node->type!=SH_NODE_MATERIAL) + node= NULL; + } + if(node) { + rctf rct; + rct.xmin= 10.0f; + rct.xmax= 300.0f; + rct.ymax= 114.0f; + rct.ymin= 95.0f; + node->typeinfo->butfunc(block, ma->nodetree, node, &rct); + } + } + + /* main render pipeline settings */ + uiDefBut(block, LABEL, B_DIFF, "Render Pipeline", 10, 70, 300, 20, 0, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButBitI(block, TOG, MA_HALO, B_MATHALO, "Halo", 10,50,100,19, &(ma->mode), 0, 0, 0, 0, "Renders material as a halo"); + uiDefButBitI(block, TOG, MA_ZTRA, B_MATZTRANSP,"ZTransp", 110,50,100,19, &(ma->mode), 0, 0, 0, 0, "Enables Z-Buffering of transparent faces"); + uiDefButF(block, NUM, B_DIFF, "Zoffs:", 210,50,100,19, &(ma->zoffs), 0.0, 10.0, 100, 0, "Gives faces an artificial offset in the Z buffer for Ztransp option"); + + uiDefButBitI(block, TOG, MA_WIRE, 0, "Wire", 10,30,100,19, &(ma->mode), 0, 0, 0, 0, "Renders only the edges of faces as a wireframe"); + uiDefBlockBut(block, strand_menu, ma, "Strands", 110,30,100, 19, "Display strand settings for static particles"); + uiDefButBitI(block, TOG, MA_ZINV, 0, "ZInvert", 210,30,100,19, &(ma->mode), 0, 0, 0, 0, "Renders material's faces with inverted Z Buffer"); + + uiDefButBitI(block, TOG, MA_FULL_OSA, 0, "Full Osa", 10,10,75,19, &(ma->mode), 0.0, 10.0, 0, 0, "Forces to render all OSA samples, for shading and texture antialiasing"); + uiDefButBitI(block, TOG, MA_RADIO, B_NOP, "Radio", 85,10,75,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering"); + uiDefButBitI(block, TOG, MA_TRACEBLE, B_NOP,"Traceable", 160,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing"); + uiDefButBitI(block, TOG, MA_SHADBUF, B_NOP, "Shadbuf", 235,10,75,19, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers"); + + +} + static void material_panel_preview(Material *ma) { uiBlock *block; @@ -3290,18 +3251,20 @@ static void material_panel_preview(Material *ma) if(uiNewPanel(curarea, block, "Preview", "Material", 0, 0, 318, 204)==0) return; if(ma) { + G.buts->lockpoin= ma; /* BIF_previewdraw callback will read it */ + uiBlockSetDrawExtraFunc(block, BIF_previewdraw); // label to force a boundbox for buttons not to be centered uiDefBut(block, LABEL, 0, " ", 20,20,10,10, 0, 0, 0, 0, 0, ""); uiBlockSetCol(block, TH_BUT_NEUTRAL); uiBlockBeginAlign(block); - uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE, 210,180,25,22, &(ma->pr_type), 10, 0, 0, 0, ""); - uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 210,158,25,22, &(ma->pr_type), 10, 1, 0, 0, ""); - uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE, 210,136,25,22, &(ma->pr_type), 10, 2, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATPLANE, 210,180,25,22, &(ma->pr_type), 10, 2, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 210,158,25,22, &(ma->pr_type), 10, 0, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATCUBE, 210,136,25,22, &(ma->pr_type), 10, 1, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, MA_DARK, 210,114,25,22, &(ma->pr_type), 10, 3, 0, 0, ""); + uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 210, 92,25,22, &(ma->pr_type), 10, 4, 0, 0, ""); uiBlockEndAlign(block); - - uiDefIconButBitS(block, ICONTOG, MA_DARK, B_MATPRV, ICON_TRANSP_HLT, 210,100,25,22, &(ma->pr_back), 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefIconButBitS(block, TOG, 2, B_MATPRV, ICON_LAMP, 210,40,25,20, &(ma->pr_lamp), 0, 0, 0, 0, ""); @@ -3323,20 +3286,28 @@ void material_panels() // always draw first 2 panels material_panel_preview(ma); - material_panel_material(ob, ma); + material_panel_links(ob, ma); + if(ma && ma->use_nodes) { + material_panel_nodes(ma); + } + + ma= editnode_get_active_material(ma); if(ma) { + material_panel_material(ma); material_panel_ramps(ma); material_panel_shading(ma); + if (G.scene->r.renderer==R_INTERN) material_panel_tramir(ma); else { - if (ma->YF_ar==0.f) { + if(ma->YF_ar==0.f) { ma->YF_ar = ma->YF_ag = ma->YF_ab = 1; ma->YF_dscale = 1; } material_panel_tramir_yafray(ma); } + material_panel_texture(ma); mtex= ma->mtex[ ma->texact ]; @@ -3397,12 +3368,23 @@ void texture_panels() Material *ma=NULL; Lamp *la=NULL; World *wrld=NULL; + bNode *node=NULL; Object *ob= OBACT; MTex *mtex= NULL; if(G.buts->texfrom==0) { if(ob) { ma= give_current_material(ob, ob->actcol); + + if(ma && ma->use_nodes) { + node= editnode_get_active_idnode(ma->nodetree, ID_TE); + + if(node) + ma= NULL; + else { + ma= editnode_get_active_material(ma); + } + } if(ma) mtex= ma->mtex[ ma->texact ]; } } @@ -3417,150 +3399,67 @@ void texture_panels() } } - texture_panel_preview(ma || wrld || la); // for 'from' buttons + texture_panel_preview(ma || wrld || la || node); // for 'from' buttons - if(ma || wrld || la) { - - texture_panel_texture(mtex, ma, wrld, la); + if(ma || wrld || la || node) { + Tex *tex= NULL; - if(mtex && mtex->tex) { - texture_panel_colors(mtex->tex); + texture_panel_texture(mtex, ma, wrld, la, node); + + if(mtex) tex= mtex->tex; + else if(node) tex= (Tex *)node->id; + + if(tex) { + texture_panel_colors(tex); - switch(mtex->tex->type) { + switch(tex->type) { case TEX_IMAGE: - texture_panel_image(mtex->tex); - texture_panel_image1(mtex->tex); + texture_panel_image(tex); + texture_panel_image1(tex); break; case TEX_ENVMAP: - texture_panel_envmap(mtex->tex); + texture_panel_envmap(tex); break; case TEX_CLOUDS: - texture_panel_clouds(mtex->tex); + texture_panel_clouds(tex); break; case TEX_MARBLE: - texture_panel_marble(mtex->tex); + texture_panel_marble(tex); break; case TEX_STUCCI: - texture_panel_stucci(mtex->tex); + texture_panel_stucci(tex); break; case TEX_WOOD: - texture_panel_wood(mtex->tex); + texture_panel_wood(tex); break; case TEX_BLEND: - texture_panel_blend(mtex->tex); + texture_panel_blend(tex); break; case TEX_MAGIC: - texture_panel_magic(mtex->tex); + texture_panel_magic(tex); break; case TEX_PLUGIN: - texture_panel_plugin(mtex->tex); + texture_panel_plugin(tex); break; case TEX_NOISE: // no panel! (e: not really true, is affected by noisedepth param) break; - /* newnoise: musgrave panels */ + /* newnoise: musgrave panels */ case TEX_MUSGRAVE: - texture_panel_musgrave(mtex->tex); + texture_panel_musgrave(tex); break; case TEX_DISTNOISE: - texture_panel_distnoise(mtex->tex); + texture_panel_distnoise(tex); break; - /* newnoise: voronoi */ + /* newnoise: voronoi */ case TEX_VORONOI: - texture_panel_voronoi(mtex->tex); + texture_panel_voronoi(tex); break; } } } } -/* old popup.. too hackish, should be fixed once (ton) */ -void clever_numbuts_buts() -{ - Material *ma; - Lamp *la; - World *wo; - static char hexrgb[8]; /* Uh... */ - static char hexspec[8]; /* Uh... */ - static char hexmir[8]; /* Uh... */ - static char hexho[8]; - static char hexze[8]; - int rgb[3]; - - if(G.buts->mainb!= CONTEXT_SHADING) return; - - switch (G.buts->tab[CONTEXT_SHADING]) { - case TAB_SHADING_LAMP: - la= G.buts->lockpoin; - if (la){ - sprintf(hexrgb, "%02X%02X%02X", (int)(la->r*255), (int)(la->g*255), (int)(la->b*255)); - add_numbut(0, TEX, "RGB:", 0, 6, hexrgb, "HTML Hex value for the lamp color"); - do_clever_numbuts("Lamp RGB Hex Values", 1, REDRAW); - sscanf(hexrgb, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - la->r = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - la->g = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - la->b = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - BIF_preview_changed(G.buts); - } - break; - case TAB_SHADING_WORLD: - wo= G.buts->lockpoin; - if (wo){ - sprintf(hexho, "%02X%02X%02X", (int)(wo->horr*255), (int)(wo->horg*255), (int)(wo->horb*255)); - sprintf(hexze, "%02X%02X%02X", (int)(wo->zenr*255), (int)(wo->zeng*255), (int)(wo->zenb*255)); - add_numbut(0, TEX, "Zen:", 0, 6, hexze, "HTML Hex value for the Zenith color"); - add_numbut(1, TEX, "Hor:", 0, 6, hexho, "HTML Hex value for the Horizon color"); - do_clever_numbuts("World RGB Hex Values", 2, REDRAW); - - sscanf(hexho, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - wo->horr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - wo->horg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - wo->horb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - sscanf(hexze, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - wo->zenr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - wo->zeng = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - wo->zenb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - BIF_preview_changed(G.buts); - - } - break; - case TAB_SHADING_MAT: - - ma= G.buts->lockpoin; - - /* Build a hex value */ - if (ma){ - sprintf(hexrgb, "%02X%02X%02X", (int)(ma->r*255), (int)(ma->g*255), (int)(ma->b*255)); - sprintf(hexspec, "%02X%02X%02X", (int)(ma->specr*255), (int)(ma->specg*255), (int)(ma->specb*255)); - sprintf(hexmir, "%02X%02X%02X", (int)(ma->mirr*255), (int)(ma->mirg*255), (int)(ma->mirb*255)); - - add_numbut(0, TEX, "Col:", 0, 6, hexrgb, "HTML Hex value for the RGB color"); - add_numbut(1, TEX, "Spec:", 0, 6, hexspec, "HTML Hex value for the Spec color"); - add_numbut(2, TEX, "Mir:", 0, 6, hexmir, "HTML Hex value for the Mir color"); - do_clever_numbuts("Material RGB Hex Values", 3, REDRAW); - - /* Assign the new hex value */ - sscanf(hexrgb, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - ma->r = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - ma->g = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - ma->b = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - sscanf(hexspec, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - ma->specr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - ma->specg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - ma->specb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - sscanf(hexmir, "%02X%02X%02X", &rgb[0], &rgb[1], &rgb[2]); - ma->mirr = (rgb[0]/255.0 >= 0.0 && rgb[0]/255.0 <= 1.0 ? rgb[0]/255.0 : 0.0) ; - ma->mirg = (rgb[1]/255.0 >= 0.0 && rgb[1]/255.0 <= 1.0 ? rgb[1]/255.0 : 0.0) ; - ma->mirb = (rgb[2]/255.0 >= 0.0 && rgb[2]/255.0 <= 1.0 ? rgb[2]/255.0 : 0.0) ; - - BIF_preview_changed(G.buts); - } - break; - } -} - - - void radio_panels() { Radio *rad; diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 7d92b8a746b..0a4f52b6174 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -49,6 +49,7 @@ /* Types --------------------------------------------------------------- */ #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" @@ -67,6 +68,7 @@ #include "BIF_editaction.h" #include "BIF_editkey.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_resources.h" @@ -211,7 +213,7 @@ void draw_cfra_action(void) glLineWidth(1.0); } - +/* left hand */ static void draw_action_channel_names(bAction *act) { bActionChannel *chan; @@ -222,28 +224,30 @@ static void draw_action_channel_names(bAction *act) y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); for (chan=act->chanbase.first; chan; chan=chan->next){ - BIF_ThemeColorShade(TH_HEADER, 20); - glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2); - - if (chan->flag & ACHAN_SELECTED) - BIF_ThemeColor(TH_TEXT_HI); - else - BIF_ThemeColor(TH_TEXT); - glRasterPos2f(x+8, y-4); - BMF_DrawString(G.font, chan->name); - y-=CHANNELHEIGHT+CHANNELSKIP; - - /* Draw constraint channels */ - for (conchan=chan->constraintChannels.first; - conchan; conchan=conchan->next){ - if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + if((chan->flag & ACHAN_HIDDEN)==0) { + BIF_ThemeColorShade(TH_HEADER, 20); + glRectf(x, y-CHANNELHEIGHT/2, (float)NAMEWIDTH, y+CHANNELHEIGHT/2); + + if (chan->flag & ACHAN_SELECTED) BIF_ThemeColor(TH_TEXT_HI); else BIF_ThemeColor(TH_TEXT); - - glRasterPos2f(x+32, y-4); - BMF_DrawString(G.font, conchan->name); + glRasterPos2f(x+8, y-4); + BMF_DrawString(G.font, chan->name); y-=CHANNELHEIGHT+CHANNELSKIP; + + /* Draw constraint channels */ + for (conchan=chan->constraintChannels.first; + conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColor(TH_TEXT); + + glRasterPos2f(x+32, y-4); + BMF_DrawString(G.font, conchan->name); + y-=CHANNELHEIGHT+CHANNELSKIP; + } } } } @@ -292,6 +296,7 @@ static void draw_action_mesh_names(Key *key) } } +/* left hand part */ static void draw_channel_names(void) { short ofsx, ofsy = 0; @@ -345,13 +350,39 @@ int count_action_levels(bAction *act) return 0; for (achan=act->chanbase.first; achan; achan=achan->next){ - y+=1; - y+=BLI_countlist(&achan->constraintChannels); + if((achan->flag & ACHAN_HIDDEN)==0) { + y+=1; + y+=BLI_countlist(&achan->constraintChannels); + } } return y; } +/* sets or clears hidden flags */ +void check_action_context(SpaceAction *saction) +{ + bActionChannel *achan; + + if(saction->action==NULL) return; + + for (achan=saction->action->chanbase.first; achan; achan=achan->next) + achan->flag &= ~ACHAN_HIDDEN; + + if (G.saction->pin==0 && OBACT) { + Object *ob= OBACT; + bPoseChannel *pchan; + bArmature *arm= ob->data; + + for (achan=saction->action->chanbase.first; achan; achan=achan->next) { + pchan= get_pose_channel(ob->pose, achan->name); + if(pchan) + if((pchan->bone->layer & arm->layer)==0) + achan->flag |= ACHAN_HIDDEN; + } + } +} + static void draw_channel_strips(SpaceAction *saction) { rcti scr_rct; @@ -381,7 +412,7 @@ static void draw_channel_strips(SpaceAction *saction) map_active_strip(di, OBACT, 0); /* start and end of action itself */ - calc_action_range(act, &sta, &end); + calc_action_range(act, &sta, &end, 0); gla2DDrawTranslatePt(di, sta, 0.0f, &act_start, &dummy); gla2DDrawTranslatePt(di, end, 0.0f, &act_end, &dummy); @@ -392,34 +423,36 @@ static void draw_channel_strips(SpaceAction *saction) y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); glEnable(GL_BLEND); for (chan=act->chanbase.first; chan; chan=chan->next){ - int frame1_x, channel_y; - - gla2DDrawTranslatePt(di, G.v2d->cur.xmin, y, &frame1_x, &channel_y); - - if (chan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); - else glColor4ub(col2[0], col2[1], col2[2], 0x22); - glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2); - - if (chan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); - else glColor4ub(col2[0], col2[1], col2[2], 0x22); - glRectf(act_start, channel_y-CHANNELHEIGHT/2, act_end, channel_y+CHANNELHEIGHT/2); - - /* Increment the step */ - y-=CHANNELHEIGHT+CHANNELSKIP; - - /* Draw constraint channels */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ - gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + if((chan->flag & ACHAN_HIDDEN)==0) { + int frame1_x, channel_y; - if (conchan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); + gla2DDrawTranslatePt(di, G.v2d->cur.xmin, y, &frame1_x, &channel_y); + + if (chan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); else glColor4ub(col2[0], col2[1], col2[2], 0x22); - glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4); + glRectf(frame1_x, channel_y-CHANNELHEIGHT/2, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2); - if (conchan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); + if (chan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); else glColor4ub(col2[0], col2[1], col2[2], 0x22); - glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4); + glRectf(act_start, channel_y-CHANNELHEIGHT/2, act_end, channel_y+CHANNELHEIGHT/2); + /* Increment the step */ y-=CHANNELHEIGHT+CHANNELSKIP; + + /* Draw constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + gla2DDrawTranslatePt(di, 1, y, &frame1_x, &channel_y); + + if (conchan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); + else glColor4ub(col2[0], col2[1], col2[2], 0x22); + glRectf(frame1_x, channel_y-CHANNELHEIGHT/2+4, G.v2d->hor.xmax, channel_y+CHANNELHEIGHT/2-4); + + if (conchan->flag & ACHAN_SELECTED) glColor4ub(col1[0], col1[1], col1[2], 0x22); + else glColor4ub(col2[0], col2[1], col2[2], 0x22); + glRectf(act_start, channel_y-CHANNELHEIGHT/2+4, act_end, channel_y+CHANNELHEIGHT/2-4); + + y-=CHANNELHEIGHT+CHANNELSKIP; + } } } glDisable(GL_BLEND); @@ -430,13 +463,16 @@ static void draw_channel_strips(SpaceAction *saction) /* dot thingies */ y= count_action_levels(act)*(CHANNELHEIGHT+CHANNELSKIP); for (chan=act->chanbase.first; chan; chan=chan->next){ - draw_ipo_channel(di, chan->ipo, 0, y); - y-=CHANNELHEIGHT+CHANNELSKIP; - - /* Draw constraint channels */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ - draw_ipo_channel(di, conchan->ipo, 0, y); + if((chan->flag & ACHAN_HIDDEN)==0) { + + draw_ipo_channel(di, chan->ipo, 0, y); y-=CHANNELHEIGHT+CHANNELSKIP; + + /* Draw constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + draw_ipo_channel(di, conchan->ipo, 0, y); + y-=CHANNELHEIGHT+CHANNELSKIP; + } } } @@ -633,6 +669,8 @@ void drawactionspace(ScrArea *sa, void *spacedata) calc_ipogrid(); draw_ipogrid(); + check_action_context(G.saction); + /* Draw channel strips */ draw_channel_strips(G.saction); @@ -750,8 +788,8 @@ static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, floa gla2DDrawTranslatePt(di, blist[v]->vec[1][0], ypos, &sc_x, &sc_y); // draw_key_but(sc_x-5, sc_y-6, 13, 13, (blist[v]->f2 & 1)); - if(blist[v]->f2 & 1) BIF_draw_icon_blended(sc_x-7, sc_y-6, ICON_SPACE2, TH_HEADER, 0); - else BIF_draw_icon_blended(sc_x-7, sc_y-6, ICON_SPACE3, TH_HEADER, 0); + if(blist[v]->f2 & 1) BIF_icon_draw_blended(sc_x-7, sc_y-6, ICON_SPACE2, TH_HEADER, 0); + else BIF_icon_draw_blended(sc_x-7, sc_y-6, ICON_SPACE3, TH_HEADER, 0); } } @@ -932,17 +970,18 @@ static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert) if (act){ /* Count required keys */ for (achan=act->chanbase.first; achan; achan=achan->next){ - /* Count transformation keys */ - if(achan->ipo) { - for (icu=achan->ipo->curve.first; icu; icu=icu->next) - count+=icu->totvert; - } - /* Count constraint keys */ - for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) - if(conchan->ipo) - for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + if((achan->flag & ACHAN_HIDDEN)==0) { + /* Count transformation keys */ + if(achan->ipo) { + for (icu=achan->ipo->curve.first; icu; icu=icu->next) count+=icu->totvert; - + } + /* Count constraint keys */ + for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) + if(conchan->ipo) + for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + count+=icu->totvert; + } } /* Build the list */ @@ -951,21 +990,22 @@ static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert) count=0; for (achan=act->chanbase.first; achan; achan=achan->next){ - if(achan->ipo) { - /* Add transformation keys */ - for (icu=achan->ipo->curve.first; icu; icu=icu->next){ - for (v=0; vtotvert; v++) - list[count++]=&icu->bezt[v]; - } - } - /* Add constraint keys */ - for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){ - if(conchan->ipo) - for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + if((achan->flag & ACHAN_HIDDEN)==0) { + if(achan->ipo) { + /* Add transformation keys */ + for (icu=achan->ipo->curve.first; icu; icu=icu->next){ for (v=0; vtotvert; v++) list[count++]=&icu->bezt[v]; - } - + } + } + /* Add constraint keys */ + for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){ + if(conchan->ipo) + for (icu=conchan->ipo->curve.first; icu; icu=icu->next) + for (v=0; vtotvert; v++) + list[count++]=&icu->bezt[v]; + } + } } qsort(list, count, sizeof(BezTriple*), bezt_compare); diff --git a/source/blender/src/drawarmature.c b/source/blender/src/drawarmature.c index b4c31179e2d..083125442af 100644 --- a/source/blender/src/drawarmature.c +++ b/source/blender/src/drawarmature.c @@ -57,6 +57,7 @@ #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_object.h" @@ -1069,6 +1070,28 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned } } +static void draw_custom_bone(Object *ob, int dt, int armflag, int boneflag, unsigned int id, float length) +{ + + if(ob==NULL || ob->type!=OB_MESH) return; + + glScalef(length, length, length); + + /* colors for posemode */ + if (armflag & ARM_POSEMODE) { + if (boneflag & BONE_ACTIVE) BIF_ThemeColorShade(TH_BONE_POSE, 40); + else if (boneflag & BONE_SELECTED) BIF_ThemeColor(TH_BONE_POSE); + else BIF_ThemeColor(TH_WIRE); + } + + if (id != -1) { + glLoadName ((GLuint) id|BONESEL_BONE); + } + + draw_object_instance(ob, dt, armflag & ARM_POSEMODE); +} + + static void pchan_draw_IK_root_lines(bPoseChannel *pchan) { bConstraint *con; @@ -1181,103 +1204,106 @@ static void draw_dof_ellipse(float ax, float az) static void draw_pose_dofs(Object *ob) { + bArmature *arm= ob->data; bPoseChannel *pchan; Bone *bone; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) { - bone= pchan->bone; - if(bone && !(bone->flag & BONE_HIDDEN_P)) { - if(bone->flag & BONE_SELECTED) { - if(pose_channel_in_IK_chain(ob, pchan)) { - float corner[4][3], posetrans[3], mat[4][4]; - float phi=0.0f, theta=0.0f, scale; - int a, i; + bone= pchan->bone; + if(bone && !(bone->flag & BONE_HIDDEN_P)) { + if(bone->flag & BONE_SELECTED) { + if(bone->layer & arm->layer) { + if(pchan->ikflag & (BONE_IK_XLIMIT|BONE_IK_ZLIMIT)) { + if(pose_channel_in_IK_chain(ob, pchan)) { + float corner[4][3], posetrans[3], mat[4][4]; + float phi=0.0f, theta=0.0f, scale; + int a, i; - /* in parent-bone pose, but own restspace */ - glPushMatrix(); + /* in parent-bone pose, but own restspace */ + glPushMatrix(); - VECCOPY(posetrans, pchan->pose_mat[3]); - glTranslatef(posetrans[0], posetrans[1], posetrans[2]); + VECCOPY(posetrans, pchan->pose_mat[3]); + glTranslatef(posetrans[0], posetrans[1], posetrans[2]); - if(pchan->parent) { - Mat4CpyMat4(mat, pchan->parent->pose_mat); - mat[3][0]= mat[3][1]= mat[3][2]= 0.0f; + if(pchan->parent) { + Mat4CpyMat4(mat, pchan->parent->pose_mat); + mat[3][0]= mat[3][1]= mat[3][2]= 0.0f; + glMultMatrixf(mat); + } + + Mat4CpyMat3(mat, pchan->bone->bone_mat); glMultMatrixf(mat); - } - Mat4CpyMat3(mat, pchan->bone->bone_mat); - glMultMatrixf(mat); + scale= bone->length*pchan->size[1]; + glScalef(scale, scale, scale); - scale= bone->length*pchan->size[1]; - glScalef(scale, scale, scale); + if(pchan->ikflag & BONE_IK_XLIMIT) { + if(pchan->ikflag & BONE_IK_ZLIMIT) { + float amin[3], amax[3]; - if(pchan->ikflag & BONE_IK_XLIMIT) { - if(pchan->ikflag & BONE_IK_ZLIMIT) { - float amin[3], amax[3]; - - for(i=0; i<3; i++) { - amin[i]= sin(pchan->limitmin[i]*M_PI/360.0); - amax[i]= sin(pchan->limitmax[i]*M_PI/360.0); + for(i=0; i<3; i++) { + amin[i]= sin(pchan->limitmin[i]*M_PI/360.0); + amax[i]= sin(pchan->limitmax[i]*M_PI/360.0); + } + + glScalef(1.0, -1.0, 1.0); + if (amin[0] != 0.0 && amin[2] != 0.0) + draw_dof_ellipse(amin[0], amin[2]); + if (amin[0] != 0.0 && amax[2] != 0.0) + draw_dof_ellipse(amin[0], amax[2]); + if (amax[0] != 0.0 && amin[2] != 0.0) + draw_dof_ellipse(amax[0], amin[2]); + if (amax[0] != 0.0 && amax[2] != 0.0) + draw_dof_ellipse(amax[0], amax[2]); + glScalef(1.0, -1.0, 1.0); } - - glScalef(1.0, -1.0, 1.0); - if (amin[0] != 0.0 && amin[2] != 0.0) - draw_dof_ellipse(amin[0], amin[2]); - if (amin[0] != 0.0 && amax[2] != 0.0) - draw_dof_ellipse(amin[0], amax[2]); - if (amax[0] != 0.0 && amin[2] != 0.0) - draw_dof_ellipse(amax[0], amin[2]); - if (amax[0] != 0.0 && amax[2] != 0.0) - draw_dof_ellipse(amax[0], amax[2]); - glScalef(1.0, -1.0, 1.0); } + + /* arcs */ + if(pchan->ikflag & BONE_IK_ZLIMIT) { + theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]); + glRotatef(theta, 0.0f, 0.0f, 1.0f); + + glColor3ub(50, 50, 255); // blue, Z axis limit + glBegin(GL_LINE_STRIP); + for(a=-16; a<=16; a++) { + float fac= ((float)a)/16.0f; + phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]); + + if(a==-16) i= 0; else i= 1; + corner[i][0]= sin(phi); + corner[i][1]= cos(phi); + corner[i][2]= 0.0f; + glVertex3fv(corner[i]); + } + glEnd(); + + glRotatef(-theta, 0.0f, 0.0f, 1.0f); + } + + if(pchan->ikflag & BONE_IK_XLIMIT) { + theta= 0.5*( pchan->limitmin[0]+pchan->limitmax[0]); + glRotatef(theta, 1.0f, 0.0f, 0.0f); + + glColor3ub(255, 50, 50); // Red, X axis limit + glBegin(GL_LINE_STRIP); + for(a=-16; a<=16; a++) { + float fac= ((float)a)/16.0f; + phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]); + + if(a==-16) i= 2; else i= 3; + corner[i][0]= 0.0f; + corner[i][1]= sin(phi); + corner[i][2]= cos(phi); + glVertex3fv(corner[i]); + } + glEnd(); + + glRotatef(-theta, 1.0f, 0.0f, 0.0f); + } + + glPopMatrix(); // out of cone, out of bone } - - /* arcs */ - if(pchan->ikflag & BONE_IK_ZLIMIT) { - theta= 0.5*(pchan->limitmin[2]+pchan->limitmax[2]); - glRotatef(theta, 0.0f, 0.0f, 1.0f); - - glColor3ub(50, 50, 255); // blue, Z axis limit - glBegin(GL_LINE_STRIP); - for(a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f; - phi= fac*(M_PI/360.0f)*(pchan->limitmax[2]-pchan->limitmin[2]); - - if(a==-16) i= 0; else i= 1; - corner[i][0]= sin(phi); - corner[i][1]= cos(phi); - corner[i][2]= 0.0f; - glVertex3fv(corner[i]); - } - glEnd(); - - glRotatef(-theta, 0.0f, 0.0f, 1.0f); - } - - if(pchan->ikflag & BONE_IK_XLIMIT) { - theta= 0.5*( pchan->limitmin[0]+pchan->limitmax[0]); - glRotatef(theta, 1.0f, 0.0f, 0.0f); - - glColor3ub(255, 50, 50); // Red, X axis limit - glBegin(GL_LINE_STRIP); - for(a=-16; a<=16; a++) { - float fac= ((float)a)/16.0f; - phi= 0.5f*M_PI + fac*(M_PI/360.0f)*(pchan->limitmax[0]-pchan->limitmin[0]); - - if(a==-16) i= 2; else i= 3; - corner[i][0]= 0.0f; - corner[i][1]= sin(phi); - corner[i][2]= cos(phi); - glVertex3fv(corner[i]); - } - glEnd(); - - glRotatef(-theta, 1.0f, 0.0f, 0.0f); - } - - glPopMatrix(); // out of cone, out of bone } } } @@ -1301,6 +1327,7 @@ static void draw_pose_channels(Base *base, int dt) /* hacky... prevent outline select from drawing dashed helplines */ glGetFloatv(GL_LINE_WIDTH, &tmp); if(tmp > 1.1) do_dashed= 0; + if (G.vd->flag & V3D_HIDE_HELPLINES) do_dashed= 0; /* precalc inverse matrix for drawing screen aligned */ if(arm->drawtype==ARM_ENVELOPE) { @@ -1320,7 +1347,8 @@ static void draw_pose_channels(Base *base, int dt) bone= pchan->bone; if(bone && !(bone->flag & (BONE_HIDDEN_P|BONE_NO_DEFORM))) { if(bone->flag & (BONE_SELECTED)) - draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL); + if(bone->layer & arm->layer) + draw_sphere_bone_dist(smat, imat, bone->flag, pchan, NULL); } } @@ -1335,33 +1363,42 @@ static void draw_pose_channels(Base *base, int dt) glEnable(GL_CULL_FACE); /* if solid we draw that first, with selection codes, but without names, axes etc */ - if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) { + if(dt>OB_WIRE) { if(arm->flag & ARM_POSEMODE) index= base->selcol; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; if(bone && !(bone->flag & BONE_HIDDEN_P)) { - glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - - /* catch exception for bone with hidden parent */ - flag= bone->flag; - if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P)) - flag &= ~BONE_CONNECTED; - - if(arm->drawtype==ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - else if(arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); + if(bone->layer & arm->layer) { + glPushMatrix(); + glMultMatrixf(pchan->pose_mat); + + /* catch exception for bone with hidden parent */ + flag= bone->flag; + if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P)) + flag &= ~BONE_CONNECTED; + + if(pchan->custom) + draw_custom_bone(pchan->custom, OB_SOLID, arm->flag, flag, index, bone->length); + else if(arm->drawtype==ARM_LINE) + ; /* nothing in solid */ + else if(arm->drawtype==ARM_ENVELOPE) + draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); + else if(arm->drawtype==ARM_B_BONE) + draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL); + else { + draw_bone(OB_SOLID, arm->flag, flag, 0, index, bone->length); + } + glPopMatrix(); } - glPopMatrix(); } if (index!= -1) index+= 0x10000; // pose bones count in higher 2 bytes only } - glLoadName (index & 0xFFFF); // object tag, for bordersel optim - index= -1; + /* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet, stick bones are dawn in next loop */ + if(arm->drawtype!=ARM_LINE) { + glLoadName (index & 0xFFFF); // object tag, for bordersel optim + index= -1; + } } /* wire draw over solid only in posemode */ @@ -1381,67 +1418,72 @@ static void draw_pose_channels(Base *base, int dt) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; if(bone && !(bone->flag & BONE_HIDDEN_P)) { - - if (do_dashed && bone->parent) { - // Draw a line from our root to the parent's tip - if(!(bone->flag & BONE_CONNECTED) ){ - if (arm->flag & ARM_POSEMODE) { - glLoadName (index & 0xFFFF); // object tag, for bordersel optim - BIF_ThemeColor(TH_WIRE); + if(bone->layer & arm->layer) { + if (do_dashed && bone->parent) { + /* Draw a line from our root to the parent's tip */ + if(!(bone->flag & BONE_CONNECTED) ){ + if (arm->flag & ARM_POSEMODE) { + glLoadName (index & 0xFFFF); // object tag, for bordersel optim + BIF_ThemeColor(TH_WIRE); + } + setlinestyle(3); + glBegin(GL_LINES); + glVertex3fv(pchan->pose_head); + glVertex3fv(pchan->parent->pose_tail); + glEnd(); + setlinestyle(0); } - setlinestyle(3); - glBegin(GL_LINES); - glVertex3fv(pchan->pose_head); - glVertex3fv(pchan->parent->pose_tail); - glEnd(); - setlinestyle(0); - } - // Draw a line to IK root bone - if(arm->flag & ARM_POSEMODE) { - if(pchan->constflag & PCHAN_HAS_IK) { - if(bone->flag & BONE_SELECTED) { - - if(pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0); - else glColor3ub(200, 200, 50); // add theme! + // Draw a line to IK root bone + if(arm->flag & ARM_POSEMODE) { + if(pchan->constflag & PCHAN_HAS_IK) { + if(bone->flag & BONE_SELECTED) { + + if(pchan->constflag & PCHAN_HAS_TARGET) glColor3ub(200, 120, 0); + else glColor3ub(200, 200, 50); // add theme! - glLoadName (index & 0xFFFF); - pchan_draw_IK_root_lines(pchan); + glLoadName (index & 0xFFFF); + pchan_draw_IK_root_lines(pchan); + } } } } - } - - if(arm->drawtype!=ARM_ENVELOPE) { - glPushMatrix(); - glMultMatrixf(pchan->pose_mat); - } - - /* catch exception for bone with hidden parent */ - flag= bone->flag; - if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P)) - flag &= ~BONE_CONNECTED; - - /* extra draw service for pose mode */ - constflag= pchan->constflag; - if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) - constflag |= PCHAN_HAS_ACTION; - if(pchan->flag & POSE_STRIDE) - constflag |= PCHAN_HAS_STRIDE; + + if(arm->drawtype!=ARM_ENVELOPE) { + glPushMatrix(); + glMultMatrixf(pchan->pose_mat); + } + + /* catch exception for bone with hidden parent */ + flag= bone->flag; + if(bone->parent && (bone->parent->flag & BONE_HIDDEN_P)) + flag &= ~BONE_CONNECTED; + + /* extra draw service for pose mode */ + constflag= pchan->constflag; + if(pchan->flag & (POSE_ROT|POSE_LOC|POSE_SIZE)) + constflag |= PCHAN_HAS_ACTION; + if(pchan->flag & POSE_STRIDE) + constflag |= PCHAN_HAS_STRIDE; - if(arm->drawtype==ARM_ENVELOPE) { - if(dtflag, flag, constflag, index, pchan, NULL); + if(pchan->custom) { + if(dtcustom, OB_WIRE, arm->flag, flag, index, bone->length); + } + else if(arm->drawtype==ARM_ENVELOPE) { + if(dtflag, flag, constflag, index, pchan, NULL); + } + else if(arm->drawtype==ARM_LINE) + draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); + else if(arm->drawtype==ARM_B_BONE) + draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); + else { + draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); + } + + if(arm->drawtype!=ARM_ENVELOPE) + glPopMatrix(); } - else if(arm->drawtype==ARM_LINE) - draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL); - else if(arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL); - else { - draw_bone(OB_WIRE, arm->flag, flag, constflag, index, bone->length); - } - - if(arm->drawtype!=ARM_ENVELOPE) - glPopMatrix(); } if (index!= -1) index+= 0x10000; // pose bones count in higher 2 bytes only } @@ -1468,26 +1510,28 @@ static void draw_pose_channels(Base *base, int dt) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if((pchan->bone->flag & BONE_HIDDEN_P)==0) { - if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) { - bone= pchan->bone; - if(bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); - else BIF_ThemeColor(TH_TEXT); - } - else if(dt > OB_WIRE) BIF_ThemeColor(TH_TEXT); - - if (arm->flag & ARM_DRAWNAMES){ - VecMidf(vec, pchan->pose_head, pchan->pose_tail); - glRasterPos3fv(vec); - BMF_DrawString(G.font, " "); - BMF_DrawString(G.font, pchan->name); - } - /* Draw additional axes */ - 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); - glPopMatrix(); + if(pchan->bone->layer & arm->layer) { + if (arm->flag & (ARM_EDITMODE|ARM_POSEMODE)) { + bone= pchan->bone; + if(bone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); + else BIF_ThemeColor(TH_TEXT); + } + else if(dt > OB_WIRE) BIF_ThemeColor(TH_TEXT); + + if (arm->flag & ARM_DRAWNAMES){ + VecMidf(vec, pchan->pose_head, pchan->pose_tail); + glRasterPos3fv(vec); + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, pchan->name); + } + /* Draw additional axes */ + 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); + glPopMatrix(); + } } } } @@ -1542,9 +1586,10 @@ static void draw_ebones(Object *ob, int dt) if(G.vd->zbuf) glDisable(GL_DEPTH_TEST); for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){ - if(!(eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))) - if(eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL)) - draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone); + if(eBone->layer & arm->layer) + if(!(eBone->flag & (BONE_HIDDEN_A|BONE_NO_DEFORM))) + if(eBone->flag & (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL)) + draw_sphere_bone_dist(smat, imat, eBone->flag, NULL, eBone); } if(G.vd->zbuf) glEnable(GL_DEPTH_TEST); @@ -1556,24 +1601,26 @@ static void draw_ebones(Object *ob, int dt) if(dt>OB_WIRE && arm->drawtype!=ARM_LINE) { index= 0; for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){ - if(!(eBone->flag & BONE_HIDDEN_A)) { - glPushMatrix(); - set_matrix_editbone(eBone); - - /* catch exception for bone with hidden parent */ - flag= eBone->flag; - if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A)) - flag &= ~BONE_CONNECTED; - - if(arm->drawtype==ARM_ENVELOPE) - draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else if(arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); - else { - draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); + if(eBone->layer & arm->layer) { + if(!(eBone->flag & BONE_HIDDEN_A)) { + glPushMatrix(); + set_matrix_editbone(eBone); + + /* catch exception for bone with hidden parent */ + flag= eBone->flag; + if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) + flag &= ~BONE_CONNECTED; + + if(arm->drawtype==ARM_ENVELOPE) + draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); + else if(arm->drawtype==ARM_B_BONE) + draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone); + else { + draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length); + } + + glPopMatrix(); } - - glPopMatrix(); } } } @@ -1591,43 +1638,45 @@ static void draw_ebones(Object *ob, int dt) index= 0; // do selection codes for (eBone=G.edbo.first; eBone; eBone=eBone->next){ - if(!(eBone->flag & BONE_HIDDEN_A)) { - - /* catch exception for bone with hidden parent */ - flag= eBone->flag; - if(eBone->parent && (eBone->parent->flag & BONE_HIDDEN_A)) - flag &= ~BONE_CONNECTED; - - if(arm->drawtype==ARM_ENVELOPE) { - if(dtflag, flag, 0, index, NULL, eBone); - } - else { - glPushMatrix(); - set_matrix_editbone(eBone); + if(eBone->layer & arm->layer) { + if(!(eBone->flag & BONE_HIDDEN_A)) { - if(arm->drawtype==ARM_LINE) - draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); - else if(arm->drawtype==ARM_B_BONE) - draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); - else - draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); + /* catch exception for bone with hidden parent */ + flag= eBone->flag; + if(eBone->parent && ((eBone->parent->flag & BONE_HIDDEN_A) || (eBone->parent->layer & arm->layer)==0) ) + flag &= ~BONE_CONNECTED; + + if(arm->drawtype==ARM_ENVELOPE) { + if(dtflag, flag, 0, index, NULL, eBone); + } + else { + glPushMatrix(); + set_matrix_editbone(eBone); + + if(arm->drawtype==ARM_LINE) + draw_line_bone(arm->flag, flag, 0, index, NULL, eBone); + else if(arm->drawtype==ARM_B_BONE) + draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone); + else + draw_bone(OB_WIRE, arm->flag, flag, 0, index, eBone->length); - glPopMatrix(); - } - - /* offset to parent */ - if (eBone->parent) { - BIF_ThemeColor(TH_WIRE); - glLoadName (-1); // -1 here is OK! - setlinestyle(3); - - glBegin(GL_LINES); - glVertex3fv(eBone->parent->tail); - glVertex3fv(eBone->head); - glEnd(); - - setlinestyle(0); + glPopMatrix(); + } + + /* offset to parent */ + if (eBone->parent) { + BIF_ThemeColor(TH_WIRE); + glLoadName (-1); // -1 here is OK! + setlinestyle(3); + + glBegin(GL_LINES); + glVertex3fv(eBone->parent->tail); + glVertex3fv(eBone->head); + glEnd(); + + setlinestyle(0); + } } } if(index!=-1) index++; @@ -1646,27 +1695,29 @@ static void draw_ebones(Object *ob, int dt) if(G.vd->zbuf) glDisable(GL_DEPTH_TEST); for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){ - if(!(eBone->flag & BONE_HIDDEN_A)) { - - if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); - else BIF_ThemeColor(TH_TEXT); - - /* Draw name */ - if(arm->flag & ARM_DRAWNAMES){ - VecMidf(vec, eBone->head, eBone->tail); - glRasterPos3fv(vec); - BMF_DrawString(G.font, " "); - BMF_DrawString(G.font, eBone->name); - } - /* Draw additional axes */ - if(arm->flag & ARM_DRAWAXES){ - glPushMatrix(); - set_matrix_editbone(eBone); - glTranslatef(0.0f, eBone->length, 0.0f); - drawaxes(eBone->length*0.25f, 0); - glPopMatrix(); + if(eBone->layer & arm->layer) { + if(!(eBone->flag & BONE_HIDDEN_A)) { + + if(eBone->flag & BONE_SELECTED) BIF_ThemeColor(TH_TEXT_HI); + else BIF_ThemeColor(TH_TEXT); + + /* Draw name */ + if(arm->flag & ARM_DRAWNAMES){ + VecMidf(vec, eBone->head, eBone->tail); + glRasterPos3fv(vec); + BMF_DrawString(G.font, " "); + BMF_DrawString(G.font, eBone->name); + } + /* Draw additional axes */ + if(arm->flag & ARM_DRAWAXES){ + glPushMatrix(); + set_matrix_editbone(eBone); + glTranslatef(0.0f, eBone->length, 0.0f); + drawaxes(eBone->length*0.25f, 0, OB_ARROWS); + glPopMatrix(); + } + } - } } @@ -1678,6 +1729,7 @@ static void draw_ebones(Object *ob, int dt) /* in view space */ static void draw_pose_paths(Object *ob) { + bArmature *arm= ob->data; bPoseChannel *pchan; float *fp; int a; @@ -1688,26 +1740,28 @@ static void draw_pose_paths(Object *ob) glLoadMatrixf(G.vd->viewmat); for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->path) { - - BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); - glBegin(GL_LINE_STRIP); - for(a=0, fp= pchan->path; apathlen; a++, fp+=3) - glVertex3fv(fp); - glEnd(); - - glPointSize(1.0); - BIF_ThemeColor(TH_WIRE); - glBegin(GL_POINTS); - for(a=0, fp= pchan->path; apathlen; a++, fp+=3) - glVertex3fv(fp); - glEnd(); - - BIF_ThemeColor(TH_TEXT_HI); - glBegin(GL_POINTS); - for(a=0, fp= pchan->path; apathlen; a+=10, fp+=30) - glVertex3fv(fp); - glEnd(); + if(pchan->bone->layer & arm->layer) { + if(pchan->path) { + + BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7); + glBegin(GL_LINE_STRIP); + for(a=0, fp= pchan->path; apathlen; a++, fp+=3) + glVertex3fv(fp); + glEnd(); + + glPointSize(1.0); + BIF_ThemeColor(TH_WIRE); + glBegin(GL_POINTS); + for(a=0, fp= pchan->path; apathlen; a++, fp+=3) + glVertex3fv(fp); + glEnd(); + + BIF_ThemeColor(TH_TEXT_HI); + glBegin(GL_POINTS); + for(a=0, fp= pchan->path; apathlen; a+=10, fp+=30) + glVertex3fv(fp); + glEnd(); + } } } @@ -1729,7 +1783,7 @@ static void draw_ghost_poses(Base *base) if(ob->action==NULL) return; - calc_action_range(ob->action, &start, &end); + calc_action_range(ob->action, &start, &end, 0); if(start==end) return; diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index d63d4e5009c..e3655beaac0 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -47,17 +47,22 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "DNA_camera_types.h" +#include "DNA_color_types.h" #include "DNA_image_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_object_types.h" #include "DNA_packedFile_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" +#include "BKE_colortools.h" #include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_main.h" @@ -77,6 +82,7 @@ #include "BIF_drawimage.h" #include "BIF_resources.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_editsima.h" #include "BIF_glutil.h" #include "BIF_space.h" @@ -593,16 +599,16 @@ static void draw_image_view_icon(void) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(G.sima->flag & SI_STICKYUVS) { - BIF_draw_icon(xPos, 5.0, ICON_STICKY2_UVS); + BIF_icon_draw(xPos, 5.0, ICON_STICKY2_UVS); xPos = 25.0; } else if(G.sima->flag & SI_LOCALSTICKY) { - BIF_draw_icon(xPos, 5.0, ICON_STICKY_UVS); + BIF_icon_draw(xPos, 5.0, ICON_STICKY_UVS); xPos = 25.0; } if(G.sima->flag & SI_SELACTFACE) { - BIF_draw_icon(xPos, 5.0, ICON_DRAW_UVFACES); + BIF_icon_draw(xPos, 5.0, ICON_DRAW_UVFACES); } glBlendFunc(GL_ONE, GL_ZERO); @@ -815,6 +821,17 @@ void do_imagebuts(unsigned short event) case B_SIMABRUSHCHANGE: allqueue(REDRAWIMAGE, 0); break; + + case B_SIMACURVES: + curvemapping_do_image(G.sima->cumap, G.sima->image); + allqueue(REDRAWIMAGE, 0); + break; + + case B_SIMARANGE: + curvemapping_set_black_white(G.sima->cumap, NULL, NULL); + curvemapping_do_image(G.sima->cumap, G.sima->image); + allqueue(REDRAWIMAGE, 0); + break; } } @@ -825,13 +842,18 @@ static void image_panel_properties(short cntrl) // IMAGE_HANDLER_PROPERTIES block= uiNewBlock(&curarea->uiblocks, "image_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiSetPanelHandler(IMAGE_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "Properties", "Image", 10, 230, 318, 204)==0) + if(uiNewPanel(curarea, block, "Properties", "Image", 10, 10, 318, 204)==0) return; if (G.sima->image && G.sima->image->ibuf) { - char str[32]; + char str[64]; sprintf(str, "Image: size %d x %d", G.sima->image->ibuf->x, G.sima->image->ibuf->y); + if(G.sima->image->ibuf->rect_float) + strcat(str, " 4x32 bits"); + else + strcat(str, " 4x8 bits"); + uiDefBut(block, LABEL, B_NOP, str, 10,180,300,19, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); @@ -890,7 +912,7 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES uiBlockBeginAlign(block); id= (ID*)Gip.clone.image; - std_libbuttons(block, 979, 40, 0, NULL, B_SIMACLONEBROWSE, id, 0, &G.sima->menunr, 0, 0, B_SIMACLONEDELETE, 0, 0); + std_libbuttons(block, 979, 40, 0, NULL, B_SIMACLONEBROWSE, ID_IM, 0, id, 0, &G.sima->menunr, 0, 0, B_SIMACLONEDELETE, 0, 0); uiDefButF(block, NUMSLI, B_SIMABRUSHCHANGE, "B ",979,20,230,19, &Gip.clone.alpha , 0.0, 1.0, 0, 0, "Blend clone image"); uiBlockEndAlign(block); @@ -901,6 +923,79 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES uiDefButBitS(block, TOG|BIT, IMAGEPAINT_TORUS, B_SIMABRUSHCHANGE, "Wrap", 890,1,50,19, &Gip.flag, 0, 0, 0, 0, "Enables torus wrapping"); } +static void image_panel_curves_reset(void *cumap_v, void *unused) +{ + 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_image(cumap, G.sima->image); + + allqueue(REDRAWIMAGE, 0); +} + + +static void image_panel_curves(short cntrl) // IMAGE_HANDLER_PROPERTIES +{ + uiBlock *block; + uiBut *bt; + + block= uiNewBlock(&curarea->uiblocks, "image_panel_curves", UI_EMBOSS, UI_HELV, curarea->win); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); + uiSetPanelHandler(IMAGE_HANDLER_CURVES); // for close and esc + if(uiNewPanel(curarea, block, "Curves", "Image", 10, 450, 318, 204)==0) + return; + + if (G.sima->image && G.sima->image->ibuf) { + rctf rect; + + if(G.sima->cumap==NULL) + G.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, G.sima->cumap, 'c', B_SIMACURVES, B_SIMAGEDRAW, &rect); + + 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, G.sima->cumap, NULL); + + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_SIMARANGE, "Min R:", 10, 120, 90, 19, G.sima->cumap->black, -1000.0f, 1000.0f, 10, 2, "Black level"); + uiDefButF(block, NUM, B_SIMARANGE, "Min G:", 10, 100, 90, 19, G.sima->cumap->black+1, -1000.0f, 1000.0f, 10, 2, "Black level"); + uiDefButF(block, NUM, B_SIMARANGE, "Min B:", 10, 80, 90, 19, G.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, G.sima->cumap->white, -1000.0f, 1000.0f, 10, 2, "White level"); + uiDefButF(block, NUM, B_SIMARANGE, "Max G:", 10, 30, 90, 19, G.sima->cumap->white+1, -1000.0f, 1000.0f, 10, 2, "White level"); + uiDefButF(block, NUM, B_SIMARANGE, "Max B:", 10, 10, 90, 19, G.sima->cumap->white+2, -1000.0f, 1000.0f, 10, 2, "White level"); + + } +} + +/* are there curves? curves visible? and curves do something? */ +static int image_curves_active(ScrArea *sa) +{ + SpaceImage *sima= sa->spacedata.first; + + if(sima->cumap) { + if(curvemapping_RGBA_does_something(sima->cumap)) { + short a; + for(a=0; ablockhandler[a] == IMAGE_HANDLER_CURVES) + return 1; + } + } + } + return 0; +} + static void image_blockhandlers(ScrArea *sa) { SpaceImage *sima= sa->spacedata.first; @@ -918,6 +1013,9 @@ static void image_blockhandlers(ScrArea *sa) case IMAGE_HANDLER_PAINT: image_panel_paint(sima->blockhandler[a+1]); break; + case IMAGE_HANDLER_CURVES: + image_panel_curves(sima->blockhandler[a+1]); + break; } /* clear action value for event */ sima->blockhandler[a+1]= 0; @@ -977,6 +1075,126 @@ static void imagespace_grid(SpaceImage *sima) } +static void sima_draw_alpha_backdrop(SpaceImage *sima, float x1, float y1, float xsize, float ysize) +{ + float tile= sima->zoom*15.0f; + float x, y, maxx, maxy; + + glColor3ub(100, 100, 100); + glRectf(x1, y1, x1 + sima->zoom*xsize, y1 + sima->zoom*ysize); + glColor3ub(160, 160, 160); + + maxx= x1+sima->zoom*xsize; + maxy= y1+sima->zoom*ysize; + + for(x=0; xzoom*x; + float fy= y1 + sima->zoom*y; + float tilex= tile, tiley= tile; + + if(fx+tile > maxx) + tilex= maxx-fx; + if(fy+tile > maxy) + tiley= maxy-fy; + + glRectf(fx, fy, fx + tilex, fy + tiley); + } + } + for(x=15; xzoom*x; + float fy= y1 + sima->zoom*y; + float tilex= tile, tiley= tile; + + if(fx+tile > maxx) + tilex= maxx-fx; + if(fy+tile > maxy) + tiley= maxy-fy; + + glRectf(fx, fy, fx + tilex, fy + tiley); + } + } +} + +static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti) +{ + + /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ + glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); + glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_UNSIGNED_INT, recti); + glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); +} + +static void sima_draw_alpha_pixelsf(float x1, float y1, int rectx, int recty, float *rectf) +{ + float *trectf= MEM_mallocN(rectx*recty*4, "temp"); + int a, b; + + for(a= rectx*recty -1, b= 4*a+3; a>=0; a--, b-=4) + trectf[a]= rectf[b]; + + glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, trectf); + MEM_freeN(trectf); + /* ogl trick below is slower... (on ATI 9600) */ +// glColorMask(1, 0, 0, 0); +// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+3); +// glColorMask(0, 1, 0, 0); +// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+2); +// glColorMask(0, 0, 1, 0); +// glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_RGBA, GL_FLOAT, rectf+1); +// glColorMask(1, 1, 1, 1); +} + +static void sima_draw_zbuf_pixels(float x1, float y1, int rectx, int recty, int *recti) +{ + if(recti==NULL) + return; + + /* zbuffer values are signed, so we need to shift color range */ + glPixelTransferf(GL_RED_SCALE, 0.5f); + glPixelTransferf(GL_GREEN_SCALE, 0.5f); + glPixelTransferf(GL_BLUE_SCALE, 0.5f); + glPixelTransferf(GL_RED_BIAS, 0.5f); + glPixelTransferf(GL_GREEN_BIAS, 0.5f); + glPixelTransferf(GL_BLUE_BIAS, 0.5f); + + glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_INT, recti); + + glPixelTransferf(GL_RED_SCALE, 1.0f); + glPixelTransferf(GL_GREEN_SCALE, 1.0f); + glPixelTransferf(GL_BLUE_SCALE, 1.0f); + glPixelTransferf(GL_RED_BIAS, 0.0f); + glPixelTransferf(GL_GREEN_BIAS, 0.0f); + glPixelTransferf(GL_BLUE_BIAS, 0.0f); +} + +static void sima_draw_zbuffloat_pixels(float x1, float y1, int rectx, int recty, float *rect_float) +{ + float bias, scale, *rectf; + int a; + + if(rect_float==NULL) + return; + + if(G.scene->camera && G.scene->camera->type==OB_CAMERA) { + bias= ((Camera *)G.scene->camera->data)->clipsta; + scale= 1.0f/((Camera *)G.scene->camera->data)->clipend; + } + else { + bias= 0.1f; + scale= 0.01f; + } + + rectf= MEM_mallocN(rectx*recty*4, "temp"); + for(a= rectx*recty -1; a>=0; a--) + rectf[a]= (rect_float[a]-bias)*scale; + + glaDrawPixelsSafe(x1, y1, rectx, recty, rectx, GL_LUMINANCE, GL_FLOAT, rectf); + + MEM_freeN(rectf); +} + void drawimagespace(ScrArea *sa, void *spacedata) { SpaceImage *sima= spacedata; @@ -1005,14 +1223,15 @@ void drawimagespace(ScrArea *sa, void *spacedata) what_image(sima); if(sima->image) { - if(sima->image->ibuf==0) { + if(sima->image->ibuf==NULL) { load_image(sima->image, IB_rect, G.sce, G.scene->r.cfra); + scrarea_queue_headredraw(sa); /* update header for image options */ } tag_image_time(sima->image); ibuf= sima->image->ibuf; } - if(ibuf==NULL || ibuf->rect==NULL) { + if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { calc_image_view(sima, 'f'); myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); BIF_ThemeColorShade(TH_BACK, 20); @@ -1033,7 +1252,7 @@ void drawimagespace(ScrArea *sa, void *spacedata) glPixelZoom((float)sima->zoom, (float)sima->zoom); if(sima->flag & SI_EDITTILE) { - glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->rect); + glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glPixelZoom(1.0, 1.0); @@ -1078,14 +1297,55 @@ void drawimagespace(ScrArea *sa, void *spacedata) /* rect= ibuf->rect; */ for(sy= 0; sy+dy<=ibuf->y; sy+= dy) { for(sx= 0; sx+dx<=ibuf->x; sx+= dx) { - glaDrawPixelsSafe(x1+sx*sima->zoom, y1+sy*sima->zoom, dx, dy, rect); + glaDrawPixelsSafe(x1+sx*sima->zoom, y1+sy*sima->zoom, dx, dy, dx, GL_RGBA, GL_UNSIGNED_BYTE, rect); } } MEM_freeN(rect); } - else - glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->rect); + else { + /* this part is generic image display */ + + if(sima->flag & SI_SHOW_ALPHA) { + if(ibuf->rect) + sima_draw_alpha_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->rect); + else if(ibuf->rect_float) + sima_draw_alpha_pixelsf(x1, y1, ibuf->x, ibuf->y, ibuf->rect_float); + } + else if(sima->flag & SI_SHOW_ZBUF) { + if(ibuf->zbuf) + sima_draw_zbuf_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf); + else + sima_draw_zbuffloat_pixels(x1, y1, ibuf->x, ibuf->y, ibuf->zbuf_float); + } + else { + if(sima->flag & SI_USE_ALPHA) { + sima_draw_alpha_backdrop(sima, x1, y1, (float)ibuf->x, (float)ibuf->y); + glEnable(GL_BLEND); + } + + /* detect if we need to redo the curve map. + ibuf->rect is zero for compositor and render results after change + also: if no curves are active, we only keep the float rect + */ + if(ibuf->rect_float) { + if(image_curves_active(sa)) { + if(ibuf->rect==NULL) + curvemapping_do_image(G.sima->cumap, G.sima->image); + } + else if(ibuf->rect) + imb_freerectImBuf(ibuf); + } + + if(ibuf->rect) + glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + else + glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float); + + if(sima->flag & SI_USE_ALPHA) + glDisable(GL_BLEND); + } + } if(Gip.current == IMAGEPAINT_CLONE) { int w, h; @@ -1102,7 +1362,7 @@ void drawimagespace(ScrArea *sa, void *spacedata) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glaDrawPixelsSafe(x1 + offx, y1 + offy, w, h, clonerect); + glaDrawPixelsSafe(x1 + offx, y1 + offy, w, h, w, GL_RGBA, GL_UNSIGNED_BYTE, clonerect); glDisable(GL_BLEND); MEM_freeN(clonerect); @@ -1119,6 +1379,7 @@ void drawimagespace(ScrArea *sa, void *spacedata) draw_image_transform(ibuf); + mywinset(sa->win); /* restore scissor after gla call... */ myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); draw_image_view_tool(); diff --git a/source/blender/src/drawimasel.c b/source/blender/src/drawimasel.c index f8d358a9051..83649aa839f 100644 --- a/source/blender/src/drawimasel.c +++ b/source/blender/src/drawimasel.c @@ -59,6 +59,7 @@ #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_imasel.h" #include "BIF_mywindow.h" #include "BIF_space.h" @@ -509,23 +510,23 @@ void draw_sima_area(SpaceImaSel *simasel) sy = simasel->deey+6; if (bitset(simasel->fase, IMS_FOUND_BIP)) { - BIF_draw_icon(sx+16*0, sy, ICON_BPIBFOLDER_HLT); + BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_HLT); } else if (bitset(simasel->fase, IMS_WRITE_NO_BIP)) { - BIF_draw_icon(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT); + BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT); } else { - BIF_draw_icon(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT); + BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT); } if (bitset(simasel->fase, IMS_KNOW_INF)) { - BIF_draw_icon(sx+16*1, sy, ICON_FOLDER_HLT); + BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_HLT); } else { - BIF_draw_icon(sx+16*1, sy, ICON_FOLDER_DEHLT); + BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_DEHLT); } if (bitset(simasel->fase, IMS_KNOW_IMA)) { - BIF_draw_icon(sx+16*2, sy, ICON_BLUEIMAGE_HLT); + BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_HLT); } else { - BIF_draw_icon(sx+16*2, sy, ICON_BLUEIMAGE_DEHLT); + BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_DEHLT); } } @@ -865,7 +866,7 @@ void drawimaselspace(ScrArea *sa, void *spacedata) myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375); if (simasel->fase == 0){ - checkdir(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); clear_ima_dir(simasel); } diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c index 407d5779354..e6280b6a6f4 100644 --- a/source/blender/src/drawipo.c +++ b/source/blender/src/drawipo.c @@ -2076,14 +2076,13 @@ int view2dzoom(unsigned short event) ScrArea *sa; float fac, dx, dy, wtemp; short mval[2], mvalo[2]; + short is_wheel= (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE); - areawinset(curarea->win); /* from buttons */ - curarea->head_swap= 0; getmouseco_areawin(mvalo); mval[0]= mvalo[0]; mval[1]= mvalo[1]; - while( (get_mbut()&(L_MOUSE|M_MOUSE)) || (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE) ) { + while( (get_mbut()&(L_MOUSE|M_MOUSE)) || is_wheel ) { /* regular mousewheel: zoom regular * alt-shift mousewheel: zoom y only @@ -2205,7 +2204,7 @@ int view2dzoom(unsigned short event) else BIF_wait_for_statechange(); /* return if we were using the mousewheel */ - if ( (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE) ) return 1; + if ( is_wheel ) return 1; } return 1; } @@ -2233,11 +2232,10 @@ int view2dmove(unsigned short event) /* return 1 when something was done */ float facx=0.0, facy=0.0, dx, dy, left=1.0, right=1.0; short mval[2], mvalo[2], leftret=1, mousebut; + short is_wheel= (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE); + + /* when wheel is used, we only draw it once */ - /* init */ - scrarea_do_windraw(curarea); - curarea->head_swap= 0; - /* try to do some zooming if the * middlemouse and ctrl are pressed * or if the mousewheel is being used. @@ -2248,19 +2246,17 @@ int view2dmove(unsigned short event) if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE; else mousebut = L_MOUSE; - if ( (G.qual & LR_CTRLKEY) || (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE) ) { + if ( (G.qual & LR_CTRLKEY) || is_wheel ) { /* patch for oops & buttonswin, standard scroll no zoom */ if(curarea->spacetype==SPACE_OOPS) { SpaceOops *soops= curarea->spacedata.first; if(soops->type==SO_OUTLINER); else if (view2dzoom(event)) { - curarea->head_swap= 0; return 0; } } else if(curarea->spacetype==SPACE_BUTS && (G.qual & LR_CTRLKEY)==0); else if (view2dzoom(event)) { - curarea->head_swap= 0; return 0; } } @@ -2268,67 +2264,64 @@ int view2dmove(unsigned short event) /* test where mouse is */ getmouseco_areawin(mvalo); - if ELEM7(curarea->spacetype, SPACE_IPO, SPACE_SEQ, SPACE_OOPS, SPACE_SOUND, SPACE_ACTION, SPACE_NLA, SPACE_TIME) - { + if ELEM7(curarea->spacetype, SPACE_IPO, SPACE_SEQ, SPACE_OOPS, SPACE_SOUND, SPACE_ACTION, SPACE_NLA, SPACE_TIME) { - if( BLI_in_rcti(&G.v2d->mask, (int)mvalo[0], (int)mvalo[1]) ) { - facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); - facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + if( BLI_in_rcti(&G.v2d->mask, (int)mvalo[0], (int)mvalo[1]) ) { + facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + } + /* stoopid exception to allow scroll in lefthand side */ + else if(curarea->spacetype==SPACE_ACTION && BLI_in_rcti(&G.v2d->mask, ACTWIDTH+(int)mvalo[0], (int)mvalo[1]) ) { + facx= 0.0f; + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + } + else if(curarea->spacetype==SPACE_NLA && BLI_in_rcti(&G.v2d->mask, NLAWIDTH+(int)mvalo[0], (int)mvalo[1]) ) { + facx= 0.0f; + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + } + else if(IN_2D_VERT_SCROLL((int)mvalo)) { + facy= -(G.v2d->tot.ymax-G.v2d->tot.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); + if(get_mbut() & mousebut) { + /* which part of scrollbar should move? */ + if(mvalo[1]< (vertymin+vertymax)/2 ) right= 0.0; + else left= 0.0; + leftret= 0; } - /* stoopid exception to allow scroll in lefthand side */ - else if(curarea->spacetype==SPACE_ACTION && BLI_in_rcti(&G.v2d->mask, ACTWIDTH+(int)mvalo[0], (int)mvalo[1]) ) { - facx= 0.0f; - facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - } - else if(curarea->spacetype==SPACE_NLA && BLI_in_rcti(&G.v2d->mask, NLAWIDTH+(int)mvalo[0], (int)mvalo[1]) ) { - facx= 0.0f; - facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - } - else if(IN_2D_VERT_SCROLL((int)mvalo)) { - facy= -(G.v2d->tot.ymax-G.v2d->tot.ymin)/(float)(G.v2d->mask.ymax-G.v2d->mask.ymin); - if(get_mbut() & mousebut) { - /* which part of scrollbar should move? */ - if(mvalo[1]< (vertymin+vertymax)/2 ) right= 0.0; - else left= 0.0; - leftret= 0; - } - if((event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE)) - facy= -facy; - } - else if(IN_2D_HORIZ_SCROLL((int)mvalo)) { - facx= -(G.v2d->tot.xmax-G.v2d->tot.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); - if(get_mbut() & mousebut) { - /* which part of scrollbar should move? */ - if(mvalo[0]< (horxmin+horxmax)/2 ) right= 0.0; - else left= 0.0; - leftret= 0; - } + if(is_wheel) + facy= -facy; + } + else if(IN_2D_HORIZ_SCROLL((int)mvalo)) { + facx= -(G.v2d->tot.xmax-G.v2d->tot.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin); + if(get_mbut() & mousebut) { + /* which part of scrollbar should move? */ + if(mvalo[0]< (horxmin+horxmax)/2 ) right= 0.0; + else left= 0.0; + leftret= 0; } } - else { - facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(curarea->winx); - facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(curarea->winy); - } + } + else { + facx= (G.v2d->cur.xmax-G.v2d->cur.xmin)/(float)(curarea->winx); + facy= (G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)(curarea->winy); + } - /* no x move in outliner */ - if(curarea->spacetype==SPACE_OOPS && G.v2d->scroll) facx= 0.0; - - /* no y move in audio & time */ - if ELEM(curarea->spacetype, SPACE_SOUND, SPACE_TIME) facy= 0.0; - - if(get_mbut() & mousebut && leftret) return 0; - if(facx==0.0 && facy==0.0) return 1; - - while( (get_mbut()&(L_MOUSE|M_MOUSE)) || - (event==WHEELUPMOUSE) || - (event==WHEELDOWNMOUSE) ) { + /* no x move in outliner */ + if(curarea->spacetype==SPACE_OOPS && G.v2d->scroll) facx= 0.0; + + /* no y move in audio & time */ + if ELEM(curarea->spacetype, SPACE_SOUND, SPACE_TIME) facy= 0.0; + + if(get_mbut() & mousebut && leftret) return 0; + if(facx==0.0 && facy==0.0) return 1; + + while( (get_mbut()&(L_MOUSE|M_MOUSE)) || is_wheel) { /* If the mousewheel is used with shift key * the scroll up and down. If the mousewheel * is used with the ctrl key then scroll left * and right. */ - if (event==WHEELUPMOUSE || event==WHEELDOWNMOUSE) { + if (is_wheel) { if(event==WHEELDOWNMOUSE) { facx= -facx; facy= -facy; } @@ -2356,8 +2349,6 @@ int view2dmove(unsigned short event) else return 0; break; } - mval[0]= mvalo[0]+1; // force redraw below - mval[1]= mvalo[1]+1; } else { getmouseco_areawin(mval); @@ -2365,7 +2356,7 @@ int view2dmove(unsigned short event) dy= facy*(mvalo[1]-mval[1]); } - if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || is_wheel) { ScrArea *sa; G.v2d->cur.xmin+= left*dx; @@ -2374,6 +2365,7 @@ int view2dmove(unsigned short event) G.v2d->cur.ymax+= right*dy; test_view2d(G.v2d, curarea->winx, curarea->winy); + sa= curarea; /* bad global */ view2d_do_locks(curarea, V2D_LOCK_COPY|V2D_LOCK_REDRAW); areawinset(sa->win); @@ -2383,15 +2375,13 @@ int view2dmove(unsigned short event) mvalo[0]= mval[0]; mvalo[1]= mval[1]; - } else BIF_wait_for_statechange(); /* return if we were using the mousewheel */ - if ( (event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE) ) return 1; + if ( is_wheel ) return 1; } - curarea->head_swap= 0; return 1; } diff --git a/source/blender/src/drawnla.c b/source/blender/src/drawnla.c index 2b0ba1a7ad3..e3436645adc 100644 --- a/source/blender/src/drawnla.c +++ b/source/blender/src/drawnla.c @@ -70,6 +70,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_mywindow.h" #include "BIF_resources.h" #include "BIF_screen.h" @@ -79,6 +80,7 @@ #include "BDR_editcurve.h" #include "blendef.h" +#include "butspace.h" #include "mydevice.h" #define TESTBASE_SAFE(base) ((base)->flag & SELECT) @@ -130,9 +132,9 @@ static void draw_nla_channels(void) if(ob->nlastrips.first && ob->action) { glEnable(GL_BLEND); if(ob->nlaflag & OB_NLA_OVERRIDE) - BIF_draw_icon_blended(x+5, y-8, ICON_NLA, TH_HEADER, 0); + BIF_icon_draw_blended(x+5, y-8, ICON_NLA, TH_HEADER, 0); else - BIF_draw_icon_blended(x+5, y-8, ICON_ACTION, TH_HEADER, 0); + BIF_icon_draw_blended(x+5, y-8, ICON_ACTION, TH_HEADER, 0); glDisable(GL_BLEND); } y-=NLACHANNELHEIGHT+NLACHANNELSKIP; @@ -154,7 +156,7 @@ static void draw_nla_channels(void) if(strip->flag & ACTSTRIP_ACTIVE) break; if(strip==NULL) { glEnable(GL_BLEND); - BIF_draw_icon_blended(x, y-8, ICON_DOT, TH_BACK, 0); + BIF_icon_draw_blended(x, y-8, ICON_DOT, TH_BACK, 0); glDisable(GL_BLEND); } @@ -178,7 +180,7 @@ static void draw_nla_channels(void) if(strip->flag & ACTSTRIP_ACTIVE) { glEnable(GL_BLEND); - BIF_draw_icon_blended(x+16, y-8, ICON_DOT, TH_BACK, 0); + BIF_icon_draw_blended(x+16, y-8, ICON_DOT, TH_BACK, 0); glDisable(GL_BLEND); } } @@ -460,9 +462,8 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES /* first labels, for simpler align code :) */ uiDefBut(block, LABEL, 0, "Timeline Range:", 10,180,300,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Blending:", 10,120,300,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Options:", 10,80,300,19, 0, 0, 0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Stride Support:", 10,40,300,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Blending:", 10,120,150,19, 0, 0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Options:", 160,120,150,19, 0, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); uiDefButF(block, NUM, B_NLA_PANEL, "Strip Start:", 10,160,150,19, &strip->start, -1000.0, strip->end-1, 100, 0, "First frame in the timeline"); @@ -482,18 +483,24 @@ static void nla_panel_properties(short cntrl) // NLA_HANDLER_PROPERTIES } uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,100,150,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in"); - uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 160,100,150,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out"); + uiDefButF(block, NUM, B_NLA_PANEL, "Blendin:", 10,100,145,19, &strip->blendin, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-in"); + uiDefButF(block, NUM, B_NLA_PANEL, "Blendout:", 10,80,145,19, &strip->blendout, 0.0, strip->actend-strip->actstart, 100, 0, "Number of frames of ease-out"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 10,60,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat"); - uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,60,75,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip"); - uiDefButS(block, TOG, B_NLA_PANEL, "Add", 230,60,75,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode"); + uiDefButF(block, NUM, B_NLA_PANEL, "Repeat:", 160,100,150,19, &strip->repeat, 0.001, 1000.0f, 100, 0, "Number of times the action should repeat"); + uiDefButBitS(block, TOG, ACTSTRIP_HOLDLASTFRAME, B_NLA_PANEL, "Hold", 160,80,75,19, &strip->flag, 0, 0, 0, 0, "Toggles whether to continue displaying the last frame past the end of the strip"); + uiDefButS(block, TOG, B_NLA_PANEL, "Add", 235,80,75,19, &strip->mode, 0, 0, 0, 0, "Toggles additive blending mode"); + uiBlockEndAlign(block); + + uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_NLA_PANEL, "Stride Path", 10, 50,140,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride"); + if(ob->dup_group) + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_NLA_PANEL, "Target:", 160,50, 150, 19, &strip->object, "Target Object in this group"); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, ACTSTRIP_USESTRIDE, B_NLA_PANEL, "Stride Path", 10,20,100,19, &strip->flag, 0, 0, 0, 0, "Plays action based on path position & stride"); - uiDefButBitS(block, TOG, OB_DISABLE_PATH, B_NLA_PANEL, "Disable Path", 110,20,100,19, &ob->ipoflag, 0, 0, 0, 0, "Plays action based on path position & stride"); - uiDefButF(block, NUM, B_NLA_PANEL, "Stride:", 210,20,100,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range"); + uiDefButBitS(block, TOG, OB_DISABLE_PATH, B_NLA_PANEL, "Disable", 10,20,60,19, &ob->ipoflag, 0, 0, 0, 0, "Disable path temporally, for editing cycles"); + + uiDefButF(block, NUM, B_NLA_PANEL, "Offs:", 70,20,120,19, &strip->actoffs, -500, 500.0, 100, 0, "Action offset in frames to tweak cycle of the action within the stride"); + uiDefButF(block, NUM, B_NLA_PANEL, "Stri:", 190,20,120,19, &strip->stridelen, 0.0001, 1000.0, 100, 0, "Distance covered by one complete cycle of the action specified in the Action Range"); uiDefButS(block, ROW, B_NLA_PANEL, "X", 10, 0, 33, 19, &strip->stride_axis, 1, 0, 0, 0, "Dominant axis for Stride Bone"); uiDefButS(block, ROW, B_NLA_PANEL, "Y", 43, 0, 33, 19, &strip->stride_axis, 1, 1, 0, 0, "Dominant axis for Stride Bone"); diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c new file mode 100644 index 00000000000..bdb3c0bf67f --- /dev/null +++ b/source/blender/src/drawnode.c @@ -0,0 +1,1729 @@ +/** + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "DNA_action_types.h" +#include "DNA_ipo_types.h" +#include "DNA_ID.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_texture_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_material.h" +#include "BKE_node.h" +#include "BKE_object.h" +#include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_interface.h" +#include "BIF_interface_icons.h" +#include "BIF_language.h" +#include "BIF_mywindow.h" +#include "BIF_previewrender.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" + +#include "BSE_drawipo.h" +#include "BSE_node.h" +#include "BSE_view.h" + +#include "BMF_Api.h" + +#include "MEM_guardedalloc.h" + +#include "RE_pipeline.h" + +#include "blendef.h" +#include "butspace.h" +#include "interface.h" /* urm... for rasterpos_safe, roundbox */ +#include "mydevice.h" + + + +static void snode_drawstring(SpaceNode *snode, char *str, int okwidth) +{ + char drawstr[NODE_MAXSTR]; + int width; + + if(str[0]==0 || okwidth<4) return; + + BLI_strncpy(drawstr, str, NODE_MAXSTR); + width= snode->aspect*BIF_GetStringWidth(snode->curfont, drawstr, 0); + + if(width > okwidth) { + int len= strlen(drawstr)-1; + + while(width > okwidth && len>=0) { + drawstr[len]= 0; + + width= snode->aspect*BIF_GetStringWidth(snode->curfont, drawstr, 0); + len--; + } + if(len==0) return; + } + BIF_DrawString(snode->curfont, drawstr, 0); + +} + +/* ************** Socket callbacks *********** */ + +/* NOTE: this is a block-menu, needs 0 events, otherwise the menu closes */ +static uiBlock *socket_vector_menu(void *butpoin_v) +{ + float *butpoin= butpoin_v; + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, "socket menu", UI_EMBOSS, UI_HELV, curarea->win); + + /* use this for a fake extra empy space around the buttons */ + uiDefBut(block, LABEL, 0, "", -4, -4, 188, 68, NULL, 0, 0, 0, 0, ""); + + uiBlockBeginAlign(block); + uiDefButF(block, NUMSLI, 0, "X ", 0,40,180,20, butpoin, -1.0, 1.0, 10, 0, ""); + uiDefButF(block, NUMSLI, 0, "Y ", 0,20,180,20, butpoin+1, -1.0, 1.0, 10, 0, ""); + uiDefButF(block, NUMSLI, 0, "Z ", 0,0,180,20, butpoin+2, -1.0, 1.0, 10, 0, ""); + + uiBlockSetDirection(block, UI_TOP); + + allqueue(REDRAWNODE, 0); + + return block; +} + +static void node_sync_cb(void *snode_v, void *node_v) +{ + SpaceNode *snode= snode_v; + + if(snode->treetype==NTREE_SHADER) { + nodeShaderSynchronizeID(node_v, 1); + allqueue(REDRAWBUTSSHADING, 0); + } +} + +/* ****************** GENERAL CALLBACKS FOR NODES ***************** */ + +static void node_ID_title_cb(void *node_v, void *unused_v) +{ + bNode *node= node_v; + + if(node->id) { + test_idbutton(node->id->name+2); /* library.c, verifies unique name */ + BLI_strncpy(node->name, node->id->name+2, 21); + + allqueue(REDRAWBUTSSHADING, 0); + allqueue(REDRAWNODE, 0); + allqueue(REDRAWOOPS, 0); + } +} + + +static void node_but_title_cb(void *node_v, void *but_v) +{ + bNode *node= node_v; + uiBut *bt= but_v; + BLI_strncpy(node->name, bt->drawstr, NODE_MAXSTR); + + allqueue(REDRAWNODE, 0); +} + + +/* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ + +static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block && node->id) { + uiBut *bt; + short width; + + uiBlockBeginAlign(block); + + /* name button */ + width= (short)(butr->xmax-butr->xmin - (node->id->us>1?19.0f:0.0f)); + bt= uiDefBut(block, TEX, B_NOP, "NT:", + butr->xmin, butr->ymin, width, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "NodeTree name"); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); + + /* user amount */ + if(node->id->us>1) { + char str1[32]; + sprintf(str1, "%d", node->id->us); + bt= uiDefBut(block, BUT, B_NOP, str1, + butr->xmax-19, butr->ymin, 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); + } + + uiBlockEndAlign(block); + } + return 19; +} + +static int node_buts_value(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + bNodeSocket *sock= node->outputs.first; /* first socket stores value */ + + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, + sock->ns.vec, 0.0f, 1.0f, 10, 2, ""); + + } + return 20; +} + +static int node_buts_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + 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+node->nr, "", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 12, + sock->ns.vec, 0.0f, 1.0f, 3, 0, ""); + uiDefButF(block, HSVCUBE, B_NODE_EXEC+node->nr, "", + butr->xmin, 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, "", + butr->xmin, 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); +} + +static int node_buts_mix_rgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + + /* blend type */ + bt=uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8", + 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; +} + +static int node_buts_valtorgb(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + if(node->storage) { + draw_colorband_buts_small(block, node->storage, butr, B_NODE_EXEC+node->nr); + } + } + return 40; +} + +static int node_buts_curvevec(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + curvemap_buttons(block, node->storage, 'v', B_NODE_EXEC+node->nr, B_REDR, butr); + } + return (int)(node->width-NODE_DY); +} + +static int node_buts_curvecol(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + curvemap_buttons(block, node->storage, 'c', B_NODE_EXEC+node->nr, B_REDR, butr); + } + return (int)(node->width-NODE_DY); +} + +static int node_buts_normal(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + bNodeSocket *sock= node->outputs.first; /* first socket stores normal */ + + uiDefButF(block, BUT_NORMAL, B_NODE_EXEC+node->nr, "", + butr->xmin, 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); +} + + + +/* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ + + +static void node_mat_alone_cb(void *node_v, void *unused) +{ + bNode *node= node_v; + + node->id= (ID *)copy_material((Material *)node->id); + + BIF_undo_push("Single user material"); + allqueue(REDRAWBUTSSHADING, 0); + allqueue(REDRAWNODE, 0); + allqueue(REDRAWOOPS, 0); +} + +static void node_browse_mat_cb(void *ntree_v, void *node_v) +{ + bNodeTree *ntree= ntree_v; + bNode *node= node_v; + + if(node->menunr<1) return; + + if(node->menunr==32767) { /* code for Add New */ + if(node->id) { + /* make copy, but make sure it doesnt have the node tag nor nodes */ + Material *ma= (Material *)node->id; + ma->id.us--; + ma= copy_material(ma); + ma->use_nodes= 0; + if(ma->nodetree) { + ntreeFreeTree(ma->nodetree); + MEM_freeN(ma->nodetree); + } + ma->nodetree= NULL; + node->id= (ID *)ma; + } + else node->id= (ID *)add_material("MatNode"); + } + else { + if(node->id) node->id->us--; + node->id= BLI_findlink(&G.main->mat, node->menunr-1); + id_us_plus(node->id); + } + BLI_strncpy(node->name, node->id->name+2, 21); + + nodeSetActive(ntree, node); + + allqueue(REDRAWBUTSSHADING, 0); + allqueue(REDRAWNODE, 0); + BIF_preview_changed(ID_MA); + + node->menunr= 0; +} + +static void node_new_mat_cb(void *ntree_v, void *node_v) +{ + bNodeTree *ntree= ntree_v; + bNode *node= node_v; + + node->id= (ID *)add_material("MatNode"); + BLI_strncpy(node->name, node->id->name+2, 21); + + nodeSetActive(ntree, node); + + allqueue(REDRAWBUTSSHADING, 0); + allqueue(REDRAWNODE, 0); + BIF_preview_changed(ID_MA); + +} + +static void node_texmap_cb(void *texmap_v, void *unused_v) +{ + init_mapping(texmap_v); +} + +static int node_shader_buts_material(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + 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); + 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); + uiBlockSetCol(block, TH_AUTO); + } + 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 */ + uiBlockSetCol(block, TH_AUTO); + uiDefButBitS(block, TOG, SH_NODE_MAT_DIFF, B_NODE_EXEC+node->nr, "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+node->nr, "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+node->nr, "Neg Normal", + butr->xmax-dx, butr->ymin, dx, 19, + &node->custom1, 0, 0, 0, 0, "Material Node uses inverted Normal"); + } + } + uiBlockEndAlign(block); + } + return 38; +} + +static int node_shader_buts_texture(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + + bt= uiDefIDPoinBut(block, test_texpoin_but, ID_TE, B_NODE_EXEC+node->nr, "", + butr->xmin, butr->ymin, butr->xmax-butr->xmin, 19, + &node->id, ""); + uiButSetFunc(bt, node_ID_title_cb, node, NULL); + + } + return 19; +} + + +static int node_shader_buts_mapping(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + 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+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->loc+1, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", 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+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->rot, -1000.0f, 1000.0f, 1000, 1, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->rot+1, -1000.0f, 1000.0f, 1000, 1, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", 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+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->size, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->size+1, -1000.0f, 1000.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", 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+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->min, -10.0f, 10.0f, 100, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->min+1, -10.0f, 10.0f, 100, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", 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+node->nr, "", butr->xmin+dx, dy, 2*dx, 19, texmap->max, -10.0f, 10.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", butr->xmin+3*dx, dy, 2*dx, 19, texmap->max+1, -10.0f, 10.0f, 10, 2, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", 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+node->nr, "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+node->nr, "Max", butr->xmin, dy, dx-4, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + + } + return 5*19 + 6; +} + + +/* only once called */ +static void node_shader_set_butfunc(bNodeType *ntype) +{ + switch(ntype->type) { + case NODE_GROUP: /* note, generic type, but put here because we call this function anyway */ + ntype->butfunc= node_buts_group; + break; + case SH_NODE_MATERIAL: + ntype->butfunc= node_shader_buts_material; + break; + case SH_NODE_TEXTURE: + ntype->butfunc= node_shader_buts_texture; + break; + case SH_NODE_NORMAL: + ntype->butfunc= node_buts_normal; + break; + case SH_NODE_CURVE_VEC: + ntype->butfunc= node_buts_curvevec; + break; + case SH_NODE_CURVE_RGB: + ntype->butfunc= node_buts_curvecol; + break; + case SH_NODE_MAPPING: + ntype->butfunc= node_shader_buts_mapping; + break; + case SH_NODE_VALUE: + ntype->butfunc= node_buts_value; + break; + case SH_NODE_RGB: + ntype->butfunc= node_buts_rgb; + break; + case SH_NODE_MIX_RGB: + ntype->butfunc= node_buts_mix_rgb; + break; + case SH_NODE_VALTORGB: + ntype->butfunc= node_buts_valtorgb; + break; + default: + ntype->butfunc= NULL; + } +} + +/* ****************** BUTTON CALLBACKS FOR COMPOSIT NODES ***************** */ + + + +static void node_browse_image_cb(void *ntree_v, void *node_v) +{ + bNodeTree *ntree= ntree_v; + bNode *node= node_v; + + nodeSetActive(ntree, node); + + if(node->menunr<1) return; + if(node->menunr==32767) { /* code for Load New */ + addqueue(curarea->win, UI_BUT_EVENT, B_NODE_LOADIMAGE); + } + else { + if(node->id) node->id->us--; + node->id= BLI_findlink(&G.main->image, node->menunr-1); + id_us_plus(node->id); + + BLI_strncpy(node->name, node->id->name+2, 21); + + addqueue(curarea->win, RENDERPREVIEW, 1); + } + node->menunr= 0; +} + +static void node_active_cb(void *ntree_v, void *node_v) +{ + nodeSetActive(ntree_v, node_v); +} +static void node_image_anim_cb(void *node_v, void *unused) +{ + bNode *node= node_v; + NodeImageAnim *nia; + + if(node->storage) { + MEM_freeN(node->storage); + node->storage= NULL; + } + else { + nia= node->storage= MEM_callocN(sizeof(NodeImageAnim), "node image anim"); + nia->sfra= nia->nr= 1; + } + allqueue(REDRAWNODE, 1); +} + +static int node_composit_buts_image(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + short dy= (short)butr->ymax-19; + char *strp; + + uiBlockBeginAlign(block); + uiBlockSetCol(block, TH_BUT_SETTING2); + + /* browse button */ + IDnames_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); + uiBlockSetCol(block, TH_AUTO); + } + else { + /* name button */ + short width= (short)(butr->xmax-butr->xmin-38.0f); + bt= uiDefBut(block, TEX, B_NOP, "IMA:", + butr->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); + bt= uiDefIconBut(block, BUT, B_NOP, ICON_SEQUENCE, + butr->xmax-19, dy, 19, 19, + node->id->name+2, 0.0, 19.0, 0, 0, "Enable/Disable Image animation"); + uiButSetFunc(bt, node_image_anim_cb, node, NULL); + } + if(node->storage) { + NodeImageAnim *nia= node->storage; + short width= (short)(butr->xmax-butr->xmin)/2; + + dy-= 19; + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Frs:", + butr->xmin, dy, width, 19, + &nia->frames, 0.0, 10000.0, 0, 0, "Amount of images used in animation"); + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "SFra:", + butr->xmin+width, dy, width, 19, + &nia->sfra, 1.0, 1000.0, 0, 0, "Start frame of animation"); + dy-= 19; + uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "First:", + butr->xmin, dy, width, 19, + &nia->nr, 0.0, 10000.0, 0, 0, "Number in image name, used as first in animation"); + uiDefButC(block, TOG, B_NODE_EXEC+node->nr, "Cycl", + butr->xmin+width, dy, width, 19, + &nia->cyclic, 0.0, 0.0, 0, 0, "Make animation go cyclic"); + + } + + } + if(node->storage) + return 57; + else + return 19; +} + +static char *scene_layer_menu(void) +{ + SceneRenderLayer *srl; + int len= 32 + 32*BLI_countlist(&G.scene->r.layers); + short a, nr; + char *str= MEM_callocN(len, "menu layers"); + + strcpy(str, "Active Layer %t"); + a= strlen(str); + for(nr=0, srl= G.scene->r.layers.first; srl; srl= srl->next, nr++) { + a+= sprintf(str+a, "|%s %%x%d", srl->name, nr); + } + + return str; +} + + +static int node_composit_buts_renderresult(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + char *strp; + + strp= scene_layer_menu(); + bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp, + butr->xmin, butr->ymin, (butr->xmax-butr->xmin), 19, + &node->custom1, 0, 0, 0, 0, "Choose Render Layer"); + uiButSetFunc(bt, node_but_title_cb, node, bt); + MEM_freeN(strp); + } + return 19; +} + +static int node_composit_buts_blur(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + + uiBlockBeginAlign(block); + bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "X:", + butr->xmin, butr->ymin, (butr->xmax-butr->xmin)/2, 19, + &node->custom1, 0, 256, 0, 0, ""); + bt=uiDefButS(block, NUM, B_NODE_EXEC+node->nr, "Y:", + butr->xmin+(butr->xmax-butr->xmin)/2, butr->ymin, (butr->xmax-butr->xmin)/2, 19, + &node->custom2, 0, 256, 0, 0, ""); + } + return 19; +} + +static int node_composit_buts_filter(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *butr) +{ + if(block) { + uiBut *bt; + + /* blend type */ + bt=uiDefButS(block, MENU, B_NODE_EXEC+node->nr, "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; +} + +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+node->nr, "Offs:", xstart, dy, 2*dx, 19, texmap->loc, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 19; + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "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+node->nr, "Min", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); + dy-= 19; + uiDefButBitI(block, TOG, TEXMAP_CLIP_MIN, B_NODE_EXEC+node->nr, "Max", xstart, dy, dx, 19, &texmap->flag, 0.0f, 0.0f, 0, 0, ""); + uiDefButF(block, NUM, B_NODE_EXEC+node->nr, "", xstart+dx, dy, dx, 19, texmap->min, -1000.0f, 1000.0f, 10, 2, ""); + } + return 80; +} + + +/* only once called */ +static void node_composit_set_butfunc(bNodeType *ntype) +{ + switch(ntype->type) { + case NODE_GROUP: /* note, generic type, but put here because we call this function anyway */ + ntype->butfunc= node_buts_group; + break; + case CMP_NODE_IMAGE: + ntype->butfunc= node_composit_buts_image; + break; + case CMP_NODE_R_RESULT: + ntype->butfunc= node_composit_buts_renderresult; + break; + case CMP_NODE_NORMAL: + ntype->butfunc= node_buts_normal; + break; + case CMP_NODE_CURVE_VEC: + ntype->butfunc= node_buts_curvevec; + break; + case CMP_NODE_CURVE_RGB: + ntype->butfunc= node_buts_curvecol; + break; + case CMP_NODE_VALUE: + ntype->butfunc= node_buts_value; + break; + case CMP_NODE_RGB: + ntype->butfunc= node_buts_rgb; + break; + case CMP_NODE_MIX_RGB: + ntype->butfunc= node_buts_mix_rgb; + break; + case CMP_NODE_VALTORGB: + ntype->butfunc= node_buts_valtorgb; + break; + case CMP_NODE_BLUR: + ntype->butfunc= node_composit_buts_blur; + break; + case CMP_NODE_FILTER: + ntype->butfunc= node_composit_buts_filter; + break; + case CMP_NODE_MAP_VALUE: + ntype->butfunc= node_composit_buts_map_value; + break; + default: + ntype->butfunc= NULL; + } +} + + +/* ******* init draw callbacks for all tree types, only called in usiblender.c, once ************* */ + +void init_node_butfuncs(void) +{ + bNodeType **typedefs; + + /* shader nodes */ + typedefs= node_all_shaders; /* BKE_node.h */ + while( *typedefs) { + node_shader_set_butfunc(*typedefs); + typedefs++; + } + /* composit nodes */ + typedefs= node_all_composit; /* BKE_node.h */ + while( *typedefs) { + node_composit_set_butfunc(*typedefs); + typedefs++; + } +} + +/* ************** Generic drawing ************** */ + +static void draw_nodespace_grid(SpaceNode *snode) +{ + float start, step= 25.0f; + + BIF_ThemeColorShade(TH_BACK, -10); + + start= snode->v2d.cur.xmin -fmod(snode->v2d.cur.xmin, step); + + glBegin(GL_LINES); + for(; startv2d.cur.xmax; start+=step) { + glVertex2f(start, snode->v2d.cur.ymin); + glVertex2f(start, snode->v2d.cur.ymax); + } + + start= snode->v2d.cur.ymin -fmod(snode->v2d.cur.ymin, step); + for(; startv2d.cur.ymax; start+=step) { + glVertex2f(snode->v2d.cur.xmin, start); + glVertex2f(snode->v2d.cur.xmax, start); + } + + /* X and Y axis */ + BIF_ThemeColorShade(TH_BACK, -18); + glVertex2f(0.0f, snode->v2d.cur.ymin); + glVertex2f(0.0f, snode->v2d.cur.ymax); + glVertex2f(snode->v2d.cur.xmin, 0.0f); + glVertex2f(snode->v2d.cur.xmax, 0.0f); + + glEnd(); +} + + +static void nodeshadow(rctf *rct, float radius, float aspect, int select) +{ + float rad; + float a; + char alpha= 2; + + glEnable(GL_BLEND); + + if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f) + rad= (rct->ymax-rct->ymin-10.0f)/2.0f; + else + rad= radius; + + if(select) a= 10.0f*aspect; else a= 7.0f*aspect; + for(; a>0.0f; a-=aspect) { + /* alpha ranges from 2 to 20 or so */ + glColor4ub(0, 0, 0, alpha); + alpha+= 2; + + gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a); + } + + /* outline emphasis */ + glEnable( GL_LINE_SMOOTH ); + glColor4ub(0, 0, 0, 100); + gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius); + glDisable( GL_LINE_SMOOTH ); + + glDisable(GL_BLEND); +} + +/* nice AA filled circle */ +static void socket_circle_draw(float x, float y, float size, int type, int select) +{ + /* 16 values of sin function */ + static float si[16] = { + 0.00000000, 0.39435585,0.72479278,0.93775213, + 0.99871650,0.89780453,0.65137248,0.29936312, + -0.10116832,-0.48530196,-0.79077573,-0.96807711, + -0.98846832,-0.84864425,-0.57126821,-0.20129852 + }; + /* 16 values of cos function */ + static float co[16] ={ + 1.00000000,0.91895781,0.68896691,0.34730525, + -0.05064916,-0.44039415,-0.75875812,-0.95413925, + -0.99486932,-0.87434661,-0.61210598,-0.25065253, + 0.15142777,0.52896401,0.82076344,0.97952994, + }; + int a; + + if(select==0) { + if(type==-1) + glColor3ub(0, 0, 0); + else if(type==SOCK_VALUE) + glColor3ub(160, 160, 160); + else if(type==SOCK_VECTOR) + glColor3ub(100, 100, 200); + else if(type==SOCK_RGBA) + glColor3ub(200, 200, 40); + else + glColor3ub(100, 200, 100); + } + else { + if(type==SOCK_VALUE) + glColor3ub(200, 200, 200); + else if(type==SOCK_VECTOR) + glColor3ub(140, 140, 240); + else if(type==SOCK_RGBA) + glColor3ub(240, 240, 100); + else + glColor3ub(140, 240, 140); + } + + glBegin(GL_POLYGON); + for(a=0; a<16; a++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + + glColor4ub(0, 0, 0, 150); + glEnable(GL_BLEND); + glEnable( GL_LINE_SMOOTH ); + glBegin(GL_LINE_LOOP); + for(a=0; a<16; a++) + glVertex2f(x+size*si[a], y+size*co[a]); + glEnd(); + glDisable( GL_LINE_SMOOTH ); + glDisable(GL_BLEND); +} + +/* not a callback */ +static void node_draw_preview(bNodePreview *preview, rctf *prv) +{ + float scale= (prv->xmax-prv->xmin)/((float)preview->xsize); + float centx= prv->xmin + 0.5*(prv->xmax-prv->xmin); + float centy= prv->ymin + 0.5*(prv->ymax-prv->ymin); + + /* draw standard bacdrop to show alpha */ + glBegin(GL_TRIANGLES); + glColor3f(0.625f, 0.625f, 0.625f); + glVertex2f(prv->xmin, prv->ymin); + glVertex2f(prv->xmax, prv->ymin); + glVertex2f(centx, centy); + glVertex2f(prv->xmin, prv->ymax); + glVertex2f(prv->xmax, prv->ymax); + glVertex2f(centx, centy); + + glColor3f(0.25f, 0.25f, 0.25f); + glVertex2f(prv->xmin, prv->ymin); + glVertex2f(prv->xmin, prv->ymax); + glVertex2f(centx, centy); + glVertex2f(prv->xmax, prv->ymin); + glVertex2f(prv->xmax, prv->ymax); + glVertex2f(centx, centy); + glEnd(); + + glPixelZoom(scale, scale); + glEnable(GL_BLEND); + + glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_FLOAT, preview->rect); + + glDisable(GL_BLEND); + glPixelZoom(1.0f, 1.0f); + +} + +/* based on settings in node, sets drawing rect info. each redraw! */ +static void node_update_hidden(bNode *node) +{ + bNodeSocket *nsock; + float rad, drad, hiddenrad= HIDDEN_RAD; + int totin=0, totout=0, tot; + + /* calculate minimal radius */ + for(nsock= node->inputs.first; nsock; nsock= nsock->next) + if(!(nsock->flag & SOCK_HIDDEN)) + totin++; + for(nsock= node->outputs.first; nsock; nsock= nsock->next) + if(!(nsock->flag & SOCK_HIDDEN)) + totout++; + + tot= MAX2(totin, totout); + if(tot>4) { + hiddenrad += 5.0*(float)(tot-4); + } + + node->totr.xmin= node->locx; + node->totr.xmax= node->locx + 3*hiddenrad + node->miniwidth; + node->totr.ymax= node->locy + (hiddenrad - 0.5f*NODE_DY); + node->totr.ymin= node->totr.ymax - 2*hiddenrad; + + /* output sockets */ + rad=drad= M_PI/(1.0f + (float)totout); + + for(nsock= node->outputs.first; nsock; nsock= nsock->next) { + if(!(nsock->flag & SOCK_HIDDEN)) { + nsock->locx= node->totr.xmax - hiddenrad + sin(rad)*hiddenrad; + nsock->locy= node->totr.ymin + hiddenrad + cos(rad)*hiddenrad; + rad+= drad; + } + } + + /* input sockets */ + rad=drad= - M_PI/(1.0f + (float)totin); + + for(nsock= node->inputs.first; nsock; nsock= nsock->next) { + if(!(nsock->flag & SOCK_HIDDEN)) { + nsock->locx= node->totr.xmin + hiddenrad + sin(rad)*hiddenrad; + nsock->locy= node->totr.ymin + hiddenrad + cos(rad)*hiddenrad; + rad+= drad; + } + } +} + +/* based on settings in node, sets drawing rect info. each redraw! */ +static void node_update(bNode *node) +{ + bNodeSocket *nsock; + float dy= node->locy; + + /* header */ + dy-= NODE_DY; + + /* 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)) { + nsock->locx= node->locx + node->width; + nsock->locy= dy - NODE_DYS; + 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; + + /* preview rect? */ + if(node->flag & NODE_PREVIEW) { + /* only recalculate size when there's a preview actually, otherwise we use stored result */ + if(node->preview && node->preview->rect) { + float aspect= 1.0f; + + if(node->preview && node->preview->xsize && node->preview->ysize) + aspect= (float)node->preview->ysize/(float)node->preview->xsize; + + dy-= NODE_DYS/2; + node->prvr.ymax= dy; + node->prvr.ymin= dy - aspect*(node->width-NODE_DY); + dy= node->prvr.ymin - NODE_DYS/2; + } + else { + float oldh= node->prvr.ymax - node->prvr.ymin; + if(oldh==0.0f) + oldh= node->width-NODE_DY; + dy-= NODE_DYS/2; + node->prvr.ymax= dy; + node->prvr.ymin= dy - oldh; + dy= node->prvr.ymin - NODE_DYS/2; + } + } + + /* buttons rect? */ + if((node->flag & NODE_OPTIONS) && node->typeinfo->butfunc) { + 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; + } + + /* input sockets */ + for(nsock= node->inputs.first; nsock; nsock= nsock->next) { + if(!(nsock->flag & SOCK_HIDDEN)) { + nsock->locx= node->locx; + nsock->locy= dy - NODE_DYS; + dy-= NODE_DY; + } + } + + /* 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; + node->totr.ymin= dy; +} + +/* 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) +{ + bNodeTree *ngroup= (bNodeTree *)gnode->id; + bNode *node; + bNodeSocket *nsock; + rctf *rect= &gnode->totr; + int counter; + + /* center them, is a bit of abuse of locx and locy though */ + for(node= ngroup->nodes.first; node; node= node->next) { + node->locx+= gnode->locx; + node->locy+= gnode->locy; + if(node->flag & NODE_HIDDEN) + node_update_hidden(node); + else + node_update(node); + node->locx-= gnode->locx; + node->locy-= gnode->locy; + } + counter= 1; + for(node= ngroup->nodes.first; node; node= node->next) { + if(counter) { + *rect= node->totr; + counter= 0; + } + else + BLI_union_rctf(rect, &node->totr); + } + if(counter==1) return; /* should be prevented? */ + + rect->xmin-= NODE_DY; + rect->ymin-= NODE_DY; + rect->xmax+= NODE_DY; + rect->ymax+= NODE_DY; + + /* output sockets */ + for(nsock= gnode->outputs.first; nsock; nsock= nsock->next) { + nsock->locx= rect->xmax; + nsock->locy= nsock->tosock->locy; + } + + /* input sockets */ + for(nsock= gnode->inputs.first; nsock; nsock= nsock->next) { + nsock->locx= rect->xmin; + nsock->locy= nsock->tosock->locy; + } +} + +static void node_scaling_widget(int color_id, float aspect, float xmin, float ymin, float xmax, float ymax) +{ + float dx; + float dy; + + dx= 0.5f*(xmax-xmin); + dy= 0.5f*(ymax-ymin); + + BIF_ThemeColorShade(color_id, +30); + fdrawline(xmin, ymin, xmax, ymax); + fdrawline(xmin+dx, ymin, xmax, ymax-dy); + + BIF_ThemeColorShade(color_id, -10); + fdrawline(xmin, ymin+aspect, xmax, ymax+aspect); + fdrawline(xmin+dx, ymin+aspect, xmax, ymax-dy+aspect); +} + +static int node_get_colorid(bNode *node) +{ + if(node->typeinfo->nclass==NODE_CLASS_INPUT) + return TH_NODE_IN_OUT; + if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + if(node->flag & NODE_DO_OUTPUT) + return TH_NODE_IN_OUT; + else + return TH_NODE; + } + if(node->typeinfo->nclass==NODE_CLASS_GENERATOR) + return TH_NODE_GENERATOR; + if(node->typeinfo->nclass==NODE_CLASS_OPERATOR) + return TH_NODE_OPERATOR; + if(node->typeinfo->nclass==NODE_CLASS_GROUP) + return TH_NODE_GROUP; + return TH_NODE; +} + +static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node) +{ + bNodeSocket *sock; + uiBut *bt; + rctf *rct= &node->totr; + float slen, iconofs; + int ofs, color_id= node_get_colorid(node); + + uiSetRoundBox(15-4); + nodeshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT); + + /* header */ + if(color_id==TH_NODE) + BIF_ThemeColorShade(color_id, -20); + else + BIF_ThemeColor(color_id); + + uiSetRoundBox(3); + uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); + + /* show/hide icons, note this sequence is copied in editnode.c */ + iconofs= rct->xmax; + + if(node->typeinfo->flag & NODE_PREVIEW) { + int icon_id; + + if(node->flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT)) + icon_id= ICON_MATERIAL; + else + icon_id= ICON_MATERIAL_DEHLT; + iconofs-= 18.0f; + glEnable(GL_BLEND); + BIF_icon_set_aspect(icon_id, snode->aspect); + BIF_icon_draw_blended(iconofs, rct->ymax-NODE_DY+2, icon_id, 0, -60); + glDisable(GL_BLEND); + } + if(node->type == NODE_GROUP) { + iconofs-= 18.0f; + glEnable(GL_BLEND); + BIF_icon_set_aspect(ICON_NODE, snode->aspect); + BIF_icon_draw_blended(iconofs, rct->ymax-NODE_DY+2, ICON_NODE, 0, -60); + glDisable(GL_BLEND); + } + if(node->typeinfo->flag & NODE_OPTIONS) { + iconofs-= 18.0f; + glEnable(GL_BLEND); + BIF_icon_set_aspect(ICON_BUTS, snode->aspect); + BIF_icon_draw_blended(iconofs, rct->ymax-NODE_DY+2, ICON_BUTS, 0, -60); + glDisable(GL_BLEND); + } + if(node->outputs.first) { + int shade; + /* socket selector */ + iconofs-= 18.0f; + if(node_has_hidden_sockets(node)) + shade= -40; + else + shade= -90; + glEnable(GL_BLEND); + BIF_icon_set_aspect(ICON_PLUS, snode->aspect); + BIF_icon_draw_blended(iconofs, rct->ymax-NODE_DY+2, ICON_PLUS, 0, shade); + glDisable(GL_BLEND); + } + + /* title */ + if(node->flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColorBlendShade(TH_TEXT, color_id, 0.4, 10); + + /* open/close entirely? */ + ui_draw_tria_icon(rct->xmin+8.0f, rct->ymax-NODE_DY+4.0f, snode->aspect, 'v'); + + if(node->flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColor(TH_TEXT); + + ui_rasterpos_safe(rct->xmin+19.0f, rct->ymax-NODE_DY+5.0f, snode->aspect); + snode_drawstring(snode, node->name, (int)(iconofs - rct->xmin-18.0f)); + + /* body */ + BIF_ThemeColor(TH_NODE); + uiSetRoundBox(8); + uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax-NODE_DY, BASIS_RAD); + + /* scaling indicator */ + node_scaling_widget(TH_NODE, snode->aspect, rct->xmax-BASIS_RAD*snode->aspect, rct->ymin, rct->xmax, rct->ymin+BASIS_RAD*snode->aspect); + + /* outline active emphasis */ + if(node->flag & NODE_ACTIVE) { + glEnable(GL_BLEND); + glColor4ub(200, 200, 200, 140); + uiSetRoundBox(15-4); + gl_round_box(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, BASIS_RAD); + glDisable(GL_BLEND); + } + + /* we make buttons for input sockets, if... */ + if(node->flag & NODE_OPTIONS) { + if(node->inputs.first || node->typeinfo->butfunc) { + uiBlock *block= uiNewBlock(NULL, "node buttons", UI_EMBOSS, UI_HELV, sa->win); + BLI_addtail(&sa->uiblocks, block); + uiBlockSetFlag(block, UI_BLOCK_NO_HILITE); + if(snode->id) + uiSetButLock(snode->id->lib!=NULL, "Can't edit library data"); + node->block= block; + } + } + + /* hurmf... another candidate for callback, have to see how this works first */ + if(node->id && node->block && snode->treetype==NTREE_SHADER) + nodeShaderSynchronizeID(node, 0); + + /* socket inputs, buttons */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + + if(node->block && sock->link==NULL) { + float *butpoin= sock->ns.vec; + + if(node->type==NODE_GROUP && sock->tosock) + butpoin= sock->tosock->ns.vec; + + if(sock->type==SOCK_VALUE) { + bt= uiDefButF(node->block, NUM, B_NODE_EXEC+node->nr, sock->name, + (short)sock->locx+NODE_DYS, (short)(sock->locy)-9, (short)node->width-NODE_DY, 17, + butpoin, 0.0f, 1.0f, 10, 2, ""); + uiButSetFunc(bt, node_sync_cb, snode, node); + } + else if(sock->type==SOCK_VECTOR) { + uiDefBlockBut(node->block, socket_vector_menu, butpoin, sock->name, + (short)sock->locx+NODE_DYS, (short)sock->locy-9, (short)node->width-NODE_DY, 17, + ""); + } + else if(node->block && sock->type==SOCK_RGBA) { + short labelw= node->width-NODE_DY-40, width; + + if(labelw>0) width= 40; else width= node->width-NODE_DY; + + bt= uiDefButF(node->block, COL, B_NODE_EXEC+node->nr, "", + (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(node->block, LABEL, 0, sock->name, + (short)(sock->locx+NODE_DYS) + 40, (short)sock->locy-8, labelw, 15, + NULL, 0, 0, 0, 0, ""); + } + } + else { + BIF_ThemeColor(TH_TEXT); + ui_rasterpos_safe(sock->locx+8.0f, sock->locy-5.0f, snode->aspect); + BIF_DrawString(snode->curfont, sock->name, 0); + } + } + } + + /* socket outputs */ + for(sock= node->outputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + + BIF_ThemeColor(TH_TEXT); + ofs= 0; + slen= snode->aspect*BIF_GetStringWidth(snode->curfont, sock->name, 0); + while(slen > node->width) { + ofs++; + slen= snode->aspect*BIF_GetStringWidth(snode->curfont, sock->name+ofs, 0); + } + ui_rasterpos_safe(sock->locx-8.0f-slen, sock->locy-5.0f, snode->aspect); + BIF_DrawString(snode->curfont, sock->name+ofs, 0); + } + } + + /* preview */ + if(node->flag & NODE_PREVIEW) + if(node->preview && node->preview->rect) + node_draw_preview(node->preview, &node->prvr); + + /* buttons */ + if(node->flag & NODE_OPTIONS) { + if(node->typeinfo->butfunc) { + node->typeinfo->butfunc(node->block, snode->nodetree, node, &node->butr); + } + uiDrawBlock(node->block); + } + +} + +void node_draw_hidden(SpaceNode *snode, bNode *node) +{ + 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); + + /* shadow */ + uiSetRoundBox(15); + nodeshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT); + + /* body */ + BIF_ThemeColor(color_id); + uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); + + /* outline active emphasis */ + if(node->flag & NODE_ACTIVE) { + glEnable(GL_BLEND); + glColor4ub(200, 200, 200, 140); + gl_round_box(GL_LINE_LOOP, rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); + glDisable(GL_BLEND); + } + + /* title */ + if(node->flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColorBlendShade(TH_TEXT, color_id, 0.4, 10); + + /* open entirely icon */ + ui_draw_tria_icon(rct->xmin+9.0f, centy-6.0f, snode->aspect, 'h'); + + if(node->flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColor(TH_TEXT); + + if(node->miniwidth>0.0f) { + ui_rasterpos_safe(rct->xmin+21.0f, centy-4.0f, snode->aspect); + snode_drawstring(snode, node->name, (int)(rct->xmax - rct->xmin-18.0f -12.0f)); + } + + /* scale widget thing */ + BIF_ThemeColorShade(color_id, -10); + dx= 10.0f; + fdrawline(rct->xmax-dx, centy-4.0f, rct->xmax-dx, centy+4.0f); + fdrawline(rct->xmax-dx-3.0f*snode->aspect, centy-4.0f, rct->xmax-dx-3.0f*snode->aspect, centy+4.0f); + + BIF_ThemeColorShade(color_id, +30); + dx-= snode->aspect; + fdrawline(rct->xmax-dx, centy-4.0f, rct->xmax-dx, centy+4.0f); + fdrawline(rct->xmax-dx-3.0f*snode->aspect, centy-4.0f, rct->xmax-dx-3.0f*snode->aspect, centy+4.0f); + + /* sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + } + + for(sock= node->outputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + } +} + +/* note; this is used for fake links in groups too */ +void node_draw_link(SpaceNode *snode, bNodeLink *link) +{ + float vec[4][3]; + float dist, spline_step, mx=0.0f, my=0.0f; + int curve_res, do_shaded= 1, th_col1= TH_WIRE, th_col2= TH_WIRE; + + if(link->fromnode==NULL && link->tonode==NULL) + return; + + /* this is dragging link */ + if(link->fromnode==NULL || link->tonode==NULL) { + short mval[2]; + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + BIF_ThemeColor(TH_WIRE); + do_shaded= 0; + } + else { + /* a bit ugly... but thats how we detect the internal group links */ + if(link->fromnode==link->tonode) { + BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.25f); + do_shaded= 0; + } + else { + /* check cyclic */ + if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF) { + if(link->fromnode->flag & SELECT) + th_col1= TH_EDGE_SELECT; + if(link->tonode->flag & SELECT) + th_col2= TH_EDGE_SELECT; + } + else { + BIF_ThemeColor(TH_REDALERT); + do_shaded= 0; + } + } + } + + vec[0][2]= vec[1][2]= vec[2][2]= vec[3][2]= 0.0; /* only 2d spline, set the Z to 0*/ + + /* in v0 and v3 we put begin/end points */ + if(link->fromnode) { + vec[0][0]= link->fromsock->locx; + vec[0][1]= link->fromsock->locy; + } + else { + vec[0][0]= mx; + vec[0][1]= my; + } + if(link->tonode) { + vec[3][0]= link->tosock->locx; + vec[3][1]= link->tosock->locy; + } + else { + vec[3][0]= mx; + vec[3][1]= my; + } + + dist= 0.5f*ABS(vec[0][0] - vec[3][0]); + + /* check direction later, for top sockets */ + vec[1][0]= vec[0][0]+dist; + vec[1][1]= vec[0][1]; + + vec[2][0]= vec[3][0]-dist; + vec[2][1]= vec[3][1]; + + if( MIN4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) > G.v2d->cur.xmax); /* clipped */ + else if ( MAX4(vec[0][0], vec[1][0], vec[2][0], vec[3][0]) < G.v2d->cur.xmin); /* clipped */ + else { + curve_res = 24; + + /* we can reuse the dist variable here to increment the GL curve eval amount*/ + dist = 1.0f/curve_res; + spline_step = 0.0f; + + glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, vec[0]); + glBegin(GL_LINE_STRIP); + while (spline_step < 1.000001f) { + if(do_shaded) + BIF_ThemeColorBlend(th_col1, th_col2, spline_step); + glEvalCoord1f(spline_step); + spline_step += dist; + } + glEnd(); + } +} + +static void node_draw_nodetree(ScrArea *sa, SpaceNode *snode, bNodeTree *ntree) +{ + bNode *node; + bNodeLink *link; + int a; + + if(ntree==NULL) return; /* groups... */ + + /* node lines */ + glEnable(GL_BLEND); + glEnable( GL_LINE_SMOOTH ); + for(link= ntree->links.first; link; link= link->next) + node_draw_link(snode, link); + glDisable(GL_BLEND); + glDisable( GL_LINE_SMOOTH ); + + /* not selected first */ + for(a=0, node= ntree->nodes.first; node; node= node->next, a++) { + node->block= NULL; /* were freed */ + node->nr= a; /* index of node in list, used for exec event code */ + if(!(node->flag & SELECT)) { + if(node->flag & NODE_GROUP_EDIT); + else if(node->flag & NODE_HIDDEN) + node_draw_hidden(snode, node); + else + node_draw_basis(sa, snode, node); + } + } + + /* selected */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + if(node->flag & NODE_GROUP_EDIT); + else if(node->flag & NODE_HIDDEN) + node_draw_hidden(snode, node); + else + node_draw_basis(sa, snode, node); + } + } +} + +/* fake links from groupnode to internal nodes */ +static void node_draw_group_links(SpaceNode *snode, bNode *gnode) +{ + bNodeLink fakelink; + bNodeSocket *sock; + + glEnable(GL_BLEND); + glEnable( GL_LINE_SMOOTH ); + + fakelink.tonode= fakelink.fromnode= gnode; + + for(sock= gnode->inputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(sock->tosock) { + fakelink.fromsock= sock; + fakelink.tosock= sock->tosock; + node_draw_link(snode, &fakelink); + } + } + } + + for(sock= gnode->outputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(sock->tosock) { + fakelink.tosock= sock; + fakelink.fromsock= sock->tosock; + node_draw_link(snode, &fakelink); + } + } + } + + glDisable(GL_BLEND); + glDisable( GL_LINE_SMOOTH ); +} + +/* groups are, on creation, centered around 0,0 */ +static void node_draw_group(ScrArea *sa, SpaceNode *snode, bNode *gnode) +{ + bNodeTree *ngroup= (bNodeTree *)gnode->id; + bNodeSocket *sock; + rctf rect= gnode->totr; + + /* backdrop header */ + glEnable(GL_BLEND); + uiSetRoundBox(3); + BIF_ThemeColorShadeAlpha(TH_NODE_GROUP, 0, -70); + gl_round_box(GL_POLYGON, rect.xmin, rect.ymax, rect.xmax, rect.ymax+NODE_DY, BASIS_RAD); + + /* backdrop body */ + BIF_ThemeColorShadeAlpha(TH_BACK, -8, -70); + uiSetRoundBox(12); + gl_round_box(GL_POLYGON, rect.xmin, rect.ymin, rect.xmax, rect.ymax, BASIS_RAD); + + /* selection outline */ + uiSetRoundBox(15); + glColor4ub(200, 200, 200, 140); + glEnable( GL_LINE_SMOOTH ); + gl_round_box(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax+NODE_DY, BASIS_RAD); + glDisable( GL_LINE_SMOOTH ); + glDisable(GL_BLEND); + + /* backdrop title */ + BIF_ThemeColor(TH_TEXT_HI); + ui_rasterpos_safe(rect.xmin+8.0f, rect.ymax+5.0f, snode->aspect); + BIF_DrawString(snode->curfont, ngroup->id.name+2, 0); + + /* links from groupsockets to the internal nodes */ + node_draw_group_links(snode, gnode); + + /* group sockets */ + for(sock= gnode->inputs.first; sock; sock= sock->next) + if(!(sock->flag & SOCK_HIDDEN)) + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + for(sock= gnode->outputs.first; sock; sock= sock->next) + if(!(sock->flag & SOCK_HIDDEN)) + socket_circle_draw(sock->locx, sock->locy, NODE_SOCKSIZE, sock->type, sock->flag & SELECT); + + /* and finally the whole tree */ + node_draw_nodetree(sa, snode, ngroup); +} + + +void drawnodespace(ScrArea *sa, void *spacedata) +{ + SpaceNode *snode= sa->spacedata.first; + float col[3]; + + BIF_GetThemeColor3fv(TH_BACK, col); + glClearColor(col[0], col[1], col[2], 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + calc_scrollrcts(sa, &(snode->v2d), sa->winx, sa->winy); + + myortho2(snode->v2d.cur.xmin, snode->v2d.cur.xmax, snode->v2d.cur.ymin, snode->v2d.cur.ymax); + bwin_clear_viewmat(sa->win); /* clear buttons view */ + glLoadIdentity(); + + /* always free, blocks here have no unique identifier (1 block per node) */ + uiFreeBlocksWin(&sa->uiblocks, sa->win); + + /* only set once */ + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glEnable(GL_MAP1_VERTEX_3); + + /* aspect+font, set each time */ + snode->aspect= (snode->v2d.cur.xmax - snode->v2d.cur.xmin)/((float)sa->winx); + snode->curfont= uiSetCurFont_ext(snode->aspect); + + /* backdrop */ + draw_nodespace_grid(snode); + + /* nodes */ + snode_set_context(snode); + + if(snode->nodetree) { + bNode *node; + + /* 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); + else if(node->flag & NODE_HIDDEN) + node_update_hidden(node); + else + node_update(node); + } + + node_draw_nodetree(sa, snode, snode->nodetree); + + /* active group */ + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(node->flag & NODE_GROUP_EDIT) + node_draw_group(sa, snode, node); + } + } + + /* restore viewport (not needed yet) */ + mywinset(sa->win); + + /* ortho at pixel level curarea */ + myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); + + draw_area_emboss(sa); + curarea->win_swap= WIN_BACK_OK; + + /* in the end, this is a delayed previewrender test, to allow buttons to be first */ + if(snode->flag & SNODE_DO_PREVIEW) { + addafterqueue(sa->win, RENDERPREVIEW, 1); + snode->flag &= ~SNODE_DO_PREVIEW; + } +} diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 1ccaa2b71c8..8c150afac1e 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -158,7 +158,7 @@ static int set_gl_material(int nr) } /* returns 1: when there's alpha needed to be drawn in a 2nd pass */ -static int init_gl_materials(Object *ob) +static int init_gl_materials(Object *ob, int check_alpha) { extern Material defmaterial; // render module abuse... Material *ma; @@ -189,7 +189,7 @@ static int init_gl_materials(Object *ob) matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b; /* draw transparent, not in pick-select, nor editmode */ - if(!(G.f & G_PICKSEL) && (ob->dtx & OB_DRAWTRANSP) && !(G.obedit && G.obedit->data==ob->data)) { + if(check_alpha && !(G.f & G_PICKSEL) && (ob->dtx & OB_DRAWTRANSP) && !(G.obedit && G.obedit->data==ob->data)) { if(G.vd->transp) { // drawing the transparent pass if(ma->alpha==1.0) matbuf[a][0][3]= 0.0; // means skip solid else matbuf[a][0][3]= ma->alpha; @@ -222,7 +222,7 @@ static unsigned int colortab[24]= {0x0, 0xFF88FF, 0xFFBBFF, 0x403000, 0xFFFF88, 0xFFFFBB, 0x104040, 0x66CCCC, 0x77CCCC, - 0x101040, 0x5588FF, 0x88BBFF, + 0x104010, 0x55BB55, 0x66FF66, 0xFFFFFF }; @@ -239,44 +239,67 @@ static float cube[8][3] = { }; /* flag is same as for draw_object */ -void drawaxes(float size, int flag) +void drawaxes(float size, int flag, char drawtype) { + View3D *v3d= G.vd; int axis; - - for (axis=0; axis<3; axis++) { - float v1[3]= {0.0, 0.0, 0.0}; - float v2[3]= {0.0, 0.0, 0.0}; - int arrow_axis= (axis==0)?1:0; - - glBegin(GL_LINES); - - v2[axis]= size; - glVertex3fv(v1); - glVertex3fv(v2); + float vec[3]= {0.0, 0.0, 0.0}; + + switch(drawtype) { + + case OB_PLAINAXES: + for (axis=0; axis<3; axis++) { + float v1[3]= {0.0, 0.0, 0.0}; + float v2[3]= {0.0, 0.0, 0.0}; - v1[axis]= size*0.8; - v1[arrow_axis]= -size*0.125; - glVertex3fv(v1); - glVertex3fv(v2); - - v1[arrow_axis]= size*0.125; - glVertex3fv(v1); - glVertex3fv(v2); + glBegin(GL_LINES); - glEnd(); + v1[axis]= size; + v2[axis]= -size; + glVertex3fv(v1); + glVertex3fv(v2); - v2[axis]+= size*0.125; - glRasterPos3fv(v2); - - // patch for 3d cards crashing on glSelect for text drawing (IBM) - if((flag & DRAW_PICKING) == 0) { - if (axis==0) - BMF_DrawString(G.font, "x"); - else if (axis==1) - BMF_DrawString(G.font, "y"); - else - BMF_DrawString(G.font, "z"); + glEnd(); } + break; + case OB_ARROWS: + default: + for (axis=0; axis<3; axis++) { + float v1[3]= {0.0, 0.0, 0.0}; + float v2[3]= {0.0, 0.0, 0.0}; + int arrow_axis= (axis==0)?1:0; + + glBegin(GL_LINES); + + v2[axis]= size; + glVertex3fv(v1); + glVertex3fv(v2); + + v1[axis]= size*0.8; + v1[arrow_axis]= -size*0.125; + glVertex3fv(v1); + glVertex3fv(v2); + + v1[arrow_axis]= size*0.125; + glVertex3fv(v1); + glVertex3fv(v2); + + glEnd(); + + v2[axis]+= size*0.125; + glRasterPos3fv(v2); + + // patch for 3d cards crashing on glSelect for text drawing (IBM) + if((flag & DRAW_PICKING) == 0) { + if (axis==0) + BMF_DrawString(G.font, "x"); + else if (axis==1) + BMF_DrawString(G.font, "y"); + else + BMF_DrawString(G.font, "z"); + } + } + break; } } @@ -1754,8 +1777,9 @@ static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot return 1; } -static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, int dt) +static void draw_mesh_fancy(Base *base, DerivedMesh *baseDM, DerivedMesh *dm, int dt) { + Object *ob= base->object; Mesh *me = ob->data; Material *ma= give_current_material(ob, 1); int hasHaloMat = (ma && (ma->mode&MA_HALO)); @@ -1780,7 +1804,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in } else if( (ob==OBACT && (G.f & G_FACESELECT)) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) { - if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) { + if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) { draw_mesh_object_outline(ob, dm); } @@ -1788,7 +1812,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in } else if(dt==OB_SOLID ) { - if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !draw_wire) { + if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire) { draw_mesh_object_outline(ob, dm); } @@ -1802,7 +1826,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in glFrontFace(GL_CCW); glDisable(GL_LIGHTING); - if(ob->flag & SELECT) { + if(base->flag & SELECT) { BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); } else { BIF_ThemeColor(TH_WIRE); @@ -1842,11 +1866,11 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in if(do_draw) { dl = ob->disp.first; if (!dl || !dl->col1) { - shadeDispList(ob); + shadeDispList(base); dl = find_displist(&ob->disp, DL_VERTCOL); } - if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !draw_wire) { + if ((G.vd->flag&V3D_SELECT_OUTLINE) && (base->flag&SELECT) && !draw_wire) { draw_mesh_object_outline(ob, dm); } @@ -1858,7 +1882,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in dm->drawFacesColored(dm, me->flag&ME_TWOSIDED, (unsigned char*) obCol1, (unsigned char*) obCol2); } - if(ob->flag & SELECT) { + if(base->flag & SELECT) { BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); } else { BIF_ThemeColor(TH_WIRE); @@ -1872,7 +1896,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in * overlaying the wires. */ if (dt!=OB_WIRE) { - if(ob->flag & SELECT) { + if(base->flag & SELECT) { BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT); } else { BIF_ThemeColor(TH_WIRE); @@ -1920,7 +1944,7 @@ static int draw_mesh_object(Base *base, int dt) cageDM = editmesh_get_derived_cage_and_final(&finalDM, &cageNeedsFree, &finalNeedsFree); } - if(dt>OB_WIRE) init_gl_materials(ob); // no transp in editmode, the fancy draw over goes bad then + if(dt>OB_WIRE) init_gl_materials(ob, 0); // no transp in editmode, the fancy draw over goes bad then draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt); if (cageNeedsFree) cageDM->release(cageDM); @@ -1934,8 +1958,8 @@ static int draw_mesh_object(Base *base, int dt) DerivedMesh *baseDM = mesh_get_derived_deform(ob, &baseDMneedsFree); DerivedMesh *realDM = mesh_get_derived_final(ob, &realDMneedsFree); - if(dt==OB_SOLID) has_alpha= init_gl_materials(ob); - if(baseDM && realDM) draw_mesh_fancy(ob, baseDM, realDM, dt); + if(dt==OB_SOLID) has_alpha= init_gl_materials(ob, (base->flag & OB_FROMDUPLI)==0); + if(baseDM && realDM) draw_mesh_fancy(base, baseDM, realDM, dt); if(me->totvert==0) retval= 1; @@ -2358,8 +2382,9 @@ static void drawDispListshaded(ListBase *lb, Object *ob) } /* returns 1 when nothing was drawn */ -static int drawDispList(Object *ob, int dt) +static int drawDispList(Base *base, int dt) { + Object *ob= base->object; ListBase *lb=0; DispList *dl; Curve *cu; @@ -2388,11 +2413,11 @@ static int drawDispList(Object *ob, int dt) } else { if(dt==OB_SHADED) { - if(ob->disp.first==0) shadeDispList(ob); + if(ob->disp.first==0) shadeDispList(base); drawDispListshaded(lb, ob); } else { - init_gl_materials(ob); + init_gl_materials(ob, 0); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); drawDispListsolid(lb, ob); } @@ -2422,11 +2447,11 @@ static int drawDispList(Object *ob, int dt) if(dl->nors==NULL) addnormalsDispList(ob, lb); if(dt==OB_SHADED) { - if(ob->disp.first==NULL) shadeDispList(ob); + if(ob->disp.first==NULL) shadeDispList(base); drawDispListshaded(lb, ob); } else { - init_gl_materials(ob); + init_gl_materials(ob, 0); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); drawDispListsolid(lb, ob); @@ -2447,11 +2472,11 @@ static int drawDispList(Object *ob, int dt) if(dt==OB_SHADED) { dl= lb->first; - if(dl && dl->col1==0) shadeDispList(ob); + if(dl && dl->col1==0) shadeDispList(base); drawDispListshaded(lb, ob); } else { - init_gl_materials(ob); + init_gl_materials(ob, 0); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); drawDispListsolid(lb, ob); @@ -2474,17 +2499,19 @@ static int drawDispList(Object *ob, int dt) static void draw_particle_system(Object *ob, PartEff *paf) { Particle *pa; - float ptime, ctime, vec[3], vec1[3]; + float ptime, ctime, vec[3], vec1[3], mat[4][4]; int a, totpart; pa= paf->keys; - if(pa==0) { + if(pa==NULL) { build_particle_system(ob); pa= paf->keys; - if(pa==0) return; + if(pa==NULL) return; } myloadmatrix(G.vd->viewmat); + Mat4MulMat4(mat, paf->imat, ob->obmat); + mymultmatrix(mat); if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf; else ptime= 0.0; @@ -2521,6 +2548,7 @@ static void draw_particle_system(Object *ob, PartEff *paf) } if(paf->stype!=PAF_VECT) glEnd(); + myloadmatrix(G.vd->viewmat); mymultmatrix(ob->obmat); // bring back local matrix for dtx } @@ -2795,15 +2823,16 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel) } } -static void drawnurb(Object *ob, Nurb *nurb, int dt) +static void drawnurb(Base *base, Nurb *nurb, int dt) { + Object *ob= base->object; Curve *cu = ob->data; Nurb *nu; BevList *bl; /* DispList */ BIF_ThemeColor(TH_WIRE); - drawDispList(ob, dt); + drawDispList(base, dt); if(G.vd->zbuf) glDisable(GL_DEPTH_TEST); @@ -3072,8 +3101,9 @@ void drawcircball(int mode, float *cent, float rad, float tmat[][4]) } /* return 1 if nothing was drawn */ -static int drawmball(Object *ob, int dt) +static int drawmball(Base *base, int dt) { + Object *ob= base->object; MetaBall *mb; MetaElem *ml; float imat[4][4], tmat[4][4]; @@ -3083,11 +3113,12 @@ static int drawmball(Object *ob, int dt) if(ob==G.obedit) { BIF_ThemeColor(TH_WIRE); - if((G.f & G_PICKSEL)==0 ) drawDispList(ob, dt); + if((G.f & G_PICKSEL)==0 ) drawDispList(base, dt); ml= editelems.first; } else { - drawDispList(ob, dt); + if((base->flag & OB_FROMDUPLI)==0) + drawDispList(base, dt); ml= mb->elems.first; } @@ -3412,7 +3443,8 @@ static void drawSolidSelect(Base *base) drawDispListwire(&cu->disp); } } else if (ob->type==OB_MBALL) { - drawDispListwire(&ob->disp); + if((base->flag & OB_FROMDUPLI)==0) + drawDispListwire(&ob->disp); } else if(ob->type==OB_ARMATURE) { if(!(ob->flag & OB_POSEMODE)) { @@ -3501,7 +3533,7 @@ void draw_object(Base *base, int flag) ob= base->object; /* xray delay? */ - if((flag & DRAW_PICKING)==0) { + if((flag & DRAW_PICKING)==0 && (base->flag & OB_FROMDUPLI)==0) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) { add_view3d_after(G.vd, base, V3D_XRAY); @@ -3610,9 +3642,19 @@ void draw_object(Base *base, int flag) else colindex = 3; } else if(warning_recursive==1) { - if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 7; + if(base->flag & (SELECT+BA_WAS_SEL)) { + if(G.scene->basact==base) colindex = 8; + else colindex= 7; + } else colindex = 6; } + else if(ob->flag & OB_FROMGROUP) { + if(base->flag & (SELECT+BA_WAS_SEL)) { + if(G.scene->basact==base) colindex = 11; + else colindex= 10; + } + else colindex = 9; + } } @@ -3699,10 +3741,10 @@ void draw_object(Base *base, int flag) if (cu->flag & CU_FAST) { cpack(0xFFFFFF); set_inverted_drawing(1); - drawDispList(ob, OB_WIRE); + drawDispList(base, OB_WIRE); set_inverted_drawing(0); } else { - drawDispList(ob, dt); + drawDispList(base, dt); } if (cu->linewidth != 0.0) { @@ -3777,7 +3819,7 @@ void draw_object(Base *base, int flag) else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); else if(boundbox_clip(ob->obmat, cu->bb)) - empty_object= drawDispList(ob, dt); + empty_object= drawDispList(base, dt); break; case OB_CURVE: @@ -3787,24 +3829,24 @@ void draw_object(Base *base, int flag) if (cu->disp.first==NULL) makeDispListCurveTypes(ob, 0); if(ob==G.obedit) { - drawnurb(ob, editNurb.first, dt); + drawnurb(base, editNurb.first, dt); } else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); else if(boundbox_clip(ob->obmat, cu->bb)) - empty_object= drawDispList(ob, dt); + empty_object= drawDispList(base, dt); break; case OB_MBALL: if(ob==G.obedit) - drawmball(ob, dt); + drawmball(base, dt); else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob); else - empty_object= drawmball(ob, dt); + empty_object= drawmball(base, dt); break; case OB_EMPTY: - drawaxes(1.0, flag); + drawaxes(ob->empty_drawsize, flag, ob->empty_drawtype); break; case OB_LAMP: drawlamp(ob); @@ -3821,7 +3863,7 @@ void draw_object(Base *base, int flag) empty_object= draw_armature(base, dt); break; default: - drawaxes(1.0, flag); + drawaxes(1.0, flag, OB_ARROWS); } if(ob->pd && ob->pd->forcefield) draw_forcefield(ob); @@ -3830,7 +3872,7 @@ void draw_object(Base *base, int flag) if(dtx) { if(G.f & G_SIMULATION); else if(dtx & OB_AXIS) { - drawaxes(1.0f, flag); + drawaxes(1.0f, flag, OB_ARROWS); } if(dtx & OB_BOUNDBOX) draw_bounding_volume(ob); if(dtx & OB_TEXSPACE) drawtexspace(ob); @@ -3884,7 +3926,7 @@ void draw_object(Base *base, int flag) } /* not for sets, duplicators or picking */ - if(flag==0) { + if(flag==0 && (!(G.vd->flag & V3D_HIDE_HELPLINES))) { ListBase *list; /* draw hook center and offset line */ @@ -4122,5 +4164,55 @@ void draw_object_backbufsel(Object *ob) } myloadmatrix(G.vd->viewmat); - } + + +/* ************* draw object instances for bones, for example ****************** */ +/* assumes all matrices/etc set OK */ + +void draw_object_instance(Object *ob, int dt, int outline) +{ + DerivedMesh *dm=NULL, *edm=NULL; + int needsfree= 1; + + if(ob==NULL || ob->type!=OB_MESH) return; + + if(G.obedit && ob->data==G.obedit->data) + edm= editmesh_get_derived_base(); + else + dm = mesh_get_derived_final(ob, &needsfree); + + if(dt<=OB_WIRE) { + if(dm) + dm->drawEdges(dm, 1); + else if(edm) + edm->drawEdges(edm, 1); + } + else { + if(outline) + draw_mesh_object_outline(ob, dm?dm:edm); + + if(dm) + init_gl_materials(ob, 0); + else { + glEnable(GL_COLOR_MATERIAL); + BIF_ThemeColor(TH_BONE_SOLID); + glDisable(GL_COLOR_MATERIAL); + } + + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); + glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); + glEnable(GL_LIGHTING); + + if(dm) + dm->drawFacesSolid(dm, set_gl_material); + else if(edm) + edm->drawMappedFaces(edm, NULL, NULL, 0); + + glDisable(GL_LIGHTING); + } + + if(edm) edm->release(edm); + if(dm && needsfree) dm->release(dm); +} + diff --git a/source/blender/src/drawoops.c b/source/blender/src/drawoops.c index 032b78eec9c..dbf245179df 100644 --- a/source/blender/src/drawoops.c +++ b/source/blender/src/drawoops.c @@ -55,6 +55,7 @@ #include "BKE_global.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_mywindow.h" @@ -222,7 +223,7 @@ void draw_icon_oops(float *co, short type) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - BIF_draw_icon(co[0], co[1]-0.2, icon); + BIF_icon_draw(co[0], co[1]-0.2, icon); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index f1eac0cc1aa..153b304079e 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -470,13 +470,16 @@ static void draw_image_seq(ScrArea *sa) SpaceSeq *sseq; StripElem *se; struct ImBuf *ibuf; - int x1, y1; + int x1, y1, rectx, recty; float zoom; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - - ibuf= (ImBuf *)give_ibuf_seq( (G.scene->r.cfra)); + + rectx= (G.scene->r.size*G.scene->r.xsch)/100; + recty= (G.scene->r.size*G.scene->r.ysch)/100; + + ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra)); if(special_seq_update) { se = special_seq_update->curelem; @@ -503,7 +506,7 @@ static void draw_image_seq(ScrArea *sa) glaDefine2DArea(&curarea->winrct); glPixelZoom(zoom, zoom); - glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->rect); + glaDrawPixelsSafe(x1, y1, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glPixelZoom(1.0, 1.0); diff --git a/source/blender/src/drawtime.c b/source/blender/src/drawtime.c index 9ec0f864cdb..7ad6c492c5b 100644 --- a/source/blender/src/drawtime.c +++ b/source/blender/src/drawtime.c @@ -1,15 +1,12 @@ /** * $Id: * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -56,6 +53,7 @@ #include "BKE_global.h" #include "BIF_gl.h" +#include "BIF_interface_icons.h" #include "BIF_mywindow.h" #include "BIF_screen.h" #include "BIF_resources.h" @@ -138,9 +136,9 @@ static void draw_marker(TimeMarker *marker) /* 5 px to offset icon to align properly, space / pixels corrects for zoom */ if(marker->flag & SELECT) - BIF_draw_icon_blended(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER_HLT, TH_BACK, 0); + BIF_icon_draw_blended(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER_HLT, TH_BACK, 0); else - BIF_draw_icon_blended(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER, TH_BACK, 0); + BIF_icon_draw_blended(xpos-(5.0*(xspace/xpixels)), 12.0*yspace/ypixels, ICON_MARKER, TH_BACK, 0); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 47795b39c82..5e8cc3225ee 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -35,10 +35,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #ifndef WIN32 #include #include @@ -67,10 +63,12 @@ #include "DNA_meta_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" -#include "DNA_texture_types.h" -#include "DNA_view3d_types.h" -#include "DNA_userdef_types.h" +#include "DNA_scene_types.h" #include "DNA_space_types.h" +#include "DNA_texture_types.h" +#include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" +#include "DNA_world_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -102,8 +100,10 @@ #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_mywindow.h" #include "BIF_poseobject.h" +#include "BIF_previewrender.h" #include "BIF_resources.h" #include "BIF_screen.h" #include "BIF_space.h" @@ -121,8 +121,6 @@ #include "BSE_time.h" #include "BSE_view.h" -#include "RE_renderconverter.h" - #include "BPY_extern.h" #include "blendef.h" @@ -132,7 +130,6 @@ #include "BIF_transform.h" /* Modules used */ -#include "render.h" // for ogl render #include "radio.h" /* locals */ @@ -340,10 +337,9 @@ static void draw_bgpic(void) if(bgpic==0) return; if(bgpic->tex) { - init_render_texture(bgpic->tex); +// init_render_texture(bgpic->tex); free_unused_animimages(); ima= bgpic->tex->ima; - end_render_texture(bgpic->tex); } else { ima= bgpic->ima; @@ -436,7 +432,7 @@ static void draw_bgpic(void) glaDefine2DArea(&curarea->winrct); glPixelZoom(zoomx, zoomy); - glaDrawPixelsSafe(x1, y1, ima->ibuf->x, ima->ibuf->y, bgpic->rect); + glaDrawPixelsSafe(x1, y1, ima->ibuf->x, ima->ibuf->y, ima->ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, bgpic->rect); glPixelZoom(1.0, 1.0); glMatrixMode(GL_PROJECTION); @@ -451,23 +447,6 @@ static void draw_bgpic(void) areawinset(curarea->win); // restore viewport / scissor } -void timestr(double time, char *str) -{ - /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ - int hr= (int) time/(60*60); - int min= (int) fmod(time/60, 60.0); - int sec= (int) fmod(time, 60.0); - int hun= (int) fmod(time*100.0, 100.0); - - if (hr) { - sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun); - } else { - sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun); - } - - str[11]=0; -} - static void drawgrid_draw(float wx, float wy, float x, float y, float dx) { float fx, fy; @@ -867,7 +846,8 @@ static void view3d_get_viewborder_size(View3D *v3d, float size_r[2]) void calc_viewborder(struct View3D *v3d, rcti *viewborder_r) { float zoomfac, size[2]; - + float dx= 0.0f, dy= 0.0f; + view3d_get_viewborder_size(v3d, size); /* magic zoom calculation, no idea what @@ -889,6 +869,15 @@ void calc_viewborder(struct View3D *v3d, rcti *viewborder_r) viewborder_r->ymin= 0.5*v3d->area->winy - 0.5*size[1]; viewborder_r->xmax= viewborder_r->xmin + size[0]; viewborder_r->ymax= viewborder_r->ymin + size[1]; + + dx= v3d->area->winx*G.vd->camdx; + dy= v3d->area->winy*G.vd->camdy; + + /* apply offset */ + viewborder_r->xmin-= dx; + viewborder_r->ymin-= dy; + viewborder_r->xmax-= dx; + viewborder_r->ymax-= dy; } void view3d_set_1_to_1_viewborder(View3D *v3d) @@ -928,14 +917,15 @@ static void drawviewborder(void) glEnable(GL_BLEND); glColor4f(0, 0, 0, ca->passepartalpha); - if (x1 > 0.0) { + if (x1 > 0.0) glRectf(0.0, (float)curarea->winy, x1, 0.0); + if (x2 < (float)curarea->winx) glRectf(x2, (float)curarea->winy, (float)curarea->winx, 0.0); - } - if (y1 > 0.0) { + if (y2 < (float)curarea->winy) glRectf(x1, (float)curarea->winy, x2, y2); + if (y2 > 0.0) glRectf(x1, y1, x2, 0.0); - } + glDisable(GL_BLEND); } @@ -1080,12 +1070,13 @@ static void draw_selected_name(Object *ob) char info[128]; if(ob->type==OB_ARMATURE) { + bArmature *arm= ob->data; char *name= NULL; if(ob==G.obedit) { EditBone *ebo; for (ebo=G.edbo.first; ebo; ebo=ebo->next){ - if (ebo->flag & BONE_ACTIVE) { + if ((ebo->flag & BONE_ACTIVE) && (ebo->layer & arm->layer)) { name= ebo->name; break; } @@ -1094,7 +1085,7 @@ static void draw_selected_name(Object *ob) else if(ob->pose && (ob->flag & OB_POSEMODE)) { bPoseChannel *pchan; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & BONE_ACTIVE) { + if((pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) { name= pchan->name; break; } @@ -1125,7 +1116,7 @@ static void draw_view_icon(void) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - BIF_draw_icon(5.0, 5.0, icon); + BIF_icon_draw(5.0, 5.0, icon); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); @@ -1518,7 +1509,8 @@ static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone = pchan->bone; - if(bone && (bone->flag & BONE_ACTIVE)) break; + if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer)) + break; } if (!pchan) return; @@ -1558,13 +1550,14 @@ static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim) static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim) { + bArmature *arm= G.obedit->data; EditBone *ebone; uiBut *but; ebone= G.edbo.first; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_ACTIVE) + if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer)) break; } @@ -1703,6 +1696,7 @@ void do_viewbuts(unsigned short event) DAG_scene_sort(G.scene); DAG_object_flush_update(G.scene, ob, OB_RECALC_OB); allqueue(REDRAWVIEW3D, 1); + allqueue(REDRAWBUTSOBJECT, 0); } } break; @@ -1712,9 +1706,9 @@ void do_viewbuts(unsigned short event) bArmature *arm= G.obedit->data; EditBone *ebone, *child; - ebone= G.edbo.first; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_ACTIVE) break; + if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer)) + break; } if (ebone) { ebone->roll= M_PI*ob_eul[0]/180.0; @@ -1765,7 +1759,8 @@ void do_viewbuts(unsigned short event) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone = pchan->bone; - if(bone && (bone->flag & BONE_ACTIVE)) break; + if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer)) + break; } if (!pchan) return; @@ -1777,6 +1772,7 @@ void do_viewbuts(unsigned short event) /* no break, pass on */ case B_ARMATUREPANEL2: { + ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); allqueue(REDRAWVIEW3D, 1); } @@ -1971,47 +1967,74 @@ static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS block= uiNewBlock(&curarea->uiblocks, "view3d_panel_properties", UI_EMBOSS, UI_HELV, curarea->win); uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl); uiSetPanelHandler(VIEW3D_HANDLER_PROPERTIES); // for close and esc - if(uiNewPanel(curarea, block, "View Properties", "View3d", 340, 10, 318, 204)==0) return; + if(uiNewPanel(curarea, block, "View Properties", "View3d", 340, 30, 318, 254)==0) return; + + /* to force height */ + uiNewPanelHeight(block, 254); if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { uiBlockSetFlag(block, UI_BLOCK_FRONTBUFFER); // force old style frontbuffer draw } - uiDefBut(block, LABEL, 1, "Grid:", 10, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefButF(block, NUM, REDRAWVIEW3D, "Spacing:", 10, 160, 140, 19, &vd->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines"); - uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:", 10, 136, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines"); + uiDefBut(block, LABEL, 1, "Grid:", 10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefButF(block, NUM, REDRAWVIEW3D, "Spacing:", 10, 200, 140, 19, &vd->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines"); + uiDefButS(block, NUM, REDRAWVIEW3D, "Lines:", 10, 176, 140, 19, &vd->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines"); - uiDefBut(block, LABEL, 1, "3D Display:", 160, 180, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefButBitS(block, TOG, V3D_SHOW_FLOOR, REDRAWVIEW3D, "Grid Floor",160, 160, 150, 19, &vd->gridflag, 0, 0, 0, 0, "Show the grid floor in free camera mode"); + uiDefBut(block, LABEL, 1, "3D Display:", 160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefButBitS(block, TOG, V3D_SHOW_FLOOR, REDRAWVIEW3D, "Grid Floor",160, 200, 150, 19, &vd->gridflag, 0, 0, 0, 0, "Show the grid floor in free camera mode"); + uiDefButBitS(block, TOG, V3D_SHOW_X, REDRAWVIEW3D, "X Axis", 160, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the X Axis line"); + uiDefButBitS(block, TOG, V3D_SHOW_Y, REDRAWVIEW3D, "Y Axis", 212, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Y Axis line"); + uiDefButBitS(block, TOG, V3D_SHOW_Z, REDRAWVIEW3D, "Z Axis", 262, 176, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Z Axis line"); + + uiDefBut(block, LABEL, 1, "View Camera:", 10, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefButF(block, NUM, REDRAWVIEW3D, "Lens:", 10, 130, 140, 19, &vd->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view"); uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, V3D_SHOW_X, REDRAWVIEW3D, "X Axis", 160, 136, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the X Axis line"); - uiDefButBitS(block, TOG, V3D_SHOW_Y, REDRAWVIEW3D, "Y Axis", 212, 136, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Y Axis line"); - uiDefButBitS(block, TOG, V3D_SHOW_Z, REDRAWVIEW3D, "Z Axis", 262, 136, 48, 19, &vd->gridflag, 0, 0, 0, 0, "Show the Z Axis line"); - uiBlockEndAlign(block); - - uiDefBut(block, LABEL, 1, "View Camera:", 10, 110, 140, 19, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefButF(block, NUM, REDRAWVIEW3D, "Lens:", 10, 90, 140, 19, &vd->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view"); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, REDRAWVIEW3D, "Clip Start:", 10, 66, 140, 19, &vd->near, vd->grid/10.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)"); - uiDefButF(block, NUM, REDRAWVIEW3D, "Clip End:", 10, 46, 140, 19, &vd->far, 1.0, 1000.0*vd->grid, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Clip Start:", 10, 106, 140, 19, &vd->near, vd->grid/10.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Clip End:", 10, 86, 140, 19, &vd->far, 1.0, 1000.0*vd->grid, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)"); uiBlockEndAlign(block); - uiDefBut(block, LABEL, 1, "3D Cursor:", 160, 110, 140, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "3D Cursor:", 160, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, ""); uiBlockBeginAlign(block); curs= give_cursor(); - uiDefButF(block, NUM, REDRAWVIEW3D, "X:", 160, 90, 150, 22, curs, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "X co-ordinate of the 3D cursor"); - uiDefButF(block, NUM, REDRAWVIEW3D, "Y:", 160, 68, 150, 22, curs+1, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Y co-ordinate of the 3D cursor"); - uiDefButF(block, NUM, REDRAWVIEW3D, "Z:", 160, 46, 150, 22, curs+2, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Z co-ordinate of the 3D cursor"); + uiDefButF(block, NUM, REDRAWVIEW3D, "X:", 160, 130, 150, 22, curs, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "X co-ordinate of the 3D cursor"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Y:", 160, 108, 150, 22, curs+1, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Y co-ordinate of the 3D cursor"); + uiDefButF(block, NUM, REDRAWVIEW3D, "Z:", 160, 86, 150, 22, curs+2, -1000.0*vd->grid, 1000.0*vd->grid, 10, 0, "Z co-ordinate of the 3D cursor"); uiBlockEndAlign(block); - uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, REDRAWVIEW3D, "Outline Selected", 10, 10, 140, 19, &vd->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes"); - uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, REDRAWVIEW3D, "All Object Centers", 160, 10, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw the center points on all objects"); + uiDefBut(block, LABEL, 1, "Display:", 10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, REDRAWVIEW3D, "Outline Selected", 10, 30, 140, 19, &vd->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes"); + uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, REDRAWVIEW3D, "All Object Centers", 160, 30, 150, 19, &vd->flag, 0, 0, 0, 0, "Draw the center points on all objects"); + + uiDefButBitS(block, TOGN, V3D_HIDE_HELPLINES, REDRAWVIEW3D, "Relationship Lines", 10, 6, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships"); } +static void view3d_panel_preview(ScrArea *sa, short cntrl) // VIEW3D_HANDLER_PREVIEW +{ + uiBlock *block; + View3D *v3d= sa->spacedata.first; + int ofsx, ofsy; + + block= uiNewBlock(&sa->uiblocks, "view3d_panel_preview", UI_EMBOSS, UI_HELV, sa->win); + uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl); + uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW); // for close and esc + + ofsx= -150+(sa->winx/2)/v3d->blockscale; + ofsy= -100+(sa->winy/2)/v3d->blockscale; + if(uiNewPanel(sa, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return; + + uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw); + + if(G.scene->recalc & SCE_PRV_CHANGED) { + G.scene->recalc &= ~SCE_PRV_CHANGED; + //printf("found recalc\n"); + BIF_view3d_previewrender_free(sa); + BIF_preview_changed(0); + } +} static void view3d_blockhandlers(ScrArea *sa) @@ -2034,9 +2057,11 @@ static void view3d_blockhandlers(ScrArea *sa) break; case VIEW3D_HANDLER_OBJECT: view3d_panel_object(v3d->blockhandler[a+1]); - break; - + case VIEW3D_HANDLER_PREVIEW: + view3d_panel_preview(sa, v3d->blockhandler[a+1]); + break; + } /* clear action value for event */ v3d->blockhandler[a+1]= 0; @@ -2045,6 +2070,14 @@ static void view3d_blockhandlers(ScrArea *sa) } +/* ****************** View3d afterdraw *************** */ + +typedef struct View3DAfter { + struct View3DAfter *next, *prev; + struct Base *base; + int type; +} View3DAfter; + /* temp storage of Objects that need to be drawn as last */ void add_view3d_after(View3D *v3d, Base *base, int type) { @@ -2102,6 +2135,45 @@ static void view3d_draw_transp(View3D *v3d, int flag) } +/* *********************** */ + +static void draw_dupli_objects(View3D *v3d, Base *base) +{ + ListBase *lb; + DupliObject *dob; + Base tbase; + int color= (base->flag & SELECT)?TH_SELECT:TH_WIRE; + char dt, dtx; + + /* debug */ + if(base->object->dup_group && base->object->dup_group->id.us<1) + color= TH_REDALERT; + + tbase.flag= OB_FROMDUPLI|base->flag; + lb= object_duplilist(G.scene, base->object); + + for(dob= lb->first; dob; dob= dob->next) { + tbase.object= dob->ob; + + Mat4CpyMat4(dob->ob->obmat, dob->mat); + /* extra service: draw the duplicator in drawtype of parent */ + dt= tbase.object->dt; tbase.object->dt= base->object->dt; + dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx; + + BIF_ThemeColorBlend(color, TH_BACK, 0.5); + draw_object(&tbase, DRAW_CONSTCOLOR); + + /* restore */ + Mat4CpyMat4(dob->ob->obmat, dob->omat); + tbase.object->dt= dt; + tbase.object->dtx= dtx; + } + /* Transp afterdraw disabled, afterdraw only stores base pointers, and duplis can be same obj */ + + BLI_freelistN(lb); + +} + void drawview3dspace(ScrArea *sa, void *spacedata) { View3D *v3d= spacedata; @@ -2109,10 +2181,10 @@ void drawview3dspace(ScrArea *sa, void *spacedata) Object *ob; Scene *setscene; - setwinmatrixview3d(0); /* 0= no pick rect */ + setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */ setviewmatrixview3d(); /* note: calls where_is_object for camera... */ - Mat4MulMat4(v3d->persmat, v3d->viewmat, curarea->winmat); + Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat); Mat4Invert(v3d->persinv, v3d->persmat); Mat4Invert(v3d->viewinv, v3d->viewmat); @@ -2128,7 +2200,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) v3d->pixsize= 2.0f*(len1>len2?len1:len2); /* correct for window size */ - if(curarea->winx > sa->winy) v3d->pixsize/= (float)sa->winx; + if(sa->winx > sa->winy) v3d->pixsize/= (float)sa->winx; else v3d->pixsize/= (float)sa->winy; } @@ -2171,8 +2243,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata) if(v3d->persp==2) { if(G.scene->world) { if(G.scene->world->mode & WO_STARS) { - RE_make_stars(star_stuff_init_func, star_stuff_vertex_func, - star_stuff_term_func); +// RE_make_stars(star_stuff_init_func, star_stuff_vertex_func, +// star_stuff_term_func); } } if(v3d->flag & V3D_DISPBGPIC) draw_bgpic(); @@ -2204,21 +2276,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) draw_object(base, DRAW_CONSTCOLOR); if(base->object->transflag & OB_DUPLI) { - extern ListBase duplilist; - Base tbase; - - tbase= *base; - - tbase.flag= OB_FROMDUPLI; - make_duplilist(setscene, base->object); /* make_duplilist(G.scene->set, base->object); */ - ob= duplilist.first; - while(ob) { - tbase.object= ob; - draw_object(&tbase, DRAW_CONSTCOLOR); - ob= ob->id.next; - } - free_duplilist(); - + draw_dupli_objects(v3d, base); } } @@ -2245,21 +2303,7 @@ void drawview3dspace(ScrArea *sa, void *spacedata) /* dupli drawing */ if(base->object->transflag & OB_DUPLI) { - extern ListBase duplilist; - Base tbase; - - BIF_ThemeColorBlend(TH_BACK, TH_WIRE, 0.5); - - tbase.flag= OB_FROMDUPLI; - make_duplilist(G.scene, base->object); - - ob= duplilist.first; - while(ob) { - tbase.object= ob; - draw_object(&tbase, DRAW_CONSTCOLOR); - ob= ob->id.next; - } - free_duplilist(); + draw_dupli_objects(v3d, base); } if((base->flag & SELECT)==0) { if(base->object!=G.obedit) draw_object(base, 0); @@ -2312,19 +2356,19 @@ void drawview3dspace(ScrArea *sa, void *spacedata) bwin_scalematrix(sa->win, v3d->blockscale, v3d->blockscale, v3d->blockscale); view3d_blockhandlers(sa); - curarea->win_swap= WIN_BACK_OK; + sa->win_swap= WIN_BACK_OK; if(G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT)) { v3d->flag |= V3D_NEEDBACKBUFDRAW; - addafterqueue(curarea->win, BACKBUFDRAW, 1); + addafterqueue(sa->win, BACKBUFDRAW, 1); } // test for backbuf select if(G.obedit && v3d->drawtype>OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) { extern int afterqtest(short win, unsigned short evt); //editscreen.c v3d->flag |= V3D_NEEDBACKBUFDRAW; - if(afterqtest(curarea->win, BACKBUFDRAW)==0) { - addafterqueue(curarea->win, BACKBUFDRAW, 1); + if(afterqtest(sa->win, BACKBUFDRAW)==0) { + addafterqueue(sa->win, BACKBUFDRAW, 1); } } @@ -2341,27 +2385,22 @@ void drawview3dspace(ScrArea *sa, void *spacedata) } - /* Called back by rendering system, icky - */ -void drawview3d_render(struct View3D *v3d) +void drawview3d_render(struct View3D *v3d, int winx, int winy) { - extern short v3d_windowmode; Base *base; - Object *ob; Scene *setscene; - + float winmat[4][4]; + update_for_newframe_muted(); /* first, since camera can be animated */ - v3d_windowmode= 1; - setwinmatrixview3d(0); - v3d_windowmode= 0; - glMatrixMode(GL_PROJECTION); - myloadmatrix(R.winmat); - glMatrixMode(GL_MODELVIEW); + setwinmatrixview3d(winx, winy, NULL); setviewmatrixview3d(); myloadmatrix(v3d->viewmat); - Mat4MulMat4(v3d->persmat, v3d->viewmat, R.winmat); + glMatrixMode(GL_PROJECTION); + mygetmatrix(winmat); + glMatrixMode(GL_MODELVIEW); + Mat4MulMat4(v3d->persmat, v3d->viewmat, winmat); Mat4Invert(v3d->persinv, v3d->persmat); Mat4Invert(v3d->viewinv, v3d->viewmat); @@ -2384,10 +2423,7 @@ void drawview3d_render(struct View3D *v3d) glClearColor(col[0], col[1], col[2], 0.0); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glLoadIdentity(); - myloadmatrix(v3d->viewmat); - + /* abuse! to make sure it doesnt draw the helpstuff */ G.f |= G_SIMULATION; @@ -2406,18 +2442,7 @@ void drawview3d_render(struct View3D *v3d) draw_object(base, DRAW_CONSTCOLOR); if(base->object->transflag & OB_DUPLI) { - extern ListBase duplilist; - Base tbase; - - tbase.flag= OB_FROMDUPLI; - make_duplilist(setscene, base->object); /* make_duplilist(G.scene->set, base->object); */ - ob= duplilist.first; - while(ob) { - tbase.object= ob; - draw_object(&tbase, DRAW_CONSTCOLOR); - ob= ob->id.next; - } - free_duplilist(); + draw_dupli_objects(v3d, base); } } } @@ -2442,22 +2467,7 @@ void drawview3d_render(struct View3D *v3d) else { if(base->object->transflag & OB_DUPLI) { - extern ListBase duplilist; - Base tbase; - - draw_object(base, 0); - - BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5f); - - tbase.flag= OB_FROMDUPLI; - make_duplilist(G.scene, base->object); - ob= duplilist.first; - while(ob) { - tbase.object= ob; - draw_object(&tbase, DRAW_CONSTCOLOR); - ob= ob->id.next; - } - free_duplilist(); + draw_dupli_objects(v3d, base); } else if((base->flag & SELECT)==0) { draw_object(base, 0); @@ -2498,7 +2508,6 @@ void drawview3d_render(struct View3D *v3d) glFlush(); - glReadPixels(0, 0, R.rectx, R.recty, GL_RGBA, GL_UNSIGNED_BYTE, R.rectot); glLoadIdentity(); free_all_realtime_images(); diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index 7e633bf6d35..355aee6e6c9 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -129,12 +129,12 @@ void circle_selectCB(select_CBfunc func); /* local protos ---------------*/ void snap_curs_to_firstsel(void); - -int get_border(rcti *rect, short col) +/* flag==2 only border, flag==3 cross+border */ +int get_border(rcti *rect, short flag) { float dvec[4], fac1, fac2; int retval=1; - unsigned short event; + unsigned short event= 0; short mval[2], mvalo[4], val, x1, y1; char str[64]; @@ -153,56 +153,59 @@ int get_border(rcti *rect, short col) persp(PERSP_WIN); initgrabz(0.0, 0.0, 0.0); - getmouseco_areawin(mvalo); + if(flag & 1) { + getmouseco_areawin(mvalo); - /* draws the selection initial cross */ - sdrawXORline4(0, 0, mvalo[1], curarea->winx, mvalo[1]); - sdrawXORline4(1, mvalo[0], 0, mvalo[0], curarea->winy); - glFlush(); - - while(TRUE) { - - /* selection loop while mouse pressed */ - getmouseco_areawin(mval); - - if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) { - - /* aiming cross */ - sdrawXORline4(0, 0, mval[1], curarea->winx, mval[1]); - sdrawXORline4(1, mval[0], 0, mval[0], curarea->winy); - glFlush(); - - mvalo[0]= mval[0]; - mvalo[1]= mval[1]; - } - event= extern_qread(&val); - - if(event && val) { - - /* for when a renderwindow is open, and a mouse cursor activates it */ - persp(PERSP_VIEW); - mywinset(curarea->win); - persp(PERSP_WIN); - - if(event==ESCKEY) { - retval= 0; - break; - } - else if(event==BKEY) { - /* b has been pressed twice: proceed with circle select */ - retval= 0; - break; - } - else if(event==LEFTMOUSE) break; - else if(event==MIDDLEMOUSE) break; - else if(event==RIGHTMOUSE) break; - } - else PIL_sleep_ms(10); + /* draws the selection initial cross */ + sdrawXORline4(0, 0, mvalo[1], curarea->winx, mvalo[1]); + sdrawXORline4(1, mvalo[0], 0, mvalo[0], curarea->winy); + glFlush(); - } /* end while (TRUE) */ + while(TRUE) { + + /* selection loop while mouse pressed */ + getmouseco_areawin(mval); + + if(mvalo[0]!=mval[0] || mvalo[1]!=mval[1]) { - /* erase XORed lines */ - sdrawXORline4(-1, 0, 0, 0, 0); + /* aiming cross */ + sdrawXORline4(0, 0, mval[1], curarea->winx, mval[1]); + sdrawXORline4(1, mval[0], 0, mval[0], curarea->winy); + glFlush(); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + event= extern_qread(&val); + + if(event && val) { + + /* for when a renderwindow is open, and a mouse cursor activates it */ + persp(PERSP_VIEW); + mywinset(curarea->win); + persp(PERSP_WIN); + + if(event==ESCKEY) { + retval= 0; + break; + } + else if(event==BKEY) { + /* b has been pressed twice: proceed with circle select */ + retval= 0; + break; + } + else if(event==LEFTMOUSE) break; + else if(event==MIDDLEMOUSE) break; + else if(event==RIGHTMOUSE) break; + } + else PIL_sleep_ms(10); + + } /* end while (TRUE) */ + + /* erase XORed lines */ + sdrawXORline4(-1, 0, 0, 0, 0); + } + else getmouseco_areawin(mval); if(retval) { /* box select */ @@ -684,10 +687,13 @@ void countall() } else if(ob && (ob->flag & OB_POSEMODE)) { if(ob->pose) { + bArmature *arm= ob->data; bPoseChannel *pchan; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { G.totbone++; - if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) G.totbonesel++; + if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) + if(pchan->bone->layer & arm->layer) + G.totbonesel++; } } allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */ @@ -886,28 +892,31 @@ static void make_trans_verts(float *min, float *max, int mode) } } else if (G.obedit->type==OB_ARMATURE){ + bArmature *arm= G.obedit->data; + for (ebo=G.edbo.first;ebo;ebo=ebo->next){ - if (ebo->flag & BONE_TIPSEL){ - VECCOPY (tv->oldloc, ebo->tail); - tv->loc= ebo->tail; - tv->nor= NULL; - tv->flag= 1; - tv++; - tottrans++; - } - - /* Only add the root if there is no connection */ - if (ebo->flag & BONE_ROOTSEL){ - if (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)){ - VECCOPY (tv->oldloc, ebo->head); - tv->loc= ebo->head; + if(ebo->layer & arm->layer) { + if (ebo->flag & BONE_TIPSEL){ + VECCOPY (tv->oldloc, ebo->tail); + tv->loc= ebo->tail; tv->nor= NULL; tv->flag= 1; tv++; tottrans++; - } - } - + } + + /* Only add the root if there is no connection */ + if (ebo->flag & BONE_ROOTSEL){ + if (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && ebo->parent->flag & BONE_TIPSEL)){ + VECCOPY (tv->oldloc, ebo->head); + tv->loc= ebo->head; + tv->nor= NULL; + tv->flag= 1; + tv++; + tottrans++; + } + } + } } } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) { @@ -1156,6 +1165,7 @@ void snap_sel_to_curs() ob= base->object; if(ob->flag & OB_POSEMODE) { bPoseChannel *pchan; + bArmature *arm= ob->data; float cursp[3]; Mat4Invert(ob->imat, ob->obmat); @@ -1164,10 +1174,13 @@ void snap_sel_to_curs() for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { if(pchan->bone->flag & BONE_SELECTED) { - if(pchan->parent==NULL) { - VECCOPY(pchan->loc, cursp); + if(pchan->bone->layer & arm->layer) { + if(pchan->parent==NULL) { + /* this is wrong... lazy! */ + VECCOPY(pchan->loc, cursp); + } + /* else todo... */ } - /* else todo... */ } } ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK); @@ -1265,14 +1278,17 @@ void snap_curs_to_sel() Object *ob= OBACT; if(ob && (ob->flag & OB_POSEMODE)) { + bArmature *arm= ob->data; bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) { - if(pchan->bone->flag & BONE_SELECTED) { - VECCOPY(vec, pchan->pose_head); - Mat4MulVecfl(ob->obmat, vec); - VecAddf(centroid, centroid, vec); - DO_MINMAX(vec, min, max); - count++; + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & BONE_SELECTED) { + VECCOPY(vec, pchan->pose_head); + Mat4MulVecfl(ob->obmat, vec); + VecAddf(centroid, centroid, vec); + DO_MINMAX(vec, min, max); + count++; + } } } } diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index e9081b0fbfc..4d38175e69d 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -65,6 +65,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_utildefines.h" +#include "BKE_object.h" /* for where_is_object in obanim -> action baking */ #include "BIF_butspace.h" #include "BIF_editaction.h" @@ -169,7 +170,7 @@ bAction* bake_action_with_client (bAction *act, Object *armob, float tolerance) sprintf (newname, "%s.BAKED", act->id.name+2); rename_id(&result->id, newname); - calc_action_range(act, &actstart, &actend); + calc_action_range(act, &actstart, &actend, 1); oldframe = G.scene->r.cfra; @@ -325,9 +326,11 @@ void duplicate_actionchannel_keys(void) /* Find selected items */ for (chan = act->chanbase.first; chan; chan=chan->next){ - duplicate_ipo_keys(chan->ipo); - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - duplicate_ipo_keys(conchan->ipo); + if((chan->flag & ACHAN_HIDDEN)==0) { + duplicate_ipo_keys(chan->ipo); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + duplicate_ipo_keys(conchan->ipo); + } } transform_actionchannel_keys ('g', 0); @@ -375,46 +378,16 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, *sel=0; for (chan=act->chanbase.first; chan; chan=chan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { - /* Check action channel */ - ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP); - if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && chan->ipo){ - for (icu=chan->ipo->curve.first; icu; icu=icu->next){ - for (i=0; itotvert; i++){ - if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] <= xmax ){ - if (!firstchan){ - firstchan=chan; - firstvert=icu->bezt[i].vec[1][0]; - *sel = icu->bezt[i].f2 & 1; - } - - if (icu->bezt[i].f2 & 1){ - if (!foundsel){ - foundsel=1; - foundx = icu->bezt[i].vec[1][0]; - } - } - else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ - *index=icu->bezt[i].vec[1][0]; - *sel = 0; - return chan; - } - } - } - } - } - ymax=ymin; - - /* Check constraint channels */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ - ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); - if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && conchan->ipo) { - for (icu=conchan->ipo->curve.first; icu; icu=icu->next){ + /* Check action channel */ + ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && chan->ipo){ + for (icu=chan->ipo->curve.first; icu; icu=icu->next){ for (i=0; itotvert; i++){ if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] <= xmax ){ if (!firstchan){ firstchan=chan; - firstconchan=conchan; firstvert=icu->bezt[i].vec[1][0]; *sel = icu->bezt[i].f2 & 1; } @@ -428,7 +401,6 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ *index=icu->bezt[i].vec[1][0]; *sel = 0; - *rchan = conchan; return chan; } } @@ -436,6 +408,39 @@ static bActionChannel *get_nearest_actionchannel_key (float *index, short *sel, } } ymax=ymin; + + /* Check constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)) && conchan->ipo) { + for (icu=conchan->ipo->curve.first; icu; icu=icu->next){ + for (i=0; itotvert; i++){ + if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] <= xmax ){ + if (!firstchan){ + firstchan=chan; + firstconchan=conchan; + firstvert=icu->bezt[i].vec[1][0]; + *sel = icu->bezt[i].f2 & 1; + } + + if (icu->bezt[i].f2 & 1){ + if (!foundsel){ + foundsel=1; + foundx = icu->bezt[i].vec[1][0]; + } + } + else if (foundsel && icu->bezt[i].vec[1][0] != foundx){ + *index=icu->bezt[i].vec[1][0]; + *sel = 0; + *rchan = conchan; + return chan; + } + } + } + } + } + ymax=ymin; + } } } @@ -695,23 +700,25 @@ void borderselect_action(void) ymax += CHANNELHEIGHT/2; for (chan=act->chanbase.first; chan; chan=chan->next){ - - /* Check action */ - ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); - if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) - borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, - selectmode); - - ymax=ymin; - - /* Check constraints */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { + + /* Check action */ ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) - borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, - selectmode); - + borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, + selectmode); + ymax=ymin; + + /* Check constraints */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP); + if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) + borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, + selectmode); + + ymax=ymin; + } } } BIF_undo_push("Border Select Action"); @@ -803,8 +810,9 @@ bActionChannel* get_hilighted_action_channel(bAction* action) return NULL; for (chan=action->chanbase.first; chan; chan=chan->next){ - if (chan->flag & ACHAN_SELECTED && chan->flag & ACHAN_HILIGHTED) - return chan; + if((chan->flag & ACHAN_HIDDEN)==0) + if (chan->flag & ACHAN_SELECTED && chan->flag & ACHAN_HILIGHTED) + return chan; } return NULL; @@ -857,10 +865,12 @@ void transform_actionchannel_keys(int mode, int dummy) /* Ensure that partial selections result in beztriple selections */ for (chan=act->chanbase.first; chan; chan=chan->next){ - tvtot+=fullselect_ipo_keys(chan->ipo); + if((chan->flag & ACHAN_HIDDEN)==0) { + tvtot+=fullselect_ipo_keys(chan->ipo); - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - tvtot+=fullselect_ipo_keys(conchan->ipo); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot+=fullselect_ipo_keys(conchan->ipo); + } } /* If nothing is selected, bail out */ @@ -873,10 +883,12 @@ void transform_actionchannel_keys(int mode, int dummy) tvtot=0; for (chan=act->chanbase.first; chan; chan=chan->next){ - /* Add the actionchannel */ - tvtot = add_trans_ipo_keys(chan->ipo, tv, tvtot); - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot); + if((chan->flag & ACHAN_HIDDEN)==0) { + /* Add the actionchannel */ + tvtot = add_trans_ipo_keys(chan->ipo, tv, tvtot); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot); + } } /* min max, only every other three */ @@ -1070,6 +1082,7 @@ void transform_actionchannel_keys(int mode, int dummy) allqueue (REDRAWACTION, 0); allqueue(REDRAWNLA, 0); allqueue (REDRAWIPO, 0); + allqueue(REDRAWTIME, 0); MEM_freeN (tv); } @@ -1234,6 +1247,7 @@ void transform_meshchannel_keys(char mode, Key *key) allqueue (REDRAWACTION, 0); allqueue (REDRAWIPO, 0); allqueue(REDRAWNLA, 0); + allqueue(REDRAWTIME, 0); force_draw_all(0); } else { @@ -1272,22 +1286,24 @@ void deselect_actionchannel_keys (bAction *act, int test) if (test){ for (chan=act->chanbase.first; chan; chan=chan->next){ - /* Test the channel ipos */ - if (is_ipo_key_selected(chan->ipo)){ - sel = 0; - break; - } - - /* Test the constraint ipos */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ - if (is_ipo_key_selected(conchan->ipo)){ + if((chan->flag & ACHAN_HIDDEN)==0) { + /* Test the channel ipos */ + if (is_ipo_key_selected(chan->ipo)){ sel = 0; break; } - } - if (sel == 0) - break; + /* Test the constraint ipos */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (is_ipo_key_selected(conchan->ipo)){ + sel = 0; + break; + } + } + + if (sel == 0) + break; + } } } else @@ -1295,9 +1311,11 @@ void deselect_actionchannel_keys (bAction *act, int test) /* Set the flags */ for (chan=act->chanbase.first; chan; chan=chan->next){ - set_ipo_key_selection(chan->ipo, sel); - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - set_ipo_key_selection(conchan->ipo, sel); + if((chan->flag & ACHAN_HIDDEN)==0) { + set_ipo_key_selection(chan->ipo, sel); + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + set_ipo_key_selection(conchan->ipo, sel); + } } } @@ -1334,18 +1352,20 @@ void deselect_actionchannels (bAction *act, int test) /* See if we should be selecting or deselecting */ if (test){ for (chan=act->chanbase.first; chan; chan=chan->next){ - if (!sel) - break; + if((chan->flag & ACHAN_HIDDEN)==0) { + if (!sel) + break; - if (chan->flag & ACHAN_SELECTED){ - sel=0; - break; - } - if (sel){ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ - if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ - sel=0; - break; + if (chan->flag & ACHAN_SELECTED){ + sel=0; + break; + } + if (sel){ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + sel=0; + break; + } } } } @@ -1356,18 +1376,20 @@ void deselect_actionchannels (bAction *act, int test) /* Now set the flags */ for (chan=act->chanbase.first; chan; chan=chan->next){ - select_poseelement_by_name(chan->name, sel); + if((chan->flag & ACHAN_HIDDEN)==0) { + select_poseelement_by_name(chan->name, sel); - if (sel) - chan->flag |= ACHAN_SELECTED; - else - chan->flag &= ~ACHAN_SELECTED; - - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ if (sel) - conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + chan->flag |= ACHAN_SELECTED; else - conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + chan->flag &= ~ACHAN_SELECTED; + + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next){ + if (sel) + conchan->flag |= CONSTRAINT_CHANNEL_SELECT; + else + conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT; + } } } @@ -1513,31 +1535,33 @@ static void mouse_actionchannels(bAction *act, short *mval, */ for (chan = act->chanbase.first; chan; chan=chan->next){ - if (clickmax < 0) break; - - if ( clickmin <= 0) { - /* Select the channel with the given mode. If the - * channel is freshly selected then set it to the - * active channel for the action - */ - sel = (chan->flag & ACHAN_SELECTED); - select_channel(act, chan, selectmode); - /* messy... */ - select_poseelement_by_name(chan->name, 2); - - } - --clickmin; - --clickmax; - - /* Check for click in a constraint */ - for (conchan=chan->constraintChannels.first; - conchan; conchan=conchan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { if (clickmax < 0) break; + if ( clickmin <= 0) { - select_constraint_channel(act, conchan, selectmode); + /* Select the channel with the given mode. If the + * channel is freshly selected then set it to the + * active channel for the action + */ + sel = (chan->flag & ACHAN_SELECTED); + select_channel(act, chan, selectmode); + /* messy... */ + select_poseelement_by_name(chan->name, 2); + } --clickmin; --clickmax; + + /* Check for click in a constraint */ + for (conchan=chan->constraintChannels.first; + conchan; conchan=conchan->next){ + if (clickmax < 0) break; + if ( clickmin <= 0) { + select_constraint_channel(act, conchan, selectmode); + } + --clickmin; + --clickmax; + } } } @@ -1574,13 +1598,15 @@ void delete_actionchannel_keys(void) return; for (chan = act->chanbase.first; chan; chan=chan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { - /* Check action channel keys*/ - delete_ipo_keys(chan->ipo); + /* Check action channel keys*/ + delete_ipo_keys(chan->ipo); - /* Delete constraint channel keys */ - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - delete_ipo_keys(conchan->ipo); + /* Delete constraint channel keys */ + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + delete_ipo_keys(conchan->ipo); + } } remake_action_ipos (act); @@ -1605,13 +1631,15 @@ static void delete_actionchannels (void) return; for (chan=act->chanbase.first; chan; chan=chan->next){ - if (chan->flag & ACHAN_SELECTED) - break; - for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) - { - if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ - chan=act->chanbase.last; + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->flag & ACHAN_SELECTED) break; + for (conchan=chan->constraintChannels.first; conchan; conchan=conchan->next) + { + if (conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + chan=act->chanbase.last; + break; + } } } } @@ -1625,27 +1653,28 @@ static void delete_actionchannels (void) for (chan=act->chanbase.first; chan; chan=next){ freechan = 0; next=chan->next; - - /* Remove action channels */ - if (chan->flag & ACHAN_SELECTED){ - if (chan->ipo) - chan->ipo->id.us--; /* Release the ipo */ - freechan = 1; - } - - /* Remove constraint channels */ - for (conchan=chan->constraintChannels.first; conchan; conchan=nextconchan){ - nextconchan=conchan->next; - if (freechan || conchan->flag & CONSTRAINT_CHANNEL_SELECT){ - if (conchan->ipo) - conchan->ipo->id.us--; - BLI_freelinkN(&chan->constraintChannels, conchan); + if((chan->flag & ACHAN_HIDDEN)==0) { + + /* Remove action channels */ + if (chan->flag & ACHAN_SELECTED){ + if (chan->ipo) + chan->ipo->id.us--; /* Release the ipo */ + freechan = 1; } + + /* Remove constraint channels */ + for (conchan=chan->constraintChannels.first; conchan; conchan=nextconchan){ + nextconchan=conchan->next; + if (freechan || conchan->flag & CONSTRAINT_CHANNEL_SELECT){ + if (conchan->ipo) + conchan->ipo->id.us--; + BLI_freelinkN(&chan->constraintChannels, conchan); + } + } + + if (freechan) + BLI_freelinkN (&act->chanbase, chan); } - - if (freechan) - BLI_freelinkN (&act->chanbase, chan); - } BIF_undo_push("Delete Action channels"); @@ -1678,7 +1707,8 @@ void sethandles_actionchannel_keys(int code) * of the selected keys based on the integer code */ for (chan = act->chanbase.first; chan; chan=chan->next){ - sethandles_ipo_keys(chan->ipo, code); + if((chan->flag & ACHAN_HIDDEN)==0) + sethandles_ipo_keys(chan->ipo, code); } /* Clean up and redraw stuff @@ -1722,9 +1752,11 @@ void set_ipotype_actionchannels(int ipotype) * the value from the popup). */ for (chan = act->chanbase.first; chan; chan=chan->next){ - if (chan->flag & ACHAN_SELECTED){ - if (chan->ipo) - setipotype_ipo(chan->ipo, ipotype); + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->flag & ACHAN_SELECTED){ + if (chan->ipo) + setipotype_ipo(chan->ipo, ipotype); + } } } @@ -1769,21 +1801,23 @@ void set_extendtype_actionchannels(int extendtype) * the value from the popup). */ for (chan = act->chanbase.first; chan; chan=chan->next){ - if (chan->flag & ACHAN_SELECTED) { - if (chan->ipo) { - switch (extendtype) { - case SET_EXTEND_CONSTANT: - setexprap_ipoloop(chan->ipo, IPO_HORIZ); - break; - case SET_EXTEND_EXTRAPOLATION: - setexprap_ipoloop(chan->ipo, IPO_DIR); - break; - case SET_EXTEND_CYCLIC: - setexprap_ipoloop(chan->ipo, IPO_CYCL); - break; - case SET_EXTEND_CYCLICEXTRAPOLATION: - setexprap_ipoloop(chan->ipo, IPO_CYCLX); - break; + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->flag & ACHAN_SELECTED) { + if (chan->ipo) { + switch (extendtype) { + case SET_EXTEND_CONSTANT: + setexprap_ipoloop(chan->ipo, IPO_HORIZ); + break; + case SET_EXTEND_EXTRAPOLATION: + setexprap_ipoloop(chan->ipo, IPO_DIR); + break; + case SET_EXTEND_CYCLIC: + setexprap_ipoloop(chan->ipo, IPO_CYCL); + break; + case SET_EXTEND_CYCLICEXTRAPOLATION: + setexprap_ipoloop(chan->ipo, IPO_CYCLX); + break; + } } } } @@ -1813,8 +1847,10 @@ void set_snap_actionchannels(void) /* Loop through the channels */ for (chan = act->chanbase.first; chan; chan=chan->next){ - if (chan->ipo) { - snap_ipo_keys(chan->ipo); + if((chan->flag & ACHAN_HIDDEN)==0) { + if (chan->ipo) { + snap_ipo_keys(chan->ipo); + } } } @@ -1889,12 +1925,14 @@ static void select_all_keys_frames(bAction *act, short *mval, } for (chan=act->chanbase.first; chan; chan=chan->next){ - borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, - selectmode); - for (conchan=chan->constraintChannels.first; conchan; - conchan=conchan->next){ - borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, + if((chan->flag & ACHAN_HIDDEN)==0) { + borderselect_ipo_key(chan->ipo, rectf.xmin, rectf.xmax, selectmode); + for (conchan=chan->constraintChannels.first; conchan; + conchan=conchan->next){ + borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, + selectmode); + } } } @@ -1966,27 +2004,29 @@ static void select_all_keys_channels(bAction *act, short *mval, } for (chan = act->chanbase.first; chan; chan=chan->next){ - if (clickmax < 0) break; - - if ( clickmin <= 0) { - /* Select the channel with the given mode. If the - * channel is freshly selected then set it to the - * active channel for the action - */ - select_ipo_bezier_keys(chan->ipo, selectmode); - } - --clickmin; - --clickmax; - - /* Check for click in a constraint */ - for (conchan=chan->constraintChannels.first; - conchan; conchan=conchan->next){ + if((chan->flag & ACHAN_HIDDEN)==0) { if (clickmax < 0) break; + if ( clickmin <= 0) { + /* Select the channel with the given mode. If the + * channel is freshly selected then set it to the + * active channel for the action + */ select_ipo_bezier_keys(chan->ipo, selectmode); } --clickmin; --clickmax; + + /* Check for click in a constraint */ + for (conchan=chan->constraintChannels.first; + conchan; conchan=conchan->next){ + if (clickmax < 0) break; + if ( clickmin <= 0) { + select_ipo_bezier_keys(chan->ipo, selectmode); + } + --clickmin; + --clickmax; + } } } @@ -2280,7 +2320,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } break; - + case NKEY: if(G.qual==0) { numbuts_action(); @@ -2542,14 +2582,16 @@ void top_sel_action() if (!act) return; for (chan=act->chanbase.first; chan; chan=chan->next){ - if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ - /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, chan); - /* make it first element */ - BLI_insertlinkbefore(&act->chanbase,act->chanbase.first, chan); - chan->flag |= ACHAN_MOVED; - /* restart with rest of list */ - chan=chan->next; + if((chan->flag & ACHAN_HIDDEN)==0) { + if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ + /* take it out off the chain keep data */ + BLI_remlink (&act->chanbase, chan); + /* make it first element */ + BLI_insertlinkbefore(&act->chanbase,act->chanbase.first, chan); + chan->flag |= ACHAN_MOVED; + /* restart with rest of list */ + chan=chan->next; + } } } /* clear temp flags */ @@ -2577,16 +2619,18 @@ void up_sel_action() if (!act) return; for (chan=act->chanbase.first; chan; chan=chan->next){ - if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ - prev = chan->prev; - if (prev){ - /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, chan); - /* push it up */ - BLI_insertlinkbefore(&act->chanbase,prev, chan); - chan->flag |= ACHAN_MOVED; - /* restart with rest of list */ - chan=chan->next; + if((chan->flag & ACHAN_HIDDEN)==0) { + if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ + prev = chan->prev; + if (prev){ + /* take it out off the chain keep data */ + BLI_remlink (&act->chanbase, chan); + /* push it up */ + BLI_insertlinkbefore(&act->chanbase,prev, chan); + chan->flag |= ACHAN_MOVED; + /* restart with rest of list */ + chan=chan->next; + } } } } @@ -2616,24 +2660,25 @@ void down_sel_action() if (!act) return; for (chan=act->chanbase.last; chan; chan=chan->prev){ - if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ - next = chan->next; - if (next) next = next->next; - if (next){ - /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, chan); - /* move it down */ - BLI_insertlinkbefore(&act->chanbase,next, chan); - chan->flag |= ACHAN_MOVED; + if((chan->flag & ACHAN_HIDDEN)==0) { + if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)){ + next = chan->next; + if (next) next = next->next; + if (next){ + /* take it out off the chain keep data */ + BLI_remlink (&act->chanbase, chan); + /* move it down */ + BLI_insertlinkbefore(&act->chanbase,next, chan); + chan->flag |= ACHAN_MOVED; + } + else { + /* take it out off the chain keep data */ + BLI_remlink (&act->chanbase, chan); + /* add at end */ + BLI_addtail(&act->chanbase,chan); + chan->flag |= ACHAN_MOVED; + } } - else { - /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, chan); - /* add at end */ - BLI_addtail(&act->chanbase,chan); - chan->flag |= ACHAN_MOVED; - } - } } /* clear temp flags */ @@ -2661,14 +2706,15 @@ void bottom_sel_action() if (!act) return; for (chan=act->chanbase.last; chan; chan=chan->prev){ - if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)) { - /* take it out off the chain keep data */ - BLI_remlink (&act->chanbase, chan); - /* add at end */ - BLI_addtail(&act->chanbase,chan); - chan->flag |= ACHAN_MOVED; - } - + if((chan->flag & ACHAN_HIDDEN)==0) { + if ((chan->flag & ACHAN_SELECTED) && !(chan->flag & ACHAN_MOVED)) { + /* take it out off the chain keep data */ + BLI_remlink (&act->chanbase, chan); + /* add at end */ + BLI_addtail(&act->chanbase,chan); + chan->flag |= ACHAN_MOVED; + } + } } /* clear temp flags */ for (chan=act->chanbase.first; chan; chan=chan->next){ @@ -2684,3 +2730,161 @@ void bottom_sel_action() allqueue(REDRAWIPO, 0); allqueue(REDRAWNLA, 0); } + +void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4]) +{ + float imatarm[4][4], imatbone[4][4], tmat[4][4], t2mat[4][4]; + + Mat4Invert(imatarm, armPos); + Mat4Invert(imatbone, restPos); + Mat4MulMat4(tmat, imatarm, worldSpace); + Mat4MulMat4(t2mat, tmat, imatbone); + Mat4MulMat4(boneSpaceMat, restPos, t2mat); +} + + +bAction* bake_obIPO_to_action (Object *ob) +{ + bArmature *arm; + bAction *result=NULL; + bAction *temp; + Bone *bone; + ID *id; + ListBase elems; + int oldframe,testframe; + char newname[64]; + float quat[4],tmat[4][4],startpos[4][4]; + CfraElem *firstcfra, *lastcfra; + + arm = get_armature(ob); + + if (arm) { + + oldframe = CFRA; + result = add_empty_action(ID_PO); + id = (ID *)ob; + + sprintf (newname, "TESTOBBAKE"); + rename_id(&result->id, newname); + + if(ob!=G.obedit) { // make sure object is not in edit mode + if(ob->ipo) { + /* convert the ipo to a list of 'current frame elements' */ + + temp = ob->action; + ob->action = result; + + elems.first= elems.last= NULL; + make_cfra_list(ob->ipo, &elems); + /* set the beginning armature location */ + firstcfra=elems.first; + lastcfra=elems.last; + CFRA=firstcfra->cfra; + + where_is_object(ob); + Mat4CpyMat4(startpos,ob->obmat); + + /* loop from first key to last, sampling every 10 */ + for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) { + CFRA=testframe; + where_is_object(ob); + + for (bone = arm->bonebase.first; bone; bone=bone->next) { + if (!bone->parent) { /* this is a root bone, so give it a key! */ + world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos); + Mat4ToQuat(tmat,quat); + printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]); + } + } + } + BLI_freelistN(&elems); + } + } + CFRA = oldframe; + } + return result; +} + +bAction* bake_everything_to_action (Object *ob) +{ + bArmature *arm; + bAction *result=NULL; + bAction *temp; + Bone *bone; + ID *id; + ListBase elems; + int oldframe,testframe; + char newname[64]; + float quat[4],tmat[4][4],startpos[4][4]; + CfraElem *firstcfra, *lastcfra; + + arm = get_armature(ob); + + if (arm) { + + oldframe = CFRA; + result = add_empty_action(ID_PO); + id = (ID *)ob; + + sprintf (newname, "TESTOBBAKE"); + rename_id(&result->id, newname); + + if(ob!=G.obedit) { // make sure object is not in edit mode + if(ob->ipo) { + /* convert the ipo to a list of 'current frame elements' */ + + temp = ob->action; + ob->action = result; + + elems.first= elems.last= NULL; + make_cfra_list(ob->ipo, &elems); + /* set the beginning armature location */ + firstcfra=elems.first; + lastcfra=elems.last; + CFRA=firstcfra->cfra; + + where_is_object(ob); + Mat4CpyMat4(startpos,ob->obmat); + + /* loop from first key to last, sampling every 10 */ + for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) { + CFRA=testframe; + + do_all_pose_actions(ob); + where_is_object(ob); + for (bone = arm->bonebase.first; bone; bone=bone->next) { + if (!bone->parent) { /* this is a root bone, so give it a key! */ + world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos); + + Mat4ToQuat(tmat,quat); + printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]); + insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]); + //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]); + } + } + } + BLI_freelistN(&elems); + } + } + CFRA = oldframe; + } + return result; +} diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index d80f603aa28..0c315e65005 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -137,6 +137,8 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent) else eBone->flag |= BONE_ROOTSEL; } + else + eBone->flag &= ~BONE_ROOTSEL; VECCOPY(eBone->head, curBone->arm_head); VECCOPY(eBone->tail, curBone->arm_tail); @@ -166,7 +168,7 @@ void make_boneList(ListBase* list, ListBase *bones, EditBone *parent) eBone->rad_head= curBone->rad_head; eBone->rad_tail= curBone->rad_tail; eBone->segments = curBone->segments; - eBone->boneclass = curBone->boneclass; + eBone->layer = curBone->layer; BLI_addtail (list, eBone); @@ -262,7 +264,7 @@ void editbones_to_armature (ListBase *list, Object *ob) newBone->rad_head= eBone->rad_head; newBone->rad_tail= eBone->rad_tail; newBone->segments= eBone->segments; - newBone->boneclass = eBone->boneclass; + newBone->layer = eBone->layer; } @@ -606,42 +608,6 @@ void selectconnected_posearmature(void) } -static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbones){ - - Bone *curBone; - - if (!bone) - return incount; - - if (bone->flag & flagmask || flagmask == 0xFFFFFFFF){ - incount++; - if (!allbones) - return incount; - } - - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - incount=count_bonechildren (curBone, incount, flagmask, allbones); - } - - return incount; -} - -static int count_bones (bArmature *arm, int flagmask, int allbones) -{ - int count=0; - Bone *curBone; - - if (!arm) - return 0; - - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ - count = count_bonechildren (curBone, count, flagmask, allbones); - } - - return count; - -} - /* **************** END Posemode stuff ********************** */ /* **************** EditMode stuff ********************** */ @@ -811,20 +777,21 @@ static EditBone *editbone_name_exists (char *name); // proto for below /* only editmode! */ void delete_armature(void) { + bArmature *arm= G.obedit->data; EditBone *curBone, *next; bConstraint *con; TEST_EDITARMATURE; if(okee("Erase selected bone(s)")==0) return; - /* First rase any associated pose channel */ + /* First erase any associated pose channel */ if (G.obedit->pose){ bPoseChannel *chan, *next; for (chan=G.obedit->pose->chanbase.first; chan; chan=next) { next= chan->next; curBone = editbone_name_exists (chan->name); - if (curBone && (curBone->flag&BONE_SELECTED)) { + if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) { free_constraints(&chan->constraints); BLI_freelinkN (&G.obedit->pose->chanbase, chan); } @@ -833,7 +800,7 @@ void delete_armature(void) char *subtarget = get_con_subtarget_name(con, G.obedit); if (subtarget) { curBone = editbone_name_exists (subtarget); - if (curBone && (curBone->flag&BONE_SELECTED)) { + if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) { con->flag |= CONSTRAINT_DISABLE; subtarget[0]= 0; } @@ -846,8 +813,9 @@ void delete_armature(void) for (curBone=G.edbo.first;curBone;curBone=next){ next=curBone->next; - if (curBone->flag&BONE_SELECTED) - delete_bone(curBone); + if(arm->layer & curBone->layer) + if (curBone->flag & BONE_SELECTED) + delete_bone(curBone); } @@ -993,6 +961,7 @@ void load_editArmature(void) */ void deselectall_armature(int toggle) { + bArmature *arm= G.obedit->data; EditBone *eBone; int sel=1; @@ -1000,18 +969,25 @@ void deselectall_armature(int toggle) /* Determine if there are any selected bones And therefore whether we are selecting or deselecting */ for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){ - sel=0; - break; +// if(arm->layer & eBone->layer) { + if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){ + sel=0; + break; + } } - } +// } } else sel= toggle; /* Set the flags */ for (eBone=G.edbo.first;eBone;eBone=eBone->next){ - if (sel==1) - eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + if (sel==1) { + if(arm->layer & eBone->layer) { + eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + if(eBone->parent) + eBone->parent->flag |= (BONE_TIPSEL); + } + } else if (sel==2) eBone->flag &= ~(BONE_ACTIVE); else @@ -1029,6 +1005,7 @@ void deselectall_armature(int toggle) void auto_align_armature(void) /* Sets the roll value of selected bones so that their zaxes point upwards */ { + bArmature *arm= G.obedit->data; EditBone *ebone; float xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0}; float targetmat[3][3], imat[3][3]; @@ -1036,26 +1013,28 @@ void auto_align_armature(void) float delta[3]; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if (ebone->flag & BONE_SELECTED){ - /* Find the current bone matrix */ - VecSubf(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, 0.0, curmat); - - /* Make new matrix based on y axis & z-up */ - VECCOPY (yaxis, curmat[1]); - - Mat3One(targetmat); - VECCOPY (targetmat[0], xaxis); - VECCOPY (targetmat[1], yaxis); - VECCOPY (targetmat[2], zaxis); - Mat3Ortho(targetmat); - - /* Find the difference between the two matrices */ - Mat3Inv(imat, targetmat); - Mat3MulMat3(diffmat, imat, curmat); - - ebone->roll = atan(diffmat[2][0]/diffmat[2][2]); - + if(arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED){ + /* Find the current bone matrix */ + VecSubf(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, 0.0, curmat); + + /* Make new matrix based on y axis & z-up */ + VECCOPY (yaxis, curmat[1]); + + Mat3One(targetmat); + VECCOPY (targetmat[0], xaxis); + VECCOPY (targetmat[1], yaxis); + VECCOPY (targetmat[2], zaxis); + Mat3Ortho(targetmat); + + /* Find the difference between the two matrices */ + Mat3Inv(imat, targetmat); + Mat3MulMat3(diffmat, imat, curmat); + + ebone->roll = atan(diffmat[2][0]/diffmat[2][2]); + + } } } } @@ -1130,6 +1109,8 @@ void undo_push_armature(char *name) /* default bone add, returns it selected, but without tail set */ static EditBone *add_editbone(char *name) { + bArmature *arm= G.obedit->data; + EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone"); BLI_strncpy (bone->name, name, 32); @@ -1147,6 +1128,7 @@ static EditBone *add_editbone(char *name) bone->rad_head= 0.10; bone->rad_tail= 0.05; bone->segments= 1; + bone->layer= arm->layer; return bone; } @@ -1223,11 +1205,13 @@ void addvert_armature(void) /* find the active or selected bone */ for (ebone = G.edbo.first; ebone; ebone=ebone->next) - if(ebone->flag & (BONE_ACTIVE|BONE_TIPSEL)) break; + if(arm->layer & ebone->layer) + if(ebone->flag & (BONE_ACTIVE|BONE_TIPSEL)) break; if(ebone==NULL) { for (ebone = G.edbo.first; ebone; ebone=ebone->next) - if(ebone->flag & (BONE_ACTIVE|BONE_ROOTSEL)) break; + if(arm->layer & ebone->layer) + if(ebone->flag & (BONE_ACTIVE|BONE_ROOTSEL)) break; if(ebone==NULL) return; @@ -1294,6 +1278,7 @@ void addvert_armature(void) void adduplicate_armature(void) { + bArmature *arm= G.obedit->data; EditBone *eBone = NULL; EditBone *curBone; EditBone *firstDup=NULL; /* The beginning of the duplicated bones in the edbo list */ @@ -1302,66 +1287,69 @@ void adduplicate_armature(void) /* Find the selected bones and duplicate them as needed */ for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ - if (curBone->flag & BONE_SELECTED){ - - eBone=MEM_callocN(sizeof(EditBone), "addup_editbone"); - eBone->flag |= BONE_SELECTED; - - /* Copy data from old bone to new bone */ - memcpy (eBone, curBone, sizeof(EditBone)); - - curBone->temp = eBone; - eBone->temp = curBone; - - unique_editbone_name (eBone->name); - BLI_addtail (&G.edbo, eBone); - if (!firstDup) - firstDup=eBone; - - /* Lets duplicate the list of constraits that the - * current bone has. - */ - /* temporal removed (ton) */ + if(arm->layer & curBone->layer) { + if (curBone->flag & BONE_SELECTED){ + + eBone=MEM_callocN(sizeof(EditBone), "addup_editbone"); + eBone->flag |= BONE_SELECTED; + + /* Copy data from old bone to new bone */ + memcpy (eBone, curBone, sizeof(EditBone)); + + curBone->temp = eBone; + eBone->temp = curBone; + + unique_editbone_name (eBone->name); + BLI_addtail (&G.edbo, eBone); + if (!firstDup) + firstDup=eBone; + + /* Lets duplicate the list of constraits that the + * current bone has. + */ + /* temporal removed (ton) */ + } } } /* Run though the list and fix the pointers */ for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ - - if (curBone->flag & BONE_SELECTED){ - eBone=(EditBone*) curBone->temp; - - /* If this bone has no parent, - Set the duplicate->parent to NULL - */ - if (!curBone->parent){ - eBone->parent = NULL; - } - /* If this bone has a parent that IS selected, - Set the duplicate->parent to the curBone->parent->duplicate + if(arm->layer & curBone->layer) { + if (curBone->flag & BONE_SELECTED){ + eBone=(EditBone*) curBone->temp; + + /* If this bone has no parent, + Set the duplicate->parent to NULL */ - else if (curBone->parent->flag & BONE_SELECTED){ - eBone->parent=(EditBone*) curBone->parent->temp; - } - /* If this bone has a parent that IS not selected, - Set the duplicate->parent to the curBone->parent - */ - else { - eBone->parent=(EditBone*) curBone->parent; - eBone->flag &= ~BONE_CONNECTED; - } - - /* Lets try to fix any constraint subtargets that might - have been duplicated */ - /* temporal removed (ton) */ - + if (!curBone->parent){ + eBone->parent = NULL; + } + /* If this bone has a parent that IS selected, + Set the duplicate->parent to the curBone->parent->duplicate + */ + else if (curBone->parent->flag & BONE_SELECTED){ + eBone->parent=(EditBone*) curBone->parent->temp; + } + /* If this bone has a parent that IS not selected, + Set the duplicate->parent to the curBone->parent + */ + else { + eBone->parent=(EditBone*) curBone->parent; + eBone->flag &= ~BONE_CONNECTED; + } + + /* Lets try to fix any constraint subtargets that might + have been duplicated */ + /* temporal removed (ton) */ + } } } /* Deselect the old bones and select the new ones */ for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){ - curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); + if(arm->layer & curBone->layer) + curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE); } BIF_TransformSetUndo("Add Duplicate"); @@ -1381,12 +1369,15 @@ void adduplicate_armature(void) void hide_selected_armature_bones(void) { + bArmature *arm= G.obedit->data; EditBone *ebone; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if(ebone->flag & (BONE_SELECTED)) { - ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); - ebone->flag |= BONE_HIDDEN_A; + if(arm->layer & ebone->layer) { + if(ebone->flag & (BONE_SELECTED)) { + ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); + ebone->flag |= BONE_HIDDEN_A; + } } } countall(); @@ -1399,10 +1390,13 @@ void hide_unselected_armature_bones(void) EditBone *ebone; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if(ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL)); - else { - ebone->flag &= ~BONE_ACTIVE; - ebone->flag |= BONE_HIDDEN_A; + bArmature *arm= G.obedit->data; + if(arm->layer & ebone->layer) { + if(ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL)); + else { + ebone->flag &= ~BONE_ACTIVE; + ebone->flag |= BONE_HIDDEN_A; + } } } countall(); @@ -1415,9 +1409,12 @@ void show_all_armature_bones(void) EditBone *ebone; for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if(ebone->flag & BONE_HIDDEN_A) { - ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); - ebone->flag &= ~BONE_HIDDEN_A; + bArmature *arm= G.obedit->data; + if(arm->layer & ebone->layer) { + if(ebone->flag & BONE_HIDDEN_A) { + ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL); + ebone->flag &= ~BONE_HIDDEN_A; + } } } countall(); @@ -1427,6 +1424,7 @@ void show_all_armature_bones(void) void make_bone_parent(void) { + bArmature *arm= G.obedit->data; EditBone *ebone; float offset[3]; short val; @@ -1437,18 +1435,22 @@ void make_bone_parent(void) /* find active */ for (ebone = G.edbo.first; ebone; ebone=ebone->next) - if(ebone->flag & BONE_ACTIVE) break; + if(arm->layer & ebone->layer) + if(ebone->flag & BONE_ACTIVE) break; + if(ebone) { EditBone *actbone= ebone, *selbone= NULL; /* find selected */ for (ebone = G.edbo.first; ebone; ebone=ebone->next) { - if(ebone->flag & BONE_SELECTED) { - if(ebone!=actbone) { - if(selbone==NULL) selbone= ebone; - else { - error("Need one active and one selected bone"); - return; + if(arm->layer & ebone->layer) { + if(ebone->flag & BONE_SELECTED) { + if(ebone!=actbone) { + if(selbone==NULL) selbone= ebone; + else { + error("Need one active and one selected bone"); + return; + } } } } @@ -1516,6 +1518,7 @@ void make_bone_parent(void) void clear_bone_parent(void) { + bArmature *arm= G.obedit->data; EditBone *ebone; short val; @@ -1523,13 +1526,15 @@ void clear_bone_parent(void) if(val<1) return; for (ebone = G.edbo.first; ebone; ebone=ebone->next) { - if(ebone->flag & BONE_SELECTED) { - if(ebone->parent) { - /* for nice selection */ - ebone->parent->flag &= ~(BONE_TIPSEL); - - if(val==1) ebone->parent= NULL; - ebone->flag &= ~BONE_CONNECTED; + if(arm->layer & ebone->layer) { + if(ebone->flag & BONE_SELECTED) { + if(ebone->parent) { + /* for nice selection */ + ebone->parent->flag &= ~(BONE_TIPSEL); + + if(val==1) ebone->parent= NULL; + ebone->flag &= ~BONE_CONNECTED; + } } } } @@ -1592,108 +1597,111 @@ void extrude_armature(int forked) /* since we allow root extrude too, we have to make sure selection is OK */ for (ebone = G.edbo.first; ebone; ebone=ebone->next){ - if(ebone->flag & BONE_ROOTSEL) { - if(ebone->parent && (ebone->flag & BONE_CONNECTED)) { - if(ebone->parent->flag & BONE_TIPSEL) - ebone->flag &= ~BONE_ROOTSEL; + if(arm->layer & ebone->layer) { + if(ebone->flag & BONE_ROOTSEL) { + if(ebone->parent && (ebone->flag & BONE_CONNECTED)) { + if(ebone->parent->flag & BONE_TIPSEL) + ebone->flag &= ~BONE_ROOTSEL; + } } } } /* Duplicate the necessary bones */ for (ebone = G.edbo.first; ((ebone) && (ebone!=first)); ebone=ebone->next){ - - /* we extrude per definition the tip */ - do_extrude= 0; - if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED)) - do_extrude= 1; - else if(ebone->flag & BONE_ROOTSEL) { - /* but, a bone with parent deselected we do the root... */ - if(ebone->parent && (ebone->parent->flag & BONE_TIPSEL)); - else do_extrude= 2; - } - - if (do_extrude) { - - /* we re-use code for mirror editing... */ - flipbone= NULL; - if(arm->flag & ARM_MIRROR_EDIT) { - flipbone= armature_bone_get_mirrored(ebone); - if (flipbone) { - forked= 0; // we extrude 2 different bones - if(flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED)) - /* don't want this bone to be selected... */ - flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); - } - if(flipbone==NULL && forked) - flipbone= ebone; + if(arm->layer & ebone->layer) { + + /* we extrude per definition the tip */ + do_extrude= 0; + if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED)) + do_extrude= 1; + else if(ebone->flag & BONE_ROOTSEL) { + /* but, a bone with parent deselected we do the root... */ + if(ebone->parent && (ebone->parent->flag & BONE_TIPSEL)); + else do_extrude= 2; } - for(a=0; a<2; a++) { - if(a==1) { - if(flipbone==NULL) - break; + if (do_extrude) { + + /* we re-use code for mirror editing... */ + flipbone= NULL; + if(arm->flag & ARM_MIRROR_EDIT) { + flipbone= armature_bone_get_mirrored(ebone); + if (flipbone) { + forked= 0; // we extrude 2 different bones + if(flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED)) + /* don't want this bone to be selected... */ + flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); + } + if(flipbone==NULL && forked) + flipbone= ebone; + } + + for(a=0; a<2; a++) { + if(a==1) { + if(flipbone==NULL) + break; + else { + SWAP(EditBone *, flipbone, ebone); + } + } + + totbone++; + newbone = MEM_callocN(sizeof(EditBone), "extrudebone"); + + if(do_extrude==1) { + VECCOPY (newbone->head, ebone->tail); + VECCOPY (newbone->tail, newbone->head); + newbone->parent = ebone; + + newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone + } else { + VECCOPY(newbone->head, ebone->head); + VECCOPY(newbone->tail, ebone->head); + newbone->parent= ebone->parent; + + newbone->flag= BONE_TIPSEL; + } + + newbone->weight= ebone->weight; + newbone->dist= ebone->dist; + newbone->xwidth= ebone->xwidth; + newbone->zwidth= ebone->zwidth; + newbone->ease1= ebone->ease1; + newbone->ease2= ebone->ease2; + newbone->rad_head= ebone->rad_tail; // dont copy entire bone... + newbone->rad_tail= ebone->rad_tail; + newbone->segments= 1; + newbone->layer= ebone->layer; + + if(newbone->parent) newbone->flag |= BONE_CONNECTED; + + BLI_strncpy (newbone->name, ebone->name, 32); + + if(flipbone && forked) { // only set if mirror edit + if(strlen(newbone->name)<30) { + if(a==0) strcat(newbone->name, "_L"); + else strcat(newbone->name, "_R"); + } + } + unique_editbone_name(newbone->name); + + /* Add the new bone to the list */ + BLI_addtail(&G.edbo, newbone); + if (!first) + first = newbone; + + /* restore ebone if we were flipping */ + if(a==1 && flipbone) SWAP(EditBone *, flipbone, ebone); - } - } - - totbone++; - newbone = MEM_callocN(sizeof(EditBone), "extrudebone"); - - if(do_extrude==1) { - VECCOPY (newbone->head, ebone->tail); - VECCOPY (newbone->tail, newbone->head); - newbone->parent = ebone; - - newbone->flag = ebone->flag & BONE_TIPSEL; // copies it, in case mirrored bone - } - else { - VECCOPY(newbone->head, ebone->head); - VECCOPY(newbone->tail, ebone->head); - newbone->parent= ebone->parent; - - newbone->flag= BONE_TIPSEL; - } - newbone->weight= ebone->weight; - newbone->dist= ebone->dist; - newbone->xwidth= ebone->xwidth; - newbone->zwidth= ebone->zwidth; - newbone->ease1= ebone->ease1; - newbone->ease2= ebone->ease2; - newbone->rad_head= ebone->rad_tail; // dont copy entire bone... - newbone->rad_tail= ebone->rad_tail; - newbone->segments= 1; - newbone->boneclass= ebone->boneclass; - - if(newbone->parent) newbone->flag |= BONE_CONNECTED; - - BLI_strncpy (newbone->name, ebone->name, 32); - - if(flipbone && forked) { // only set if mirror edit - if(strlen(newbone->name)<30) { - if(a==0) strcat(newbone->name, "_L"); - else strcat(newbone->name, "_R"); - } } - unique_editbone_name(newbone->name); - - /* Add the new bone to the list */ - BLI_addtail(&G.edbo, newbone); - if (!first) - first = newbone; - - /* restore ebone if we were flipping */ - if(a==1 && flipbone) - SWAP(EditBone *, flipbone, ebone); - } - } - - /* Deselect the old bone */ - ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); - + + /* Deselect the old bone */ + ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE); + } } /* if only one bone, make this one active */ if(totbone==1 && first) first->flag |= BONE_ACTIVE; @@ -1717,39 +1725,41 @@ void subdivide_armature(void) int a; for (mbone = G.edbo.last; mbone; mbone= mbone->prev) { - if(mbone->flag & BONE_SELECTED) { - - /* take care of mirrored stuff */ - for(a=0; a<2; a++) { - if(a==0) ebone= mbone; - else { - if(arm->flag & ARM_MIRROR_EDIT) - ebone= armature_bone_get_mirrored(mbone); - else ebone= NULL; - } - if(ebone) { - - newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv"); - *newbone = *ebone; - BLI_addtail(&G.edbo, newbone); - - VecMidf(newbone->head, ebone->head, ebone->tail); - VECCOPY(newbone->tail, ebone->tail); - VECCOPY(ebone->tail, newbone->head); - - newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail); - ebone->rad_tail= newbone->rad_head; - - newbone->flag |= BONE_CONNECTED; - - unique_editbone_name (newbone->name); - - /* correct parent bones */ - for (tbone = G.edbo.first; tbone; tbone=tbone->next){ - if(tbone->parent==ebone) - tbone->parent= newbone; + if(arm->layer & mbone->layer) { + if(mbone->flag & BONE_SELECTED) { + + /* take care of mirrored stuff */ + for(a=0; a<2; a++) { + if(a==0) ebone= mbone; + else { + if(arm->flag & ARM_MIRROR_EDIT) + ebone= armature_bone_get_mirrored(mbone); + else ebone= NULL; + } + if(ebone) { + + newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv"); + *newbone = *ebone; + BLI_addtail(&G.edbo, newbone); + + VecMidf(newbone->head, ebone->head, ebone->tail); + VECCOPY(newbone->tail, ebone->tail); + VECCOPY(ebone->tail, newbone->head); + + newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail); + ebone->rad_tail= newbone->rad_head; + + newbone->flag |= BONE_CONNECTED; + + unique_editbone_name (newbone->name); + + /* correct parent bones */ + for (tbone = G.edbo.first; tbone; tbone=tbone->next){ + if(tbone->parent==ebone) + tbone->parent= newbone; + } + newbone->parent= ebone; } - newbone->parent= ebone; } } } @@ -1770,17 +1780,19 @@ void clear_armature(Object *ob, char mode) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { - switch (mode){ - case 'r': - pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; pchan->quat[0]=1.0F; - break; - case 'g': - pchan->loc[0]=pchan->loc[1]=pchan->loc[2]=0.0F; - break; - case 's': - pchan->size[0]=pchan->size[1]=pchan->size[2]=1.0F; - break; - + if(arm->layer & pchan->bone->layer) { + switch (mode){ + case 'r': + pchan->quat[1]=pchan->quat[2]=pchan->quat[3]=0.0F; pchan->quat[0]=1.0F; + break; + case 'g': + pchan->loc[0]=pchan->loc[1]=pchan->loc[2]=0.0F; + break; + case 's': + pchan->size[0]=pchan->size[1]=pchan->size[2]=1.0F; + break; + + } } } } @@ -1860,32 +1872,6 @@ int do_pose_selectbuffer(Base *base, unsigned int *buffer, short hits) } -/* mode==0: deselect - mode==1: select - mode==2: clear active tag -*/ -static void deselect_bonechildren (Object *ob, Bone *bone, int mode) -{ - Bone *curBone; - - if (!bone) - return; - - if (mode==0) - bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); - else if (mode==1) { - if(!(bone->flag & BONE_HIDDEN_P)) - bone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); - } - else bone->flag &= ~BONE_ACTIVE; - - if(mode!=2) select_actionchannel_by_name(ob->action, bone->name, mode); - - for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ - deselect_bonechildren(ob, curBone, mode); - } -} - /* test==0: deselect all test==1: swap select test==2: only clear active tag @@ -1893,7 +1879,7 @@ static void deselect_bonechildren (Object *ob, Bone *bone, int mode) void deselectall_posearmature (Object *ob, int test) { bArmature *arm; - Bone *curBone; + bPoseChannel *pchan; int selectmode= 0; /* we call this from outliner too, but with OBACT set OK */ @@ -1902,15 +1888,30 @@ void deselectall_posearmature (Object *ob, int test) /* Determine if we're selecting or deselecting */ if (test==1) { - if (!count_bones (arm, BONE_SELECTED, 0)) + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) + if(pchan->bone->layer & arm->layer) + if(pchan->bone->flag & BONE_SELECTED) + break; + + if (pchan==NULL) selectmode= 1; } else if(test==2) selectmode= 2; /* Set the flags accordingly */ - for (curBone=arm->bonebase.first; curBone; curBone=curBone->next) - deselect_bonechildren (ob, curBone, selectmode); + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone->layer & arm->layer) { + if(selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE); + else if(selectmode==1) pchan->bone->flag |= BONE_SELECTED; + else pchan->bone->flag &= ~BONE_ACTIVE; + } + } + + /* action editor */ + deselect_actionchannels(ob->action, 0); /* deselects for sure */ + if(selectmode==1) + deselect_actionchannels(ob->action, 1); /* swaps */ allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSOBJECT, 0); @@ -2229,9 +2230,13 @@ void create_vgroups_from_armature(Object *ob, Object *par) static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) { - if (bone->flag & BONE_SELECTED) { - bone->flag |= BONE_HIDDEN_P; - bone->flag &= ~BONE_SELECTED; + bArmature *arm= ob->data; + + if(arm->layer & bone->layer) { + if (bone->flag & BONE_SELECTED) { + bone->flag |= BONE_HIDDEN_P; + bone->flag &= ~BONE_SELECTED; + } } return 0; } @@ -2239,9 +2244,7 @@ static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr) /* active object is armature */ void hide_selected_pose_bones(void) { - bArmature *arm; - - arm= get_armature (OBACT); + bArmature *arm= OBACT->data; if (!arm) return; @@ -2255,8 +2258,12 @@ void hide_selected_pose_bones(void) static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr) { - if (~bone->flag & BONE_SELECTED) { - bone->flag |= BONE_HIDDEN_P; + bArmature *arm= ob->data; + + if(arm->layer & bone->layer) { + if (~bone->flag & BONE_SELECTED) { + bone->flag |= BONE_HIDDEN_P; + } } return 0; } @@ -2280,9 +2287,13 @@ void hide_unselected_pose_bones(void) static int show_pose_bone(Object *ob, Bone *bone, void *ptr) { - if (bone->flag & BONE_HIDDEN_P) { - bone->flag &= ~BONE_HIDDEN_P; - bone->flag |= BONE_SELECTED; + bArmature *arm= ob->data; + + if(arm->layer & bone->layer) { + if (bone->flag & BONE_HIDDEN_P) { + bone->flag &= ~BONE_HIDDEN_P; + bone->flag |= BONE_SELECTED; + } } return 0; @@ -2454,14 +2465,17 @@ void armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) /* context editmode object */ void armature_flip_names(void) { + bArmature *arm= G.obedit->data; EditBone *ebone; char newname[32]; for (ebone = G.edbo.first; ebone; ebone=ebone->next) { - if(ebone->flag & BONE_SELECTED) { - BLI_strncpy(newname, ebone->name, sizeof(newname)); - bone_flip_name(newname, 1); // 1 = do strip off number extensions - armature_bone_rename(G.obedit->data, ebone->name, newname); + if(arm->layer & ebone->layer) { + if(ebone->flag & BONE_SELECTED) { + BLI_strncpy(newname, ebone->name, sizeof(newname)); + bone_flip_name(newname, 1); // 1 = do strip off number extensions + armature_bone_rename(G.obedit->data, ebone->name, newname); + } } } @@ -2497,6 +2511,7 @@ void transform_armature_mirror_update(void) EditBone *ebo, *eboflip; for (ebo=G.edbo.first; ebo; ebo=ebo->next) { + /* no layer check, correct mirror is more important */ if(ebo->flag & (BONE_TIPSEL|BONE_ROOTSEL)) { eboflip= armature_bone_get_mirrored(ebo); diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c index 229c70c89ec..a85f0dd835d 100644 --- a/source/blender/src/editconstraint.c +++ b/source/blender/src/editconstraint.c @@ -587,18 +587,20 @@ void add_constraint(int only_IK) /* paranoia checks */ if(ob==NULL || ob==G.obedit) return; - + if(ob->pose && (ob->flag & OB_POSEMODE)) { - + bArmature *arm= ob->data; + /* find active channel */ - for(pchanact= ob->pose->chanbase.first; pchanact; pchanact= pchanact->next) - if(pchanact->bone->flag & BONE_ACTIVE) break; + pchanact= get_active_posechannel(ob); if(pchanact==NULL) return; /* find selected bone */ for(pchansel= ob->pose->chanbase.first; pchansel; pchansel= pchansel->next) { if(pchansel!=pchanact) - if(pchansel->bone->flag & BONE_SELECTED) break; + if(pchansel->bone->flag & BONE_SELECTED) + if(pchansel->bone->layer & arm->layer) + break; } } @@ -674,6 +676,7 @@ void add_constraint(int only_IK) con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC); BLI_addtail(&pchanact->constraints, con); + unique_constraint_name(con, &pchanact->constraints); pchanact->constflag |= PCHAN_HAS_IK; // for draw, but also for detecting while pose solving if(nr==11) pchanact->constflag |= PCHAN_HAS_TARGET; } @@ -691,10 +694,12 @@ void add_constraint(int only_IK) if(pchanact) { BLI_addtail(&pchanact->constraints, con); + unique_constraint_name(con, &pchanact->constraints); pchanact->constflag |= PCHAN_HAS_CONST; /* for draw */ } else { BLI_addtail(&ob->constraints, con); + unique_constraint_name(con, &ob->constraints); } } diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index 787b6a6471a..11179467a2f 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -34,10 +34,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" @@ -1023,7 +1019,8 @@ void face_borderselect() Mesh *me; TFace *tface; rcti rect; - unsigned int *rectm, *rt; + struct ImBuf *ibuf; + unsigned int *rt; int a, sx, sy, index, val; char *selar; @@ -1046,9 +1043,10 @@ void face_borderselect() sy= (rect.ymax-rect.ymin+1); if(sx*sy<=0) return; - rt=rectm= MEM_mallocN(sizeof(int)*sx*sy, "selrect"); - glReadPixels(rect.xmin+curarea->winrct.xmin, rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, rectm); - if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(sx*sy, rectm); + ibuf = IMB_allocImBuf(sx,sy,32,0,0); + rt = ibuf->rect; + glReadPixels(rect.xmin+curarea->winrct.xmin, rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); a= sx*sy; while(a--) { @@ -1070,7 +1068,7 @@ void face_borderselect() } } - MEM_freeN(rectm); + IMB_freeImBuf(ibuf); MEM_freeN(selar); BIF_undo_push("Border Select UV face"); diff --git a/source/blender/src/editgroup.c b/source/blender/src/editgroup.c index f55f07986a4..67d6701b13e 100644 --- a/source/blender/src/editgroup.c +++ b/source/blender/src/editgroup.c @@ -42,14 +42,15 @@ #include "DNA_scene_types.h" #include "DNA_view3d_types.h" +#include "BKE_depsgraph.h" #include "BKE_group.h" #include "BKE_global.h" #include "BKE_main.h" -#include "BIF_space.h" #include "BIF_interface.h" -#include "BIF_toolbox.h" #include "BIF_editgroup.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" #include "blendef.h" #include "mydevice.h" @@ -58,115 +59,73 @@ #include #endif -void set_active_group(void) +void add_selected_to_group(Group *group) { - /* with active object, find active group */ - Group *group; - GroupObject *go; + Base *base; - G.scene->group= NULL; - - if(BASACT) { - group= G.main->group.first; - while(group) { - go= group->gobject.first; - while(go) { - if(go->ob == OBACT) { - G.scene->group= group; - return; - } - go= go->next; - } - group= group->id.next; - } - } -} - - -void add_selected_to_group(void) -{ - Base *base= FIRSTBASE; - Group *group; - - if(BASACT==NULL) { - error("No active object"); - return; - } - - if(okee("Add selected to group")==0) return; - - if(G.scene->group==NULL) G.scene->group= add_group(); - - while(base) { + for(base=FIRSTBASE; base; base= base->next) { if TESTBASE(base) { - - /* each object only in one group */ - group= find_group(base->object); - if(group==G.scene->group); - else { - if(group) { - rem_from_group(group, base->object); - } - add_to_group(G.scene->group, base->object); - base->object->flag |= OB_FROMGROUP; - base->flag |= OB_FROMGROUP; - } + add_to_group(group, base->object); + base->object->flag |= OB_FROMGROUP; + base->flag |= OB_FROMGROUP; } - base= base->next; } allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSOBJECT, 0); + DAG_scene_sort(G.scene); + BIF_undo_push("Add to Group"); } void rem_selected_from_group(void) { - Base *base=FIRSTBASE; + Base *base; Group *group; - if(okee("Remove selected from group")==0) return; - - while(base) { + for(base=FIRSTBASE; base; base= base->next) { if TESTBASE(base) { - group= find_group(base->object); - if(group) { + while( (group = find_group(base->object)) ) { rem_from_group(group, base->object); - - base->object->flag &= ~OB_FROMGROUP; - base->flag &= ~OB_FROMGROUP; } + base->object->flag &= ~OB_FROMGROUP; + base->flag &= ~OB_FROMGROUP; } - base= base->next; } + DAG_scene_sort(G.scene); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWBUTSOBJECT, 0); + BIF_undo_push("Remove from Group"); } -void prev_group_key(Group *group) +void group_operation_with_menu(void) { - GroupKey *gk= group->active; + Base *base; + Group *group= NULL; + int mode; - if(gk) gk= gk->prev; + for(base=FIRSTBASE; base; base= base->next) { + if TESTBASE(base) { + group= find_group(base->object); + if(group) break; + } + } - if(gk==NULL) group->active= group->gkey.last; - else group->active= gk; + if(group && group->id.lib) { + error("Cannot edit library data"); + return; + } - set_group_key(group); -} - -void next_group_key(Group *group) -{ - GroupKey *gk= group->active; + if(base) + mode= pupmenu("Groups %t|Add to current Group %x3|Add to New Group %x1|Remove from all Groups %x2"); + else + mode= pupmenu("Groups %t|Add to New Group %x1|Remove from all Groups %x2"); - if(gk) gk= gk->next; - - if(gk==NULL) group->active= group->gkey.first; - else group->active= gk; - - set_group_key(group); - -} - - + if(mode>0) { + if(group==NULL || mode==1) group= add_group(); + + if(mode==1 || mode==3) add_selected_to_group(group); + else if(mode==2) rem_selected_from_group(); + } +} \ No newline at end of file diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c index 6fb5d411b98..3d2b3c8b715 100644 --- a/source/blender/src/editimasel.c +++ b/source/blender/src/editimasel.c @@ -179,7 +179,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt) queredraw = 1; case 1: /* dir entry */ - checkdir(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); clear_ima_dir(simasel); queredraw = 1; break; @@ -188,7 +188,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt) selname= fsmenu_get_entry(simasel->fileselmenuitem-1); if (selname) { strcpy(simasel->dir, selname); - checkdir(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); clear_ima_dir(simasel); queredraw = 1; } @@ -349,7 +349,7 @@ void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } if (G.qual == 0){ imadir_parent(simasel); - checkdir(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); clear_ima_dir(simasel); queredraw = 1; } diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index a7f7a24a515..e6a98b4b004 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -1969,6 +1969,42 @@ void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcod } } +/* For inserting keys based on the object matrix - not on the current IPO value + Generically - it inserts the passed float value into the appropriate IPO */ +void insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float matrixvalue) +{ + IpoCurve *icu; + Object *ob; + void *poin= NULL; + float cfra; + int vartype; + + icu= verify_ipocurve(id, blocktype, actname, constname, adrcode); + + if(icu) { + + poin= get_context_ipo_poin(id, blocktype, actname, icu, &vartype); + + if(poin) { + + cfra= frame_to_float(CFRA); + + /* if action is mapped in NLA, it returns a correction */ + if(actname && actname[0] && GS(id->name)==ID_OB) + cfra= get_action_frame((Object *)id, cfra); + + if( GS(id->name)==ID_OB ) { + ob= (Object *)id; + if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) { + /* actually frametofloat calc again! */ + cfra-= ob->sf*G.scene->r.framelen; + } + } + insert_vert_ipo(icu, cfra, matrixvalue); + } + } +} + void insertkey_editipo(void) { EditIpo *ei; @@ -2426,7 +2462,7 @@ void common_insertkey(void) ob= OBACT; if (ob && (ob->flag & OB_POSEMODE)) { - strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9"); + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13"); } else { base= FIRSTBASE; @@ -2435,8 +2471,7 @@ void common_insertkey(void) base= base->next; } if(base==NULL) return; - - strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9"); + strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13"); } if(ob) { @@ -2444,7 +2479,6 @@ void common_insertkey(void) else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7"); else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7"); else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7"); - if(ob->flag & OB_FROMGROUP) strcat(menustr, "| %x6|Entire Group%x10"); } event= pupmenu(menustr); @@ -2455,14 +2489,6 @@ void common_insertkey(void) return; } - if(event==10) { - Group *group= find_group(ob); - if(group) { - add_group_key(group); - allqueue(REDRAWBUTSOBJECT, 0); - } - } - if (ob && (ob->flag & OB_POSEMODE)){ bPoseChannel *pchan; @@ -2503,6 +2529,25 @@ void common_insertkey(void) } } } + if(event==11 || event==13) { + float obSpaceBoneMat[4][4]; + + bone2objectspace(obSpaceBoneMat, pchan->pose_mat, pchan->bone->arm_mat); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, obSpaceBoneMat[3][0]); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, obSpaceBoneMat[3][1]); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, obSpaceBoneMat[3][2]); + } + if(event==12 || event==13) { + float obSpaceBoneMat[4][4]; + float localQuat[4]; + + bone2objectspace(obSpaceBoneMat, pchan->pose_mat, pchan->bone->arm_mat); + Mat4ToQuat(obSpaceBoneMat, localQuat); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, localQuat[0]); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, localQuat[1]); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, localQuat[2]); + insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, localQuat[2]); + } } } if(ob->action) @@ -2555,6 +2600,21 @@ void common_insertkey(void) insertkey(id, ID_OB, actname, NULL, OB_LAY); base->object->lay= tlay; } + if(event==11 || event==13) { + insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X, ob->obmat[3][0]); + insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y, ob->obmat[3][1]); + insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z, ob->obmat[3][2]); + } + if(event==12 || event==13) { + float eul[3]; + float rotMat[3][3]; + + Mat3CpyMat4(rotMat, ob->obmat); + Mat3ToEul(rotMat, eul); + insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X, eul[0]*(5.72958)); + insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y, eul[1]*(5.72958)); + insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z, eul[2]*(5.72958)); + } } base= base->next; } @@ -4548,3 +4608,12 @@ void move_to_frame(void) } BIF_undo_push("Set frame to selected Ipo vertex"); } + +void bone2objectspace(float obSpaceBoneMat[][4], float obSpace[][4], float restPos[][4]) +{ + float imat[4][4]; + + Mat4Invert(imat, restPos); + Mat4MulMat4(obSpaceBoneMat, obSpace, imat); +} + diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index b62353438ad..e54bb0c156d 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -78,6 +78,7 @@ #include "BIF_editmesh.h" #include "BIF_editmode_undo.h" #include "BIF_interface.h" +#include "BIF_meshtools.h" #include "BIF_mywindow.h" #include "BIF_space.h" #include "BIF_screen.h" @@ -537,6 +538,8 @@ void free_editMesh(EditMesh *em) em->alledges= em->curedge= NULL; em->allfaces= em->curface= NULL; + mesh_octree_table(NULL, NULL, 'e'); + G.totvert= G.totface= 0; } @@ -564,7 +567,7 @@ static void edge_normal_compare(EditEdge *eed, EditFace *efa1) float cent1[3], cent2[3]; float inp; - efa2= (EditFace *)eed->vn; + efa2 = eed->tmp.f; if(efa1==efa2) return; inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2]; @@ -608,7 +611,7 @@ static void edge_drawflags(void) EditFace *efa; /* - count number of times edges are used in faces: 0 en 1 time means draw edge - * - edges more than 1 time used: in *vn is pointer to first face + * - edges more than 1 time used: in *tmp.f is pointer to first face * - check all faces, when normal differs to much: draw (flag becomes 1) */ @@ -627,7 +630,7 @@ static void edge_drawflags(void) eed= em->edges.first; while(eed) { eed->f2= eed->f1= 0; - eed->vn= 0; + eed->tmp.f = 0; eed= eed->next; } @@ -642,10 +645,10 @@ static void edge_drawflags(void) if(e3->f2<4) e3->f2+= 1; if(e4 && e4->f2<4) e4->f2+= 1; - if(e1->vn==0) e1->vn= (EditVert *)efa; - if(e2->vn==0) e2->vn= (EditVert *)efa; - if(e3->vn==0) e3->vn= (EditVert *)efa; - if(e4 && e4->vn==0) e4->vn= (EditVert *)efa; + if(e1->tmp.f == 0) e1->tmp.f = (void *) efa; + if(e2->tmp.f == 0) e2->tmp.f = (void *) efa; + if(e3->tmp.f ==0) e3->tmp.f = (void *) efa; + if(e4 && (e4->tmp.f == 0)) e4->tmp.f = (void *) efa; efa= efa->next; } @@ -917,7 +920,7 @@ void load_editMesh(void) me->mface= mface; me->totface= G.totface; - /* the vertices, abuse ->vn as counter */ + /* the vertices, use ->tmp.l as counter */ eve= em->verts.first; a= 0; @@ -941,7 +944,7 @@ void load_editMesh(void) } } - eve->vn= (EditVert *)(long)(a++); /* counter */ + eve->tmp.l = a++; /* counter */ mvert->flag= 0; if(eve->f1==1) mvert->flag |= ME_SPHERETEST; @@ -956,8 +959,8 @@ void load_editMesh(void) /* the edges */ eed= em->edges.first; while(eed) { - medge->v1= (unsigned int) eed->v1->vn; - medge->v2= (unsigned int) eed->v2->vn; + medge->v1= (unsigned int) eed->v1->tmp.l; + medge->v2= (unsigned int) eed->v2->tmp.l; medge->flag= (eed->f & SELECT) | ME_EDGERENDER; if(eed->f2<2) medge->flag |= ME_EDGEDRAW; @@ -978,10 +981,10 @@ void load_editMesh(void) while(efa) { mface= &((MFace *) me->mface)[i]; - mface->v1= (unsigned int) efa->v1->vn; - mface->v2= (unsigned int) efa->v2->vn; - mface->v3= (unsigned int) efa->v3->vn; - if(efa->v4) mface->v4= (unsigned int) efa->v4->vn; + mface->v1= (unsigned int) efa->v1->tmp.l; + mface->v2= (unsigned int) efa->v2->tmp.l; + mface->v3= (unsigned int) efa->v3->tmp.l; + if (efa->v4) mface->v4 = (unsigned int) efa->v4->tmp.l; mface->mat_nr= efa->mat_nr; @@ -1104,7 +1107,7 @@ void load_editMesh(void) eve = vertMap[hmd->indexar[i]]; if (eve) { - hmd->indexar[j++] = (long) eve->vn; + hmd->indexar[j++] = eve->tmp.l; } } else j++; @@ -1172,10 +1175,10 @@ void load_editMesh(void) if(oldverts) MEM_freeN(oldverts); - /* to be sure: clear ->vn pointers */ + /* to be sure: clear ->tmp.l pointers */ eve= em->verts.first; while(eve) { - eve->vn= 0; + eve->tmp.l = 0; eve= eve->next; } @@ -1636,13 +1639,13 @@ static void *editMesh_to_undoMesh(void) evec->totweight= eve->totweight; evec->dw= MEM_dupallocN(eve->dw); - eve->vn= (EditVert *)a; + eve->tmp.l = a; } /* copy edges */ for(eed=em->edges.first; eed; eed= eed->next, eedc++) { - eedc->v1= (int)eed->v1->vn; - eedc->v2= (int)eed->v2->vn; + eedc->v1= (int)eed->v1->tmp.l; + eedc->v2= (int)eed->v2->tmp.l; eedc->f= eed->f; eedc->h= eed->h; eedc->seam= eed->seam; @@ -1652,10 +1655,10 @@ static void *editMesh_to_undoMesh(void) /* copy faces */ for(efa=em->faces.first; efa; efa= efa->next, efac++) { - efac->v1= (int)efa->v1->vn; - efac->v2= (int)efa->v2->vn; - efac->v3= (int)efa->v3->vn; - if(efa->v4) efac->v4= (int)efa->v4->vn; + efac->v1= (int)efa->v1->tmp.l; + efac->v2= (int)efa->v2->tmp.l; + efac->v3= (int)efa->v3->tmp.l; + if(efa->v4) efac->v4= (int)efa->v4->tmp.l; else efac->v4= -1; efac->mat_nr= efa->mat_nr; diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index 153a6b1b945..fecd6efecce 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -604,9 +604,9 @@ short extrudeflag_edges_indiv(short flag, float *nor) EditEdge *eed; EditFace *efa; - for(eve= em->verts.first; eve; eve= eve->next) eve->vn= NULL; + for(eve= em->verts.first; eve; eve= eve->next) eve->tmp.v = NULL; for(eed= em->edges.first; eed; eed= eed->next) { - eed->vn= NULL; + eed->tmp.f = NULL; eed->f2= ((eed->f & flag)!=0); } @@ -614,24 +614,32 @@ short extrudeflag_edges_indiv(short flag, float *nor) /* sample for next loop */ for(efa= em->faces.first; efa; efa= efa->next) { - efa->e1->vn= (EditVert *)efa; - efa->e2->vn= (EditVert *)efa; - efa->e3->vn= (EditVert *)efa; - if(efa->e4) efa->e4->vn= (EditVert *)efa; + efa->e1->tmp.f = efa; + efa->e2->tmp.f = efa; + efa->e3->tmp.f = efa; + if(efa->e4) efa->e4->tmp.f = efa; } /* make the faces */ for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & flag) { - if(eed->v1->vn==NULL) eed->v1->vn= addvertlist(eed->v1->co); - if(eed->v2->vn==NULL) eed->v2->vn= addvertlist(eed->v2->co); + if(eed->v1->tmp.v == NULL) + eed->v1->tmp.v = addvertlist(eed->v1->co); + if(eed->v2->tmp.v == NULL) + eed->v2->tmp.v = addvertlist(eed->v2->co); - if(eed->dir==1) addfacelist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, (EditFace *)eed->vn, NULL); - else addfacelist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, (EditFace *)eed->vn, NULL); + if(eed->dir==1) + addfacelist(eed->v1, eed->v2, + eed->v2->tmp.v, eed->v1->tmp.v, + eed->tmp.f, NULL); + else + addfacelist(eed->v2, eed->v1, + eed->v1->tmp.v, eed->v2->tmp.v, + eed->tmp.f, NULL); /* for transform */ - if(eed->vn) { - efa= (EditFace *)eed->vn; - if(efa->f & SELECT) add_normal_aligned(nor, efa->n); + if(eed->tmp.f) { + efa = eed->tmp.f; + if (efa->f & SELECT) add_normal_aligned(nor, efa->n); } } } @@ -640,8 +648,8 @@ short extrudeflag_edges_indiv(short flag, float *nor) /* set correct selection */ EM_clear_flag_all(SELECT); for(eve= em->verts.last; eve; eve= eve->prev) { - if(eve->vn) { - eve->vn->f |= flag; + if(eve->tmp.v) { + eve->tmp.v->f |= flag; } } @@ -662,16 +670,18 @@ short extrudeflag_verts_indiv(short flag, float *nor) /* make the edges */ for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & flag) { - eve->vn= addvertlist(eve->co); - addedgelist(eve, eve->vn, NULL); + eve->tmp.v = addvertlist(eve->co); + addedgelist(eve, eve->tmp.v, NULL); } - else eve->vn= NULL; + else eve->tmp.v = NULL; } /* set correct selection */ EM_clear_flag_all(SELECT); - for(eve= em->verts.last; eve; eve= eve->prev) if(eve->vn) eve->vn->f |= flag; + for(eve= em->verts.last; eve; eve= eve->prev) + if (eve->tmp.v) + eve->tmp.v->f |= flag; return 'g'; // g is grab } @@ -706,7 +716,7 @@ static short extrudeflag_edge(short flag, float *nor) recalc_editnormals(); for(eve= em->verts.first; eve; eve= eve->next) { - eve->vn= NULL; + eve->tmp.v = NULL; eve->f1= 0; } @@ -717,7 +727,7 @@ static short extrudeflag_edge(short flag, float *nor) eed->v1->f1= 1; // we call this 'selected vertex' now eed->v2->f1= 1; } - eed->vn= NULL; // here we tuck face pointer, as sample + eed->tmp.f = NULL; // here we tuck face pointer, as sample } for(efa= em->faces.first; efa; efa= efa->next) { if(efa->f & SELECT) { @@ -727,10 +737,10 @@ static short extrudeflag_edge(short flag, float *nor) if(efa->e4) efa->e4->f2++; // sample for next loop - efa->e1->vn= (EditVert *)efa; - efa->e2->vn= (EditVert *)efa; - efa->e3->vn= (EditVert *)efa; - if(efa->e4) efa->e4->vn= (EditVert *)efa; + efa->e1->tmp.f = efa; + efa->e2->tmp.f = efa; + efa->e3->tmp.f = efa; + if(efa->e4) efa->e4->tmp.f = efa; } else { efa->e1->f1++; @@ -756,14 +766,22 @@ static short extrudeflag_edge(short flag, float *nor) for(eed= em->edges.last; eed; eed= eed->prev) { if(eed->f & SELECT) { if(eed->f2<2) { - if(eed->v1->vn==NULL) - eed->v1->vn= addvertlist(eed->v1->co); - if(eed->v2->vn==NULL) - eed->v2->vn= addvertlist(eed->v2->co); + if(eed->v1->tmp.v == NULL) + eed->v1->tmp.v = addvertlist(eed->v1->co); + if(eed->v2->tmp.v == NULL) + eed->v2->tmp.v = addvertlist(eed->v2->co); - /* if del_old, the preferred normal direction is exact opposite as for keep old faces */ - if(eed->dir!=del_old) addfacelist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, (EditFace *)eed->vn, NULL); - else addfacelist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, (EditFace *)eed->vn, NULL); + /* if del_old, the preferred normal direction is exact + * opposite as for keep old faces + */ + if(eed->dir!=del_old) + addfacelist(eed->v1, eed->v2, + eed->v2->tmp.v, eed->v1->tmp.v, + eed->tmp.f, NULL); + else + addfacelist(eed->v2, eed->v1, + eed->v1->tmp.v, eed->v2->tmp.v, + eed->tmp.f, NULL); } } } @@ -771,22 +789,30 @@ static short extrudeflag_edge(short flag, float *nor) /* step 3: make new faces from faces */ for(efa= em->faces.last; efa; efa= efa->prev) { if(efa->f & SELECT) { - if(efa->v1->vn==NULL) efa->v1->vn= addvertlist(efa->v1->co); - if(efa->v2->vn==NULL) efa->v2->vn= addvertlist(efa->v2->co); - if(efa->v3->vn==NULL) efa->v3->vn= addvertlist(efa->v3->co); - if(efa->v4 && efa->v4->vn==NULL) efa->v4->vn= addvertlist(efa->v4->co); + if (efa->v1->tmp.v == NULL) + efa->v1->tmp.v = addvertlist(efa->v1->co); + if (efa->v2->tmp.v ==NULL) + efa->v2->tmp.v = addvertlist(efa->v2->co); + if (efa->v3->tmp.v ==NULL) + efa->v3->tmp.v = addvertlist(efa->v3->co); + if (efa->v4 && (efa->v4->tmp.v == NULL)) + efa->v4->tmp.v = addvertlist(efa->v4->co); if(del_old==0) { // keep old faces means flipping normal if(efa->v4) - addfacelist(efa->v4->vn, efa->v3->vn, efa->v2->vn, efa->v1->vn, efa, efa); + addfacelist(efa->v4->tmp.v, efa->v3->tmp.v, + efa->v2->tmp.v, efa->v1->tmp.v, efa, efa); else - addfacelist(efa->v3->vn, efa->v2->vn, efa->v1->vn, NULL, efa, efa); + addfacelist(efa->v3->tmp.v, efa->v2->tmp.v, + efa->v1->tmp.v, NULL, efa, efa); } else { if(efa->v4) - addfacelist(efa->v1->vn, efa->v2->vn, efa->v3->vn, efa->v4->vn, efa, efa); + addfacelist(efa->v1->tmp.v, efa->v2->tmp.v, + efa->v3->tmp.v, efa->v4->tmp.v, efa, efa); else - addfacelist(efa->v1->vn, efa->v2->vn, efa->v3->vn, NULL, efa, efa); + addfacelist(efa->v1->tmp.v, efa->v2->tmp.v, + efa->v3->tmp.v, NULL, efa, efa); } /* for transform */ @@ -837,7 +863,7 @@ static short extrudeflag_edge(short flag, float *nor) nextve= eve->next; if(eve->f1) { // hack... but we need it for step 7, redoing selection - if(eve->vn) eve->vn->vn= eve->vn; + if(eve->tmp.v) eve->tmp.v->tmp.v= eve->tmp.v; BLI_remlink(&em->verts, eve); free_editvert(eve); @@ -852,8 +878,8 @@ static short extrudeflag_edge(short flag, float *nor) EM_clear_flag_all(SELECT); for(eve= em->verts.first; eve; eve= eve->next) { - if(eve->vn) { - eve->vn->f |= SELECT; + if(eve->tmp.v) { + eve->tmp.v->f |= SELECT; } } @@ -893,7 +919,7 @@ short extrudeflag_vert(short flag, float *nor) else eed->f2= 0; eed->f1= 1; /* this indicates it is an 'old' edge (in this routine we make new ones) */ - eed->vn= NULL; /* abused as sample */ + eed->tmp.f = NULL; /* used as sample */ eed= eed->next; } @@ -931,10 +957,10 @@ short extrudeflag_vert(short flag, float *nor) } // sample for next loop - efa->e1->vn= (EditVert *)efa; - efa->e2->vn= (EditVert *)efa; - efa->e3->vn= (EditVert *)efa; - if(efa->e4) efa->e4->vn= (EditVert *)efa; + efa->e1->tmp.f = efa; + efa->e2->tmp.f = efa; + efa->e3->tmp.f = efa; + if(efa->e4) efa->e4->tmp.f = efa; efa= efa->next; } @@ -957,7 +983,7 @@ short extrudeflag_vert(short flag, float *nor) */ /* copy all selected vertices, */ - /* write pointer to new vert in old struct at eve->vn */ + /* write pointer to new vert in old struct at eve->tmp.v */ eve= em->verts.last; while(eve) { eve->f &= ~128; /* clear, for later test for loose verts */ @@ -968,9 +994,9 @@ short extrudeflag_vert(short flag, float *nor) VECCOPY(v1->co, eve->co); v1->f= eve->f; eve->f-= flag; - eve->vn= v1; + eve->tmp.v = v1; } - else eve->vn= 0; + else eve->tmp.v = 0; eve= eve->prev; } @@ -1007,11 +1033,17 @@ short extrudeflag_vert(short flag, float *nor) if( (eed->f2==1 || eed->f2==2) ) { /* if del_old, the preferred normal direction is exact opposite as for keep old faces */ - if(eed->dir!=del_old) efa2= addfacelist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL, NULL); - else efa2= addfacelist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL, NULL); + if(eed->dir != del_old) + efa2 = addfacelist(eed->v1, eed->v2, + eed->v2->tmp.v, eed->v1->tmp.v, + NULL, NULL); + else + efa2 = addfacelist(eed->v2, eed->v1, + eed->v1->tmp.v, eed->v2->tmp.v, + NULL, NULL); - if(eed->vn) { - efa= (EditFace *)eed->vn; + if(eed->tmp.f) { + efa = eed->tmp.f; efa2->mat_nr= efa->mat_nr; efa2->tf= efa->tf; efa2->flag= efa->flag; @@ -1046,15 +1078,19 @@ short extrudeflag_vert(short flag, float *nor) nextvl= efa->next; if(efa->f1 & 1) { - v1= efa->v1->vn; - v2= efa->v2->vn; - v3= efa->v3->vn; - if(efa->v4) v4= efa->v4->vn; else v4= 0; - - if(del_old==0) // if we keep old, we flip normal - efa2= addfacelist(v3, v2, v1, v4, efa, efa); /* hmm .. not sure about edges here */ + v1 = efa->v1->tmp.v; + v2 = efa->v2->tmp.v; + v3 = efa->v3->tmp.v; + if(efa->v4) + v4 = efa->v4->tmp.v; else - efa2= addfacelist(v1, v2, v3, v4, efa, efa); /* hmm .. not sure about edges here */ + v4= 0; + + /* hmm .. not sure about edges here */ + if(del_old==0) // if we keep old, we flip normal + efa2= addfacelist(v3, v2, v1, v4, efa, efa); + else + efa2= addfacelist(v1, v2, v3, v4, efa, efa); /* for transform */ add_normal_aligned(nor, efa->n); @@ -1069,15 +1105,15 @@ short extrudeflag_vert(short flag, float *nor) Normalise(nor); // for grab - /* for all vertices with eve->vn!=0 + /* for all vertices with eve->tmp.v!=0 if eve->f1==1: make edge if flag!=128 : if del_old==1: remove */ eve= em->verts.last; while(eve) { nextve= eve->prev; - if(eve->vn) { - if(eve->f1==1) addedgelist(eve, eve->vn, NULL); + if(eve->tmp.v) { + if(eve->f1==1) addedgelist(eve, eve->tmp.v, NULL); else if( (eve->f & 128)==0) { if(del_old) { BLI_remlink(&em->verts,eve); @@ -1168,7 +1204,7 @@ void adduplicateflag(int flag) eve->f-= flag; eve->f|= 128; - eve->vn= v1; + eve->tmp.v = v1; /* >>>>> FIXME: Copy deformation weight ? */ v1->totweight = eve->totweight; @@ -1184,8 +1220,8 @@ void adduplicateflag(int flag) /* copy edges */ for(eed= em->edges.last; eed; eed= eed->prev) { if( eed->f & flag ) { - v1= eed->v1->vn; - v2= eed->v2->vn; + v1 = eed->v1->tmp.v; + v2 = eed->v2->tmp.v; newed= addedgelist(v1, v2, eed); newed->f= eed->f; @@ -1197,10 +1233,10 @@ void adduplicateflag(int flag) /* then dupicate faces */ for(efa= em->faces.last; efa; efa= efa->prev) { if(efa->f & flag) { - v1= efa->v1->vn; - v2= efa->v2->vn; - v3= efa->v3->vn; - if(efa->v4) v4= efa->v4->vn; else v4= NULL; + v1 = efa->v1->tmp.v; + v2 = efa->v2->tmp.v; + v3 = efa->v3->tmp.v; + if(efa->v4) v4 = efa->v4->tmp.v; else v4= NULL; newfa= addfacelist(v1, v2, v3, v4, efa, efa); newfa->f= efa->f; diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index eda53fe0edc..330555c5f14 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -40,10 +40,6 @@ editmesh_mods.c, UI level access, no geometry changes #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MEM_guardedalloc.h" #include "MTC_matrixops.h" @@ -92,27 +88,19 @@ editmesh_mods.c, UI level access, no geometry changes #include "BSE_edit.h" #include "BSE_view.h" +#include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "RE_render_ext.h" // externtex + #include "mydevice.h" #include "blendef.h" -#include "render.h" // externtex #include "editmesh.h" /* ****************************** MIRROR **************** */ -static EditVert *get_x_mirror_vert(EditVert *eve) -{ - int index; - - index= mesh_get_x_mirror_vert(G.obedit, POINTER_TO_INT(eve)); - if(index != -1) - return INT_TO_POINTER(index); - return NULL; -} - void EM_select_mirrored(void) { if(G.scene->selectmode & SCE_SELECT_VERTEX) { @@ -121,7 +109,7 @@ void EM_select_mirrored(void) for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & SELECT) { - v1= get_x_mirror_vert(eve); + v1= editmesh_get_x_mirror_vert(G.obedit, eve->co); if(v1) { eve->f &= ~SELECT; v1->f |= SELECT; @@ -165,11 +153,12 @@ static unsigned int sample_backbuf(int x, int y) } /* reads full rect, converts indices */ -static unsigned int *read_backbuf(short xmin, short ymin, short xmax, short ymax) +struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax) { - unsigned int *dr, *buf; + unsigned int *dr, *rd; + struct ImBuf *ibuf, *ibuf1; int a; - short xminc, yminc, xmaxc, ymaxc; + short xminc, yminc, xmaxc, ymaxc, xs, ys; /* clip */ if(xmin<0) xminc= 0; else xminc= xmin; @@ -180,55 +169,49 @@ static unsigned int *read_backbuf(short xmin, short ymin, short xmax, short ymax if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax; if(yminc > ymaxc) return NULL; - buf= MEM_mallocN( (xmaxc-xminc+1)*(ymaxc-yminc+1)*sizeof(int), "sample rect"); + ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0); check_backbuf(); // actually not needed for apple #ifdef __APPLE__ glReadBuffer(GL_AUX0); #endif - glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, buf); + glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glReadBuffer(GL_BACK); - if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr((xmaxc-xminc+1)*(ymaxc-yminc+1), buf); + if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); a= (xmaxc-xminc+1)*(ymaxc-yminc+1); - dr= buf; + dr= ibuf->rect; while(a--) { if(*dr) *dr= framebuffer_to_index(*dr); dr++; } /* put clipped result back, if needed */ - if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return buf; - else { - unsigned int *buf1= MEM_callocN( (xmax-xmin+1)*(ymax-ymin+1)*sizeof(int), "sample rect2"); - unsigned int *rd; - short xs, ys; - - rd= buf; - dr= buf1; + if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf; + ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0); + rd= ibuf->rect; + dr= ibuf1->rect; - for(ys= ymin; ys<=ymax; ys++) { - for(xs= xmin; xs<=xmax; xs++, dr++) { - if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) { - *dr= *rd; - rd++; - } + for(ys= ymin; ys<=ymax; ys++) { + for(xs= xmin; xs<=xmax; xs++, dr++) { + if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) { + *dr= *rd; + rd++; } } - MEM_freeN(buf); - return buf1; } - - return buf; + IMB_freeImBuf(ibuf); + return ibuf1; } /* smart function to sample a rect spiralling outside, nice for backbuf selection */ static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist) { - unsigned int *buf, *bufmin, *bufmax; + struct ImBuf *buf; + unsigned int *bufmin, *bufmax, *tbuf; int minx, miny; int a, b, rc, nr, amount, dirvec[4][2]; short distance=0; @@ -239,8 +222,7 @@ static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int mi minx = mval[0]-(amount+1); miny = mval[1]-(amount+1); buf = read_backbuf(minx, miny, minx+size-1, miny+size-1); - if (!buf) - return 0; + if (!buf) return 0; rc= 0; @@ -249,23 +231,24 @@ static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int mi dirvec[2][0]= -1; dirvec[2][1]= 0; dirvec[3][0]= 0; dirvec[3][1]= size; - bufmin= buf; - bufmax= buf+ size*size; - buf+= amount*size+ amount; + bufmin = buf->rect; + tbuf = buf->rect; + bufmax = buf->rect + size*size; + tbuf+= amount*size+ amount; for(nr=1; nr<=size; nr++) { for(a=0; a<2; a++) { for(b=0; b=min && *buf=min && *tbuf=bufmax) { + if(tbuf=bufmax) { goto exit; } } @@ -275,7 +258,7 @@ static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int mi } exit: - MEM_freeN(bufmin); + IMB_freeImBuf(buf); return index; } @@ -332,14 +315,17 @@ static void draw_triangulated(short mcords[][2], short tot) /* returns if all is OK */ int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax) { - unsigned int *buf, *dr; + struct ImBuf *buf; + unsigned int *dr; int a; if(G.obedit==NULL || G.vd->drawtypeflag & V3D_ZBUF_SELECT)==0) return 0; if(em_vertoffs==0) return 0; - dr= buf= read_backbuf(xmin, ymin, xmax, ymax); + buf= read_backbuf(xmin, ymin, xmax, ymax); if(buf==NULL) return 0; + + dr = buf->rect; /* build selection lookup */ selbuf= MEM_callocN(em_vertoffs+1, "selbuf"); @@ -350,7 +336,7 @@ int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax) selbuf[*dr]= 1; dr++; } - MEM_freeN(buf); + IMB_freeImBuf(buf); return 1; } @@ -376,7 +362,8 @@ void EM_free_backbuf(void) */ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) { - unsigned int *buf, *bufmask, *dr, *drm; + unsigned int *dr, *drm; + struct ImBuf *buf, *bufmask; int a; /* method in use for face selecting too */ @@ -388,9 +375,11 @@ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short if(em_vertoffs==0) return 0; - dr= buf= read_backbuf(xmin, ymin, xmax, ymax); + buf= read_backbuf(xmin, ymin, xmax, ymax); if(buf==NULL) return 0; + dr = buf->rect; + /* draw the mask */ #ifdef __APPLE__ glDrawBuffer(GL_AUX0); @@ -413,7 +402,8 @@ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short glDrawBuffer(GL_BACK); /* grab mask */ - drm= bufmask= read_backbuf(xmin, ymin, xmax, ymax); + bufmask= read_backbuf(xmin, ymin, xmax, ymax); + drm = bufmask->rect; if(bufmask==NULL) return 0; // only when mem alloc fails, go crash somewhere else! /* build selection lookup */ @@ -424,8 +414,8 @@ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short if(*dr>0 && *dr<=em_vertoffs && *drm==0) selbuf[*dr]= 1; dr++; drm++; } - MEM_freeN(buf); - MEM_freeN(bufmask); + IMB_freeImBuf(buf); + IMB_freeImBuf(bufmask); return 1; } @@ -433,7 +423,8 @@ int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short /* circle shaped sample area */ int EM_init_backbuf_circle(short xs, short ys, short rads) { - unsigned int *buf, *dr; + struct ImBuf *buf; + unsigned int *dr; short xmin, ymin, xmax, ymax, xc, yc; int radsq; @@ -447,8 +438,10 @@ int EM_init_backbuf_circle(short xs, short ys, short rads) xmin= xs-rads; xmax= xs+rads; ymin= ys-rads; ymax= ys+rads; - dr= buf= read_backbuf(xmin, ymin, xmax, ymax); + buf= read_backbuf(xmin, ymin, xmax, ymax); if(buf==NULL) return 0; + + dr = buf->rect; /* build selection lookup */ selbuf= MEM_callocN(em_vertoffs+1, "selbuf"); @@ -461,7 +454,7 @@ int EM_init_backbuf_circle(short xs, short ys, short rads) } } - MEM_freeN(buf); + IMB_freeImBuf(buf); return 1; } @@ -1517,6 +1510,250 @@ void select_faces_by_numverts(int numverts) BIF_undo_push("Select non-Triangles/Quads"); } +void select_sharp_edges(void) +{ + /* Find edges that have exactly two neighboring faces, + * check the angle between those faces, and if angle is + * small enough, select the edge + */ + EditMesh *em = G.editMesh; + EditEdge *eed; + EditFace *efa; + EditFace **efa1; + EditFace **efa2; + long edgecount = 0, i; + static short sharpness = 135; + float fsharpness; + + if(G.scene->selectmode==SCE_SELECT_FACE) { + error("Doesn't work in face selection mode"); + return; + } + + if(button(&sharpness,0, 180,"Max Angle:")==0) return; + /* if faces are at angle 'sharpness', then the face normals + * are at angle 180.0 - 'sharpness' (convert to radians too) + */ + fsharpness = ((180.0 - sharpness) * M_PI) / 180.0; + + i=0; + /* count edges, use tmp.l */ + eed= em->edges.first; + while(eed) { + edgecount++; + eed->tmp.l = i; + eed= eed->next; + ++i; + } + + /* for each edge, we want a pointer to two adjacent faces */ + efa1 = MEM_callocN(edgecount*sizeof(EditFace *), + "pairs of edit face pointers"); + efa2 = MEM_callocN(edgecount*sizeof(EditFace *), + "pairs of edit face pointers"); + +#define face_table_edge(eed) { \ + i = eed->tmp.l; \ + if (i != -1) { \ + if (efa1[i]) { \ + if (efa2[i]) { \ + /* invalidate, edge has more than two neighbors */ \ + eed->tmp.l = -1; \ + } \ + else { \ + efa2[i] = efa; \ + } \ + } \ + else { \ + efa1[i] = efa; \ + } \ + } \ + } + + /* find the adjacent faces of each edge, we want only two */ + efa= em->faces.first; + while(efa) { + face_table_edge(efa->e1); + face_table_edge(efa->e2); + face_table_edge(efa->e3); + if (efa->e4) { + face_table_edge(efa->e4); + } + efa= efa->next; + } + +#undef face_table_edge + + eed = em->edges.first; + while(eed) { + i = eed->tmp.l; + if (i != -1) { + /* edge has two or less neighboring faces */ + if ( (efa1[i]) && (efa2[i]) ) { + /* edge has exactly two neighboring faces, check angle */ + float angle; + angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] + + efa1[i]->n[1]*efa2[i]->n[1] + + efa1[i]->n[2]*efa2[i]->n[2]); + if (fabs(angle) >= fsharpness) + EM_select_edge(eed, 1); + } + } + + eed= eed->next; + } + + MEM_freeN(efa1); + MEM_freeN(efa2); + + countall(); + addqueue(curarea->win, REDRAW, 0); + BIF_undo_push("Select Sharp Edges"); +} + +void select_linked_flat_faces(void) +{ + /* Find faces that are linked to selected faces that are + * relatively flat (angle between faces is higher than + * specified angle) + */ + EditMesh *em = G.editMesh; + EditEdge *eed; + EditFace *efa; + EditFace **efa1; + EditFace **efa2; + long edgecount = 0, i, faceselcount=0, faceselcountold=0; + static short sharpness = 135; + float fsharpness; + + if(G.scene->selectmode!=SCE_SELECT_FACE) { + error("Only works in face selection mode"); + return; + } + + if(button(&sharpness,0, 180,"Min Angle:")==0) return; + /* if faces are at angle 'sharpness', then the face normals + * are at angle 180.0 - 'sharpness' (convert to radians too) + */ + fsharpness = ((180.0 - sharpness) * M_PI) / 180.0; + + i=0; + /* count edges, use tmp.l */ + eed= em->edges.first; + while(eed) { + edgecount++; + eed->tmp.l = i; + eed= eed->next; + ++i; + } + + /* for each edge, we want a pointer to two adjacent faces */ + efa1 = MEM_callocN(edgecount*sizeof(EditFace *), + "pairs of edit face pointers"); + efa2 = MEM_callocN(edgecount*sizeof(EditFace *), + "pairs of edit face pointers"); + +#define face_table_edge(eed) { \ + i = eed->tmp.l; \ + if (i != -1) { \ + if (efa1[i]) { \ + if (efa2[i]) { \ + /* invalidate, edge has more than two neighbors */ \ + eed->tmp.l = -1; \ + } \ + else { \ + efa2[i] = efa; \ + } \ + } \ + else { \ + efa1[i] = efa; \ + } \ + } \ + } + + /* find the adjacent faces of each edge, we want only two */ + efa= em->faces.first; + while(efa) { + face_table_edge(efa->e1); + face_table_edge(efa->e2); + face_table_edge(efa->e3); + if (efa->e4) { + face_table_edge(efa->e4); + } + + /* while were at it, count the selected faces */ + if (efa->f & SELECT) ++faceselcount; + + efa= efa->next; + } + +#undef face_table_edge + + eed= em->edges.first; + while(eed) { + i = eed->tmp.l; + if (i != -1) { + /* edge has two or less neighboring faces */ + if ( (efa1[i]) && (efa2[i]) ) { + /* edge has exactly two neighboring faces, check angle */ + float angle; + angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] + + efa1[i]->n[1]*efa2[i]->n[1] + + efa1[i]->n[2]*efa2[i]->n[2]); + /* invalidate: edge too sharp */ + if (fabs(angle) >= fsharpness) + eed->tmp.l = -1; + } + else { + /* invalidate: less than two neighbors */ + eed->tmp.l = -1; + } + } + + eed= eed->next; + } + +#define select_flat_neighbor(eed) { \ + i = eed->tmp.l; \ + if (i!=-1) { \ + if (! (efa1[i]->f & SELECT) ) { \ + EM_select_face(efa1[i], 1); \ + ++faceselcount; \ + } \ + if (! (efa2[i]->f & SELECT) ) { \ + EM_select_face(efa2[i], 1); \ + ++faceselcount; \ + } \ + } \ + } + + while (faceselcount != faceselcountold) { + faceselcountold = faceselcount; + + efa= em->faces.first; + while(efa) { + if (efa->f & SELECT) { + select_flat_neighbor(efa->e1); + select_flat_neighbor(efa->e2); + select_flat_neighbor(efa->e3); + if (efa->e4) { + select_flat_neighbor(efa->e4); + } + } + efa= efa->next; + } + } + +#undef select_flat_neighbor + + MEM_freeN(efa1); + MEM_freeN(efa2); + + countall(); + addqueue(curarea->win, REDRAW, 0); + BIF_undo_push("Select Linked Flat Faces"); +} + void select_non_manifold(void) { EditMesh *em = G.editMesh; @@ -2300,7 +2537,7 @@ void vertexsmooth(void) eve= em->verts.first; while(eve) { if(eve->f & SELECT) { - eve->vn= (EditVert *)adr; + eve->tmp.fp = adr; eve->f1= 0; eve->f2= 0; adr+= 3; @@ -2348,11 +2585,11 @@ void vertexsmooth(void) if((eed->v1->f & SELECT) && eed->v1->f1<255) { eed->v1->f1++; - VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec); + VecAddf(eed->v1->tmp.fp, eed->v1->tmp.fp, fvec); } if((eed->v2->f & SELECT) && eed->v2->f1<255) { eed->v2->f1++; - VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec); + VecAddf(eed->v2->tmp.fp, eed->v2->tmp.fp, fvec); } } eed= eed->next; @@ -2362,7 +2599,7 @@ void vertexsmooth(void) while(eve) { if(eve->f & SELECT) { if(eve->f1) { - adr= (float *)eve->vn; + adr = eve->tmp.fp; fac= 0.5/(float)eve->f1; eve->co[0]= 0.5*eve->co[0]+fac*adr[0]; @@ -2382,7 +2619,7 @@ void vertexsmooth(void) } } } - eve->vn= 0; + eve->tmp.fp= 0; } eve= eve->next; } diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index 83875661519..c244f1d249c 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -54,6 +54,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" +#include "DNA_key_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -258,7 +259,7 @@ int removedoublesflag(short flag, float limit) /* return amount */ dist= (float)fabs(v1->co[2]-eve->co[2]); if(dist<=limit) { v1->f|= 128; - v1->vn= eve; + v1->tmp.v = eve; } } } @@ -284,8 +285,8 @@ int removedoublesflag(short flag, float limit) /* return amount */ if( (eed->v1->f & 128) || (eed->v2->f & 128) ) { remedge(eed); - if(eed->v1->f & 128) eed->v1= eed->v1->vn; - if(eed->v2->f & 128) eed->v2= eed->v2->vn; + if(eed->v1->f & 128) eed->v1 = eed->v1->tmp.v; + if(eed->v2->f & 128) eed->v2 = eed->v2->tmp.v; e1= addedgelist(eed->v1, eed->v2, eed); if(e1) e1->f2= 1; @@ -315,10 +316,10 @@ int removedoublesflag(short flag, float limit) /* return amount */ nextvl= efa->next; if(efa->f1==1) { - if(efa->v1->f & 128) efa->v1= efa->v1->vn; - if(efa->v2->f & 128) efa->v2= efa->v2->vn; - if(efa->v3->f & 128) efa->v3= efa->v3->vn; - if(efa->v4 && (efa->v4->f & 128)) efa->v4= efa->v4->vn; + if(efa->v1->f & 128) efa->v1= efa->v1->tmp.v; + if(efa->v2->f & 128) efa->v2= efa->v2->tmp.v; + if(efa->v3->f & 128) efa->v3= efa->v3->tmp.v; + if(efa->v4 && (efa->v4->f & 128)) efa->v4= efa->v4->tmp.v; test= 0; if(efa->v1==efa->v2) test+=1; @@ -1060,8 +1061,8 @@ void fill_mesh(void) while(eve) { if(eve->f & SELECT) { v1= BLI_addfillvert(eve->co); - eve->vn= v1; - v1->vn= eve; + eve->tmp.v= v1; + v1->tmp.v= eve; v1->xs= 0; // used for counting edges } eve= eve->next; @@ -1070,7 +1071,7 @@ void fill_mesh(void) eed= em->edges.first; while(eed) { if( (eed->v1->f & SELECT) && (eed->v2->f & SELECT) ) { - e1= BLI_addfilledge(eed->v1->vn, eed->v2->vn); + e1= BLI_addfilledge(eed->v1->tmp.v, eed->v2->tmp.v); e1->v1->xs++; e1->v2->xs++; } @@ -1084,10 +1085,10 @@ void fill_mesh(void) while(efa) { nextvl= efa->next; if( faceselectedAND(efa, 1) ) { - efa->v1->vn->xs--; - efa->v2->vn->xs--; - efa->v3->vn->xs--; - if(efa->v4) efa->v4->vn->xs--; + efa->v1->tmp.v->xs--; + efa->v2->tmp.v->xs--; + efa->v3->tmp.v->xs--; + if(efa->v4) efa->v4->tmp.v->xs--; ok= 1; } @@ -1107,7 +1108,9 @@ void fill_mesh(void) if(BLI_edgefill(0, (G.obedit && G.obedit->actcol)?(G.obedit->actcol-1):0)) { efa= fillfacebase.first; while(efa) { - efan= addfacelist(efa->v3->vn, efa->v2->vn, efa->v1->vn, 0, NULL, NULL); // normals default pointing up + /* normals default pointing up */ + efan= addfacelist(efa->v3->tmp.v, efa->v2->tmp.v, + efa->v1->tmp.v, 0, NULL, NULL); EM_select_face(efan, 1); efa= efa->next; } @@ -2625,7 +2628,7 @@ static int count_selected_edges(EditEdge *ed) { int totedge = 0; while(ed) { - ed->vn= 0; + ed->tmp.p = 0; if( ed->f & SELECT ) totedge++; ed= ed->next; } @@ -2652,10 +2655,10 @@ static int collect_quadedges(EVPTuple *efaa, EditEdge *eed, EditFace *efa) eed->f2= 0; eed->f1= 0; if( eed->f & SELECT ) { - eed->vn= (EditVert *) (&efaa[i]); + eed->tmp.p = (EditVert *) (&efaa[i]); i++; } - else eed->vn= NULL; + else eed->tmp.p = NULL; eed= eed->next; } @@ -2675,23 +2678,23 @@ static int collect_quadedges(EVPTuple *efaa, EditEdge *eed, EditFace *efa) e1= efa->e1; e2= efa->e2; e3= efa->e3; - if(e1->f2<3 && e1->vn) { + if(e1->f2<3 && e1->tmp.p) { if(e1->f2<2) { - evp= (EVPtr *) e1->vn; - evp[(int)e1->f2]= efa; + evp= (EVPtr *) e1->tmp.p; + evp[(int)e1->f2] = efa; } e1->f2+= 1; } - if(e2->f2<3 && e2->vn) { + if(e2->f2<3 && e2->tmp.p) { if(e2->f2<2) { - evp= (EVPtr *) e2->vn; + evp= (EVPtr *) e2->tmp.p; evp[(int)e2->f2]= efa; } e2->f2+= 1; } - if(e3->f2<3 && e3->vn) { + if(e3->f2<3 && e3->tmp.p) { if(e3->f2<2) { - evp= (EVPtr *) e3->vn; + evp= (EVPtr *) e3->tmp.p; evp[(int)e3->f2]= efa; } e3->f2+= 1; @@ -2903,7 +2906,7 @@ void beauty_fill(void) /* f2 is set in collect_quadedges() */ if(eed->f2==2 && eed->h==0) { - efaa = (EVPtr *) eed->vn; + efaa = (EVPtr *) eed->tmp.p; /* none of the faces should be treated before, nor be part of fgon */ ok= 1; @@ -3075,7 +3078,7 @@ void join_triangles(void) if(eed->f2==2) { /* points to 2 faces */ - efaa= (EVPtr *) eed->vn; + efaa= (EVPtr *) eed->tmp.p; /* don't do it if flagged */ @@ -3172,7 +3175,7 @@ void edge_flip(void) if(eed->f2==2) { /* points to 2 faces */ - efaa= (EVPtr *) eed->vn; + efaa= (EVPtr *) eed->tmp.p; /* don't do it if flagged */ @@ -4040,7 +4043,7 @@ static void bevel_mesh(float bsize, int allfaces) efa->f1-= 1; v1= addvertlist(efa->v1->co); v1->f= efa->v1->f & ~128; - efa->v1->vn= v1; + efa->v1->tmp.v = v1; #ifdef __NLA v1->totweight = efa->v1->totweight; if (efa->v1->totweight) { @@ -4052,7 +4055,7 @@ static void bevel_mesh(float bsize, int allfaces) #endif v1= addvertlist(efa->v2->co); v1->f= efa->v2->f & ~128; - efa->v2->vn= v1; + efa->v2->tmp.v = v1; #ifdef __NLA v1->totweight = efa->v2->totweight; if (efa->v2->totweight) { @@ -4064,7 +4067,7 @@ static void bevel_mesh(float bsize, int allfaces) #endif v1= addvertlist(efa->v3->co); v1->f= efa->v3->f & ~128; - efa->v3->vn= v1; + efa->v3->tmp.v = v1; #ifdef __NLA v1->totweight = efa->v3->totweight; if (efa->v3->totweight) { @@ -4077,7 +4080,7 @@ static void bevel_mesh(float bsize, int allfaces) if (efa->v4) { v1= addvertlist(efa->v4->co); v1->f= efa->v4->f & ~128; - efa->v4->vn= v1; + efa->v4->tmp.v = v1; #ifdef __NLA v1->totweight = efa->v4->totweight; if (efa->v4->totweight) { @@ -4090,21 +4093,29 @@ static void bevel_mesh(float bsize, int allfaces) } /* Needs better adaption of creases? */ - addedgelist(efa->e1->v1->vn, efa->e1->v2->vn, efa->e1); - addedgelist(efa->e2->v1->vn,efa->e2->v2->vn, efa->e2); - addedgelist(efa->e3->v1->vn,efa->e3->v2->vn, efa->e3); - if (efa->e4) addedgelist(efa->e4->v1->vn,efa->e4->v2->vn, efa->e4); + addedgelist(efa->e1->v1->tmp.v, + efa->e1->v2->tmp.v, + efa->e1); + addedgelist(efa->e2->v1->tmp.v, + efa->e2->v2->tmp.v, + efa->e2); + addedgelist(efa->e3->v1->tmp.v, + efa->e3->v2->tmp.v, + efa->e3); + if (efa->e4) addedgelist(efa->e4->v1->tmp.v, + efa->e4->v2->tmp.v, + efa->e4); if(efa->v4) { - v1= efa->v1->vn; - v2= efa->v2->vn; - v3= efa->v3->vn; - v4= efa->v4->vn; + v1 = efa->v1->tmp.v; + v2 = efa->v2->tmp.v; + v3 = efa->v3->tmp.v; + v4 = efa->v4->tmp.v; addfacelist(v1, v2, v3, v4, efa,NULL); } else { - v1= efa->v1->vn; - v2= efa->v2->vn; - v3= efa->v3->vn; + v1= efa->v1->tmp.v; + v2= efa->v2->tmp.v; + v3= efa->v3->tmp.v; addfacelist(v1, v2, v3, 0, efa,NULL); } @@ -4140,8 +4151,9 @@ static void bevel_mesh(float bsize, int allfaces) eed= em->edges.first; while(eed) { eed->f2= eed->f1= 0; - if ( ((eed->v1->f & eed->v2->f) & 1) || allfaces) eed->f1 |= 4; /* original edges */ - eed->vn= 0; + if ( ((eed->v1->f & eed->v2->f) & 1) || allfaces) + eed->f1 |= 4; /* original edges */ + eed->tmp.v = 0; eed= eed->next; } @@ -4219,7 +4231,7 @@ static void bevel_mesh(float bsize, int allfaces) eed->f1= 0; eed->v1->f1 &= ~1; eed->v2->f1 &= ~1; - eed->vn= 0; + eed->tmp.v = 0; eed= eed->next; } @@ -4232,11 +4244,11 @@ static void bevel_mesh(float bsize, int allfaces) eve= em->verts.first; while (eve) { eve->f &= ~(64|128); - eve->vn= NULL; + eve->tmp.v = NULL; eve= eve->next; } - /* eve->f: 128: first vertex in a list (->vn) */ + /* eve->f: 128: first vertex in a list (->tmp.v) */ /* 64: vertex is in a list */ eve= em->verts.first; @@ -4249,11 +4261,11 @@ static void bevel_mesh(float bsize, int allfaces) if ((eve->f & (128|64)) == 0) { /* fprintf(stderr,"Found vertex cluster:\n *\n *\n"); */ eve->f |= 128; - eve->vn= eve2; + eve->tmp.v = eve2; eve3= eve2; } else if ((eve->f & 64) == 0) { /* fprintf(stderr," *\n"); */ - if (eve3) eve3->vn= eve2; + if (eve3) eve3->tmp.v = eve2; eve2->f |= 64; eve3= eve2; } @@ -4261,7 +4273,7 @@ static void bevel_mesh(float bsize, int allfaces) } eve2= eve2->next; if (!eve2) { - if (eve3) eve3->vn= NULL; + if (eve3) eve3->tmp.v = NULL; } } eve= eve->next; @@ -4291,11 +4303,11 @@ static void bevel_mesh(float bsize, int allfaces) eve->f &= ~128; a= 0; neweve[a]= eve; - eve2= eve->vn; + eve2 = eve->tmp.v; while (eve2) { a++; neweve[a]= eve2; - eve2= eve2->vn; + eve2 = eve2->tmp.v; } a++; efa= NULL; @@ -4378,7 +4390,7 @@ static void bevel_mesh(float bsize, int allfaces) while (eve) { eve->f1= 0; eve->f &= ~(128|64); - eve->vn= NULL; + eve->tmp.v= NULL; eve= eve->next; } @@ -5143,10 +5155,10 @@ static float mesh_rip_edgedist(float mat[][4], float *co1, float *co2, short *mv static void mesh_rip_setface(EditFace *sefa) { /* put new vertices & edges in best face */ - if(sefa->v1->vn) sefa->v1= sefa->v1->vn; - if(sefa->v2->vn) sefa->v2= sefa->v2->vn; - if(sefa->v3->vn) sefa->v3= sefa->v3->vn; - if(sefa->v4 && sefa->v4->vn) sefa->v4= sefa->v4->vn; + if(sefa->v1->tmp.v) sefa->v1= sefa->v1->tmp.v; + if(sefa->v2->tmp.v) sefa->v2= sefa->v2->tmp.v; + if(sefa->v3->tmp.v) sefa->v3= sefa->v3->tmp.v; + if(sefa->v4 && sefa->v4->tmp.v) sefa->v4= sefa->v4->tmp.v; sefa->e1= addedgelist(sefa->v1, sefa->v2, sefa->e1); sefa->e2= addedgelist(sefa->v2, sefa->v3, sefa->e2); @@ -5212,11 +5224,11 @@ void mesh_rip(void) /* duplicate vertices, new vertices get selected */ for(eve = em->verts.last; eve; eve= eve->prev) { - eve->vn= NULL; + eve->tmp.v = NULL; if(eve->f & SELECT) { - eve->vn= addvertlist(eve->co); + eve->tmp.v = addvertlist(eve->co); eve->f &= ~SELECT; - eve->vn->f |= SELECT; + eve->tmp.v->f |= SELECT; } } @@ -5230,29 +5242,37 @@ void mesh_rip(void) /* or we do the distance trick */ if(seed==NULL) { mindist= 1000000.0f; - if(sefa->e1->v1->vn || sefa->e1->v2->vn) { - dist= mesh_rip_edgedist(projectMat, sefa->e1->v1->co, sefa->e1->v2->co, mval); + if(sefa->e1->v1->tmp.v || sefa->e1->v2->tmp.v) { + dist = mesh_rip_edgedist(projectMat, + sefa->e1->v1->co, + sefa->e1->v2->co, mval); if(diste1; mindist= dist; } } - if(sefa->e2->v1->vn || sefa->e2->v2->vn) { - dist= mesh_rip_edgedist(projectMat, sefa->e2->v1->co, sefa->e2->v2->co, mval); + if(sefa->e2->v1->tmp.v || sefa->e2->v2->tmp.v) { + dist = mesh_rip_edgedist(projectMat, + sefa->e2->v1->co, + sefa->e2->v2->co, mval); if(diste2; mindist= dist; } } - if(sefa->e3->v1->vn || sefa->e3->v2->vn) { - dist= mesh_rip_edgedist(projectMat, sefa->e3->v1->co, sefa->e3->v2->co, mval); + if(sefa->e3->v1->tmp.v || sefa->e3->v2->tmp.v) { + dist= mesh_rip_edgedist(projectMat, + sefa->e3->v1->co, + sefa->e3->v2->co, mval); if(diste3; mindist= dist; } } - if(sefa->e4 && (sefa->e4->v1->vn || sefa->e4->v2->vn)) { - dist= mesh_rip_edgedist(projectMat, sefa->e4->v1->co, sefa->e4->v2->co, mval); + if(sefa->e4 && (sefa->e4->v1->tmp.v || sefa->e4->v2->tmp.v)) { + dist= mesh_rip_edgedist(projectMat, + sefa->e4->v1->co, + sefa->e4->v2->co, mval); if(diste4; mindist= dist; @@ -5269,16 +5289,17 @@ void mesh_rip(void) /* duplicate edges in the loop, with at least 1 vertex selected, needed for selection flip */ for(eed = em->edges.last; eed; eed= eed->prev) { - eed->vn= NULL; - if((eed->v1->vn) || (eed->v2->vn)) { + eed->tmp.v = NULL; + if((eed->v1->tmp.v) || (eed->v2->tmp.v)) { EditEdge *newed; - newed= addedgelist(eed->v1->vn?eed->v1->vn:eed->v1, eed->v2->vn?eed->v2->vn:eed->v2, eed); + newed= addedgelist(eed->v1->tmp.v?eed->v1->tmp.v:eed->v1, + eed->v2->tmp.v?eed->v2->tmp.v:eed->v2, eed); if(eed->f & SELECT) { eed->f &= ~SELECT; newed->f |= SELECT; } - eed->vn= (EditVert *)newed; + eed->tmp.v = (EditVert *)newed; } } @@ -5296,7 +5317,8 @@ void mesh_rip(void) for(efa= em->faces.first; efa; efa=efa->next) { /* new vert in face */ - if(efa->v1->vn || efa->v2->vn || efa->v3->vn || (efa->v4 && efa->v4->vn)) { + if (efa->v1->tmp.v || efa->v2->tmp.v || + efa->v3->tmp.v || (efa->v4 && efa->v4->tmp.v)) { /* face is tagged with loop */ if(efa->f1==1) { mesh_rip_setface(efa); @@ -5320,7 +5342,8 @@ void mesh_rip(void) for(eed = em->edges.last; eed; eed= seed) { seed= eed->prev; if(eed->f1==0) { - if(eed->v1->vn || eed->v2->vn || (eed->v1->f & SELECT) || (eed->v2->f & SELECT)) { + if(eed->v1->tmp.v || eed->v2->tmp.v || + (eed->v1->f & SELECT) || (eed->v2->f & SELECT)) { remedge(eed); free_editedge(eed); eed= NULL; @@ -5335,7 +5358,7 @@ void mesh_rip(void) /* and remove loose selected vertices, that got duplicated accidentally */ for(eve = em->verts.first; eve; eve= nextve) { nextve= eve->next; - if(eve->f1==0 && (eve->vn || (eve->f & SELECT))) { + if(eve->f1==0 && (eve->tmp.v || (eve->f & SELECT))) { BLI_remlink(&em->verts,eve); free_editvert(eve); } @@ -5348,3 +5371,198 @@ void mesh_rip(void) Transform(); } +void shape_propagate(){ + EditMesh *em = G.editMesh; + EditVert *ev = NULL; + Mesh* me = (Mesh*)G.obedit->data; + Key* ky = NULL; + KeyBlock* kb = NULL; + Base* base=NULL; + + + if(me->key){ + ky = me->key; + } else { + error("Object Has No Key"); + return; + } + + if(ky->block.first){ + for(ev = em->verts.first; ev ; ev = ev->next){ + if(ev->f & SELECT){ + for(kb=ky->block.first;kb;kb = kb->next){ + float *data; + data = kb->data; + VECCOPY(data+(ev->keyindex*3),ev->co); + } + } + } + } else { + error("Object Has No Blendshapes"); + return; + } + + //TAG Mesh Objects that share this data + for(base = G.scene->base.first; base; base = base->next){ + if(base->object && base->object->data == me){ + base->object->recalc = OB_RECALC_DATA; + } + } + + BIF_undo_push("Propagate Blendshape Verts"); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + allqueue(REDRAWVIEW3D, 0); + return; +} + +void shape_copy_from_lerp(KeyBlock* thisBlock, KeyBlock* fromBlock) +{ + EditMesh *em = G.editMesh; + EditVert *ev = NULL; + short mval[2], curval[2], event = 0, finished = 0, canceled = 0, fullcopy=0 ; + float perc = 0; + char str[64]; + float *data, *odata; + + data = fromBlock->data; + odata = thisBlock->data; + + getmouseco_areawin(mval); + curval[0] = mval[0] + 1; curval[1] = mval[1] + 1; + + while (finished == 0) + { + getmouseco_areawin(mval); + if (mval[0] != curval[0] || mval[1] != curval[1]) + { + + if(mval[0] > curval[0]) + perc += 0.1; + else if(mval[0] < curval[0]) + perc -= 0.1; + + if(perc < 0) perc = 0; + if(perc > 1) perc = 1; + + curval[0] = mval[0]; + curval[1] = mval[1]; + + if(fullcopy == 1){ + perc = 1; + } + + for(ev = em->verts.first; ev ; ev = ev->next){ + if(ev->f & SELECT){ + VecLerpf(ev->co,odata+(ev->keyindex*3),data+(ev->keyindex*3),perc); + } + } + sprintf(str,"Blending at %d%c MMB to Copy at 100%c",(int)(perc*100),'%','%'); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); + headerprint(str); + force_draw(0); + + if(fullcopy == 1){ + break; + } + + } else { + PIL_sleep_ms(10); + } + + while(qtest()) { + unsigned short val=0; + event= extern_qread(&val); + if(val){ + if(ELEM3(event, PADENTER, LEFTMOUSE, RETKEY)){ + finished = 1; + } + else if (event == MIDDLEMOUSE){ + fullcopy = 1; + } + else if (ELEM3(event,ESCKEY,RIGHTMOUSE,RIGHTMOUSE)){ + canceled = 1; + finished = 1; + } + } + } + } + if(!canceled) + BIF_undo_push("Copy Blendshape Verts"); + else + for(ev = em->verts.first; ev ; ev = ev->next){ + if(ev->f & SELECT){ + VECCOPY(ev->co, odata+(ev->keyindex*3)); + } + } + return; +} + + + +void shape_copy_select_from() +{ + Mesh* me = (Mesh*)G.obedit->data; + EditMesh *em = G.editMesh; + EditVert *ev = NULL; + int totverts = 0,curshape = G.obedit->shapenr; + + Key* ky = NULL; + KeyBlock *kb = NULL,*thisBlock = NULL; + int maxlen=32, nr=0, a=0; + char *menu; + + if(me->key){ + ky = me->key; + } else { + error("Object Has No Key"); + return; + } + + if(ky->block.first){ + for(kb=ky->block.first;kb;kb = kb->next){ + maxlen += 40; // Size of a block name + if(a == curshape-1){ + thisBlock = kb; + } + + a++; + } + a=0; + menu = MEM_callocN(maxlen, "Copy Shape Menu Text"); + strcpy(menu, "Copy Vert Positions from Shape %t|"); + for(kb=ky->block.first;kb;kb = kb->next){ + if(a != curshape-1){ + sprintf(menu,"%s %s %cx%d|",menu,kb->name,'%',a); + } + a++; + } + nr = pupmenu(menu); + MEM_freeN(menu); + } else { + error("Object Has No Blendshapes"); + return; + } + + a = 0; + + for(kb=ky->block.first;kb;kb = kb->next){ + if(a == nr){ + + for(ev = em->verts.first;ev;ev = ev->next){ + totverts++; + } + + if(me->totvert != totverts){ + error("Shape Has had Verts Added/Removed, please cycle editmode before copying"); + return; + } + shape_copy_from_lerp(thisBlock,kb); + + return; + } + a++; + } + return; +} + + diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c index 74e3bbd1d34..3a2a1d0d21c 100644 --- a/source/blender/src/editnla.c +++ b/source/blender/src/editnla.c @@ -1,15 +1,12 @@ /** -* $Id$ -* - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * $Id$ + * + * ***** BEGIN GPL 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,11 +24,12 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** -* This file is a horrible mess: An attmept to cram some -* final functionality into blender before it is too late. -* -* Hopefully it can be tidied up at a later date... + * ***** END GPL ***** + * + * This file is a horrible mess: An attmept to cram some + * final functionality into blender before it is too late. + * + * Hopefully it can be tidied up at a later date... */ #include @@ -44,19 +42,20 @@ #include "BLI_blenlib.h" +#include "DNA_action_types.h" +#include "DNA_constraint_types.h" +#include "DNA_curve_types.h" +#include "DNA_ipo_types.h" +#include "DNA_object_types.h" +#include "DNA_nla_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_scene_types.h" -#include "DNA_ipo_types.h" -#include "DNA_curve_types.h" -#include "DNA_object_types.h" #include "DNA_userdef_types.h" -#include "DNA_action_types.h" -#include "DNA_nla_types.h" -#include "DNA_constraint_types.h" #include "BKE_action.h" #include "BKE_depsgraph.h" +#include "BKE_group.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_library.h" @@ -97,7 +96,6 @@ static Base *get_nearest_nlachannel_ob_key (float *index, short *sel); static bAction *get_nearest_nlachannel_ac_key (float *index, short *sel); static Base *get_nearest_nlastrip (bActionStrip **rstrip, short *sel); static void mouse_nlachannels(short mval[2]); -static void add_nlablock(short mval[2]); static void convert_nla(short mval[2]); /* ******************** SPACE: NLA ********************** */ @@ -186,7 +184,7 @@ void synchronize_action_strips(void) if (strip->flag & ACTSTRIP_LOCK_ACTION) { float actstart, actend; - calc_action_range(strip->act, &actstart, &actend); + calc_action_range(strip->act, &actstart, &actend, 1); if(strip->actstart!=actstart || strip->actend!=actend) { float mapping= (strip->end - strip->start)/(strip->actend - strip->actstart); @@ -212,7 +210,7 @@ void reset_action_strips(int val) for (strip = base->object->nlastrips.last; strip; strip=strip->prev) { if (strip->flag & ACTSTRIP_SELECT) { if(val==2) { - calc_action_range(strip->act, &strip->actstart, &strip->actend); + calc_action_range(strip->act, &strip->actstart, &strip->actend, 1); } else if(val==1) { float mapping= (strip->actend - strip->actstart)/(strip->end - strip->start); @@ -249,189 +247,6 @@ void snap_action_strips(void) allqueue (REDRAWNLA, 0); } -void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt) -{ - unsigned short event= evt->event; - short val= evt->val; - SpaceNla *snla = curarea->spacedata.first; - int doredraw= 0; - short mval[2]; - float dx,dy; - int cfra; - short mousebut = L_MOUSE; - - if (curarea->win==0) return; - if (!snla) return; - - if(val) { - if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; - - /* swap mouse buttons based on user preference */ - if (U.flag & USER_LMOUSESELECT) { - if (event == LEFTMOUSE) { - event = RIGHTMOUSE; - mousebut = L_MOUSE; - } else if (event == RIGHTMOUSE) { - event = LEFTMOUSE; - mousebut = R_MOUSE; - } - } - - getmouseco_areawin(mval); - - switch(event) { - case UI_BUT_EVENT: - do_nlabuts(val); // in drawnla.c - break; - - case HOMEKEY: - do_nla_buttons(B_NLAHOME); - break; - - case EQUALKEY: - case PAGEUPKEY: - shift_nlastrips_up(); - break; - - case MINUSKEY: - case PAGEDOWNKEY: - shift_nlastrips_down(); - break; - - case AKEY: - if (G.qual & LR_SHIFTKEY){ - add_nlablock(mval); - allqueue (REDRAWNLA, 0); - allqueue (REDRAWVIEW3D, 0); - } - else{ - if (mval[0]>=NLAWIDTH) - deselect_nlachannel_keys(1); - else{ - deselect_nlachannels(1); - allqueue (REDRAWVIEW3D, 0); - } - allqueue (REDRAWNLA, 0); - allqueue (REDRAWIPO, 0); - BIF_undo_push("(De)select all NLA"); - } - break; - - case BKEY: - borderselect_nla(); - break; - - case CKEY: - convert_nla(mval); - break; - - case DKEY: - if (G.qual & LR_SHIFTKEY && mval[0]>=NLAWIDTH){ - duplicate_nlachannel_keys(); - update_for_newframe_muted(); - } - break; - - case GKEY: - if (mval[0]>=NLAWIDTH) - transform_nlachannel_keys ('g', 0); - update_for_newframe_muted(); - break; - - case NKEY: - if(G.qual==0) { - toggle_blockhandler(curarea, NLA_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); - scrarea_queue_winredraw(curarea); - } - break; - - case SKEY: - if(G.qual==LR_ALTKEY) { - val= pupmenu("Action Strip Scale%t|Clear Strip Size%x1|Remap Start/End%x2"); - if(val==1) - reset_action_strips(1); - else if(val==2) - reset_action_strips(2); - } - else if(G.qual & LR_SHIFTKEY) { - if(okee("Snap Strips to Frame")) - snap_action_strips(); - } - else { - if (mval[0]>=NLAWIDTH) - transform_nlachannel_keys ('s', 0); - update_for_newframe_muted(); - } - break; - - case DELKEY: - case XKEY: - if (mval[0]>=NLAWIDTH) - delete_nlachannel_keys (); - - update_for_newframe_muted(); - break; - - /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above, - * based on user preference USER_LMOUSESELECT - */ - case LEFTMOUSE: - if(view2dmove(LEFTMOUSE)) - break; // only checks for sliders - else if (mval[0]>=snla->v2d.mask.xmin) { - do { - getmouseco_areawin(mval); - - areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); - - cfra= (int)dx; - if(cfra< 1) cfra= 1; - - if( cfra!=CFRA ) { - CFRA= cfra; - update_for_newframe(); - force_draw_all(0); - } - else PIL_sleep_ms(30); - - } while(get_mbut() & mousebut); - break; - } - /* else pass on! */ - case RIGHTMOUSE: - if (mval[0]>=snla->v2d.mask.xmin) { - if(G.qual & LR_SHIFTKEY) - mouse_nla(SELECT_INVERT); - else - mouse_nla(SELECT_REPLACE); - } - else - mouse_nlachannels(mval); - break; - - case PADPLUSKEY: - view2d_zoom(G.v2d, 0.1154, sa->winx, sa->winy); - test_view2d(G.v2d, sa->winx, sa->winy); - view2d_do_locks(curarea, V2D_LOCK_COPY); - doredraw= 1; - break; - case PADMINUS: - view2d_zoom(G.v2d, -0.15, sa->winx, sa->winy); - test_view2d(G.v2d, sa->winx, sa->winy); - view2d_do_locks(curarea, V2D_LOCK_COPY); - doredraw= 1; - break; - case MIDDLEMOUSE: - case WHEELUPMOUSE: - case WHEELDOWNMOUSE: - view2dmove(event); /* in drawipo.c */ - break; - } - } - - if(doredraw) scrarea_queue_winredraw(curarea); -} - static void set_active_strip(Object *ob, bActionStrip *act) { bActionStrip *strip; @@ -444,9 +259,13 @@ static void set_active_strip(Object *ob, bActionStrip *act) if(ob->action!=act->act) { if(ob->action) ob->action->id.us--; - ob->action= act->act; - ob->action->id.us++; - + if(act->act->id.lib) { + ob->action= NULL; + } + else { + ob->action= act->act; + id_us_plus(&ob->action->id); + } allqueue(REDRAWIPO, 0); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWACTION, 0); @@ -532,8 +351,8 @@ static void convert_nla(short mval[2]) /* Link the action to the nstrip */ nstrip->act = base->object->action; - nstrip->act->id.us++; - calc_action_range(nstrip->act, &nstrip->actstart, &nstrip->actend); + id_us_plus(&nstrip->act->id); + calc_action_range(nstrip->act, &nstrip->actstart, &nstrip->actend, 1); nstrip->start = nstrip->actstart; nstrip->end = nstrip->actend; nstrip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION; @@ -556,11 +375,9 @@ static void convert_nla(short mval[2]) } } - -static Base *nla_base=NULL; /* global, bad, bad! put it in nla space later, or recode the 2 functions below (ton) */ - static void add_nla_block(short event) { + Object *ob= OBACT; bAction *act=NULL; bActionStrip *strip; int cur; @@ -585,23 +402,24 @@ static void add_nla_block(short event) /* Link the action to the strip */ strip->act = act; - calc_action_range(strip->act, &strip->actstart, &strip->actend); + id_us_plus(&act->id); + calc_action_range(strip->act, &strip->actstart, &strip->actend, 1); strip->start = G.scene->r.cfra; /* could be mval[0] another time... */ strip->end = strip->start + (strip->actend-strip->actstart); /* simple prevention of zero strips */ if(strip->start>strip->end-2) strip->end= strip->start+100; + strip->repeat = 1.0; strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION; - find_stridechannel(nla_base->object, strip); - set_active_strip(nla_base->object, strip); - - strip->repeat = 1.0; - - act->id.us++; - - BLI_addtail(&nla_base->object->nlastrips, strip); + find_stridechannel(ob, strip); + set_active_strip(ob, strip); + strip->object= group_get_member_with_action(ob->dup_group, act); + if(strip->object) + id_lib_extern(&strip->object->id); /* checks lib data, sets correct flag for saving then */ + + BLI_addtail(&ob->nlastrips, strip); BIF_undo_push("Add NLA strip"); } @@ -611,72 +429,32 @@ static void add_nla_databrowse_callback(unsigned short val) /* val is not used, databrowse needs it to optional pass an event */ short event; - if(nla_base==NULL) return; + if(OBACT==NULL) return; event= G.snla->menunr; /* set by databrowse or pupmenu */ add_nla_block(event); } -static void add_nlablock(short mval[2]) +/* Adds strip to to active Object */ +static void add_nlablock(void) { - /* Make sure we are over an object with action */ - Base *base; - rctf rectf; - float ymin, ymax; - float x, y; + Object *ob= OBACT; short event; - short nr; - char *str; - - areamouseco_to_ipoco(G.v2d, mval, &x, &y); + short nr=0; + char *str, title[64]; - mval[0]-=7; - areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); - - mval[0]+=14; - areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); - - ymax = count_nla_levels(); - ymax*= (NLACHANNELHEIGHT + NLACHANNELSKIP); - ymax+= NLACHANNELHEIGHT/2; - - for (base=G.scene->base.first; base; base=base->next){ - /* Handle object ipo selection */ - if (nla_filter(base)) { - - /* Area that encloses object name (or ipo) */ - ymin=ymax-(NLACHANNELHEIGHT+NLACHANNELSKIP); - - /* Area that encloses action */ - if (base->object->action) - ymin-=(NLACHANNELHEIGHT+NLACHANNELSKIP); - - /* Area that encloses nla strips */ - ymin-=(NLACHANNELHEIGHT+NLACHANNELSKIP)* - (BLI_countlist(&base->object->nlastrips)); - - /* Test to see the mouse is in an action area */ - if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) - break; - - ymax=ymin; - } - } - - /* global... for the call above, because the NLA system seems not to have an 'active strip' stored */ - nla_base= base; - - /* Make sure we have an action */ - if (!base){ - error ("Object has not an Action"); + if(ob==NULL) { + error("Need active Object to add NLA strips"); return; } - /* Popup action menu */ - IDnames_to_pupstring(&str, "Add Action", NULL, &G.main->action, (ID *)G.scene, &nr); + sprintf(title, "Add Action strip to: %s", ob->id.name+2); - if(strncmp(str+13, "DataBrow", 8)==0) { + /* Popup action menu */ + IDnames_to_pupstring(&str, title, NULL, &G.main->action, (ID *)G.scene, &nr); + + if(nr==-2) { MEM_freeN(str); activate_databrowse((ID *)NULL, ID_AC, 0, 0, &G.snla->menunr, @@ -685,17 +463,56 @@ static void add_nlablock(short mval[2]) return; } else { - event = pupmenu(str); + event = pupmenu_col(str, 20); MEM_freeN(str); add_nla_block(event); } - - /* Ton: this is a callback for databrowse too - Hos: no, I don't think it is - add_nla_block(0); - */ } +/* Adds strip to to active Object */ +static void relink_active_strip(void) +{ + Object *ob= OBACT; + bActionStrip *strip; + bAction *act; + short event; + short cur; + char *str; + + if(ob==NULL) return; + + for (strip = ob->nlastrips.first; strip; strip=strip->next) + if(strip->flag & ACTSTRIP_ACTIVE) + break; + + if(strip==NULL) return; + + /* Popup action menu */ + IDnames_to_pupstring(&str, "Relink Action strip", NULL, &G.main->action, (ID *)G.scene, NULL); + if(str) { + event = pupmenu_col(str, 20); + MEM_freeN(str); + + for (cur = 1, act=G.main->action.first; act; act=act->id.next, cur++){ + if (cur==event){ + break; + } + } + + if(act) { + if(strip->act) strip->act->id.us--; + strip->act = act; + id_us_plus(&act->id); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + } + } +} + + + /* Left hand side of channels display, selects objects */ static void mouse_nlachannels(short mval[2]) { @@ -1761,3 +1578,305 @@ void deselect_nlachannels(int test) base->object->flag= base->flag; } } + +static Object *get_object_from_active_strip(void) { + + Base *base; + bActionStrip *strip; + + for (base=G.scene->base.first; base; base=base->next) { + for (strip = base->object->nlastrips.first; + strip; strip=strip->next){ + if (strip->flag & ACTSTRIP_SELECT) { + return base->object; + } + } + } + return NULL; +} + + +void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt) +{ + unsigned short event= evt->event; + short val= evt->val; + SpaceNla *snla = curarea->spacedata.first; + int doredraw= 0; + short mval[2]; + float dx,dy; + int cfra; + short mousebut = L_MOUSE; + Object *ob; //in shift-B / bake + + if (curarea->win==0) return; + if (!snla) return; + + if(val) { + if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0; + + /* swap mouse buttons based on user preference */ + if (U.flag & USER_LMOUSESELECT) { + if (event == LEFTMOUSE) { + event = RIGHTMOUSE; + mousebut = L_MOUSE; + } else if (event == RIGHTMOUSE) { + event = LEFTMOUSE; + mousebut = R_MOUSE; + } + } + + getmouseco_areawin(mval); + + switch(event) { + case UI_BUT_EVENT: + do_nlabuts(val); // in drawnla.c + break; + + case HOMEKEY: + do_nla_buttons(B_NLAHOME); + break; + + case EQUALKEY: + case PAGEUPKEY: + shift_nlastrips_up(); + break; + + case MINUSKEY: + case PAGEDOWNKEY: + shift_nlastrips_down(); + break; + + case AKEY: + if (G.qual & LR_SHIFTKEY){ + add_nlablock(); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWVIEW3D, 0); + } + else{ + if (mval[0]>=NLAWIDTH) + deselect_nlachannel_keys(1); + else{ + deselect_nlachannels(1); + allqueue (REDRAWVIEW3D, 0); + } + allqueue (REDRAWNLA, 0); + allqueue (REDRAWIPO, 0); + BIF_undo_push("(De)select all NLA"); + } + break; + + case BKEY: + if (G.qual & LR_SHIFTKEY){ + bake_all_to_action(); + allqueue (REDRAWNLA, 0); + allqueue (REDRAWVIEW3D, 0); + BIF_undo_push("Bake All To Action"); + ob = get_object_from_active_strip(); + //build_match_caches(ob); + } + else + borderselect_nla(); + break; + + case CKEY: + convert_nla(mval); + break; + + case DKEY: + if (G.qual & LR_SHIFTKEY && mval[0]>=NLAWIDTH){ + duplicate_nlachannel_keys(); + update_for_newframe_muted(); + } + break; + + case GKEY: + if (mval[0]>=NLAWIDTH) + transform_nlachannel_keys ('g', 0); + update_for_newframe_muted(); + break; + + case NKEY: + if(G.qual==0) { + toggle_blockhandler(curarea, NLA_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE); + scrarea_queue_winredraw(curarea); + } + break; + case LKEY: + relink_active_strip(); + break; + + case SKEY: + if(G.qual==LR_ALTKEY) { + val= pupmenu("Action Strip Scale%t|Clear Strip Size%x1|Remap Start/End%x2"); + if(val==1) + reset_action_strips(1); + else if(val==2) + reset_action_strips(2); + } + else if(G.qual & LR_SHIFTKEY) { + if(okee("Snap Strips to Frame")) + snap_action_strips(); + } + else { + if (mval[0]>=NLAWIDTH) + transform_nlachannel_keys ('s', 0); + update_for_newframe_muted(); + } + break; + + case DELKEY: + case XKEY: + if (mval[0]>=NLAWIDTH) + delete_nlachannel_keys (); + + update_for_newframe_muted(); + break; + + /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above, + * based on user preference USER_LMOUSESELECT + */ + case LEFTMOUSE: + if(view2dmove(LEFTMOUSE)) + break; // only checks for sliders + else if (mval[0]>=snla->v2d.mask.xmin) { + do { + getmouseco_areawin(mval); + + areamouseco_to_ipoco(G.v2d, mval, &dx, &dy); + + cfra= (int)dx; + if(cfra< 1) cfra= 1; + + if( cfra!=CFRA ) { + CFRA= cfra; + update_for_newframe(); + force_draw_all(0); + } + else PIL_sleep_ms(30); + + } while(get_mbut() & mousebut); + break; + } + /* else pass on! */ + case RIGHTMOUSE: + if (mval[0]>=snla->v2d.mask.xmin) { + if(G.qual & LR_SHIFTKEY) + mouse_nla(SELECT_INVERT); + else + mouse_nla(SELECT_REPLACE); + } + else + mouse_nlachannels(mval); + break; + + case PADPLUSKEY: + view2d_zoom(G.v2d, 0.1154, sa->winx, sa->winy); + test_view2d(G.v2d, sa->winx, sa->winy); + view2d_do_locks(curarea, V2D_LOCK_COPY); + doredraw= 1; + break; + case PADMINUS: + view2d_zoom(G.v2d, -0.15, sa->winx, sa->winy); + test_view2d(G.v2d, sa->winx, sa->winy); + view2d_do_locks(curarea, V2D_LOCK_COPY); + doredraw= 1; + break; + case MIDDLEMOUSE: + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: + view2dmove(event); /* in drawipo.c */ + break; + } + } + + if(doredraw) scrarea_queue_winredraw(curarea); +} + +static void add_nla_block_by_name(char name[32], Object *ob, short hold, short add, float repeat) +{ + bAction *act=NULL; + bActionStrip *strip; + int cur; + + if (name){ + for (cur = 1, act=G.main->action.first; act; act=act->id.next, cur++){ + if (strcmp(name,act->id.name)==0) { + break; + } + } + } + + /* Bail out if no action was chosen */ + if (!act){ + return; + } + + /* Initialize the new action block */ + strip = MEM_callocN(sizeof(bActionStrip), "bActionStrip"); + + deselect_nlachannel_keys(0); + + /* Link the action to the strip */ + strip->act = act; + calc_action_range(strip->act, &strip->actstart, &strip->actend, 1); + strip->start = G.scene->r.cfra; /* could be mval[0] another time... */ + strip->end = strip->start + (strip->actend-strip->actstart); + /* simple prevention of zero strips */ + if(strip->start>strip->end-2) + strip->end= strip->start+100; + + strip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION; //|ACTSTRIP_USEMATCH; + + if (hold==1) + strip->flag = strip->flag|ACTSTRIP_HOLDLASTFRAME; + + if (add==1) + strip->mode = ACTSTRIPMODE_ADD; + + find_stridechannel(ob, strip); + + set_active_strip(ob, strip); + + strip->repeat = repeat; + + act->id.us++; + + BLI_addtail(&ob->nlastrips, strip); + + BIF_undo_push("Add NLA strip"); +} + +void bake_all_to_action(void) +{ + Object *ob; + bAction *newAction; + Ipo *ipo; + ID *id; + short hold, add; + float repeat; + + /* burn object-level motion into a new action */ + ob = get_object_from_active_strip(); + if (ob) { + if (ob->flag&OB_ARMATURE) { + newAction = bake_obIPO_to_action(ob); + if (newAction) { + /* unlink the object's IPO */ + ipo=ob->ipo; + if (ipo) { + id = &ipo->id; + if (id->us > 0) + id->us--; + ob->ipo = NULL; + } + + /* add the new Action to NLA as a strip */ + hold=1; + add=1; + repeat=1.0; + printf("about to add nla block...\n"); + add_nla_block_by_name(newAction->id.name, ob, hold, add, repeat); + } + } + } +} diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c new file mode 100644 index 00000000000..84354859067 --- /dev/null +++ b/source/blender/src/editnode.c @@ -0,0 +1,1758 @@ +/** + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_action_types.h" +#include "DNA_image_types.h" +#include "DNA_ipo_types.h" +#include "DNA_object_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_space_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_userdef_types.h" + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_material.h" +#include "BKE_utildefines.h" + +#include "BIF_editview.h" +#include "BIF_gl.h" +#include "BIF_graphics.h" +#include "BIF_interface.h" +#include "BIF_mywindow.h" +#include "BIF_previewrender.h" +#include "BIF_resources.h" +#include "BIF_renderwin.h" +#include "BIF_space.h" +#include "BIF_screen.h" +#include "BIF_toolbox.h" + +#include "BSE_drawipo.h" +#include "BSE_edit.h" +#include "BSE_filesel.h" +#include "BSE_headerbuttons.h" +#include "BSE_node.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "BDR_editobject.h" + +#include "blendef.h" +#include "butspace.h" +#include "PIL_time.h" +#include "mydevice.h" + + +/* currently called from BIF_preview_changed */ +void snode_tag_dirty(SpaceNode *snode) +{ + bNode *node; + + if(snode->treetype==NTREE_SHADER) { + if(snode->nodetree) { + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(node->type==SH_NODE_OUTPUT) + node->lasty= 0; + } + snode->flag |= SNODE_DO_PREVIEW; /* this adds an afterqueue on a redraw, to allow button previews to work first */ + } + } + allqueue(REDRAWNODE, 1); +} + +static void shader_node_previewrender(ScrArea *sa, SpaceNode *snode) +{ + bNode *node; + + if(snode->id==NULL) return; + if( ((Material *)snode->id )->use_nodes==0 ) return; + + for(node= snode->nodetree->nodes.first; node; node= node->next) { + if(node->type==SH_NODE_OUTPUT) { + if(node->flag & NODE_DO_OUTPUT) { + if(node->lastylasty; + + ri.cury = node->lasty; + ri.rect = NULL; + ri.pr_rectx = PREVIEW_RENDERSIZE; + ri.pr_recty = PREVIEW_RENDERSIZE; + + BIF_previewrender(snode->id, &ri, NULL, PR_DO_RENDER); /* sends redraw event */ + if(ri.rect) MEM_freeN(ri.rect); + + if(ri.curywin, RENDERPREVIEW, 1); +// if(test!=node->lasty) +// printf("node rendered to %d\n", node->lasty); + + break; + } + } + } + } +} + + +static void snode_handle_recalc(SpaceNode *snode) +{ + if(snode->treetype==NTREE_SHADER) { + BIF_preview_changed(ID_MA); /* signals buttons windows and node editors */ + } + else if(snode->treetype==NTREE_COMPOSIT) { + if(G.scene->use_nodes) { + snode->nodetree->timecursor= set_timecursor; + + ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */ + + waitcursor(0); + allqueue(REDRAWNODE, 1); + allqueue(REDRAWIMAGE, 1); + if(G.scene->r.scemode & R_DOCOMP) { + BIF_redraw_render_rect(); /* seems to screwup display? */ + mywinset(curarea->win); + } + + snode->nodetree->timecursor= NULL; + } + } +} + +static void shader_node_event(SpaceNode *snode, short event) +{ + switch(event) { + case B_REDR: + allqueue(REDRAWNODE, 1); + break; + default: + /* B_NODE_EXEC */ + snode_handle_recalc(snode); + break; + + } +} + +static void load_node_image(char *str) /* called from fileselect */ +{ + SpaceNode *snode= curarea->spacedata.first; + bNode *node= nodeGetActive(snode->edittree); + Image *ima= NULL; + + ima= add_image(str); + if(ima) { + if(node->id) + node->id->us--; + + node->id= &ima->id; + ima->id.us++; + + free_image_buffers(ima); /* force read again */ + ima->ok= 1; + + addqueue(curarea->win, RENDERPREVIEW, 1); + allqueue(REDRAWNODE, 0); + } +} + +static void composit_node_event(SpaceNode *snode, short event) +{ + + switch(event) { + case B_REDR: + allqueue(REDRAWNODE, 1); + break; + case B_NODE_LOADIMAGE: + { + bNode *node= nodeGetActive(snode->edittree); + char name[FILE_MAXDIR+FILE_MAXFILE]; + + if(node->id) + strcpy(name, ((Image *)node->id)->name); + else strcpy(name, U.textudir); + + activate_fileselect(FILE_SPECIAL, "SELECT IMAGE", name, load_node_image); + } + case B_NODE_TREE_EXEC: + snode_handle_recalc(snode); + break; + default: + /* B_NODE_EXEC */ + { + bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC); + if(node) NodeTagChanged(snode->edittree, node); + snode_handle_recalc(snode); + } + } +} + + +/* assumes nothing being done in ntree yet, sets the default in/out node */ +/* called from shading buttons or header */ +void node_shader_default(Material *ma) +{ + bNode *in, *out; + bNodeSocket *fromsock, *tosock; + + /* but lets check it anyway */ + if(ma->nodetree) { + printf("error in shader initialize\n"); + return; + } + + ma->nodetree= ntreeAddTree(NTREE_SHADER); + + out= nodeAddNodeType(ma->nodetree, SH_NODE_OUTPUT, NULL); + out->locx= 300.0f; out->locy= 300.0f; + + in= nodeAddNodeType(ma->nodetree, SH_NODE_MATERIAL, NULL); + in->locx= 10.0f; in->locy= 300.0f; + nodeSetActive(ma->nodetree, in); + + /* only a link from color to color */ + fromsock= in->outputs.first; + tosock= out->inputs.first; + nodeAddLink(ma->nodetree, in, fromsock, out, tosock); + + ntreeSolveOrder(ma->nodetree); /* needed for pointers */ +} + +/* assumes nothing being done in ntree yet, sets the default in/out node */ +/* called from shading buttons or header */ +void node_composit_default(Scene *sce) +{ + bNode *in, *out; + bNodeSocket *fromsock, *tosock; + + /* but lets check it anyway */ + if(sce->nodetree) { + printf("error in composit initialize\n"); + return; + } + + sce->nodetree= ntreeAddTree(NTREE_COMPOSIT); + + out= nodeAddNodeType(sce->nodetree, CMP_NODE_VIEWER, NULL); + out->locx= 300.0f; out->locy= 300.0f; + + in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_RESULT, NULL); + in->locx= 10.0f; in->locy= 300.0f; + nodeSetActive(sce->nodetree, in); + + /* only a link from color to color */ + fromsock= in->outputs.first; + tosock= out->inputs.first; + nodeAddLink(sce->nodetree, in, fromsock, out, tosock); + + ntreeSolveOrder(sce->nodetree); /* needed for pointers */ + + out->id= find_id("IM", "Compositor"); + if(out->id==NULL) { + Image *ima= alloc_libblock(&G.main->image, ID_IM, "Compositor"); + strcpy(ima->name, "Compositor"); + ima->ok= 1; + ima->xrep= ima->yrep= 1; + out->id= &ima->id; + } +} + +/* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */ +void snode_set_context(SpaceNode *snode) +{ + Object *ob= OBACT; + bNode *node= NULL; + + snode->nodetree= NULL; + snode->id= snode->from= NULL; + + if(snode->treetype==NTREE_SHADER) { + /* need active object, or we allow pinning... */ + if(ob) { + Material *ma= give_current_material(ob, ob->actcol); + if(ma) { + snode->from= material_from(ob, ob->actcol); + snode->id= &ma->id; + snode->nodetree= ma->nodetree; + } + } + } + else if(snode->treetype==NTREE_COMPOSIT) { + snode->from= NULL; + snode->id= &G.scene->id; + snode->nodetree= G.scene->nodetree; + } + + /* 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; +} + +static void node_set_active(SpaceNode *snode, bNode *node) +{ + + nodeSetActive(snode->edittree, node); + + if(node->type!=NODE_GROUP) { + + /* tree specific activate calls */ + if(snode->treetype==NTREE_SHADER) { + + /* when we select a material, active texture is cleared, for buttons */ + if(node->id && GS(node->id->name)==ID_MA) + nodeClearActiveID(snode->edittree, ID_TE); + if(node->id) + BIF_preview_changed(-1); /* temp hack to force texture preview to update */ + + allqueue(REDRAWBUTSSHADING, 1); + } + else if(snode->treetype==NTREE_COMPOSIT) { + /* make active viewer, currently only 1 supported... */ + if(node->type==CMP_NODE_VIEWER) { + bNode *tnode; + int was_output= node->flag & NODE_DO_OUTPUT; + + for(tnode= snode->edittree->nodes.first; tnode; tnode= tnode->next) + if(tnode->type==CMP_NODE_VIEWER) + tnode->flag &= ~NODE_DO_OUTPUT; + + node->flag |= NODE_DO_OUTPUT; + if(was_output==0) { + NodeTagChanged(snode->edittree, node); + snode_handle_recalc(snode); + } + + /* add node doesnt link this yet... */ + if(node->id==NULL) { + node->id= find_id("IM", "Compositor"); + if(node->id==NULL) { + Image *ima= alloc_libblock(&G.main->image, ID_IM, "Compositor"); + strcpy(ima->name, "Compositor"); + ima->ok= 1; + ima->xrep= ima->yrep= 1; + node->id= &ima->id; + } + else + node->id->us++; + } + } + } + } +} + +static bNode *snode_get_editgroup(SpaceNode *snode) +{ + bNode *gnode; + + /* get the groupnode */ + for(gnode= snode->nodetree->nodes.first; gnode; gnode= gnode->next) + if(gnode->flag & NODE_GROUP_EDIT) + break; + return gnode; +} + +static void snode_make_group_editable(SpaceNode *snode, bNode *gnode) +{ + bNode *node; + + /* make sure nothing has group editing on */ + for(node= snode->nodetree->nodes.first; node; node= node->next) + node->flag &= ~NODE_GROUP_EDIT; + + if(gnode==NULL) { + /* with NULL argument we do a toggle */ + if(snode->edittree==snode->nodetree) + gnode= nodeGetActive(snode->nodetree); + } + + if(gnode && gnode->type==NODE_GROUP && gnode->id) { + gnode->flag |= NODE_GROUP_EDIT; + snode->edittree= (bNodeTree *)gnode->id; + + /* deselect all other nodes, so we can also do grabbing of entire subtree */ + for(node= snode->nodetree->nodes.first; node; node= node->next) + node->flag &= ~SELECT; + gnode->flag |= SELECT; + + } + else + snode->edittree= snode->nodetree; + + /* finally send out events for new active node */ + if(snode->treetype==NTREE_SHADER) { + allqueue(REDRAWBUTSSHADING, 0); + + BIF_preview_changed(-1); /* temp hack to force texture preview to update */ + } + + allqueue(REDRAWNODE, 0); +} + +static void node_ungroup(SpaceNode *snode) +{ + bNode *gnode; + + gnode= nodeGetActive(snode->edittree); + if(gnode->type!=NODE_GROUP) + error("Not a group"); + else { + if(nodeGroupUnGroup(snode->edittree, gnode)) { + + ntreeSolveOrder(snode->edittree); + BIF_undo_push("Deselect all nodes"); + allqueue(REDRAWNODE, 0); + } + else + error("Can't ungroup"); + } +} + +/* when links in groups change, inputs/outputs change, nodes added/deleted... */ +static void snode_verify_groups(SpaceNode *snode) +{ + bNode *gnode; + + gnode= snode_get_editgroup(snode); + + /* does all materials */ + if(gnode) + nodeVerifyGroup((bNodeTree *)gnode->id); + +} + +/* ************************** Node generic ************** */ + +/* allows to walk the list in order of visibility */ +static bNode *next_node(bNodeTree *ntree) +{ + static bNode *current=NULL, *last= NULL; + + if(ntree) { + /* set current to the first selected node */ + for(current= ntree->nodes.last; current; current= current->prev) + if(current->flag & NODE_SELECT) + break; + + /* set last to the first unselected node */ + for(last= ntree->nodes.last; last; last= last->prev) + if((last->flag & NODE_SELECT)==0) + break; + + if(current==NULL) + current= last; + + return NULL; + } + /* no nodes, or we are ready */ + if(current==NULL) + return NULL; + + /* now we walk the list backwards, but we always return current */ + if(current->flag & NODE_SELECT) { + bNode *node= current; + + /* find previous selected */ + current= current->prev; + while(current && (current->flag & NODE_SELECT)==0) + current= current->prev; + + /* find first unselected */ + if(current==NULL) + current= last; + + return node; + } + else { + bNode *node= current; + + /* find previous unselected */ + current= current->prev; + while(current && (current->flag & NODE_SELECT)) + current= current->prev; + + return node; + } + + return NULL; +} + +/* is rct in visible part of node? */ +static bNode *visible_node(SpaceNode *snode, rctf *rct) +{ + bNode *tnode; + + for(next_node(snode->edittree); (tnode=next_node(NULL));) { + if(BLI_isect_rctf(&tnode->totr, rct, NULL)) + break; + } + return tnode; +} + +static void snode_home(ScrArea *sa, SpaceNode *snode) +{ + bNode *node; + int first= 1; + + snode->v2d.cur.xmin= snode->v2d.cur.ymin= 0.0f; + snode->v2d.cur.xmax= sa->winx; + snode->v2d.cur.xmax= sa->winy; + + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(first) { + first= 0; + snode->v2d.cur= node->totr; + } + else { + BLI_union_rctf(&snode->v2d.cur, &node->totr); + } + } + snode->v2d.tot= snode->v2d.cur; + test_view2d(G.v2d, sa->winx, sa->winy); + +} + +/* checks mouse position, and returns found node/socket */ +/* type is SOCK_IN and/or SOCK_OUT */ +static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **sockp, int in_out) +{ + bNode *node; + bNodeSocket *sock; + rctf rect; + short mval[2]; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin); + + rect.xmin -= NODE_SOCKSIZE+3; + rect.ymin -= NODE_SOCKSIZE+3; + rect.xmax = rect.xmin + 2*NODE_SOCKSIZE+6; + rect.ymax = rect.ymin + 2*NODE_SOCKSIZE+6; + + /* check if we click in a socket */ + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(in_out & SOCK_IN) { + for(sock= node->inputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { + if(node == visible_node(snode, &rect)) { + *nodep= node; + *sockp= sock; + return 1; + } + } + } + } + } + if(in_out & SOCK_OUT) { + for(sock= node->outputs.first; sock; sock= sock->next) { + if(!(sock->flag & SOCK_HIDDEN)) { + if(BLI_in_rctf(&rect, sock->locx, sock->locy)) { + if(node == visible_node(snode, &rect)) { + *nodep= node; + *sockp= sock; + return 1; + } + } + } + } + } + } + return 0; +} + +/* ********************* transform ****************** */ + +/* releases on event, only intern (for extern see below) */ +/* we need argument ntree to allow operations on edittree or nodetree */ +static void transform_nodes(bNodeTree *ntree, char mode, char *undostr) +{ + bNode *node; + float mxstart, mystart, mx, my, *oldlocs, *ol; + int cont=1, tot=0, cancel=0, firsttime=1; + short mval[2], mvalo[2]; + + /* count total */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & SELECT) tot++; + + if(tot==0) return; + + /* store oldlocs */ + ol= oldlocs= MEM_mallocN(sizeof(float)*2*tot, "oldlocs transform"); + for(node= ntree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + ol[0]= node->locx; ol[1]= node->locy; + ol+= 2; + } + } + + getmouseco_areawin(mvalo); + areamouseco_to_ipoco(G.v2d, mvalo, &mxstart, &mystart); + + while(cont) { + + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) { +// char str[64]; + + firsttime= 0; + + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + for(ol= oldlocs, node= ntree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + node->locx= ol[0] + mx-mxstart; + node->locy= ol[1] + my-mystart; + ol+= 2; + } + } + +// sprintf(str, "X: %.1f Y: %.1f", mx-mxstart, my-mystart); +// headerprint(str); + force_draw(0); + } + else + PIL_sleep_ms(10); + + while (qtest()) { + short val; + unsigned short event= extern_qread(&val); + + switch (event) { + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + cont=0; + break; + case ESCKEY: + case RIGHTMOUSE: + if(val) { + cancel=1; + cont=0; + } + break; + default: + if(val) arrows_move_cursor(event); + break; + } + } + + } + + if(cancel) { + for(ol= oldlocs, node= ntree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + node->locx= ol[0]; + node->locy= ol[1]; + ol+= 2; + } + } + + } + else + BIF_undo_push(undostr); + + allqueue(REDRAWNODE, 1); + MEM_freeN(oldlocs); +} + +/* external call, also for callback */ +void node_transform_ext(int mode, int unused) +{ + SpaceNode *snode= curarea->spacedata.first; + + transform_nodes(snode->edittree, 'g', "Translate node"); +} + + +/* releases on event, only 1 node */ +static void scale_node(SpaceNode *snode, bNode *node) +{ + float mxstart, mystart, mx, my, oldwidth; + int cont=1, cancel=0; + short mval[2], mvalo[2]; + + /* store old */ + if(node->flag & NODE_HIDDEN) + oldwidth= node->miniwidth; + else + oldwidth= node->width; + + getmouseco_areawin(mvalo); + areamouseco_to_ipoco(G.v2d, mvalo, &mxstart, &mystart); + + while(cont) { + + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + if(node->flag & NODE_HIDDEN) { + node->miniwidth= oldwidth + mx-mxstart; + CLAMP(node->miniwidth, 0.0f, 100.0f); + } + else { + node->width= oldwidth + mx-mxstart; + CLAMP(node->width, node->typeinfo->minwidth, node->typeinfo->maxwidth); + } + + force_draw(0); + } + else + PIL_sleep_ms(10); + + while (qtest()) { + short val; + unsigned short event= extern_qread(&val); + + switch (event) { + case LEFTMOUSE: + case SPACEKEY: + case RETKEY: + cont=0; + break; + case ESCKEY: + case RIGHTMOUSE: + if(val) { + cancel=1; + cont=0; + } + break; + } + } + + } + + if(cancel) { + node->width= oldwidth; + } + else + BIF_undo_push("Scale Node"); + + allqueue(REDRAWNODE, 1); +} + + + +/* ********************** select ******************** */ + +/* used in buttons to check context, also checks for edited groups */ +bNode *editnode_get_active_idnode(bNodeTree *ntree, short id_code) +{ + bNode *node; + + /* check for edited group */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_GROUP_EDIT) + break; + if(node) + return nodeGetActiveID((bNodeTree *)node->id, id_code); + else + return nodeGetActiveID(ntree, id_code); +} + +/* used in buttons to check context, also checks for edited groups */ +Material *editnode_get_active_material(Material *ma) +{ + if(ma && ma->use_nodes && ma->nodetree) { + bNode *node= editnode_get_active_idnode(ma->nodetree, ID_MA); + if(node) + return (Material *)node->id; + else + return NULL; + } + return ma; +} + +/* used in buttons to check context, also checks for edited groups */ +bNode *editnode_get_active(bNodeTree *ntree) +{ + bNode *node; + + /* check for edited group */ + for(node= ntree->nodes.first; node; node= node->next) + if(node->flag & NODE_GROUP_EDIT) + break; + if(node) + return nodeGetActive((bNodeTree *)node->id); + else + return nodeGetActive(ntree); +} + + +/* no undo here! */ +void node_deselectall(SpaceNode *snode, int swap) +{ + 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; + allqueue(REDRAWNODE, 0); + return; + } + /* else pass on to deselect */ + } + + for(node= snode->edittree->nodes.first; node; node= node->next) + node->flag &= ~SELECT; + + allqueue(REDRAWNODE, 0); +} + +int node_has_hidden_sockets(bNode *node) +{ + bNodeSocket *sock; + + for(sock= node->inputs.first; sock; sock= sock->next) + if(sock->flag & SOCK_HIDDEN) + return 1; + for(sock= node->outputs.first; sock; sock= sock->next) + if(sock->flag & SOCK_HIDDEN) + return 1; + return 0; +} + + +static void node_hide_unhide_sockets(SpaceNode *snode, bNode *node) +{ + bNodeSocket *sock; + + /* unhide all */ + if( node_has_hidden_sockets(node) ) { + for(sock= node->inputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_HIDDEN; + for(sock= node->outputs.first; sock; sock= sock->next) + sock->flag &= ~SOCK_HIDDEN; + } + else { + bNode *gnode= snode_get_editgroup(snode); + + /* hiding inside group should not break links in other group users */ + if(gnode) { + nodeGroupSocketUseFlags((bNodeTree *)gnode->id); + for(sock= node->inputs.first; sock; sock= sock->next) + if(!(sock->flag & SOCK_IN_USE)) + if(sock->link==NULL) + sock->flag |= SOCK_HIDDEN; + for(sock= node->outputs.first; sock; sock= sock->next) + if(!(sock->flag & SOCK_IN_USE)) + if(nodeCountSocketLinks(snode->edittree, sock)==0) + sock->flag |= SOCK_HIDDEN; + } + else { + /* hide unused sockets */ + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->link==NULL) + sock->flag |= SOCK_HIDDEN; + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(nodeCountSocketLinks(snode->edittree, sock)==0) + sock->flag |= SOCK_HIDDEN; + } + } + } + + allqueue(REDRAWNODE, 1); + snode_verify_groups(snode); + BIF_undo_push("Hide/Unhide sockets"); + +} + +static int do_header_node(SpaceNode *snode, bNode *node, float mx, float my) +{ + rctf totr= node->totr; + + totr.ymin= totr.ymax-20.0f; + + totr.xmax= totr.xmin+15.0f; + if(BLI_in_rctf(&totr, mx, my)) { + node->flag |= NODE_HIDDEN; + allqueue(REDRAWNODE, 0); + return 1; + } + + totr.xmax= node->totr.xmax; + totr.xmin= totr.xmax-18.0f; + if(node->typeinfo->flag & NODE_PREVIEW) { + if(BLI_in_rctf(&totr, mx, my)) { + node->flag ^= NODE_PREVIEW; + allqueue(REDRAWNODE, 0); + return 1; + } + totr.xmin-=18.0f; + } + if(node->type == NODE_GROUP) { + if(BLI_in_rctf(&totr, mx, my)) { + snode_make_group_editable(snode, node); + return 1; + } + totr.xmin-=18.0f; + } + if(node->typeinfo->flag & NODE_OPTIONS) { + if(BLI_in_rctf(&totr, mx, my)) { + node->flag ^= NODE_OPTIONS; + allqueue(REDRAWNODE, 0); + return 1; + } + totr.xmin-=18.0f; + } + if(node->outputs.first) { + if(BLI_in_rctf(&totr, mx, my)) { + node_hide_unhide_sockets(snode, node); + } + } + + + totr= node->totr; + totr.xmin= totr.xmax-10.0f; + totr.ymax= totr.ymin+10.0f; + if(BLI_in_rctf(&totr, mx, my)) { + scale_node(snode, node); + return 1; + } + return 0; +} + +static int do_header_hidden_node(SpaceNode *snode, bNode *node, float mx, float my) +{ + rctf totr= node->totr; + + totr.xmax= totr.xmin+15.0f; + if(BLI_in_rctf(&totr, mx, my)) { + node->flag &= ~NODE_HIDDEN; + allqueue(REDRAWNODE, 0); + return 1; + } + + totr.xmax= node->totr.xmax; + totr.xmin= node->totr.xmax-15.0f; + if(BLI_in_rctf(&totr, mx, my)) { + scale_node(snode, node); + return 1; + } + return 0; +} + + +/* return 0: nothing done */ +static int node_mouse_select(SpaceNode *snode, unsigned short event) +{ + bNode *node; + float mx, my; + short mval[2]; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + + for(next_node(snode->edittree); (node=next_node(NULL));) { + + /* first check for the headers or scaling widget */ + if(node->flag & NODE_HIDDEN) { + if(do_header_hidden_node(snode, node, mx, my)) + return 1; + } + else { + if(do_header_node(snode, node, mx, my)) + return 1; + } + + /* node body */ + if(BLI_in_rctf(&node->totr, mx, my)) + break; + } + if(node) { + if((G.qual & LR_SHIFTKEY)==0) + node_deselectall(snode, 0); + + if(G.qual & LR_SHIFTKEY) { + if(node->flag & SELECT) + node->flag &= ~SELECT; + else + node->flag |= SELECT; + } + else + node->flag |= SELECT; + + node_set_active(snode, node); + + /* not so nice (no event), but function below delays redraw otherwise */ + force_draw(0); + + std_rmouse_transform(node_transform_ext); /* does undo push for select */ + + return 1; + } + return 0; +} + +/* return 0, nothing done */ +static int node_mouse_groupheader(SpaceNode *snode) +{ + bNode *gnode; + float mx, my; + short mval[2]; + + gnode= snode_get_editgroup(snode); + if(gnode==NULL) return 0; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + + /* click in header or outside? */ + if(BLI_in_rctf(&gnode->totr, mx, my)==0) { + rctf rect= gnode->totr; + + rect.ymax += NODE_DY; + if(BLI_in_rctf(&rect, mx, my)==0) + snode_make_group_editable(snode, NULL); /* toggles, so exits editmode */ + else + transform_nodes(snode->nodetree, 'g', "Move group"); + + return 1; + } + return 0; +} + +static int node_socket_hilights(SpaceNode *snode, int in_out) +{ + bNode *node; + bNodeSocket *sock, *tsock, *socksel= NULL; + float mx, my; + short mval[2], redraw= 0; + + if(snode->edittree==NULL) return 0; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &mx, &my); + + /* deselect socks */ + for(node= snode->edittree->nodes.first; node; node= node->next) { + for(sock= node->inputs.first; sock; sock= sock->next) { + if(sock->flag & SELECT) { + sock->flag &= ~SELECT; + redraw++; + socksel= sock; + } + } + for(sock= node->outputs.first; sock; sock= sock->next) { + if(sock->flag & SELECT) { + sock->flag &= ~SELECT; + redraw++; + socksel= sock; + } + } + } + + if(find_indicated_socket(snode, &node, &tsock, in_out)) { + tsock->flag |= SELECT; + if(redraw==1 && tsock==socksel) redraw= 0; + else redraw= 1; + } + + return redraw; +} + +void node_border_select(SpaceNode *snode) +{ + bNode *node; + rcti rect; + rctf rectf; + short val, mval[2]; + + if ( (val = get_border(&rect, 3)) ) { + + mval[0]= rect.xmin; + mval[1]= rect.ymin; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax); + + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(BLI_isect_rctf(&rectf, &node->totr, NULL)) { + if(val==LEFTMOUSE) + node->flag |= SELECT; + else + node->flag &= ~SELECT; + } + } + allqueue(REDRAWNODE, 1); + BIF_undo_push("Border select nodes"); + } +} + +/* ****************** Add *********************** */ + +/* can be called from menus too, but they should do own undopush and redraws */ +bNode *node_add_node(SpaceNode *snode, int type, float locx, float locy) +{ + bNode *node= NULL, *gnode; + + node_deselectall(snode, 0); + + node= nodeAddNodeType(snode->edittree, type, NULL); + + /* generics */ + if(node) { + node->locx= locx; + node->locy= locy + 60.0f; // arbitrary.. so its visible + node->flag |= SELECT; + + gnode= snode_get_editgroup(snode); + if(gnode) { + node->locx -= gnode->locx; + node->locy -= gnode->locy; + } + + node_set_active(snode, node); + snode_verify_groups(snode); + } + return node; +} + +/* hotkey context */ +static void node_add_menu(SpaceNode *snode) +{ + float locx, locy; + short event, mval[2]; + + if(snode->treetype==NTREE_SHADER) { + /* shader menu, still hardcoded defines... solve */ + event= pupmenu("Add Node%t|Output%x1|Geometry%x108|Material%x100|Texture%x106|Mapping%x109|Normal%x107|RGB Curves%x111|Vector Curves%x110|Value %x102|Color %x101|Mix Color %x103|ColorRamp %x104|Color to BW %x105"); + if(event<1) return; + } + else if(snode->treetype==NTREE_COMPOSIT) { + /* compo menu, still hardcoded defines... solve */ + event= pupmenu("Add Node%t|Render Result %x221|Composite %x222|Viewer%x201|Image %x220|RGB Curves%x209|AlphaOver %x210|Blur %x211|Filter %x212|Value %x203|Color %x202|Mix %x204|ColorRamp %x205|Color to BW %x206|Map Value %x213|Normal %x207"); + if(event<1) return; + } + else return; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &locx, &locy); + node_add_node(snode, event, locx, locy); + + snode_handle_recalc(snode); + + BIF_undo_push("Add Node"); +} + +void node_adduplicate(SpaceNode *snode) +{ + + ntreeCopyTree(snode->edittree, 1); /* 1 == internally selected nodes */ + + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(snode); + + transform_nodes(snode->edittree, 'g', "Duplicate"); +} + +static void node_insert_convertor(SpaceNode *snode, bNodeLink *link) +{ + bNode *newnode= NULL; + + if(link->fromsock->type==SOCK_RGBA && link->tosock->type==SOCK_VALUE) { + if(snode->edittree->type==NTREE_SHADER) + newnode= node_add_node(snode, SH_NODE_RGBTOBW, 0.0f, 0.0f); + else if(snode->edittree->type==NTREE_COMPOSIT) + newnode= node_add_node(snode, CMP_NODE_RGBTOBW, 0.0f, 0.0f); + else + newnode= NULL; + } + else if(link->fromsock->type==SOCK_VALUE && link->tosock->type==SOCK_RGBA) { + if(snode->edittree->type==NTREE_SHADER) + newnode= node_add_node(snode, SH_NODE_VALTORGB, 0.0f, 0.0f); + else if(snode->edittree->type==NTREE_COMPOSIT) + newnode= node_add_node(snode, CMP_NODE_VALTORGB, 0.0f, 0.0f); + else + newnode= NULL; + } + + if(newnode) { + /* dangerous assumption to use first in/out socks, but thats fine for now */ + newnode->flag |= NODE_HIDDEN; + newnode->locx= 0.5f*(link->fromsock->locx + link->tosock->locx); + newnode->locy= 0.5f*(link->fromsock->locy + link->tosock->locy) + HIDDEN_RAD; + + nodeAddLink(snode->edittree, newnode, newnode->outputs.first, link->tonode, link->tosock); + link->tonode= newnode; + link->tosock= newnode->inputs.first; + } +} + + +/* loop that adds a nodelink, called by function below */ +/* in_out = starting socket */ +static int node_add_link_drag(SpaceNode *snode, bNode *node, bNodeSocket *sock, int in_out) +{ + bNode *tnode; + bNodeSocket *tsock; + bNodeLink *link= NULL; + short mval[2], mvalo[2], firsttime=1; /* firsttime reconnects a link broken by caller */ + + /* we make a temporal link */ + if(in_out==SOCK_OUT) + link= nodeAddLink(snode->edittree, node, sock, NULL, NULL); + else + link= nodeAddLink(snode->edittree, NULL, NULL, node, sock); + + getmouseco_areawin(mvalo); + while (get_mbut() & L_MOUSE) { + + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) { + firsttime= 0; + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + + if(in_out==SOCK_OUT) { + if(find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { + if(nodeFindLink(snode->edittree, sock, tsock)==NULL) { + if(tnode!=node && link->tonode!=tnode && link->tosock!= tsock) { + link->tonode= tnode; + link->tosock= tsock; + ntreeSolveOrder(snode->edittree); /* for interactive red line warning */ + } + } + } + else { + link->tonode= NULL; + link->tosock= NULL; + } + } + else { + if(find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) { + if(nodeFindLink(snode->edittree, sock, tsock)==NULL) { + if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) { + if(tnode!=node && link->fromnode!=tnode && link->fromsock!= tsock) { + link->fromnode= tnode; + link->fromsock= tsock; + ntreeSolveOrder(snode->edittree); /* for interactive red line warning */ + } + } + } + } + else { + link->fromnode= NULL; + link->fromsock= NULL; + } + } + /* hilight target sockets only */ + node_socket_hilights(snode, in_out==SOCK_OUT?SOCK_IN:SOCK_OUT); + + force_draw(0); + } + else BIF_wait_for_statechange(); + } + + /* remove link? */ + if(link->tonode==NULL || link->fromnode==NULL) { + nodeRemLink(snode->edittree, link); + } + else { + bNodeLink *tlink; + + /* send changed events for original tonode and new */ + if(link->tonode) + NodeTagChanged(snode->edittree, link->tonode); + + /* we might need to remove a link */ + if(in_out==SOCK_OUT) { + if(nodeCountSocketLinks(snode->edittree, link->tosock) > tsock->limit) { + + for(tlink= snode->edittree->links.first; tlink; tlink= tlink->next) { + if(link!=tlink && tlink->tosock==link->tosock) + break; + } + if(tlink) { + /* is there a free input socket with same type? */ + for(tsock= tlink->tonode->inputs.first; tsock; tsock= tsock->next) { + if(tsock->type==tlink->fromsock->type) + if(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) + break; + } + if(tsock) + tlink->tosock= tsock; + else { + nodeRemLink(snode->edittree, tlink); + } + } + } + } + + /* and last trick: insert a convertor when types dont match */ + if(link->tosock->type!=link->fromsock->type) { + node_insert_convertor(snode, link); + ntreeSolveOrder(snode->edittree); /* so nice do it twice! well, the sort-order can only handle 1 added link at a time */ + } + } + + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(snode); + + allqueue(REDRAWNODE, 0); + BIF_undo_push("Add link"); + + return 1; +} + +/* return 1 when socket clicked */ +static int node_add_link(SpaceNode *snode) +{ + bNode *node; + bNodeLink *link; + bNodeSocket *sock; + + /* output indicated? */ + if(find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { + if(nodeCountSocketLinks(snode->edittree, sock)limit) + return node_add_link_drag(snode, node, sock, SOCK_OUT); + else { + /* find if we break a link */ + for(link= snode->edittree->links.first; link; link= link->next) { + if(link->fromsock==sock) + break; + } + if(link) { + node= link->tonode; + sock= link->tosock; + nodeRemLink(snode->edittree, link); + return node_add_link_drag(snode, node, sock, SOCK_IN); + } + } + } + /* or an input? */ + else if(find_indicated_socket(snode, &node, &sock, SOCK_IN)) { + if(nodeCountSocketLinks(snode->edittree, sock)limit) + return node_add_link_drag(snode, node, sock, SOCK_IN); + else { + /* find if we break a link */ + for(link= snode->edittree->links.first; link; link= link->next) { + if(link->tosock==sock) + break; + } + if(link) { + /* send changed event to original tonode */ + if(link->tonode) + NodeTagChanged(snode->edittree, link->tonode); + + node= link->fromnode; + sock= link->fromsock; + nodeRemLink(snode->edittree, link); + return node_add_link_drag(snode, node, sock, SOCK_OUT); + } + } + } + + return 0; +} + +static void node_delete(SpaceNode *snode) +{ + bNode *node, *next; + + for(node= snode->edittree->nodes.first; node; node= next) { + next= node->next; + if(node->flag & SELECT) + nodeFreeNode(snode->edittree, node); + } + + snode_verify_groups(snode); + snode_handle_recalc(snode); + BIF_undo_push("Delete nodes"); + allqueue(REDRAWNODE, 1); +} + +static void node_hide(SpaceNode *snode) +{ + bNode *node; + int nothidden=0, ishidden=0; + + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + if(node->flag & NODE_HIDDEN) + ishidden++; + else + nothidden++; + } + } + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(node->flag & SELECT) { + if( (ishidden && nothidden) || ishidden==0) + node->flag |= NODE_HIDDEN; + else + node->flag &= ~NODE_HIDDEN; + } + } + BIF_undo_push("Hide nodes"); + allqueue(REDRAWNODE, 1); +} + + +static void node_border_link_delete(SpaceNode *snode) +{ + rcti rect; + short val, mval[2], mvalo[2]; + + /* to make this work more friendly, we first wait for a mouse move */ + getmouseco_areawin(mvalo); + while (get_mbut() & L_MOUSE) { + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) + break; + else BIF_wait_for_statechange(); + } + if((get_mbut() & L_MOUSE)==0) + return; + + /* now change cursor and draw border */ + setcursor_space(SPACE_NODE, CURSOR_VPAINT); + + if ( (val = get_border(&rect, 2)) ) { + if(rect.xminv2d, mval, &rectf.xmin, &rectf.ymin); + mval[0]= rect.xmax; + mval[1]= rect.ymax; + areamouseco_to_ipoco(&snode->v2d, mval, &rectf.xmax, &rectf.ymax); + + myortho2(rectf.xmin, rectf.xmax, rectf.ymin, rectf.ymax); + + glSelectBuffer(256, buffer); + glRenderMode(GL_SELECT); + glInitNames(); + glPushName(-1); + + /* draw links */ + for(link= snode->edittree->links.first; link; link= link->next) { + glLoadName(code++); + node_draw_link(snode, link); + } + + hits= glRenderMode(GL_RENDER); + glPopName(); + if(hits>0) { + int a; + for(a=0; aedittree->links, buffer[ (4 * a) + 3]); + if(link) + link->fromnode= NULL; /* first tag for delete, otherwise indices are wrong */ + } + for(link= snode->edittree->links.first; link; link= next) { + next= link->next; + if(link->fromnode==NULL) { + NodeTagChanged(snode->edittree, link->tonode); + nodeRemLink(snode->edittree, link); + } + } + ntreeSolveOrder(snode->edittree); + snode_verify_groups(snode); + snode_handle_recalc(snode); + } + allqueue(REDRAWNODE, 0); + BIF_undo_push("Erase links"); + } + } + + setcursor_space(SPACE_NODE, CURSOR_STD); +} + + +/* ********************** */ + +void node_make_group(SpaceNode *snode) +{ + bNode *gnode; + + if(snode->edittree!=snode->nodetree) { + error("Can not add a new Group in a Group"); + return; + } + + /* for time being... is too complex to handle */ + if(snode->treetype==NTREE_COMPOSIT) { + for(gnode=snode->nodetree->nodes.first; gnode; gnode= gnode->next) { + if(gnode->flag & SELECT) + if(gnode->type==CMP_NODE_R_RESULT) + break; + } + if(gnode) { + error("Can not add RenderResult in a Group"); + return; + } + } + + gnode= nodeMakeGroupFromSelected(snode->nodetree); + if(gnode==NULL) { + error("Can not make Group"); + } + else { + nodeSetActive(snode->nodetree, gnode); + ntreeSolveOrder(snode->nodetree); + allqueue(REDRAWNODE, 0); + BIF_undo_push("Make Node Group"); + } +} + +/* ******************** main event loop ****************** */ + +/* special version to prevent overlapping buttons, has a bit of hack... */ +/* yes, check for example composit_node_event(), file window use... */ +static int node_uiDoBlocks(SpaceNode *snode, ListBase *lb, short event) +{ + bNode *node; + rctf rect; + ListBase listb= *lb; + void *prev; + int retval= UI_NOTHING; + short mval[2]; + + getmouseco_areawin(mval); + areamouseco_to_ipoco(G.v2d, mval, &rect.xmin, &rect.ymin); + + /* this happens after filesel usage... */ + if(lb->first==NULL) { + return UI_NOTHING; + } + + rect.xmin -= 2.0f; + rect.ymin -= 2.0f; + rect.xmax = rect.xmin + 4.0f; + rect.ymax = rect.ymin + 4.0f; + + for(node= snode->edittree->nodes.first; node; node= node->next) { + if(node->block) { + if(node == visible_node(snode, &rect)) { + + /* when there's menus, the prev pointer becomes zero! */ + prev= ((struct Link *)node->block)->prev; + + lb->first= lb->last= node->block; + retval= uiDoBlocks(lb, event); + + ((struct Link *)node->block)->prev= prev; + + break; + } + } + } + + *lb= listb; + + return retval; +} + +void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt) +{ + SpaceNode *snode= spacedata; + float dx; + unsigned short event= evt->event; + short val= evt->val, doredraw=0, fromlib= 0; + + if(sa->win==0) return; + if(snode->nodetree==NULL) return; + + if(val) { + + if( node_uiDoBlocks(snode, &sa->uiblocks, event)!=UI_NOTHING ) event= 0; + + fromlib= (snode->id && snode->id->lib); + + switch(event) { + case LEFTMOUSE: + if(fromlib) { + if(node_mouse_groupheader(snode)==0) + node_mouse_select(snode, event); + } + else { + if(node_add_link(snode)==0) + if(node_mouse_groupheader(snode)==0) + if(node_mouse_select(snode, event)==0) + node_border_link_delete(snode); + } + break; + + case RIGHTMOUSE: + node_mouse_select(snode, event); + + break; + case MIDDLEMOUSE: + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: + view2dmove(event); /* in drawipo.c */ + break; + + case MOUSEY: + doredraw= node_socket_hilights(snode, SOCK_IN|SOCK_OUT); + break; + + case UI_BUT_EVENT: + /* future: handlerize this! */ + if(snode->treetype==NTREE_SHADER) + shader_node_event(snode, val); + else if(snode->treetype==NTREE_COMPOSIT) + composit_node_event(snode, val); + break; + + case RENDERPREVIEW: + if(snode->treetype==NTREE_SHADER) + shader_node_previewrender(sa, snode); + else if(snode->treetype==NTREE_COMPOSIT) + snode_handle_recalc(snode); + break; + + case PADPLUSKEY: + dx= (float)(0.1154*(G.v2d->cur.xmax-G.v2d->cur.xmin)); + G.v2d->cur.xmin+= dx; + G.v2d->cur.xmax-= dx; + dx= (float)(0.1154*(G.v2d->cur.ymax-G.v2d->cur.ymin)); + G.v2d->cur.ymin+= dx; + G.v2d->cur.ymax-= dx; + test_view2d(G.v2d, sa->winx, sa->winy); + doredraw= 1; + break; + case PADMINUS: + dx= (float)(0.15*(G.v2d->cur.xmax-G.v2d->cur.xmin)); + G.v2d->cur.xmin-= dx; + G.v2d->cur.xmax+= dx; + dx= (float)(0.15*(G.v2d->cur.ymax-G.v2d->cur.ymin)); + G.v2d->cur.ymin-= dx; + G.v2d->cur.ymax+= dx; + test_view2d(G.v2d, sa->winx, sa->winy); + doredraw= 1; + break; + case HOMEKEY: + snode_home(sa, snode); + doredraw= 1; + break; + case TABKEY: + if(fromlib) fromlib= -1; + else snode_make_group_editable(snode, NULL); + break; + + case AKEY: + if(G.qual==LR_SHIFTKEY) { + if(fromlib) fromlib= -1; + else node_add_menu(snode); + } + else if(G.qual==0) { + node_deselectall(snode, 1); + BIF_undo_push("Deselect all nodes"); + } + break; + case BKEY: + if(G.qual==0) + node_border_select(snode); + break; + case CKEY: /* sort again, showing cyclics */ + ntreeSolveOrder(snode->edittree); + doredraw= 1; + break; + case DKEY: + if(G.qual==LR_SHIFTKEY) { + if(fromlib) fromlib= -1; + else node_adduplicate(snode); + } + break; + case GKEY: + if(fromlib) fromlib= -1; + else { + if(G.qual==LR_CTRLKEY) { + if(okee("Make Group")) + node_make_group(snode); + } + else if(G.qual==LR_ALTKEY) { + if(okee("Ungroup")) + node_ungroup(snode); + } + else + transform_nodes(snode->edittree, 'g', "Translate Node"); + } + break; + case HKEY: + node_hide(snode); + break; + + case DELKEY: + case XKEY: + if(fromlib) fromlib= -1; + else node_delete(snode); + break; + } + } + + if(fromlib==-1) + error("Cannot edit Library Data"); + if(doredraw) + scrarea_queue_winredraw(sa); + if(doredraw==2) + scrarea_queue_headredraw(sa); +} + + diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 871663c8126..1498bf15c06 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -62,6 +62,7 @@ #include "DNA_constraint_types.h" #include "DNA_curve_types.h" #include "DNA_effect_types.h" +#include "DNA_group_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" #include "DNA_key_types.h" @@ -71,6 +72,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_meta_types.h" +#include "DNA_nla_types.h" #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_scene_types.h" @@ -101,6 +103,7 @@ #include "BKE_effect.h" #include "BKE_font.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_ipo.h" #include "BKE_key.h" #include "BKE_lattice.h" @@ -276,7 +279,7 @@ void delete_obj(int ok) allqueue(REDRAWNLA, 0); DAG_scene_sort(G.scene); - + BIF_undo_push("Delete object(s)"); } @@ -2066,7 +2069,7 @@ void special_editmenu(void) } else if(G.obedit->type==OB_MESH) { - nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15"); + nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15|Blend From Shape%x16|Propagate To All Shapes%x17"); switch(nr) { case 1: @@ -2134,6 +2137,12 @@ void special_editmenu(void) case 15: mesh_set_smooth_faces(0); break; + case 16: + shape_copy_select_from(); + break; + case 17: + shape_propagate(); + break; } DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); @@ -2653,6 +2662,7 @@ void copy_attr_menu() if(!(ob=OBACT)) return; strcat (str, "|Object Constraints%x22"); + strcat (str, "|NLA Strips%x26"); if ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) { strcat(str, "|Texture Space%x17"); @@ -2742,6 +2752,8 @@ void copy_attr(short event) 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; @@ -2914,6 +2926,9 @@ void copy_attr(short event) BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody)); } } + else if(event==26) { + copy_nlastrips(&base->object->nlastrips, &ob->nlastrips); + } } } base= base->next; @@ -2926,7 +2941,7 @@ void copy_attr(short event) allqueue(REDRAWBUTSOBJECT, 0); } - BIF_undo_push("Copy attributes"); + BIF_undo_push("Copy Attributes"); } void link_to_scene(unsigned short nr) @@ -2994,7 +3009,7 @@ void make_links(short event) ID *id; Material ***matarar, ***obmatarar, **matar1, **matar2; int a; - short *totcolp, nr; + short *totcolp, nr=0; char *strp; if(!(ob=OBACT)) return; @@ -3002,7 +3017,7 @@ void make_links(short event) if(event==1) { IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr); - if(strncmp(strp, "DataBrow", 8)==0) { + if(nr == -2) { MEM_freeN(strp); activate_databrowse((ID *)G.scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene ); @@ -3153,7 +3168,7 @@ void make_duplilist_real() { Base *base, *basen; Object *ob; - extern ListBase duplilist; +// extern ListBase duplilist; if(okee("Make dupli objects real")==0) return; @@ -3162,11 +3177,11 @@ void make_duplilist_real() if TESTBASELIB(base) { if(base->object->transflag & OB_DUPLI) { - - make_duplilist(G.scene, base->object); - ob= duplilist.first; - while(ob) { - + ListBase *lb= object_duplilist(G.scene, base->object); + DupliObject *dob; + + 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... */ @@ -3175,19 +3190,17 @@ void make_duplilist_real() basen= MEM_dupallocN(base); basen->flag &= ~OB_FROMDUPLI; BLI_addhead(&G.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; - basen->object= copy_object(ob); - basen->object->flag &= ~OB_FROMDUPLI; + ob->transflag &= ~OB_DUPLI; - apply_obmat(basen->object); - - ob= ob->id.next; + Mat4CpyMat4(ob->obmat, dob->mat); + apply_obmat(ob); } - free_duplilist(); + BLI_freelistN(lb); base->object->transflag &= ~OB_DUPLI; } @@ -3559,9 +3572,14 @@ void std_rmouse_transform(void (*xf_func)(int, int)) short timer=0; short mousebut; - /* check for left mouse select/right mouse select user pref */ - if (U.flag & USER_LMOUSESELECT) mousebut = L_MOUSE; - else mousebut = R_MOUSE; + /* check for left mouse select/right mouse select */ + + if(curarea->spacetype==SPACE_NODE) + mousebut = L_MOUSE|R_MOUSE; + else if (U.flag & USER_LMOUSESELECT) + mousebut = L_MOUSE; + else + mousebut = R_MOUSE; getmouseco_areawin(mval); xo= mval[0]; @@ -4018,11 +4036,31 @@ void single_user(void) /* ************************************************************* */ +/* helper for below, ma was checked to be not NULL */ +static void make_local_makelocalmaterial(Material *ma) +{ + ID *id; + int b; + + make_local_material(ma); + + for(b=0; bmtex[b] && ma->mtex[b]->tex) { + make_local_texture(ma->mtex[b]->tex); + } + } + + id= (ID *)ma->ipo; + if(id && id->lib) make_local_ipo(ma->ipo); + + /* nodetree? XXX */ +} void make_local(void) { Base *base; Object *ob; + bActionStrip *strip; Material *ma, ***matarar; Lamp *la; Curve *cu; @@ -4033,14 +4071,14 @@ void make_local(void) if(G.scene->id.lib) return; - mode= pupmenu("Make Local%t|Selected %x1|All %x2"); + mode= pupmenu("Make Local%t|Selected Objects %x1|Selected Objects and Data %x2|All %x3"); - if(mode==2) { + if(mode==3) { all_local(NULL); // NULL is all libs allqueue(REDRAWALL, 0); return; } - else if(mode!=1) return; + else if(mode<1) return; clear_id_newpoins(); @@ -4075,7 +4113,7 @@ void make_local(void) id= ob->data; - if(id) { + if(id && mode>1) { switch(ob->type) { case OB_LAMP: @@ -4119,62 +4157,51 @@ void make_local(void) 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); + } + } base= base->next; } - base= FIRSTBASE; - while(base) { - ob= base->object; - if(base->flag & SELECT ) { - - 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 { - - for(a=0; atotcol; a++) { - ma= ob->mat[a]; - if(ma) { - make_local_material(ma); - - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - make_local_texture(ma->mtex[b]->tex); - } - } - id= (ID *)ma->ipo; - if(id && id->lib) make_local_ipo(ma->ipo); - } - } - - matarar= (Material ***)give_matarar(ob); - - for(a=0; atotcol; a++) { - ma= (*matarar)[a]; - if(ma) { - make_local_material(ma); - - for(b=0; bmtex[b] && ma->mtex[b]->tex) { - make_local_texture(ma->mtex[b]->tex); - } - } - id= (ID *)ma->ipo; - if(id && id->lib) make_local_ipo(ma->ipo); + if(mode>1) { + base= FIRSTBASE; + while(base) { + ob= base->object; + if(base->flag & SELECT ) { + + 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 { + + for(a=0; atotcol; a++) { + ma= ob->mat[a]; + if(ma) + make_local_makelocalmaterial(ma); + } + + matarar= (Material ***)give_matarar(ob); + + for(a=0; atotcol; a++) { + ma= (*matarar)[a]; + if(ma) + make_local_makelocalmaterial(ma); } } } + base= base->next; } - base= base->next; } - allqueue(REDRAWALL, 0); BIF_undo_push("Make local"); } @@ -4227,7 +4254,14 @@ void adduplicate(int mode, int dupflag) BLI_addhead(&G.scene->base, basen); /* addhead: prevent eternal loop */ basen->object= obn; base->flag &= ~SELECT; - basen->flag &= ~OB_FROMGROUP; + + 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); + } + } if(BASACT==base) BASACT= basen; @@ -4404,20 +4438,6 @@ void adduplicate(int mode, int dupflag) base= base->next; } - /* ipos */ - ipo= G.main->ipo.first; - while(ipo) { - if(ipo->id.lib==NULL && ipo->id.newid) { - IpoCurve *icu; - for(icu= ipo->curve.first; icu; icu= icu->next) { - if(icu->driver) { - ID_NEW(icu->driver->ob); - } - } - } - ipo= ipo->id.next; - } - /* materials */ if( dupflag & USER_DUP_MAT) { mao= G.main->mat.first; @@ -4449,6 +4469,40 @@ void adduplicate(int mode, int dupflag) } } + /* 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; + } + + + DAG_scene_sort(G.scene); DAG_scene_flush_update(G.scene, screen_view3d_layers()); set_sca_new_poins(); diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index b665c64e0e3..061e70c5938 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -58,6 +58,7 @@ #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_sound_types.h" @@ -78,6 +79,7 @@ #include "BIF_gl.h" #include "BIF_graphics.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_mainqueue.h" #include "BIF_mywindow.h" #include "BIF_renderwin.h" @@ -98,7 +100,6 @@ #include "BPY_extern.h" #include "mydevice.h" #include "blendef.h" -#include "render.h" /* R.flag */ #include "winlay.h" @@ -110,6 +111,8 @@ always reset to zero. */ +/* comment added to test orange branch */ + static void testareas(void); static void area_autoplayscreen(void); static void wait_for_event(void); @@ -325,10 +328,16 @@ void areawinset(short win) G.v2d= &G.snla->v2d; break; case SPACE_TIME: - { + { SpaceTime *stime= curarea->spacedata.first; G.v2d= &stime->v2d; - } + } + break; + case SPACE_NODE: + { + SpaceNode *snode= curarea->spacedata.first; + G.v2d= &snode->v2d; + } break; default: break; @@ -398,7 +407,9 @@ void scrarea_do_headdraw(ScrArea *area) case SPACE_ACTION: action_buttons(); break; case SPACE_NLA: nla_buttons(); break; case SPACE_TIME: time_buttons(area); break; + case SPACE_NODE: node_buttons(area); break; } + uiClearButLock(); //glScissor(area->winrct.xmin, area->winrct.xmax, area->winx, area->winy); area->head_swap= WIN_BACK_OK; @@ -644,7 +655,6 @@ int is_allowed_to_change_screen(bScreen *new) void splash(void *data, int datasize, char *string) { - extern void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy); ImBuf *bbuf; int oldwin; short val; @@ -851,7 +861,7 @@ static void flush_extqd_events(void) { ext_inputchange= ext_reshape= ext_redraw= ext_mousemove= 0; } -unsigned short qtest(void) +int qtest(void) { if (!mainqtest()) { winlay_process_events(0); @@ -1763,7 +1773,7 @@ static void del_area(ScrArea *sa) closeareawin(sa); closeheadwin(sa); - freespacelist(&sa->spacedata); + freespacelist(sa); uiFreeBlocks(&sa->uiblocks); uiFreePanels(&sa->panels); @@ -1782,7 +1792,7 @@ static void copy_areadata(ScrArea *sa1, ScrArea *sa2) sa1->spacetype= sa2->spacetype; Mat4CpyMat4(sa1->winmat, sa2->winmat); - freespacelist(&sa1->spacedata); + freespacelist(sa1); duplicatespacelist(sa1, &sa1->spacedata, &sa2->spacedata); BLI_freelistN(&sa1->panels); @@ -3508,10 +3518,10 @@ void draw_area_emboss(ScrArea *sa) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - BIF_draw_icon(8.0, 10.0, ICON_MATERIAL_HLT); - BIF_draw_icon(8.0, 30.0, ICON_IPO_HLT); - BIF_draw_icon(8.0, 50.0, ICON_HOME); - BIF_draw_icon(8.0, 70.0, ICON_BORDERMOVE); + BIF_icon_draw(8.0, 10.0, ICON_MATERIAL_HLT); + BIF_icon_draw(8.0, 30.0, ICON_IPO_HLT); + BIF_icon_draw(8.0, 50.0, ICON_HOME); + BIF_icon_draw(8.0, 70.0, ICON_BORDERMOVE); glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); @@ -3635,7 +3645,7 @@ int get_cursor(void) { } void set_cursor(int curs) { - if (!(R.flag & R_RENDERING) && G.background == 0) { + if (!(G.rendering) && G.background == 0) { if (curs!=curcursor) { curcursor= curs; window_set_cursor(mainwin, curs); diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index eca241c155f..897c4516069 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -59,6 +59,7 @@ #include "DNA_image_types.h" #include "DNA_object_types.h" // only for uvedit_selectionCB() (struct Object) +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -84,6 +85,8 @@ #include "BDR_editobject.h" #include "BDR_unwrapper.h" +#include "BMF_Api.h" + #include "blendef.h" #include "mydevice.h" @@ -1395,3 +1398,106 @@ int minmax_tface_uv(float *min, float *max) return sel; } +static void sima_show_info(int x, int y, char *cp, float *fp, int *zp, float *zpf) +{ + short ofs; + char str[256]; + + ofs= sprintf(str, "X: %d Y: %d ", x, y); + if(cp) + ofs+= sprintf(str+ofs, "| R: %d G: %d B: %d A: %d ", cp[0], cp[1], cp[2], cp[3]); + if(fp) + ofs+= sprintf(str+ofs, "| R: %.3f G: %.3f B: %.3f A: %.3f ", fp[0], fp[1], fp[2], fp[3]); + if(zp) + ofs+= sprintf(str+ofs, "| Z: %.4f ", 0.5+0.5*( ((float)*zp)/(float)0x7fffffff)); + if(zpf) + ofs+= sprintf(str+ofs, "| Z: %.3f ", *zpf); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glColor4f(.0,.0,.0,.25); + glRectf(0.0, 0.0, curarea->winx, 30.0); + glDisable(GL_BLEND); + + glColor3ub(255, 255, 255); + glRasterPos2i(10, 10); + + BMF_DrawString(G.fonts, str); + +} + +void sima_sample_color(void) +{ + ImBuf *ibuf; + float fx, fy; + short mval[2], mvalo[2], firsttime=1; + + if(G.sima->image==NULL) return; + if(G.sima->image->ibuf==NULL) return; + ibuf= G.sima->image->ibuf; + + calc_image_view(G.sima, 'f'); + getmouseco_areawin(mvalo); + + while(get_mbut() & L_MOUSE) { + + getmouseco_areawin(mval); + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) { + firsttime= 0; + areamouseco_to_ipoco(G.v2d, mval, &fx, &fy); + + if(fx>=0.0 && fy>=0.0 && fx<1.0 && fy<1.0) { + float *fp= NULL, *zpf= NULL; + int *zp= NULL; + char *cp= NULL; + + int x= (int) (fx*ibuf->x); + int y= (int) (fy*ibuf->y); + + if(x>=ibuf->x) x= ibuf->x-1; + if(y>=ibuf->y) y= ibuf->y-1; + + if(ibuf->rect) + cp= (char *)(ibuf->rect + y*ibuf->x + x); + if(ibuf->zbuf) + zp= ibuf->zbuf + y*ibuf->x + x; + if(ibuf->zbuf_float) + zpf= ibuf->zbuf_float + y*ibuf->x + x; + if(ibuf->rect_float) + fp= (ibuf->rect_float + 4*(y*ibuf->x + x)); + + if(G.sima->cumap) { + float vec[3]; + if(fp==NULL) { + fp= vec; + vec[0]= (float)cp[0]/255.0f; + vec[1]= (float)cp[1]/255.0f; + vec[2]= (float)cp[2]/255.0f; + } + + if(G.qual & LR_CTRLKEY) { + curvemapping_set_black_white(G.sima->cumap, NULL, fp); + curvemapping_do_image(G.sima->cumap, G.sima->image); + } + else if(G.qual & LR_SHIFTKEY) { + curvemapping_set_black_white(G.sima->cumap, fp, NULL); + curvemapping_do_image(G.sima->cumap, G.sima->image); + } + } + + scrarea_do_windraw(curarea); + myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375); + glLoadIdentity(); + sima_show_info(x, y, cp, fp, zp, zpf); + screen_swapbuffers(); + } + + } + BIF_wait_for_statechange(); + } + + scrarea_queue_winredraw(curarea); +} + + diff --git a/source/blender/src/edittime.c b/source/blender/src/edittime.c index 26aa3e1cbae..48c65a29cd9 100644 --- a/source/blender/src/edittime.c +++ b/source/blender/src/edittime.c @@ -1,15 +1,12 @@ /** * $Id: * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +24,7 @@ * * Contributor(s): none yet. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 2376fe93619..ea640897963 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -46,10 +46,11 @@ #include "DNA_action_types.h" #include "DNA_armature_types.h" +#include "DNA_curve_types.h" +#include "DNA_group_types.h" +#include "DNA_lattice_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" -#include "DNA_curve_types.h" -#include "DNA_lattice_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -63,7 +64,9 @@ #include "BKE_armature.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_lattice.h" +#include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_utildefines.h" @@ -1023,8 +1026,6 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo) } #endif -#define SELECTSIZE 51 - void set_active_base(Base *base) { Base *tbase; @@ -1032,15 +1033,16 @@ void set_active_base(Base *base) BASACT= base; if(base) { + /* signals to buttons */ redraw_test_buttons(base->object); - - set_active_group(); /* signal to ipo */ allqueue(REDRAWIPO, base->object->ipowin); + allqueue(REDRAWACTION, 0); allqueue(REDRAWNLA, 0); + allqueue(REDRAWNODE, 0); /* signal to action */ select_actionchannel_by_name(base->object->action, "Object", 1); @@ -1059,13 +1061,34 @@ void set_active_object(Object *ob) { Base *base; - base= FIRSTBASE; - while(base) { + for(base= FIRSTBASE; base; base= base->next) { if(base->object==ob) { set_active_base(base); return; } - base= base->next; + } +} + +static void select_all_from_groups(Base *basact) +{ + Group *group; + GroupObject *go; + int deselect= basact->flag & SELECT; + + for(group= G.main->group.first; group; group= group->id.next) { + if(object_in_group(basact->object, group)) { + for(go= group->gobject.first; go; go= go->next) { + if(deselect) go->ob->flag &= ~SELECT; + else go->ob->flag |= SELECT; + } + } + } + /* sync bases */ + for(basact= G.scene->base.first; basact; basact= basact->next) { + if(basact->object->flag & SELECT) + basact->flag |= SELECT; + else + basact->flag &= ~SELECT; } } @@ -1342,6 +1365,9 @@ void mouse_select(void) deselectall_except(basact); basact->flag |= SELECT; } + else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) { + select_all_from_groups(basact); + } else { if(basact->flag & SELECT) { if(basact==oldbasact) @@ -1933,7 +1959,7 @@ void set_render_border(void) if(G.vd->persp!=2) return; - val= get_border(&rect, 2); + val= get_border(&rect, 3); if(val) { rcti vb; diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 8123e2b4cd5..e4cfb833895 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -456,93 +456,6 @@ void filesel_statistics(SpaceFile *sfile, int *totfile, int *selfile, float *tot /* *************** HELP FUNCTIONS ******************* */ -/* This is a really ugly function... its purpose is to - * take the space file name and clean it up, replacing - * excess file entry stuff (like /tmp/../tmp/../) - */ - -void checkdir(char *dir) -{ - short a; - char *start, *eind; - char tmp[FILE_MAXDIR+FILE_MAXFILE]; - - BLI_make_file_string(G.sce, tmp, dir, ""); - strcpy(dir, tmp); - -#ifdef WIN32 - if(dir[0]=='.') { /* happens for example in FILE_MAIN */ - dir[0]= '\\'; - dir[1]= 0; - return; - } - - while ( (start = strstr(dir, "\\..\\")) ) { - eind = start + strlen("\\..\\") - 1; - a = start-dir-1; - while (a>0) { - if (dir[a] == '\\') break; - a--; - } - strcpy(dir+a,eind); - } - - while ( (start = strstr(dir,"\\.\\")) ){ - eind = start + strlen("\\.\\") - 1; - strcpy(start,eind); - } - - while ( (start = strstr(dir,"\\\\" )) ){ - eind = start + strlen("\\\\") - 1; - strcpy(start,eind); - } - - if((a = strlen(dir))){ /* remove the '\\' at the end */ - while(a>0 && dir[a-1] == '\\'){ - a--; - dir[a] = 0; - } - } - - strcat(dir, "\\"); -#else - if(dir[0]=='.') { /* happens, for example in FILE_MAIN */ - dir[0]= '/'; - dir[1]= 0; - return; - } - - while ( (start = strstr(dir, "/../")) ) { - eind = start + strlen("/../") - 1; - a = start-dir-1; - while (a>0) { - if (dir[a] == '/') break; - a--; - } - strcpy(dir+a,eind); - } - - while ( (start = strstr(dir,"/./")) ){ - eind = start + strlen("/./") - 1; - strcpy(start,eind); - } - - while ( (start = strstr(dir,"//" )) ){ - eind = start + strlen("//") - 1; - strcpy(start,eind); - } - - if( (a = strlen(dir)) ){ /* remove all '/' at the end */ - while(dir[a-1] == '/'){ - a--; - dir[a] = 0; - if (a<=0) break; - } - } - - strcat(dir, "/"); -#endif -} /* not called when browsing .blend itself */ void test_flags_file(SpaceFile *sfile) @@ -589,10 +502,13 @@ void test_flags_file(SpaceFile *sfile) (BLI_testextensie(file->relname, ".tif") || BLI_testextensie(file->relname, ".tiff"))) { file->flags |= IMAGEFILE; + } else if (BLI_testextensie(file->relname, ".exr")) { + file->flags |= IMAGEFILE; } else if (G.have_quicktime){ if( BLI_testextensie(file->relname, ".jpg") || BLI_testextensie(file->relname, ".jpeg") || BLI_testextensie(file->relname, ".hdr") + || BLI_testextensie(file->relname, ".exr") || BLI_testextensie(file->relname, ".tga") || BLI_testextensie(file->relname, ".rgb") || BLI_testextensie(file->relname, ".bmp") @@ -619,7 +535,8 @@ void test_flags_file(SpaceFile *sfile) } } else { // no quicktime if(BLI_testextensie(file->relname, ".jpg") - || BLI_testextensie(file->relname, ".hdr") + || BLI_testextensie(file->relname, ".hdr") + || BLI_testextensie(file->relname, ".exr") || BLI_testextensie(file->relname, ".tga") || BLI_testextensie(file->relname, ".rgb") || BLI_testextensie(file->relname, ".bmp") @@ -1360,7 +1277,7 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *) } else { /* FILE_BLENDER */ split_sfile(sfile, name); /* test filelist too */ - checkdir(sfile->dir); + BLI_cleanup_dir(G.sce, sfile->dir); /* free: filelist and libfiledata became incorrect */ if(sfile->libfiledata) BLO_blendhandle_close(sfile->libfiledata); @@ -1394,7 +1311,7 @@ void activate_imageselect(int type, char *title, char *file, void (*func)(char * else simasel->mode &= ~IMS_STRINGCODE; BLI_split_dirfile(name, dir, simasel->file); - checkdir(simasel->dir); + BLI_cleanup_dir(G.sce, simasel->dir); if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0; strcpy(simasel->dir, dir); @@ -1412,9 +1329,9 @@ void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *me SpaceFile *sfile; char str[32]; - if(id==0) { + if(id==NULL) { lb= wich_libbase(G.main, idcode); - id= lb->last; + id= lb->first; } if(id) strcpy(str, id->name); @@ -1623,7 +1540,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) } else if(event== 2) { /* reuse the butname variable */ - checkdir(sfile->dir); + BLI_cleanup_dir(G.sce, sfile->dir); BLI_make_file_string(G.sce, butname, sfile->dir, ""); /* strip the trailing slash if its a real dir */ @@ -1649,7 +1566,7 @@ static void do_filesel_buttons(short event, SpaceFile *sfile) if (selected) { strcpy(sfile->dir, selected); BLI_make_exist(sfile->dir); - checkdir(sfile->dir); + BLI_cleanup_dir(G.sce, sfile->dir); freefilelist(sfile); sfile->ofs= 0; scrarea_queue_winredraw(curarea); @@ -1928,7 +1845,7 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt) if(S_ISDIR(sfile->filelist[act].type)) { strcat(sfile->dir, sfile->filelist[act].relname); strcat(sfile->dir,"/"); - checkdir(sfile->dir); + BLI_cleanup_dir(G.sce, sfile->dir); freefilelist(sfile); sfile->ofs= 0; do_draw= 1; @@ -2345,7 +2262,7 @@ static void do_library_append(SpaceFile *sfile) Object *ob; int idcode = groupname_to_code(group); - BLO_library_append(sfile, dir, idcode); /* warning; if relative, it changes the *dir to relative path */ + BLO_library_append(sfile, dir, idcode); /* DISPLISTS? */ ob= G.main->object.first; @@ -2359,7 +2276,7 @@ static void do_library_append(SpaceFile *sfile) /* and now find the latest append lib file */ lib= G.main->library.first; while(lib) { - if (BLI_streq(dir, lib->name)) break; + if (BLI_streq(dir, lib->filename)) break; lib= lib->id.next; } @@ -2541,7 +2458,7 @@ void main_to_filelist(SpaceFile *sfile) if( sfile->dir[0]==0) { /* make directories */ - sfile->totfile= 21; + sfile->totfile= 23; sfile->filelist= (struct direntry *)malloc(sfile->totfile * sizeof(struct direntry)); for(a=0; atotfile; a++) { @@ -2552,24 +2469,27 @@ void main_to_filelist(SpaceFile *sfile) sfile->filelist[0].relname= BLI_strdup(".."); sfile->filelist[1].relname= BLI_strdup("."); sfile->filelist[2].relname= BLI_strdup("Scene"); - sfile->filelist[3].relname= BLI_strdup("Object"); - sfile->filelist[4].relname= BLI_strdup("Mesh"); - sfile->filelist[5].relname= BLI_strdup("Curve"); - sfile->filelist[6].relname= BLI_strdup("Metaball"); - sfile->filelist[7].relname= BLI_strdup("Material"); - sfile->filelist[8].relname= BLI_strdup("Texture"); - sfile->filelist[9].relname= BLI_strdup("Image"); - sfile->filelist[10].relname= BLI_strdup("Wave"); - sfile->filelist[11].relname= BLI_strdup("Lattice"); - sfile->filelist[12].relname= BLI_strdup("Lamp"); - sfile->filelist[13].relname= BLI_strdup("Camera"); - sfile->filelist[14].relname= BLI_strdup("Ipo"); - sfile->filelist[15].relname= BLI_strdup("World"); - sfile->filelist[16].relname= BLI_strdup("Screen"); - sfile->filelist[17].relname= BLI_strdup("VFont"); - sfile->filelist[18].relname= BLI_strdup("Text"); - sfile->filelist[19].relname= BLI_strdup("Armature"); - sfile->filelist[20].relname= BLI_strdup("Action"); + sfile->filelist[3].relname= BLI_strdup("Group"); + sfile->filelist[4].relname= BLI_strdup("Object"); + sfile->filelist[5].relname= BLI_strdup("Mesh"); + sfile->filelist[6].relname= BLI_strdup("Curve"); + sfile->filelist[7].relname= BLI_strdup("Metaball"); + sfile->filelist[8].relname= BLI_strdup("Material"); + sfile->filelist[9].relname= BLI_strdup("Texture"); + sfile->filelist[10].relname= BLI_strdup("Image"); + sfile->filelist[11].relname= BLI_strdup("Wave"); + sfile->filelist[12].relname= BLI_strdup("Lattice"); + sfile->filelist[13].relname= BLI_strdup("Lamp"); + sfile->filelist[14].relname= BLI_strdup("Camera"); + sfile->filelist[15].relname= BLI_strdup("Ipo"); + sfile->filelist[16].relname= BLI_strdup("World"); + sfile->filelist[17].relname= BLI_strdup("Screen"); + sfile->filelist[18].relname= BLI_strdup("VFont"); + sfile->filelist[19].relname= BLI_strdup("Text"); + sfile->filelist[20].relname= BLI_strdup("Armature"); + sfile->filelist[21].relname= BLI_strdup("Action"); + sfile->filelist[22].relname= BLI_strdup("NodeTree"); + qsort(sfile->filelist, sfile->totfile, sizeof(struct direntry), compare_name); } else { @@ -2623,7 +2543,12 @@ void main_to_filelist(SpaceFile *sfile) if (hide==0 || id->name[2] != '.') { memset( files, 0 , sizeof(struct direntry)); - files->relname= BLI_strdup(id->name+2); + 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); + } if(sfile->returnfunc==0) { /* F4 DATA BROWSE */ if(idcode==ID_OB) { diff --git a/source/blender/src/fluidsim.c b/source/blender/src/fluidsim.c index 3044584cb31..bab93250d23 100644 --- a/source/blender/src/fluidsim.c +++ b/source/blender/src/fluidsim.c @@ -80,7 +80,6 @@ #include "BSE_headerbuttons.h" #include "mydevice.h" -#include "render.h" // for RE_make_existing_file #include "SDL.h" #include "SDL_thread.h" @@ -357,7 +356,7 @@ void fluidsimBake(struct Object *ob) // make sure all directories exist // as the bobjs use the same dir, this only needs to be checked // for the cfg output - RE_make_existing_file(targetFile); + BLI_make_existing_file(targetFile); // check selected directory // simply try to open cfg file for writing to test validity of settings @@ -408,7 +407,7 @@ void fluidsimBake(struct Object *ob) strcat(targetFile, suffixConfig); // make sure these directories exist as well if(outStringsChanged) { - RE_make_existing_file(targetFile); + BLI_make_existing_file(targetFile); } fileCfg = fopen(targetFile, "w"); if(!fileCfg) { diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c index 16571fbec95..4cdc65f621c 100644 --- a/source/blender/src/glutil.c +++ b/source/blender/src/glutil.c @@ -220,9 +220,9 @@ static int get_cached_work_texture(int *w_r, int *h_r) glBindTexture(GL_TEXTURE_2D, texid); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); tbuf= MEM_callocN(tex_w*tex_h*4, "tbuf"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tbuf); @@ -236,9 +236,10 @@ static int get_cached_work_texture(int *w_r, int *h_r) return texid; } -void glaDrawPixelsTex(float x, float y, int img_w, int img_h, void *rect) +void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect) { unsigned char *uc_rect= (unsigned char*) rect; + float *f_rect= (float *)rect; float xzoom= glaGetOneFloat(GL_ZOOM_X), yzoom= glaGetOneFloat(GL_ZOOM_Y); int ltexid= glaGetOneInteger(GL_TEXTURE_2D); int lrowlength= glaGetOneInteger(GL_UNPACK_ROW_LENGTH); @@ -256,9 +257,12 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, void *rect) int subpart_h= (subpart_y==nsubparts_y-1)?(img_h-subpart_y*tex_h):tex_h; float rast_x= x+subpart_x*tex_w*xzoom; float rast_y= y+subpart_y*tex_h*yzoom; - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); - + + if(format==GL_FLOAT) + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_FLOAT, &f_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); + else + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y*tex_w)*img_w*4 + (subpart_x*tex_w)*4]); + glColor3ub(255, 255, 255); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); @@ -282,10 +286,8 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, void *rect) glPixelStorei(GL_UNPACK_ROW_LENGTH, lrowlength); } -void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, void *rect) +void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect) { - unsigned char *uc_rect= (unsigned char*) rect; - float xzoom= glaGetOneFloat(GL_ZOOM_X); float yzoom= glaGetOneFloat(GL_ZOOM_Y); @@ -336,8 +338,28 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, void *rect) glaRasterPosSafe2f(rast_x, rast_y, 0, 0); } - glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); - glDrawPixels(draw_w, draw_h, GL_RGBA, GL_UNSIGNED_BYTE, uc_rect + (off_y*img_w + off_x)*4); + glPixelStorei(GL_UNPACK_ROW_LENGTH, row_w); + if(format==GL_LUMINANCE || format==GL_RED) { + if(type==GL_FLOAT) { + float *f_rect= (float *)rect; + glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y*row_w + off_x)); + } + else if(type==GL_INT || type==GL_UNSIGNED_INT) { + int *i_rect= (int *)rect; + glDrawPixels(draw_w, draw_h, format, type, i_rect + (off_y*row_w + off_x)); + } + } + else { /* RGBA */ + if(type==GL_FLOAT) { + float *f_rect= (float *)rect; + glDrawPixels(draw_w, draw_h, format, type, f_rect + (off_y*row_w + off_x)*4); + } + else if(type==GL_UNSIGNED_BYTE) { + unsigned char *uc_rect= (unsigned char *) rect; + glDrawPixels(draw_w, draw_h, format, type, uc_rect + (off_y*row_w + off_x)*4); + } + } + glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); } } diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index 3ab573ff9ce..e6b4442bdd5 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -150,7 +150,7 @@ void do_action_buttons(unsigned short event) else { float extra; - calc_action_range(G.saction->action, &G.v2d->cur.xmin, &G.v2d->cur.xmax); + calc_action_range(G.saction->action, &G.v2d->cur.xmin, &G.v2d->cur.xmax, 0); if(G.saction->pin==0 && ob) { G.v2d->cur.xmin= get_action_frame_inv(ob, G.v2d->cur.xmin); G.v2d->cur.xmax= get_action_frame_inv(ob, G.v2d->cur.xmax); @@ -929,7 +929,7 @@ void action_buttons(void) from = (ID*) ob; xco= std_libbuttons(block, xco, 0, B_ACTPIN, &G.saction->pin, - B_ACTIONBROWSE, (ID*)G.saction->action, + B_ACTIONBROWSE, ID_AC, 0, (ID*)G.saction->action, from, &(G.saction->actnr), B_ACTALONE, B_ACTLOCAL, B_ACTIONDELETE, 0, 0); diff --git a/source/blender/src/header_buttonswin.c b/source/blender/src/header_buttonswin.c index 7b992263bb7..b1fdf0f5475 100644 --- a/source/blender/src/header_buttonswin.c +++ b/source/blender/src/header_buttonswin.c @@ -46,6 +46,7 @@ #include "DNA_armature_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -62,16 +63,21 @@ #include "BIF_butspace.h" #include "BKE_armature.h" +#include "BKE_blender.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_node.h" #include "BKE_texture.h" #include "BKE_utildefines.h" + #include "BSE_drawipo.h" +#include "BSE_node.h" #include "BSE_headerbuttons.h" #include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" #include "blendef.h" #include "mydevice.h" @@ -98,9 +104,12 @@ void free_matcopybuf(void) if(matcopybuf.ramp_col) MEM_freeN(matcopybuf.ramp_col); if(matcopybuf.ramp_spec) MEM_freeN(matcopybuf.ramp_spec); + matcopybuf.ramp_col= NULL; matcopybuf.ramp_spec= NULL; + ntreeFreeTree(matcopybuf.nodetree); + default_mtex(&mtexcopybuf); } @@ -131,7 +140,7 @@ void do_buts_buttons(short event) scrarea_queue_winredraw(curarea); break; case B_BUTSPREVIEW: - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_TE); G.buts->oldkeypress = 0; scrarea_queue_headredraw(curarea); scrarea_queue_winredraw(curarea); @@ -143,9 +152,10 @@ void do_buts_buttons(short event) break; case B_MATCOPY: if(G.buts->lockpoin) { + ma= G.buts->lockpoin; if(matcopied) free_matcopybuf(); - memcpy(&matcopybuf, G.buts->lockpoin, sizeof(Material)); + memcpy(&matcopybuf, ma, sizeof(Material)); if(matcopybuf.ramp_col) matcopybuf.ramp_col= MEM_dupallocN(matcopybuf.ramp_col); if(matcopybuf.ramp_spec) matcopybuf.ramp_spec= MEM_dupallocN(matcopybuf.ramp_spec); @@ -155,12 +165,15 @@ void do_buts_buttons(short event) matcopybuf.mtex[a]= MEM_dupallocN(mtex); } } + matcopybuf.nodetree= ntreeCopyTree(ma->nodetree, 0); + matcopied= 1; } break; case B_MATPASTE: if(matcopied && G.buts->lockpoin) { ma= G.buts->lockpoin; + /* free current mat */ if(ma->ramp_col) MEM_freeN(ma->ramp_col); if(ma->ramp_spec) MEM_freeN(ma->ramp_spec); @@ -169,7 +182,7 @@ void do_buts_buttons(short event) if(mtex && mtex->tex) mtex->tex->id.us--; if(mtex) MEM_freeN(mtex); } - + id= (ma->id); memcpy(G.buts->lockpoin, &matcopybuf, sizeof(Material)); (ma->id)= id; @@ -184,7 +197,10 @@ void do_buts_buttons(short event) if(mtex->tex) id_us_plus((ID *)mtex->tex); } } - BIF_preview_changed(G.buts); + ntreeFreeTree(ma->nodetree); + ma->nodetree= ntreeCopyTree(matcopybuf.nodetree, 0); + + BIF_preview_changed(ID_MA); BIF_undo_push("Paste material settings"); scrarea_queue_winredraw(curarea); } @@ -261,11 +277,23 @@ void buttons_active_id(ID **id, ID **idfrom) if(G.buts->texfrom==0) { if(ob && ob->typetype) { + bNode *node= NULL; + ma= give_current_material(ob, ob->actcol); - *idfrom= (ID *)ma; - if(ma) { - mtex= ma->mtex[ ma->texact ]; - if(mtex) *id= (ID *)mtex->tex; + if(ma && ma->use_nodes) + node= editnode_get_active_idnode(ma->nodetree, ID_TE); + + if(node) { + *idfrom= NULL; + *id= node->id; + } + else { + ma= editnode_get_active_material(ma); + *idfrom= (ID *)ma; + if(ma) { + mtex= ma->mtex[ ma->texact ]; + if(mtex) *id= (ID *)mtex->tex; + } } } } diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index e0571e94e45..d3ef7ebb8f0 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -177,27 +177,20 @@ static void save_paint(char *name) { char str[FILE_MAXDIR+FILE_MAXFILE]; Image *ima = G.sima->image; - ImBuf *ibuf; if (ima && ima->ibuf) { BLI_strncpy(str, name, sizeof(str)); BLI_convertstringcode(str, G.sce, G.scene->r.cfra); - + if (saveover(str)) { - ibuf = IMB_dupImBuf(ima->ibuf); - - if (ibuf) { - if (BIF_write_ibuf(ibuf, str)) { - BLI_strncpy(ima->name, name, sizeof(ima->name)); - ima->ibuf->userflags &= ~IB_BITMAPDIRTY; - allqueue(REDRAWHEADERS, 0); - allqueue(REDRAWBUTSSHADING, 0); - } else { - error("Couldn't write image: %s", str); - } - - IMB_freeImBuf(ibuf); + if (BKE_write_ibuf(ima->ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality)) { + BLI_strncpy(ima->name, name, sizeof(ima->name)); + ima->ibuf->userflags &= ~IB_BITMAPDIRTY; + allqueue(REDRAWHEADERS, 0); + allqueue(REDRAWBUTSSHADING, 0); + } else { + error("Couldn't write image: %s", str); } } } @@ -335,12 +328,31 @@ void do_image_buttons(unsigned short event) if (ima) { strcpy(name, ima->name); if (ima->ibuf) { - char str[32]; // sufficient for message + char str[64]; save_image_filesel_str(str); + + if(G.scene->r.scemode & R_EXTENSION) + BKE_add_image_extension(name, G.scene->r.imtype); + activate_fileselect(FILE_SPECIAL, str, name, save_paint); } } break; + case B_SIMA_USE_ALPHA: + G.sima->flag &= ~(SI_SHOW_ALPHA|SI_SHOW_ZBUF); + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + break; + case B_SIMA_SHOW_ALPHA: + G.sima->flag &= ~(SI_USE_ALPHA|SI_SHOW_ZBUF); + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + break; + case B_SIMA_SHOW_ZBUF: + G.sima->flag &= ~(SI_SHOW_ALPHA|SI_USE_ALPHA); + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + break; } } @@ -445,6 +457,9 @@ static void do_image_viewmenu(void *arg, int event) G.sima->flag ^= SI_COORDFLOATS; allqueue(REDRAWIMAGE, 0); break; + case 11: /* Curves Panel... */ + add_blockhandler(curarea, IMAGE_HANDLER_CURVES, UI_PNL_UNSTOW); + break; } allqueue(REDRAWVIEW3D, 0); } @@ -458,8 +473,9 @@ static uiBlock *image_viewmenu(void *arg_unused) block= uiNewBlock(&curarea->uiblocks, "image_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin); uiBlockSetButmFunc(block, do_image_viewmenu, NULL); - uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "View Paint Tool...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Properties...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Paint Tool...|C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Show Curves Tool...", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, ""); if(G.sima->flag & SI_COORDFLOATS) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, ""); else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Display Normalized Coordinates|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, ""); @@ -702,8 +718,12 @@ static void do_image_imagemenu(void *arg, int event) if (ima) { strcpy(name, ima->name); if (ima->ibuf) { - char str[32]; // sufficient for message + char str[64]; save_image_filesel_str(str); + + if(G.scene->r.scemode & R_EXTENSION) + BKE_add_image_extension(name, G.scene->r.imtype); + activate_fileselect(FILE_SPECIAL, str, name, save_paint); } } @@ -1013,6 +1033,9 @@ static void do_image_uvsmenu(void *arg, int event) if(G.sima->flag & SI_LSCM_LIVE) G.sima->flag &= ~SI_LSCM_LIVE; else G.sima->flag |= SI_LSCM_LIVE; break; + case 12: + minimize_stretch_tface_uv(); + break; } } @@ -1047,6 +1070,7 @@ static uiBlock *image_uvsmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, ""); uiDefIconTextBlockBut(block, image_uvs_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, ""); @@ -1099,6 +1123,7 @@ void image_buttons(void) char naam[256]; /* This should not be a static var */ static int headerbuttons_packdummy; + extern short CurrentUnwrapper; headerbuttons_packdummy = 0; @@ -1154,7 +1179,7 @@ void image_buttons(void) /* other buttons: */ uiBlockSetEmboss(block, UI_EMBOSS); - xco= std_libbuttons(block, xco, 0, 0, NULL, B_SIMABROWSE, (ID *)G.sima->image, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0); + xco= std_libbuttons(block, xco, 0, 0, NULL, B_SIMABROWSE, ID_IM, 0, (ID *)G.sima->image, 0, &(G.sima->imanr), 0, 0, B_IMAGEDELETE, 0, 0); if (G.sima->image) { xco+= 8; @@ -1163,19 +1188,32 @@ void image_buttons(void) headerbuttons_packdummy = 1; } uiDefIconButBitI(block, TOG, 1, B_SIMAPACKIMA, ICON_PACKAGE, xco,0,XIC,YIC, &headerbuttons_packdummy, 0, 0, 0, 0, "Pack/Unpack this image"); - - xco+= XIC; - } + xco+= XIC+8; - xco+= 8; - - if (G.sima->image) { uiDefIconButBitS(block, TOG, SI_DRAWTOOL, B_SIMAGEPAINTTOOL, ICON_TPAINT_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Enables painting textures on the image with left mouse button"); xco+= XIC+8; + + uiBlockBeginAlign(block); + uiDefIconButBitS(block, TOG, SI_USE_ALPHA, B_SIMA_USE_ALPHA, ICON_TRANSP_HLT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws image with alpha"); + xco+= XIC; + uiDefIconButBitS(block, TOG, SI_SHOW_ALPHA, B_SIMA_SHOW_ALPHA, ICON_DOT, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws only alpha"); + xco+= XIC; + if(G.sima->image->ibuf) { + if(G.sima->image->ibuf->zbuf || G.sima->image->ibuf->zbuf_float) { + uiDefIconButBitS(block, TOG, SI_SHOW_ZBUF, B_SIMA_SHOW_ZBUF, ICON_SOLID, xco,0,XIC,YIC, &G.sima->flag, 0, 0, 0, 0, "Draws zbuffer values"); + xco+= XIC; + } + else G.sima->flag &= ~SI_SHOW_ZBUF; /* no confusing display for non-zbuf images */ + } + uiBlockEndAlign(block); + xco+= 8; } /* draw LOCK */ uiDefIconButS(block, ICONTOG, 0, ICON_UNLOCKED, xco,0,XIC,YIC, &(G.sima->lock), 0, 0, 0, 0, "Updates other affected window spaces automatically to reflect changes in real time"); + + xco += 2*XIC; + uiDefButS(block, MENU, B_NOP, "Unwrapper%t|Old LSCM%x0|New LSCM%x1",xco,0,85,YIC, &CurrentUnwrapper, 0, 0, 0, 0, "Unwrapper"); /* Always do this last */ curarea->headbutlen= xco+2*XIC; diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index f5e3b5d16d5..ce8d21612bd 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -43,6 +43,7 @@ #include #endif +#include "DNA_group_types.h" #include "DNA_ID.h" #include "DNA_image_types.h" #include "DNA_lamp_types.h" @@ -73,14 +74,17 @@ #include "BIF_toets.h" #include "BIF_toolbox.h" #include "BIF_usiblender.h" +#include "BIF_writeimage.h" #include "BIF_drawscene.h" #include "BKE_blender.h" +#include "BKE_depsgraph.h" #include "BKE_exotic.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_packedFile.h" #include "BKE_scene.h" #include "BKE_world.h" @@ -312,6 +316,9 @@ Scene *copy_scene(Scene *sce, int level) scen->toolsettings= MEM_dupallocN(sce->toolsettings); duplicatelist(&(scen->markers), &(sce->markers)); + duplicatelist(&(scen->r.layers), &(sce->r.layers)); + + scen->nodetree= ntreeCopyTree(sce->nodetree, 0); obase= sce->base.first; base= scen->base.first; @@ -471,7 +478,7 @@ void do_info_buttons(unsigned short event) set_scene(sce); } - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_TE); break; case B_INFODELSCE: @@ -762,7 +769,7 @@ static void do_info_filemenu(void *arg, int event) } break; case 6: /* save image */ - BIF_save_rendered_image(); + BIF_save_rendered_image_fs(); break; case 22: /* save runtime */ activate_fileselect(FILE_SPECIAL, "Save Runtime", "", write_runtime_check); @@ -1177,6 +1184,44 @@ static uiBlock *info_add_lampmenu(void *arg_unused) return block; } +static void do_info_add_groupmenu(void *arg, int event) +{ + Object *ob; + + add_object_draw(OB_EMPTY); + ob= OBACT; + + ob->dup_group= BLI_findlink(&G.main->group, event); + if(ob->dup_group) { + id_us_plus((ID *)ob->dup_group); + ob->transflag |= OB_DUPLIGROUP; + DAG_scene_sort(G.scene); + } +} + + +static uiBlock *info_add_groupmenu(void *arg_unused) +{ + uiBlock *block; + short yco= 0; + + Group *group; + int a; + int tot= BLI_countlist(&G.main->group); + + block= uiNewBlock(&curarea->uiblocks, "add_groupmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin); + uiBlockSetButmFunc(block, do_info_add_groupmenu, NULL); + + for(a=0, group= G.main->group.first; group; group= group->id.next, a++) { + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, group->id.name+2, 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, a, ""); + } + + uiBlockSetDirection(block, UI_RIGHT); + uiTextBoundsBlock(block, 50); + + return block; +} + void do_info_addmenu(void *arg, int event) { switch(event) { @@ -1212,6 +1257,9 @@ void do_info_addmenu(void *arg, int event) /* Lattice */ add_object_draw(OB_LATTICE); break; + case 10: + /* group instance not yet */ + break; default: break; } @@ -1237,6 +1285,10 @@ static uiBlock *info_addmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBlockBut(block, info_add_groupmenu, NULL, ICON_RIGHTARROW_THIN, "Group", 0, yco-=20, 120, 19, ""); + + uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Camera", 0, yco-=20, 120, 19, NULL, 0.0, 0.0, 1, 6, ""); uiDefIconTextBlockBut(block, info_add_lampmenu, NULL, ICON_RIGHTARROW_THIN, "Lamp", 0, yco-=20, 120, 19, ""); @@ -1505,12 +1557,12 @@ static uiBlock *info_rendermenu(void *arg_unused) uiBlockSetButmFunc(block, do_info_rendermenu, NULL); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Current Frame|F12", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Animation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Render Animation|Ctrl F12", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Render Buffer|F11", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Rendered Animation", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Rendered Animation|Ctrl F11", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -1826,12 +1878,12 @@ void info_buttons(void) uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), 8,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types."); /* STD SCREEN BUTTONS */ - xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCR, (ID *)G.curscreen, 0, &G.curscreen->screennr, 1, 1, B_INFODELSCR, 0, 0); + xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCR, ID_SCR, 0, (ID *)G.curscreen, 0, &G.curscreen->screennr, 1, 1, B_INFODELSCR, 0, 0); xco +=8; /* STD SCENE BUTTONS */ - xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCE, (ID *)G.scene, 0, &G.curscreen->scenenr, 1, 1, B_INFODELSCE, 0, 0); + xco= std_libbuttons(block, xco, 0, 0, NULL, B_INFOSCE, ID_SCE, 0, (ID *)G.scene, 0, &G.curscreen->scenenr, 1, 1, B_INFODELSCE, 0, 0); } else xco= 430; diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 79d4e6ca3f6..ea02e03b8bd 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -886,7 +886,7 @@ void do_ipo_buttons(short event) scrarea_queue_winredraw(curarea); break; case B_IPOBORDER: - val= get_border(&rect, 2); + val= get_border(&rect, 3); if(val) { mval[0]= rect.xmin; mval[1]= rect.ymin; @@ -1179,7 +1179,7 @@ void ipo_buttons(void) uiClearButLock(); - xco= std_libbuttons(block, (short)(xco+1.5*XIC), 0, B_IPOPIN, &G.sipo->pin, B_IPOBROWSE, (ID*)G.sipo->ipo, G.sipo->from, &(G.sipo->menunr), B_IPOALONE, B_IPOLOCAL, B_IPODELETE, 0, B_KEEPDATA); + xco= std_libbuttons(block, (short)(xco+1.5*XIC), 0, B_IPOPIN, &G.sipo->pin, B_IPOBROWSE, ID_IP, G.sipo->blocktype, (ID*)G.sipo->ipo, G.sipo->from, &(G.sipo->menunr), B_IPOALONE, B_IPOLOCAL, B_IPODELETE, 0, B_KEEPDATA); /* COPY PASTE */ xco-= XIC/2; diff --git a/source/blender/src/header_node.c b/source/blender/src/header_node.c new file mode 100644 index 00000000000..b1ee0043be6 --- /dev/null +++ b/source/blender/src/header_node.c @@ -0,0 +1,180 @@ +/** + * + * $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) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#include "DNA_ID.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_space_types.h" +#include "DNA_view2d_types.h" +#include "DNA_userdef_types.h" + +#include "BIF_gl.h" +#include "BIF_interface.h" +#include "BIF_previewrender.h" +#include "BIF_resources.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_toolbox.h" +#include "BIF_butspace.h" + +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_material.h" + +#include "BSE_headerbuttons.h" +#include "BSE_node.h" + +#include "blendef.h" +#include "butspace.h" +#include "mydevice.h" + +void do_node_buttons(ScrArea *sa, unsigned short event) +{ + SpaceNode *snode= sa->spacedata.first; + Material *ma; + + switch(event) { + case B_NODE_USEMAT: + ma= (Material *)snode->id; + if(ma) { + if(ma->use_nodes && ma->nodetree==NULL) { + node_shader_default(ma); + snode_set_context(snode); + } + BIF_preview_changed(ID_MA); + allqueue(REDRAWNODE, 0); + allqueue(REDRAWBUTSSHADING, 0); + } + break; + + case B_NODE_USESCENE: + if(G.scene->use_nodes) { + if(G.scene->nodetree==NULL) + node_composit_default(G.scene); + addqueue(curarea->win, UI_BUT_EVENT, B_NODE_TREE_EXEC); + } + snode_set_context(snode); + allqueue(REDRAWNODE, 0); + break; + } +} + + +void node_buttons(ScrArea *sa) +{ + SpaceNode *snode= sa->spacedata.first; + uiBlock *block; + short xco; + char name[256]; + + sprintf(name, "header %d", sa->headwin); + block= uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->headwin); + + if(area_is_active_area(sa)) uiBlockSetCol(block, TH_HEADER); + else uiBlockSetCol(block, TH_HEADERDESEL); + + sa->butspacetype= SPACE_NODE; + + xco = 8; + + uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, + windowtype_pup(), xco, 0, XIC+10, YIC, + &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, + "Displays Current Window Type"); + + xco += XIC + 14; + + uiBlockSetEmboss(block, UI_EMBOSSN); + if (sa->flag & HEADER_NO_PULLDOWN) { + uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, + ICON_DISCLOSURE_TRI_RIGHT, xco,2,XIC,YIC-2, + &(sa->flag), 0, 0, 0, 0, "Show pulldown menus"); + } + else { + uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, B_FLIPINFOMENU, + ICON_DISCLOSURE_TRI_DOWN, xco,2,XIC,YIC-2, + &(sa->flag), 0, 0, 0, 0, "Hide pulldown menus"); + } + xco+=XIC; + + if((sa->flag & HEADER_NO_PULLDOWN)==0) { + /* pull down menus */ + uiBlockSetEmboss(block, UI_EMBOSSP); + +// xmax= GetButStringLength("View"); +// uiDefPulldownBut(block, time_viewmenu, NULL, +// "View", xco, -2, xmax-3, 24, ""); +// xco+= xmax; + } + + uiBlockSetEmboss(block, UI_EMBOSS); + + /* main type choosing */ + uiBlockBeginAlign(block); + uiDefIconButI(block, ROW, B_REDR, ICON_MATERIAL_DEHLT, xco,2,XIC,YIC-2, + &(snode->treetype), 2, 0, 0, 0, "Material Nodes"); + xco+= XIC; + uiDefIconButI(block, ROW, B_REDR, ICON_IMAGE_DEHLT, xco,2,XIC,YIC-2, + &(snode->treetype), 2, 1, 0, 0, "Composit Nodes"); + xco+= 2*XIC; + uiBlockEndAlign(block); + + /* find and set the context */ + snode_set_context(snode); + + if(snode->treetype==NTREE_SHADER) { + if(snode->from) { + /* 0, NULL -> pin */ + xco= std_libbuttons(block, xco, 0, 0, NULL, B_MATBROWSE, ID_MA, 1, snode->id, snode->from, &(snode->menunr), + B_MATALONE, B_MATLOCAL, B_MATDELETE, B_AUTOMATNAME, B_KEEPDATA); + + if(snode->id) { + Material *ma= (Material *)snode->id; + uiDefButC(block, TOG, B_NODE_USEMAT, "Use Nodes", xco+5,0,70,19, &ma->use_nodes, 0.0f, 0.0f, 0, 0, ""); + xco+=80; + } + } + } + else if(snode->treetype==NTREE_COMPOSIT) { + uiDefButS(block, TOG, B_NODE_USESCENE, "Use Nodes", xco+5,0,70,19, &G.scene->use_nodes, 0.0f, 0.0f, 0, 0, ""); + } + + /* always as last */ + sa->headbutlen= xco+2*XIC; + + uiDrawBlock(block); +} diff --git a/source/blender/src/header_oops.c b/source/blender/src/header_oops.c index e7b168bbd64..f84cee782d7 100644 --- a/source/blender/src/header_oops.c +++ b/source/blender/src/header_oops.c @@ -1,20 +1,12 @@ /** - * header_oops.c oct-2003 - * - * Functions to draw the "OOPS Schematic" window header - * and handle user events sent to it. - * * $Id$ * - * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * ***** 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. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,11 +20,11 @@ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. * All rights reserved. * - * The Original Code is: all of this file. + * The Original Code is: not all of this file anymore. * - * Contributor(s): none yet. + * Contributor(s): Blender Foundation. * - * ***** END GPL/BL DUAL LICENSE BLOCK ***** + * ***** END GPL LICENSE BLOCK ***** */ #include @@ -485,7 +477,7 @@ void oops_buttons(void) } #endif else { - uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4", xco, 0, 100, 20, &soops->outlinevis, 0, 0, 0, 0, ""); } /* always do as last */ diff --git a/source/blender/src/header_script.c b/source/blender/src/header_script.c index 6838aea6882..cb1f89d465f 100644 --- a/source/blender/src/header_script.c +++ b/source/blender/src/header_script.c @@ -267,7 +267,7 @@ void script_buttons(void) /* STD SCRIPT BUTTONS */ xco += 2*XIC; - xco= std_libbuttons(block, xco, 0, 0, NULL, B_SCRIPTBROWSE, (ID*)sc->script, 0, &(sc->menunr), 0, 0, 0, 0, 0); + xco= std_libbuttons(block, xco, 0, 0, NULL, B_SCRIPTBROWSE, ID_SCRIPT, 0, (ID*)sc->script, 0, &(sc->menunr), 0, 0, 0, 0, 0); /* always as last */ curarea->headbutlen= xco+2*XIC; diff --git a/source/blender/src/header_sound.c b/source/blender/src/header_sound.c index d3a577075d6..fccbebe1350 100644 --- a/source/blender/src/header_sound.c +++ b/source/blender/src/header_sound.c @@ -281,7 +281,7 @@ void sound_buttons(void) } uiBlockSetEmboss(block, UI_EMBOSS); - xco= std_libbuttons(block, xco+8, 0, 0, NULL, B_SOUNDBROWSE, (ID *)G.ssound->sound, 0, &(G.ssound->sndnr), 1, 0, 0, 0, 0); + xco= std_libbuttons(block, xco+8, 0, 0, NULL, B_SOUNDBROWSE, ID_SO, 0, (ID *)G.ssound->sound, 0, &(G.ssound->sndnr), 1, 0, 0, 0, 0); if(G.ssound->sound) { bSound *sound= G.ssound->sound; diff --git a/source/blender/src/header_text.c b/source/blender/src/header_text.c index f78bcb54d37..9a6236bb3f7 100644 --- a/source/blender/src/header_text.c +++ b/source/blender/src/header_text.c @@ -624,7 +624,7 @@ void text_buttons(void) /* STD TEXT BUTTONS */ xco+= 2*XIC; - xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXTBROWSE, (ID*)st->text, 0, &(st->menunr), 0, 0, B_TEXTDELETE, 0, 0); + xco= std_libbuttons(block, xco, 0, 0, NULL, B_TEXTBROWSE, ID_TXT, 0, (ID*)st->text, 0, &(st->menunr), 0, 0, B_TEXTDELETE, 0, 0); /* if (st->text) { diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 32c5946b82a..e8598bd265f 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -745,7 +745,7 @@ void do_view3d_select_object_groupedmenu(void *arg, int event) case 2: /* Immediate Children */ case 3: /* Parent */ case 4: /* Objects on Shared Layers */ - select_group((short)event); + select_grouped((short)event); break; } allqueue(REDRAWVIEW3D, 0); @@ -859,6 +859,12 @@ void do_view3d_select_meshmenu(void *arg, int event) case 13: /* select non-triangles/quads */ select_faces_by_numverts(5); break; + case 14: /* select less */ + select_sharp_edges(); + break; + case 15: /* select less */ + select_linked_flat_faces(); + break; } allqueue(REDRAWVIEW3D, 0); @@ -887,6 +893,12 @@ static uiBlock *view3d_select_meshmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Non-Manifold|Ctrl Alt Shift M", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Sharp Edges|Ctrl Alt Shift S", + 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, + "Linked flat faces|Ctrl Alt Shift F", + 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -1776,6 +1788,7 @@ static void do_view3d_edit_object_copyattrmenu(void *arg, int event) case 23: case 24: case 25: + case 26: copy_attr((short)event); break; } @@ -1810,32 +1823,33 @@ static uiBlock *view3d_edit_object_copyattrmenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Constraints|Ctrl C, 22", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Object Constraints|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 22, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "NLA Strips|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 26, ""); if (ob) { if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_SURF) || (ob->type == OB_FONT) || (ob->type == OB_MBALL)) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Space|Ctrl C, 17", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Texture Space|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 17, ""); } if(ob->type == OB_FONT) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Font Settings|Ctrl C, 18", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel Settings|Ctrl C, 19", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Curve Resolution|Ctrl C, 20", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Font Settings|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel Settings|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Curve Resolution|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); } if(ob->type == OB_CURVE) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel Settings|Ctrl C, 19", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Curve Resolution|Ctrl C, 20", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel Settings|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 19, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Curve Resolution|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 25, ""); } if(ob->type==OB_MESH) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdiv|Ctrl C, 21", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Modifiers ...|Ctrl C, 24", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdiv|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 21, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Modifiers ...|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 24, ""); } if( give_parteff(ob) ) { - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Particle Settings|Ctrl C, 20", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Particle Settings|Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 20, ""); } } diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index c9383d2dded..8955794b755 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -150,6 +150,7 @@ #include "BSE_edit.h" #include "BSE_filesel.h" #include "BSE_headerbuttons.h" +#include "BSE_node.h" #include "BSE_view.h" #include "BSE_sequence.h" #include "BSE_editipo.h" @@ -208,6 +209,7 @@ char *windowtype_pup(void) strcat(string, "|User Preferences %x7"); //213 strcat(string, "|Outliner %x3"); //232 strcat(string, "|Buttons Window %x4"); //251 + strcat(string, "|Node Editor %x16"); strcat(string, "|%l"); //254 @@ -232,15 +234,13 @@ int GetButStringLength(char *str) { /* ********************** GLOBAL ****************************** */ int std_libbuttons(uiBlock *block, short xco, short yco, - int pin, short *pinpoin, int browse, ID *id, + int pin, short *pinpoin, int browse, short id_code, short special, ID *id, ID *parid, short *menupoin, int users, int lib, int del, int autobut, int keepbut) { ListBase *lb; - Object *ob; - Ipo *ipo; uiBut *but; - int len, idwasnul=0, idtype, oldcol, add_addbutton=0; + int len, oldcol, add_addbutton=0; char *str=NULL, str1[10]; uiBlockBeginAlign(block); @@ -250,141 +250,47 @@ int std_libbuttons(uiBlock *block, short xco, short yco, uiDefIconButS(block, ICONTOG, pin, ICON_PIN_DEHLT, xco,yco,XIC,YIC, pinpoin, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected"); xco+= XIC; } + /* browse menu */ if(browse) { - if(id==0) { - idwasnul= 1; - /* only the browse button */ - ob= OBACT; - if(curarea->spacetype==SPACE_IMAGE) { - id= G.main->image.first; - } - else if(curarea->spacetype==SPACE_SOUND) { - id= G.main->sound.first; - } - else if(curarea->spacetype==SPACE_ACTION) { - if(ob) id= G.main->action.first; - } - else if(curarea->spacetype==SPACE_NLA) { - id= NULL; - } - else if(curarea->spacetype==SPACE_IPO) { - id= G.main->ipo.first; - - /* test for ipotype */ - while(id) { - ipo= (Ipo *)id; - if(G.sipo->blocktype==ipo->blocktype) break; - id= id->next; - } - if(ob==NULL) { - if(G.sipo->blocktype!=ID_SEQ && G.sipo->blocktype!=ID_WO) { - id= NULL; - idwasnul= 0; - } - } - } - else if(curarea->spacetype==SPACE_BUTS) { - if(browse==B_WORLDBROWSE) { - id= G.main->world.first; - } - else if(ob && ob->type && (ob->type<=OB_LAMP)) { - if(G.buts->mainb==CONTEXT_SHADING) { - int tab= G.buts->tab[CONTEXT_SHADING]; - - if(tab==TAB_SHADING_MAT) id= G.main->mat.first; - else if(tab==TAB_SHADING_TEX) id= G.main->tex.first; - - add_addbutton= 1; - } - } - } - else if(curarea->spacetype==SPACE_TEXT) { - id= G.main->text.first; - } - else if(curarea->spacetype==SPACE_SCRIPT) { - id= G.main->script.first; - } - } - if(id) { - char *extrastr= NULL; - - idtype= GS(id->name); - lb= wich_libbase(G.main, GS(id->name)); - - if(idwasnul) id= NULL; - else if(id->us>1) uiBlockSetCol(block, TH_BUT_SETTING1); - - if (pin && *pinpoin) { - uiBlockSetCol(block, TH_BUT_SETTING2); - } - - if ELEM7( idtype, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC) extrastr= "ADD NEW %x 32767"; - else if (idtype==ID_TXT) extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767"; - else if (idtype==ID_SO) extrastr= "OPEN NEW %x 32766"; - - uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); - if( idtype==ID_SCE || idtype==ID_SCR ) uiClearButLock(); - - if(curarea->spacetype==SPACE_BUTS) - uiSetButLock(idtype!=ID_SCR && G.obedit!=0 && G.buts->mainb==CONTEXT_EDITING, NULL); - - if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); - - if (lb) { - if( idtype==ID_IP) - IPOnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin, G.sipo->blocktype); - else - IDnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin); - } - - uiDefButS(block, MENU, browse, str, xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses existing choices or adds NEW"); - - uiClearButLock(); + char *extrastr= NULL; - MEM_freeN(str); - } - else if(curarea->spacetype==SPACE_BUTS) { - if(G.buts->mainb==CONTEXT_SHADING) { - uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); - if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); - uiDefButS(block, MENU, browse, "ADD NEW %x 32767",xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - uiClearButLock(); - } else if (G.buts->mainb == CONTEXT_SCENE) { - if(G.buts->tab[CONTEXT_SCENE]== TAB_SCENE_SOUND) { - uiDefButS(block, MENU, browse, "OPEN NEW %x 32766",xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - } - } - } - else if(curarea->spacetype==SPACE_TEXT) { - uiDefButS(block, MENU, browse, "OPEN NEW %x 32766 | ADD NEW %x 32767", xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - } - else if(curarea->spacetype==SPACE_SCRIPT) { - uiDefButS(block, MENU, browse, "No running scripts", xco, yco, XIC, YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - } - else if(curarea->spacetype==SPACE_SOUND) { - uiDefButS(block, MENU, browse, "OPEN NEW %x 32766",xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - } - else if(curarea->spacetype==SPACE_ACTION) { - uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); - if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + if(ELEM(id_code, ID_MA, ID_TE)) add_addbutton= 1; + + lb= wich_libbase(G.main, id_code); + + if(id && id->us>1) uiBlockSetCol(block, TH_BUT_SETTING1); - uiDefButS(block, MENU, browse, "ADD NEW %x 32767", xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - uiClearButLock(); - } - else if(curarea->spacetype==SPACE_IPO) { - if(idwasnul) { - uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); - if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); - - uiDefButS(block, MENU, browse, "ADD NEW %x 32767", xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses Datablock"); - uiClearButLock(); - } + if (pin && *pinpoin) { + uiBlockSetCol(block, TH_BUT_SETTING2); } + if ELEM7( id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC) extrastr= "ADD NEW %x 32767"; + else if (id_code==ID_TXT) extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767"; + else if (id_code==ID_SO) extrastr= "OPEN NEW %x 32766"; + + uiSetButLock(G.scene->id.lib!=0, "Can't edit library data"); + if( id_code==ID_SCE || id_code==ID_SCR ) uiClearButLock(); + + if(curarea->spacetype==SPACE_BUTS) + uiSetButLock(id_code!=ID_SCR && G.obedit!=0 && G.buts->mainb==CONTEXT_EDITING, NULL); + + if(parid) uiSetButLock(parid->lib!=0, "Can't edit library data"); + + if (lb) { + if( id_code==ID_IP) + IPOnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin, G.sipo->blocktype); + else + IDnames_to_pupstring(&str, NULL, extrastr, lb, id, menupoin); + } + + uiDefButS(block, MENU, browse, str, xco,yco,XIC,YIC, menupoin, 0, 0, 0, 0, "Browses existing choices or adds NEW"); xco+= XIC; + + uiClearButLock(); + + MEM_freeN(str); } - uiBlockSetCol(block, oldcol); if(id) { /* text button with name */ @@ -400,12 +306,20 @@ int std_libbuttons(uiBlock *block, short xco, short yco, uiSetButLock(id->lib!=0, "Can't edit library data"); - str1[0]= id->name[0]; - str1[1]= id->name[1]; - str1[2]= ':'; - str1[3]= 0; - if(strcmp(str1, "SC:")==0) strcpy(str1, "SCE:"); - else if(strcmp(str1, "SR:")==0) strcpy(str1, "SCR:"); + if(GS(id->name)==ID_SCE) strcpy(str1, "SCE:"); + else if(GS(id->name)==ID_SCE) strcpy(str1, "SCR:"); + else if(GS(id->name)==ID_MA) { + if( ((Material *)id)->use_nodes ) + strcpy(str1, "NT:"); + else + strcpy(str1, "MA:"); + } + else { + str1[0]= id->name[0]; + str1[1]= id->name[1]; + str1[2]= ':'; + str1[3]= 0; + } if( GS(id->name)==ID_IP) len= 110; else if(yco) len= 140; // comes from button panel @@ -498,6 +412,8 @@ static void do_update_for_newframe(int mute, int events) scene_update_for_newframe(G.scene, screen_view3d_layers()); /* BKE_scene.h */ if ( (CFRA>1) && (!mute) && (G.scene->audio.flag & AUDIO_SCRUB)) audiostream_scrub( CFRA ); + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); + } void update_for_newframe(void) @@ -781,7 +697,8 @@ void do_global_buttons(unsigned short event) BIF_undo_push("Browse Material"); allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); - BIF_preview_changed(G.buts); + allqueue(REDRAWNODE, 0); + BIF_preview_changed(ID_MA); } } @@ -798,7 +715,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } } break; @@ -809,6 +726,7 @@ void do_global_buttons(unsigned short event) else { if(G.buts->texfrom==0) { /* from mat */ ma= give_current_material(ob, ob->actcol); + ma= editnode_get_active_material(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) { @@ -817,7 +735,7 @@ void do_global_buttons(unsigned short event) ma->mtex[ ma->texact ]= NULL; allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } } } @@ -831,7 +749,7 @@ void do_global_buttons(unsigned short event) wrld->mtex[ wrld->texact ]= NULL; allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_WO); } } } @@ -845,7 +763,7 @@ void do_global_buttons(unsigned short event) la->mtex[ la->texact ]= NULL; allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_LA); } } } @@ -861,6 +779,7 @@ void do_global_buttons(unsigned short event) if(event==B_EXTEXBROWSE) { id= NULL; ma= give_current_material(ob, ob->actcol); + ma= editnode_get_active_material(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) id= (ID *)mtex->tex; @@ -879,6 +798,7 @@ void do_global_buttons(unsigned short event) id= NULL; ma= give_current_material(ob, ob->actcol); + ma= editnode_get_active_material(ma); if(ma) { mtex= ma->mtex[ ma->texact ]; if(mtex) id= (ID *)mtex->tex; @@ -909,7 +829,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_MA); } } break; @@ -1097,7 +1017,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_WO); } break; case B_WORLDDELETE: @@ -1165,7 +1085,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_WO); } } break; @@ -1205,7 +1125,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_LA); } break; @@ -1262,7 +1182,7 @@ void do_global_buttons(unsigned short event) allqueue(REDRAWBUTSSHADING, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWOOPS, 0); - BIF_preview_changed(G.buts); + BIF_preview_changed(ID_LA); } } break; @@ -1522,6 +1442,8 @@ void do_global_buttons(unsigned short event) id= (ID *)G.buts->lockpoin; } else if(curarea->spacetype==SPACE_IPO) { id = (ID *)G.sipo->ipo; + } else if(curarea->spacetype==SPACE_NODE) { + id = ((SpaceNode *)curarea->spacedata.first)->id; } /* similar for other spacetypes ? */ if (id) { if( id->flag & LIB_FAKEUSER) { @@ -1790,6 +1712,7 @@ void do_global_buttons2(short event) if(G.buts->texfrom==0) { /* from mat */ if(ob==0) return; ma= give_current_material(ob, ob->actcol); + ma= editnode_get_active_material(ma); if(ma && ma->id.lib==0) { mtex= ma->mtex[ ma->texact ]; if(mtex->tex && mtex->tex->id.us>1) { @@ -1830,6 +1753,7 @@ void do_global_buttons2(short event) if(G.buts->texfrom==0) { /* from mat */ if(ob==0) return; ma= give_current_material(ob, ob->actcol); + ma= editnode_get_active_material(ma); if(ma && ma->id.lib==0) { mtex= ma->mtex[ ma->texact ]; if(mtex->tex && mtex->tex->id.lib) { @@ -1968,7 +1892,8 @@ void do_headerbuttons(short event) else if(event<700) do_sound_buttons(event); else if(event<750) do_action_buttons(event); else if(event<800) do_time_buttons(curarea, event); - else if(event<900) do_nla_buttons(event); + else if(event<850) do_nla_buttons(event); + else if(event<900) do_node_buttons(curarea, event); else if(event>=REDRAWVIEW3D) allqueue(event, 0); } diff --git a/source/blender/src/imasel.c b/source/blender/src/imasel.c index c39fe83954e..6c232ea6464 100644 --- a/source/blender/src/imasel.c +++ b/source/blender/src/imasel.c @@ -34,10 +34,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #ifndef WIN32 #include #else @@ -538,7 +534,7 @@ void get_next_image(SpaceImaSel *simasel) /* the whole cmap system is wacko */ if (G.order==B_ENDIAN) - IMB_convert_rgba_to_abgr(ima->dw*ima->dh, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); ibuf->mincol = 0; ibuf->maxcol = 256; @@ -555,7 +551,7 @@ void get_next_image(SpaceImaSel *simasel) longtochar(ima->pict_rect, ibuf->rect, size); IMB_applycmap(ibuf); - IMB_convert_rgba_to_abgr(size, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); if (ima->pict) IMB_freeImBuf(ima->pict); ima->pict = ibuf; @@ -797,7 +793,7 @@ void get_pib_file(SpaceImaSel *simasel) ima->pict->cmap = simasel->cmap->cmap; ima->pict->maxcol = 256; IMB_applycmap(ima->pict); - IMB_convert_rgba_to_abgr(size, ima->pict->rect); + IMB_convert_rgba_to_abgr(ima->pict); } ima->selected = 0; ima->selectable = 0; diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index 2b50cb1cf8e..3d534744ed3 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -64,16 +64,20 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "DNA_color_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_vec_types.h" #include "DNA_object_types.h" +#include "DNA_texture_types.h" #include "DNA_vfont_types.h" #include "BKE_blender.h" +#include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_library.h" +#include "BKE_texture.h" #include "BKE_utildefines.h" #include "BIF_gl.h" @@ -88,7 +92,9 @@ #include "BIF_glutil.h" #include "BIF_editfont.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_butspace.h" +#include "BIF_previewrender.h" #include "BSE_view.h" @@ -117,7 +123,6 @@ uiBut *UIbuttip; /* ************* PROTOTYPES ***************** */ static void ui_set_but_val(uiBut *but, double value); -static void ui_set_ftf_font(uiBlock *block); static void ui_do_but_tip(uiBut *buttip); /* ****************************** */ @@ -153,6 +158,24 @@ void ui_graphics_to_window(int win, float *x, float *y) /* for rectwrite */ *y= ((float)sy) + ((float)getsizey)*(0.5+ 0.5*(gx*UIwinmat[0][1]+ gy*UIwinmat[1][1]+ UIwinmat[3][1])); } +void ui_graphics_to_window_rct(int win, rctf *graph, rcti *winr) +{ + float gx, gy; + int sx, sy; + int getsizex, getsizey; + + bwin_getsize(win, &getsizex, &getsizey); + bwin_getsuborigin(win, &sx, &sy); + + gx= graph->xmin; + gy= graph->ymin; + winr->xmin= (int)((float)sx) + ((float)getsizex)*(0.5+ 0.5*(gx*UIwinmat[0][0]+ gy*UIwinmat[1][0]+ UIwinmat[3][0])); + winr->ymin= (int)((float)sy) + ((float)getsizey)*(0.5+ 0.5*(gx*UIwinmat[0][1]+ gy*UIwinmat[1][1]+ UIwinmat[3][1])); + gx= graph->xmax; + gy= graph->ymax; + winr->xmax= (int)((float)sx) + ((float)getsizex)*(0.5+ 0.5*(gx*UIwinmat[0][0]+ gy*UIwinmat[1][0]+ UIwinmat[3][0])); + winr->ymax= (int)((float)sy) + ((float)getsizey)*(0.5+ 0.5*(gx*UIwinmat[0][1]+ gy*UIwinmat[1][1]+ UIwinmat[3][1])); +} void ui_window_to_graphics(int win, float *x, float *y) /* for mouse cursor */ @@ -600,6 +623,7 @@ static void ui_positionblock(uiBlock *block, uiBut *but) /* position block relative to but */ uiBut *bt; rctf butrct; + float aspect; int xsize, ysize, xof=0, yof=0, centre; short dir1= 0, dir2=0; @@ -634,7 +658,8 @@ static void ui_positionblock(uiBlock *block, uiBut *but) block->minx= block->miny= 0; block->maxx= block->maxy= 20; } - + + aspect= (float)(block->maxx - block->minx + 4); ui_graphics_to_window(block->win, &block->minx, &block->miny); ui_graphics_to_window(block->win, &block->maxx, &block->maxy); @@ -643,6 +668,7 @@ static void ui_positionblock(uiBlock *block, uiBut *but) xsize= block->maxx - block->minx+4; // 4 for shadow ysize= block->maxy - block->miny+4; + aspect/= (float)xsize; if(but) { short left=0, right=0, top=0, down=0; @@ -738,8 +764,8 @@ static void ui_positionblock(uiBlock *block, uiBut *but) } /* apply */ - bt= block->buttons.first; - while(bt) { + + for(bt= block->buttons.first; bt; bt= bt->next) { ui_graphics_to_window(block->win, &bt->x1, &bt->y1); ui_graphics_to_window(block->win, &bt->x2, &bt->y2); @@ -752,8 +778,6 @@ static void ui_positionblock(uiBlock *block, uiBut *but) bt->aspect= 1.0; // ui_check_but recalculates drawstring size in pixels ui_check_but(bt); - - bt= bt->next; } block->minx += xof; @@ -907,6 +931,9 @@ void uiDrawBlock(uiBlock *block) uiBut *but; short testmouse=0, mouse[2]; + /* we set this only once */ + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + /* handle pending stuff */ if(block->autofill) ui_autofill(block); if(block->minx==0.0 && block->maxx==0.0) uiBoundsBlock(block, 0); @@ -928,7 +955,7 @@ void uiDrawBlock(uiBlock *block) if(block->panel) ui_draw_panel(block); } - if(block->drawextra) block->drawextra(); + if(block->drawextra) block->drawextra(curarea, block); for (but= block->buttons.first; but; but= but->next) { @@ -1131,6 +1158,9 @@ static int ui_do_but_MENU(uiBut *but) while (rows*columnsnitems) rows++; + /* prevent scaling up of pupmenu */ + if (but->aspect < 1.0f) but->aspect = 1.0f; + /* size and location */ if(md->title) width= 1.5*but->aspect*strlen(md->title)+BIF_GetStringWidth(block->curfont, md->title, (U.transopts & USER_TR_MENUS)); @@ -1139,6 +1169,7 @@ static int ui_do_but_MENU(uiBut *but) for(a=0; anitems; a++) { xmax= but->aspect*BIF_GetStringWidth(block->curfont, md->items[a].str, (U.transopts & USER_TR_MENUS)); + if ( md->items[a].icon) xmax += 20*but->aspect; if(xmax>width) width= xmax; } @@ -1194,7 +1225,7 @@ static int ui_do_but_MENU(uiBut *but) } else if(md->items[md->nitems-a-1].icon) { uiBut *bt= uiDefIconTextBut(block, BUTM|but->pointype, but->retval, md->items[md->nitems-a-1].icon ,md->items[md->nitems-a-1].str, x1, y1,(short)(width-(rows>1)), (short)(boxh-1), but->poin, (float) md->items[md->nitems-a-1].retval, 0.0, 0, 0, ""); - if(active==a) bt->flag |= UI_ACTIVE; + if(active==a) bt->flag |= UI_ACTIVE; } else { uiBut *bt= uiDefBut(block, BUTM|but->pointype, but->retval, md->items[md->nitems-a-1].str, x1, y1,(short)(width-(rows>1)), (short)(boxh-1), but->poin, (float) md->items[md->nitems-a-1].retval, 0.0, 0, 0, ""); @@ -1956,7 +1987,7 @@ static int ui_do_but_NUM(uiBut *but) { double value; float deler, fstart, f, tempf; - int lvalue, temp; /* , firsttime=1; */ + int lvalue, temp, orig_x; /* , firsttime=1; */ short retval=0, qual, sx, mval[2], pos=0; but->flag |= UI_SELECT; @@ -1967,6 +1998,7 @@ static int ui_do_but_NUM(uiBut *but) value= ui_get_but_val(but); sx= mval[0]; + orig_x = sx; /* Store so we can scale the rate of change by the dist the mouse is from its original xlocation */ fstart= (value - but->min)/(but->max-but->min); f= fstart; @@ -1982,21 +2014,30 @@ static int ui_do_but_NUM(uiBut *but) while (get_mbut() & L_MOUSE) { qual= get_qual(); + uiGetMouse(mywinget(), mval); + deler= 500; if( but->pointype!=FLO ) { if( (but->max-but->min)<100 ) deler= 200.0; if( (but->max-but->min)<25 ) deler= 50.0; - } + if(qual & LR_SHIFTKEY) deler*= 10.0; if(qual & LR_ALTKEY) deler*= 20.0; - - uiGetMouse(mywinget(), mval); if(mval[0] != sx) { - - f+= ((float)(mval[0]-sx))/deler; + if( but->pointype==FLO && but->max-but->min > 11) { + /* non linear change in mouse input- good for high precicsion */ + f+= (((float)(mval[0]-sx))/deler) * (fabs(orig_x-mval[0])*0.002); + } else if ( but->pointype!=FLO && but->max-but->min > 129) { /* only scale large int buttons */ + /* non linear change in mouse input- good for high precicsionm ints need less fine tuning */ + f+= (((float)(mval[0]-sx))/deler) * (fabs(orig_x-mval[0])*0.004); + } else { + /*no scaling */ + f+= ((float)(mval[0]-sx))/deler ; + } + if(f>1.0) f= 1.0; if(f<0.0) f= 0.0; sx= mval[0]; @@ -2451,7 +2492,7 @@ static int ui_do_but_NUMSLI(uiBut *but) } /* event denotes if we make first item active or not */ -static int ui_do_but_BLOCK(uiBut *but, int event) +static uiBlock *ui_do_but_BLOCK(uiBut *but, int event) { uiBlock *block; uiBut *bt; @@ -2492,7 +2533,10 @@ static int ui_do_but_BLOCK(uiBut *but, int event) but->flag &= ~UI_SELECT; uibut_do_func(but); - return 0; + if(but->retval) + addqueue(curarea->win, UI_BUT_EVENT, (short)but->retval); + + return block; } static int ui_do_but_BUTM(uiBut *but) @@ -2508,7 +2552,6 @@ static int ui_do_but_BUTM(uiBut *but) static int ui_do_but_LABEL(uiBut *but) { - uibut_do_func(but); return but->retval; } @@ -2748,7 +2791,7 @@ static void update_picker_hex(uiBlock *block, float *rgb) } } -static void update_picker_buts_hsv(uiBlock *block, float *hsv) +static void update_picker_buts_hsv(uiBlock *block, float *hsv, char *poin) { uiBut *bt; float r, g, b; @@ -2761,34 +2804,36 @@ static void update_picker_buts_hsv(uiBlock *block, float *hsv) update_picker_hex(block, rgb); for(bt= block->buttons.first; bt; bt= bt->next) { - if(bt->type==HSVCUBE) { - VECCOPY(bt->hsv, hsv); - ui_set_but_hsv(bt); - } - else if(bt->str[1]==' ') { - if(bt->str[0]=='R') { - ui_set_but_val(bt, r); - ui_check_but(bt); + if(bt->poin == poin) { + if(bt->type==HSVCUBE) { + VECCOPY(bt->hsv, hsv); + ui_set_but_hsv(bt); } - else if(bt->str[0]=='G') { - ui_set_but_val(bt, g); - ui_check_but(bt); - } - else if(bt->str[0]=='B') { - ui_set_but_val(bt, b); - ui_check_but(bt); - } - else if(bt->str[0]=='H') { - ui_set_but_val(bt, hsv[0]); - ui_check_but(bt); - } - else if(bt->str[0]=='S') { - ui_set_but_val(bt, hsv[1]); - ui_check_but(bt); - } - else if(bt->str[0]=='V') { - ui_set_but_val(bt, hsv[2]); - ui_check_but(bt); + else if(bt->str[1]==' ') { + if(bt->str[0]=='R') { + ui_set_but_val(bt, r); + ui_check_but(bt); + } + else if(bt->str[0]=='G') { + ui_set_but_val(bt, g); + ui_check_but(bt); + } + else if(bt->str[0]=='B') { + ui_set_but_val(bt, b); + ui_check_but(bt); + } + else if(bt->str[0]=='H') { + ui_set_but_val(bt, hsv[0]); + ui_check_but(bt); + } + else if(bt->str[0]=='S') { + ui_set_but_val(bt, hsv[1]); + ui_check_but(bt); + } + else if(bt->str[0]=='V') { + ui_set_but_val(bt, hsv[2]); + ui_check_but(bt); + } } } } @@ -2862,7 +2907,7 @@ static void do_palette_cb(void *bt1, void *col1) } rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2); - update_picker_buts_hsv(but1->block, hsv); + update_picker_buts_hsv(but1->block, hsv, but1->poin); update_picker_hex(but1->block, col); for (but= but1->block->buttons.first; but; but= but->next) { @@ -2889,7 +2934,7 @@ static void do_palette1_cb(void *bt1, void *hsv1) rgb_to_hsv(fp[0], fp[1], fp[2], hsv, hsv+1, hsv+2); } - update_picker_buts_hsv(but1->block, hsv); + update_picker_buts_hsv(but1->block, hsv, but1->poin); if (fp) update_picker_hex(but1->block, fp); for (but= but1->block->buttons.first; but; but= but->next) { @@ -3028,6 +3073,7 @@ static int ui_do_but_COL(uiBut *but) if(but->pointype==CHA) ui_set_but_vectorf(but, colstore); + uibut_do_func(but); return but->retval; } @@ -3079,7 +3125,7 @@ static int ui_do_but_HSVCUBE(uiBut *but) ui_set_but_hsv(but); // converts to rgb // update button values and strings - update_picker_buts_hsv(but->block, but->hsv); + update_picker_buts_hsv(but->block, but->hsv, but->poin); // update_picker_buts_hex(but->block, but->hsv); /* we redraw the entire block */ @@ -3143,6 +3189,356 @@ static int ui_do_but_CHARTAB(uiBut *but) #endif +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 do_colorband_evt(ColorBand *coba) +{ + int a; + + if(coba==NULL) return; + + 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) { + if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); /* button cur */ + coba->cur= a; + break; + } + } +} + +static int ui_do_but_COLORBAND(uiBut *but) +{ + ColorBand *coba= (ColorBand *)but->poin; + CBData *cbd; + float dx, width= but->x2-but->x1; + int a; + int mindist= 12, xco; + short mval[2], mvalo[2]; + + uiGetMouse(mywinget(), mvalo); + + if(G.qual & LR_CTRLKEY) { + /* insert new key on mouse location */ + if(coba->tot < MAXCOLORBAND-1) { + float pos= ((float)(mvalo[0] - but->x1))/width; + float col[4]; + + do_colorband(coba, pos, col); /* executes it */ + + coba->tot++; + coba->cur= coba->tot-1; + + coba->data[coba->cur].r= col[0]; + coba->data[coba->cur].g= col[1]; + coba->data[coba->cur].b= col[2]; + coba->data[coba->cur].a= col[3]; + coba->data[coba->cur].pos= pos; + + do_colorband_evt(coba); + } + } + else { + + /* first, activate new key when mouse is close */ + for(a=0, cbd= coba->data; atot; a++, cbd++) { + xco= but->x1 + (cbd->pos*width); + xco= ABS(xco-mvalo[0]); + if(a==coba->cur) xco+= 5; // selected one disadvantage + if(xcocur= a; + mindist= xco; + } + } + + cbd= coba->data + coba->cur; + + while(get_mbut() & L_MOUSE) { + uiGetMouse(mywinget(), mval); + if(mval[0]!=mvalo[0]) { + dx= mval[0]-mvalo[0]; + dx/= width; + cbd->pos+= dx; + CLAMP(cbd->pos, 0.0, 1.0); + + ui_draw_but(but); + ui_block_flush_back(but->block); + + do_colorband_evt(coba); + cbd= coba->data + coba->cur; /* because qsort */ + + mvalo[0]= mval[0]; + } + BIF_wait_for_statechange(); + } + } + + return but->retval; +} + +/* button is presumed square */ +/* if mouse moves outside of sphere, it does negative normal */ +static int ui_do_but_NORMAL(uiBut *but) +{ + float dx, dy, rad, radsq, mrad, *fp= (float *)but->poin; + int firsttime=1; + short mval[2], mvalo[2], mvals[2], mvaldx, mvaldy; + + rad= (but->x2 - but->x1); + radsq= rad*rad; + + if(fp[2]>0.0f) { + mvaldx= (rad*fp[0]); + mvaldy= (rad*fp[1]); + } + else if(fp[2]> -1.0f) { + mrad= rad/sqrt(fp[0]*fp[0] + fp[1]*fp[1]); + + mvaldx= 2.0f*mrad*fp[0] - (rad*fp[0]); + mvaldy= 2.0f*mrad*fp[1] - (rad*fp[1]); + } + else mvaldx= mvaldy= 0; + + uiGetMouse(mywinget(), mvalo); + mvals[0]= mvalo[0]; + mvals[1]= mvalo[1]; + + while(get_mbut() & L_MOUSE) { + + uiGetMouse(mywinget(), mval); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || firsttime) { + firsttime= 0; + + dx= (float)(mval[0]+mvaldx-mvals[0]); + dy= (float)(mval[1]+mvaldy-mvals[1]); + + mrad= dx*dx+dy*dy; + if(mrad < radsq) { /* inner circle */ + fp[0]= dx; + fp[1]= dy; + fp[2]= sqrt( radsq-dx*dx-dy*dy ); + } + else { /* outer circle */ + + mrad= rad/sqrt(mrad); // veclen + + dx*= (2.0f*mrad - 1.0f); + dy*= (2.0f*mrad - 1.0f); + + mrad= dx*dx+dy*dy; + if(mrad < radsq) { + fp[0]= dx; + fp[1]= dy; + fp[2]= -sqrt( radsq-dx*dx-dy*dy ); + } + } + Normalise(fp); + + ui_draw_but(but); + ui_block_flush_back(but->block); + + mvalo[0]= mval[0]; + mvalo[1]= mval[1]; + } + BIF_wait_for_statechange(); + } + + return but->retval; +} + +static int ui_do_but_CURVE(uiBut *but) +{ + CurveMapping *cumap= (CurveMapping *)but->poin; + CurveMap *cuma= cumap->cm+cumap->cur; + CurveMapPoint *cmp= cuma->curve; + float fx, fy, zoomx, zoomy, offsx, offsy; + float dist, mindist= 200.0f; // 14 pixels radius + int a, sel= -1, retval= but->retval; + short mval[2], mvalo[2]; + + uiGetMouse(mywinget(), mval); + + /* calculate offset and zoom */ + zoomx= (but->x2-but->x1)/(cumap->curr.xmax-cumap->curr.xmin); + zoomy= (but->y2-but->y1)/(cumap->curr.ymax-cumap->curr.ymin); + offsx= cumap->curr.xmin; + offsy= cumap->curr.ymin; + + if(G.qual & LR_CTRLKEY) { + + fx= ((float)mval[0] - but->x1)/zoomx + offsx; + fy= ((float)mval[1] - but->y1)/zoomy + offsy; + + curvemap_insert(cuma, fx, fy); + curvemapping_changed(cumap, 0); + + ui_draw_but(but); + ui_block_flush_back(but->block); + } + + + /* check for selecting of a point */ + cmp= cuma->curve; /* ctrl adds point, new malloc */ + for(a=0; atotpoint; a++) { + fx= but->x1 + zoomx*(cmp[a].x-offsx); + fy= but->y1 + zoomy*(cmp[a].y-offsy); + dist= (fx-mval[0])*(fx-mval[0]) + (fy-mval[1])*(fy-mval[1]); + if(dist < mindist) { + sel= a; + mindist= dist; + } + } + + if (sel == -1) { + /* if the click didn't select anything, check if it's clicked on the + * curve itself, and if so, add a point */ + fx= ((float)mval[0] - but->x1)/zoomx + offsx; + fy= ((float)mval[1] - but->y1)/zoomy + offsy; + + cmp= cuma->table; + + /* loop through the curve segment table and find what's near the mouse. + * 0.05 is kinda arbitrary, but seems to be what works nicely. */ + for(a=0; a<=CM_TABLE; a++) { + if ( ( fabs(fx - cmp[a].x) < (0.05) ) && ( fabs(fy - cmp[a].y) < (0.05) ) ) { + + curvemap_insert(cuma, fx, fy); + curvemapping_changed(cumap, 0); + + ui_draw_but(but); + ui_block_flush_back(but->block); + + /* reset cmp back to the curve points again, rather than drawing segments */ + cmp= cuma->curve; + + /* find newly added point and make it 'sel' */ + for(a=0; atotpoint; a++) { + if (cmp[a].x == fx) sel = a; + } + + break; + } + } + } + + /* ok, we move a point */ + if(sel!= -1) { + int moved_point; + int moved_mouse= 0; + + /* deselect all if this one is deselect. except if we hold shift */ + if((G.qual & LR_SHIFTKEY)==0 && (cmp[sel].flag & SELECT)==0) + for(a=0; atotpoint; a++) + cmp[a].flag &= ~SELECT; + cmp[sel].flag |= SELECT; + + /* draw to show select updates */ + ui_draw_but(but); + ui_block_flush_back(but->block); + + /* while move mouse, do move points around */ + while(get_mbut() & L_MOUSE) { + + uiGetMouse(mywinget(), mvalo); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + moved_mouse= 1; /* for selection */ + moved_point= 0; /* for ctrl grid, can't use orig coords because of sorting */ + + fx= (mvalo[0]-mval[0])/zoomx; + fy= (mvalo[1]-mval[1])/zoomy; + for(a=0; atotpoint; a++) { + if(cmp[a].flag & SELECT) { + float origx= cmp[a].x, origy= cmp[a].y; + cmp[a].x+= fx; + cmp[a].y+= fy; + if( (get_qual() & LR_SHIFTKEY) ) { + cmp[a].x= 0.125f*floor(0.5f + 8.0f*cmp[a].x); + cmp[a].y= 0.125f*floor(0.5f + 8.0f*cmp[a].y); + } + if(cmp[a].x!=origx || cmp[a].y!=origy) + moved_point= 1; + } + } + curvemapping_changed(cumap, 0); /* no remove doubles */ + + ui_draw_but(but); + ui_block_flush_back(but->block); + + if(moved_point) { + mval[0]= mvalo[0]; + mval[1]= mvalo[1]; + } + } + BIF_wait_for_statechange(); + } + + if(moved_mouse==0) { + /* deselect all, select one */ + if((G.qual & LR_SHIFTKEY)==0) { + for(a=0; atotpoint; a++) + cmp[a].flag &= ~SELECT; + cmp[sel].flag |= SELECT; + } + } + else + curvemapping_changed(cumap, 1); /* remove doubles */ + + ui_draw_but(but); + ui_block_flush_back(but->block); + } + else { + /* we move the view */ + retval= B_NOP; + + while(get_mbut() & L_MOUSE) { + + uiGetMouse(mywinget(), mvalo); + + if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) { + fx= (mvalo[0]-mval[0])/zoomx; + fy= (mvalo[1]-mval[1])/zoomy; + + /* clamp for clip */ + if(cumap->flag & CUMA_DO_CLIP) { + if(cumap->curr.xmin-fx < cumap->clipr.xmin) + fx= cumap->curr.xmin - cumap->clipr.xmin; + else if(cumap->curr.xmax-fx > cumap->clipr.xmax) + fx= cumap->curr.xmax - cumap->clipr.xmax; + if(cumap->curr.ymin-fy < cumap->clipr.ymin) + fy= cumap->curr.ymin - cumap->clipr.ymin; + else if(cumap->curr.ymax-fy > cumap->clipr.ymax) + fy= cumap->curr.ymax - cumap->clipr.ymax; + } + cumap->curr.xmin-=fx; + cumap->curr.ymin-=fy; + cumap->curr.xmax-=fx; + cumap->curr.ymax-=fy; + + ui_draw_but(but); + ui_block_flush_back(but->block); + + mval[0]= mvalo[0]; + mval[1]= mvalo[1]; + } + } + BIF_wait_for_statechange(); + } + + return retval; +} /* ************************************************ */ @@ -3316,7 +3712,8 @@ static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent) case BLOCK: case PULLDOWN: if(uevent->val) { - retval= ui_do_but_BLOCK(but, uevent->event); + ui_do_but_BLOCK(but, uevent->event); + retval= 0; if(block->auto_open==0) block->auto_open= 1; } break; @@ -3337,6 +3734,15 @@ static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent) case HSVCUBE: retval= ui_do_but_HSVCUBE(but); break; + case BUT_COLORBAND: + retval= ui_do_but_COLORBAND(but); + break; + case BUT_NORMAL: + retval= ui_do_but_NORMAL(but); + break; + case BUT_CURVE: + retval= ui_do_but_CURVE(but); + break; #ifdef INTERNATIONAL case CHARTAB: @@ -3553,14 +3959,14 @@ static int ui_mouse_motion_towards_block(uiBlock *block, uiEvent *uevent) } -static void ui_set_ftf_font(uiBlock *block) +static void ui_set_ftf_font(float aspect) { #ifdef INTERNATIONAL - if(block->aspect<1.15) { + if(aspect<1.15) { FTF_SetFontSize('l'); } - else if(block->aspect<1.59) { + else if(aspect<1.59) { FTF_SetFontSize('m'); } else { @@ -3647,7 +4053,7 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent) } } - ui_set_ftf_font(block); // sets just a pointer in ftf lib... the button dont have ftf handles + ui_set_ftf_font(block->aspect); // sets just a pointer in ftf lib... the button dont have ftf handles // added this for panels in windows with buttons... // maybe speed optimize should require test @@ -3677,13 +4083,19 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent) } else if( (block->maxy <= uevent->mval[1]) && (block->maxy+PNL_HEADER >= uevent->mval[1]) ) inside= 2; - + else if( block->panel->control & UI_PNL_SCALE) { + if( (block->maxx-PNL_HEADER <= uevent->mval[0])) + if( (block->miny+PNL_HEADER >= uevent->mval[1]) && inside ) + inside= 3; + } + if(inside) { // this stuff should move to do_panel if(uevent->event==LEFTMOUSE) { - if(inside==2) { + if(inside>=2) { uiPanelPop(block); // pop matrix; no return without pop! - ui_do_panel(block, uevent); + if(inside==2) ui_do_panel(block, uevent); + else ui_scale_panel(block); return UI_EXIT_LOOP; // exit loops because of moving panels } } @@ -3696,11 +4108,13 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent) else if(uevent->event==PADPLUSKEY || uevent->event==PADMINUS) { SpaceLink *sl= curarea->spacedata.first; if(curarea->spacetype!=SPACE_BUTS) { - if(uevent->event==PADPLUSKEY) sl->blockscale+= 0.1; - else sl->blockscale-= 0.1; - CLAMP(sl->blockscale, 0.6, 1.0); - addqueue(block->winq, REDRAW, 1); - retval= UI_CONT; + if(!(block->panel->control & UI_PNL_SCALE)) { + if(uevent->event==PADPLUSKEY) sl->blockscale+= 0.1; + else sl->blockscale-= 0.1; + CLAMP(sl->blockscale, 0.6, 1.0); + addqueue(block->winq, REDRAW, 1); + retval= UI_RETURN_OK; + } } } } @@ -4293,9 +4707,9 @@ int uiDoBlocks(ListBase *lb, int event) } block->in_use= 1; // bit awkward, but now we can detect if frontbuf flush should be set - retval= ui_do_block(block, &uevent); + retval |= ui_do_block(block, &uevent); /* we 'or' because 2nd loop can return to here, and we we want 'out' to return */ block->in_use= 0; - if(retval==UI_EXIT_LOOP) break; + if(retval & UI_EXIT_LOOP) break; /* now a new block could be created for menus, this is inserted in the beginning of a list */ @@ -4510,7 +4924,7 @@ static void ui_set_but_val(uiBut *but, double value) void uiSetCurFont(uiBlock *block, int index) { - ui_set_ftf_font(block); + ui_set_ftf_font(block->aspect); if(block->aspect<0.60) { block->curfont= UIfont[index].xl; @@ -4531,6 +4945,32 @@ void uiSetCurFont(uiBlock *block, int index) } +/* called by node editor */ +void *uiSetCurFont_ext(float aspect) +{ + void *curfont; + + ui_set_ftf_font(aspect); + + if(aspect<0.60) { + curfont= UIfont[0].xl; + } + else if(aspect<1.15) { + curfont= UIfont[0].large; + } + else if(aspect<1.59) { + curfont= UIfont[0].medium; + } + else { + curfont= UIfont[0].small; + } + + if(curfont==NULL) curfont= UIfont[0].large; + if(curfont==NULL) curfont= UIfont[0].medium; + + return curfont; +} + void uiDefFont(unsigned int index, void *xl, void *large, void *medium, void *small) { if(index>=UI_ARRAY) return; @@ -4828,7 +5268,7 @@ void ui_check_but(uiBut *but) but->strwidth= 0; /* automatic width */ - if(but->x2==0.0) { + if(but->x2==0.0f && but->x1 > 0.0f) { but->x2= (but->x1+but->strwidth+6); } @@ -4839,37 +5279,32 @@ void ui_check_but(uiBut *but) /* calc but->ofs, to draw the string shorter if too long */ but->ofs= 0; while(but->strwidth > (int)okwidth ) { - but->ofs++; - if(but->drawstr[but->ofs]) + if ELEM(but->type, NUM, TEX) { // only these cut off left + but->ofs++; but->strwidth= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, transopts); - else but->strwidth= 0; - - /* textbut exception */ - if(but->pos != -1) { - pos= but->pos+strlen(but->str); - if(pos-1 < but->ofs) { - pos= but->ofs-pos+1; - but->ofs -= pos; - if(but->ofs<0) { - but->ofs= 0; - pos--; + + /* textbut exception */ + if(but->pos != -1) { + pos= but->pos+strlen(but->str); + if(pos-1 < but->ofs) { + pos= but->ofs-pos+1; + but->ofs -= pos; + if(but->ofs<0) { + but->ofs= 0; + pos--; + } + but->drawstr[ strlen(but->drawstr)-pos ]= 0; } - but->drawstr[ strlen(but->drawstr)-pos ]= 0; } } + else { + but->drawstr[ strlen(but->drawstr)-1 ]= 0; + but->strwidth= but->aspect*BIF_GetStringWidth(but->font, but->drawstr, transopts); + } if(but->strwidth < 10) break; } - - /* fix for buttons that better not have text cut off to the right */ - if(but->ofs) { - if ELEM(but->type, NUM, TEX); // only these cut off left - else { - but->drawstr[ strlen(but->drawstr)-but->ofs ]= 0; - but->ofs= 0; - } - } } } @@ -5094,6 +5529,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->pointype= type & BUTPOIN; but->bit= type & BIT; but->bitnr= type & 31; + but->icon = 0; BLI_addtail(&block->buttons, but); @@ -5172,6 +5608,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short but->flag |= UI_NO_HILITE; but->flag |= (block->flag & UI_BUT_ALIGN); + if(block->flag & UI_BLOCK_NO_HILITE) + but->flag |= UI_NO_HILITE; return but; } @@ -5596,6 +6034,23 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, int return but; } +/* Block button containing icon */ +uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, int retval, int icon, short x1, short y1, short x2, short y2, char *tip) +{ + uiBut *but= ui_def_but(block, BLOCK, retval, "", x1, y1, x2, y2, arg, 0.0, 0.0, 0.0, 0.0, tip); + + but->icon= (BIFIconID) icon; + but->flag|= UI_HAS_ICON; + + but->flag|= UI_ICON_LEFT; + but->flag|= UI_ICON_RIGHT; + + but->block_func= func; + ui_check_but(but); + + return but; +} + void 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); @@ -5801,8 +6256,12 @@ short pupmenu_col(char *instr, int maxrow) while (rows*columns<(md->nitems+columns) ) rows++; /* size and location */ - if(md->title) width= 2*strlen(md->title)+BIF_GetStringWidth(uiBlockGetCurFont(block), md->title, (U.transopts & USER_TR_BUTTONS)); + if(md->title) { + width= 2*strlen(md->title)+BIF_GetStringWidth(uiBlockGetCurFont(block), md->title, (U.transopts & USER_TR_BUTTONS)); + width /= columns; + } else width= 0; + for(a=0; anitems; a++) { xmax= BIF_GetStringWidth(uiBlockGetCurFont(block), md->items[a].str, (U.transopts & USER_TR_BUTTONS)); if(xmax>width) width= xmax; @@ -5877,7 +6336,7 @@ short pupmenu_col(char *instr, int maxrow) if(md->title) { uiBut *bt; uiSetCurFont(block, UI_HELVB); - bt= uiDefBut(block, LABEL, 0, md->title, startx, (short)(starty+rows*boxh), (short)width, (short)boxh, NULL, 0.0, 0.0, 0, 0, ""); + bt= uiDefBut(block, LABEL, 0, md->title, startx, (short)(starty+rows*boxh), columns*(short)width, (short)boxh, NULL, 0.0, 0.0, 0, 0, ""); uiSetCurFont(block, UI_HELV); bt->flag= UI_TEXT_LEFT; } @@ -5885,6 +6344,8 @@ short pupmenu_col(char *instr, int maxrow) for(a=0; anitems; a++) { char *name= md->items[a].str; + int icon = md->items[a].icon; + x1= startx + width*((int)a/rows); y1= starty - boxh*(a%rows) + (rows-1)*boxh; @@ -5892,6 +6353,10 @@ short pupmenu_col(char *instr, int maxrow) uiDefBut(block, SEPR, B_NOP, "", x1, y1, width, PUP_LABELH, NULL, 0, 0.0, 0, 0, ""); y1 -= PUP_LABELH; } + else if (icon) { + uiDefIconButI(block, BUTM, B_NOP, icon, x1, y1, width+16, boxh-1, &val, (float) md->items[a].retval, 0.0, 0, 0, ""); + y1 -= boxh; + } else { uiDefButI(block, BUTM, B_NOP, name, x1, y1, width, boxh-1, &val, (float) md->items[a].retval, 0.0, 0, 0, ""); y1 -= boxh; diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index 3a2880e1373..450181a1e99 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -55,17 +55,23 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "DNA_color_types.h" +#include "DNA_key_types.h" +#include "DNA_packedFile_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "DNA_texture_types.h" #include "DNA_userdef_types.h" #include "DNA_vec_types.h" #include "DNA_vfont_types.h" -#include "DNA_packedFile_types.h" #include "BKE_blender.h" -#include "BKE_utildefines.h" +#include "BKE_colortools.h" #include "BKE_font.h" #include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_utildefines.h" + #include "datatoc.h" /* std font */ #include "BIF_gl.h" @@ -79,6 +85,7 @@ #include "BIF_space.h" #include "BIF_glutil.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_butspace.h" #include "BIF_language.h" @@ -95,9 +102,6 @@ // globals extern float UIwinmat[4][4]; -// local prototypes -void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy); - /* ************** safe rasterpos for pixmap alignment with pixels ************* */ @@ -153,15 +157,32 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel) /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */ +/* icons have been standardized... and this call draws in untransformed coordinates */ +#define ICON_HEIGHT 16.0f + static void ui_draw_icon(uiBut *but, BIFIconID icon) { - // void BIF_icon_pos(float xs, float ys); + float xs=0, ys=0, aspect, height; int blend= 0; - float xs=0, ys=0; - // this icon doesn't need draw... + /* this icon doesn't need draw... */ if(icon==ICON_BLANK1) return; - + + /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */ + aspect= but->block->aspect; + if(aspect != but->aspect) { + /* prevent scaling up icon in pupmenu */ + if (aspect < 1.0f) { + height= ICON_HEIGHT; + aspect = 1.0f; + + } + else + height= ICON_HEIGHT/aspect; + } + else + height= ICON_HEIGHT; + if(but->flag & UI_ICON_LEFT) { if (but->type==BUTM) { xs= but->x1+1.0; @@ -172,22 +193,21 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon) else { xs= but->x1+6.0; } - ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0; + ys= (but->y1+but->y2- height)/2.0; } if(but->flag & UI_ICON_RIGHT) { xs= but->x2-17.0; - ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0; + ys= (but->y1+but->y2- height)/2.0; } if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) { - xs= (but->x1+but->x2- BIF_get_icon_width(icon))/2.0; - ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0; + xs= (but->x1+but->x2- height)/2.0; + ys= (but->y1+but->y2- height)/2.0; } - if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect); - else if(but->aspect<0.9) glPixelZoom(1.0/but->aspect, 1.0/but->aspect); + /* aspect for the icon has to be stored */ + BIF_icon_set_aspect(icon, aspect); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* calculate blend color */ if ELEM4(but->type, ICONTOG, TOG, ROW, TOGN) { @@ -195,12 +215,10 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon) else if(but->flag & UI_ACTIVE); else blend= -60; } - BIF_draw_icon_blended(xs, ys, icon, but->themecol, blend); + BIF_icon_draw_blended(xs, ys, icon, but->themecol, blend); - glBlendFunc(GL_ONE, GL_ZERO); glDisable(GL_BLEND); - glPixelZoom(1.0, 1.0); } @@ -408,7 +426,6 @@ static void ui_default_iconrow_arrows(float x1, float y1, float x2, float y2) { glEnable( GL_POLYGON_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glShadeModel(GL_FLAT); glBegin(GL_TRIANGLES); @@ -432,7 +449,6 @@ static void ui_default_menu_arrows(float x1, float y1, float x2, float y2) { glEnable( GL_POLYGON_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glShadeModel(GL_FLAT); glBegin(GL_TRIANGLES); @@ -458,7 +474,6 @@ static void ui_default_num_arrows(float x1, float y1, float x2, float y2) glEnable( GL_POLYGON_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glShadeModel(GL_FLAT); glBegin(GL_TRIANGLES); @@ -488,7 +503,6 @@ static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype) short alpha = 30; if (seltype == 0) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glColor4ub(0, 0, 0, alpha); @@ -499,7 +513,6 @@ static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype) glDisable(GL_BLEND); } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glColor4ub(255, 255, 255, alpha); @@ -523,7 +536,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float if (!((align == UI_BUT_ALIGN_DOWN) || (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) || (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); MM_WHITE_OP; fdrawline(x1, y1-1, x2, y1-1); @@ -549,7 +561,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float case UI_BUT_ALIGN_LEFT: /* RIGHT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -566,7 +577,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float case UI_BUT_ALIGN_RIGHT: /* LEFT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -592,7 +602,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT: /* LEFT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -609,7 +618,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT: /* RIGHT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -630,7 +638,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float } } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); @@ -665,7 +672,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float case ICONROW: case ICONTEXTROW: /* DARKENED AREA */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glColor4ub(0, 0, 0, 30); @@ -681,7 +687,6 @@ static void ui_default_button(int type, int colorid, float asp, float x1, float break; case MENU: /* DARKENED AREA */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glColor4ub(0, 0, 0, 30); @@ -710,7 +715,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 if (!((align == UI_BUT_ALIGN_DOWN) || (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) || (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); MM_WHITE_OP; fdrawline(x1, y1-1, x2, y1-1); @@ -736,7 +740,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 case UI_BUT_ALIGN_LEFT: /* RIGHT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -753,7 +756,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 case UI_BUT_ALIGN_RIGHT: /* LEFT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -779,7 +781,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT: /* LEFT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -796,7 +797,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT: /* RIGHT OUTER SUNKEN EFFECT */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); glBegin(GL_LINES); @@ -818,7 +818,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1 } else { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); @@ -1081,7 +1080,6 @@ static void round_button(float x1, float y1, float x2, float y2, float asp, /* fake AA */ uiSetRoundBox(round); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); BIF_GetThemeColor3ubv(colorid, col); @@ -1326,7 +1324,6 @@ static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); @@ -1407,7 +1404,6 @@ static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, fl BIF_GetThemeColor4ubv(TH_MENU_BACK, col); if(col[3]!=255) { glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } if((flag & UI_ACTIVE) && type!=LABEL) { @@ -1435,7 +1431,6 @@ static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, f glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0); glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); @@ -1529,7 +1524,7 @@ static void ui_draw_text_icon(uiBut *but) if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) { ui_draw_icon(but, but->icon); - if(but->flag & UI_TEXT_LEFT) x= but->x1+24.0; + if(but->flag & UI_TEXT_LEFT) x= but->x1 + BIF_icon_get_width(but->icon)+4.0; else x= (but->x1+but->x2-but->strwidth+1)/2.0; } else { @@ -1899,9 +1894,315 @@ static void ui_draw_but_CHARTAB(uiBut *but) #endif // INTERNATIONAL +static void ui_draw_but_COLORBAND(uiBut *but) +{ + ColorBand *coba= (ColorBand *)but->poin; + CBData *cbd; + float x1, y1, sizex, sizey; + float dx, v3[2], v1[2], v2[2]; + int a; + + if(coba==NULL) return; + + x1= but->x1; + y1= but->y1; + sizex= but->x2-x1; + sizey= but->y2-y1; + + /* first background, to show tranparency */ + dx= sizex/12.0; + v1[0]= x1; + for(a=0; a<12; a++) { + if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8); + glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey); + if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3); + glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey); + v1[0]+= dx; + } + + glShadeModel(GL_SMOOTH); + glEnable(GL_BLEND); + + cbd= coba->data; + + v1[0]= v2[0]= x1; + v1[1]= y1; + v2[1]= y1+sizey; + + glBegin(GL_QUAD_STRIP); + + glColor4fv( &cbd->r ); + glVertex2fv(v1); glVertex2fv(v2); + + for(a=0; atot; a++, cbd++) { + + v1[0]=v2[0]= x1+ cbd->pos*sizex; + + glColor4fv( &cbd->r ); + glVertex2fv(v1); glVertex2fv(v2); + } + + v1[0]=v2[0]= x1+ sizex; + glVertex2fv(v1); glVertex2fv(v2); + + glEnd(); + glShadeModel(GL_FLAT); + glDisable(GL_BLEND); + + /* outline */ + v1[0]= x1; v1[1]= y1; + + cpack(0x0); + glBegin(GL_LINE_LOOP); + glVertex2fv(v1); + v1[0]+= sizex; + glVertex2fv(v1); + v1[1]+= sizey; + glVertex2fv(v1); + v1[0]-= sizex; + glVertex2fv(v1); + glEnd(); + + + /* help lines */ + v1[0]= v2[0]=v3[0]= x1; + v1[1]= y1; + v2[1]= y1+0.5*sizey; + v3[1]= y1+sizey; + + cbd= coba->data; + glBegin(GL_LINES); + for(a=0; atot; a++, cbd++) { + v1[0]=v2[0]=v3[0]= x1+ cbd->pos*sizex; + + glColor3ub(0, 0, 0); + glVertex2fv(v1); + glVertex2fv(v2); + + if(a==coba->cur) { + glVertex2f(v1[0]-1, v1[1]); + glVertex2f(v2[0]-1, v2[1]); + glVertex2f(v1[0]+1, v1[1]); + glVertex2f(v2[0]+1, v2[1]); + } + + glColor3ub(255, 255, 255); + glVertex2fv(v2); + glVertex2fv(v3); + + if(a==coba->cur) { + if(cbd->pos>0.01) { + glVertex2f(v2[0]-1, v2[1]); + glVertex2f(v3[0]-1, v3[1]); + } + if(cbd->pos<0.99) { + glVertex2f(v2[0]+1, v2[1]); + glVertex2f(v3[0]+1, v3[1]); + } + } + } + glEnd(); +} + +static void ui_draw_but_NORMAL(uiBut *but) +{ + static GLuint displist=0; + int a, old[8]; + GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f}; + float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f}; + float dir[4], size; + + /* store stuff */ + glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff); + + /* backdrop */ + BIF_ThemeColor(TH_BUT_NEUTRAL); + uiSetRoundBox(15); + gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, 5.0f); + + /* sphere color */ + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn); + glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + + /* disable blender light */ + for(a=0; a<8; a++) { + old[a]= glIsEnabled(GL_LIGHT0+a); + glDisable(GL_LIGHT0+a); + } + + /* own light */ + glEnable(GL_LIGHT7); + glEnable(GL_LIGHTING); + + VECCOPY(dir, (float *)but->poin); + dir[3]= 0.0f; /* glLight needs 4 args, 0.0 is sun */ + glLightfv(GL_LIGHT7, GL_POSITION, dir); + glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn); + glLightfv(GL_LIGHT7, GL_SPECULAR, vec0); + glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f); + glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f); + + /* transform to button */ + glPushMatrix(); + glTranslatef(but->x1 + 0.5f*(but->x2-but->x1), but->y1+ 0.5f*(but->y2-but->y1), 0.0f); + size= (but->x2-but->x1)/200.f; + glScalef(size, size, size); + + if(displist==0) { + GLUquadricObj *qobj; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); + + qobj= gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + glShadeModel(GL_SMOOTH); + gluSphere( qobj, 100.0, 32, 24); + glShadeModel(GL_FLAT); + gluDeleteQuadric(qobj); + + glEndList(); + } + else glCallList(displist); + + /* restore */ + glPopMatrix(); + glDisable(GL_LIGHTING); + glDisable(GL_CULL_FACE); + glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); + + glDisable(GL_LIGHT7); + + /* enable blender light */ + for(a=0; a<8; a++) { + if(old[a]) + glEnable(GL_LIGHT0+a); + } +} + +static void ui_draw_but_curve_grid(uiBut *but, float zoomx, float zoomy, float offsx, float offsy, float step) +{ + float dx, dy, fx, fy; + + glBegin(GL_LINES); + dx= step*zoomx; + fx= but->x1 + zoomx*(-offsx); + if(fx > but->x1) fx -= dx*( floor(fx-but->x1)); + while(fx < but->x2) { + glVertex2f(fx, but->y1); + glVertex2f(fx, but->y2); + fx+= dx; + } + + dy= step*zoomy; + fy= but->y1 + zoomy*(-offsy); + if(fy > but->y1) fy -= dy*( floor(fy-but->y1)); + while(fy < but->y2) { + glVertex2f(but->x1, fy); + glVertex2f(but->x2, fy); + fy+= dy; + } + glEnd(); + +} + +static void ui_draw_but_CURVE(uiBut *but) +{ + CurveMapping *cumap= (CurveMapping *)but->poin; + CurveMap *cuma= cumap->cm+cumap->cur; + CurveMapPoint *cmp; + float fx, fy, dx, dy, fac[2], zoomx, zoomy, offsx, offsy; + GLint scissor[4]; + int a; + + /* need scissor test, curve can draw outside of boundary */ + glGetIntegerv(GL_VIEWPORT, scissor); + fx= but->x1; fy= but->y1; + ui_graphics_to_window(but->win, &fx, &fy); + dx= but->x2; dy= but->y2; + ui_graphics_to_window(but->win, &dx, &dy); + glScissor((int)floor(fx), (int)floor(fy), (int)ceil(dx-fx), (int)ceil(dy-fy)); + + /* calculate offset and zoom */ + zoomx= (but->x2-but->x1-2.0*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin); + zoomy= (but->y2-but->y1-2.0*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin); + offsx= cumap->curr.xmin-but->aspect/zoomx; + offsy= cumap->curr.ymin-but->aspect/zoomy; + + /* backdrop */ + if(cumap->flag & CUMA_DO_CLIP) { + BIF_ThemeColorShade(TH_BUT_NEUTRAL, -20); + glRectf(but->x1, but->y1, but->x2, but->y2); + BIF_ThemeColor(TH_BUT_NEUTRAL); + glRectf(but->x1 + zoomx*(cumap->clipr.xmin-offsx), + but->y1 + zoomy*(cumap->clipr.ymin-offsy), + but->x1 + zoomx*(cumap->clipr.xmax-offsx), + but->y1 + zoomy*(cumap->clipr.ymax-offsy)); + } + else { + BIF_ThemeColor(TH_BUT_NEUTRAL); + glRectf(but->x1, but->y1, but->x2, but->y2); + } + + /* grid, every .25 step */ + BIF_ThemeColorBlend(TH_BUT_NEUTRAL, TH_BUT_OUTLINE, 0.06f); + ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 0.25f); + /* grid, every 1.0 step */ + BIF_ThemeColorBlend(TH_BUT_NEUTRAL, TH_BUT_OUTLINE, 0.12f); + ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 1.0f); + /* axes */ + BIF_ThemeColorBlend(TH_BUT_NEUTRAL, TH_BUT_OUTLINE, 0.25f); + glBegin(GL_LINES); + glVertex2f(but->x1, but->y1 + zoomy*(-offsy)); + glVertex2f(but->x2, but->y1 + zoomy*(-offsy)); + glVertex2f(but->x1 + zoomx*(-offsx), but->y1); + glVertex2f(but->x1 + zoomx*(-offsx), but->y2); + glEnd(); + + /* the curve */ + BIF_ThemeColor(TH_TEXT); + glBegin(GL_LINE_STRIP); + + if(cuma->table==NULL) + curvemapping_changed(cumap, 0); /* 0 = no remove doubles */ + cmp= cuma->table; + + glVertex2f(but->x1, but->y1 + zoomy*(cmp[0].y-offsy)); /* first point */ + for(a=0; a<=CM_TABLE; a++) { + fx= but->x1 + zoomx*(cmp[a].x-offsx); + fy= but->y1 + zoomy*(cmp[a].y-offsy); + glVertex2f(fx, fy); + } + glVertex2f(but->x2, but->y1 + zoomy*(cmp[a-1].y-offsy)); /* last point */ + glEnd(); + + /* the points, use aspect to make them visible on edges */ + cmp= cuma->curve; + glPointSize(3.0f); + bglBegin(GL_POINTS); + for(a=0; atotpoint; a++) { + if(cmp[a].flag & SELECT) + BIF_ThemeColor(TH_TEXT_HI); + else + BIF_ThemeColor(TH_TEXT); + fac[0]= but->x1 + zoomx*(cmp[a].x-offsx); + fac[1]= but->y1 + zoomy*(cmp[a].y-offsy); + bglVertex2fv(fac); + } + bglEnd(); + glPointSize(1.0f); + + /* restore scissortest */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + + /* outline */ + BIF_ThemeColor(TH_BUT_OUTLINE); + fdrawbox(but->x1, but->y1, but->x2, but->y2); + +} + static void ui_draw_roundbox(uiBut *but) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); BIF_ThemeColorShadeAlpha(TH_PANEL, but->a2, but->a2); @@ -2014,7 +2315,18 @@ void ui_draw_but(uiBut *but) case ROUNDBOX: ui_draw_roundbox(but); - + break; + + case BUT_COLORBAND: + ui_draw_but_COLORBAND(but); + break; + case BUT_NORMAL: + ui_draw_but_NORMAL(but); + break; + case BUT_CURVE: + ui_draw_but_CURVE(but); + break; + default: but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag); ui_draw_text_icon(but); diff --git a/source/blender/src/interface_icons.c b/source/blender/src/interface_icons.c new file mode 100644 index 00000000000..35889e3c220 --- /dev/null +++ b/source/blender/src/interface_icons.c @@ -0,0 +1,810 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif +#ifndef WIN32 +#include +#else +#include +#endif +#include "MEM_guardedalloc.h" + +#include "BLI_arithb.h" + +#include "DNA_material_types.h" +#include "DNA_texture_types.h" +#include "DNA_world_types.h" +#include "DNA_object_types.h" +#include "DNA_lamp_types.h" +#include "DNA_image_types.h" +#include "DNA_texture_types.h" +#include "DNA_world_types.h" +#include "DNA_camera_types.h" +#include "DNA_image_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BKE_global.h" +#include "BKE_material.h" +#include "BKE_texture.h" +#include "BKE_world.h" +#include "BKE_image.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" +#include "BKE_icons.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" +#include "BIF_interface.h" +#include "BIF_interface_icons.h" +#include "BIF_previewrender.h" +#include "BIF_resources.h" /* elubie: should be removed once the enum for the ICONS is in BIF_preview_icons.h */ + +#include "interface.h" + +#include "PIL_time.h" + +#include "blendef.h" // CLAMP +#include "datatoc.h" +#include "mydevice.h" + +/* OpenGL textures have to be size 2n+2 x 2m+2 for some n,m */ +/* choose ICON_RENDERSIZE accordingly */ +#define ICON_RENDERSIZE 32 +#define ICON_MIPMAPS 8 + +typedef struct DrawInfo { + int w; + int h; + int rw; + int rh; + VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */ + float aspect; + unsigned int* rect; +} DrawInfo; + +static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs) +{ + Icon* new_icon = 0; + DrawInfo* di; + int y = 0; + + new_icon = MEM_callocN(sizeof(Icon), "texicon"); + + new_icon->obj = 0; /* icon is not for library object */ + new_icon->type = 0; + new_icon->changed = 0; + + + di = MEM_callocN(sizeof(DrawInfo), "drawinfo"); + di->drawFunc = 0; + di->w = ICON_DEFAULT_HEIGHT; + di->h = ICON_DEFAULT_HEIGHT; + di->rw = ICON_DEFAULT_HEIGHT; + di->rh = ICON_DEFAULT_HEIGHT; + di->aspect = 1.0f; + di->rect = MEM_mallocN(ICON_DEFAULT_HEIGHT*ICON_DEFAULT_HEIGHT*sizeof(unsigned int), "icon_rect"); + + /* Here we store the rect in the icon - same as before */ + for (y=0; yrect[y*ICON_DEFAULT_HEIGHT], &bbuf->rect[(y+yofs)*512+xofs], ICON_DEFAULT_HEIGHT*sizeof(int)); + } + + new_icon->drawinfo_free = BIF_icons_free_drawinfo; + new_icon->drawinfo = di; + + BKE_icon_set(icon_id, new_icon); +} + +static void def_internal_vicon( int icon_id, VectorDrawFunc drawFunc) +{ + Icon* new_icon = 0; + DrawInfo* di; + + new_icon = MEM_callocN(sizeof(Icon), "texicon"); + + new_icon->obj = 0; /* icon is not for library object */ + new_icon->type = 0; + new_icon->changed = 0; + + di = MEM_callocN(sizeof(DrawInfo), "drawinfo"); + di->drawFunc =drawFunc; + di->w = ICON_DEFAULT_HEIGHT; + di->h = ICON_DEFAULT_HEIGHT; + di->rw = ICON_DEFAULT_HEIGHT; + di->rh = ICON_DEFAULT_HEIGHT; + di->aspect = 1.0f; + di->rect = 0; + + new_icon->drawinfo_free = 0; + new_icon->drawinfo = di; + + BKE_icon_set(icon_id, new_icon); +} + +/* Vector Icon Drawing Routines */ + + /* Utilities */ + +static void viconutil_set_point(GLint pt[2], int x, int y) +{ + pt[0] = x; + pt[1] = y; +} + +static void viconutil_draw_tri(GLint (*pts)[2]) +{ + glBegin(GL_TRIANGLES); + glVertex2iv(pts[0]); + glVertex2iv(pts[1]); + glVertex2iv(pts[2]); + glEnd(); +} + +#if 0 +static void viconutil_draw_quad(GLint (*pts)[2]) +{ + glBegin(GL_QUADS); + glVertex2iv(pts[0]); + glVertex2iv(pts[1]); + glVertex2iv(pts[2]); + glVertex2iv(pts[3]); + glEnd(); +} +#endif + +static void viconutil_draw_lineloop(GLint (*pts)[2], int numPoints) +{ + int i; + + glBegin(GL_LINE_LOOP); + for (i=0; ival) pxl[0]-= val; else pxl[0]= 0; + if(pxl[1]>val) pxl[1]-= val; else pxl[1]= 0; + if(pxl[2]>val) pxl[2]-= val; else pxl[2]= 0; + + pxl[3]= 128; + } + } + } + } + } +} + +static void clear_transp_rect(unsigned char *transp, unsigned char *rect, int w, int h, int rowstride) +{ + int x,y; + for (y=0; yx*4; + char *back= (char *)bbuf->rect; + unsigned char transp[4]; + + /* this sets blueish outside of icon to zero alpha */ + QUATCOPY(transp, back); + clear_transp_rect(transp, back, bbuf->x, bbuf->y, rowstride); + + /* hack! */ +#if 0 + for (y=0; y<12; y++) { + for (x=0; x<21; x++) { + unsigned char *start= ((unsigned char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4; + /* this sets backdrop of icon to zero alpha */ + transp[0]= start[0]; + transp[1]= start[1]; + transp[2]= start[2]; + transp[3]= start[3]; + clear_transp_rect(transp, start, 20, 21, rowstride); + clear_transp_rect_soft(transp, start, 20, 21, rowstride); + + } + } +#endif +} + + +static void init_internal_icons() +{ + ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect); + int x, y; + + prepare_internal_icons(bbuf); + + for (y=0; y<12; y++) { + for (x=0; x<21; x++) { + def_internal_icon(bbuf, BIFICONID_FIRST + y*21 + x, x*20+3, y*21+3); + } + } + + def_internal_vicon(VICON_VIEW3D, vicon_view3d_draw); + def_internal_vicon(VICON_EDIT, vicon_edit_draw); + def_internal_vicon(VICON_EDITMODE_DEHLT, vicon_editmode_dehlt_draw); + def_internal_vicon(VICON_EDITMODE_HLT, vicon_editmode_hlt_draw); + def_internal_vicon(VICON_DISCLOSURE_TRI_RIGHT, vicon_disclosure_tri_right_draw); + def_internal_vicon(VICON_DISCLOSURE_TRI_DOWN, vicon_disclosure_tri_down_draw); + def_internal_vicon(VICON_MOVE_UP, vicon_move_up_draw); + def_internal_vicon(VICON_MOVE_DOWN, vicon_move_down_draw); + def_internal_vicon(VICON_X, vicon_x_draw); + + IMB_freeImBuf(bbuf); +} + + + +void BIF_icons_free() +{ + BKE_icons_free(); +} + +void BIF_icons_free_drawinfo(void *drawinfo) +{ + DrawInfo* di = drawinfo; + + if (di) + { + MEM_freeN(di->rect); + MEM_freeN(di); + } +} + +static DrawInfo* icon_create_drawinfo() +{ + DrawInfo* di = 0; + + di = MEM_callocN(sizeof(DrawInfo), "di_icon"); + + di->drawFunc = 0; + di->w = 16; + di->h = 16; + di->rw = ICON_RENDERSIZE; + di->rh = ICON_RENDERSIZE; + di->rect = 0; + di->aspect = 1.0f; + + return di; +} + +int BIF_icon_get_width(int icon_id) +{ + Icon* icon = 0; + DrawInfo* di = 0; + + icon = BKE_icon_get(icon_id); + + if (!icon) { + printf("BIF_icon_get_width: Internal error, no icon for icon ID: %d\n", icon_id); + return 0; + } + + di = (DrawInfo*)icon->drawinfo; + if (!di) { + di = icon_create_drawinfo(); + icon->drawinfo = di; + } + + if (di) + return di->w; + + return 0; +} + +int BIF_icon_get_height(int icon_id) +{ + Icon* icon = 0; + DrawInfo* di = 0; + + icon = BKE_icon_get(icon_id); + + if (!icon) { + printf("BIF_icon_get_width: Internal error, no icon for icon ID: %d\n", icon_id); + return 0; + } + + di = (DrawInfo*)icon->drawinfo; + + if (!di) { + di = icon_create_drawinfo(); + icon->drawinfo = di; + } + + if (di) + return di->h; + + return 0; +} + +void BIF_icons_init(int first_dyn_id) +{ + + BKE_icons_init(first_dyn_id); + init_internal_icons(); +} + +/* create single icon from jpg, png etc. */ +static void icon_from_image(Image* img, RenderInfo* ri, unsigned int w, unsigned int h) +{ + struct ImBuf *ima; + struct ImBuf *imb; + float scaledx, scaledy; + int pr_size = w*h*sizeof(unsigned int); + short ex, ey, dx, dy; + + if (!img) + return; + + if (!ri->rect) { + ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "butsrect"); + memset(ri->rect, 0xFF, w*h*sizeof(unsigned int)); + } + + /* bail out now... loading and reducing images is too expensive */ + if(img->ibuf==NULL || img->ibuf->rect==NULL) { + return; +// load_image(img, IB_rect, G.sce, G.scene->r.cfra); + } + + ima = IMB_dupImBuf(img->ibuf); + + if (!ima) + return; + + if (ima->x > ima->y) { + scaledx = (float)w; + scaledy = ( (float)ima->y/(float)ima->x )*(float)w; + } + else { + scaledx = ( (float)ima->x/(float)ima->y )*(float)h; + scaledy = (float)h; + } + + ex = (short)scaledx; + ey = (short)scaledy; + + dx = (w - ex) / 2; + dy = (h - ey) / 2; + + IMB_scalefastImBuf(ima, ex, ey); + + /* sigh, need to copy the float buffer too */ + imb = IMB_allocImBuf(w, h, 32, IB_rect | IB_rectfloat, 0); + + IMB_rectcpy(imb, ima, dx, dy, 0, 0, ex, ey); + + IMB_freeImBuf(ima); + + memcpy(ri->rect, imb->rect,pr_size); + + IMB_freeImBuf(imb); +} + + +/* only called when icon has changed */ +/* only call with valid pointer from BIF_icon_draw */ +static void icon_set_image(ID* id, DrawInfo* di) +{ + RenderInfo ri; + + if (!di) return; + + if (!di->rect) + di->rect = MEM_callocN(di->rw*di->rh*sizeof(unsigned int), "laprevrect"); + + ri.cury = 0; + ri.rect = 0; + ri.pr_rectx = di->rw; + ri.pr_recty = di->rh; + + /* 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, &ri, ri.pr_rectx, ri.pr_recty); + else { + BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER); + } + + /* and copy the image into the icon */ + memcpy(di->rect, ri.rect,di->rw*di->rh*sizeof(unsigned int)); + + /* and clean up */ + MEM_freeN(ri.rect); + ri.rect = 0; + +} + +void BIF_icon_draw(float x, float y, int icon_id) +{ + Icon* icon = 0; + DrawInfo* di = 0; + + icon = BKE_icon_get(icon_id); + + if (!icon) { + printf("BIF_icon_draw: Internal error, no icon for icon ID: %d\n", icon_id); + return; + } + + di = (DrawInfo*)icon->drawinfo; + + if (!di) { + + di = icon_create_drawinfo(); + + icon->changed = 1; + icon->drawinfo = di; + icon->drawinfo_free = BIF_icons_free_drawinfo; + } + + if (di->drawFunc) { + /* vector icons use the uiBlock transformation, they are not drawn + with untransformed coordinates like the other icons */ + di->drawFunc(x, y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f); + } + else { + if (icon->changed) /* changed only ever set by dynamic icons */ + { + icon_set_image((ID*)icon->obj, icon->drawinfo); + icon->changed = 0; + } + + if (!di->rect) return; /* something has gone wrong! */ + + ui_rasterpos_safe(x, y, di->aspect); + + if(di->w<1 || di->h<1) { + printf("what the heck!\n"); + } + /* di->rect contains image in 'rendersize', we only scale if needed */ + else if(di->rw!=di->w && di->rh!=di->h) { + ImBuf *ima; + /* first allocate imbuf for scaling and copy preview into it */ + ima = IMB_allocImBuf(di->rw, di->rh, 32, IB_rect, 0); + memcpy(ima->rect, di->rect, di->rw*di->rh*sizeof(unsigned int)); + + /* scale it */ + IMB_scaleImBuf(ima, di->w, di->h); + glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect); + + IMB_freeImBuf(ima); + } + else + glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, di->rect); + } +} + + +void BIF_icon_draw_blended(float x, float y, int icon_id, int colorid, int shade) +{ + + if(shade < 0) { + float r= (128+shade)/128.0; + glPixelTransferf(GL_ALPHA_SCALE, r); + } + + BIF_icon_draw(x, y, icon_id); + + glPixelTransferf(GL_ALPHA_SCALE, 1.0); +} + +void BIF_icon_set_aspect(int icon_id, float aspect) +{ + Icon* icon = 0; + DrawInfo* di = 0; + + icon = BKE_icon_get(icon_id); + + if (!icon) { + printf("BIF_icon_set_aspect: Internal error, no icon for icon ID: %d\n", icon_id); + return; + } + + di = (DrawInfo*)icon->drawinfo; + + if (!di) { + di = icon_create_drawinfo(); + + icon->changed = 1; + icon->drawinfo = di; + icon->drawinfo_free = BIF_icons_free_drawinfo; + } + di->aspect = aspect; + /* scale width and height according to aspect */ + di->w = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f); + di->h = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f); + +} + diff --git a/source/blender/src/interface_panel.c b/source/blender/src/interface_panel.c index 54bab5703a3..d1ba75a5036 100644 --- a/source/blender/src/interface_panel.c +++ b/source/blender/src/interface_panel.c @@ -72,6 +72,7 @@ #include "BIF_keyval.h" #include "BIF_mainqueue.h" +#include "BIF_previewrender.h" #include "BIF_screen.h" #include "BIF_toolbox.h" #include "BIF_mywindow.h" @@ -344,7 +345,6 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, color[3]= 0.5; glColor4fv(color); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } /* solid part */ @@ -357,7 +357,6 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, /* set antialias line */ glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); /* top shade */ gl_round_box_topshade(minx+1, miny+1, maxx-1, maxy-1, rad); @@ -387,13 +386,11 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad) color[3]= 0.5; glColor4fv(color); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } /* set antialias line */ glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); @@ -413,7 +410,6 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad) color[3]= 0.5; glColor4fv(color); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); } /* solid part */ @@ -422,7 +418,6 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad) /* set antialias line */ glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad); @@ -473,7 +468,7 @@ void uiSetPanelHandler(int handler) /* return 1 if visible (create buttons!) */ int uiNewPanel(ScrArea *sa, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey) { - Panel *pa, *palign; + Panel *pa; /* check if Panel exists, then use that one */ pa= sa->panels.first; @@ -487,10 +482,14 @@ int uiNewPanel(ScrArea *sa, uiBlock *block, char *panelname, char *tabname, int } if(pa) { - if(pa->sizex != sizex) { + /* scale correction */ + if(pa->control & UI_PNL_SCALE); + else { pa->sizex= sizex; - pa->ofsy+= (pa->sizey - sizey); // check uiNewPanelHeight() - pa->sizey= sizey; + if(pa->sizey != sizey) { + pa->ofsy+= (pa->sizey - sizey); // check uiNewPanelHeight() + pa->sizey= sizey; + } } } else { @@ -506,18 +505,6 @@ int uiNewPanel(ScrArea *sa, uiBlock *block, char *panelname, char *tabname, int pa->sizex= sizex; pa->sizey= sizey; - /* pre align, for good sorting later on */ - if(sa->spacetype==SPACE_BUTS && pa->prev) { - SpaceButs *sbuts= sa->spacedata.first; - - palign= pa->prev; - if(sbuts->align==BUT_VERTICAL) { - pa->ofsy= palign->ofsy - pa->sizey - PNL_HEADER; - } - else if(sbuts->align==BUT_HORIZONTAL) { - pa->ofsx= palign->ofsx + palign->sizex; - } - } /* make new Panel tabbed? */ if(panel_tabbed && group_tabbed) { Panel *papar; @@ -652,7 +639,7 @@ void uiSetPanel_view2d(ScrArea *sa) pa= sa->panels.first; while(pa) { - if(pa->active) { + if(pa->active && pa->paneltab==NULL) { done= 1; if(pa->ofsx < minx) minx= pa->ofsx; if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex; @@ -696,7 +683,7 @@ void uiMatchPanel_view2d(ScrArea *sa) pa= sa->panels.first; while(pa) { - if(pa->active) { + if(pa->active && pa->paneltab==NULL) { done= 1; if(pa->ofsx < G.v2d->tot.xmin) G.v2d->tot.xmin= pa->ofsx; if(pa->ofsx+pa->sizex > G.v2d->tot.xmax) @@ -752,19 +739,16 @@ uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name) static void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) { - // we draw twice, anti polygons not widely supported... - glBegin(GL_POLYGON); glVertex2f(x1, y1); glVertex2f(x2, y2); glVertex2f(x3, y3); glEnd(); - + /* set antialias line */ glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBegin(GL_LINE_LOOP); glVertex2f(x1, y1); @@ -774,29 +758,25 @@ static void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); - } /* triangle 'icon' for panel header */ -static void ui_draw_tria_icon(float x, float y, float aspect, char dir) +void ui_draw_tria_icon(float x, float y, float aspect, char dir) { - BIF_ThemeColor(TH_TEXT_HI); - if(dir=='h') { - ui_draw_anti_tria( x, y+1, x, y+10.0, x+7, y+6.25); + ui_draw_anti_tria( x, y+1, x, y+10.0, x+8, y+6.25); } else { - ui_draw_anti_tria( x-2, y+8, x+9-2, y+8, x+4.75-2, y+1); + ui_draw_anti_tria( x-2, y+9, x+8-2, y+9, x+4.25-2, y+1); } } -static void ui_draw_anti_x(float x1, float y1, float x2, float y2) +void ui_draw_anti_x(float x1, float y1, float x2, float y2) { /* set antialias line */ glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glLineWidth(2.0); @@ -953,6 +933,30 @@ static void ui_draw_panel_header(uiBlock *block) } +static void ui_draw_panel_scalewidget(uiBlock *block) +{ + float xmin, xmax, dx; + float ymin, ymax, dy; + + xmin= block->maxx-PNL_HEADER+2; + xmax= block->maxx-3; + ymin= block->miny+3; + ymax= block->miny+PNL_HEADER-2; + + dx= 0.5f*(xmax-xmin); + dy= 0.5f*(ymax-ymin); + + glEnable(GL_BLEND); + glColor4ub(255, 255, 255, 50); + fdrawline(xmin, ymin, xmax, ymax); + fdrawline(xmin+dx, ymin, xmax, ymax-dy); + + glColor4ub(0, 0, 0, 50); + fdrawline(xmin, ymin+block->aspect, xmax, ymax+block->aspect); + fdrawline(xmin+dx, ymin+block->aspect, xmax, ymax-dy+block->aspect); + glDisable(GL_BLEND); +} + void ui_draw_panel(uiBlock *block) { Panel *panel= block->panel; @@ -1039,7 +1043,6 @@ void ui_draw_panel(uiBlock *block) uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8); // blend now for panels in 3d window, test... - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable(GL_BLEND); BIF_ThemeColor4(TH_PANEL); @@ -1070,7 +1073,6 @@ void ui_draw_panel(uiBlock *block) uiSetRoundBox(3); uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable(GL_BLEND); BIF_ThemeColor4(TH_PANEL); glRectf(block->minx, block->miny, block->maxx, block->maxy); @@ -1097,10 +1099,12 @@ void ui_draw_panel(uiBlock *block) uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 8); } + if(panel->control & UI_PNL_SCALE) + ui_draw_panel_scalewidget(block); + /* and a soft shadow-line for now */ /* glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4ub(0, 0, 0, 50); fdrawline(block->maxx, block->miny, block->maxx, block->maxy+PNL_HEADER/2); fdrawline(block->minx, block->miny, block->maxx, block->miny); @@ -1117,7 +1121,7 @@ void ui_draw_panel(uiBlock *block) ui_draw_x_icon(block->minx+2+ofsx, block->maxy+5); /* if(block->aspect>1.1) glPixelZoom(1.0/block->aspect, 1.0/block->aspect); - BIF_draw_icon(block->minx+4, block->maxy+3, ICON_PANEL_CLOSE); + BIF_icon_draw(block->minx+4, block->maxy+3, ICON_PANEL_CLOSE); if(block->aspect>1.1) glPixelZoom(1.0, 1.0); */ ofsx= 22; @@ -1125,6 +1129,8 @@ void ui_draw_panel(uiBlock *block) /* draw collapse icon */ + BIF_ThemeColor(TH_TEXT_HI); + if(panel->flag & PNL_CLOSEDY) ui_draw_tria_icon(block->minx+6+ofsx, block->maxy+5, block->aspect, 'h'); else if(panel->flag & PNL_CLOSEDX) @@ -1263,7 +1269,7 @@ int uiAlignPanelStep(ScrArea *sa, float fac) for(a=0 ; aalign==BUT_VERTICAL) { psnext->pa->ofsx = ps->pa->ofsx; psnext->pa->ofsy = get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-PNL_DIST; @@ -1522,11 +1528,12 @@ static void test_add_new_tabs(ScrArea *sa) /* ------------ panel drag ---------------- */ -static void ui_drag_panel(uiBlock *block) +static void ui_drag_panel(uiBlock *block, int doscale) { Panel *panel= block->panel; - short align=0, first=1, ofsx, ofsy, dx=0, dy=0, dxo=0, dyo=0, mval[2], mvalo[2]; - + short align=0, first=1, dx=0, dy=0, dxo=0, dyo=0, mval[2], mvalo[2]; + short ofsx, ofsy, sizex, sizey; + if(curarea->spacetype==SPACE_BUTS) { SpaceButs *sbuts= curarea->spacedata.first; align= sbuts->align; @@ -1535,9 +1542,15 @@ static void ui_drag_panel(uiBlock *block) uiGetMouse(block->win, mvalo); ofsx= block->panel->ofsx; ofsy= block->panel->ofsy; + sizex= block->panel->sizex; + sizey= block->panel->sizey; panel->flag |= PNL_SELECT; + /* exception handling, 3d window preview panel */ + if(block->drawextra==BIF_view3d_previewdraw) + BIF_view3d_previewrender_clear(curarea); + while(TRUE) { if( !(get_mbut() & L_MOUSE) ) break; @@ -1554,13 +1567,25 @@ static void ui_drag_panel(uiBlock *block) dxo= dx; dyo= dy; first= 0; - panel->ofsx = ofsx+dx; - panel->ofsy = ofsy+dy; - - check_panel_overlap(curarea, panel); - - if(align) uiAlignPanelStep(curarea, 0.2); + if(doscale) { + panel->sizex = MAX2(sizex+dx, UI_PANEL_MINX); + + if(sizey-dy < UI_PANEL_MINY) { + dy= -UI_PANEL_MINY+sizey; + } + panel->sizey = sizey-dy; + + panel->ofsy= ofsy+dy; + } + else { + panel->ofsx = ofsx+dx; + panel->ofsy = ofsy+dy; + check_panel_overlap(curarea, panel); + + if(align) uiAlignPanelStep(curarea, 0.2); + } + /* warn: this re-allocs blocks! */ scrarea_do_windraw(curarea); ui_redraw_select_panel(curarea); @@ -1594,6 +1619,11 @@ static void ui_drag_panel(uiBlock *block) if(align==0) addqueue(block->win, REDRAW, 1); else ui_animate_panels(curarea); + + /* exception handling, 3d window preview panel */ + if(block->drawextra==BIF_view3d_previewdraw) + BIF_view3d_previewrender_signal(curarea, PR_DISPRECT); + } @@ -1634,7 +1664,7 @@ static void ui_panel_untab(uiBlock *block) pa= pa->next; } - ui_drag_panel(block); + ui_drag_panel(block, 0); break; } @@ -1808,16 +1838,25 @@ void ui_do_panel(uiBlock *block, uiEvent *uevent) } else if(block->panel->flag & PNL_CLOSED) { - ui_drag_panel(block); + ui_drag_panel(block, 0); } /* check if clicked in tabbed area */ else if(uevent->mval[0] < block->maxx-PNL_ICON-3 && panel_has_tabs(block->panel)) { panel_clicked_tabs(block, uevent->mval[0]); } else { - ui_drag_panel(block); + ui_drag_panel(block, 0); } } } +/* panel with scaling widget */ +void ui_scale_panel(uiBlock *block) +{ + if(block->panel->flag & PNL_CLOSED) + return; + + ui_drag_panel(block, 1); +} + diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 09d9f8bb5bf..3a7df18c584 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -604,7 +604,7 @@ void sort_faces(void) typedef struct MocNode { struct MocNode *next; - int index[MOC_NODE_RES]; + long index[MOC_NODE_RES]; } MocNode; static int mesh_octree_get_base_offs(float *co, float *offs, float *div) @@ -622,7 +622,7 @@ static int mesh_octree_get_base_offs(float *co, float *offs, float *div) return (vx*MOC_RES*MOC_RES) + vy*MOC_RES + vz; } -static void mesh_octree_add_node(MocNode **bt, int index) +static void mesh_octree_add_node(MocNode **bt, long index) { if(*bt==NULL) { *bt= MEM_callocN(sizeof(MocNode), "MocNode"); @@ -654,7 +654,7 @@ static void mesh_octree_free_node(MocNode **bt) /* temporal define, just to make nicer code below */ #define MOC_ADDNODE(vx, vy, vz) mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index) -static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, int index) +static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, long index) { float fx, fy, fz; int vx, vy, vz; @@ -695,7 +695,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f } -static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) +static long mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) { float *vec; int a; @@ -708,15 +708,13 @@ static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) /* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */ if(mvert) { vec= (mvert+(*bt)->index[a]-1)->co; - if(FloatCompare(vec, co, MOC_THRESH)) return (*bt)->index[a]-1; } else { - EditVert *eve= (EditVert *)INT_TO_POINTER((*bt)->index[a]); - + EditVert *eve= (EditVert *)((*bt)->index[a]); if(FloatCompare(eve->co, co, MOC_THRESH)) - return (int)eve; + return (*bt)->index[a]; } } else return -1; @@ -730,7 +728,7 @@ static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) /* mode is 's' start, or 'e' end, or 'u' use */ /* if end, ob can be NULL */ -int mesh_octree_table(Object *ob, float *co, char mode) +long mesh_octree_table(Object *ob, float *co, char mode) { MocNode **bt; static MocNode **basetable= NULL; @@ -756,21 +754,23 @@ int mesh_octree_table(Object *ob, float *co, char mode) /* for quick unit coordinate calculus */ VECCOPY(offs, bb->vec[0]); - offs[0]+= MOC_THRESH; /* we offset it 1 threshold unit extra */ - offs[1]+= MOC_THRESH; - offs[2]+= MOC_THRESH; + offs[0]-= MOC_THRESH; /* we offset it 1 threshold unit extra */ + offs[1]-= MOC_THRESH; + offs[2]-= MOC_THRESH; - VecSubf(div, bb->vec[6], offs); - div[0]+= MOC_THRESH; /* and divide with 1 threshold unit more extra (try 8x8 unit grid on paint) */ - div[1]+= MOC_THRESH; - div[2]+= MOC_THRESH; + VecSubf(div, bb->vec[6], bb->vec[0]); + div[0]+= 2*MOC_THRESH; /* and divide with 2 threshold unit more extra (try 8x8 unit grid on paint) */ + div[1]+= 2*MOC_THRESH; + div[2]+= 2*MOC_THRESH; VecMulf(div, 1.0f/MOC_RES); if(div[0]==0.0f) div[0]= 1.0f; if(div[1]==0.0f) div[1]= 1.0f; if(div[2]==0.0f) div[2]= 1.0f; - - if(basetable) /* happens when entering wpaint without closing it */ + printvecf("ofs", offs); + printvecf("div", div); + + if(basetable) /* happens when entering this call without ending it */ mesh_octree_table(ob, co, 'e'); basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table"); @@ -779,12 +779,12 @@ int mesh_octree_table(Object *ob, float *co, char mode) EditVert *eve; for(eve= G.editMesh->verts.first; eve; eve= eve->next) { - mesh_octree_add_nodes(basetable, eve->co, offs, div, POINTER_TO_INT(eve)); + mesh_octree_add_nodes(basetable, eve->co, offs, div, (long)(eve)); } } else { MVert *mvert; - int a; + long a; for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) { mesh_octree_add_nodes(basetable, mvert->co, offs, div, a); @@ -817,3 +817,18 @@ int mesh_get_x_mirror_vert(Object *ob, int index) return mesh_octree_table(ob, vec, 'u'); } + +EditVert *editmesh_get_x_mirror_vert(Object *ob, float *co) +{ + float vec[3]; + long poinval; + + vec[0]= -co[0]; + vec[1]= co[1]; + vec[2]= co[2]; + + poinval= mesh_octree_table(ob, vec, 'u'); + if(poinval != -1) + return (EditVert *)(poinval); + return NULL; +} \ No newline at end of file diff --git a/source/blender/src/mywindow.c b/source/blender/src/mywindow.c index 5a0d8eb3ce1..f211558bacf 100644 --- a/source/blender/src/mywindow.c +++ b/source/blender/src/mywindow.c @@ -478,7 +478,7 @@ void myortho2(float x1, float x2, float y1, float y2) /* prevent opengl from generating errors */ if(x1==x2) x2+=1.0; if(y1==y2) y2+=1.0; - bwin_ortho(curswin, x1, x2, y1, y2, -1, 1); + bwin_ortho(curswin, x1, x2, y1, y2, -100, 100); } void mywindow(float x1, float x2, float y1, float y2, float n, float f) diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 5ebf97d7ecc..1f6c94cf5b0 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -39,6 +39,7 @@ #include "DNA_camera_types.h" #include "DNA_image_types.h" #include "DNA_ipo_types.h" +#include "DNA_group_types.h" #include "DNA_key_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -60,11 +61,13 @@ #include "BKE_constraint.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_group.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_screen.h" +#include "BKE_scene.h" #include "BKE_utildefines.h" #include "BIF_butspace.h" @@ -79,6 +82,7 @@ #include "BIF_gl.h" #include "BIF_graphics.h" #include "BIF_interface.h" +#include "BIF_interface_icons.h" #include "BIF_mywindow.h" #include "BIF_outliner.h" #include "BIF_language.h" @@ -108,7 +112,7 @@ #define TS_CHUNK 128 -#define TREESTORE(a) soops->treestore->data+(a)->store_index +#define TREESTORE(a) ((a)?soops->treestore->data+(a)->store_index:NULL) /* ******************** PERSISTANT DATA ***************** */ @@ -509,13 +513,13 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->name= md->name; if (md->type==eModifierType_Lattice) { - outliner_add_element(soops, &te->subtree, ((LatticeModifierData*) md)->object, te, TSE_MODIFIER_OB, 0); + outliner_add_element(soops, &te->subtree, ((LatticeModifierData*) md)->object, te, TSE_LINKED_OB, 0); } else if (md->type==eModifierType_Curve) { - outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_MODIFIER_OB, 0); + outliner_add_element(soops, &te->subtree, ((CurveModifierData*) md)->object, te, TSE_LINKED_OB, 0); } else if (md->type==eModifierType_Armature) { - outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_MODIFIER_OB, 0); + outliner_add_element(soops, &te->subtree, ((ArmatureModifierData*) md)->object, te, TSE_LINKED_OB, 0); } else if (md->type==eModifierType_Hook) { - outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_MODIFIER_OB, 0); + outliner_add_element(soops, &te->subtree, ((HookModifierData*) md)->object, te, TSE_LINKED_OB, 0); } } } @@ -541,6 +545,10 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i outliner_add_element(soops, &tenla->subtree, ob->scriptlink.scripts[a], te, 0, 0); } } + + if(ob->dup_group) + outliner_add_element(soops, &te->subtree, ob->dup_group, te, 0, 0); + if(ob->nlastrips.first) { bActionStrip *strip; TreeElement *ten; @@ -768,6 +776,25 @@ static void outliner_build_tree(SpaceOops *soops) } outliner_make_hierarchy(soops, &soops->tree); } + else if(soops->outlinevis == SO_GROUPS) { + Group *group; + GroupObject *go; + + for(group= G.main->group.first; group; group= group->id.next) { + if(group->id.us) { + te= outliner_add_element(soops, &soops->tree, group, NULL, 0, 0); + tselem= TREESTORE(te); + + for(go= group->gobject.first; go; go= go->next) { + ten= outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0); + ten->directdata= NULL; + } + outliner_make_hierarchy(soops, &te->subtree); + /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */ + for(go= group->gobject.first; go; go= go->next) go->ob->id.newid= NULL; + } + } + } else if(soops->outlinevis == SO_SAME_TYPE) { Object *ob= OBACT; if(ob) { @@ -1006,8 +1033,9 @@ static int tree_element_active_material(SpaceOops *soops, TreeElement *te, int s } if(set) { extern_set_butspace(F5KEY); // force shading buttons - BIF_all_preview_changed(); + BIF_preview_changed(ID_MA); allqueue(REDRAWBUTSSHADING, 1); + allqueue(REDRAWNODE, 0); allqueue(REDRAWOOPS, 0); allqueue(REDRAWIPO, 0); } @@ -1101,7 +1129,7 @@ static int tree_element_active_lamp(SpaceOops *soops, TreeElement *te, int set) if(set) { extern_set_butspace(F5KEY); - BIF_all_preview_changed(); + BIF_preview_changed(ID_LA); allqueue(REDRAWBUTSSHADING, 1); allqueue(REDRAWOOPS, 0); allqueue(REDRAWIPO, 0); @@ -1406,7 +1434,7 @@ static int tree_element_type_active(SpaceOops *soops, TreeElement *te, TreeStore return tree_element_active_ebone(te, tselem, set); case TSE_MODIFIER: return tree_element_active_modifier(te, tselem, set); - case TSE_MODIFIER_OB: + case TSE_LINKED_OB: if(set) tree_element_active_object(soops, te); else if(tselem->id==(ID *)OBACT) return 1; break; @@ -1456,6 +1484,8 @@ static int do_outliner_mouse_event(SpaceOops *soops, TreeElement *te, short even if(G.qual & LR_CTRLKEY) { if(ELEM5(tselem->type, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, TSE_SCRIPT_BASE)) error("Cannot edit builtin name"); + else if(tselem->id->lib) + error("Cannot edit Library Data"); else { tselem->flag |= TSE_TEXTBUT; } @@ -1689,12 +1719,9 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb) case ID_ME: case ID_CU: case ID_MB: case ID_LT: case ID_LA: case ID_AR: case ID_CA: - idlevel= -2; - break; - case ID_MA: case ID_TE: case ID_IP: case ID_IM: case ID_SO: case ID_KE: case ID_WO: case ID_AC: - case ID_NLA: case ID_TXT: + case ID_NLA: case ID_TXT: case ID_GR: if(idlevel==0) idlevel= idcode; else if(idlevel!=idcode) idlevel= -1; break; @@ -1705,7 +1732,7 @@ static void set_operation_types(SpaceOops *soops, ListBase *lb) } } -static void unlink_material_cb(TreeElement *te, TreeStoreElem *tsep) +static void unlink_material_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { Material **matar=NULL; int a, totcol=0; @@ -1739,7 +1766,7 @@ static void unlink_material_cb(TreeElement *te, TreeStoreElem *tsep) } } -static void unlink_texture_cb(TreeElement *te, TreeStoreElem *tsep) +static void unlink_texture_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { MTex **mtex= NULL; int a; @@ -1768,8 +1795,25 @@ static void unlink_texture_cb(TreeElement *te, TreeStoreElem *tsep) } } +static void unlink_group_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + Group *group= (Group *)tselem->id; + + if(tsep) { + if( GS(tsep->id->name)==ID_OB) { + Object *ob= (Object *)tsep->id; + ob->dup_group= NULL; + group->id.us--; + } + } + else { + unlink_group(group); + group->id.us= 0; + } +} + static void outliner_do_libdata_operation(SpaceOops *soops, ListBase *lb, - void (*operation_cb)(TreeElement *, TreeStoreElem *)) + void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *)) { TreeElement *te; TreeStoreElem *tselem; @@ -1779,7 +1823,7 @@ static void outliner_do_libdata_operation(SpaceOops *soops, ListBase *lb, if(tselem->flag & TSE_SELECTED) { if(tselem->type==0) { TreeStoreElem *tsep= TREESTORE(te->parent); - operation_cb(te, tsep); + operation_cb(te, tsep, tselem); } } if((tselem->flag & TSE_CLOSED)==0) { @@ -1790,26 +1834,33 @@ static void outliner_do_libdata_operation(SpaceOops *soops, ListBase *lb, /* */ -static void object_select_cb(TreeElement *te, TreeStoreElem *tselem) +static void object_select_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { Base *base= (Base *)te->directdata; - base->flag |= SELECT; - base->object->flag |= SELECT; + if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene); + if(base) { + base->flag |= SELECT; + base->object->flag |= SELECT; + } } -static void object_deselect_cb(TreeElement *te, TreeStoreElem *tselem) +static void object_deselect_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { Base *base= (Base *)te->directdata; - base->flag &= ~SELECT; - base->object->flag &= ~SELECT; + if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene); + if(base) { + base->flag &= ~SELECT; + base->object->flag &= ~SELECT; + } } -static void object_delete_cb(TreeElement *te, TreeStoreElem *tselem) +static void object_delete_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) { Base *base= (Base *)te->directdata; + if(base==NULL) base= object_in_scene((Object *)tselem->id, G.scene); if(base) { // check also library later if(G.obedit==base->object) exit_editmode(2); @@ -1825,9 +1876,17 @@ static void object_delete_cb(TreeElement *te, TreeStoreElem *tselem) } } +static void id_local_cb(TreeElement *te, TreeStoreElem *tsep, TreeStoreElem *tselem) +{ + if(tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) { + tselem->id->lib= NULL; + tselem->id->flag= LIB_LOCAL; + new_id(0, tselem->id, 0); + } +} static void outliner_do_object_operation(SpaceOops *soops, ListBase *lb, - void (*operation_cb)(TreeElement *, TreeStoreElem *)) + void (*operation_cb)(TreeElement *, TreeStoreElem *, TreeStoreElem *)) { TreeElement *te; TreeStoreElem *tselem; @@ -1840,7 +1899,7 @@ static void outliner_do_object_operation(SpaceOops *soops, ListBase *lb, Scene *sce= (Scene *)outliner_search_back(soops, te, ID_SCE); if(sce && G.scene != sce) set_scene(sce); - operation_cb(te, tselem); + operation_cb(te, NULL, tselem); } } if((tselem->flag & TSE_CLOSED)==0) { @@ -1931,7 +1990,7 @@ void outliner_operation_menu(ScrArea *sa) //else pupmenu("Scene Operations%t|Delete"); } else if(objectlevel) { - short event= pupmenu("Object Operations%t|Select%x1|Deselect%x2|Delete%x4"); + short event= pupmenu("Object Operations%t|Select%x1|Deselect%x2|Delete%x4|Make Local%x5"); if(event>0) { char *str=""; @@ -1951,18 +2010,21 @@ void outliner_operation_menu(ScrArea *sa) DAG_scene_sort(G.scene); str= "Delete Objects"; } + else if(event==5) { + outliner_do_object_operation(soops, &soops->tree, id_local_cb); + str= "Localized Objects"; + } countall(); BIF_undo_push(str); - allqueue(REDRAWALL, 0); // yah... to be sure :) + allqueue(REDRAWALL, 0); } } else if(idlevel) { if(idlevel==-1 || datalevel) error("Mixed selection"); - else if(idlevel==-2) error("No operations available"); else { - short event= pupmenu("Data Operations%t|Unlink"); + short event= pupmenu("Data Operations%t|Unlink %x1|Make Local %x2"); if(event==1) { switch(idlevel) { @@ -1976,12 +2038,19 @@ void outliner_operation_menu(ScrArea *sa) allqueue(REDRAWBUTSSHADING, 1); BIF_undo_push("Unlink texture"); break; + case ID_GR: + outliner_do_libdata_operation(soops, &soops->tree, unlink_group_cb); + BIF_undo_push("Unlink group"); + break; default: error("Not yet..."); } - allqueue(REDRAWOOPS, 0); - allqueue(REDRAWBUTSALL, 0); - allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWALL, 0); + } + else if(event==2) { + outliner_do_libdata_operation(soops, &soops->tree, id_local_cb); + BIF_undo_push("Localized Data"); + allqueue(REDRAWALL, 0); } } } @@ -2025,102 +2094,104 @@ static void tselem_draw_icon(float x, float y, TreeStoreElem *tselem, TreeElemen if(tselem->type) { switch( tselem->type) { case TSE_NLA: - BIF_draw_icon(x, y, ICON_NLA); break; + BIF_icon_draw(x, y, ICON_NLA); break; case TSE_NLA_ACTION: - BIF_draw_icon(x, y, ICON_ACTION); break; + BIF_icon_draw(x, y, ICON_ACTION); break; case TSE_DEFGROUP_BASE: - BIF_draw_icon(x, y, ICON_VERTEXSEL); break; + BIF_icon_draw(x, y, ICON_VERTEXSEL); break; case TSE_BONE: case TSE_EBONE: - BIF_draw_icon(x, y, ICON_WPAINT_DEHLT); break; + BIF_icon_draw(x, y, ICON_WPAINT_DEHLT); break; case TSE_CONSTRAINT_BASE: - BIF_draw_icon(x, y, ICON_CONSTRAINT); break; + BIF_icon_draw(x, y, ICON_CONSTRAINT); break; case TSE_MODIFIER_BASE: - BIF_draw_icon(x, y, ICON_MODIFIER); break; - case TSE_MODIFIER_OB: - BIF_draw_icon(x, y, ICON_OBJECT); break; + BIF_icon_draw(x, y, ICON_MODIFIER); break; + case TSE_LINKED_OB: + BIF_icon_draw(x, y, ICON_OBJECT); break; case TSE_MODIFIER: { Object *ob= (Object *)tselem->id; ModifierData *md= BLI_findlink(&ob->modifiers, tselem->nr); switch(md->type) { case eModifierType_Subsurf: - BIF_draw_icon(x, y, ICON_MOD_SUBSURF); break; + BIF_icon_draw(x, y, ICON_MOD_SUBSURF); break; case eModifierType_Armature: - BIF_draw_icon(x, y, ICON_ARMATURE); break; + BIF_icon_draw(x, y, ICON_ARMATURE); break; case eModifierType_Lattice: - BIF_draw_icon(x, y, ICON_LATTICE); break; + BIF_icon_draw(x, y, ICON_LATTICE); break; case eModifierType_Curve: - BIF_draw_icon(x, y, ICON_CURVE); break; + BIF_icon_draw(x, y, ICON_CURVE); break; case eModifierType_Build: - BIF_draw_icon(x, y, ICON_MOD_BUILD); break; + BIF_icon_draw(x, y, ICON_MOD_BUILD); break; case eModifierType_Mirror: - BIF_draw_icon(x, y, ICON_MOD_MIRROR); break; + BIF_icon_draw(x, y, ICON_MOD_MIRROR); break; case eModifierType_Decimate: - BIF_draw_icon(x, y, ICON_MOD_DECIM); break; + BIF_icon_draw(x, y, ICON_MOD_DECIM); break; case eModifierType_Wave: - BIF_draw_icon(x, y, ICON_MOD_WAVE); break; + BIF_icon_draw(x, y, ICON_MOD_WAVE); break; case eModifierType_Hook: - BIF_draw_icon(x, y, ICON_HOOK); break; + BIF_icon_draw(x, y, ICON_HOOK); break; case eModifierType_Softbody: - BIF_draw_icon(x, y, ICON_MOD_SOFT); break; + BIF_icon_draw(x, y, ICON_MOD_SOFT); break; case eModifierType_Boolean: - BIF_draw_icon(x, y, ICON_MOD_BOOLEAN); break; + BIF_icon_draw(x, y, ICON_MOD_BOOLEAN); break; default: - BIF_draw_icon(x, y, ICON_DOT); break; + BIF_icon_draw(x, y, ICON_DOT); break; } break; } case TSE_SCRIPT_BASE: - BIF_draw_icon(x, y, ICON_TEXT); break; + BIF_icon_draw(x, y, ICON_TEXT); break; case TSE_POSE_BASE: - BIF_draw_icon(x, y, ICON_ARMATURE_DEHLT); break; + BIF_icon_draw(x, y, ICON_ARMATURE_DEHLT); break; case TSE_POSE_CHANNEL: - BIF_draw_icon(x, y, ICON_WPAINT_DEHLT); break; + BIF_icon_draw(x, y, ICON_WPAINT_DEHLT); break; default: - BIF_draw_icon(x, y, ICON_DOT); break; + BIF_icon_draw(x, y, ICON_DOT); break; } } else { switch( GS(tselem->id->name)) { case ID_SCE: - BIF_draw_icon(x, y, ICON_SCENE_DEHLT); break; + BIF_icon_draw(x, y, ICON_SCENE_DEHLT); break; case ID_OB: - BIF_draw_icon(x, y, ICON_OBJECT); break; + BIF_icon_draw(x, y, ICON_OBJECT); break; case ID_ME: - BIF_draw_icon(x, y, ICON_MESH); break; + BIF_icon_draw(x, y, ICON_MESH); break; case ID_CU: - BIF_draw_icon(x, y, ICON_CURVE); break; + BIF_icon_draw(x, y, ICON_CURVE); break; case ID_MB: - BIF_draw_icon(x, y, ICON_MBALL); break; + BIF_icon_draw(x, y, ICON_MBALL); break; case ID_LT: - BIF_draw_icon(x, y, ICON_LATTICE); break; + BIF_icon_draw(x, y, ICON_LATTICE); break; case ID_LA: - BIF_draw_icon(x, y, ICON_LAMP_DEHLT); break; + BIF_icon_draw(x, y, ICON_LAMP_DEHLT); break; case ID_MA: - BIF_draw_icon(x, y, ICON_MATERIAL_DEHLT); break; + BIF_icon_draw(x, y, ICON_MATERIAL_DEHLT); break; case ID_TE: - BIF_draw_icon(x, y, ICON_TEXTURE_DEHLT); break; + BIF_icon_draw(x, y, ICON_TEXTURE_DEHLT); break; case ID_IP: - BIF_draw_icon(x, y, ICON_IPO_DEHLT); break; + BIF_icon_draw(x, y, ICON_IPO_DEHLT); break; case ID_IM: - BIF_draw_icon(x, y, ICON_IMAGE_DEHLT); break; + BIF_icon_draw(x, y, ICON_IMAGE_DEHLT); break; case ID_SO: - BIF_draw_icon(x, y, ICON_SPEAKER); break; + BIF_icon_draw(x, y, ICON_SPEAKER); break; case ID_AR: - BIF_draw_icon(x, y, ICON_ARMATURE); break; + BIF_icon_draw(x, y, ICON_ARMATURE); break; case ID_CA: - BIF_draw_icon(x, y, ICON_CAMERA_DEHLT); break; + BIF_icon_draw(x, y, ICON_CAMERA_DEHLT); break; case ID_KE: - BIF_draw_icon(x, y, ICON_EDIT_DEHLT); break; + BIF_icon_draw(x, y, ICON_EDIT_DEHLT); break; case ID_WO: - BIF_draw_icon(x, y, ICON_WORLD_DEHLT); break; + BIF_icon_draw(x, y, ICON_WORLD_DEHLT); break; case ID_AC: - BIF_draw_icon(x, y, ICON_ACTION); break; + BIF_icon_draw(x, y, ICON_ACTION); break; case ID_NLA: - BIF_draw_icon(x, y, ICON_NLA); break; + BIF_icon_draw(x, y, ICON_NLA); break; case ID_TXT: - BIF_draw_icon(x, y, ICON_SCRIPT); break; + BIF_icon_draw(x, y, ICON_SCRIPT); break; + case ID_GR: + BIF_icon_draw(x, y, ICON_CIRCLE_DEHLT); break; } } } @@ -2223,7 +2294,7 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st if(active) { uiSetRoundBox(15); uiRoundBox( (float)startx+OL_H-1.5, (float)*starty+2.0, (float)startx+2*OL_H-4.0, (float)*starty+OL_H-1.0, OL_H/2.0-2.0); - glEnable(GL_BLEND); + glEnable(GL_BLEND); /* roundbox disables it */ te->flag |= TE_ACTIVE; // for lookup in display hierarchies } @@ -2238,9 +2309,9 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st // icons a bit higher if(tselem->flag & TSE_CLOSED) - BIF_draw_icon(icon_x, *starty+2, ICON_TRIA_RIGHT); + BIF_icon_draw(icon_x, *starty+2, ICON_TRIA_RIGHT); else - BIF_draw_icon(icon_x, *starty+2, ICON_TRIA_DOWN); + BIF_icon_draw(icon_x, *starty+2, ICON_TRIA_DOWN); } offsx+= OL_X; @@ -2249,6 +2320,16 @@ static void outliner_draw_tree_element(SpaceOops *soops, TreeElement *te, int st // icons a bit higher tselem_draw_icon(startx+offsx, *starty+2, tselem, te); offsx+= OL_X; + + if(tselem->id->lib && tselem->type==0) { + glPixelTransferf(GL_ALPHA_SCALE, 0.5); + if(tselem->id->flag & LIB_INDIRECT) + BIF_icon_draw(startx+offsx, *starty+2, ICON_DATALIB); + else + BIF_icon_draw(startx+offsx, *starty+2, ICON_PARLIB); + glPixelTransferf(GL_ALPHA_SCALE, 1.0); + offsx+= OL_X; + } glDisable(GL_BLEND); /* name */ diff --git a/source/blender/src/parametrizer.c b/source/blender/src/parametrizer.c new file mode 100644 index 00000000000..6d8ede47a0f --- /dev/null +++ b/source/blender/src/parametrizer.c @@ -0,0 +1,1893 @@ + +#include "MEM_guardedalloc.h" + +#include "BLI_memarena.h" +#include "BLI_arithb.h" +#include "BLI_rand.h" + +#include "BKE_utildefines.h" + +#include "BIF_editsima.h" +#include "BIF_toolbox.h" + +#include "ONL_opennl.h" + +#include "parametrizer.h" +#include "parametrizer_intern.h" + +#include +#include +#include +#include + +#if defined(_WIN32) +#define M_PI 3.14159265358979323846 +#endif + +/* Hash */ + +static int PHashSizes[] = { + 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, + 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459 +}; + +#define PHASH_hash(ph, item) (((unsigned long) (item))%((unsigned int) (ph)->cursize)) + +PHash *phash_new(int sizehint) +{ + PHash *ph = (PHash*)MEM_callocN(sizeof(PHash), "PHash"); + ph->size = 0; + ph->cursize_id = 0; + ph->first = NULL; + + while (PHashSizes[ph->cursize_id] < sizehint) + ph->cursize_id++; + + ph->cursize = PHashSizes[ph->cursize_id]; + ph->buckets = (PHashLink**)MEM_callocN(ph->cursize*sizeof(*ph->buckets), "PHashBuckets"); + + return ph; +} + +void phash_delete(PHash *ph) +{ + MEM_freeN(ph->buckets); + MEM_freeN(ph); +} + +void phash_delete_with_links(PHash *ph) +{ + PHashLink *link, *next=NULL; + + for (link = ph->first; link; link = next) { + next = link->next; + MEM_freeN(link); + } + + phash_delete(ph); +} + +int phash_size(PHash *ph) +{ + return ph->size; +} + +void phash_insert(PHash *ph, PHashLink *link) +{ + int size = ph->cursize; + int hash = PHASH_hash(ph, link->key); + PHashLink *lookup = ph->buckets[hash]; + + if (lookup == NULL) { + /* insert in front of the list */ + ph->buckets[hash] = link; + link->next = ph->first; + ph->first = link; + } + else { + /* insert after existing element */ + link->next = lookup->next; + lookup->next = link; + } + + ph->size++; + + if (ph->size > (size*3)) { + PHashLink *next = NULL, *first = ph->first; + + ph->cursize = PHashSizes[++ph->cursize_id]; + MEM_freeN(ph->buckets); + ph->buckets = (PHashLink**)MEM_callocN(ph->cursize*sizeof(*ph->buckets), "PHashBuckets"); + ph->size = 0; + ph->first = NULL; + + for (link = first; link; link = next) { + next = link->next; + phash_insert(ph, link); + } + } +} + +PHashLink *phash_lookup(PHash *ph, PHashKey key) +{ + PHashLink *link; + int hash = PHASH_hash(ph, key); + + for (link = ph->buckets[hash]; link; link = link->next) + if (link->key == key) + return link; + else if (PHASH_hash(ph, link->key) != hash) + return NULL; + + return link; +} + +PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link) +{ + int hash = PHASH_hash(ph, key); + + for (link = link->next; link; link = link->next) + if (link->key == key) + return link; + else if (PHASH_hash(ph, link->key) != hash) + return NULL; + + return link; +} + +/* Heap */ + +#define PHEAP_PARENT(i) ((i-1)>>1) +#define PHEAP_LEFT(i) ((i<<1)+1) +#define PHEAP_RIGHT(i) ((i<<1)+2) +#define PHEAP_COMPARE(a, b) (a->value < b->value) +#define PHEAP_EQUALS(a, b) (a->value == b->value) +#define PHEAP_SWAP(heap, i, j) \ + { SWAP(int, heap->tree[i]->index, heap->tree[j]->index); \ + SWAP(PHeapLink*, heap->tree[i], heap->tree[j]); } + +static void pheap_down(PHeap *heap, int i) +{ + while (P_TRUE) { + int size = heap->size, smallest; + int l = PHEAP_LEFT(i); + int r = PHEAP_RIGHT(i); + + smallest = ((l < size) && PHEAP_COMPARE(heap->tree[l], heap->tree[i]))? l: i; + + if ((r < size) && PHEAP_COMPARE(heap->tree[r], heap->tree[smallest])) + smallest = r; + + if (smallest == i) + break; + + PHEAP_SWAP(heap, i, smallest); + i = smallest; + } +} + +static void pheap_up(PHeap *heap, int i) +{ + while (i > 0) { + int p = PHEAP_PARENT(i); + + if (PHEAP_COMPARE(heap->tree[p], heap->tree[i])) + break; + + PHEAP_SWAP(heap, p, i); + i = p; + } +} + +PHeap *pheap_new() +{ + /* TODO: replace mallocN with something faster */ + + PHeap *heap = (PHeap*)MEM_callocN(sizeof(PHeap), "PHeap"); + heap->bufsize = 1; + heap->tree = (PHeapLink**)MEM_mallocN(sizeof(PHeapLink*), "PHeapTree"); + + return heap; +} + +void pheap_delete(PHeap *heap) +{ + MEM_freeN(heap->tree); + MEM_freeN(heap); +} + +PHeapLink *pheap_insert(PHeap *heap, float value, void *ptr) +{ + PHeapLink *link; + + if ((heap->size + 1) > heap->bufsize) { + int newsize = heap->bufsize*2; + + PHeapLink **ntree = (PHeapLink**)MEM_mallocN(newsize*sizeof(PHeapLink*), "PHeapTree"); + memcpy(ntree, heap->tree, sizeof(PHeapLink*)*heap->size); + MEM_freeN(heap->tree); + + heap->tree = ntree; + heap->bufsize = newsize; + } + + param_assert(heap->size < heap->bufsize); + + link = MEM_mallocN(sizeof *link, "PHeapLink"); + link->value = value; + link->ptr = ptr; + link->index = heap->size; + + heap->tree[link->index] = link; + + heap->size++; + + pheap_up(heap, heap->size-1); + + return link; +} + +int pheap_empty(PHeap *heap) +{ + return (heap->size == 0); +} + +int pheap_size(PHeap *heap) +{ + return heap->size; +} + +void *pheap_min(PHeap *heap) +{ + return heap->tree[0]->ptr; +} + +void *pheap_popmin(PHeap *heap) +{ + void *ptr = heap->tree[0]->ptr; + + MEM_freeN(heap->tree[0]); + + if (heap->size == 1) + heap->size--; + else { + PHEAP_SWAP(heap, 0, heap->size-1); + heap->size--; + + pheap_down(heap, 0); + } + + return ptr; +} + +static void pheap_remove(PHeap *heap, PHeapLink *link) +{ + int i = link->index; + + while (i > 0) { + int p = PHEAP_PARENT(i); + + PHEAP_SWAP(heap, p, i); + i = p; + } + + pheap_popmin(heap); +} + +/* Construction */ + +PEdge *p_wheel_edge_next(PEdge *e) +{ + return e->next->next->pair; +} + +PEdge *p_wheel_edge_prev(PEdge *e) +{ + return (e->pair)? e->pair->next: NULL; +} + +static PVert *p_vert_add(PChart *chart, PHashKey key, float *co, PEdge *e) +{ + PVert *v = (PVert*)BLI_memarena_alloc(chart->handle->arena, sizeof *v); + v->co = co; + v->link.key = key; + v->edge = e; + v->flag = 0; + + phash_insert(chart->verts, (PHashLink*)v); + + return v; +} + +static PVert *p_vert_lookup(PChart *chart, PHashKey key, float *co, PEdge *e) +{ + PVert *v = (PVert*)phash_lookup(chart->verts, key); + + if (v) + return v; + else + return p_vert_add(chart, key, co, e); +} + +static PVert *p_vert_copy(PChart *chart, PVert *v) +{ + PVert *nv = (PVert*)BLI_memarena_alloc(chart->handle->arena, sizeof *nv); + nv->co = v->co; + nv->uv[0] = v->uv[0]; + nv->uv[1] = v->uv[1]; + nv->link.key = v->link.key; + nv->edge = v->edge; + nv->flag = v->flag; + + phash_insert(chart->verts, (PHashLink*)nv); + + return nv; +} + +static PEdge *p_edge_lookup(PChart *chart, PHashKey *vkeys) +{ + PHashKey key = vkeys[0]^vkeys[1]; + PEdge *e = (PEdge*)phash_lookup(chart->edges, key); + + while (e) { + if ((e->vert->link.key == vkeys[0]) && (e->next->vert->link.key == vkeys[1])) + return e; + else if ((e->vert->link.key == vkeys[1]) && (e->next->vert->link.key == vkeys[0])) + return e; + + e = (PEdge*)phash_next(chart->edges, key, (PHashLink*)e); + } + + return NULL; +} + +static void p_face_flip(PFace *f) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + int f1 = e1->flag, f2 = e2->flag, f3 = e3->flag; + + e1->vert = v2; + e1->next = e3; + e1->flag = (f1 & ~PEDGE_VERTEX_FLAGS) | (f2 & PEDGE_VERTEX_FLAGS); + + e2->vert = v3; + e2->next = e1; + e2->flag = (f2 & ~PEDGE_VERTEX_FLAGS) | (f3 & PEDGE_VERTEX_FLAGS); + + e3->vert = v1; + e3->next = e2; + e3->flag = (f3 & ~PEDGE_VERTEX_FLAGS) | (f1 & PEDGE_VERTEX_FLAGS); +} + +static void p_vert_load_pin_select_uvs(PVert *v) +{ + PEdge *e; + int nedges = 0; + + v->uv[0] = v->uv[1] = 0.0f; + nedges = 0; + e = v->edge; + do { + if (e->orig_uv && (e->flag & PEDGE_PIN)) { + if (e->flag & PEDGE_SELECT) + v->flag |= PVERT_SELECT; + + v->flag |= PVERT_PIN; + v->uv[0] += e->orig_uv[0]; + v->uv[1] += e->orig_uv[1]; + nedges++; + } + + e = p_wheel_edge_next(e); + } while (e && e != (v->edge)); + + if (nedges > 0) { + v->uv[0] /= nedges; + v->uv[1] /= nedges; + } +} + +static void p_vert_load_select_uvs(PVert *v) +{ + PEdge *e; + int nedges = 0; + + v->uv[0] = v->uv[1] = 0.0f; + nedges = 0; + e = v->edge; + do { + if (e->orig_uv && (e->flag & PEDGE_SELECT)) + v->flag |= PVERT_SELECT; + + v->uv[0] += e->orig_uv[0]; + v->uv[1] += e->orig_uv[1]; + nedges++; + + e = p_wheel_edge_next(e); + } while (e && e != (v->edge)); + + if (nedges > 0) { + v->uv[0] /= nedges; + v->uv[1] /= nedges; + } +} + +static void p_extrema_verts(PChart *chart, PVert **v1, PVert **v2) +{ + float minv[3], maxv[3], dirlen; + PVert *v, *minvert[3], *maxvert[3]; + int i, dir; + + /* find minimum and maximum verts over x/y/z axes */ + minv[0] = minv[1] = minv[2] = 1e20; + maxv[0] = maxv[1] = maxv[2] = -1e20; + + minvert[0] = minvert[1] = minvert[2] = NULL; + maxvert[0] = maxvert[1] = maxvert[2] = NULL; + + for (v = (PVert*)chart->verts->first; v; v=v->link.next) { + for (i = 0; i < 3; i++) { + if (v->co[i] < minv[i]) { + minv[i] = v->co[i]; + minvert[i] = v; + } + if (v->co[i] > maxv[i]) { + maxv[i] = v->co[i]; + maxvert[i] = v; + } + } + } + + /* find axes with longest distance */ + dir = 0; + dirlen = -1.0; + + for (i = 0; i < 3; i++) { + if (maxv[i] - minv[i] > dirlen) { + dir = i; + dirlen = maxv[i] - minv[i]; + } + } + + if (minvert[dir] == maxvert[dir]) { + /* degenerate case */ + PFace *f = (PFace*)chart->faces->first; + *v1 = f->edge->vert; + *v2 = f->edge->next->vert; + + (*v1)->uv[0] = 0.0f; + (*v1)->uv[1] = 0.5f; + (*v2)->uv[0] = 1.0f; + (*v2)->uv[1] = 0.5f; + } + else { + *v1 = minvert[dir]; + *v2 = maxvert[dir]; + + (*v1)->uv[0] = (*v1)->co[dir]; + (*v1)->uv[1] = (*v1)->co[(dir+1)%3]; + (*v2)->uv[0] = (*v2)->co[dir]; + (*v2)->uv[1] = (*v2)->co[(dir+1)%3]; + } +} + +static float p_vec_normalise(float *v) +{ + float d; + + d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); + + if(d != 0.0f) { + d = 1.0f/d; + + v[0] *= d; + v[1] *= d; + v[2] *= d; + } + + return d; +} + +static float p_vec_angle_cos(float *v1, float *v2, float *v3) +{ + float d1[3], d2[3]; + + d1[0] = v1[0] - v2[0]; + d1[1] = v1[1] - v2[1]; + d1[2] = v1[2] - v2[2]; + + d2[0] = v3[0] - v2[0]; + d2[1] = v3[1] - v2[1]; + d2[2] = v3[2] - v2[2]; + + p_vec_normalise(d1); + p_vec_normalise(d2); + + return d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]; +} + +static float p_vec_angle(float *v1, float *v2, float *v3) +{ + float dot = p_vec_angle_cos(v1, v2, v3); + + if (dot <= -1.0f) + return (float)M_PI; + else if (dot >= 1.0f) + return 0.0f; + else + return (float)acos(dot); +} + +static void p_face_angles(PFace *f, float *a1, float *a2, float *a3) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + + *a1 = p_vec_angle(v3->co, v1->co, v2->co); + *a2 = p_vec_angle(v1->co, v2->co, v3->co); + *a3 = M_PI - *a2 - *a1; +} + +static float p_face_area(PFace *f) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + + return AreaT3Dfl(v1->co, v2->co, v3->co); +} + +static float p_face_uv_area_signed(PFace *f) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + + return 0.5f*(((v2->uv[0]-v1->uv[0]) * (v3->uv[1]-v1->uv[1])) - + ((v3->uv[0]-v1->uv[0]) * (v2->uv[1]-v1->uv[1]))); +} + +static float p_face_uv_area(PFace *f) +{ + return fabs(p_face_uv_area_signed(f)); +} + +static void p_chart_area(PChart *chart, float *uv_area, float *area) +{ + PFace *f; + + *uv_area = *area = 0.0f; + + for (f=(PFace*)chart->faces->first; f; f=f->link.next) { + *uv_area += p_face_uv_area(f); + *area += p_face_area(f); + } +} + +static PChart *p_chart_new(PHandle *handle) +{ + PChart *chart = (PChart*)MEM_callocN(sizeof*chart, "PChart"); + chart->verts = phash_new(1); + chart->edges = phash_new(1); + chart->faces = phash_new(1); + chart->handle = handle; + + return chart; +} + +static void p_chart_delete(PChart *chart) +{ + /* the actual links are free by memarena */ + phash_delete(chart->verts); + phash_delete(chart->edges); + phash_delete(chart->faces); + + MEM_freeN(chart); +} + +static PBool p_edge_implicit_seam(PEdge *e, PEdge *ep) +{ + float *uv1, *uv2, *uvp1, *uvp2; + float limit[2]; + + uv1 = e->orig_uv; + uv2 = e->next->orig_uv; + + if (e->vert->link.key == ep->vert->link.key) { + uvp1 = ep->orig_uv; + uvp2 = ep->next->orig_uv; + } + else { + uvp1 = ep->next->orig_uv; + uvp2 = ep->orig_uv; + } + + get_connected_limit_tface_uv(limit); + + if((fabs(uv1[0]-uvp1[0]) > limit[0]) && (fabs(uv1[1]-uvp1[1]) > limit[1])) { + e->flag |= PEDGE_SEAM; + ep->flag |= PEDGE_SEAM; + return P_TRUE; + } + if((fabs(uv2[0]-uvp2[0]) > limit[0]) && (fabs(uv2[1]-uvp2[1]) > limit[1])) { + e->flag |= PEDGE_SEAM; + ep->flag |= PEDGE_SEAM; + return P_TRUE; + } + + return P_FALSE; +} + +static PBool p_edge_has_pair(PChart *chart, PEdge *e, PEdge **pair, PBool impl) +{ + PHashKey key; + PEdge *pe; + PVert *v1, *v2; + PHashKey key1 = e->vert->link.key; + PHashKey key2 = e->next->vert->link.key; + + if (e->flag & PEDGE_SEAM) + return P_FALSE; + + key = key1 ^ key2; + pe = (PEdge*)phash_lookup(chart->edges, key); + *pair = NULL; + + while (pe) { + if (pe != e) { + v1 = pe->vert; + v2 = pe->next->vert; + + if (((v1->link.key == key1) && (v2->link.key == key2)) || + ((v1->link.key == key2) && (v2->link.key == key1))) { + + /* don't connect seams and t-junctions */ + if ((pe->flag & PEDGE_SEAM) || *pair || + (impl && p_edge_implicit_seam(e, pe))) { + *pair = NULL; + return P_FALSE; + } + + *pair = pe; + } + } + + pe = (PEdge*)phash_next(chart->edges, key, (PHashLink*)pe); + } + + if (*pair && (e->vert == (*pair)->vert)) { + if ((*pair)->next->pair || (*pair)->next->next->pair) { + /* non unfoldable, maybe mobius ring or klein bottle */ + *pair = NULL; + return P_FALSE; + } + } + + return (*pair != NULL); +} + +static PBool p_edge_connect_pair(PChart *chart, PEdge *e, PEdge ***stack, PBool impl) +{ + PEdge *pair = NULL; + + if(!e->pair && p_edge_has_pair(chart, e, &pair, impl)) { + if (e->vert == pair->vert) + p_face_flip(pair->face); + + e->pair = pair; + pair->pair = e; + + if (!(pair->face->flag & PFACE_CONNECTED)) { + **stack = pair; + (*stack)++; + } + } + + return (e->pair != NULL); +} + +static int p_connect_pairs(PChart *chart, PBool impl) +{ + PEdge **stackbase = MEM_mallocN(sizeof*stackbase * phash_size(chart->faces), "Pstackbase"); + PEdge **stack = stackbase; + PFace *f, *first; + PEdge *e, *e1, *e2; + int ncharts = 0; + + /* connect pairs, count edges, set vertex-edge pointer to a pairless edge */ + for (first=(PFace*)chart->faces->first; first; first=first->link.next) { + if (first->flag & PFACE_CONNECTED) + continue; + + *stack = first->edge; + stack++; + + while (stack != stackbase) { + stack--; + e = *stack; + e1 = e->next; + e2 = e1->next; + + f = e->face; + f->flag |= PFACE_CONNECTED; + + /* assign verts to charts so we can sort them later */ + f->u.chart = ncharts; + + if (!p_edge_connect_pair(chart, e, &stack, impl)) + e->vert->edge = e; + if (!p_edge_connect_pair(chart, e1, &stack, impl)) + e1->vert->edge = e1; + if (!p_edge_connect_pair(chart, e2, &stack, impl)) + e2->vert->edge = e2; + } + + ncharts++; + } + + MEM_freeN(stackbase); + + return ncharts; +} + +static void p_split_vert(PChart *chart, PEdge *e) +{ + PEdge *we, *lastwe = NULL; + PVert *v = e->vert; + PBool copy = P_TRUE; + + if (e->flag & PEDGE_VERTEX_SPLIT) + return; + + /* rewind to start */ + lastwe = e; + for (we = p_wheel_edge_prev(e); we && (we != e); we = p_wheel_edge_prev(we)) + lastwe = we; + + /* go over all edges in wheel */ + for (we = lastwe; we; we = p_wheel_edge_next(we)) { + if (we->flag & PEDGE_VERTEX_SPLIT) + break; + + we->flag |= PEDGE_VERTEX_SPLIT; + + if (we == v->edge) { + /* found it, no need to copy */ + copy = P_FALSE; + phash_insert(chart->verts, (PHashLink*)v); + } + } + + if (copy) { + /* not found, copying */ + v = p_vert_copy(chart, v); + v->edge = lastwe; + + we = lastwe; + do { + we->vert = v; + we = p_wheel_edge_next(we); + } while (we && (we != lastwe)); + } +} + +static PChart **p_split_charts(PHandle *handle, PChart *chart, int ncharts) +{ + PChart **charts = MEM_mallocN(sizeof*charts * ncharts, "PCharts"), *nchart; + PFace *f, *nextf; + int i; + + for (i = 0; i < ncharts; i++) + charts[i] = p_chart_new(handle); + + f = (PFace*)chart->faces->first; + while (f) { + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + nextf = f->link.next; + + nchart = charts[f->u.chart]; + + phash_insert(nchart->faces, (PHashLink*)f); + phash_insert(nchart->edges, (PHashLink*)e1); + phash_insert(nchart->edges, (PHashLink*)e2); + phash_insert(nchart->edges, (PHashLink*)e3); + + p_split_vert(nchart, e1); + p_split_vert(nchart, e2); + p_split_vert(nchart, e3); + + f = nextf; + } + + return charts; +} + +static void p_face_backup_uvs(PFace *f) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + + e1->old_uv[0] = e1->orig_uv[0]; + e1->old_uv[1] = e1->orig_uv[1]; + e2->old_uv[0] = e2->orig_uv[0]; + e2->old_uv[1] = e2->orig_uv[1]; + e3->old_uv[0] = e3->orig_uv[0]; + e3->old_uv[1] = e3->orig_uv[1]; +} + +static void p_face_restore_uvs(PFace *f) +{ + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + + e1->orig_uv[0] = e1->old_uv[0]; + e1->orig_uv[1] = e1->old_uv[1]; + e2->orig_uv[0] = e2->old_uv[0]; + e2->orig_uv[1] = e2->old_uv[1]; + e3->orig_uv[0] = e3->old_uv[0]; + e3->orig_uv[1] = e3->old_uv[1]; +} + +static PFace *p_face_add(PChart *chart, ParamKey key, ParamKey *vkeys, + float *co[3], float *uv[3], int i1, int i2, int i3, + ParamBool *pin, ParamBool *select) +{ + PFace *f; + PEdge *e1, *e2, *e3; + + /* allocate */ + f = (PFace*)BLI_memarena_alloc(chart->handle->arena, sizeof *f); + f->flag=0; // init ! + + e1 = (PEdge*)BLI_memarena_alloc(chart->handle->arena, sizeof *e1); + e2 = (PEdge*)BLI_memarena_alloc(chart->handle->arena, sizeof *e2); + e3 = (PEdge*)BLI_memarena_alloc(chart->handle->arena, sizeof *e3); + + + + + /* set up edges */ + f->edge = e1; + e1->face = e2->face = e3->face = f; + + e1->next = e2; + e2->next = e3; + e3->next = e1; + + e1->pair = NULL; + e2->pair = NULL; + e3->pair = NULL; + + e1->flag =0; + e2->flag =0; + e3->flag =0; + + + if (co && uv) { + e1->vert = p_vert_lookup(chart, vkeys[i1], co[i1], e1); + e2->vert = p_vert_lookup(chart, vkeys[i2], co[i2], e2); + e3->vert = p_vert_lookup(chart, vkeys[i3], co[i3], e3); + + e1->orig_uv = uv[i1]; + e2->orig_uv = uv[i2]; + e3->orig_uv = uv[i3]; + + } + else { + /* internal call to add face */ + e1->vert = e2->vert = e3->vert = NULL; + e1->orig_uv = e2->orig_uv = e3->orig_uv = NULL; + } + + if (pin) { + if (pin[i1]) e1->flag |= PEDGE_PIN; + if (pin[i2]) e2->flag |= PEDGE_PIN; + if (pin[i3]) e3->flag |= PEDGE_PIN; + } + + if (select) { + if (select[i1]) e1->flag |= PEDGE_SELECT; + if (select[i2]) e2->flag |= PEDGE_SELECT; + if (select[i3]) e3->flag |= PEDGE_SELECT; + } + + /* insert into hash */ + f->link.key = key; + phash_insert(chart->faces, (PHashLink*)f); + + e1->link.key = vkeys[i1]^vkeys[i2]; + e2->link.key = vkeys[i2]^vkeys[i3]; + e3->link.key = vkeys[i3]^vkeys[i1]; + + phash_insert(chart->edges, (PHashLink*)e1); + phash_insert(chart->edges, (PHashLink*)e2); + phash_insert(chart->edges, (PHashLink*)e3); + + return f; +} + +static PBool p_quad_split_direction(float **co) +{ + float a1, a2; + + a1 = p_vec_angle_cos(co[0], co[1], co[2]); + a1 += p_vec_angle_cos(co[1], co[0], co[2]); + a1 += p_vec_angle_cos(co[2], co[0], co[1]); + + a2 = p_vec_angle_cos(co[0], co[1], co[3]); + a2 += p_vec_angle_cos(co[1], co[0], co[3]); + a2 += p_vec_angle_cos(co[3], co[0], co[1]); + + return (a1 > a2); +} + +static float p_edge_length(PEdge *e) +{ + PVert *v1 = e->vert, *v2 = e->next->vert; + float d[3]; + + d[0] = v2->co[0] - v1->co[0]; + d[1] = v2->co[1] - v1->co[1]; + d[2] = v2->co[2] - v1->co[2]; + + return sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]); +} + +static float p_edge_uv_length(PEdge *e) +{ + PVert *v1 = e->vert, *v2 = e->next->vert; + float d[3]; + + d[0] = v2->uv[0] - v1->uv[0]; + d[1] = v2->uv[1] - v1->uv[1]; + + return sqrt(d[0]*d[0] + d[1]*d[1]); +} + +void p_chart_uv_bbox(PChart *chart, float *minv, float *maxv) +{ + PVert *v; + + INIT_MINMAX2(minv, maxv); + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + DO_MINMAX2(v->uv, minv, maxv); + } +} + +static void p_chart_uv_scale(PChart *chart, float scale) +{ + PVert *v; + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + v->uv[0] *= scale; + v->uv[1] *= scale; + } +} + +static void p_chart_uv_translate(PChart *chart, float trans[2]) +{ + PVert *v; + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + v->uv[0] += trans[0]; + v->uv[1] += trans[1]; + } +} + +static void p_chart_boundaries(PChart *chart, int *nboundaries, PEdge **outer) +{ + PEdge *e, *be; + float len, maxlen = -1.0; + + *nboundaries = 0; + *outer = NULL; + + for (e=(PEdge*)chart->edges->first; e; e=e->link.next) { + if (e->pair || (e->flag & PEDGE_DONE)) + continue; + + (*nboundaries)++; + len = 0.0f; + + be = e; + do { + be->flag |= PEDGE_DONE; + len += p_edge_length(be); + be = be->next->vert->edge; + } while(be != e); + + if (len > maxlen) { + *outer = e; + maxlen = len; + } + } + + for (e=(PEdge*)chart->edges->first; e; e=e->link.next) + e->flag &= ~PEDGE_DONE; +} + +static float p_edge_boundary_angle(PEdge *e) +{ + PEdge *we; + PVert *v, *v1, *v2; + float angle; + int n = 0; + + v = e->vert; + + /* concave angle check -- could be better */ + angle = M_PI; + + we = v->edge; + do { + v1 = we->next->vert; + v2 = we->next->next->vert; + angle -= p_vec_angle(v1->co, v->co, v2->co); + + we = we->next->next->pair; + n++; + } while (we && (we != v->edge)); + + return angle; +} + +static PEdge *p_boundary_edge_next(PEdge *e) +{ + return e->next->vert->edge; +} + +static PEdge *p_boundary_edge_prev(PEdge *e) +{ + PEdge *we = e, *last; + + do { + last = we; + we = p_wheel_edge_next(we); + } while (we && (we != e)); + + return last->next->next; +} + +static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges) +{ + PEdge *e, *e1, *e2; + PHashKey vkeys[3]; + PFace *f; + struct PHeap *heap = pheap_new(nedges); + float angle; + + e = be; + do { + angle = p_edge_boundary_angle(e); + e->u.heaplink = pheap_insert(heap, angle, e); + + e = e->next->vert->edge; + } while(e != be); + + if (nedges == 2) { + /* no real boundary, but an isolated seam */ + e = be->next->vert->edge; + e->pair = be; + be->pair = e; + + pheap_remove(heap, e->u.heaplink); + pheap_remove(heap, be->u.heaplink); + } + else { + while (nedges > 2) { + PEdge *ne, *ne1, *ne2; + + e = pheap_popmin(heap); + + e1 = p_boundary_edge_prev(e); + e2 = p_boundary_edge_next(e); + + pheap_remove(heap, e1->u.heaplink); + pheap_remove(heap, e2->u.heaplink); + e->u.heaplink = e1->u.heaplink = e2->u.heaplink = NULL; + + e->flag |= PEDGE_FILLED; + e1->flag |= PEDGE_FILLED; + + vkeys[0] = e->vert->link.key; + vkeys[1] = e1->vert->link.key; + vkeys[2] = e2->vert->link.key; + + f = p_face_add(chart, -1, vkeys, NULL, NULL, 0, 1, 2, NULL, NULL); + f->flag |= PFACE_FILLED; + + ne = f->edge->next->next; + ne1 = f->edge; + ne2 = f->edge->next; + + ne->flag = ne1->flag = ne2->flag = PEDGE_FILLED; + + e->pair = ne; + ne->pair = e; + e1->pair = ne1; + ne1->pair = e1; + + ne->vert = e2->vert; + ne1->vert = e->vert; + ne2->vert = e1->vert; + + if (nedges == 3) { + e2->pair = ne2; + ne2->pair = e2; + } + else { + ne2->vert->edge = ne2; + + ne2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(ne2), ne2); + e2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(e2), e2); + } + + nedges--; + } + } + + pheap_delete(heap); +} + +static void p_chart_fill_boundaries(PChart *chart, PEdge *outer) +{ + PEdge *e, *enext, *be; + int nedges; + + for (e=(PEdge*)chart->edges->first; e; e=e->link.next) { + enext = e->link.next; + + if (e->pair || (e->flag & PEDGE_FILLED)) + continue; + + nedges = 0; + be = e; + do { + be->flag |= PEDGE_FILLED; + be = be->next->vert->edge; + nedges++; + } while(be != e); + + if (e != outer) + p_chart_fill_boundary(chart, e, nedges); + } +} + +static void p_flush_uvs(PChart *chart) +{ + PEdge *e; + + for (e=(PEdge*)chart->edges->first; e; e=e->link.next) { + if (e->orig_uv) { + e->orig_uv[0] = e->vert->uv[0]; + e->orig_uv[1] = e->vert->uv[1]; + } + } +} + +static void p_flush_uvs_blend(PChart *chart, float blend) +{ + PEdge *e; + float invblend = 1.0f - blend; + + for (e=(PEdge*)chart->edges->first; e; e=e->link.next) { + if (e->orig_uv) { + e->orig_uv[0] = blend*e->old_uv[0] + invblend*e->vert->uv[0]; + e->orig_uv[1] = blend*e->old_uv[1] + invblend*e->vert->uv[1]; + } + } +} + +/* Exported */ + +ParamHandle *param_construct_begin() +{ + PHandle *handle = MEM_callocN(sizeof*handle, "PHandle"); + handle->construction_chart = p_chart_new(handle); + handle->state = PHANDLE_STATE_ALLOCATED; + handle->arena = BLI_memarena_new((1<<16)); + + return (ParamHandle*)handle; +} + +void param_delete(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + int i; + + param_assert((phandle->state == PHANDLE_STATE_ALLOCATED) || + (phandle->state == PHANDLE_STATE_CONSTRUCTED)); + + for (i = 0; i < phandle->ncharts; i++) + p_chart_delete(phandle->charts[i]); + + if (phandle->charts) + MEM_freeN(phandle->charts); + + if (phandle->construction_chart) + p_chart_delete(phandle->construction_chart); + + BLI_memarena_free(phandle->arena); + MEM_freeN(phandle); +} + +void param_face_add(ParamHandle *handle, ParamKey key, int nverts, + ParamKey *vkeys, float **co, float **uv, + ParamBool *pin, ParamBool *select) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart = phandle->construction_chart; + + param_assert(phash_lookup(chart->faces, key) == NULL); + param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); + param_assert((nverts == 3) || (nverts == 4)); + + if (nverts == 4) { + if (!p_quad_split_direction(co)) { + p_face_add(chart, key, vkeys, co, uv, 0, 1, 2, pin, select); + p_face_add(chart, key, vkeys, co, uv, 0, 2, 3, pin, select); + } + else { + p_face_add(chart, key, vkeys, co, uv, 0, 1, 3, pin, select); + p_face_add(chart, key, vkeys, co, uv, 1, 2, 3, pin, select); + } + } + else + p_face_add(chart, key, vkeys, co, uv, 0, 1, 2, pin, select); +} + +void param_edge_set_seam(ParamHandle *handle, ParamKey *vkeys) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart = phandle->construction_chart; + PEdge *e; + + param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); + + e = p_edge_lookup(chart, vkeys); + if (e) + e->flag |= PEDGE_SEAM; +} + +void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart = phandle->construction_chart; + int i, j, nboundaries = 0; + PEdge *outer; + + param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); + + phandle->ncharts = p_connect_pairs(chart, impl); + phandle->charts = p_split_charts(phandle, chart, phandle->ncharts); + + p_chart_delete(chart); + phandle->construction_chart = NULL; + + for (i = j = 0; i < phandle->ncharts; i++) { + p_chart_boundaries(phandle->charts[i], &nboundaries, &outer); + + if (nboundaries == 0) { + p_chart_delete(phandle->charts[i]); + continue; + } + + phandle->charts[j] = phandle->charts[i]; + j++; + +#if 0 + if (fill && (nboundaries > 1)) + p_chart_fill_boundaries(phandle->charts[i], outer); +#endif + } + + phandle->ncharts = j; + + phandle->state = PHANDLE_STATE_CONSTRUCTED; +} + +/* Least Squares Conformal Maps */ + +static void p_chart_lscm_load_solution(PChart *chart) +{ + PVert *v; + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + v->uv[0] = nlGetVariable(2*v->u.index); + v->uv[1] = nlGetVariable(2*v->u.index + 1); + } +} + +static void p_chart_lscm_begin(PChart *chart, PBool live) +{ + PVert *v, *pin1, *pin2; + PBool select = P_FALSE; + int npins = 0, id = 0; + + /* give vertices matrix indices and count pins */ + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + p_vert_load_pin_select_uvs(v); + + if (v->flag & PVERT_PIN) + npins++; + + if (v->flag & PVERT_SELECT) + select = P_TRUE; + + v->u.index = id++; + } + + if ((live && !select) || (npins == 1)) { + chart->u.lscm.context = NULL; + } + else { + if (npins <= 1) { + /* not enough pins, lets find some ourself */ + p_extrema_verts(chart, &pin1, &pin2); + + chart->u.lscm.pin1 = pin1; + chart->u.lscm.pin2 = pin2; + } + else { + chart->flag |= PCHART_NOPACK; + } + + nlNewContext(); + nlSolverParameteri(NL_NB_VARIABLES, 2*phash_size(chart->verts)); + nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); + + chart->u.lscm.context = nlGetCurrent(); + } +} + +static PBool p_chart_lscm_solve(PChart *chart) +{ + PVert *v, *pin1 = chart->u.lscm.pin1, *pin2 = chart->u.lscm.pin2; + PFace *f; + + nlMakeCurrent(chart->u.lscm.context); + + nlBegin(NL_SYSTEM); + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) + if (v->flag & PVERT_PIN) + p_vert_load_pin_select_uvs(v); + + if (chart->u.lscm.pin1) { + nlLockVariable(2*pin1->u.index); + nlLockVariable(2*pin1->u.index + 1); + nlLockVariable(2*pin2->u.index); + nlLockVariable(2*pin2->u.index + 1); + + nlSetVariable(2*pin1->u.index, pin1->uv[0]); + nlSetVariable(2*pin1->u.index + 1, pin1->uv[1]); + nlSetVariable(2*pin2->u.index, pin2->uv[0]); + nlSetVariable(2*pin2->u.index + 1, pin2->uv[1]); + } + else { + /* set and lock the pins */ + for (v=(PVert*)chart->verts->first; v; v=v->link.next) { + if (v->flag & PVERT_PIN) { + nlLockVariable(2*v->u.index); + nlLockVariable(2*v->u.index + 1); + + nlSetVariable(2*v->u.index, v->uv[0]); + nlSetVariable(2*v->u.index + 1, v->uv[1]); + } + } + } + + /* construct matrix */ + + nlBegin(NL_MATRIX); + + for (f=(PFace*)chart->faces->first; f; f=f->link.next) { + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + float a1, a2, a3, ratio, cosine, sine; + float sina1, sina2, sina3, sinmax; + + if (chart->u.lscm.abf_alpha) { + /* use abf angles if passed on */ + a1 = *(chart->u.lscm.abf_alpha++); + a2 = *(chart->u.lscm.abf_alpha++); + a3 = *(chart->u.lscm.abf_alpha++); + } + else + p_face_angles(f, &a1, &a2, &a3); + + sina1 = sin(a1); + sina2 = sin(a2); + sina3 = sin(a3); + + sinmax = MAX3(sina1, sina2, sina3); + + /* shift vertices to find most stable order */ + #define SHIFT3(type, a, b, c) \ + { type tmp; tmp = a; a = c; c = b; b = tmp; } + + if (sina3 != sinmax) { + SHIFT3(PVert*, v1, v2, v3); + SHIFT3(float, a1, a2, a3); + SHIFT3(float, sina1, sina2, sina3); + + if (sina2 == sinmax) { + SHIFT3(PVert*, v1, v2, v3); + SHIFT3(float, a1, a2, a3); + SHIFT3(float, sina1, sina2, sina3); + } + } + + /* angle based lscm formulation */ + ratio = (sina3 == 0.0f)? 0.0f: sina2/sina3; + cosine = cos(a1)*ratio; + sine = sina1*ratio; + + nlBegin(NL_ROW); + nlCoefficient(2*v1->u.index, cosine - 1.0); + nlCoefficient(2*v1->u.index+1, -sine); + nlCoefficient(2*v2->u.index, -cosine); + nlCoefficient(2*v2->u.index+1, sine); + nlCoefficient(2*v3->u.index, 1.0); + nlEnd(NL_ROW); + + nlBegin(NL_ROW); + nlCoefficient(2*v1->u.index, sine); + nlCoefficient(2*v1->u.index+1, cosine - 1.0); + nlCoefficient(2*v2->u.index, -sine); + nlCoefficient(2*v2->u.index+1, -cosine); + nlCoefficient(2*v3->u.index+1, 1.0); + nlEnd(NL_ROW); + } + + nlEnd(NL_MATRIX); + + nlEnd(NL_SYSTEM); + + if (nlSolveAdvanced(NULL, NL_TRUE)) { + p_chart_lscm_load_solution(chart); + return P_TRUE; + } + + return P_FALSE; +} + +static void p_chart_lscm_end(PChart *chart) +{ + if (chart->u.lscm.context) + nlDeleteContext(chart->u.lscm.context); + + chart->u.lscm.context = NULL; + chart->u.lscm.pin1 = NULL; + chart->u.lscm.pin2 = NULL; +} + +void param_lscm_begin(ParamHandle *handle, ParamBool live) +{ + PHandle *phandle = (PHandle*)handle; + int i; + + param_assert(phandle->state == PHANDLE_STATE_CONSTRUCTED); + phandle->state = PHANDLE_STATE_LSCM; + + for (i = 0; i < phandle->ncharts; i++) + p_chart_lscm_begin(phandle->charts[i], live); +} + +void param_lscm_solve(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + int i; + PBool result; + + param_assert(phandle->state == PHANDLE_STATE_LSCM); + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + if (chart->u.lscm.context) { + result = p_chart_lscm_solve(chart); + + if (!result || (chart->u.lscm.pin1)) + p_chart_lscm_end(chart); + } + } +} + +void param_lscm_end(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + int i; + + param_assert(phandle->state == PHANDLE_STATE_LSCM); + + for (i = 0; i < phandle->ncharts; i++) + p_chart_lscm_end(phandle->charts[i]); + + phandle->state = PHANDLE_STATE_CONSTRUCTED; +} + +/* Stretch */ + +#define P_STRETCH_ITER 20 + +static void p_stretch_pin_boundary(PChart *chart) +{ + PVert *v; + + for(v=(PVert*)chart->verts->first; v; v=v->link.next) + if (v->edge->pair == NULL) + v->flag |= PVERT_PIN; + else + v->flag &= ~PVERT_PIN; +} + +static float p_face_stretch(PFace *f) +{ + float T, w, tmp[3]; + float Ps[3], Pt[3]; + float a, c, area; + PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next; + PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert; + + area = p_face_uv_area_signed(f); + + if (area <= 0.0f) /* flipped face -> infinite stretch */ + return 1e10f; + + if (f->flag & PFACE_FILLED) + return 0.0f; + + w= 1.0f/(2.0f*area); + + /* compute derivatives */ + VecCopyf(Ps, v1->co); + VecMulf(Ps, (v2->uv[1] - v3->uv[1])); + + VecCopyf(tmp, v2->co); + VecMulf(tmp, (v3->uv[1] - v1->uv[1])); + VecAddf(Ps, Ps, tmp); + + VecCopyf(tmp, v3->co); + VecMulf(tmp, (v1->uv[1] - v2->uv[1])); + VecAddf(Ps, Ps, tmp); + + VecMulf(Ps, w); + + VecCopyf(Pt, v1->co); + VecMulf(Pt, (v3->uv[0] - v2->uv[0])); + + VecCopyf(tmp, v2->co); + VecMulf(tmp, (v1->uv[0] - v3->uv[0])); + VecAddf(Pt, Pt, tmp); + + VecCopyf(tmp, v3->co); + VecMulf(tmp, (v2->uv[0] - v1->uv[0])); + VecAddf(Pt, Pt, tmp); + + VecMulf(Pt, w); + + /* Sander Tensor */ + a= Inpf(Ps, Ps); + c= Inpf(Pt, Pt); + + T = sqrt(0.5f*(a + c)*f->u.area3d); + + return T; +} + +static float p_stretch_compute_vertex(PVert *v) +{ + PEdge *e = v->edge; + float sum = 0.0f; + + do { + sum += p_face_stretch(e->face); + e = p_wheel_edge_next(e); + } while (e && e != (v->edge)); + + return sum; +} + +static void p_chart_stretch_minimize(PChart *chart, RNG *rng) +{ + PVert *v; + PEdge *e; + int j, nedges; + float orig_stretch, low, stretch_low, high, stretch_high, mid, stretch; + float orig_uv[2], dir[2], random_angle, trusted_radius; + + for(v=(PVert*)chart->verts->first; v; v=v->link.next) { + if((v->flag & PVERT_PIN) || !(v->flag & PVERT_SELECT)) + continue; + + orig_stretch = p_stretch_compute_vertex(v); + orig_uv[0] = v->uv[0]; + orig_uv[1] = v->uv[1]; + + /* move vertex in a random direction */ + trusted_radius = 0.0f; + nedges = 0; + e = v->edge; + + do { + trusted_radius += p_edge_uv_length(e); + nedges++; + + e = p_wheel_edge_next(e); + } while (e && e != (v->edge)); + + trusted_radius /= 2 * nedges; + + random_angle = rng_getFloat(rng) * 2.0 * M_PI; + dir[0] = trusted_radius * cos(random_angle); + dir[1] = trusted_radius * sin(random_angle); + + /* calculate old and new stretch */ + low = 0; + stretch_low = orig_stretch; + + Vec2Addf(v->uv, orig_uv, dir); + high = 1; + stretch = stretch_high = p_stretch_compute_vertex(v); + + /* binary search for lowest stretch position */ + for (j = 0; j < P_STRETCH_ITER; j++) { + mid = 0.5 * (low + high); + v->uv[0]= orig_uv[0] + mid*dir[0]; + v->uv[1]= orig_uv[1] + mid*dir[1]; + stretch = p_stretch_compute_vertex(v); + + if (stretch_low < stretch_high) { + high = mid; + stretch_high = stretch; + } + else { + low = mid; + stretch_low = stretch; + } + } + + /* no luck, stretch has increased, reset to old values */ + if(stretch >= orig_stretch) + Vec2Copyf(v->uv, orig_uv); + } +} + +void param_stretch_begin(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + PVert *v; + PFace *f; + int i; + + param_assert(phandle->state == PHANDLE_STATE_CONSTRUCTED); + phandle->state = PHANDLE_STATE_STRETCH; + + phandle->rng = rng_new(31415926); + phandle->blend = 0.0f; + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + for (v=(PVert*)chart->verts->first; v; v=v->link.next) + p_vert_load_select_uvs(v); + + p_stretch_pin_boundary(chart); + + for (f=(PFace*)chart->faces->first; f; f=f->link.next) { + p_face_backup_uvs(f); + f->u.area3d = p_face_area(f); + } + } +} + +void param_stretch_blend(ParamHandle *handle, float blend) +{ + PHandle *phandle = (PHandle*)handle; + + param_assert(phandle->state == PHANDLE_STATE_STRETCH); + phandle->blend = blend; +} + +void param_stretch_iter(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + int i; + + param_assert(phandle->state == PHANDLE_STATE_STRETCH); + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + p_chart_stretch_minimize(chart, phandle->rng); + } +} + +void param_stretch_end(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + + param_assert(phandle->state == PHANDLE_STATE_STRETCH); + phandle->state = PHANDLE_STATE_CONSTRUCTED; + + rng_free(phandle->rng); + phandle->rng = NULL; +} + +/* Flushing */ + +void param_flush(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + int i; + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + if ((phandle->state == PHANDLE_STATE_LSCM) && !chart->u.lscm.context) + continue; + + if (phandle->blend == 0.0f) + p_flush_uvs(chart); + else + p_flush_uvs_blend(chart, phandle->blend); + } +} + +void param_flush_restore(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + PFace *f; + int i; + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + for (f=(PFace*)chart->faces->first; f; f=f->link.next) + p_face_restore_uvs(f); + } +} + +/* Packing */ + +static int compare_chart_area(const void *a, const void *b) +{ + PChart *ca = *((PChart**)a); + PChart *cb = *((PChart**)b); + + if (ca->u.pack.area > cb->u.pack.area) + return -1; + else if (ca->u.pack.area == cb->u.pack.area) + return 0; + else + return 1; +} + +static PBool p_pack_try(PHandle *handle, float side) +{ + PChart *chart; + float packx, packy, rowh, groupw, w, h; + int i; + + packx= packy= 0.0; + rowh= 0.0; + groupw= 1.0/sqrt(handle->ncharts); + + for (i = 0; i < handle->ncharts; i++) { + chart = handle->charts[i]; + + if (chart->flag & PCHART_NOPACK) + continue; + + w = chart->u.pack.size[0]; + h = chart->u.pack.size[1]; + + if(w <= (side-packx)) { + chart->u.pack.trans[0] = packx; + chart->u.pack.trans[1] = packy; + + packx += w; + rowh= MAX2(rowh, h); + } + else { + packy += rowh; + packx = w; + rowh = h; + + chart->u.pack.trans[0] = 0.0; + chart->u.pack.trans[1] = packy; + } + + if (packy+rowh > side) + return P_FALSE; + } + + return P_TRUE; +} + +#define PACK_SEARCH_DEPTH 15 + +void param_pack(ParamHandle *handle) +{ + PHandle *phandle = (PHandle*)handle; + PChart *chart; + float uv_area, area, trans[2], minside, maxside, totarea, side; + int i; + + /* very simple rectangle packing */ + + if (phandle->ncharts == 0) + return; + + totarea = 0.0f; + maxside = 0.0f; + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + if (chart->flag & PCHART_NOPACK) { + chart->u.pack.area = 0.0f; + continue; + } + + p_chart_area(chart, &uv_area, &area); + p_chart_uv_bbox(chart, trans, chart->u.pack.size); + + /* translate to origin and make area equal to 3d area */ + chart->u.pack.rescale = (uv_area > 0.0f)? sqrt(area)/sqrt(uv_area): 0.0f; + chart->u.pack.area = area; + totarea += area; + + trans[0] = -trans[0]; + trans[1] = -trans[1]; + p_chart_uv_translate(chart, trans); + p_chart_uv_scale(chart, chart->u.pack.rescale); + + /* compute new dimensions for packing */ + chart->u.pack.size[0] += trans[0]; + chart->u.pack.size[1] += trans[1]; + chart->u.pack.size[0] *= chart->u.pack.rescale; + chart->u.pack.size[1] *= chart->u.pack.rescale; + + maxside = MAX3(maxside, chart->u.pack.size[0], chart->u.pack.size[1]); + } + + /* sort by chart area, largest first */ + qsort(phandle->charts, phandle->ncharts, sizeof(PChart*), compare_chart_area); + + /* binary search over pack region size */ + minside = MAX2(sqrt(totarea), maxside); + maxside = (((int)sqrt(phandle->ncharts-1))+1)*maxside; + + if (minside < maxside) { /* should always be true */ + + for (i = 0; i < PACK_SEARCH_DEPTH; i++) { + if (p_pack_try(phandle, (minside+maxside)*0.5f + 1e-5)) + maxside = (minside+maxside)*0.5f; + else + minside = (minside+maxside)*0.5f; + } + } + + /* do the actual packing */ + side = maxside + 1e-5; + if (!p_pack_try(phandle, side)) + param_warning("packing failed.\n"); + + for (i = 0; i < phandle->ncharts; i++) { + chart = phandle->charts[i]; + + if (chart->flag & PCHART_NOPACK) + continue; + + p_chart_uv_scale(chart, 1.0f/side); + trans[0] = chart->u.pack.trans[0]/side; + trans[1] = chart->u.pack.trans[1]/side; + p_chart_uv_translate(chart, trans); + } +} + diff --git a/source/blender/src/parametrizer.h b/source/blender/src/parametrizer.h new file mode 100644 index 00000000000..38bad0e6092 --- /dev/null +++ b/source/blender/src/parametrizer.h @@ -0,0 +1,80 @@ + +#ifndef __PARAMETRIZER_H__ +#define __PARAMETRIZER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void ParamHandle; /* handle to a set of charts */ +typedef long ParamKey; /* (hash) key for identifying verts and faces */ +typedef enum ParamBool { + PARAM_TRUE = 1, + PARAM_FALSE = 0 +} ParamBool; + +/* Chart construction: + ------------------- + - faces and seams may only be added between construct_{begin|end} + - the pointers to co and uv are stored, rather than being copied + - vertices are implicitly created + - in construct_end the mesh will be split up according to the seams + - the resulting charts must be: + - manifold, connected, open (at least one boundary loop) + - output will be written to the uv pointers +*/ + +ParamHandle *param_construct_begin(); + +void param_face_add(ParamHandle *handle, + ParamKey key, + int nverts, + ParamKey *vkeys, + float **co, + float **uv, + ParamBool *pin, + ParamBool *select); + +void param_edge_set_seam(ParamHandle *handle, + ParamKey *vkeys); + +void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl); +void param_delete(ParamHandle *chart); + +/* Least Squares Conformal Maps: + ----------------------------- + - charts with less than two pinned vertices are assigned 2 pins + - lscm is divided in three steps: + - begin: compute matrix and it's factorization (expensive) + - solve using pinned coordinates (cheap) + - end: clean up + - uv coordinates are allowed to change within begin/end, for + quick re-solving +*/ + +void param_lscm_begin(ParamHandle *handle, ParamBool live); +void param_lscm_solve(ParamHandle *handle); +void param_lscm_end(ParamHandle *handle); + +/* Stretch */ + +void param_stretch_begin(ParamHandle *handle); +void param_stretch_blend(ParamHandle *handle, float blend); +void param_stretch_iter(ParamHandle *handle); +void param_stretch_end(ParamHandle *handle); + +/* Packing */ + +void param_pack(ParamHandle *handle); + +/* Flushing */ + +void param_flush(ParamHandle *handle); +void param_flush_restore(ParamHandle *handle); + +#ifdef __cplusplus +} +#endif + +#endif /*__PARAMETRIZER_H__*/ + diff --git a/source/blender/src/parametrizer_intern.h b/source/blender/src/parametrizer_intern.h new file mode 100644 index 00000000000..f22a7e4ab66 --- /dev/null +++ b/source/blender/src/parametrizer_intern.h @@ -0,0 +1,191 @@ + +#ifndef __PARAMETRIZER_INTERN_H__ +#define __PARAMETRIZER_INTERN_H__ + +/* Hash: + ----- + - insert only + - elements are all stored in a flat linked list +*/ + +typedef long PHashKey; + +typedef struct PHashLink { + struct PHashLink *next; + PHashKey key; +} PHashLink; + +typedef struct PHash { + PHashLink *first; + PHashLink **buckets; + int size, cursize, cursize_id; +} PHash; + +PHash *phash_new(int sizehint); +void phash_delete_with_links(PHash *ph); +void phash_delete(PHash *ph); + +int phash_size(PHash *ph); + +void phash_insert(PHash *ph, PHashLink *link); +PHashLink *phash_lookup(PHash *ph, PHashKey key); +PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link); + +#if 0 + #define param_assert(condition) + #define param_warning(message); +#else + #define param_assert(condition) \ + if (!(condition)) \ + { printf("Assertion %s:%d\n", __FILE__, __LINE__); abort(); } + #define param_warning(message) \ + { printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message); } +#endif + +typedef enum PBool { + P_TRUE = 1, + P_FALSE = 0 +} PBool; + +struct PVert; +struct PEdge; +struct PFace; +struct PChart; +struct PHandle; + +/* Heap */ + +typedef struct PHeapLink { + void *ptr; + float value; + int index; +} PHeapLink; + +typedef struct PHeap { + unsigned int size; + unsigned int bufsize; + PHeapLink *links; + PHeapLink **tree; +} PHeap; + +/* Simplices */ + +typedef struct PVert { + struct PVertLink { + struct PVert *next; + PHashKey key; + } link; + + struct PEdge *edge; + float *co; + float uv[2]; + int flag; + + union PVertUnion { + int index; /* lscm matrix index */ + float distortion; /* area smoothing */ + } u; +} PVert; + +typedef struct PEdge { + struct PEdgeLink { + struct PEdge *next; + PHashKey key; + } link; + + struct PVert *vert; + struct PEdge *pair; + struct PEdge *next; + struct PFace *face; + float *orig_uv, old_uv[2]; + int flag; + + union PEdgeUnion { + PHeapLink *heaplink; + } u; +} PEdge; + +typedef struct PFace { + struct PFaceLink { + struct PFace *next; + PHashKey key; + } link; + + struct PEdge *edge; + int flag; + + union PFaceUnion { + int chart; /* chart construction */ + float area3d; /* stretch */ + } u; +} PFace; + +enum PVertFlag { + PVERT_PIN = 1, + PVERT_SELECT = 2 +}; + +enum PEdgeFlag { + PEDGE_SEAM = 1, + PEDGE_VERTEX_SPLIT = 2, + PEDGE_PIN = 4, + PEDGE_SELECT = 8, + PEDGE_DONE = 16, + PEDGE_FILLED = 32 +}; + +/* for flipping faces */ +#define PEDGE_VERTEX_FLAGS (PEDGE_PIN) + +enum PFaceFlag { + PFACE_CONNECTED = 1, + PFACE_FILLED = 2 +}; + +/* Chart */ + +typedef struct PChart { + PHash *verts; + PHash *edges; + PHash *faces; + + union PChartUnion { + struct PChartLscm { + NLContext context; + float *abf_alpha; + PVert *pin1, *pin2; + } lscm; + struct PChartPack { + float rescale, area; + float size[2], trans[2]; + } pack; + } u; + + int flag; + struct PHandle *handle; +} PChart; + +enum PChartFlag { + PCHART_NOPACK = 1 +}; + +enum PHandleState { + PHANDLE_STATE_ALLOCATED, + PHANDLE_STATE_CONSTRUCTED, + PHANDLE_STATE_LSCM, + PHANDLE_STATE_STRETCH, +}; + +typedef struct PHandle { + PChart *construction_chart; + PChart **charts; + int ncharts; + enum PHandleState state; + MemArena *arena; + PBool implicit; + RNG *rng; + float blend; +} PHandle; + +#endif /*__PARAMETRIZER_INTERN_H__*/ + diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 3c0cdc0ed20..865db9fe000 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -119,12 +119,13 @@ void enter_posemode(void) void set_pose_keys (Object *ob) { + bArmature *arm= ob->data; bPoseChannel *chan; if (ob->pose){ for (chan=ob->pose->chanbase.first; chan; chan=chan->next){ Bone *bone= chan->bone; - if(bone && (bone->flag & BONE_SELECTED)) { + if(bone && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) { chan->flag |= POSE_KEY; } else { @@ -157,11 +158,12 @@ void exit_posemode(void) /* called by buttons to find a bone to display/edit values for */ bPoseChannel *get_active_posechannel (Object *ob) { + bArmature *arm= ob->data; bPoseChannel *pchan; /* find active */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE)) + if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) return pchan; } @@ -194,6 +196,7 @@ int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan) /* for the object with pose/action: create path curves for selected bones */ void pose_calculate_path(Object *ob) { + bArmature *arm; bPoseChannel *pchan; Base *base; float *fp; @@ -201,6 +204,7 @@ void pose_calculate_path(Object *ob) if(ob==NULL || ob->pose==NULL) return; + arm= ob->data; if(EFRA<=SFRA) return; @@ -209,10 +213,12 @@ void pose_calculate_path(Object *ob) /* malloc the path blocks */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { - pchan->pathlen= EFRA-SFRA; - if(pchan->path) - MEM_freeN(pchan->path); - pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path"); + if(arm->layer & pchan->bone->layer) { + pchan->pathlen= EFRA-SFRA; + if(pchan->path) + MEM_freeN(pchan->path); + pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path"); + } } } @@ -230,10 +236,12 @@ void pose_calculate_path(Object *ob) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone && (pchan->bone->flag & BONE_SELECTED)) { - if(pchan->path) { - fp= pchan->path+3*(CFRA-SFRA); - VECCOPY(fp, pchan->pose_tail); - Mat4MulVecfl(ob->obmat, fp); + if(arm->layer & pchan->bone->layer) { + if(pchan->path) { + fp= pchan->path+3*(CFRA-SFRA); + VECCOPY(fp, pchan->pose_tail); + Mat4MulVecfl(ob->obmat, fp); + } } } } @@ -268,6 +276,7 @@ void pose_clear_paths(Object *ob) void pose_select_constraint_target(void) { Object *ob= OBACT; + bArmature *arm= ob->data; bPoseChannel *pchan; bConstraint *con; @@ -276,16 +285,18 @@ void pose_select_constraint_target(void) if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { - - for(con= pchan->constraints.first; con; con= con->next) { - char *subtarget; - Object *target= get_constraint_target(con, &subtarget); + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { - if(ob==target) { - if(subtarget) { - bPoseChannel *pchanc= get_pose_channel(ob->pose, subtarget); - pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; + for(con= pchan->constraints.first; con; con= con->next) { + char *subtarget; + Object *target= get_constraint_target(con, &subtarget); + + if(ob==target) { + if(subtarget) { + bPoseChannel *pchanc= get_pose_channel(ob->pose, subtarget); + pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL; + } } } } @@ -340,6 +351,7 @@ void pose_add_IK(void) void pose_clear_IK(void) { Object *ob= OBACT; + bArmature *arm= ob->data; bPoseChannel *pchan; bConstraint *con; bConstraint *next; @@ -351,17 +363,19 @@ void pose_clear_IK(void) if(okee("Remove IK constraint(s)")==0) return; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { - - for(con= pchan->constraints.first; con; con= next) { - next= con->next; - if(con->type==CONSTRAINT_TYPE_KINEMATIC) { - BLI_remlink(&pchan->constraints, con); - free_constraint_data(con); - MEM_freeN(con); + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { + + for(con= pchan->constraints.first; con; con= next) { + next= con->next; + if(con->type==CONSTRAINT_TYPE_KINEMATIC) { + BLI_remlink(&pchan->constraints, con); + free_constraint_data(con); + MEM_freeN(con); + } } + pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); } - pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET); } } @@ -377,6 +391,7 @@ void pose_clear_IK(void) void pose_clear_constraints(void) { Object *ob= OBACT; + bArmature *arm= ob->data; bPoseChannel *pchan; /* paranoia checks */ @@ -387,9 +402,11 @@ void pose_clear_constraints(void) /* find active */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { - free_constraints(&pchan->constraints); - pchan->constflag= 0; + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { + free_constraints(&pchan->constraints); + pchan->constflag= 0; + } } } @@ -407,6 +424,7 @@ void pose_clear_constraints(void) void pose_copy_menu(void) { Object *ob= OBACT; + bArmature *arm= ob->data; bPoseChannel *pchan, *pchanact; short nr; @@ -425,21 +443,23 @@ void pose_copy_menu(void) nr= pupmenu("Copy Pose Attributes %t|Location%x1|Rotation%x2|Size%x3|Constraints"); for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & BONE_SELECTED) { - if(pchan!=pchanact) { - if(nr==1) { - VECCOPY(pchan->loc, pchanact->loc); - } - else if(nr==2) { - QUATCOPY(pchan->quat, pchanact->quat); - } - else if(nr==3) { - VECCOPY(pchan->size, pchanact->size); - } - else if(nr==4) { - free_constraints(&pchan->constraints); - copy_constraints(&pchan->constraints, &pchanact->constraints); - pchan->constflag = pchanact->constflag; + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & BONE_SELECTED) { + if(pchan!=pchanact) { + if(nr==1) { + VECCOPY(pchan->loc, pchanact->loc); + } + else if(nr==2) { + QUATCOPY(pchan->quat, pchanact->quat); + } + else if(nr==3) { + VECCOPY(pchan->size, pchanact->size); + } + else if(nr==4) { + free_constraints(&pchan->constraints); + copy_constraints(&pchan->constraints, &pchanact->constraints); + pchan->constflag = pchanact->constflag; + } } } } @@ -616,6 +636,7 @@ void pose_adds_vgroups(Object *meshobj) struct vgroup_map map; DerivedMesh *dm; Object *poseobj= modifiers_isDeformedByArmature(meshobj); + bArmature *arm= poseobj->data; bPoseChannel *pchan; Bone *bone; bDeformGroup *dg, *curdef; @@ -629,47 +650,49 @@ void pose_adds_vgroups(Object *meshobj) for(pchan= poseobj->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; - if(bone->flag & (BONE_SELECTED)) { - - /* check if mesh has vgroups */ - dg= get_named_vertexgroup(meshobj, bone->name); - if(dg==NULL) - dg= add_defgroup_name(meshobj, bone->name); - - /* flipped bone */ - if(Gwp.flag & VP_MIRROR_X) { - char name[32]; + if(arm->layer & pchan->bone->layer) { + if(bone->flag & (BONE_SELECTED)) { - BLI_strncpy(name, dg->name, 32); - bone_flip_name(name, 0); // 0 = don't strip off number extensions + /* check if mesh has vgroups */ + dg= get_named_vertexgroup(meshobj, bone->name); + if(dg==NULL) + dg= add_defgroup_name(meshobj, bone->name); + + /* flipped bone */ + if(Gwp.flag & VP_MIRROR_X) { + char name[32]; + + BLI_strncpy(name, dg->name, 32); + bone_flip_name(name, 0); // 0 = don't strip off number extensions + + for (curdef = meshobj->defbase.first; curdef; curdef=curdef->next) + if (!strcmp(curdef->name, name)) + break; + map.dgflip= curdef; + } + else map.dgflip= NULL; + + /* get the root of the bone in global coords */ + VECCOPY(map.head, bone->arm_head); + Mat4MulVecfl(poseobj->obmat, map.head); + + /* get the tip of the bone in global coords */ + VECCOPY(map.tail, bone->arm_tail); + Mat4MulVecfl(poseobj->obmat, map.tail); + + /* use the optimal vertices instead of mverts */ + map.dg= dg; + map.bone= bone; + if(dm->foreachMappedVert) + dm->foreachMappedVert(dm, pose_adds_vgroups__mapFunc, (void*) &map); + else { + Mesh *me= meshobj->data; + int i; + for(i=0; itotvert; i++) + pose_adds_vgroups__mapFunc(&map, i, (me->mvert+i)->co, NULL, NULL); + } - for (curdef = meshobj->defbase.first; curdef; curdef=curdef->next) - if (!strcmp(curdef->name, name)) - break; - map.dgflip= curdef; } - else map.dgflip= NULL; - - /* get the root of the bone in global coords */ - VECCOPY(map.head, bone->arm_head); - Mat4MulVecfl(poseobj->obmat, map.head); - - /* get the tip of the bone in global coords */ - VECCOPY(map.tail, bone->arm_tail); - Mat4MulVecfl(poseobj->obmat, map.tail); - - /* use the optimal vertices instead of mverts */ - map.dg= dg; - map.bone= bone; - if(dm->foreachMappedVert) - dm->foreachMappedVert(dm, pose_adds_vgroups__mapFunc, (void*) &map); - else { - Mesh *me= meshobj->data; - int i; - for(i=0; itotvert; i++) - pose_adds_vgroups__mapFunc(&map, i, (me->mvert+i)->co, NULL, NULL); - } - } } @@ -688,6 +711,7 @@ void pose_adds_vgroups(Object *meshobj) void pose_flip_names(void) { Object *ob= OBACT; + bArmature *arm= ob->data; bPoseChannel *pchan; char newname[32]; @@ -696,10 +720,12 @@ void pose_flip_names(void) if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { - BLI_strncpy(newname, pchan->name, sizeof(newname)); - bone_flip_name(newname, 1); // 1 = do strip off number extensions - armature_bone_rename(ob->data, pchan->name, newname); + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { + BLI_strncpy(newname, pchan->name, sizeof(newname)); + bone_flip_name(newname, 1); // 1 = do strip off number extensions + armature_bone_rename(ob->data, pchan->name, newname); + } } } @@ -716,6 +742,7 @@ void pose_flip_names(void) void pose_activate_flipped_bone(void) { Object *ob= OBACT; + bArmature *arm= ob->data; if(ob==NULL) return; @@ -726,8 +753,9 @@ void pose_activate_flipped_bone(void) bPoseChannel *pchan, *pchanf; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & BONE_ACTIVE) { - break; + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & BONE_ACTIVE) + break; } } if(pchan) { @@ -760,3 +788,39 @@ void pose_activate_flipped_bone(void) } } + +void pose_movetolayer(void) +{ + Object *ob= OBACT; + bArmature *arm; + short lay= 0; + + if(ob==NULL) return; + arm= ob->data; + + if(ob->flag & OB_POSEMODE) { + bPoseChannel *pchan; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & BONE_SELECTED) + lay |= pchan->bone->layer; + } + } + if(lay==0) return; + + if( movetolayer_short_buts(&lay)==0 ) return; + if(lay==0) return; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(arm->layer & pchan->bone->layer) { + if(pchan->bone->flag & BONE_SELECTED) + pchan->bone->layer= lay; + } + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWBUTSEDIT, 0); + } +} diff --git a/source/blender/src/preview.blend.c b/source/blender/src/preview.blend.c new file mode 100644 index 00000000000..d3441287c00 --- /dev/null +++ b/source/blender/src/preview.blend.c @@ -0,0 +1,4634 @@ +/* DataToC output of file */ + +int datatoc_preview_blend_size= 148112; +char datatoc_preview_blend[]= { + 66, 76, 69, 78, 68, 69, 82, 95, 86, 50, 52, 48, 82, 69, 78, 68, + 0, 0, 0, 32,191,255,243, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,250,112,114,101,118,105,101,119, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 83, 82, 0, 0, 0,116, 3, 59, 65,112, 0, 0, 0,111, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 82,115, 99,114,101,101,110, 0, 45, 83, 99, +114,105,112,116,105,110,103, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 56,232, 64, 3, 54, 11, 96, 3, 54, 11, 0, + 3, 59, 67, 16, 3, 59, 67, 80, 3, 59, 95, 0, 3,152,218, 32, 0, 0, 3,231, 1,143, 4,174, 3,232, 3, 32, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, + 3, 56,232, 64, 0, 0, 0,112, 0, 0, 0, 1, 3, 55,114, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0, 20, 3, 55,114, 48, 0, 0, 0,112, 0, 0, 0, 1, 3, 55,113,208, 3, 56,232, 64, 0, 0, 0, 0, + 0, 0, 3, 32, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, 3, 55,113,208, 0, 0, 0,112, 0, 0, 0, 1, 3, 55,113,112, + 3, 55,114, 48, 0, 0, 0, 0, 3,232, 3, 32, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, 3, 55,113,112, 0, 0, 0,112, + 0, 0, 0, 1, 3, 54, 11,176, 3, 55,113,208, 0, 0, 0, 0, 3,232, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 20, + 3, 54, 11,176, 0, 0, 0,112, 0, 0, 0, 1, 3, 54, 11, 96, 3, 55,113,112, 0, 0, 0, 0, 0, 0, 2, 76, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0, 20, 3, 54, 11, 96, 0, 0, 0,112, 0, 0, 0, 1, 0, 0, 0, 0, 3, 54, 11,176, 0, 0, 0, 0, + 3,232, 2, 76, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 54, 11, 0, 0, 0, 0,113, 0, 0, 0, 1, 3, 58,168,192, + 0, 0, 0, 0, 3, 55,113,208, 3, 55,114, 48, 0, 1, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 58,168,192, + 0, 0, 0,113, 0, 0, 0, 1, 3, 59, 66, 16, 3, 54, 11, 0, 3, 54, 11,176, 3, 55,114, 48, 0, 1, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0, 24, 3, 59, 66, 16, 0, 0, 0,113, 0, 0, 0, 1, 3, 59, 66, 80, 3, 58,168,192, 3, 54, 11, 96, + 3, 55,113,208, 0, 1, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 59, 66, 80, 0, 0, 0,113, 0, 0, 0, 1, + 3, 59, 66,144, 3, 59, 66, 16, 3, 54, 11, 96, 3, 54, 11,176, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, + 3, 59, 66,144, 0, 0, 0,113, 0, 0, 0, 1, 3, 59, 66,208, 3, 59, 66, 80, 3, 54, 11, 96, 3, 55,113,112, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 59, 66,208, 0, 0, 0,113, 0, 0, 0, 1, 3, 59, 67, 16, 3, 59, 66,144, + 3, 54, 11,176, 3, 56,232, 64, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 59, 67, 16, 0, 0, 0,113, + 0, 0, 0, 1, 0, 0, 0, 0, 3, 59, 66,208, 3, 55,113,112, 3, 56,232, 64, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,204, 3, 59, 67, 80, 0, 0, 0,115, 0, 0, 0, 1, 3, 59, 95, 0, 0, 0, 0, 0, 3, 54, 11,176, 3, 55,114, 48, + 3, 55,113,208, 3, 54, 11, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,232, 0, 0, 2, 77, 0, 0, 3, 32, 0, 0, 0, 0, + 0, 0, 3,232, 0, 0, 2, 77, 0, 0, 2,103, 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 2,104, 0, 0, 3, 32, 0, 5, 0, 4, + 0, 1, 4, 4, 3,233, 0,185, 1, 0, 1, 1, 1,176, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 59, 92,176, 3, 59, 93,176, 3, 58,217, 0, 3, 58,225, 64, 3, 59, 68, 80, 3, 55,165,112, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 68, 80, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 69, 32, 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, 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, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 69, 32, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 69,240, 3, 59, 68, 80, 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, 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, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 69,240, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 70,192, 3, 59, 69, 32, 65,110,105,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, 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, 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 70,192, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 71,144, 3, 59, 69,240, + 70,111,114,109, 97,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, + 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, + 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 71,144, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 72, 96, 3, 59, 70,192, 80,114,101,118,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, 76, 97,109,112, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 72, 96, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 73, 48, 3, 59, 71,144, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 73, 48, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 74, 0, 3, 59, 72, 96, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,112,111,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, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 74, 0, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 74,208, 3, 59, 73, 48, + 84,101,120,116,117,114,101, 32, 97,110,100, 32, 73,110,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, + 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 74,208, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 75,160, 3, 59, 74, 0, 77, 97,112, 32, 84,111, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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,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, 3,210, 0, 0, 1, 62, 0,204, + 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 3, 59, 74, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 75,160, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 76,112, 3, 59, 74,208, 80,114,101,118,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, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 76,112, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 77, 64, 3, 59, 75,160, 76,105,110,107,115, 32, 97,110,100, 32, 80,105,112,101,108,105,110,101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 77, 64, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 78, 16, 3, 59, 76,112, + 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 78, 16, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 78,224, 3, 59, 77, 64, 82, 97,109,112,115, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 97,116,101,114,105, 97,108, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,140, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 77, 64, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 78,224, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 79,176, 3, 59, 78, 16, 83,104, 97,100,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, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 79,176, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 80,128, 3, 59, 78,224, 77,105,114,114,111,114, 32, 84,114, 97,110,115,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, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 59, 78,224, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 80,128, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 81, 80, 3, 59, 79,176, + 84,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 81, 80, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 82, 32, 3, 59, 80,128, 77, 97,112, 32, 73,110,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, 77, 97,116,101,114,105, 97,108, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 80,128, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 82, 32, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 82,240, 3, 59, 81, 80, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 59, 80,128, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 82,240, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 83,192, 3, 59, 82, 32, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,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, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 83,192, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 84,144, 3, 59, 82,240, + 77,101,115,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 84,144, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 85, 96, 3, 59, 83,192, 77,111,100,105,102,105,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, 69,100,105,116,105,110,103, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,140, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 85, 96, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 86, 48, 3, 59, 84,144, 83,104, 97,112,101,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6, 3, 59, 84,144, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 86, 48, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 87, 0, 3, 59, 85, 96, 77,101,115,104, 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, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 87, 0, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 87,208, 3, 59, 86, 48, + 77,101,115,104, 32, 84,111,111,108,115, 32, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 24, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 87,208, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 88,160, 3, 59, 87, 0, 80,114,101,118,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, 87,111,114,108,100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 88,160, + 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 89,112, 3, 59, 87,208, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 89,112, 0, 0, 0,114, 0, 0, 0, 1, + 3, 59, 90, 64, 3, 59, 88,160, 77,105,115,116, 32, 47, 32, 83,116, 97,114,115, 32, 47, 32, 80,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, 87,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 90, 64, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 91, 16, 3, 59, 89,112, + 65,109, 98, 32, 79, 99, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 3, 59, 89,112, 68, 65, 84, 65, + 0, 0, 0,164, 3, 59, 91, 16, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 91,224, 3, 59, 90, 64, 84,101,120,116,117,114,101, 32, + 97,110,100, 32, 73,110,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, 87,111,114,108,100, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 91,224, + 0, 0, 0,114, 0, 0, 0, 1, 3, 56,228, 48, 3, 59, 91, 16, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,111,114,108,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 3, 59, 91, 16, 68, 65, 84, 65, 0, 0, 0,164, 3, 56,228, 48, 0, 0, 0,114, 0, 0, 0, 1, + 3, 55,131,240, 3, 59, 91,224, 80,114,101,118,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, 84,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 55,131,240, 0, 0, 0,114, 0, 0, 0, 1, 3, 55,132,192, 3, 56,228, 48, + 84,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 84,101,120,116,117,114,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 55,132,192, 0, 0, 0,114, 0, 0, 0, 1, 3, 58,187, 64, 3, 55,131,240, 67,111,108,111,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, 84,101,120,116,117,114,101, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 55,131,240, 68, 65, 84, 65, 0, 0, 0,164, 3, 58,187, 64, + 0, 0, 0,114, 0, 0, 0, 1, 3, 56,230, 16, 3, 55,132,192, 79, 98,106,101, 99,116, 32, 97,110,100, 32, 76,105,110,107,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, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 56,230, 16, 0, 0, 0,114, 0, 0, 0, 1, + 3, 55,160,160, 3, 58,187, 64, 65,110,105,109, 32,115,101,116,116,105,110,103,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, 79, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 70, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 55,160,160, 0, 0, 0,114, 0, 0, 0, 1, 3, 55,165,112, 3, 56,230, 16, + 68,114, 97,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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,140, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0,164, 3, 55,165,112, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 0, 3, 55,160,160, 67,111,110,115,116,114, 97,105, +110,116,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,210, 0, 0, 1, 62, 0,204, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,204, 3, 59, 92,176, + 0, 0, 0, 95, 0, 0, 0, 1, 3, 59, 93,176, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 3, 59, 67, 80, 3, 56,238, 96, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4,193, 0, 0, 0, 68,203,192, 0, +193, 0, 0, 0, 67,104, 0, 0,192,255,255,129, 68,161, 83, 8,193, 0, 0, 0, 67,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0, 66, 40, 0, 0, 69, 0, 0, 0, 67,225, 0, 0, 63, 0, 0, 0, 63,154,225, 72, + 0, 0, 0, 1, 0, 1, 0, 1, 3,233, 0,185, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 3, 3, 59,121, 0,255,255, 0, 0, + 0, 0, 0, 0, 1,150, 0, 0, 1, 51, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 40, 3, 59, 93,176, + 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, 0, 0, 3, 59, 92,176, 0, 0, 0, 2, 63, 51, 51, 51, 3, 59, 67, 80, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,122, 0, 0,189,204,204,205, + 63,140,204,205, 63,128, 0, 0, 67,122, 0, 0,192,160, 0, 0, 64,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0,185, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 16, + 0, 0, 0,185, 60, 35,215, 10, 60, 35,215, 10, 70,106, 96, 0, 70, 28, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152,242, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67,122, 0, 0,189,204,204,205, 63,140,204,205, 68, 65, 84, 65, 0, 0, 0,204, 3, 59, 95, 0, 0, 0, 0,115, + 0, 0, 0, 1, 0, 0, 0, 0, 3, 59, 67, 80, 3, 56,232, 64, 3, 54, 11,176, 3, 54, 11, 96, 3, 55,113,112, 0, 0, 0, 0, + 60,190,133,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 41,249,186, 0, 0, 0, 0, 0, 0, 0, 0, +128, 0, 0, 0,128, 0, 0, 0,187,131, 18,111,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 0, 0, 0, 0, 2, 75, 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 0, 0, 0, 3,232, 0, 0, 0, 27, 0, 0, 2, 75, 0, 7, 0, 6, 0, 1, 1, 1, 3,233, 2, 49, 1, 0, 1, 0, + 2,195, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152,214, 32, 3, 59,113, 16, + 3, 55,190, 16, 3, 55,190, 16, 3, 59, 96, 0, 3, 59,104,240, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 96, 0, 0, 0, 0,114, + 0, 0, 0, 1, 3, 59, 96,208, 0, 0, 0, 0, 84,114, 97,110,115,102,111,114,109, 32, 80,114,111,112,101,114,116,105,101,115, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,112,111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,167, 1, 62, 0,204, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 96,208, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 97,160, + 3, 59, 96, 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, 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, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 97,160, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 98,112, 3, 59, 96,208, 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, 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, 1, 64, 0, 0, + 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, + 3, 59, 98,112, 0, 0, 0,114, 0, 0, 0, 1, 3, 59, 99, 64, 3, 59, 97,160, 65,110,105,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, 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, 2,128, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59, 99, 64, 0, 0, 0,114, + 0, 0, 0, 1, 3, 59,100, 16, 3, 59, 98,112, 70,111,114,109, 97,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, 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, 3,192, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59,100, 16, 0, 0, 0,114, 0, 0, 0, 1, 3, 59,100,224, + 3, 59, 99, 64, 76,105,110,107, 32, 97,110,100, 32, 77, 97,116,101,114,105, 97,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, 69,100,105,116,105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0,164, 3, 59,100,224, 0, 0, 0,114, 0, 0, 0, 1, 3, 59,101,176, 3, 59,100, 16, 67, 97,109,101, +114, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69,100,105,116, +105,110,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, + 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, + 3, 59,101,176, 0, 0, 0,114, 0, 0, 0, 1, 3, 59,102,128, 3, 59,100,224, 80,114,101,118,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, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 62, 0,204, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59,102,128, 0, 0, 0,114, + 0, 0, 0, 1, 3, 59,103, 80, 3, 59,101,176, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 24, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, 3, 59,103, 80, 0, 0, 0,114, 0, 0, 0, 1, 3, 59,104, 32, + 3, 59,102,128, 83,104, 97,100,111,119, 32, 97,110,100, 32, 83,112,111,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, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,254, 48, 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0,164, 3, 59,104, 32, 0, 0, 0,114, 0, 0, 0, 1, 3, 59,104,240, 3, 59,103, 80, 84,101,120,116, +117,114,101, 32, 97,110,100, 32, 73,110,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, 76, 97,109,112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, + 1, 62, 0,204, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,164, + 3, 59,104,240, 0, 0, 0,114, 0, 0, 0, 1, 0, 0, 0, 0, 3, 59,104, 32, 77, 97,112, 32, 84,111, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,109,112, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,253, 72, 1, 62, 0,204, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,104, 32, 68, 65, 84, 65, 0, 0, 2,192, 3,152,214, 32, 0, 0, 0, 90, + 0, 0, 0, 1, 3, 59,105,192, 0, 0, 0, 0, 0, 0, 0, 1, 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 51, 19, 2,174, +191,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 63,127,255,255, 51, 19, 2,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 19, 2,176, + 63,128, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,191,128, 0, 1, 51, 19, 2,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 60,190,133,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,195, 56, 91, + 59,131, 18,110, 0, 0, 0, 0, 0, 0, 0, 0, 61, 41,249,185,175, 22,137,234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 66, 43,253,156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 93,105,149, + 65,192,199,223, 0, 0, 0, 0, 0, 0, 0, 0, 67,122, 0, 1,183, 15,144,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 60,190,133,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 41,249,186, + 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0,128, 0, 0, 0,187,131, 18,111,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 51, 19, 2,174, +191,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 63,127,255,255, 51, 19, 2,174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63, 53, 4,243,191, 53, 4,243, 0, 0, 0, 0, 0, 0, 0, 0, 66, 43,253,156, 0, 0, 0, 1, + 3,152,230, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 1, 0, 0, +255,251, 24, 8, 66, 12, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 61,175,241, 71, 60, 35,215, 10, 67,250, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 2, + 0, 7, 0,175, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,255,255, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,204, 3, 59,105,192, 0, 0, 0, 95, 0, 0, 0, 1, 3, 59,106,192, 3,152,214, 32, + 0, 0, 0, 4, 0, 0, 0, 0, 3, 59, 95, 0, 0, 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, 4, 0, 0, 0, 0, 68,160, 0, 0,196, 46, 0, 0, 67,100, 0, 0, 55,136,197,197, 68, 78,209,118, +195,231,222, 40, 67, 25,158,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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0, 66, 40, 0, 0, + 69, 0, 0, 0, 67,225, 0, 0, 63, 0, 0, 0, 63,154,225, 72, 0, 0, 0, 1, 0, 1, 0, 1, 3,233, 2,235, 0, 0, 0, 0, + 0, 3, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0,255,255, 0, 0, 0, 0, 0, 0, 1,150, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 40, 3, 59,106,192, 0, 0, 0, 94, 0, 0, 0, 1, 3, 59,108, 16, 3, 59,105,192, + 0, 0, 0, 2, 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 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,122, 0, 0,189,204,204,205, 63,140,204,205, 63,128, 0, 0, 67,122, 0, 0,192,160, 0, 0, + 64,160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 2,235, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 3,168, 0, 0, 0, 16, 0, 0, 2,235, 60, 35,215, 10, 60, 35,215, 10, 70,106, 96, 0, + 68,122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,152,242, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,122, 0, 0,189,204,204,205, 63,140,204,205, + 68, 65, 84, 65, 0, 0, 0,120, 3, 59,108, 16, 0, 0, 0,101, 0, 0, 0, 1, 3, 59,108,176, 3, 59,106,192, 0, 0, 0, 9, + 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,123,128, 0, 0, 0, 0, + 0, 0, 0, 62, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 5, 0, 0, 0, 17, 0, 0, 2,225, 0, 0, 2,227, 0, 0, 0, 5, + 0, 0, 0, 17, 0, 0, 2,207, 0, 0, 2,227, 68, 65, 84, 65, 0, 0, 0,188, 3, 59,108,176, 0, 0, 0, 99, 0, 0, 0, 1, + 3, 59,109,160, 3, 59,108, 16, 0, 0, 0, 6, 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67,128, 0, 0, 0, 0, 0, 0, 67,128, 0, 0,190,120, 0, 0, 63,159, 0, 0,190,242, 0, 0, + 63,188,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, 1,124, 0, 0, 0, 0, 0, 0, 1,242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 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, 0, 0,196, 3, 59,109,160, 0, 0, 0, 98, 0, 0, 0, 1, 3, 59,110,144, 3, 59,108,176, 0, 0, 0, 3, 63, 51, 51, 51, + 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67,182, 0, 0,195,209, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 67,182, 0, 0,195,190, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 1,124, 0, 0, 0, 0, + 0, 0, 1,124,195,190, 0, 0,195,190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1, + 0, 1, 0, 1, 1,108, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,142, 0, 1, 0, 0, 0, 0, 0, 0, + 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, 0, 0,160, 3, 59,110,144, + 0, 0, 0,168, 0, 0, 0, 1, 3, 59,111, 96, 3, 59,109,160, 0, 0, 0, 11, 63, 51, 51, 51, 3, 59, 95, 0,192,128, 0, 0, + 67,122, 0, 0,192,128, 0, 0, 67,127, 0, 0,192,128, 0, 0, 66, 72, 0, 0,192,128, 0, 0, 67,127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 1,124, 0, 0, 0, 16, 0, 0, 1,124, 63,128, 0, 0, 67,129,128, 0, 70,250, 0, 0, 67,129,128, 0, 61,204,204,205, + 65, 32, 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, 68, 65, 84, 65, 0, 0, 0,164, 3, 59,111, 96, 0, 0, 0,100, 0, 0, 0, 1, 3, 59,112, 48, + 3, 59,110,144, 0, 0, 0, 13, 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 68,122, 0, 0, 0, 0, 0, 0, 68,122, 0, 0,192,160, 0, 0, 66,130, 0, 0, + 0, 0, 0, 0, 67,182, 0, 0, 0, 0, 1,108, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 1,124, 0, 0, 0,196, 0, 0, 1,108, + 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,196, 0, 0, 1,108, 0, 0, 0, 16, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 0, + 68,122, 0, 0, 68,122, 0, 0, 61,204,204,205, 66, 72, 0, 0, 0, 10, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 68, 65, 84, 65, 0, 0, 0,176, 3, 59,112, 48, 0, 0, 0,177, 0, 0, 0, 1, 3, 59,113, 16, 3, 59,111, 96, 0, 0, 0, 12, + 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,191, 0, 0, 0, 66, 2, 0, 0, +193,128, 0, 0, 67,247, 0, 0,191, 0, 0, 0, 66, 2, 0, 0,193,128, 0, 0, 67,247, 0, 0, 0, 0, 1,108, 0, 0, 1,124, + 0, 0, 0, 0, 0, 0, 2, 14, 0, 0, 0,128, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,128, 0, 0, 1,108, + 0, 0, 0, 16, 0, 0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 70,250, 0, 0, 68,122, 0, 0, 60, 35,215, 10, 66, 72, 0, 0, + 0, 10, 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, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1, 84, 3, 59,113, 16, 0, 0, 0, 97, 0, 0, 0, 1, 0, 0, 0, 0, 3, 59,112, 48, + 0, 0, 0, 5, 63, 51, 51, 51, 3, 59, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,101, 83, 97,118,101, 32, 70,105,108,101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 85,115,101, +114,115, 47,116,111,110, 47, 68,101,115,107,116,111,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,112,114,101,118, +105,101,119, 46, 98,108,101,110,100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 53, 0, 0, 0, 0, 1, 76, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67, 0, 0, 3,244, 3,152,218, 32, 0, 0, 0, 88, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 67,112,114,101,118,105,101,119, 0, 0, 99,101,110,101, 46, + 48, 48, 49, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3,152,230, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 59, 62, 80, 3, 59,117, 16, 3, 59,116, 32,192,170, 70, 9, 65,150,211,102, 65, 24,138,188,190, 20, 72, 63, 63,236, 94, 79, + 63,212,186,156,190, 20, 72, 63, 63,236, 94, 79, 63,212,186,156,190, 20, 72, 63, 63,236, 94, 79, 63,212,186,156, 0, 0, 0, 16, + 61,204,204,205, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,117, 96, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,117,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0,250, 0,100, + 0,100, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,128, + 1,224, 0, 60, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 25, 0,141, 2, 88, 2, 88, 0,100, 0,100, 0, 4, + 0, 4, 0, 0, 0, 24, 0, 4, 0, 0, 0, 0, 0, 90, 0, 16, 0, 0, 0, 2, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 25, 0, 10, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63, 76,204,205, 63,102,102,102, 63,128, 0, 0, 64,128, 0, 0, 65, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 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, + 47, 47,102,116,121,112,101, 0, 64, 38, 35, 0, 0, 0, 0, 0, 64, 94, 0, 0, 64, 38, 94, 0, 0, 0, 35, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,172, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 53, 73,192, 0, 1, 0, 0, 0, 0, 0, 1, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59, 62, 80, + 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,114,144, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 1,244, 1, 44, + 3,149, 52, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,114,144, 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,114,224, 3, 59, 62, 80, + 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 1,244, 1, 44, 3,152,254, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,114,224, + 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,115, 48, 3, 59,114,144, 0, 0, 0, 31, 0, 0, 0, 1, 0, 0, 4, 0, 1, 85, 0,253, + 3,152,234, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,115, 48, 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,115,128, 3, 59,114,224, + 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 1,241, 1, 51, 3,152,250, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,115,128, + 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,115,208, 3, 59,115, 48, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1,242, 1, 43, + 3,153, 6, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,115,208, 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,116, 32, 3, 59,115,128, + 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 0, 1,245, 1, 44, 3,152,246, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,116, 32, + 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,116,112, 3, 59,115,208, 0, 0, 0, 27, 0, 0, 0, 4, 0, 0, 4, 1, 1,210, 2, 8, + 3,152,242, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,116,112, 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,116,192, 3, 59,116, 32, + 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 1,229, 1, 56, 3,153, 2, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,116,192, + 0, 0, 0, 80, 0, 0, 0, 1, 3, 59,117, 16, 3, 59,116,112, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 4, 0, 2, 45, 1, 75, + 3,152,238, 32, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,117, 16, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 3, 59,116,192, + 0, 0, 0, 31, 0, 0, 0, 6, 0, 0, 4, 0, 1,243, 1, 44, 3,152,230, 32, 68, 65, 84, 65, 0, 0, 0, 40, 3, 59,117, 96, + 0, 0, 0, 79, 0, 0, 0, 1, 1, 44, 0, 0, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 1, 1,244, 0,200, 0,100, 0, 20, + 0, 0, 39, 16, 61,204,204,205, 65,240, 0, 0, 64, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 28, 3, 59,117,176, 0, 0, 0, 87, + 0, 0, 0, 1, 0, 1, 0, 1, 0, 90, 0, 9, 0, 1, 0,248, 63,128, 0, 0, 58,131, 18,111, 0, 32, 0, 32, 0, 32, 0, 12, + 0, 0, 67, 65, 0, 0, 0,116, 3, 59,118, 0, 0, 0, 0, 23, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 65, 67, 97,109,101,114, 97, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 62, 76,204,205, 0, 0, 0, 0, 61,204,204,205, 66,200, 0, 0, 65,240, 0, 0, 64,234, 14,161, + 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, 76, 65, 0, 0, 0,252, 3, 59,118,160, 0, 0, 0, 32, 0, 0, 0, 1, 3, 59,119,208, + 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, 0, 1, 0, 0, 0, 0, 1, 7, 0, 0, 48, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 62,241,111,110, 65,239,255,247, 66,150, 0, 0, 62, 25,153,154, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 11, 64, 0, 3, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0, 0,252, + 3, 59,119,208, 0, 0, 0, 32, 0, 0, 0, 1, 3, 59,121, 0, 3, 59,118,160, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112, +111,116, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 8, 0, 0, 32, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 65,239,255,247, 66,150, 0, 0, + 62, 25,153,154, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 11, 64, 0, 3, 63,128, 26, 46, 65,240, 4, 25, 66, 52, 0, 0, + 63,128, 0, 0, 64, 64, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 0, 0, 0,252, 3, 59,121, 0, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 0, + 3, 59,119,208, 0, 0, 0, 0, 0, 0, 0, 0, 76, 65, 83,112,111,116, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 9, 0, 2, 0, 1, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 65,239,255,247, 66,134,189, 89, 63, 8,156,171, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 2, 0, 0, 3, 65, 68,207, 78, 65,240, 4, 25, 66, 52, 0, 0, 63,128, 0, 0, 64, 64, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 88, 0, 0, 0,100, + 3, 59,123,128, 0, 0, 0, 21, 0, 0, 0, 1, 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, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 1, 3, 59,124, 16, 3, 59,124, 16, 3, 59,124, 16, 3, 59,124, 16, 0, 0, 0, 0, 0, 0, 0, 0, + 3,152,224, 32,255,255,255,255, 0, 0, 4, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 24, 3, 59,124, 16, 0, 0, 0, 20, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54,253, 48, 0, 0, 0, 0, 0, 0, 0, 0, 70, 82, 69, 69, 68, 65, 84, 65, + 0, 0, 0, 4, 3, 54,253, 48, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,230, 32, + 0, 0, 0, 72, 0, 0, 0, 1, 3,152,234, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67, 97,109,101,114, 97, + 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 3, 59,118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +188, 41,199, 78,193, 30,230,225, 63,230,129,216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, + 37,128, 0, 0, 37,127,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 37,127,255,255,165,128, 0, 0, + 0, 0, 0, 0, 37,127,255,255, 51,162, 33,105, 63,128, 0, 0, 0, 0, 0, 0, 37,128, 0, 0,191,128, 0, 0, 51,162, 33,105, + 0, 0, 0, 0,188, 41,199, 78,193, 30,230,225, 63,230,129,216, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,137,145,110, 60, 24,136,133,160, + 0, 0, 0, 0, 25,127,255,254, 63,128, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0,165,127,255,255,176,136, 90, 64, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 31, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0, 64, 0, 0, 0, + 63,128, 0, 0, 63,100, 41, 6, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 63,100, 41, 6, 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, + 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,234, 32, 0, 0, 0, 72, 0, 0, 0, 1, 3,152,238, 32, 3,152,230, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 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, 3, 59,118,160, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,193, 90,123, 84,192,142, 0, 91,192, 20,182,149, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85,190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138, 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176, + 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47, 0, 0, 0, 0,193, 90,123, 84,192,142, 0, 91,192, 20,182,149, + 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 62,255,247,135,191, 44, 21,165, 63, 11,203,251, 0, 0, 0, 0, 62,182, 26,138, 63, 59,248,176, 63, 20, 7, 45, + 0, 0, 0, 0,191, 74, 39, 36,189,194, 67, 20, 63, 27, 45,217, 0, 0, 0, 0, 64,124,208, 20,192,213, 69,117, 65, 82,168,235, + 63,128, 0, 0, 0, 0, 0, 31, 4, 0, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, + 0, 0, 0, 0, 61,204,204,205, 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, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,238, 32, + 0, 0, 0, 72, 0, 0, 0, 1, 3,152,242, 32, 3,152,234, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, + 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 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, 3, 59,119,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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,158,166,168,193, 49,113, 32, 64,141,166, 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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,103, 90, 85, +190,186, 45,254, 63,128,209,115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,255,247,136, 63, 74, 39, 37, 62,182, 26,138, + 0, 0, 0, 0,191, 44, 21,164, 61,194, 67, 28, 63, 59,248,176, 0, 0, 0, 0, 63, 11,203,251,191, 27, 45,217, 63, 20, 7, 47, + 0, 0, 0, 0, 64,158,166,168,193, 49,113, 32, 64,141,166, 74, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62,255,247,138,191, 44, 21,164, 63, 11,203,252, + 0, 0, 0, 0, 62,182, 26,139, 63, 59,248,175, 63, 20, 7, 46, 0, 0, 0, 0,191, 74, 39, 35,189,194, 67, 22, 63, 27, 45,218, + 0, 0, 0, 0,192, 32, 43,120, 63,194,195,233,192,157,225, 9, 63,128, 0, 0, 0, 0, 0, 31, 4, 0, 0, 0, 0, 0, 0, 68, + 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, + 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 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, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,242, 32, 0, 0, 0, 72, 0, 0, 0, 1, 3,152,246, 32, 3,152,238, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 76, 97,109,112, 46, 48, 48, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 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, 3, 59,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,192, 57, 60,242,192, 12,214, 41, 65,165,198, 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, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,189,202,150, 78,190,106, 34, 54, 63,210, 21,188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,189,140,126,106, 63,120,183,216, 62,104, 25, 82, 0, 0, 0, 0,191,126,132,252,189, 67,160,106,189,196,254, 53, + 0, 0, 0, 0,189,169, 56, 36,190,109,131,118, 63,120, 30, 85, 0, 0, 0, 0,192, 57, 60,242,192, 12,214, 41, 65,165,198, 39, + 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0,189,140,126,123,191,126,132,253,189,169, 56, 56, 0, 0, 0, 0, 62,104, 25, 88,189,196,254, 53, 63,120, 30, 85, + 0, 0, 0, 0,191,120,183,216, 61, 67,160,105, 62,109,131,124, 0, 0, 0, 0,193, 63,245, 23,191, 45,152,205,193,134, 68,185, + 63,128, 0, 0, 0, 0, 0, 27, 4, 1, 0, 0, 0, 0, 0, 68, 0, 5, 0, 1, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, + 0, 0, 0, 0, 61,204,204,205, 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, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,246, 32, + 0, 0, 0, 72, 0, 0, 0, 1, 3,152,250, 32, 3,152,242, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 67,117, 98,101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 59,130,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 42,129, 6, 64, 10, 76, 70, 63,224,238, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64,234,184,168, 64,234,184,168, 64,234,184,168, 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, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,234,184,168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64,234,184,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,234,184,168, + 0, 0, 0, 0, 62, 42,129, 6, 64, 10, 76, 70, 63,224,238, 21, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62, 11,154,150, 36, 11,154,149,164, 11,154,150, + 0, 0, 0, 0, 35,208, 20,224, 50, 48,212, 20, 62, 11,154,150, 0, 0, 0, 0, 46,229, 96, 14,190, 11,154,150, 50, 46, 47, 96, + 0, 0, 0, 0,188,197,136,191,191,211, 4, 23, 59,194,166, 86, 63,128, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 68, + 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, + 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 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, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,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, 3, 56,213, 96, + 3, 56,214, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,250, 32, 0, 0, 0, 72, 0, 0, 0, 1, 3,152,254, 32, 3,152,246, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 59,134,176, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 54, 44, 80,190,128,229, 16, 64, 34, 43, 64, 64, 25, 22,237, 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, 86,211,232, 64, 86,211,235, 64, 86,211,232, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,209,255, 6,190,200, 64, 93, 63, 41, 50, 19, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64, 28,200,191, 63,243,211, 29, 63,163,203, 32, 0, 0, 0, 0,192, 18,182,139, 64, 7,122,207, 63,158, 98,192, + 0, 0, 0, 0,189,214,156, 60,191,227,115,184, 64, 54, 34, 4, 0, 0, 0, 0,190,128,229, 16, 64, 34, 43, 64, 64, 25, 22,237, + 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 62, 94,163,153,190, 80, 86,110,188, 24, 96,158, 0, 0, 0, 0, 61,232,151,178, 61,224,233,205, 62,129, 81, 75, + 0, 0, 0, 0,190, 45, 30,172,190, 64, 98,200, 62, 33,126,180, 0, 0, 0, 0,192, 7,207,232,192, 29, 46,151, 63,232, 60, 1, + 63,128, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, + 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 3, 54, 44, 80, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,152,254, 32, 0, 0, 0, 72, 0, 0, 0, 1, + 3,153, 2, 32, 3,152,250, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101,119, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 59,137,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 55, 39,112, 60,149,192, 57,191,103,204, 21, + 63,230,165,241, 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,155, 39,153, + 64,155, 39,153, 64,155, 39,153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, 37,192, 0, 0, 36,255,255,255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,155, 39,153, 38, 27, 39,152,166,232,187,102, 0, 0, 0, 0, 38,232,187,102, + 52,196,134,157, 64,155, 39,153, 0, 0, 0, 0, 38, 27, 39,154,192,155, 39,153, 52,196,134,157, 0, 0, 0, 0, 60,149,192, 57, +191,103,204, 21, 63,230,165,241, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 62, 83, 50, 25, 35,211, 50, 28,163,211, 50, 23, 0, 0, 0, 0,163,211, 50, 27, + 62, 83, 50, 25, 38,174, 59,158, 0, 0, 0, 0, 43,109, 64, 0,175, 96, 79,158, 62, 83, 50, 25, 0, 0, 0, 0,187,193,146,253, +185,110, 94,217, 63,238, 71,118, 63,128, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, + 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, 63,128, 0, 0, 61, 35,215, 10, + 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 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, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0, 4, 3, 55, 39,112, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,153, 2, 32, + 0, 0, 0, 72, 0, 0, 0, 1, 3,153, 6, 32, 3,152,254, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101, +119, 46, 48, 48, 50, 0, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,129,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 59,124, 80, 3, 59,124, 80, 3, 55, 8, 96, +191,155,194,150, 63,165,215, 50, 64, 52,152, 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, 65, 50,249, 88, 65, 50,249, 90, 65, 50,249, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,163, 13,190, + 62,170,212,237,191, 14,142,222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 15,142, 5,192,178,192,180,192,106,116,153, + 0, 0, 0, 0, 64,150,132, 32, 63,109, 78, 95, 65, 33,180, 10, 0, 0, 0, 0,192,151,201,228,193, 26, 89, 80, 64, 69,234,108, + 0, 0, 0, 0,191,155,194,150, 63,165,215, 50, 64, 52,152, 12, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 61,146,218,202, 61, 25,249,216,189, 27, 71, 31, + 0, 0, 0, 0,188,239,216, 77, 61,165,107,151, 60,202,119, 22, 0, 0, 0, 0, 61, 54,220,153,187,242,194,197, 61,157,229,156, + 0, 0, 0, 0, 63, 30, 28,147,189,246, 87, 4, 63, 75,107,128, 63,128, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 68, + 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, + 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,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, 3, 58,186, 16, + 3, 58,227, 32, 68, 65, 84, 65, 0, 0, 0, 4, 3, 55, 8, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 68, 65, 84, 65, + 0, 0, 0, 68, 3, 59,124, 80, 0, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 23, + 83,117, 98,115,117,114,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, 1, 0, 2, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66, 0, 0, 2,220, 3,153, 6, 32, + 0, 0, 0, 72, 0, 0, 0, 1, 3,149, 52, 32, 3,153, 2, 32, 0, 0, 0, 0, 0, 0, 0, 0, 79, 66,112,114,101,118,105,101, +119, 46, 48, 48, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 59,133,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 55,116,128, +190, 20, 72, 63, 63,236, 94, 79, 63,212,186,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, 63, 76, 39,227, 63, 76, 39,227, 63, 76, 39,227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,201, 15,218, +128, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 76, 39,227, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 51,129, 75,227, 63, 76, 39,227, 0, 0, 0, 0, 0, 0, 0, 0,191, 76, 39,227, 51,129, 75,227, + 0, 0, 0, 0,190, 20, 72, 63, 63,236, 94, 79, 63,212,186,156, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,160,129, 63,165,160,129, 62,165,160,129, 63, + 0, 0, 0, 0, 37,160,129, 63, 63,160,129, 63, 40, 73, 67,160, 0, 0, 0, 0, 48, 3,174, 26,175,163, 58, 36, 63,160,129, 63, + 0, 0, 0, 0, 62, 44,161,191, 62, 50, 87,173, 65,108, 77,158, 63,128, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 68, + 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, 0, 0, 0, 0,201,150,180, 56, + 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,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, 3, 56,215, 48, + 3, 56,215,208, 68, 65, 84, 65, 0, 0, 0, 4, 3, 55,116,128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 79, 66, + 0, 0, 2,220, 3,149, 52, 32, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 0, 0, 3,153, 6, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 79, 66,112,114,101,118,105,101,119, 46, 48, 48, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 59,133,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 54,238,240, 58, 10, 31, 0, 63,236, 94, 59, 63,231, 84,236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,110,188, 91, 63,110,188, 91, 63,110,188, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,201, 15,218,128, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,110,188, 91, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51,151, 50, 90, 63,110,188, 91, 0, 0, 0, 0, 0, 0, 0, 0, +191,110,188, 91, 51,151, 50, 90, 0, 0, 0, 0, 58, 10, 31, 0, 63,236, 94, 59, 63,231, 84,236, 63,128, 0, 0, 63,128, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,137, 65,160, +165,137, 65,159,165,137, 65,161, 0, 0, 0, 0, 37,137, 65,160, 63,137, 65,160, 40, 19, 46,157, 0, 0, 0, 0, 45, 14,127,248, +176,150,195,159, 63,137, 65,161, 0, 0, 0, 0,188, 63, 80, 29,187,226, 95, 62, 65, 74, 19, 87, 63,128, 0, 0, 0, 0, 0, 16, + 4, 0, 0, 0, 0, 0, 0, 68, 0, 1, 0, 2, 0, 0, 0, 0, 79, 66, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,100, + 0, 0, 0, 0, 64, 0, 0, 0, 63,128, 0, 0, 61, 35,215, 10, 63,128, 0, 0, 62,204,204,205, 0, 0, 0, 0, 61,204,204,205, + 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,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, 3, 55,126, 16, 3, 55,131, 80, 68, 65, 84, 65, 0, 0, 0, 4, 3, 54,238,240, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 77, 65, 0, 0, 1,164, 3, 59,124,192, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 77, 65,112,114,101,118,105,101,119, 0, 0, 97,116,101,114,105, 97,108, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 63,128, 0, 0, 63, 54,232, 61, 63, 23,161,184, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63, 76,204,205, 63, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 63,160, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, + 0, 50, 0, 6, 3, 17, 0, 3, 3, 17, 0, 3, 0, 1, 0, 4, 0, 12, 0, 4, 63, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 2, + 0, 0, 0, 0, 63, 0, 0, 0, 64,128, 0, 0, 63, 0, 0, 0, 61,204,204,205, 63, 0, 0, 0, 61,204,204,205, 61,204,204,205, + 63,128, 0, 0, 8, 1, 0, 1, 3, 59,127, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 3, 59,126,144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 88, 3, 59,126,144, 0, 0, 0, 25, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,128,192, + 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 0, 16, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, + 62, 76,204,205, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 1,136, 3, 59,127, 16, 0, 0, 0, 28, 0, 0, 0, 1, 0, 0, 0, 2, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62,220, 40,245, 0, 0, 0, 0, 63,125,112,164, + 63,128, 0, 0, 63, 24,214,106, 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 1, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, + 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, + 63,128, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63, 0, 0, 0, 63,128, 0, 0, 63, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 84, 69, 0, 0, 0,228, 3, 59,128,192, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 84,101,120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 1, 5, 62,128, 0, 0, 64,160, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0, 63,128, 0, 0, + 63,128, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 32, 0, 0, 0, 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, 63,128, 0, 0, 63,128, 0, 0, 0, 1, 0, 1, + 0, 3, 0, 0, 0, 0, 0, 0, 60,204,204,205, 0, 0, 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, 77, 69, + 0, 0, 0,188, 3, 59,129,208, 0, 0, 0, 47, 0, 0, 0, 1, 3, 59,130,192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 77, 69, 67,117, 98,101, 46, 48, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 3, 58,185,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 57, 0,144, 3,153, 98, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 3,153, 10, 32, 3,153, 50, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1,251, 0, 0, 3,237, 0, 0, 1,244, 0, 0, 0, 1, 61, 88,133,192,189, 85, 45,184,190, 24,181,196, + 63, 35, 71,185, 62,235, 31,153, 62,203,102,130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 4, 0, 1, 0, 1, 0, 1, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 3, 57, 0,144, 0, 0, 0, 0, 0, 0, 0, 1, + 3, 59,124,192, 68, 65, 84, 65, 0, 0, 39,156, 3,153, 10, 32, 0, 0, 0, 52, 0, 0, 1,251, 62,131,144,140, 60,200,163,119, + 62, 85, 9,156, 92,125,170, 70, 21,228, 1,255,190, 26,222, 50, 60,200,163,119, 62, 85, 9,156,163,131,170, 70, 21,228, 1,255, + 62,146,126, 61,188, 8, 37,223, 62, 47,183, 99, 76,247,194,191, 81,228, 3,255,190, 56,185,147,188, 8, 37,223, 62, 47,183, 99, +179, 9,194,191, 81,228, 3,255, 62,157,176,129,188,217, 91,211, 61,246,238,244, 84, 31,181,226, 61,191, 3,255,190, 79, 30, 28, +188,217, 91,211, 61,246,238,244,171,225,181,226, 61,191, 3,255, 62, 94, 19,115,189,128,251,103, 62, 14, 32,150, 9,241,144,155, + 62, 64, 3,255,189,227,161, 26,189,128,251,103, 62, 14, 32,150,246, 15,144,155, 62, 64, 3,255, 62, 94, 19,115,189, 25,118,251, + 62, 62,165, 20, 14,184,163,144, 87, 76, 3,255,189,227,161, 26,189, 25,118,251, 62, 62,165, 20,241, 72,163,144, 87, 76, 3,255, + 62, 94, 19,115, 60, 34,107,232, 62, 92,128,116, 3, 3,131,121, 29,110, 1,255,189,227,161, 26, 60, 34,107,232, 62, 92,128,116, +252,253,131,121, 29,110, 1,255, 62, 56,193, 58, 60,200,163,119, 62, 99,247, 77,171, 56,167,117, 36,206, 1,255,189,152,252,168, + 60,200,163,119, 62, 99,247, 77, 84,200,167,117, 36,206, 1,255, 62, 23, 42,109,188, 8, 37,223, 62, 73,215, 88,200,184,189,130, + 94, 93, 3,255,189, 43,158, 31,188, 8, 37,223, 62, 73,215, 88, 55, 72,189,130, 94, 93, 3,255, 62, 0,197,229,188,217, 91,211, + 62, 29, 14, 71,184,179,175, 93, 69, 66, 3,255,188,164, 23,249,188,217, 91,211, 62, 29, 14, 71, 71, 77,175, 93, 69, 66, 3,255, + 61,182,231, 88, 61,121,154,159, 62, 32,201,179,151,181,255,104, 74, 51, 3,255, 60,134,121,207, 61,121,154,159, 62, 32,201,179, +104, 75,255,104, 74, 51, 3,255, 61,242,158, 25, 61,121,154,159, 62, 73,215, 88,171, 78,255,150, 95,246, 3,255,188, 80,194,110, + 61,121,154,159, 62, 73,215, 88, 84,178,255,150, 95,246, 3,255, 62, 41,211,138, 61,121,154,159, 62, 99,247, 77,133,152,254,153, + 37, 98, 1,255,189,118, 66,143, 61,121,154,159, 62, 99,247, 77,122,104,254,153, 37, 98, 1,255, 62, 56,193, 58, 61,206,232,154, + 62, 99,247, 77,170, 24, 88, 13, 35, 89, 1,255,189,152,252,168, 61,206,232,154, 62, 99,247, 77, 85,232, 88, 13, 35, 89, 1,255, + 62, 23, 42,109, 62, 5, 79,173, 62, 73,215, 88,200,249, 65,221, 94,244, 3,255,189, 43,158, 31, 62, 5, 79,173, 62, 73,215, 88, + 55, 7, 65,221, 94,244, 3,255, 62, 0,197,229, 62, 27,180, 54, 62, 29, 14, 71,186, 51, 78, 86, 73, 78, 3,255,188,164, 23,249, + 62, 27,180, 54, 62, 29, 14, 71, 69,205, 78, 86, 73, 78, 3,255, 62, 94, 19,115, 62, 65, 6,111, 62, 14, 32,150, 11, 2,107,152, + 68,114, 3,255,189,227,161, 26, 62, 65, 6,111, 62, 14, 32,150,244,254,107,152, 68,114, 3,255, 62, 94, 19,115, 62, 35, 43, 14, + 62, 62,165, 20, 14,201, 91,180, 88, 14, 3,255,189,227,161, 26, 62, 35, 43, 14, 62, 62,165, 20,241, 55, 91,180, 88, 14, 3,255, + 62, 94, 19,115, 61,236,195,250, 62, 92,128,116, 2,134,125, 29, 26,228, 1,255,189,227,161, 26, 61,236,195,250, 62, 92,128,116, +253,122,125, 29, 26,228, 1,255, 62,131,144,140, 61,206,232,154, 62, 85, 9,156, 93, 54, 85, 67, 20,154, 1,255,190, 26,222, 50, + 61,206,232,154, 62, 85, 9,156,162,202, 85, 67, 20,154, 1,255, 62,146,126, 61, 62, 5, 79,173, 62, 47,183, 99, 76,241, 60,161, + 82, 97, 3,255,190, 56,185,147, 62, 5, 79,173, 62, 47,183, 99,179, 15, 60,161, 82, 97, 3,255, 62,157,176,129, 62, 27,180, 54, + 61,246,238,244, 83,179, 71,157, 65, 45, 3,255,190, 79, 30, 28, 62, 27,180, 54, 61,246,238,244,172, 77, 71,157, 65, 45, 3,255, + 62,176, 89,157, 61,121,154,159, 61,232, 1, 67,111, 40,255,113, 63,117, 3,255,190,116,112, 84, 61,121,154,159, 61,232, 1, 67, +144,216,255,113, 63,117, 3,255, 62,161,107,237, 61,121,154,159, 62, 40, 64,139,100, 48,255,154, 79,167, 3,255,190, 86,148,244, + 61,121,154,159, 62, 40, 64,139,155,208,255,154, 79,167, 3,255, 62,139, 7,100, 61,121,154,159, 62, 81, 78, 48,126,117,254,181, + 19,185, 1,255,190, 41,203,227, 61,121,154,159, 62, 81, 78, 48,129,139,254,181, 19,185, 1,255, 62,140,229, 26, 61,121,154,159, + 62, 88,197, 8,120,160,254,106, 42,198, 3,255,190, 45,135, 79, 61,121,154,159, 62, 88,197, 8,135, 96,254,106, 42,198, 3,255, + 62,133,110, 66, 61,214, 95,114, 62, 92,128,116, 93,173, 74,126, 45, 93, 3,255,190, 30,153,158, 61,214, 95,114, 62, 92,128,116, +162, 83, 74,126, 45, 93, 3,255, 62, 94, 19,115, 61,251,177,170, 62,103,178,185, 11, 9,115, 31, 54,216, 3,255,189,227,161, 26, + 61,251,177,170, 62,103,178,185,244,247,115, 31, 54,216, 3,255, 62, 53, 5,206, 61,214, 95,114, 62,111, 41,145,181, 9, 80,184, + 65, 43, 3,255,189,145,133,208, 61,214, 95,114, 62,111, 41,145, 74,247, 80,184, 65, 43, 3,255, 62, 34, 92,178, 61,121,154,159, + 62,111, 41,145,146,116,254, 57, 66, 43, 3,255,189, 88,103, 48, 61,121,154,159, 62,111, 41,145,109,140,254, 57, 66, 43, 3,255, + 62, 53, 5,206, 60,170,200, 22, 62,111, 41,145,182, 34,173,181, 64,115, 3,255,189,145,133,208, 60,170,200, 22, 62,111, 41,145, + 73,222,173,181, 64,115, 3,255, 62, 94, 19,115, 61,121,154,159, 62,114,228,253, 24, 74,255,139,125,171, 3,255,189,227,161, 26, + 61,121,154,159, 62,114,228,253,231,182,255,139,125,171, 3,255, 62, 94, 19,115, 59, 43,249,149, 62,103,178,185, 10,218,140,140, + 54, 45, 3,255,189,227,161, 26, 59, 43,249,149, 62,103,178,185,245, 38,140,140, 54, 45, 3,255, 62,133,110, 66, 60,170,200, 22, + 62, 92,128,116, 92,141,179,203, 44,210, 3,255,190, 30,153,158, 60,170,200, 22, 62, 92,128,116,163,115,179,203, 44,210, 3,255, + 61, 88,133,203, 62, 23,248,202, 62, 73,215, 88, 0, 0,124, 43, 31, 17, 1,255, 61, 88,133,203, 61,229, 77, 34, 62,111, 41,145, + 0, 0,249, 63,127,209, 1,255, 61, 88,133,203,190,188,254,150, 62, 70, 27,236, 0, 0,251,204,127,237, 1,255, 61, 88,133,203, +190, 78, 79,191, 62, 92,128,116, 0, 0,150, 33, 71,238, 3,255, 61, 88,133,203,190, 14,221,146, 62, 99,247, 77, 0, 0,100, 28, + 79,192, 1,255, 61, 88,133,203,190,211, 99, 30, 62, 62,165, 20, 0, 0,142,184, 59,147, 3,255, 61, 88,133,203, 62, 12,198,133, + 62, 6,169,190, 0, 0,103,143, 75, 57, 1,255, 61, 88,133,203, 62, 91, 38, 99, 61,239,120, 28, 0, 0, 78,115,101, 34, 1,255, + 61, 88,133,203, 62,187,243, 16,190,206,250,170, 0, 0,110,190,191,212, 3,255, 61, 88,133,203, 62, 87,106,247,191, 11,224,178, + 0, 0, 35,144,133, 12, 3,255, 61, 88,133,203,188,157,165, 18,191, 9, 20, 33, 0, 0,214,194,134,213, 3,255, 61, 88,133,203, +190,108, 43, 32,190,160, 83,227, 0, 0,134,154,215,113, 3,255, 62, 23, 42,109,190, 14,221,146, 61,232, 1, 67,113,144,198,122, + 13, 79, 1,255,189, 43,158, 31,190, 14,221,146, 61,232, 1, 67,142,112,198,122, 13, 79, 1,255, 62, 75,106, 87,190,131, 37,138, + 61,239,120, 28,122,196, 31, 19, 18,152, 3,255,189,190, 78,225,190,131, 37,138, 61,239,120, 28,133, 60, 31, 19, 18,152, 3,255, + 62, 94, 19,115,190,192,186, 2, 61,239,120, 28,125,167, 12,146, 20,226, 1,255,189,227,161, 26,190,192,186, 2, 61,239,120, 28, +130, 89, 12,146, 20,226, 1,255, 62,101,138, 75,190,239, 96,200, 61,202, 37,227,124,113,242,142, 26,196, 3,255,189,242,142,203, +190,239, 96,200, 61,202, 37,227,131,143,242,142, 26,196, 3,255, 62, 82,225, 47,190,252,112,195, 61,194,175, 10, 79,159,159, 44, + 25,210, 3,255,189,205, 60,146,190,252,112,195, 61,194,175, 10,176, 97,159, 44, 25,210, 3,255, 62, 11,248, 41,191, 1, 4,242, + 61,224,138,107, 19,143,131, 13, 19,178, 3,255,188,253,170, 27,191, 1, 4,242, 61,224,138,107,236,113,131, 13, 19,178, 3,255, + 61, 88,133,203,191, 2,226,168, 61,246,238,244, 0, 0,130, 75, 24, 21, 3,255, 62,131,144,140,189,240,242, 18, 61,202, 37,227, + 47,114,137,117, 8,232, 3,255,190, 26,222, 50,189,240,242, 18, 61,202, 37,227,208,142,137,117, 8,232, 3,255, 62,178, 55, 83, +189,143,233, 23, 61,209,156,187, 77, 25,154,198, 13,214, 3,255,190,120, 43,193,189,143,233, 23, 61,209,156,187,178,231,154,198, + 13,214, 3,255, 62,224,222, 26, 60,140,236,182, 61,112, 21, 49,113,216,198,247, 12,255, 3,255,190,170,188,167, 60,140,236,182, + 61,112, 21, 49,142, 40,198,247, 12,255, 3,255, 62,232, 84,243, 62, 23,248,202, 62, 2,238, 82,113,104, 51, 31, 30, 32, 3,255, +190,178, 51,128, 62, 23,248,202, 62, 2,238, 82,142,152, 51, 31, 30, 32, 3,255, 62,196,224,112, 62, 50, 24,190, 62, 17,220, 2, + 64,216,106,225, 27,121, 1,255,190,142,190,253, 62, 50, 24,190, 62, 17,220, 2,191, 40,106,225, 27,121, 1,255, 62,144,160,134, + 62,106, 20, 20, 62, 47,183, 99, 75,137,101, 82, 20, 70, 1,255,190, 52,254, 39, 62,106, 20, 20, 62, 47,183, 99,180,119,101, 82, + 20, 70, 1,255, 62, 79, 37,195, 62,154, 92, 67, 62, 70, 27,236, 38,241,119, 19, 26, 54, 3,255,189,197,197,186, 62,154, 92, 67, + 62, 70, 27,236,217, 15,119, 19, 26, 54, 3,255, 62, 0,197,229, 62,145, 7,181, 62, 81, 78, 48,175, 21, 96, 54, 24, 12, 3,255, +188,164, 23,249, 62,145, 7,181, 62, 81, 78, 48, 80,235, 96, 54, 24, 12, 3,255, 61,167,249,168, 62, 53,212, 42, 62, 77,146,196, +155,174, 76,128, 21,151, 1,255, 60,194, 48,144, 62, 53,212, 42, 62, 77,146,196,100, 82, 76,128, 21,151, 1,255, 62, 4,129, 81, + 62, 16,129,241, 62, 88,197, 8, 25, 0,237, 4,124, 22, 1,255,188,193,243, 89, 62, 16,129,241, 62, 88,197, 8,231, 0,237, 4, +124, 22, 1,255, 61,227,176,105, 61,184,132, 17, 62, 85, 9,156,255,160,232,126,125,209, 1,255,187,178,169,214, 61,184,132, 17, + 62, 85, 9,156, 0, 96,232,126,125,209, 1,255, 62, 23, 42,109,188, 8, 37,223, 62, 73,215, 88,238, 27,221,135,121,245, 1,255, +189, 43,158, 31,188, 8, 37,223, 62, 73,215, 88, 17,229,221,135,121,245, 1,255, 62,105, 69,184,189, 55, 82, 92, 62, 55, 46, 59, + 34,106,200,119,110, 16, 1,255,189,250, 5,163,189, 55, 82, 92, 62, 55, 46, 59,221,150,200,119,110, 16, 1,255, 62,144,160,134, +188,187,128,115, 62, 40, 64,139, 55,161,207, 60,104,115, 1,255,190, 52,254, 39,188,187,128,115, 62, 40, 64,139,200, 95,207, 60, +104,115, 1,255, 62,176, 89,157, 61, 17, 26,205, 62, 29, 14, 71, 58,181,226,123,109,214, 1,255,190,116,112, 84, 61, 17, 26,205, + 62, 29, 14, 71,197, 75,226,123,109,214, 1,255, 62,180, 21, 9, 61,177, 13, 57, 62, 29, 14, 71, 49,157,230, 61,115, 36, 1,255, +190,123,231, 45, 61,177, 13, 57, 62, 29, 14, 71,206, 99,230, 61,115, 36, 1,255, 62,170,192,123, 61,251,177,170, 62, 36,133, 31, + 39,206,234,175,119,196, 1,255,190,105, 62, 16, 61,251,177,170, 62, 36,133, 31,216, 50,234,175,119,196, 1,255, 62,129,178,214, + 62, 27,180, 54, 62, 62,165, 20, 24, 62,255, 85,125,173, 1,255,190, 23, 34,198, 62, 27,180, 54, 62, 62,165, 20,231,194,255, 85, +125,173, 1,255, 62, 45,142,246, 62, 42,161,230, 62, 81, 78, 48, 31,251,247, 40,123,158, 1,255,189,130,152, 32, 62, 42,161,230, + 62, 81, 78, 48,224, 5,247, 40,123,158, 1,255, 61, 88,133,203,190,209,133,104, 62, 70, 27,236, 0, 0,210,148,119,170, 1,255, + 61,212,194,185,190,198, 83, 36, 62, 70, 27,236, 19, 39,222, 65,121,248, 1,255, 58,240,196,191,190,198, 83, 36, 62, 70, 27,236, +236,217,222, 65,121,248, 1,255, 61,220, 57,145,190,226, 80,207, 62, 58,233,167, 2,134,217,132,122, 12, 1,255,186,236,241, 77, +190,226, 80,207, 62, 58,233,167,253,122,217,132,122, 12, 1,255, 61,167,249,168,190,237,131, 19, 62, 51,114,207,252, 13,214,169, +121, 18, 1,255, 60,194, 48,144,190,237,131, 19, 62, 51,114,207, 3,243,214,169,121, 18, 1,255, 61, 88,133,203,190,239, 96,200, + 62, 47,183, 99, 0, 0,219,150,122,180, 1,255, 61, 88,133,203,190, 18,152,254, 62, 77,146,196, 0, 0, 97, 46, 83, 76, 1,255, + 61, 88,133,203,189,240,242, 18, 62, 73,215, 88, 0, 0,104,197, 73,134, 1,255, 61,205, 75,225,189,248,104,235, 62, 73,215, 88, + 36, 52, 53, 2,110,187, 1,255, 59,179,158,179,189,248,104,235, 62, 73,215, 88,219,204, 53, 2,110,187, 1,255, 61,227,176,105, +190, 33,134,174, 62, 77,146,196, 95,187,212, 14, 72,182, 1,255,187,178,169,214,190, 33,134,174, 62, 77,146,196,160, 69,212, 14, + 72,182, 1,255, 61,190, 94, 48,190, 63, 98, 15, 62, 73,215, 88, 64,117,207,117, 99, 90, 1,255, 60, 81, 60,220,190, 63, 98, 15, + 62, 73,215, 88,191,139,207,117, 99, 90, 1,255, 62,116,119,252,189,151, 95,239, 62, 40, 64,139, 49,103,196,157,102, 13, 1,255, +190, 8, 53, 22,189,151, 95,239, 62, 40, 64,139,206,153,196,157,102, 13, 1,255, 62,174,123,231,188,217, 91,211, 62, 17,220, 2, + 59,142,204,107,100,223, 3,255,190,112,180,232,188,217, 91,211, 62, 17,220, 2,196,114,204,107,100,223, 3,255, 62,200,155,220, + 61, 46,246, 45, 62, 6,169,190, 66,102,217, 11,102, 65, 1,255,190,146,122,105, 61, 46,246, 45, 62, 6,169,190,189,154,217, 11, +102, 65, 1,255, 62,204, 87, 72, 61,251,177,170, 62, 32,201,179, 54, 87,228,142,112,151, 1,255,190,150, 53,213, 61,251,177,170, + 62, 32,201,179,201,169,228,142,112,151, 1,255, 62,191, 71, 78, 62, 16,129,241, 62, 66, 96,128, 42, 82,247, 97,120,125, 3,255, +190,137, 37,219, 62, 16,129,241, 62, 66, 96,128,213,174,247, 97,120,125, 3,255, 62,131,144,140, 62, 79,244, 31, 62, 99,247, 77, + 41,192,254,216,120,253, 1,255,190, 26,222, 50, 62, 79,244, 31, 62, 99,247, 77,214, 64,254,216,120,253, 1,255, 62, 75,106, 87, + 62,124,189, 48, 62,118,160,105, 28,217, 7, 53,124,126, 1,255,189,190, 78,225, 62,124,189, 48, 62,118,160,105,227, 39, 7, 53, +124,126, 1,255, 62, 23, 42,109, 62,113,138,236, 62,126, 23, 65,255,125, 5, 44,127,227, 1,255,189, 43,158, 31, 62,113,138,236, + 62,126, 23, 65, 0,131, 5, 44,127,227, 1,255, 61,205, 75,225, 62, 23,248,202, 62,122, 91,213,238,130, 2, 89,126,197, 1,255, + 59,179,158,179, 62, 23,248,202, 62,122, 91,213, 17,126, 2, 89,126,197, 1,255, 61,227,176,105,189,203,159,217, 62,107,110, 37, + 23,115,230, 27,123, 34, 1,255,187,178,169,214,189,203,159,217, 62,107,110, 37,232,141,230, 27,123, 34, 1,255, 62, 26,229,218, +190,133, 3, 64, 62, 58,233,167, 74,212, 14, 28,102,225, 3,255,189, 58,139,207,190,133, 3, 64, 62, 58,233,167,181, 44, 14, 28, +102,225, 3,255, 62, 45,142,246,190,194,151,184, 62, 47,183, 99, 72,235,252, 17,105, 31, 3,255,189,130,152, 32,190,194,151,184, + 62, 47,183, 99,183, 21,252, 17,105, 31, 3,255, 62, 53, 5,206,190,222,149, 99, 62, 36,133, 31, 66,179,225,197,104,249, 3,255, +189,145,133,208,190,222,149, 99, 62, 36,133, 31,189, 77,225,197,104,249, 3,255, 62, 38, 24, 30,190,244,249,234, 62, 21,151,111, + 44, 62,183, 4, 95, 98, 3,255,189,103, 84,224,190,244,249,234, 62, 21,151,111,211,194,183, 4, 95, 98, 3,255, 62, 4,129, 81, +190,248,181, 86, 62, 21,151,111, 19,155,158, 52, 80, 54, 3,255,188,193,243, 89,190,248,181, 86, 62, 21,151,111,236,101,158, 52, + 80, 54, 3,255, 61, 88,133,203,190,252,112,195, 62, 25, 82,219, 0, 0,154,201, 78, 88, 3,255, 61, 88,133,203,188,247, 55, 52, + 62, 66, 96,128, 0, 0,252, 2,127,239, 1,255, 61, 88,133,203, 61, 61,227,222, 62, 85, 9,156, 0, 0,227,112,124,196, 1,255, + 62, 82,225, 47, 62, 46, 93, 82, 62, 73,215, 88, 21, 58,254,234,126, 56, 1,255,189,205, 60,146, 62, 46, 93, 82, 62, 73,215, 88, +234,198,254,234,126, 56, 1,255, 62, 4,129, 81, 60, 94, 34,170, 62, 77,146,196,214, 37,232,110,118,163, 1,255,188,193,243, 89, + 60, 94, 34,170, 62, 77,146,196, 41,219,232,110,118,163, 1,255, 61,235, 39, 65, 61, 61,227,222, 62, 81, 78, 48,232,150,230,127, +123, 57, 1,255,188, 21, 11,173, 61, 61,227,222, 62, 81, 78, 48, 23,106,230,127,123, 57, 1,255, 61,220, 57,145,190,190,220, 76, + 62, 70, 27,236, 20,117,248,197,126, 36, 1,255,186,236,241, 77,190,190,220, 76, 62, 70, 27,236,235,139,248,197,126, 36, 1,255, + 61,182,231, 88,190,133, 3, 64, 62, 77,146,196, 19, 43, 0,128,126,141, 3,255, 60,134,121,207,190,133, 3, 64, 62, 77,146,196, +236,213, 0,128,126,141, 3,255, 61, 88,133,203,190,133, 3, 64, 62, 77,146,196, 0, 0,255,122,127,254, 1,255, 61, 88,133,203, +190, 82, 11, 43, 62, 73,215, 88, 0, 0,184,121,106, 36, 1,255, 61,197,213, 8,190, 55,235, 55, 62, 92,128,116, 66,167,160,139, + 53, 45, 3,255, 60, 21,134, 27,190, 55,235, 55, 62, 92,128,116,189, 89,160,139, 53, 45, 3,255, 61,235, 39, 65,190, 33,134,174, + 62, 99,247, 77,118,133,224,215, 36,239, 3,255,188, 21, 11,173,190, 33,134,174, 62, 99,247, 77,137,123,224,215, 36,239, 3,255, + 61,212,194,185,189,233,123, 57, 62, 92,128,116, 81,167, 95,141, 24, 49, 3,255, 58,240,196,191,189,233,123, 57, 62, 92,128,116, +174, 89, 95,141, 24, 49, 3,255, 61,145,149, 31,189,226, 4, 97, 62, 92,128,116,200,189,108,160, 39, 26, 3,255, 61, 13,225, 89, +189,226, 4, 97, 62, 92,128,116, 55, 67,108,160, 39, 26, 3,255, 61, 88,133,203,190, 22, 84,106, 62,114,228,253, 0, 0, 23, 42, +125,225, 1,255, 61,153, 11,247,189,248,104,235, 62,107,110, 37,231,186, 78, 89, 98, 66, 3,255, 60,253,231, 82,189,248,104,235, + 62,107,110, 37, 24, 70, 78, 89, 98, 66, 3,255, 61,197,213, 8,189,255,223,195, 62,107,110, 37, 43, 88, 62,134,102,237, 3,255, + 60, 21,134, 27,189,255,223,195, 62,107,110, 37,212,168, 62,134,102,237, 3,255, 61,212,194,185,190, 33,134,174, 62,114,228,253, + 46,247,233, 89,116,228, 3,255, 58,240,196,191,190, 33,134,174, 62,114,228,253,209, 9,233, 89,116,228, 3,255, 61,182,231, 88, +190, 44,184,243, 62,103,178,185, 31, 46,181,198, 99,128, 3,255, 60,134,121,207,190, 44,184,243, 62,103,178,185,224,210,181,198, + 99,128, 3,255, 61, 88,133,203,190, 63, 98, 15, 62,103,178,185, 0, 0,191,185,110,175, 3,255, 62, 49, 74, 98,190, 74,148, 83, + 61,224,138,107,120, 23, 41, 34, 16, 99, 1,255,189,138, 14,248,190, 74,148, 83, 61,224,138,107,135,233, 41, 34, 16, 99, 1,255, + 62, 4,129, 81,190, 40,253,134, 62, 58,233,167, 80,251,250, 26, 98,241, 1,255,188,193,243, 89,190, 40,253,134, 62, 58,233,167, +175, 5,250, 26, 98,241, 1,255, 62, 11,248, 41,190, 74,148, 83, 62, 58,233,167, 83,215, 16,153, 95, 71, 1,255,188,253,170, 27, +190, 74,148, 83, 62, 58,233,167,172, 41, 16,153, 95, 71, 1,255, 62, 38, 24, 30,190, 44,184,243, 61,224,138,107,122, 24, 35, 67, + 15, 64, 1,255,189,103, 84,224,190, 44,184,243, 61,224,138,107,133,232, 35, 67, 15, 64, 1,255, 61, 88,133,203,190,235,165, 93, + 62, 47,183, 99, 0, 0, 86,139, 94, 77, 1,255, 61,153, 11,247,190,233,199,167, 62, 47,183, 99,206,144, 70,200, 94,125, 1,255, + 60,253,231, 82,190,233,199,167, 62, 47,183, 99, 49,112, 70,200, 94,125, 1,255, 61,197,213, 8,190,222,149, 99, 62, 58,233,167, +164,253, 17,109, 88, 75, 1,255, 60, 21,134, 27,190,222,149, 99, 62, 58,233,167, 91, 3, 17,109, 88, 75, 1,255, 61,197,213, 8, +190,203,236, 70, 62, 66, 96,128,225,141,168, 87, 88, 39, 1,255, 60, 21,134, 27,190,203,236, 70, 62, 66, 96,128, 30,115,168, 87, + 88, 39, 1,255, 61, 88,133,203,190,213, 64,212, 62, 32,201,179, 0, 0,159, 20, 83,153, 1,255, 61,197,213, 8,190,205,201,252, + 62, 36,133, 31,230, 5,177,250, 98, 20, 1,255, 60, 21,134, 27,190,205,201,252, 62, 36,133, 31, 25,251,177,250, 98, 20, 1,255, + 61,197,213, 8,190,220,183,173, 62, 25, 82,219,152, 18, 24, 8, 70,188, 1,255, 60, 21,134, 27,190,220,183,173, 62, 25, 82,219, +103,238, 24, 8, 70,188, 1,255, 61,153, 11,247,190,230, 12, 59, 62, 21,151,111,222, 26, 49,242,112,221, 1,255, 60,253,231, 82, +190,230, 12, 59, 62, 21,151,111, 33,230, 49,242,112,221, 1,255, 61, 88,133,203,190,231,233,241, 62, 21,151,111, 0, 0, 60, 18, +113, 5, 1,255, 62, 8, 60,189, 61, 76,209,142, 62, 92,128,116, 30, 4,244, 93,123,225, 1,255,188,223,206,186, 61, 76,209,142, + 62, 92,128,116,225,252,244, 93,123,225, 1,255, 62, 15,179,149, 60,170,200, 22, 62, 88,197, 8, 9, 71,251, 34,127,144, 1,255, +189, 13,194,190, 60,170,200, 22, 62, 88,197, 8,246,185,251, 34,127,144, 1,255, 62, 86,156,155, 62, 23,248,202, 62, 81, 78, 48, + 17, 81, 2, 74,126,204, 1,255,189,212,179,106, 62, 23,248,202, 62, 81, 78, 48,238,175, 2, 74,126,204, 1,255, 62, 56,193, 58, + 62, 20, 61, 94, 62, 88,197, 8, 25,218,253,177,125, 86, 3,255,189,152,252,168, 62, 20, 61, 94, 62, 88,197, 8,230, 38,253,177, +125, 86, 3,255, 62,127,170, 64, 62, 9, 11, 25, 62, 88,197, 8, 21,182,240,210,125, 57, 3,255,190, 19,103, 90, 62, 9, 11, 25, + 62, 88,197, 8,234, 74,240,210,125, 57, 3,255, 62,161,107,237, 61,229, 77, 34, 62, 51,114,207, 28,143,237,249,123,117, 1,255, +190, 86,148,244, 61,229, 77, 34, 62, 51,114,207,227,113,237,249,123,117, 1,255, 62,167, 5, 15, 61,169,150, 97, 62, 47,183, 99, + 15,209,246,217,126,175, 1,255,190, 97,199, 56, 61,169,150, 97, 62, 47,183, 99,240, 47,246,217,126,175, 1,255, 62,165, 39, 89, + 61, 32, 8,125, 62, 43,251,247, 24,177,253,190,125,146, 1,255,190, 94, 11,204, 61, 32, 8,125, 62, 43,251,247,231, 79,253,190, +125,146, 1,255, 62,140,229, 26,187,152,222, 60, 62, 62,165, 20, 33, 20, 2, 75,123,160, 1,255,190, 45,135, 79,187,152,222, 60, + 62, 62,165, 20,222,236, 2, 75,123,160, 1,255, 62,105, 69,184,188,187,128,115, 62, 73,215, 88, 26, 85,248,238,125, 14, 1,255, +189,250, 5,163,188,187,128,115, 62, 73,215, 88,229,171,248,238,125, 14, 1,255, 62, 34, 92,178,186,133,194,226, 62, 92,128,116, + 7, 8,250,142,127,175, 1,255,189, 88,103, 48,186,133,194,226, 62, 92,128,116,248,248,250,142,127,175, 1,255, 62, 11,248, 41, + 61,177, 13, 57, 62, 92,128,116, 34,169,240, 2,122, 43, 1,255,188,253,170, 27, 61,177, 13, 57, 62, 92,128,116,221, 87,240, 2, +122, 43, 1,255, 62, 26,229,218, 61,251,177,170, 62, 92,128,116, 27,126,239,108,123,231, 1,255,189, 58,139,207, 61,251,177,170, + 62, 92,128,116,228,130,239,108,123,231, 1,255, 62, 38, 24, 30, 61,236,195,250, 62, 81, 78, 48, 64,226,207, 13, 98,224, 1,255, +189,103, 84,224, 61,236,195,250, 62, 81, 78, 48,191, 30,207, 13, 98,224, 1,255, 62, 19,111, 1, 61,177, 13, 57, 62, 81, 78, 48, + 96, 29,229,169, 80, 81, 1,255,189, 28,176,110, 61,177, 13, 57, 62, 81, 78, 48,159,227,229,169, 80, 81, 1,255, 62, 41,211,138, + 59,205,106, 77, 62, 81, 78, 48, 55, 36, 71,122, 90,188, 1,255,189,118, 66,143, 59,205,106, 77, 62, 81, 78, 48,200,220, 71,122, + 90,188, 1,255, 62,105, 69,184,188, 67,220,161, 62, 66, 96,128, 21, 76, 78, 90, 98,241, 1,255,189,250, 5,163,188, 67,220,161, + 62, 66, 96,128,234,180, 78, 90, 98,241, 1,255, 62,137, 41,174, 59, 43,249,149, 62, 55, 46, 59,245, 85, 69, 69,107, 25, 1,255, +190, 38, 16,118, 59, 43,249,149, 62, 55, 46, 59, 10,171, 69, 69,107, 25, 1,255, 62,157,176,129, 61, 61,227,222, 62, 40, 64,139, +223,232, 29,211,120, 67, 1,255,190, 79, 30, 28, 61, 61,227,222, 62, 40, 64,139, 32, 24, 29,211,120, 67, 1,255, 62,159,142, 55, + 61,162, 31,137, 62, 40, 64,139,210,148,238,123,118, 95, 1,255,190, 82,217,136, 61,162, 31,137, 62, 40, 64,139, 45,108,238,123, +118, 95, 1,255, 62,153,245, 21, 61,214, 95,114, 62, 43,251,247,229,216,179,108, 99, 43, 1,255,190, 71,167, 67, 61,214, 95,114, + 62, 43,251,247, 26, 40,179,108, 99, 43, 1,255, 62,123,238,212, 62, 5, 79,173, 62, 77,146,196,237,202,158,179, 81, 35, 3,255, +190, 15,171,238, 62, 5, 79,173, 62, 77,146,196, 18, 54,158,179, 81, 35, 3,255, 62, 60,124,166, 62, 9, 11, 25, 62, 85, 9,156, + 39, 24,212,118,113,214, 3,255,189,160,115,129, 62, 9, 11, 25, 62, 85, 9,156,216,232,212,118,113,214, 3,255, 62, 86,156,155, + 62, 12,198,133, 62, 77,146,196, 1,213,193,189,111,208, 1,255,189,212,179,106, 62, 12,198,133, 62, 77,146,196,254, 43,193,189, +111,208, 1,255, 62, 23, 42,109, 60,230,126,216, 62, 77,146,196, 84,226, 42,192, 85,187, 1,255,189, 43,158, 31, 60,230,126,216, + 62, 77,146,196,171, 30, 42,192, 85,187, 1,255, 62, 19,111, 1, 61, 91,191, 63, 62, 77,146,196,102,235, 2,196, 76, 11, 1,255, +189, 28,176,110, 61, 91,191, 63, 62, 77,146,196,153, 21, 2,196, 76, 11, 1,255, 61,212,194,185, 62, 38,230,122, 62, 10,101, 42, +182,183,104,118,246, 5, 1,255, 58,240,196,191, 62, 38,230,122, 62, 10,101, 42, 73, 73,104,118,246, 5, 1,255, 62, 19,111, 1, + 62,131,247,186, 62, 14, 32,150,192,208, 66,221,167, 3, 3,255,189, 28,176,110, 62,131,247,186, 62, 14, 32,150, 63, 48, 66,221, +167, 3, 3,255, 62, 86,156,155, 62,137,144,220, 62, 2,238, 82, 9, 59, 90, 89,165,208, 3,255,189,212,179,106, 62,137,144,220, + 62, 2,238, 82,246,197, 90, 89,165,208, 3,255, 62,142,194,208, 62, 83,175,139, 61,224,138,107, 37,165,114,104,212,176, 1,255, +190, 49, 66,187, 62, 83,175,139, 61,224,138,107,218, 91,114,104,212,176, 1,255, 62,189,105,152, 62, 35, 43, 14, 61,164,211,170, + 45, 67,116, 40,227, 1, 1,255,190,135, 72, 37, 62, 35, 43, 14, 61,164,211,170,210,189,116, 40,227, 1, 1,255, 62,217,103, 66, + 62, 12,198,133, 61,134,248, 73, 94,100, 79,237,223, 18, 1,255,190,163, 69,207, 62, 12,198,133, 61,134,248, 73,161,156, 79,237, +223, 18, 1,255, 62,211,206, 32, 60,200,163,119, 60,211,115,252,120,247,221,255,231,165, 1,255,190,157,172,173, 60,200,163,119, + 60,211,115,252,135, 9,221,255,231,165, 1,255, 62,170,192,123,189, 85, 45,188, 61, 52, 94,112, 76,155,154,106,242, 19, 1,255, +190,105, 62, 16,189, 85, 45,188, 61, 52, 94,112,179,101,154,106,242, 19, 1,255, 62,131,144,140,189,196, 41, 0, 61,142,111, 33, + 56,204,142, 26, 13,138, 1,255,190, 26,222, 50,189,196, 41, 0, 61,142,111, 33,199, 52,142, 26, 13,138, 1,255, 61, 88,133,203, + 62,187,243, 16,188,105,242, 89, 0, 0,106,155, 70,214, 3,255, 61, 88,133,203, 62,208,121,226,190, 62, 7,254, 0, 0,127,243, + 3, 82, 3,255, 61, 88,133,203,190, 18,152,254,190,236,214, 11, 0, 0,164, 54,166,204, 3,255, 61, 88,133,203,190,136,190,173, +189,124,142,139, 0, 0,129,179,235, 65, 1,255, 61, 88,133,203,191, 1,243,205, 61,134,248, 73, 0, 0,151,182,181,204, 3,255, + 61, 88,133,203,190,218,217,247, 60, 56, 12,241, 0, 0,221,231,132,162, 3,255, 61, 88,133,203,190,162,222,161, 57,157, 21,147, + 0, 0,212, 16,135,201, 1,255, 61, 88,133,203,190,142, 87,207,188,146,212,141, 0, 0,147,245,187, 97, 1,255, 62,230,119, 61, + 61,106,172,239,189,253, 43,161,125,164,235,181, 13,156, 1,255,190,176, 85,202, 61,106,172,239,189,253, 43,161,130, 92,235,181, + 13,156, 1,255, 62,232, 84,243, 61,199,113,194,190, 47, 26, 78,126,174,238, 23,252, 66, 1,255,190,178, 51,128, 61,199,113,194, +190, 47, 26, 78,129, 82,238, 23,252, 66, 1,255, 62,211,206, 32, 61,147, 49,216,190,180,218,181, 81, 70, 13,148,158, 15, 1,255, +190,157,172,173, 61,147, 49,216,190,180,218,181,174,186, 13,148,158, 15, 1,255, 62,137, 41,174, 62, 27,180, 54,190,244, 76,226, + 58,123, 21,228,144, 70, 3,255,190, 38, 16,118, 62, 27,180, 54,190,244, 76,226,197,133, 21,228,144, 70, 3,255, 62,202,121,146, +189,151, 95,239,189,238, 61,240, 89, 76,164,139, 6,161, 3,255,190,148, 88, 31,189,151, 95,239,189,238, 61,240,166,180,164,139, + 6,161, 3,255, 62,168,226,197,189,226, 4, 97,190,103, 21,163, 38, 93,134, 34, 7,182, 1,255,190,101,130,164,189,226, 4, 97, +190,103, 21,163,217,163,134, 34, 7,182, 1,255, 62,180, 21, 9,189,100, 27,109,190,178,252,255, 43,106,170,219,170,222, 1,255, +190,123,231, 45,189,100, 27,109,190,178,252,255,212,150,170,219,170,222, 1,255, 62, 86,156,155,188,217, 91,211,190,234,248, 85, + 55,168,213,109,148,229, 3,255,189,212,179,106,188,217, 91,211,190,234,248, 85,200, 88,213,109,148,229, 3,255, 62, 38, 24, 30, +190, 93, 61,112, 61, 37,112,191,120,197,255, 36,213,158, 1,255,189,103, 84,224,190, 93, 61,112, 61, 37,112,191,135, 59,255, 36, +213,158, 1,255, 62, 11,248, 41,190,123, 24,209,188,236,102,176, 84,188,181, 20,196, 24, 1,255,188,253,170, 27,190,123, 24,209, +188,236,102,176,171, 68,181, 20,196, 24, 1,255, 62, 64, 56, 19,190,196,117,110, 60,241, 79, 92, 79,131,254, 86,155,183, 3,255, +189,167,234, 89,190,196,117,110, 60,241, 79, 92,176,125,254, 86,155,183, 3,255, 62, 45,142,246,190,146, 19, 59, 61, 7,149, 95, + 99, 5, 1, 8,174,231, 1,255,189,130,152, 32,190,146, 19, 59, 61, 7,149, 95,156,251, 1, 8,174,231, 1,255, 62, 82,225, 47, +190,244,249,234, 61, 22,131, 15, 62, 65,185,227,168,224, 3,255,189,205, 60,146,190,244,249,234, 61, 22,131, 15,193,191,185,227, +168,224, 3,255, 61,242,158, 25,190,207,167,178, 60,181,152,155, 16,133,232,208,131, 55, 1,255,188, 80,194,110,190,207,167,178, + 60,181,152,155,239,123,232,208,131, 55, 1,255, 61,227,176,105,190,155,103,201, 60,151,189, 58, 48, 7,224,163,141,149, 1,255, +187,178,169,214,190,155,103,201, 60,151,189, 58,207,249,224,163,141,149, 1,255, 62, 4,129, 81,190,252,112,195, 61, 97, 39,129, + 12, 68,158,218,173,147, 1,255,188,193,243, 89,190,252,112,195, 61, 97, 39,129,243,188,158,218,173,147, 1,255, 62, 30,161, 70, +190, 59,166,163, 61, 82, 57,208,124,195,227,106,255,203, 1,255,189, 73,121,127,190, 59,166,163, 61, 82, 57,208,131, 61,227,106, +255,203, 1,255, 62, 26,229,218,190, 33,134,174, 61,142,111, 33,120, 29,231,105, 36,193, 1,255,189, 58,139,207,190, 33,134,174, + 61,142,111, 33,135,227,231,105, 36,193, 1,255, 62, 23, 42,109,190, 7,102,186, 61,172, 74,130,101,160,182,164, 25,240, 1,255, +189, 43,158, 31,190, 7,102,186, 61,172, 74,130,154, 96,182,164, 25,240, 1,255, 62, 26,229,218,190,111,230,140,189,148,171,206, + 84,120,159,221,253,198, 1,255,189, 58,139,207,190,111,230,140,189,148,171,206,171,136,159,221,253,198, 1,255, 62, 67,243,127, +190, 74,148, 83,190,139,205, 16, 67,255,151, 42,228, 73, 3,255,189,175, 97, 49,190, 74,148, 83,190,139,205, 16,188, 1,151, 42, +228, 73, 3,255, 62, 90, 88, 7,189,248,104,235,190,205, 28,244, 63,201,176, 25,179, 0, 3,255,189,220, 42, 66,189,248,104,235, +190,205, 28,244,192, 55,176, 25,179, 0, 3,255, 62,135, 75,248, 62,180,124, 55,190,167,202,187, 56, 34, 95,160,192, 17, 3,255, +190, 34, 85, 10, 62,180,124, 55,190,167,202,187,199,222, 95,160,192, 17, 3,255, 62,135, 75,248, 62,195,105,232,190, 58, 76,146, + 55, 54,115,120, 0,239, 3,255,190, 34, 85, 10, 62,195,105,232,190, 58, 76,146,200,202,115,120, 0,239, 3,255, 62,135, 75,248, + 62,176,192,203,189, 34,252,105, 63,239, 92,164, 60,238, 3,255,190, 34, 85, 10, 62,176,192,203,189, 34,252,105,192, 17, 92,164, + 60,238, 3,255, 62,137, 41,174, 62, 68,193,219, 61, 82, 57,208, 49,123,102,255, 57,170, 1,255,190, 38, 16,118, 62, 68,193,219, + 61, 82, 57,208,206,133,102,255, 57,170, 1,255, 62,200,155,220, 62, 12,198,133, 59,248,172, 95, 98,142, 73,198, 35, 6, 1,255, +190,146,122,105, 62, 12,198,133, 59,248,172, 95,157,114, 73,198, 35, 6, 1,255, 62,178, 55, 83, 62, 35, 43, 14,188,146,212,141, + 61,129,106,254, 33,241, 1,255,190,120, 43,193, 62, 35, 43, 14,188,146,212,141,194,127,106,254, 33,241, 1,255, 62,180, 21, 9, + 62,141, 76, 72,189,253, 43,161, 76,234, 87,151, 52,221, 1,255,190,123,231, 45, 62,141, 76, 72,189,253, 43,161,179, 22, 87,151, + 52,221, 1,255, 62,217,103, 66, 62, 87,106,247,189,185,254, 7,101,187, 66, 28, 40,199, 3,255,190,163, 69,207, 62, 87,106,247, +189,185,254, 7,154, 69, 66, 28, 40,199, 3,255, 62,217,103, 66, 62,113,138,236,190, 80,177, 26,113,183, 58, 68,248,119, 3,255, +190,163, 69,207, 62,113,138,236,190, 80,177, 26,142, 73, 58, 68,248,119, 3,255, 62,180, 21, 9, 62,152,126,141,190,118, 3, 83, + 86,235, 93,238,253,205, 1,255,190,123,231, 45, 62,152,126,141,190,118, 3, 83,169, 21, 93,238,253,205, 1,255, 62,180, 21, 9, + 62,135,179, 38,190,182,184,107, 85,232, 70,154,192,157, 3,255,190,123,231, 45, 62,135,179, 38,190,182,184,107,170, 24, 70,154, +192,157, 3,255, 62,217,103, 66, 62, 76, 56,179,190,162, 49,153,110,166, 42,177,207,222, 3,255,190,163, 69,207, 62, 76, 56,179, +190,162, 49,153,145, 90, 42,177,207,222, 3,255, 62,174,123,231, 61,206,232,154,190,216, 79, 56, 75, 58, 1, 57,152,116, 3,255, +190,112,180,232, 61,206,232,154,190,216, 79, 56,180,198, 1, 57,152,116, 3,255, 62,142,194,208,189, 40,100,171,190,206,250,170, + 70, 73,187,147,173,200, 1,255,190, 49, 66,187,189, 40,100,171,190,206,250,170,185,183,187,147,173,200, 1,255, 62,223, 0,100, + 61,206,232,154,190,121,190,191,114,194, 41, 80, 38,207, 1,255,190,168,222,241, 61,206,232,154,190,121,190,191,141, 62, 41, 80, + 38,207, 1,255, 62,120, 51,104,190, 7,102,186,189,163,153,127, 74,232,154,153, 22, 28, 1,255,190, 11,240,130,190, 7,102,186, +189,163,153,127,181, 24,154,153, 22, 28, 1,255, 62,129,178,214,190, 18,152,254,190,125,122, 44, 71, 89,151,115,237, 1, 1,255, +190, 23, 34,198,190, 18,152,254,190,125,122, 44,184,167,151,115,237, 1, 1,255, 62,239,203,202, 62, 12,198,133,190,132, 86, 56, +220, 72, 93,207, 79,106, 3,255,190,185,170, 88, 62, 12,198,133,190,132, 86, 56, 35,184, 93,207, 79,106, 3,255, 62,211,206, 32, +189,240,242, 18,190, 84,108,135, 15, 30,150, 34, 70, 84, 3,255,190,157,172,173,189,240,242, 18,190, 84,108,135,240,226,150, 34, + 70, 84, 3,255, 63, 9,160, 38,189,203,159,217,190,154,186,192, 67,164,166,138, 61,172, 1,255,190,221, 30,219,189,203,159,217, +190,154,186,192,188, 92,166,138, 61,172, 1,255, 63, 38,140,172,188,217, 91,211,190,178,252,255, 83,179,206,223, 83,114, 1,255, +191, 11,123,244,188,217, 91,211,190,178,252,255,172, 77,206,223, 83,114, 1,255, 63, 46,242, 95, 61,199,113,194,190,177, 31, 73, + 92, 54, 12,232, 87,210, 3,255,191, 19,225,167, 61,199,113,194,190,177, 31, 73,163,202, 12,232, 87,210, 3,255, 63, 32,243,138, + 62, 61, 75, 3,190,177, 31, 73, 62,247, 83,221, 73, 97, 1,255,191, 5,226,209, 62, 61, 75, 3,190,177, 31, 73,193, 9, 83,221, + 73, 97, 1,255, 63, 7,194,112, 62, 46, 93, 82,190,150,255, 84, 5,181,111, 80, 62,236, 1,255,190,217, 99,111, 62, 46, 93, 82, +190,150,255, 84,250, 75,111, 80, 62,236, 1,255, 63, 6,211,149, 62, 16,129,241,190,145,102, 50, 69,236,239,117,105,236, 1,255, +190,215,133,185, 62, 16,129,241,190,145,102, 50,186, 20,239,117,105,236, 1,255, 63, 27, 90,104, 62, 27,180, 54,190,169,168,113, + 24, 34,231,205,123, 89, 1,255,191, 0, 73,175, 62, 27,180, 54,190,169,168,113,231,222,231,205,123, 89, 1,255, 63, 36,174,246, + 61,169,150, 97,190,173, 99,221,223, 69,252, 16,123,173, 1,255,191, 9,158, 62, 61,169,150, 97,190,173, 99,221, 32,187,252, 16, +123,173, 1,255, 63, 30, 38,249,188,127,147, 98,190,173, 99,221,239,171, 39, 0,120,207, 1,255,191, 3, 22, 64,188,127,147, 98, +190,173, 99,221, 16, 85, 39, 0,120,207, 1,255, 63, 8,177, 75,189,143,233, 23,190,149, 33,158, 51, 9, 45, 56,108, 82, 1,255, +190,219, 65, 37,189,143,233, 23,190,149, 33,158,204,247, 45, 56,108, 82, 1,255, 62,224,222, 26,189,173,196,120,190, 88, 39,243, + 38,147, 62,224,104,153, 3,255,190,170,188,167,189,173,196,120,190, 88, 39,243,217,109, 62,224,104,153, 3,255, 62,247, 66,162, + 61,236,195,250,190,128,154,204, 62,218,243,152,110,206, 3,255,190,193, 33, 48, 61,236,195,250,190,128,154,204,193, 38,243,152, +110,206, 3,255, 62,252,219,196, 61,184,132, 17,190,145,102, 50, 87, 10,182, 73, 58, 19, 1,255,190,198,186, 82, 61,184,132, 17, +190,145,102, 50,168,246,182, 73, 58, 19, 1,255, 62,237,238, 21,189,128,251,103,190,125,122, 44, 15,232,121,106, 37, 64, 1,255, +190,183,204,162,189,128,251,103,190,125,122, 44,240, 24,121,106, 37, 64, 1,255, 63, 9,160, 38,189, 85, 45,188,190,164, 15, 79, +239,157,122, 89, 33,212, 1,255,190,221, 30,219,189, 85, 45,188,190,164, 15, 79, 16, 99,122, 89, 33,212, 1,255, 63, 27, 90,104, +188, 8, 37,223,190,182,184,107,158, 8, 81,202, 9,185, 1,255,191, 0, 73,175,188, 8, 37,223,190,182,184,107, 97,248, 81,202, + 9,185, 1,255, 63, 32,243,138, 61,132, 68, 40,190,182,184,107,131, 60,239,145, 23, 95, 1,255,191, 5,226,209, 61,132, 68, 40, +190,182,184,107,124,196,239,145, 23, 95, 1,255, 63, 25,124,178, 61,236,195,250,190,180,218,181,228, 27,153, 22, 70,206, 1,255, +190,252,215,242, 61,236,195,250,190,180,218,181, 27,229,153, 22, 70,206, 1,255, 63, 7,194,112, 61,221,214, 74,190,162, 49,153, + 68, 65,168,253, 64,113, 1,255,190,217, 99,111, 61,221,214, 74,190,162, 49,153,187,191,168,253, 64,113, 1,255, 62,228,153,135, + 61,169,150, 97,190,125,122, 44, 86,113,222,190, 88, 87, 1,255,190,174,120, 20, 61,169,150, 97,190,125,122, 44,169,143,222,190, + 88, 87, 1,255, 62,226,187,209, 60,230,126,216,190,141,170,198, 95,196,182,107, 42,100, 1,255,190,172,154, 93, 60,230,126,216, +190,141,170,198,160, 60,182,107, 42,100, 1,255, 62,208, 18,180,188, 8, 37,223,190,141,170,198,111, 42, 14, 21, 61,220, 1,255, +190,153,241, 65,188, 8, 37,223,190,141,170,198,144,214, 14, 21, 61,220, 1,255, 62,223, 0,100,188, 67,220,161,190,141,170,198, + 79, 3, 91, 4, 43, 19, 3,255,190,168,222,241,188, 67,220,161,190,141,170,198,176,253, 91, 4, 43, 19, 3,255, 62,228,153,135, +189, 55, 82, 92,190,141,170,198,107,207,254,198, 68,250, 3,255,190,174,120, 20,189, 55, 82, 92,190,141,170,198,148, 49,254,198, + 68,250, 3,255, 62,221, 34,174,189,115, 9, 29,190,141,170,198, 82, 7, 64,225, 73,200, 1,255,190,167, 1, 59,189,115, 9, 29, +190,141,170,198,173,249, 64,225, 73,200, 1,255, 62,200,155,220,189, 85, 45,188,190, 58, 76,146,117, 38,207, 66,239, 47, 1,255, +190,146,122,105,189, 85, 45,188,190, 58, 76,146,138,218,207, 66,239, 47, 1,255, 62,198,190, 38,189,128,251,103,190,106,209, 15, + 97,150, 18,139, 80,184, 1,255,190,144,156,179,189,128,251,103,190,106,209, 15,158,106, 18,139, 80,184, 1,255, 62,198,190, 38, +189, 10,137, 74,190,114, 71,231,116, 17,240, 66, 51,154, 1,255,190,144,156,179,189, 10,137, 74,190,114, 71,231,139,239,240, 66, + 51,154, 1,255, 62,217,103, 66, 61, 46,246, 45,190,125,122, 44,113,112,204,245, 30, 39, 1,255,190,163, 69,207, 61, 46,246, 45, +190,125,122, 44,142,144,204,245, 30, 39, 1,255, 62,239,203,202, 61,121,154,159,190,139,205, 16, 90,105,185, 61, 56,146, 1,255, +190,185,170, 88, 61,121,154,159,190,139,205, 16,165,151,185, 61, 56,146, 1,255, 62,239,203,202, 61,106,172,239,190,152,221, 10, + 82,191,204,102, 82,230, 1,255,190,185,170, 88, 61,106,172,239,190,152,221, 10,173, 65,204,102, 82,230, 1,255, 62,221, 34,174, +189,115, 9, 29,190,152,221, 10, 29,246, 98, 64, 76, 94, 1,255,190,167, 1, 59,189,115, 9, 29,190,152,221, 10,226, 10, 98, 64, + 76, 94, 1,255, 62,230,119, 61,189, 55, 82, 92,190,152,221, 10, 77,150, 17,111,100, 75, 1,255,190,176, 85,202,189, 55, 82, 92, +190,152,221, 10,178,106, 17,111,100, 75, 1,255, 62,224,222, 26,188,127,147, 98,190,152,221, 10, 60,239, 60,190, 94,195, 1,255, +190,170,188,167,188,127,147, 98,190,152,221, 10,195, 17, 60,190, 94,195, 1,255, 62,209,240,106,188, 8, 37,223,190,152,221, 10, + 83,199, 23,178, 93,209, 1,255,190,155,206,247,188, 8, 37,223,190,152,221, 10,172, 57, 23,178, 93,209, 1,255, 62,228,153,135, + 60,230,126,216,190,152,221, 10, 73, 98,200, 1, 88,170, 1,255,190,174,120, 20, 60,230,126,216,190,152,221, 10,182,158,200, 1, + 88,170, 1,255, 63, 9,160, 38, 61,206,232,154,190,175, 65,147, 68, 23,223,166,103,112, 1,255,190,221, 30,219, 61,206,232,154, +190,175, 65,147,187,233,223,166,103,112, 1,255, 63, 27, 90,104, 61,221,214, 74,190,192, 12,249, 18,165,216,156,120, 89, 1,255, +191, 0, 73,175, 61,221,214, 74,190,192, 12,249,237, 91,216,156,120, 89, 1,255, 63, 35,192, 27, 61,121,154,159,190,193,234,175, +185, 25,231, 29,103,157, 1,255,191, 8,175, 98, 61,121,154,159,190,193,234,175, 70,231,231, 29,103,157, 1,255, 63, 30, 38,249, +188, 67,220,161,190,192, 12,249,209, 43, 64, 0,100,119, 1,255,191, 3, 22, 64,188, 67,220,161,190,192, 12,249, 46,213, 64, 0, +100,119, 1,255, 63, 10,143, 1,189, 85, 45,188,190,177, 31, 73, 26, 52, 92,240, 84, 3, 1,255,190,222,252,145,189, 85, 45,188, +190,177, 31, 73,229,204, 92,240, 84, 3, 1,255, 62,237,238, 21,189,115, 9, 29,190,139,205, 16, 8, 58,111,116, 62,101, 1,255, +190,183,204,162,189,115, 9, 29,190,139,205, 16,247,198,111,116, 62,101, 1,255, 62,254,185,122, 61,169,150, 97,190,158,118, 45, + 80,198,213,102, 89,175, 1,255,190,200,152, 8, 61,169,150, 97,190,158,118, 45,175, 58,213,102, 89,175, 1,255, 62,239,203,202, +186,133,194,226,190,154,186,192, 25,136, 0,130,125,108, 1,255,190,185,170, 88,186,133,194,226,190,154,186,192,230,120, 0,130, +125,108, 1,255, 62,250,254, 14,188,187,128,115,190,156,152,119, 27, 2, 30, 58,121,104, 1,255,190,196,220,156,188,187,128,115, +190,156,152,119,228,254, 30, 58,121,104, 1,255, 63, 4,245,223, 59,205,106, 77,190,164, 15, 79, 55,218,253,126,115, 35, 1,255, +190,211,202, 76, 59,205,106, 77,190,164, 15, 79,200, 38,253,126,115, 35, 1,255, 63, 0, 75,152, 60,230,126,216,190,160, 83,227, + 41,164,255,199,121, 8, 1,255,190,202,117,190, 60,230,126,216,190,160, 83,227,214, 92,255,199,121, 8, 1,255, 63, 6,211,149, + 61,106,172,239,190,165,237, 5, 39,237, 9,191,121, 55, 1,255,190,215,133,185, 61,106,172,239,190,165,237, 5,216, 19, 9,191, +121, 55, 1,255, 63, 11,125,220, 61, 17, 26,205,190,167,202,187, 46,208,244, 41,118,137, 1,255,190,224,218, 71, 61, 17, 26,205, +190,167,202,187,209, 48,244, 41,118,137, 1,255, 63, 18, 5,218, 61, 61,227,222,190,169,168,113, 53, 70, 3, 84,116, 85, 3,255, +190,237,234, 65, 61, 61,227,222,190,169,168,113,202,186, 3, 84,116, 85, 3,255, 63, 15, 57, 73, 61,154,168,176,190,169,168,113, + 44, 99, 38, 36,113,212, 3,255,190,232, 81, 31, 61,154,168,176,190,169,168,113,211,157, 38, 36,113,212, 3,255, 63, 7,194,112, + 62, 27,180, 54,190,192, 12,249,198,249, 72, 3,166,222, 3,255,190,217, 99,111, 62, 27,180, 54,190,192, 12,249, 57, 7, 72, 3, +166,222, 3,255, 63, 34,209, 64, 62, 42,161,230,190,206,250,170, 37,198, 68,123,154,174, 3,255,191, 7,192,135, 62, 42,161,230, +190,206,250,170,218, 58, 68,123,154,174, 3,255, 63, 48,208, 21, 61,177, 13, 57,190,195,200,102,121, 3, 17,201,218, 73, 3,255, +191, 21,191, 93, 61,177, 13, 57,190,195,200,102,134,253, 17,201,218, 73, 3,255, 63, 42, 72, 24,188,217, 91,211,190,203, 63, 62, + 82, 59,200, 75,175, 70, 3,255,191, 15, 55, 96,188,217, 91,211,190,203, 63, 62,173,197,200, 75,175, 70, 3,255, 63, 9,160, 38, +189,188,178, 40,190,193,234,175,249,134,165,184,165,129, 3,255,190,221, 30,219,189,188,178, 40,190,193,234,175, 6,122,165,184, +165,129, 3,255, 62,215,137,140,189,226, 4, 97,190,154,186,192,249,126,163,122,167,205, 1,255,190,161,104, 25,189,226, 4, 97, +190,154,186,192, 6,130,163,122,167,205, 1,255, 62,232, 84,243, 62, 1,148, 65,190,167,202,187,193, 93, 65,224,165,229, 1,255, +190,178, 51,128, 62, 1,148, 65,190,167,202,187, 62,163, 65,224,165,229, 1,255, 68, 65, 84, 65, 0, 0, 47, 28, 3,153, 50, 32, + 0, 0, 0, 49, 0, 0, 3,237, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 35, + 0, 0, 0, 2, 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 0, 44, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 3, + 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 0, 3, + 0, 0, 0, 45, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 35, + 0, 0, 0, 42, 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 43, 0, 0, 0, 45, + 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 6, + 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 35, + 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 10, + 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 0, 1, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0, 14, 0, 0, 0, 35, + 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 13, + 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 0, 14, 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 0, 6, + 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 35, + 0, 0, 0, 14, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 18, + 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 15, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 17, + 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 0, 12, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 22, 0, 0, 0, 35, + 0, 0, 0, 21, 0, 0, 0, 23, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 0, 23, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 0, 24, + 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 0, 25, + 0, 0, 0, 27, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 27, 0, 0, 0, 35, + 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 0, 18, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 0, 27, 0, 0, 0, 29, + 0, 0, 0, 35, 0, 0, 0, 19, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 0, 26, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 30, + 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 0, 33, 0, 0, 0, 35, + 0, 0, 0, 27, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 31, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 34, + 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 25, + 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 38, 0, 0, 0, 35, + 0, 0, 0, 32, 0, 0, 0, 38, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 37, + 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 0, 30, + 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 0, 31, 0, 0, 0, 41, 0, 0, 0, 35, + 0, 0, 0, 38, 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 42, 0, 0, 0, 35, 0, 0, 0, 39, 0, 0, 0, 45, + 0, 0, 0, 35, 0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 0, 37, + 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 50, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 50, 0, 0, 0, 35, + 0, 0, 0, 46, 0, 0, 0, 48, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 51, 0, 0, 0, 35, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 0, 51, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 0, 50, + 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 0, 51, 0, 0, 0, 53, 0, 0, 0, 35, + 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 0, 54, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 0, 55, + 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 0, 55, 0, 0, 0, 35, 0, 0, 0, 22, 0, 0, 0, 56, 0, 0, 0, 35, 0, 0, 0, 54, + 0, 0, 0, 56, 0, 0, 0, 35, 0, 0, 0, 23, 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 0, 55, 0, 0, 0, 57, 0, 0, 0, 35, + 0, 0, 0, 12, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 0, 13, 0, 0, 0, 59, + 0, 0, 0, 35, 0, 0, 0, 57, 0, 0, 0, 59, 0, 0, 0, 35, 0, 0, 0, 10, 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 0, 58, + 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 0, 59, 0, 0, 0, 63, 0, 0, 0, 35, + 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 0, 62, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 65, + 0, 0, 0, 35, 0, 0, 0, 63, 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 0, 49, + 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 60, 0, 0, 0, 35, + 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0, 49, 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0, 60, 0, 0, 0, 62, + 0, 0, 0, 35, 0, 0, 0, 61, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 0, 58, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 59, + 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 35, + 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 55, 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0, 52, 0, 0, 0, 60, + 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0, 50, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0, 51, + 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 0,175, 0, 0, 0, 35, + 0, 0, 0, 90, 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 0, 90, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0,175, + 0, 0, 0, 35, 0, 0, 0, 89, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0, 89, 0, 0, 0, 90, 0, 0, 0, 35, 0, 0, 0, 86, + 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 0, 88, 0, 0, 0, 35, + 0, 0, 0,172, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0, 87, 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0, 87, 0, 0, 0, 89, + 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0, 84, + 0, 0, 0, 86, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 0, 85, 0, 0, 0,170, 0, 0, 0, 35, + 0, 0, 0, 85, 0, 0, 0, 87, 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 0,167, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0,169, + 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0, 83, + 0, 0, 0,168, 0, 0, 0, 35, 0, 0, 0, 83, 0, 0, 0, 85, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0,165, 0, 0, 0, 35, + 0, 0, 0,165, 0, 0, 0,167, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 82, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,168, + 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 0, 78, + 0, 0, 0, 91, 0, 0, 0, 35, 0, 0, 0, 91, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 0,145, 0, 0, 0,163, 0, 0, 0, 35, + 0, 0, 0, 78, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 0, 92, + 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0, 91, + 0, 0, 0, 93, 0, 0, 0, 35, 0, 0, 0, 93, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 0,145, 0, 0, 0,147, 0, 0, 0, 35, + 0, 0, 0, 94, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 0, 35, 0, 0, 0,146, 0, 0, 0,148, + 0, 0, 0, 35, 0, 0, 0, 93, 0, 0, 0, 95, 0, 0, 0, 35, 0, 0, 0, 95, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 0,147, + 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 0,150, 0, 0, 0, 35, 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 0, 35, + 0, 0, 0,148, 0, 0, 0,150, 0, 0, 0, 35, 0, 0, 0, 95, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 0, 97, 0, 0, 0,151, + 0, 0, 0, 35, 0, 0, 0,149, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 0, 96, + 0, 0, 0, 98, 0, 0, 0, 35, 0, 0, 0,150, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 0, 97, 0, 0, 0, 99, 0, 0, 0, 35, + 0, 0, 0, 99, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 0,151, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 0,154, + 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 0,100, 0, 0, 0, 35, 0, 0, 0,152, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 0, 99, + 0, 0, 0,101, 0, 0, 0, 35, 0, 0, 0,101, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 0,153, 0, 0, 0,155, 0, 0, 0, 35, + 0, 0, 0,102, 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 0,102, 0, 0, 0, 35, 0, 0, 0,154, 0, 0, 0,156, + 0, 0, 0, 35, 0, 0, 0,101, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 0,155, + 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 0,104, 0, 0, 0, 35, + 0, 0, 0,156, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 0,105, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 0,159, + 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 0,104, + 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 0,105, 0, 0, 0,107, 0, 0, 0, 35, + 0, 0, 0,107, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 0,159, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 0,162, + 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 0,108, 0, 0, 0, 35, 0, 0, 0,160, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0, 66, + 0, 0, 0,107, 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,161, 0, 0, 0, 35, + 0, 0, 0, 66, 0, 0, 0,108, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,162, 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 0,127, + 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 0,128, + 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 0,128, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 0,162, 0, 0, 0, 35, + 0, 0, 0,127, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0,157, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0,158, 0, 0, 0,179, + 0, 0, 0, 35, 0, 0, 0,128, 0, 0, 0,179, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 0,125, + 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 0,126, 0, 0, 0,179, 0, 0, 0, 35, + 0, 0, 0,123, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 0,154, + 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 0,126, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 0,121, + 0, 0, 0,123, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 0,122, 0, 0, 0,124, 0, 0, 0, 35, + 0, 0, 0,119, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 0,150, + 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 0,122, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 0,117, + 0, 0, 0,119, 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 0,118, 0, 0, 0,120, 0, 0, 0, 35, + 0, 0, 0,115, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 0,115, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 0,146, + 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0,113, + 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 0,116, 0, 0, 0, 35, + 0, 0, 0,113, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 0,176, + 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,114, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 0,164, + 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,111, 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 0,111, 0, 0, 0, 35, + 0, 0, 0,110, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 0, 67, 0, 0, 0,177, + 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0,112, + 0, 0, 0,183, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 0,183, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 0,182, 0, 0, 0, 35, + 0, 0, 0,176, 0, 0, 0,177, 0, 0, 0, 33, 0, 0, 0,181, 0, 0, 0,183, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 0,136, + 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 0,175, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 0,173, 0, 0, 0, 35, 0, 0, 0,135, + 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 0,135, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 0,134, 0, 0, 0, 35, + 0, 0, 0,132, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 0,172, + 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 0,169, 0, 0, 0, 35, 0, 0, 0,131, + 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 0,186, 0, 0, 0, 35, + 0, 0, 0,184, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 0,187, + 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,185, 0, 0, 0, 35, 0, 0, 0,130, + 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0,131, 0, 0, 0,185, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 0,189, 0, 0, 0, 35, + 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0, 33, 0, 0, 0,186, 0, 0, 0,188, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 0,186, + 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 0,189, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 0,187, + 0, 0, 0,188, 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 0,188, 0, 0, 0, 33, 0, 0, 0, 68, 0, 0, 0,184, 0, 0, 0, 35, + 0, 0, 0, 68, 0, 0, 0,185, 0, 0, 0, 35, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 0, 68, 0, 0, 0,129, + 0, 0, 0, 33, 0, 0, 0,129, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 0,190, + 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 0,143, 0, 0, 0,190, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 0,143, 0, 0, 0, 35, + 0, 0, 0,191, 0, 0, 0,193, 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 0,193, 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 0,144, + 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 0,191, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0,194, 0, 0, 0, 35, 0, 0, 0,192, + 0, 0, 0,194, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 0,195, 0, 0, 0, 35, + 0, 0, 0,140, 0, 0, 0,195, 0, 0, 0, 35, 0, 0, 0,140, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,196, + 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0,196, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 0,195, + 0, 0, 0,197, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,197, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0, 35, + 0, 0, 0, 70, 0, 0, 0,137, 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 0,196, 0, 0, 0, 35, 0, 0, 0,137, 0, 0, 0,138, + 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 0,197, 0, 0, 0, 35, 0, 0, 0, 69, 0, 0, 0,190, 0, 0, 0, 35, 0, 0, 0, 69, + 0, 0, 0,189, 0, 0, 0, 35, 0, 0, 0, 69, 0, 0, 0,191, 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 0,205, 0, 0, 0, 35, + 0, 0, 0,205, 0, 0, 0,207, 0, 0, 0, 35, 0, 0, 0, 69, 0, 0, 0,207, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 0,206, + 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0,207, 0, 0, 0, 35, 0, 0, 0, 70, 0, 0, 0,198, 0, 0, 0, 35, 0, 0, 0,198, + 0, 0, 0,199, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 0,199, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,200, 0, 0, 0, 35, + 0, 0, 0,197, 0, 0, 0,200, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 0,201, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0,201, + 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 0,202, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 0,202, 0, 0, 0, 35, 0, 0, 0,201, + 0, 0, 0,203, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 0,203, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0,204, 0, 0, 0, 35, + 0, 0, 0,193, 0, 0, 0,204, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 0,205, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 0,206, + 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,203, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,204, 0, 0, 0, 35, 0, 0, 0,198, + 0, 0, 0,207, 0, 0, 0, 35, 0, 0, 0,139, 0, 0, 0,163, 0, 0, 0, 35, 0, 0, 0,138, 0, 0, 0,176, 0, 0, 0, 35, + 0, 0, 0,140, 0, 0, 0,164, 0, 0, 0, 35, 0, 0, 0,141, 0, 0, 0,210, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 0,210, + 0, 0, 0, 35, 0, 0, 0,142, 0, 0, 0,211, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,211, 0, 0, 0, 35, 0, 0, 0,143, + 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0,144, 0, 0, 0,213, 0, 0, 0, 35, + 0, 0, 0,211, 0, 0, 0,213, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,213, + 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0,208, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 0,209, + 0, 0, 0,213, 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 0,209, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 0,214, 0, 0, 0, 35, + 0, 0, 0,210, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 0,215, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 0,215, + 0, 0, 0, 35, 0, 0, 0, 78, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 0,215, 0, 0, 0, 35, 0, 0, 0, 71, + 0, 0, 0,129, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 0,221, 0, 0, 0, 35, 0, 0, 0,130, 0, 0, 0,221, 0, 0, 0, 35, + 0, 0, 0,131, 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 0,221, + 0, 0, 0, 35, 0, 0, 0,132, 0, 0, 0,219, 0, 0, 0, 35, 0, 0, 0,133, 0, 0, 0,220, 0, 0, 0, 35, 0, 0, 0,220, + 0, 0, 0,222, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 0,219, 0, 0, 0, 35, 0, 0, 0,134, 0, 0, 0,217, 0, 0, 0, 35, + 0, 0, 0,135, 0, 0, 0,218, 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 0,220, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 0,217, + 0, 0, 0, 35, 0, 0, 0,136, 0, 0, 0,216, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 0,218, 0, 0, 0, 35, 0, 0, 0,217, + 0, 0, 0,228, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 0,230, 0, 0, 0, 35, + 0, 0, 0,218, 0, 0, 0,229, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 0,226, + 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 0,228, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 0,227, 0, 0, 0, 35, 0, 0, 0,227, + 0, 0, 0,229, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 0,224, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 0,226, 0, 0, 0, 35, + 0, 0, 0,222, 0, 0, 0,225, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 0,227, 0, 0, 0, 35, 0, 0, 0, 71, 0, 0, 0,223, + 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 0,224, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 0,225, 0, 0, 0, 35, 0, 0, 0,223, + 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 0,228, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 0,229, 0, 0, 0, 35, + 0, 0, 0,180, 0, 0, 0,233, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 0,233, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 0,231, + 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 0,232, 0, 0, 0, 35, 0, 0, 0,232, + 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 0,253, 0, 0, 0, 35, 0, 0, 0,111, 0, 0, 0,253, 0, 0, 0, 35, + 0, 0, 0,112, 0, 0, 0,254, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 0,254, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 0,255, + 0, 0, 0, 35, 0, 0, 0,109, 0, 0, 0,255, 0, 0, 0, 35, 0, 0, 0,110, 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 0,254, + 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 0,113, 0, 0, 0,251, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 0,251, 0, 0, 0, 35, + 0, 0, 0,114, 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 0,115, 0, 0, 0,249, + 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 0,251, 0, 0, 0, 35, 0, 0, 0,116, 0, 0, 0,250, 0, 0, 0, 35, 0, 0, 0,250, + 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 0,117, 0, 0, 0,247, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 0,249, 0, 0, 0, 35, + 0, 0, 0,118, 0, 0, 0,248, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 0,250, 0, 0, 0, 35, 0, 0, 0,119, 0, 0, 0,245, + 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 0,247, 0, 0, 0, 35, 0, 0, 0,120, 0, 0, 0,246, 0, 0, 0, 35, 0, 0, 0,246, + 0, 0, 0,248, 0, 0, 0, 35, 0, 0, 0,121, 0, 0, 0,243, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 0,245, 0, 0, 0, 35, + 0, 0, 0,122, 0, 0, 0,244, 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 0,246, 0, 0, 0, 35, 0, 0, 0,123, 0, 0, 0,241, + 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 0,243, 0, 0, 0, 35, 0, 0, 0,124, 0, 0, 0,242, 0, 0, 0, 35, 0, 0, 0,242, + 0, 0, 0,244, 0, 0, 0, 35, 0, 0, 0,125, 0, 0, 0,239, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 0,241, 0, 0, 0, 35, + 0, 0, 0,126, 0, 0, 0,240, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 0,242, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 0,235, + 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 0,239, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 0,236, 0, 0, 0, 35, 0, 0, 0,236, + 0, 0, 0,240, 0, 0, 0, 35, 0, 0, 0,127, 0, 0, 0,237, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 0,237, 0, 0, 0, 35, + 0, 0, 0,128, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 0,255, + 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 1, 1, 0, 0, 0, 35, 0, 0, 1, 1, + 0, 0, 1, 19, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 1, 19, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 1, 2, 0, 0, 0, 35, + 0, 0, 0,238, 0, 0, 1, 20, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 1, 20, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 1, 21, + 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 1, 21, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1, 20, + 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 1, 21, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1, 17, 0, 0, 0, 35, + 0, 0, 0,240, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 1, 17, + 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 1, 15, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 1, 16, 0, 0, 0, 35, 0, 0, 1, 16, + 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 1, 15, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 1, 13, 0, 0, 0, 35, + 0, 0, 0,244, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 1, 16, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 1, 13, + 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 1, 11, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 1, 12, 0, 0, 0, 35, 0, 0, 1, 12, + 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 1, 11, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 1, 9, 0, 0, 0, 35, + 0, 0, 0,248, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 1, 12, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 1, 9, + 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 1, 7, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 1, 8, 0, 0, 0, 35, 0, 0, 1, 8, + 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1, 7, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 1, 5, 0, 0, 0, 35, + 0, 0, 0,252, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 1, 8, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1, 23, + 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1, 23, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 1, 6, + 0, 0, 1, 24, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 1, 3, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 1, 3, 0, 0, 0, 35, + 0, 0, 0,254, 0, 0, 1, 4, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 1, 4, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1, 25, + 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 1, 25, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 1, 26, 0, 0, 0, 35, 0, 0, 1, 4, + 0, 0, 1, 26, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 1, 25, 0, 0, 0, 35, 0, 0, 1, 24, 0, 0, 1, 26, 0, 0, 0, 35, + 0, 0, 0,107, 0, 0, 1, 27, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 1, 27, 0, 0, 0, 35, 0, 0, 0, 66, 0, 0, 0, 72, + 0, 0, 0, 35, 0, 0, 0,108, 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 1, 28, 0, 0, 0, 35, 0, 0, 0,105, + 0, 0, 1, 29, 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 1, 29, 0, 0, 0, 35, 0, 0, 0,106, 0, 0, 1, 30, 0, 0, 0, 35, + 0, 0, 1, 28, 0, 0, 1, 30, 0, 0, 0, 35, 0, 0, 0,103, 0, 0, 1, 31, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 1, 31, + 0, 0, 0, 35, 0, 0, 0,104, 0, 0, 1, 32, 0, 0, 0, 35, 0, 0, 1, 30, 0, 0, 1, 32, 0, 0, 0, 35, 0, 0, 0,101, + 0, 0, 1, 33, 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 1, 33, 0, 0, 0, 35, 0, 0, 0,102, 0, 0, 1, 34, 0, 0, 0, 35, + 0, 0, 1, 32, 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 0, 99, 0, 0, 1, 35, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1, 35, + 0, 0, 0, 35, 0, 0, 0,100, 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 0, 97, + 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 0, 98, 0, 0, 1, 38, 0, 0, 0, 35, + 0, 0, 1, 36, 0, 0, 1, 38, 0, 0, 0, 35, 0, 0, 0, 95, 0, 0, 1, 39, 0, 0, 0, 35, 0, 0, 1, 37, 0, 0, 1, 39, + 0, 0, 0, 35, 0, 0, 0, 96, 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 1, 40, 0, 0, 0, 35, 0, 0, 0, 93, + 0, 0, 1, 41, 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 1, 41, 0, 0, 0, 35, 0, 0, 0, 94, 0, 0, 1, 42, 0, 0, 0, 35, + 0, 0, 1, 40, 0, 0, 1, 42, 0, 0, 0, 35, 0, 0, 0, 91, 0, 0, 1, 43, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1, 43, + 0, 0, 0, 35, 0, 0, 0, 92, 0, 0, 1, 44, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 1, 44, 0, 0, 0, 35, 0, 0, 1, 51, + 0, 0, 1, 52, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1, 71, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1, 81, 0, 0, 0, 35, + 0, 0, 1, 51, 0, 0, 1, 81, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 1, 82, + 0, 0, 0, 35, 0, 0, 1, 72, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1, 51, 0, 0, 0, 35, 0, 0, 1, 79, + 0, 0, 1, 81, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1, 79, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1, 80, 0, 0, 0, 35, + 0, 0, 1, 80, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1, 50, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 1, 83, + 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1, 83, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 1, 80, + 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 0, 90, 0, 0, 1, 49, 0, 0, 0, 35, 0, 0, 0, 88, 0, 0, 1, 83, 0, 0, 0, 35, + 0, 0, 0, 89, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1, 83, 0, 0, 0, 35, 0, 0, 0, 86, 0, 0, 1, 77, + 0, 0, 0, 35, 0, 0, 0, 87, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 1, 73, + 0, 0, 1, 77, 0, 0, 0, 35, 0, 0, 0, 84, 0, 0, 1, 73, 0, 0, 0, 35, 0, 0, 0, 85, 0, 0, 1, 74, 0, 0, 0, 35, + 0, 0, 1, 74, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 1, 75, 0, 0, 0, 35, 0, 0, 0, 82, 0, 0, 1, 75, + 0, 0, 0, 35, 0, 0, 0, 83, 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 1, 73, + 0, 0, 1, 79, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1, 81, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 1, 80, 0, 0, 0, 35, + 0, 0, 1, 76, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1, 75, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1, 71, + 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 0, 80, + 0, 0, 1, 69, 0, 0, 0, 35, 0, 0, 0, 81, 0, 0, 1, 70, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 1, 85, 0, 0, 0, 35, + 0, 0, 1, 85, 0, 0, 1, 87, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 1, 87, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 1, 88, + 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1, 86, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 1, 69, + 0, 0, 1, 85, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1, 86, 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 1, 89, 0, 0, 0, 35, + 0, 0, 0, 78, 0, 0, 1, 89, 0, 0, 0, 35, 0, 0, 0, 79, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 1, 88, 0, 0, 1, 90, + 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1, 89, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1, 90, 0, 0, 0, 35, 0, 0, 0, 76, + 0, 0, 1, 67, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 1, 95, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1, 95, 0, 0, 0, 35, + 0, 0, 0, 76, 0, 0, 1, 47, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 0, 76, 0, 0, 1, 68, + 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1, 96, 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 1, 95, 0, 0, 0, 35, 0, 0, 0, 77, + 0, 0, 1, 93, 0, 0, 0, 35, 0, 0, 0, 77, 0, 0, 1, 47, 0, 0, 0, 35, 0, 0, 1, 94, 0, 0, 1, 96, 0, 0, 0, 35, + 0, 0, 0, 77, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 1, 93, 0, 0, 0, 35, 0, 0, 1, 48, 0, 0, 1, 91, + 0, 0, 0, 35, 0, 0, 0, 77, 0, 0, 1, 48, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 35, 0, 0, 1, 48, + 0, 0, 1, 92, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1, 91, 0, 0, 0, 35, 0, 0, 1, 48, 0, 0, 1, 52, 0, 0, 0, 35, + 0, 0, 1, 72, 0, 0, 1, 92, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 1, 91, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 1, 92, + 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1, 61, 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 1, 61, 0, 0, 0, 35, 0, 0, 1, 39, + 0, 0, 1, 53, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 1, 62, 0, 0, 0, 35, 0, 0, 1, 40, 0, 0, 1, 54, 0, 0, 0, 35, + 0, 0, 1, 54, 0, 0, 1, 62, 0, 0, 0, 35, 0, 0, 0, 75, 0, 0, 1, 59, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1, 67, + 0, 0, 0, 35, 0, 0, 0, 75, 0, 0, 0, 76, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 1, 68, 0, 0, 0, 35, 0, 0, 0, 75, + 0, 0, 1, 60, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1,101, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 1,101, 0, 0, 0, 35, + 0, 0, 1, 46, 0, 0, 1, 99, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1, 46, 0, 0, 0, 35, 0, 0, 1,100, 0, 0, 1,102, + 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1,102, 0, 0, 0, 35, 0, 0, 1, 46, 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 1, 97, + 0, 0, 1, 99, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 1, 97, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 1, 46, 0, 0, 0, 35, + 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 1, 98, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1, 97, + 0, 0, 0, 35, 0, 0, 0, 74, 0, 0, 0, 75, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 1, 98, 0, 0, 0, 35, 0, 0, 1, 37, + 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 1,107, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1,107, 0, 0, 0, 35, + 0, 0, 1, 38, 0, 0, 1,106, 0, 0, 0, 35, 0, 0, 1, 36, 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 1,108, + 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 1,111, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 1,111, 0, 0, 0, 35, 0, 0, 1,107, + 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 1,108, 0, 0, 1,110, 0, 0, 0, 35, + 0, 0, 1,110, 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 1,113, 0, 0, 0, 35, 0, 0, 1,113, 0, 0, 1,115, + 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 1,115, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 0, 35, 0, 0, 1,110, + 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 1,113, 0, 0, 1,119, 0, 0, 0, 35, + 0, 0, 1,117, 0, 0, 1,119, 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 1,117, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 1,120, + 0, 0, 0, 35, 0, 0, 1,116, 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 1,120, 0, 0, 0, 35, 0, 0, 1, 57, + 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,119, 0, 0, 0, 35, + 0, 0, 1,118, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,120, + 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 1,117, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1, 98, + 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 1,122, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 1,115, 0, 0, 0, 35, + 0, 0, 1,100, 0, 0, 1,116, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 1,110, + 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 1,103, 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 1,107, 0, 0, 0, 35, 0, 0, 1,104, + 0, 0, 1,108, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1,103, 0, 0, 0, 35, + 0, 0, 1, 34, 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 1,103, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 1, 45, + 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 1,104, 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 1, 33, 0, 0, 0, 35, 0, 0, 1, 28, + 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 1, 27, 0, 0, 0, 35, 0, 0, 0, 73, 0, 0, 1, 28, 0, 0, 0, 35, + 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 1,106, + 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 1, 55, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,111, 0, 0, 0, 35, 0, 0, 1, 56, + 0, 0, 1,112, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 1, 56, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,125, 0, 0, 0, 35, + 0, 0, 1,113, 0, 0, 1,125, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 1, 56, 0, 0, 1,126, + 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,125, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 1, 93, + 0, 0, 1,129, 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 1,129, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 1,127, 0, 0, 0, 35, + 0, 0, 1, 94, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 1,128, 0, 0, 1,130, + 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1,129, 0, 0, 0, 35, 0, 0, 1, 61, + 0, 0, 1, 63, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 0, 35, + 0, 0, 1, 64, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1,128, + 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1, 87, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1, 44, + 0, 0, 1, 88, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 1,128, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1, 65, 0, 0, 0, 35, + 0, 0, 1, 65, 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 1,121, 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 1,124, + 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1, 66, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1, 67, + 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 1,129, 0, 0, 0, 35, + 0, 0, 1, 63, 0, 0, 1, 65, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 1, 66, + 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 1,123, 0, 0, 0, 35, 0, 0, 1, 96, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1,131, + 0, 0, 1,143, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 1,145, 0, 0, 1,157, 0, 0, 0, 35, + 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 1,144, + 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 1,145, + 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 1,143, 0, 0, 0, 35, + 0, 0, 1,146, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 1,148, + 0, 0, 0, 35, 0, 0, 1,147, 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1,139, + 0, 0, 1,141, 0, 0, 0, 35, 0, 0, 1,148, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 1,142, 0, 0, 0, 35, + 0, 0, 1,140, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 1,151, + 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 1,139, 0, 0, 0, 35, 0, 0, 1,150, 0, 0, 1,152, 0, 0, 0, 35, 0, 0, 1,138, + 0, 0, 1,140, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 1,152, 0, 0, 0, 35, 0, 0, 1,151, 0, 0, 1,153, 0, 0, 0, 35, + 0, 0, 1,135, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 1,137, 0, 0, 0, 35, 0, 0, 1,152, 0, 0, 1,154, + 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 1,138, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 1,153, + 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 1,135, 0, 0, 0, 35, + 0, 0, 1,154, 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 1,156, + 0, 0, 0, 35, 0, 0, 1,153, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1,155, + 0, 0, 1,161, 0, 0, 0, 35, 0, 0, 1,162, 0, 0, 1,164, 0, 0, 0, 35, 0, 0, 1,154, 0, 0, 1,164, 0, 0, 0, 35, + 0, 0, 1,156, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 1,151, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 1,163, 0, 0, 1,165, + 0, 0, 0, 35, 0, 0, 1,164, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1,152, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1,149, + 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 1,165, 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 1,166, 0, 0, 1,168, 0, 0, 0, 35, + 0, 0, 1,150, 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 1,147, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 1,169, + 0, 0, 0, 35, 0, 0, 1,168, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 1,148, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 1,145, + 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1,169, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1,170, 0, 0, 1,172, 0, 0, 0, 35, + 0, 0, 1,146, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 1,157, 0, 0, 1,159, 0, 0, 0, 35, 0, 0, 1,159, 0, 0, 1,171, + 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 1,160, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 1, 63, + 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1,185, 0, 0, 0, 35, + 0, 0, 1, 64, 0, 0, 1,188, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 1,186, 0, 0, 1,188, + 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1,133, 0, 0, 0, 35, 0, 0, 1,155, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 64, + 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 1,156, 0, 0, 1,188, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,185, 0, 0, 0, 35, + 0, 0, 1, 56, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 1,157, 0, 0, 1,173, + 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 1,131, 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 1,126, + 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 1,126, 0, 0, 1,132, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,183, 0, 0, 0, 35, + 0, 0, 1,183, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1,162, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 1,184, 0, 0, 1,188, + 0, 0, 0, 35, 0, 0, 1,181, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 1,187, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 1,181, + 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1,182, 0, 0, 1,190, 0, 0, 0, 35, + 0, 0, 1,182, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 1,177, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 1,181, + 0, 0, 0, 35, 0, 0, 1,177, 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 1,178, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1,178, + 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 1,180, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 1,191, 0, 0, 0, 35, + 0, 0, 1,189, 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 1,190, 0, 0, 1,192, + 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 1,173, + 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 1,173, 0, 0, 1,193, 0, 0, 0, 33, + 0, 0, 1,174, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 1,174, 0, 0, 1,194, 0, 0, 0, 33, 0, 0, 1,176, 0, 0, 1,194, + 0, 0, 0, 35, 0, 0, 1,159, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 1,160, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 1, 55, + 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 1, 56, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 1,185, 0, 0, 1,189, 0, 0, 0, 35, + 0, 0, 1,186, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1,193, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 1,195, 0, 0, 1,219, + 0, 0, 0, 35, 0, 0, 1,159, 0, 0, 1,219, 0, 0, 0, 35, 0, 0, 1,194, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 1,160, + 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 1,196, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 1,205, 0, 0, 0, 35, + 0, 0, 1,195, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 1,196, 0, 0, 1,206, + 0, 0, 0, 35, 0, 0, 1,177, 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 1,203, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 1,178, + 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 1,204, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 1,201, 0, 0, 0, 35, + 0, 0, 1,201, 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 1,180, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1,202, 0, 0, 1,204, + 0, 0, 0, 35, 0, 0, 1,181, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1,199, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 1,182, + 0, 0, 1,200, 0, 0, 0, 35, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1,183, 0, 0, 1,197, 0, 0, 0, 35, + 0, 0, 1,197, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1,184, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 1,200, + 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 1,197, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 1,162, + 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 1,207, 0, 0, 1,219, 0, 0, 0, 35, + 0, 0, 1,171, 0, 0, 1,207, 0, 0, 0, 35, 0, 0, 1,172, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 1,208, 0, 0, 1,220, + 0, 0, 0, 35, 0, 0, 1,207, 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 1,169, 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 1,170, + 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1,208, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 35, + 0, 0, 1,167, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1,168, 0, 0, 1,212, 0, 0, 0, 35, 0, 0, 1,210, 0, 0, 1,212, + 0, 0, 0, 35, 0, 0, 1,211, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 1,165, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 1,166, + 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1,213, 0, 0, 1,215, 0, 0, 0, 35, + 0, 0, 1,163, 0, 0, 1,215, 0, 0, 0, 35, 0, 0, 1,164, 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 1,214, 0, 0, 1,216, + 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 1,216, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 1,199, + 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1,221, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1,201, 0, 0, 1,221, 0, 0, 0, 35, + 0, 0, 1,200, 0, 0, 1,224, 0, 0, 0, 35, 0, 0, 1,202, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1,222, 0, 0, 1,224, + 0, 0, 0, 35, 0, 0, 1,223, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 1,225, 0, 0, 1,227, 0, 0, 0, 33, 0, 0, 1,221, + 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1,222, 0, 0, 1,228, 0, 0, 0, 35, + 0, 0, 1,226, 0, 0, 1,228, 0, 0, 0, 33, 0, 0, 1,225, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 1,229, 0, 0, 1,231, + 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 1,226, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 1,228, + 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 1,231, 0, 0, 1,233, 0, 0, 0, 35, + 0, 0, 1,233, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,229, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,232, 0, 0, 1,234, + 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 1,234, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 1,219, + 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 1,207, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,220, 0, 0, 1,230, 0, 0, 0, 35, + 0, 0, 1,208, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 1,195, 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 1,196, 0, 0, 1,228, + 0, 0, 0, 35, 0, 0, 1,205, 0, 0, 1,221, 0, 0, 0, 35, 0, 0, 1,206, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1,217, + 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1,218, 0, 0, 1,224, 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 1,225, 0, 0, 0, 35, + 0, 0, 1,216, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1,213, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 1,214, 0, 0, 1,232, + 0, 0, 0, 35, 0, 0, 1,211, 0, 0, 1,233, 0, 0, 0, 35, 0, 0, 1,212, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 1,209, + 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,210, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 1,247, 0, 0, 0, 35, + 0, 0, 1,245, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 1,248, + 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1,246, 0, 0, 1,248, 0, 0, 0, 35, 0, 0, 1,243, + 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 1,244, 0, 0, 0, 35, + 0, 0, 1,244, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1,241, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 1,241, + 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 1,242, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 1,239, + 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 1,240, 0, 0, 0, 35, + 0, 0, 1,240, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 1,237, 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 1,237, + 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1,238, 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 1,237, + 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 1,250, 0, 0, 0, 35, + 0, 0, 1,238, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1,237, 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1,247, 0, 0, 1,249, + 0, 0, 0, 35, 0, 0, 1,238, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1,248, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1,239, + 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 1,240, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,249, 0, 0, 0, 35, + 0, 0, 1, 58, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 1,248, + 0, 0, 0, 35, 68, 65, 84, 65, 0, 0, 39, 16, 3,153, 98, 32, 0, 0, 0, 48, 0, 0, 1,244, 0, 0, 0, 46, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 44, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 47, 0, 0, 0, 45, 0, 0, 0, 3, + 0, 0, 0, 44, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 45, + 0, 0, 0, 43, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 7, + 0, 0, 0, 9, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 12, + 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 13, 0, 0, 0, 11, 0, 0, 0, 9, 0, 0, 0, 3, + 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0, 15, 0, 0, 0, 9, + 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0, 20, 0, 0, 0, 18, 0, 0, 0, 16, 0, 0, 0, 3, 0, 0, 0, 19, + 0, 0, 0, 21, 0, 0, 0, 15, 0, 0, 0, 17, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 0, 22, 0, 0, 0, 20, 0, 0, 0, 14, + 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 0, 24, + 0, 0, 0, 26, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 25, 0, 0, 0, 23, 0, 0, 0, 21, 0, 0, 0, 3, + 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 27, 0, 0, 0, 21, + 0, 0, 0, 19, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 32, 0, 0, 0, 30, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 31, + 0, 0, 0, 33, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 32, 0, 0, 0, 26, + 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 36, + 0, 0, 0, 38, 0, 0, 0, 32, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 0, 33, 0, 0, 0, 3, + 0, 0, 0, 32, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 0, 39, 0, 0, 0, 33, + 0, 0, 0, 31, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 44, 0, 0, 0, 42, 0, 0, 0, 40, 0, 0, 0, 3, 0, 0, 0, 43, + 0, 0, 0, 45, 0, 0, 0, 39, 0, 0, 0, 41, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 46, 0, 0, 0, 44, 0, 0, 0, 38, + 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 3, 0, 0, 0, 46, 0, 0, 0, 36, + 0, 0, 0, 50, 0, 0, 0, 48, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0, 37, 0, 0, 0, 47, 0, 0, 0, 49, 0, 0, 0, 3, + 0, 0, 0, 36, 0, 0, 0, 34, 0, 0, 0, 52, 0, 0, 0, 50, 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 0, 37, + 0, 0, 0, 51, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 24, 0, 0, 0, 54, 0, 0, 0, 52, 0, 0, 0, 3, 0, 0, 0, 55, + 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 0, 53, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0, 22, 0, 0, 0, 56, 0, 0, 0, 54, + 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 55, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 0, 12, + 0, 0, 0, 58, 0, 0, 0, 56, 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 0, 13, 0, 0, 0, 23, 0, 0, 0, 57, 0, 0, 0, 3, + 0, 0, 0, 12, 0, 0, 0, 10, 0, 0, 0, 62, 0, 0, 0, 58, 0, 0, 0, 3, 0, 0, 0, 63, 0, 0, 0, 11, 0, 0, 0, 13, + 0, 0, 0, 59, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 62, 0, 0, 0, 3, 0, 0, 0, 65, + 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 63, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 48, 0, 0, 0, 64, + 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 1, 0, 0, 0, 65, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 64, + 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 0, 65, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 62, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 63, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 58, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 63, + 0, 0, 0, 59, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 56, 0, 0, 0, 58, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 54, + 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 0, 55, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 60, 0, 0, 0, 52, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 0, 53, 0, 0, 0, 61, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 50, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 53, + 0, 0, 0, 51, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 48, 0, 0, 0, 50, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0, 49, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 0,173, + 0, 0, 0,175, 0, 0, 0, 90, 0, 0, 0, 3, 0, 0, 0,175, 0, 0, 0,174, 0, 0, 0, 89, 0, 0, 0, 90, 0, 0, 0, 3, + 0, 0, 0, 86, 0, 0, 0,171, 0, 0, 0,173, 0, 0, 0, 88, 0, 0, 0, 3, 0, 0, 0,174, 0, 0, 0,172, 0, 0, 0, 87, + 0, 0, 0, 89, 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 0,169, 0, 0, 0,171, 0, 0, 0, 86, 0, 0, 0, 3, 0, 0, 0,172, + 0, 0, 0,170, 0, 0, 0, 85, 0, 0, 0, 87, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0,167, 0, 0, 0,169, 0, 0, 0, 84, + 0, 0, 0, 3, 0, 0, 0,170, 0, 0, 0,168, 0, 0, 0, 83, 0, 0, 0, 85, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 0,165, + 0, 0, 0,167, 0, 0, 0, 82, 0, 0, 0, 3, 0, 0, 0,168, 0, 0, 0,166, 0, 0, 0, 81, 0, 0, 0, 83, 0, 0, 0, 3, + 0, 0, 0, 78, 0, 0, 0, 91, 0, 0, 0,145, 0, 0, 0,163, 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 0, 92, 0, 0, 0, 79, + 0, 0, 0,164, 0, 0, 0, 3, 0, 0, 0, 91, 0, 0, 0, 93, 0, 0, 0,147, 0, 0, 0,145, 0, 0, 0, 3, 0, 0, 0,148, + 0, 0, 0, 94, 0, 0, 0, 92, 0, 0, 0,146, 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 0, 95, 0, 0, 0,149, 0, 0, 0,147, + 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 0, 96, 0, 0, 0, 94, 0, 0, 0,148, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 0, 97, + 0, 0, 0,151, 0, 0, 0,149, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 0, 98, 0, 0, 0, 96, 0, 0, 0,150, 0, 0, 0, 3, + 0, 0, 0, 97, 0, 0, 0, 99, 0, 0, 0,153, 0, 0, 0,151, 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 0,100, 0, 0, 0, 98, + 0, 0, 0,152, 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 0,101, 0, 0, 0,155, 0, 0, 0,153, 0, 0, 0, 3, 0, 0, 0,156, + 0, 0, 0,102, 0, 0, 0,100, 0, 0, 0,154, 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 0,103, 0, 0, 0,157, 0, 0, 0,155, + 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 0,104, 0, 0, 0,102, 0, 0, 0,156, 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 0,105, + 0, 0, 0,159, 0, 0, 0,157, 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 0,106, 0, 0, 0,104, 0, 0, 0,158, 0, 0, 0, 3, + 0, 0, 0,105, 0, 0, 0,107, 0, 0, 0,161, 0, 0, 0,159, 0, 0, 0, 3, 0, 0, 0,162, 0, 0, 0,108, 0, 0, 0,106, + 0, 0, 0,160, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 0, 66, 0, 0, 0, 67, 0, 0, 0,161, 0, 0, 0, 3, 0, 0, 0, 67, + 0, 0, 0, 66, 0, 0, 0,108, 0, 0, 0,162, 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 0,127, 0, 0, 0,159, 0, 0, 0,161, + 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 0,128, 0, 0, 0,110, 0, 0, 0,162, 0, 0, 0, 3, 0, 0, 0,127, 0, 0, 0,178, + 0, 0, 0,157, 0, 0, 0,159, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 0,179, 0, 0, 0,128, 0, 0, 0,160, 0, 0, 0, 3, + 0, 0, 0,125, 0, 0, 0,155, 0, 0, 0,157, 0, 0, 0,178, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 0,156, 0, 0, 0,126, + 0, 0, 0,179, 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 0,153, 0, 0, 0,155, 0, 0, 0,125, 0, 0, 0, 3, 0, 0, 0,156, + 0, 0, 0,154, 0, 0, 0,124, 0, 0, 0,126, 0, 0, 0, 3, 0, 0, 0,121, 0, 0, 0,151, 0, 0, 0,153, 0, 0, 0,123, + 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 0,152, 0, 0, 0,122, 0, 0, 0,124, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 0,149, + 0, 0, 0,151, 0, 0, 0,121, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 0,150, 0, 0, 0,120, 0, 0, 0,122, 0, 0, 0, 3, + 0, 0, 0,117, 0, 0, 0,147, 0, 0, 0,149, 0, 0, 0,119, 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 0,148, 0, 0, 0,118, + 0, 0, 0,120, 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 0,145, 0, 0, 0,147, 0, 0, 0,117, 0, 0, 0, 3, 0, 0, 0,148, + 0, 0, 0,146, 0, 0, 0,116, 0, 0, 0,118, 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 0,163, 0, 0, 0,145, 0, 0, 0,115, + 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 0,164, 0, 0, 0,114, 0, 0, 0,116, 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 0,180, + 0, 0, 0,176, 0, 0, 0,163, 0, 0, 0, 3, 0, 0, 0,176, 0, 0, 0,181, 0, 0, 0,114, 0, 0, 0,164, 0, 0, 0, 3, + 0, 0, 0,109, 0, 0, 0,161, 0, 0, 0, 67, 0, 0, 0,111, 0, 0, 0, 3, 0, 0, 0, 67, 0, 0, 0,162, 0, 0, 0,110, + 0, 0, 0,112, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 0, 67, 0, 0, 0,177, 0, 0, 0,182, 0, 0, 0, 3, 0, 0, 0,177, + 0, 0, 0, 67, 0, 0, 0,112, 0, 0, 0,183, 0, 0, 0, 3, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 0,182, 0, 0, 0,177, + 0, 0, 0, 3, 0, 0, 0,183, 0, 0, 0,181, 0, 0, 0,176, 0, 0, 0,177, 0, 0, 0, 3, 0, 0, 0,134, 0, 0, 0,136, + 0, 0, 0,175, 0, 0, 0,173, 0, 0, 0, 3, 0, 0, 0,175, 0, 0, 0,136, 0, 0, 0,135, 0, 0, 0,174, 0, 0, 0, 3, + 0, 0, 0,132, 0, 0, 0,134, 0, 0, 0,173, 0, 0, 0,171, 0, 0, 0, 3, 0, 0, 0,174, 0, 0, 0,135, 0, 0, 0,133, + 0, 0, 0,172, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 0,132, 0, 0, 0,171, 0, 0, 0,169, 0, 0, 0, 3, 0, 0, 0,172, + 0, 0, 0,133, 0, 0, 0,131, 0, 0, 0,170, 0, 0, 0, 3, 0, 0, 0,165, 0, 0, 0,186, 0, 0, 0,184, 0, 0, 0,167, + 0, 0, 0, 3, 0, 0, 0,185, 0, 0, 0,187, 0, 0, 0,166, 0, 0, 0,168, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 0,169, + 0, 0, 0,167, 0, 0, 0,184, 0, 0, 0, 3, 0, 0, 0,168, 0, 0, 0,170, 0, 0, 0,131, 0, 0, 0,185, 0, 0, 0, 3, + 0, 0, 0,143, 0, 0, 0,189, 0, 0, 0,188, 0, 0, 0,186, 0, 0, 0, 3, 0, 0, 0,188, 0, 0, 0,189, 0, 0, 0,144, + 0, 0, 0,187, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0,186, 0, 0, 0,188, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0,188, + 0, 0, 0,187, 0, 0, 0,185, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0,129, 0, 0, 0,130, 0, 0, 0,184, 0, 0, 0, 68, + 0, 0, 0, 3, 0, 0, 0,185, 0, 0, 0,131, 0, 0, 0,129, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 0,192, + 0, 0, 0,190, 0, 0, 0,143, 0, 0, 0, 3, 0, 0, 0,191, 0, 0, 0,193, 0, 0, 0,142, 0, 0, 0,144, 0, 0, 0, 3, + 0, 0, 0,139, 0, 0, 0,194, 0, 0, 0,192, 0, 0, 0,141, 0, 0, 0, 3, 0, 0, 0,193, 0, 0, 0,195, 0, 0, 0,140, + 0, 0, 0,142, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 0,196, 0, 0, 0,194, 0, 0, 0,139, 0, 0, 0, 3, 0, 0, 0,195, + 0, 0, 0,197, 0, 0, 0,138, 0, 0, 0,140, 0, 0, 0, 3, 0, 0, 0,137, 0, 0, 0, 70, 0, 0, 0,196, 0, 0, 0,138, + 0, 0, 0, 3, 0, 0, 0,197, 0, 0, 0, 70, 0, 0, 0,137, 0, 0, 0,138, 0, 0, 0, 3, 0, 0, 0,189, 0, 0, 0,143, + 0, 0, 0,190, 0, 0, 0, 69, 0, 0, 0, 3, 0, 0, 0,191, 0, 0, 0,144, 0, 0, 0,189, 0, 0, 0, 69, 0, 0, 0, 3, + 0, 0, 0, 69, 0, 0, 0,190, 0, 0, 0,205, 0, 0, 0,207, 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 0,191, 0, 0, 0, 69, + 0, 0, 0,207, 0, 0, 0, 3, 0, 0, 0, 70, 0, 0, 0,198, 0, 0, 0,199, 0, 0, 0,196, 0, 0, 0, 3, 0, 0, 0,200, + 0, 0, 0,198, 0, 0, 0, 70, 0, 0, 0,197, 0, 0, 0, 3, 0, 0, 0,196, 0, 0, 0,199, 0, 0, 0,201, 0, 0, 0,194, + 0, 0, 0, 3, 0, 0, 0,202, 0, 0, 0,200, 0, 0, 0,197, 0, 0, 0,195, 0, 0, 0, 3, 0, 0, 0,194, 0, 0, 0,201, + 0, 0, 0,203, 0, 0, 0,192, 0, 0, 0, 3, 0, 0, 0,204, 0, 0, 0,202, 0, 0, 0,195, 0, 0, 0,193, 0, 0, 0, 3, + 0, 0, 0,192, 0, 0, 0,203, 0, 0, 0,205, 0, 0, 0,190, 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 0,204, 0, 0, 0,193, + 0, 0, 0,191, 0, 0, 0, 3, 0, 0, 0,198, 0, 0, 0,203, 0, 0, 0,201, 0, 0, 0,199, 0, 0, 0, 3, 0, 0, 0,202, + 0, 0, 0,204, 0, 0, 0,198, 0, 0, 0,200, 0, 0, 0, 3, 0, 0, 0,198, 0, 0, 0,207, 0, 0, 0,205, 0, 0, 0,203, + 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 0,207, 0, 0, 0,198, 0, 0, 0,204, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 0,139, + 0, 0, 0,163, 0, 0, 0,176, 0, 0, 0, 3, 0, 0, 0,164, 0, 0, 0,140, 0, 0, 0,138, 0, 0, 0,176, 0, 0, 0, 3, + 0, 0, 0,139, 0, 0, 0,141, 0, 0, 0,210, 0, 0, 0,163, 0, 0, 0, 3, 0, 0, 0,211, 0, 0, 0,142, 0, 0, 0,140, + 0, 0, 0,164, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 0,143, 0, 0, 0,212, 0, 0, 0,210, 0, 0, 0, 3, 0, 0, 0,213, + 0, 0, 0,144, 0, 0, 0,142, 0, 0, 0,211, 0, 0, 0, 3, 0, 0, 0,143, 0, 0, 0,186, 0, 0, 0,165, 0, 0, 0,212, + 0, 0, 0, 3, 0, 0, 0,166, 0, 0, 0,187, 0, 0, 0,144, 0, 0, 0,213, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 0,208, + 0, 0, 0,212, 0, 0, 0,165, 0, 0, 0, 3, 0, 0, 0,213, 0, 0, 0,209, 0, 0, 0, 81, 0, 0, 0,166, 0, 0, 0, 3, + 0, 0, 0,208, 0, 0, 0,214, 0, 0, 0,210, 0, 0, 0,212, 0, 0, 0, 3, 0, 0, 0,211, 0, 0, 0,215, 0, 0, 0,209, + 0, 0, 0,213, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 0,163, 0, 0, 0,210, 0, 0, 0,214, 0, 0, 0, 3, 0, 0, 0,211, + 0, 0, 0,164, 0, 0, 0, 79, 0, 0, 0,215, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 0,129, 0, 0, 0, 71, 0, 0, 0,221, + 0, 0, 0, 3, 0, 0, 0, 71, 0, 0, 0,129, 0, 0, 0,131, 0, 0, 0,222, 0, 0, 0, 3, 0, 0, 0,132, 0, 0, 0,130, + 0, 0, 0,221, 0, 0, 0,219, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 0,131, 0, 0, 0,133, 0, 0, 0,220, 0, 0, 0, 3, + 0, 0, 0,134, 0, 0, 0,132, 0, 0, 0,219, 0, 0, 0,217, 0, 0, 0, 3, 0, 0, 0,220, 0, 0, 0,133, 0, 0, 0,135, + 0, 0, 0,218, 0, 0, 0, 3, 0, 0, 0,136, 0, 0, 0,134, 0, 0, 0,217, 0, 0, 0,216, 0, 0, 0, 3, 0, 0, 0,218, + 0, 0, 0,135, 0, 0, 0,136, 0, 0, 0,216, 0, 0, 0, 3, 0, 0, 0,216, 0, 0, 0,217, 0, 0, 0,228, 0, 0, 0,230, + 0, 0, 0, 3, 0, 0, 0,229, 0, 0, 0,218, 0, 0, 0,216, 0, 0, 0,230, 0, 0, 0, 3, 0, 0, 0,217, 0, 0, 0,219, + 0, 0, 0,226, 0, 0, 0,228, 0, 0, 0, 3, 0, 0, 0,227, 0, 0, 0,220, 0, 0, 0,218, 0, 0, 0,229, 0, 0, 0, 3, + 0, 0, 0,219, 0, 0, 0,221, 0, 0, 0,224, 0, 0, 0,226, 0, 0, 0, 3, 0, 0, 0,225, 0, 0, 0,222, 0, 0, 0,220, + 0, 0, 0,227, 0, 0, 0, 3, 0, 0, 0,221, 0, 0, 0, 71, 0, 0, 0,223, 0, 0, 0,224, 0, 0, 0, 3, 0, 0, 0,223, + 0, 0, 0, 71, 0, 0, 0,222, 0, 0, 0,225, 0, 0, 0, 3, 0, 0, 0,223, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,224, + 0, 0, 0, 3, 0, 0, 0,229, 0, 0, 0,230, 0, 0, 0,223, 0, 0, 0,225, 0, 0, 0, 3, 0, 0, 0,224, 0, 0, 0,228, + 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,227, 0, 0, 0,229, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,182, 0, 0, 0,180, 0, 0, 0,233, 0, 0, 0,231, 0, 0, 0, 3, 0, 0, 0,234, 0, 0, 0,181, 0, 0, 0,183, + 0, 0, 0,232, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 0,182, 0, 0, 0,231, 0, 0, 0,253, 0, 0, 0, 3, 0, 0, 0,232, + 0, 0, 0,183, 0, 0, 0,112, 0, 0, 0,254, 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 0,111, 0, 0, 0,253, 0, 0, 0,255, + 0, 0, 0, 3, 0, 0, 0,254, 0, 0, 0,112, 0, 0, 0,110, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0,180, 0, 0, 0,113, + 0, 0, 0,251, 0, 0, 0,233, 0, 0, 0, 3, 0, 0, 0,252, 0, 0, 0,114, 0, 0, 0,181, 0, 0, 0,234, 0, 0, 0, 3, + 0, 0, 0,113, 0, 0, 0,115, 0, 0, 0,249, 0, 0, 0,251, 0, 0, 0, 3, 0, 0, 0,250, 0, 0, 0,116, 0, 0, 0,114, + 0, 0, 0,252, 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 0,117, 0, 0, 0,247, 0, 0, 0,249, 0, 0, 0, 3, 0, 0, 0,248, + 0, 0, 0,118, 0, 0, 0,116, 0, 0, 0,250, 0, 0, 0, 3, 0, 0, 0,117, 0, 0, 0,119, 0, 0, 0,245, 0, 0, 0,247, + 0, 0, 0, 3, 0, 0, 0,246, 0, 0, 0,120, 0, 0, 0,118, 0, 0, 0,248, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 0,121, + 0, 0, 0,243, 0, 0, 0,245, 0, 0, 0, 3, 0, 0, 0,244, 0, 0, 0,122, 0, 0, 0,120, 0, 0, 0,246, 0, 0, 0, 3, + 0, 0, 0,121, 0, 0, 0,123, 0, 0, 0,241, 0, 0, 0,243, 0, 0, 0, 3, 0, 0, 0,242, 0, 0, 0,124, 0, 0, 0,122, + 0, 0, 0,244, 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 0,125, 0, 0, 0,239, 0, 0, 0,241, 0, 0, 0, 3, 0, 0, 0,240, + 0, 0, 0,126, 0, 0, 0,124, 0, 0, 0,242, 0, 0, 0, 3, 0, 0, 0,125, 0, 0, 0,178, 0, 0, 0,235, 0, 0, 0,239, + 0, 0, 0, 3, 0, 0, 0,236, 0, 0, 0,179, 0, 0, 0,126, 0, 0, 0,240, 0, 0, 0, 3, 0, 0, 0,178, 0, 0, 0,127, + 0, 0, 0,237, 0, 0, 0,235, 0, 0, 0, 3, 0, 0, 0,238, 0, 0, 0,128, 0, 0, 0,179, 0, 0, 0,236, 0, 0, 0, 3, + 0, 0, 0,127, 0, 0, 0,109, 0, 0, 0,255, 0, 0, 0,237, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0,110, 0, 0, 0,128, + 0, 0, 0,238, 0, 0, 0, 3, 0, 0, 0,237, 0, 0, 0,255, 0, 0, 1, 1, 0, 0, 1, 19, 0, 0, 0, 3, 0, 0, 1, 2, + 0, 0, 1, 0, 0, 0, 0,238, 0, 0, 1, 20, 0, 0, 0, 3, 0, 0, 0,235, 0, 0, 0,237, 0, 0, 1, 19, 0, 0, 1, 21, + 0, 0, 0, 3, 0, 0, 1, 20, 0, 0, 0,238, 0, 0, 0,236, 0, 0, 1, 22, 0, 0, 0, 3, 0, 0, 0,239, 0, 0, 0,235, + 0, 0, 1, 21, 0, 0, 1, 17, 0, 0, 0, 3, 0, 0, 1, 22, 0, 0, 0,236, 0, 0, 0,240, 0, 0, 1, 18, 0, 0, 0, 3, + 0, 0, 0,241, 0, 0, 0,239, 0, 0, 1, 17, 0, 0, 1, 15, 0, 0, 0, 3, 0, 0, 1, 18, 0, 0, 0,240, 0, 0, 0,242, + 0, 0, 1, 16, 0, 0, 0, 3, 0, 0, 0,243, 0, 0, 0,241, 0, 0, 1, 15, 0, 0, 1, 13, 0, 0, 0, 3, 0, 0, 1, 16, + 0, 0, 0,242, 0, 0, 0,244, 0, 0, 1, 14, 0, 0, 0, 3, 0, 0, 0,245, 0, 0, 0,243, 0, 0, 1, 13, 0, 0, 1, 11, + 0, 0, 0, 3, 0, 0, 1, 14, 0, 0, 0,244, 0, 0, 0,246, 0, 0, 1, 12, 0, 0, 0, 3, 0, 0, 0,247, 0, 0, 0,245, + 0, 0, 1, 11, 0, 0, 1, 9, 0, 0, 0, 3, 0, 0, 1, 12, 0, 0, 0,246, 0, 0, 0,248, 0, 0, 1, 10, 0, 0, 0, 3, + 0, 0, 0,249, 0, 0, 0,247, 0, 0, 1, 9, 0, 0, 1, 7, 0, 0, 0, 3, 0, 0, 1, 10, 0, 0, 0,248, 0, 0, 0,250, + 0, 0, 1, 8, 0, 0, 0, 3, 0, 0, 0,251, 0, 0, 0,249, 0, 0, 1, 7, 0, 0, 1, 5, 0, 0, 0, 3, 0, 0, 1, 8, + 0, 0, 0,250, 0, 0, 0,252, 0, 0, 1, 6, 0, 0, 0, 3, 0, 0, 0,233, 0, 0, 0,251, 0, 0, 1, 5, 0, 0, 1, 23, + 0, 0, 0, 3, 0, 0, 1, 6, 0, 0, 0,252, 0, 0, 0,234, 0, 0, 1, 24, 0, 0, 0, 3, 0, 0, 0,255, 0, 0, 0,253, + 0, 0, 1, 3, 0, 0, 1, 1, 0, 0, 0, 3, 0, 0, 1, 4, 0, 0, 0,254, 0, 0, 1, 0, 0, 0, 1, 2, 0, 0, 0, 3, + 0, 0, 0,253, 0, 0, 0,231, 0, 0, 1, 25, 0, 0, 1, 3, 0, 0, 0, 3, 0, 0, 1, 26, 0, 0, 0,232, 0, 0, 0,254, + 0, 0, 1, 4, 0, 0, 0, 3, 0, 0, 0,231, 0, 0, 0,233, 0, 0, 1, 23, 0, 0, 1, 25, 0, 0, 0, 3, 0, 0, 1, 24, + 0, 0, 0,234, 0, 0, 0,232, 0, 0, 1, 26, 0, 0, 0, 3, 0, 0, 0, 66, 0, 0, 0,107, 0, 0, 1, 27, 0, 0, 0, 72, + 0, 0, 0, 3, 0, 0, 1, 28, 0, 0, 0,108, 0, 0, 0, 66, 0, 0, 0, 72, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 0,105, + 0, 0, 1, 29, 0, 0, 1, 27, 0, 0, 0, 3, 0, 0, 1, 30, 0, 0, 0,106, 0, 0, 0,108, 0, 0, 1, 28, 0, 0, 0, 3, + 0, 0, 0,105, 0, 0, 0,103, 0, 0, 1, 31, 0, 0, 1, 29, 0, 0, 0, 3, 0, 0, 1, 32, 0, 0, 0,104, 0, 0, 0,106, + 0, 0, 1, 30, 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 0,101, 0, 0, 1, 33, 0, 0, 1, 31, 0, 0, 0, 3, 0, 0, 1, 34, + 0, 0, 0,102, 0, 0, 0,104, 0, 0, 1, 32, 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 0, 99, 0, 0, 1, 35, 0, 0, 1, 33, + 0, 0, 0, 3, 0, 0, 1, 36, 0, 0, 0,100, 0, 0, 0,102, 0, 0, 1, 34, 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 0, 97, + 0, 0, 1, 37, 0, 0, 1, 35, 0, 0, 0, 3, 0, 0, 1, 38, 0, 0, 0, 98, 0, 0, 0,100, 0, 0, 1, 36, 0, 0, 0, 3, + 0, 0, 0, 97, 0, 0, 0, 95, 0, 0, 1, 39, 0, 0, 1, 37, 0, 0, 0, 3, 0, 0, 1, 40, 0, 0, 0, 96, 0, 0, 0, 98, + 0, 0, 1, 38, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 0, 93, 0, 0, 1, 41, 0, 0, 1, 39, 0, 0, 0, 3, 0, 0, 1, 42, + 0, 0, 0, 94, 0, 0, 0, 96, 0, 0, 1, 40, 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 0, 91, 0, 0, 1, 43, 0, 0, 1, 41, + 0, 0, 0, 3, 0, 0, 1, 44, 0, 0, 0, 92, 0, 0, 0, 94, 0, 0, 1, 42, 0, 0, 0, 3, 0, 0, 1, 51, 0, 0, 1, 52, + 0, 0, 1, 71, 0, 0, 1, 81, 0, 0, 0, 3, 0, 0, 1, 72, 0, 0, 1, 52, 0, 0, 1, 51, 0, 0, 1, 82, 0, 0, 0, 3, + 0, 0, 1, 50, 0, 0, 1, 51, 0, 0, 1, 81, 0, 0, 1, 79, 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 1, 51, 0, 0, 1, 50, + 0, 0, 1, 80, 0, 0, 0, 3, 0, 0, 1, 49, 0, 0, 1, 50, 0, 0, 1, 79, 0, 0, 1, 83, 0, 0, 0, 3, 0, 0, 1, 80, + 0, 0, 1, 50, 0, 0, 1, 49, 0, 0, 1, 84, 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 0, 90, 0, 0, 1, 49, 0, 0, 1, 83, + 0, 0, 0, 3, 0, 0, 1, 49, 0, 0, 0, 90, 0, 0, 0, 89, 0, 0, 1, 84, 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 0, 88, + 0, 0, 1, 83, 0, 0, 1, 77, 0, 0, 0, 3, 0, 0, 1, 84, 0, 0, 0, 89, 0, 0, 0, 87, 0, 0, 1, 78, 0, 0, 0, 3, + 0, 0, 0, 84, 0, 0, 0, 86, 0, 0, 1, 77, 0, 0, 1, 73, 0, 0, 0, 3, 0, 0, 1, 78, 0, 0, 0, 87, 0, 0, 0, 85, + 0, 0, 1, 74, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0, 84, 0, 0, 1, 73, 0, 0, 1, 75, 0, 0, 0, 3, 0, 0, 1, 74, + 0, 0, 0, 85, 0, 0, 0, 83, 0, 0, 1, 76, 0, 0, 0, 3, 0, 0, 1, 73, 0, 0, 1, 79, 0, 0, 1, 81, 0, 0, 1, 75, + 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 1, 80, 0, 0, 1, 74, 0, 0, 1, 76, 0, 0, 0, 3, 0, 0, 1, 73, 0, 0, 1, 77, + 0, 0, 1, 83, 0, 0, 1, 79, 0, 0, 0, 3, 0, 0, 1, 84, 0, 0, 1, 78, 0, 0, 1, 74, 0, 0, 1, 80, 0, 0, 0, 3, + 0, 0, 1, 69, 0, 0, 1, 75, 0, 0, 1, 81, 0, 0, 1, 71, 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 1, 76, 0, 0, 1, 70, + 0, 0, 1, 72, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 0, 82, 0, 0, 1, 75, 0, 0, 1, 69, 0, 0, 0, 3, 0, 0, 1, 76, + 0, 0, 0, 83, 0, 0, 0, 81, 0, 0, 1, 70, 0, 0, 0, 3, 0, 0, 0,208, 0, 0, 1, 85, 0, 0, 1, 87, 0, 0, 0,214, + 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 1, 86, 0, 0, 0,209, 0, 0, 0,215, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 1, 69, + 0, 0, 1, 85, 0, 0, 0,208, 0, 0, 0, 3, 0, 0, 1, 86, 0, 0, 1, 70, 0, 0, 0, 81, 0, 0, 0,209, 0, 0, 0, 3, + 0, 0, 0, 78, 0, 0, 0,214, 0, 0, 1, 87, 0, 0, 1, 89, 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 0,215, 0, 0, 0, 79, + 0, 0, 1, 90, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 1, 89, 0, 0, 1, 43, 0, 0, 0, 91, 0, 0, 0, 3, 0, 0, 1, 44, + 0, 0, 1, 90, 0, 0, 0, 79, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 1, 67, 0, 0, 1, 95, 0, 0, 1, 47, + 0, 0, 0, 3, 0, 0, 1, 96, 0, 0, 1, 68, 0, 0, 0, 76, 0, 0, 1, 47, 0, 0, 0, 3, 0, 0, 1, 47, 0, 0, 1, 95, + 0, 0, 1, 93, 0, 0, 0, 77, 0, 0, 0, 3, 0, 0, 1, 94, 0, 0, 1, 96, 0, 0, 1, 47, 0, 0, 0, 77, 0, 0, 0, 3, + 0, 0, 0, 77, 0, 0, 1, 93, 0, 0, 1, 91, 0, 0, 1, 48, 0, 0, 0, 3, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 77, + 0, 0, 1, 48, 0, 0, 0, 3, 0, 0, 1, 48, 0, 0, 1, 91, 0, 0, 1, 71, 0, 0, 1, 52, 0, 0, 0, 3, 0, 0, 1, 72, + 0, 0, 1, 92, 0, 0, 1, 48, 0, 0, 1, 52, 0, 0, 0, 3, 0, 0, 1, 69, 0, 0, 1, 71, 0, 0, 1, 91, 0, 0, 1, 85, + 0, 0, 0, 3, 0, 0, 1, 92, 0, 0, 1, 72, 0, 0, 1, 70, 0, 0, 1, 86, 0, 0, 0, 3, 0, 0, 1, 39, 0, 0, 1, 41, + 0, 0, 1, 61, 0, 0, 1, 53, 0, 0, 0, 3, 0, 0, 1, 62, 0, 0, 1, 42, 0, 0, 1, 40, 0, 0, 1, 54, 0, 0, 0, 3, + 0, 0, 0, 75, 0, 0, 1, 59, 0, 0, 1, 67, 0, 0, 0, 76, 0, 0, 0, 3, 0, 0, 1, 68, 0, 0, 1, 60, 0, 0, 0, 75, + 0, 0, 0, 76, 0, 0, 0, 3, 0, 0, 1, 45, 0, 0, 1,101, 0, 0, 1, 99, 0, 0, 1, 46, 0, 0, 0, 3, 0, 0, 1,100, + 0, 0, 1,102, 0, 0, 1, 45, 0, 0, 1, 46, 0, 0, 0, 3, 0, 0, 1, 46, 0, 0, 1, 99, 0, 0, 1, 97, 0, 0, 0, 74, + 0, 0, 0, 3, 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 1, 46, 0, 0, 0, 74, 0, 0, 0, 3, 0, 0, 0, 74, 0, 0, 1, 97, + 0, 0, 1, 59, 0, 0, 0, 75, 0, 0, 0, 3, 0, 0, 1, 60, 0, 0, 1, 98, 0, 0, 0, 74, 0, 0, 0, 75, 0, 0, 0, 3, + 0, 0, 1, 35, 0, 0, 1, 37, 0, 0, 1,105, 0, 0, 1,107, 0, 0, 0, 3, 0, 0, 1,106, 0, 0, 1, 38, 0, 0, 1, 36, + 0, 0, 1,108, 0, 0, 0, 3, 0, 0, 1,107, 0, 0, 1,105, 0, 0, 1,111, 0, 0, 1,109, 0, 0, 0, 3, 0, 0, 1,112, + 0, 0, 1,106, 0, 0, 1,108, 0, 0, 1,110, 0, 0, 0, 3, 0, 0, 1,109, 0, 0, 1,111, 0, 0, 1,113, 0, 0, 1,115, + 0, 0, 0, 3, 0, 0, 1,114, 0, 0, 1,112, 0, 0, 1,110, 0, 0, 1,116, 0, 0, 0, 3, 0, 0, 1,115, 0, 0, 1,113, + 0, 0, 1,119, 0, 0, 1,117, 0, 0, 0, 3, 0, 0, 1,120, 0, 0, 1,114, 0, 0, 1,116, 0, 0, 1,118, 0, 0, 0, 3, + 0, 0, 1, 57, 0, 0, 1,121, 0, 0, 1,117, 0, 0, 1,119, 0, 0, 0, 3, 0, 0, 1,118, 0, 0, 1,122, 0, 0, 1, 58, + 0, 0, 1,120, 0, 0, 0, 3, 0, 0, 1, 59, 0, 0, 1, 97, 0, 0, 1,117, 0, 0, 1,121, 0, 0, 0, 3, 0, 0, 1,118, + 0, 0, 1, 98, 0, 0, 1, 60, 0, 0, 1,122, 0, 0, 0, 3, 0, 0, 1, 97, 0, 0, 1, 99, 0, 0, 1,115, 0, 0, 1,117, + 0, 0, 0, 3, 0, 0, 1,116, 0, 0, 1,100, 0, 0, 1, 98, 0, 0, 1,118, 0, 0, 0, 3, 0, 0, 1, 99, 0, 0, 1,101, + 0, 0, 1,109, 0, 0, 1,115, 0, 0, 0, 3, 0, 0, 1,110, 0, 0, 1,102, 0, 0, 1,100, 0, 0, 1,116, 0, 0, 0, 3, + 0, 0, 1,101, 0, 0, 1,103, 0, 0, 1,107, 0, 0, 1,109, 0, 0, 0, 3, 0, 0, 1,108, 0, 0, 1,104, 0, 0, 1,102, + 0, 0, 1,110, 0, 0, 0, 3, 0, 0, 1, 33, 0, 0, 1, 35, 0, 0, 1,107, 0, 0, 1,103, 0, 0, 0, 3, 0, 0, 1,108, + 0, 0, 1, 36, 0, 0, 1, 34, 0, 0, 1,104, 0, 0, 0, 3, 0, 0, 0, 73, 0, 0, 1,103, 0, 0, 1,101, 0, 0, 1, 45, + 0, 0, 0, 3, 0, 0, 1,102, 0, 0, 1,104, 0, 0, 0, 73, 0, 0, 1, 45, 0, 0, 0, 3, 0, 0, 1, 27, 0, 0, 1, 29, + 0, 0, 1, 31, 0, 0, 1, 33, 0, 0, 0, 3, 0, 0, 1, 32, 0, 0, 1, 30, 0, 0, 1, 28, 0, 0, 1, 34, 0, 0, 0, 3, + 0, 0, 1, 27, 0, 0, 1, 33, 0, 0, 1,103, 0, 0, 0, 73, 0, 0, 0, 3, 0, 0, 1,104, 0, 0, 1, 34, 0, 0, 1, 28, + 0, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 1, 27, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 73, + 0, 0, 1, 28, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 37, 0, 0, 1, 39, 0, 0, 1, 53, 0, 0, 1,105, + 0, 0, 0, 3, 0, 0, 1, 54, 0, 0, 1, 40, 0, 0, 1, 38, 0, 0, 1,106, 0, 0, 0, 3, 0, 0, 1, 53, 0, 0, 1, 55, + 0, 0, 1,111, 0, 0, 1,105, 0, 0, 0, 3, 0, 0, 1,112, 0, 0, 1, 56, 0, 0, 1, 54, 0, 0, 1,106, 0, 0, 0, 3, + 0, 0, 1, 55, 0, 0, 1,125, 0, 0, 1,113, 0, 0, 1,111, 0, 0, 0, 3, 0, 0, 1,114, 0, 0, 1,126, 0, 0, 1, 56, + 0, 0, 1,112, 0, 0, 0, 3, 0, 0, 1, 57, 0, 0, 1,119, 0, 0, 1,113, 0, 0, 1,125, 0, 0, 0, 3, 0, 0, 1,114, + 0, 0, 1,120, 0, 0, 1, 58, 0, 0, 1,126, 0, 0, 0, 3, 0, 0, 1, 91, 0, 0, 1, 93, 0, 0, 1,129, 0, 0, 1,127, + 0, 0, 0, 3, 0, 0, 1,130, 0, 0, 1, 94, 0, 0, 1, 92, 0, 0, 1,128, 0, 0, 0, 3, 0, 0, 1, 61, 0, 0, 1,127, + 0, 0, 1,129, 0, 0, 1, 63, 0, 0, 0, 3, 0, 0, 1,130, 0, 0, 1,128, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 0, 3, + 0, 0, 1, 41, 0, 0, 1, 43, 0, 0, 1,127, 0, 0, 1, 61, 0, 0, 0, 3, 0, 0, 1,128, 0, 0, 1, 44, 0, 0, 1, 42, + 0, 0, 1, 62, 0, 0, 0, 3, 0, 0, 1, 43, 0, 0, 1, 87, 0, 0, 1, 85, 0, 0, 1,127, 0, 0, 0, 3, 0, 0, 1, 86, + 0, 0, 1, 88, 0, 0, 1, 44, 0, 0, 1,128, 0, 0, 0, 3, 0, 0, 1, 85, 0, 0, 1, 91, 0, 0, 1,127, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,128, 0, 0, 1, 92, 0, 0, 1, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 43, 0, 0, 1, 89, + 0, 0, 1, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 1, 90, 0, 0, 1, 44, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 57, 0, 0, 1, 65, 0, 0, 1,123, 0, 0, 1,121, 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 1, 66, 0, 0, 1, 58, + 0, 0, 1,122, 0, 0, 0, 3, 0, 0, 1, 59, 0, 0, 1,121, 0, 0, 1,123, 0, 0, 1, 67, 0, 0, 0, 3, 0, 0, 1,124, + 0, 0, 1,122, 0, 0, 1, 60, 0, 0, 1, 68, 0, 0, 0, 3, 0, 0, 1, 63, 0, 0, 1,129, 0, 0, 1,123, 0, 0, 1, 65, + 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 1,130, 0, 0, 1, 64, 0, 0, 1, 66, 0, 0, 0, 3, 0, 0, 1, 93, 0, 0, 1, 95, + 0, 0, 1,123, 0, 0, 1,129, 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 1, 96, 0, 0, 1, 94, 0, 0, 1,130, 0, 0, 0, 3, + 0, 0, 1, 67, 0, 0, 1,123, 0, 0, 1, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 96, 0, 0, 1,124, 0, 0, 1, 68, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 1,131, 0, 0, 1,157, 0, 0, 1,145, 0, 0, 0, 3, 0, 0, 1,158, + 0, 0, 1,132, 0, 0, 1,144, 0, 0, 1,146, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 1,145, 0, 0, 1,147, 0, 0, 1,141, + 0, 0, 0, 3, 0, 0, 1,148, 0, 0, 1,146, 0, 0, 1,144, 0, 0, 1,142, 0, 0, 0, 3, 0, 0, 1,141, 0, 0, 1,147, + 0, 0, 1,149, 0, 0, 1,139, 0, 0, 0, 3, 0, 0, 1,150, 0, 0, 1,148, 0, 0, 1,142, 0, 0, 1,140, 0, 0, 0, 3, + 0, 0, 1,139, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 1,137, 0, 0, 0, 3, 0, 0, 1,152, 0, 0, 1,150, 0, 0, 1,140, + 0, 0, 1,138, 0, 0, 0, 3, 0, 0, 1,137, 0, 0, 1,151, 0, 0, 1,153, 0, 0, 1,135, 0, 0, 0, 3, 0, 0, 1,154, + 0, 0, 1,152, 0, 0, 1,138, 0, 0, 1,136, 0, 0, 0, 3, 0, 0, 1,135, 0, 0, 1,153, 0, 0, 1,155, 0, 0, 1,133, + 0, 0, 0, 3, 0, 0, 1,156, 0, 0, 1,154, 0, 0, 1,136, 0, 0, 1,134, 0, 0, 0, 3, 0, 0, 1,153, 0, 0, 1,163, + 0, 0, 1,161, 0, 0, 1,155, 0, 0, 0, 3, 0, 0, 1,162, 0, 0, 1,164, 0, 0, 1,154, 0, 0, 1,156, 0, 0, 0, 3, + 0, 0, 1,151, 0, 0, 1,165, 0, 0, 1,163, 0, 0, 1,153, 0, 0, 0, 3, 0, 0, 1,164, 0, 0, 1,166, 0, 0, 1,152, + 0, 0, 1,154, 0, 0, 0, 3, 0, 0, 1,149, 0, 0, 1,167, 0, 0, 1,165, 0, 0, 1,151, 0, 0, 0, 3, 0, 0, 1,166, + 0, 0, 1,168, 0, 0, 1,150, 0, 0, 1,152, 0, 0, 0, 3, 0, 0, 1,147, 0, 0, 1,169, 0, 0, 1,167, 0, 0, 1,149, + 0, 0, 0, 3, 0, 0, 1,168, 0, 0, 1,170, 0, 0, 1,148, 0, 0, 1,150, 0, 0, 0, 3, 0, 0, 1,145, 0, 0, 1,171, + 0, 0, 1,169, 0, 0, 1,147, 0, 0, 0, 3, 0, 0, 1,170, 0, 0, 1,172, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 0, 3, + 0, 0, 1,145, 0, 0, 1,157, 0, 0, 1,159, 0, 0, 1,171, 0, 0, 0, 3, 0, 0, 1,160, 0, 0, 1,158, 0, 0, 1,146, + 0, 0, 1,172, 0, 0, 0, 3, 0, 0, 1, 61, 0, 0, 1, 63, 0, 0, 1,187, 0, 0, 1,185, 0, 0, 0, 3, 0, 0, 1,188, + 0, 0, 1, 64, 0, 0, 1, 62, 0, 0, 1,186, 0, 0, 0, 3, 0, 0, 1, 63, 0, 0, 1,133, 0, 0, 1,155, 0, 0, 1,187, + 0, 0, 0, 3, 0, 0, 1,156, 0, 0, 1,134, 0, 0, 1, 64, 0, 0, 1,188, 0, 0, 0, 3, 0, 0, 1, 53, 0, 0, 1, 61, + 0, 0, 1,185, 0, 0, 1, 55, 0, 0, 0, 3, 0, 0, 1,186, 0, 0, 1, 62, 0, 0, 1, 54, 0, 0, 1, 56, 0, 0, 0, 3, + 0, 0, 1,125, 0, 0, 1,173, 0, 0, 1,157, 0, 0, 1,131, 0, 0, 0, 3, 0, 0, 1,158, 0, 0, 1,174, 0, 0, 1,126, + 0, 0, 1,132, 0, 0, 0, 3, 0, 0, 1,155, 0, 0, 1,161, 0, 0, 1,183, 0, 0, 1,187, 0, 0, 0, 3, 0, 0, 1,184, + 0, 0, 1,162, 0, 0, 1,156, 0, 0, 1,188, 0, 0, 0, 3, 0, 0, 1,181, 0, 0, 1,189, 0, 0, 1,187, 0, 0, 1,183, + 0, 0, 0, 3, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 1,182, 0, 0, 1,184, 0, 0, 0, 3, 0, 0, 1,177, 0, 0, 1,189, + 0, 0, 1,181, 0, 0, 1,179, 0, 0, 0, 3, 0, 0, 1,182, 0, 0, 1,190, 0, 0, 1,178, 0, 0, 1,180, 0, 0, 0, 3, + 0, 0, 1,175, 0, 0, 1,191, 0, 0, 1,189, 0, 0, 1,177, 0, 0, 0, 3, 0, 0, 1,190, 0, 0, 1,192, 0, 0, 1,176, + 0, 0, 1,178, 0, 0, 0, 3, 0, 0, 1,173, 0, 0, 1,191, 0, 0, 1,175, 0, 0, 1,193, 0, 0, 0, 3, 0, 0, 1,176, + 0, 0, 1,192, 0, 0, 1,174, 0, 0, 1,194, 0, 0, 0, 3, 0, 0, 1,157, 0, 0, 1,173, 0, 0, 1,193, 0, 0, 1,159, + 0, 0, 0, 3, 0, 0, 1,194, 0, 0, 1,174, 0, 0, 1,158, 0, 0, 1,160, 0, 0, 0, 3, 0, 0, 1, 55, 0, 0, 1,191, + 0, 0, 1,173, 0, 0, 1,125, 0, 0, 0, 3, 0, 0, 1,174, 0, 0, 1,192, 0, 0, 1, 56, 0, 0, 1,126, 0, 0, 0, 3, + 0, 0, 1, 55, 0, 0, 1,185, 0, 0, 1,189, 0, 0, 1,191, 0, 0, 0, 3, 0, 0, 1,190, 0, 0, 1,186, 0, 0, 1, 56, + 0, 0, 1,192, 0, 0, 0, 3, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 1,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,190, + 0, 0, 1,188, 0, 0, 1,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,159, 0, 0, 1,193, 0, 0, 1,195, 0, 0, 1,219, + 0, 0, 0, 3, 0, 0, 1,196, 0, 0, 1,194, 0, 0, 1,160, 0, 0, 1,220, 0, 0, 0, 3, 0, 0, 1,193, 0, 0, 1,175, + 0, 0, 1,205, 0, 0, 1,195, 0, 0, 0, 3, 0, 0, 1,206, 0, 0, 1,176, 0, 0, 1,194, 0, 0, 1,196, 0, 0, 0, 3, + 0, 0, 1,175, 0, 0, 1,177, 0, 0, 1,203, 0, 0, 1,205, 0, 0, 0, 3, 0, 0, 1,204, 0, 0, 1,178, 0, 0, 1,176, + 0, 0, 1,206, 0, 0, 0, 3, 0, 0, 1,177, 0, 0, 1,179, 0, 0, 1,201, 0, 0, 1,203, 0, 0, 0, 3, 0, 0, 1,202, + 0, 0, 1,180, 0, 0, 1,178, 0, 0, 1,204, 0, 0, 0, 3, 0, 0, 1,179, 0, 0, 1,181, 0, 0, 1,199, 0, 0, 1,201, + 0, 0, 0, 3, 0, 0, 1,200, 0, 0, 1,182, 0, 0, 1,180, 0, 0, 1,202, 0, 0, 0, 3, 0, 0, 1,181, 0, 0, 1,183, + 0, 0, 1,197, 0, 0, 1,199, 0, 0, 0, 3, 0, 0, 1,198, 0, 0, 1,184, 0, 0, 1,182, 0, 0, 1,200, 0, 0, 0, 3, + 0, 0, 1,183, 0, 0, 1,161, 0, 0, 1,217, 0, 0, 1,197, 0, 0, 0, 3, 0, 0, 1,218, 0, 0, 1,162, 0, 0, 1,184, + 0, 0, 1,198, 0, 0, 0, 3, 0, 0, 1,171, 0, 0, 1,159, 0, 0, 1,219, 0, 0, 1,207, 0, 0, 0, 3, 0, 0, 1,220, + 0, 0, 1,160, 0, 0, 1,172, 0, 0, 1,208, 0, 0, 0, 3, 0, 0, 1,169, 0, 0, 1,171, 0, 0, 1,207, 0, 0, 1,209, + 0, 0, 0, 3, 0, 0, 1,208, 0, 0, 1,172, 0, 0, 1,170, 0, 0, 1,210, 0, 0, 0, 3, 0, 0, 1,167, 0, 0, 1,169, + 0, 0, 1,209, 0, 0, 1,211, 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1,170, 0, 0, 1,168, 0, 0, 1,212, 0, 0, 0, 3, + 0, 0, 1,165, 0, 0, 1,167, 0, 0, 1,211, 0, 0, 1,213, 0, 0, 0, 3, 0, 0, 1,212, 0, 0, 1,168, 0, 0, 1,166, + 0, 0, 1,214, 0, 0, 0, 3, 0, 0, 1,163, 0, 0, 1,165, 0, 0, 1,213, 0, 0, 1,215, 0, 0, 0, 3, 0, 0, 1,214, + 0, 0, 1,166, 0, 0, 1,164, 0, 0, 1,216, 0, 0, 0, 3, 0, 0, 1,161, 0, 0, 1,163, 0, 0, 1,215, 0, 0, 1,217, + 0, 0, 0, 3, 0, 0, 1,216, 0, 0, 1,164, 0, 0, 1,162, 0, 0, 1,218, 0, 0, 0, 3, 0, 0, 1,201, 0, 0, 1,199, + 0, 0, 1,223, 0, 0, 1,221, 0, 0, 0, 3, 0, 0, 1,224, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 1,222, 0, 0, 0, 3, + 0, 0, 1,221, 0, 0, 1,223, 0, 0, 1,225, 0, 0, 1,227, 0, 0, 0, 3, 0, 0, 1,226, 0, 0, 1,224, 0, 0, 1,222, + 0, 0, 1,228, 0, 0, 0, 3, 0, 0, 1,227, 0, 0, 1,225, 0, 0, 1,231, 0, 0, 1,229, 0, 0, 0, 3, 0, 0, 1,232, + 0, 0, 1,226, 0, 0, 1,228, 0, 0, 1,230, 0, 0, 0, 3, 0, 0, 1,229, 0, 0, 1,231, 0, 0, 1,233, 0, 0, 1,235, + 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1,232, 0, 0, 1,230, 0, 0, 1,236, 0, 0, 0, 3, 0, 0, 1,207, 0, 0, 1,219, + 0, 0, 1,229, 0, 0, 1,235, 0, 0, 0, 3, 0, 0, 1,230, 0, 0, 1,220, 0, 0, 1,208, 0, 0, 1,236, 0, 0, 0, 3, + 0, 0, 1,195, 0, 0, 1,227, 0, 0, 1,229, 0, 0, 1,219, 0, 0, 0, 3, 0, 0, 1,230, 0, 0, 1,228, 0, 0, 1,196, + 0, 0, 1,220, 0, 0, 0, 3, 0, 0, 1,195, 0, 0, 1,205, 0, 0, 1,221, 0, 0, 1,227, 0, 0, 0, 3, 0, 0, 1,222, + 0, 0, 1,206, 0, 0, 1,196, 0, 0, 1,228, 0, 0, 0, 3, 0, 0, 1,201, 0, 0, 1,221, 0, 0, 1,205, 0, 0, 1,203, + 0, 0, 0, 3, 0, 0, 1,206, 0, 0, 1,222, 0, 0, 1,202, 0, 0, 1,204, 0, 0, 0, 3, 0, 0, 1,197, 0, 0, 1,217, + 0, 0, 1,223, 0, 0, 1,199, 0, 0, 0, 3, 0, 0, 1,224, 0, 0, 1,218, 0, 0, 1,198, 0, 0, 1,200, 0, 0, 0, 3, + 0, 0, 1,215, 0, 0, 1,225, 0, 0, 1,223, 0, 0, 1,217, 0, 0, 0, 3, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 1,216, + 0, 0, 1,218, 0, 0, 0, 3, 0, 0, 1,213, 0, 0, 1,231, 0, 0, 1,225, 0, 0, 1,215, 0, 0, 0, 3, 0, 0, 1,226, + 0, 0, 1,232, 0, 0, 1,214, 0, 0, 1,216, 0, 0, 0, 3, 0, 0, 1,211, 0, 0, 1,233, 0, 0, 1,231, 0, 0, 1,213, + 0, 0, 0, 3, 0, 0, 1,232, 0, 0, 1,234, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 3, 0, 0, 1,209, 0, 0, 1,235, + 0, 0, 1,233, 0, 0, 1,211, 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1,236, 0, 0, 1,210, 0, 0, 1,212, 0, 0, 0, 3, + 0, 0, 1,207, 0, 0, 1,235, 0, 0, 1,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1,236, 0, 0, 1,208, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,135, 0, 0, 1,133, 0, 0, 1,247, 0, 0, 1,245, 0, 0, 0, 3, 0, 0, 1,248, + 0, 0, 1,134, 0, 0, 1,136, 0, 0, 1,246, 0, 0, 0, 3, 0, 0, 1,137, 0, 0, 1,135, 0, 0, 1,245, 0, 0, 1,243, + 0, 0, 0, 3, 0, 0, 1,246, 0, 0, 1,136, 0, 0, 1,138, 0, 0, 1,244, 0, 0, 0, 3, 0, 0, 1,139, 0, 0, 1,137, + 0, 0, 1,243, 0, 0, 1,241, 0, 0, 0, 3, 0, 0, 1,244, 0, 0, 1,138, 0, 0, 1,140, 0, 0, 1,242, 0, 0, 0, 3, + 0, 0, 1,141, 0, 0, 1,139, 0, 0, 1,241, 0, 0, 1,239, 0, 0, 0, 3, 0, 0, 1,242, 0, 0, 1,140, 0, 0, 1,142, + 0, 0, 1,240, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 1,141, 0, 0, 1,239, 0, 0, 1,237, 0, 0, 0, 3, 0, 0, 1,240, + 0, 0, 1,142, 0, 0, 1,144, 0, 0, 1,238, 0, 0, 0, 3, 0, 0, 1,131, 0, 0, 1,143, 0, 0, 1,237, 0, 0, 1,249, + 0, 0, 0, 3, 0, 0, 1,238, 0, 0, 1,144, 0, 0, 1,132, 0, 0, 1,250, 0, 0, 0, 3, 0, 0, 1,237, 0, 0, 1,245, + 0, 0, 1,247, 0, 0, 1,249, 0, 0, 0, 3, 0, 0, 1,248, 0, 0, 1,246, 0, 0, 1,238, 0, 0, 1,250, 0, 0, 0, 3, + 0, 0, 1,237, 0, 0, 1,239, 0, 0, 1,243, 0, 0, 1,245, 0, 0, 0, 3, 0, 0, 1,244, 0, 0, 1,240, 0, 0, 1,238, + 0, 0, 1,246, 0, 0, 0, 3, 0, 0, 1,239, 0, 0, 1,241, 0, 0, 1,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,244, + 0, 0, 1,242, 0, 0, 1,240, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 57, 0, 0, 1,125, 0, 0, 1,131, 0, 0, 1,249, + 0, 0, 0, 3, 0, 0, 1,132, 0, 0, 1,126, 0, 0, 1, 58, 0, 0, 1,250, 0, 0, 0, 3, 0, 0, 1, 57, 0, 0, 1,249, + 0, 0, 1,247, 0, 0, 1, 65, 0, 0, 0, 3, 0, 0, 1,248, 0, 0, 1,250, 0, 0, 1, 58, 0, 0, 1, 66, 0, 0, 0, 3, + 0, 0, 1, 63, 0, 0, 1, 65, 0, 0, 1,247, 0, 0, 1,133, 0, 0, 0, 3, 0, 0, 1,248, 0, 0, 1, 66, 0, 0, 1, 64, + 0, 0, 1,134, 0, 0, 0, 3, 0, 0, 77, 69, 0, 0, 0,188, 3, 59,130,192, 0, 0, 0, 47, 0, 0, 0, 1, 3, 59,133,192, + 3, 59,129,208, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 67,117, 98,101, 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, 3, 56,212,208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 59,133, 64, 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,131,176, 3, 59,132,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, 8, 0, 0, 0, 12, 0, 0, 0, 4, 0, 0, 0, 1, + 51,128, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 4, 63,128, 0, 4, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 68, 65, 84, 65, 0, 0, 0,160, + 3, 59,131,176, 0, 0, 0, 52, 0, 0, 0, 8, 63,128, 0, 0, 63,127,255,255,191,128, 0, 0, 73,230, 73,230,182, 26, 2,255, + 63,128, 0, 0,191,128, 0, 0,191,128, 0, 0, 90,129, 0, 0,165,127, 2,255,191,128, 0, 1,191,127,255,253,191,128, 0, 0, +165,127, 0, 0,165,127, 2,255,191,127,255,250, 63,128, 0, 3,191,128, 0, 0,182, 26, 73,230,182, 26, 2,255, 63,128, 0, 4, + 63,127,255,247, 63,128, 0, 0, 90,129, 90,129, 0, 0, 3,255, 63,127,255,245,191,128, 0, 5, 63,128, 0, 0,127,255, 0, 0, + 0, 0, 0,255,191,128, 0, 3,191,127,255,250, 63,128, 0, 0,128, 1, 0, 0, 0, 0, 0,255,191,127,255,255, 63,128, 0, 0, + 63,128, 0, 0,165,127, 90,129, 0, 0, 3,255, 68, 65, 84, 65, 0, 0, 0,144, 3, 59,132,128, 0, 0, 0, 49, 0, 0, 0, 12, + 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 5, + 0, 0, 0, 6, 0, 0, 0,162, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 35, + 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 34, 0, 0, 0, 2, 0, 0, 0, 6, + 0, 0, 0, 34, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 34, 68, 65, 84, 65, 0, 0, 0, 80, 3, 59,133, 64, 0, 0, 0, 48, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 77, 69, 0, 0, 0,188, 3, 59,133,192, + 0, 0, 0, 47, 0, 0, 0, 1, 3, 59,134,176, 3, 59,130,192, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101, +119, 0, 0, 0, 0,112,104,101,114,101, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 56,214,160, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 54,175, 96, 7, 83,240, 32, 0, 0, 0, 0, 0, 0, 0, 0, 3,153,138, 32, + 7, 83,144, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,130, + 0, 0, 7,128, 0, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64,187, 89, 64, 64,187, 89, 64, + 64,187, 89, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, + 0, 1, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 3, 54,175, 96, 0, 0, 0, 0, 0, 0, 0, 1, 3, 59,124,192, 68, 65, 84, 65, + 0, 0, 50, 40, 3,153,138, 32, 0, 0, 0, 52, 0, 0, 2,130, 0, 0, 0, 0, 52,129,183,166,192,187, 89, 64, 0, 0, 0, 0, +128, 1, 3,255, 64,135,144,195,192, 68,252, 96,192, 39,145,252, 92,158,188,182,198,195, 3,255,191,207, 31, 22,192,159, 93,194, +192, 39,145,252,220,160,147, 31,198,194, 3,255,192,167,145,189, 51,232, 11,214,192, 39,145,251,141,133, 0, 0,198,195, 3,255, +191,207, 31, 22, 64,159, 93,194,192, 39,145,250,220,160,108,225,198,194, 3,255, 64,135,144,195, 64, 68,252, 96,192, 39,145,250, + 92,158, 67, 74,198,195, 3,255, 63,207, 31, 22,192,159, 93,194, 64, 39,145,250, 35, 96,147, 31, 57, 62, 3,255,192,135,144,195, +192, 68,252, 96, 64, 39,145,250,163, 98,188,182, 57, 61, 3,255,192,135,144,195, 64, 68,252, 96, 64, 39,145,252,163, 98, 67, 74, + 57, 61, 3,255, 63,207, 31, 22, 64,159, 93,194, 64, 39,145,252, 35, 96,108,225, 57, 62, 3,255, 64,167,145,189,179,232, 11,214, + 64, 39,145,251,114,123, 0, 0, 57, 61, 3,255, 0, 0, 0, 0,180,129,183,166, 64,187, 89, 64, 0, 0, 0, 0,127,255, 3,255, + 64, 31, 94, 5,191,231,146, 73,192,159, 94,112, 54,112,216,115,147, 31, 3,255,191,115,124,146,192, 59, 88,202,192,159, 94,114, +235, 53,192, 1,147, 31, 3,255, 63,196,254, 18,192,151,145, 54,192, 68,254, 20, 33,165,152,116,188,182, 3,255, 64, 31, 94, 5, + 63,231,146, 77,192,159, 94,112, 54,112, 39,141,147, 31, 3,255, 64,159, 94, 34, 52, 8,100,231,192, 68,253,230,108,225, 0, 0, +188,182, 3,255,192, 68,253, 80, 52, 92,176, 70,192,159, 94, 80,188,182, 0, 0,147, 31, 3,255,192,128,238,107,192, 59, 88,243, +192, 68,253,238,167,235,192, 1,188,182, 3,255,191,115,124,146, 64, 59, 88,205,192,159, 94,114,235, 53, 63,255,147, 31, 3,255, +192,128,238,107, 64, 59, 88,244,192, 68,253,238,167,235, 63,255,188,182, 3,255, 63,196,254, 21, 64,151,145, 54,192, 68,254, 17, + 33,165,103,140,188,182, 3,255, 64,178, 45,238, 63,231,146,136, 51,160, 86, 86,121,187, 39,141, 0, 0, 3,255, 64,178, 45,238, +191,231,146,136,179,160, 86, 86,121,187,216,115, 0, 0, 3,255, 64, 92, 61,222,192,151,145,116,180, 81,227, 20, 75, 59,152,115, + 0, 0, 3,255, 0, 0, 0, 0,192,187, 89, 64,180,129,183,166, 0, 0,128, 1, 0, 0, 3,255,192, 92, 61,222,192,151,145,116, +180, 81,227, 20,180,197,152,115, 0, 0, 3,255,192,178, 45,238,191,231,146,136,179,160, 86, 86,134, 69,216,115, 0, 0, 3,255, +192,178, 45,238, 63,231,146,136, 51,160, 86, 86,134, 69, 39,141, 0, 0, 3,255,192, 92, 61,222, 64,151,145,116, 52, 81,227, 20, +180,197,103,141, 0, 0, 3,255, 0, 0, 0, 0, 64,187, 89, 64, 52,129,183,166, 0, 0,127,255, 0, 0, 3,255, 64, 92, 61,222, + 64,151,145,116, 52, 81,227, 20, 75, 59,103,141, 0, 0, 3,255, 64,128,238,107,192, 59, 88,244, 64, 68,253,238, 88, 21,192, 1, + 67, 74, 3,255,191,196,254, 21,192,151,145, 54, 64, 68,254, 17,222, 91,152,116, 67, 74, 3,255,192,159, 94, 34,180, 8,100,231, + 64, 68,253,230,147, 31, 0, 0, 67, 74, 3,255,191,196,254, 18, 64,151,145, 54, 64, 68,254, 20,222, 91,103,140, 67, 74, 3,255, + 64,128,238,107, 64, 59, 88,243, 64, 68,253,238, 88, 21, 63,255, 67, 74, 3,255, 64, 68,253, 80,180, 92,176, 70, 64,159, 94, 80, + 67, 74, 0, 0,108,225, 3,255, 63,115,124,146,192, 59, 88,205, 64,159, 94,114, 20,203,192, 1,108,225, 3,255,192, 31, 94, 5, +191,231,146, 77, 64,159, 94,112,201,144,216,115,108,225, 3,255,192, 31, 94, 5, 63,231,146, 73, 64,159, 94,112,201,144, 39,141, +108,225, 3,255, 63,115,124,146, 64, 59, 88,202, 64,159, 94,114, 20,203, 63,255,108,225, 3,255, 63,165,172, 68,191,112,187,226, +192,180, 55,208, 27, 45,236, 66,132,126, 3,255, 64, 95,196,100,192, 34,147, 13,192,124,198,189, 77, 56,199,230,170,185, 3,255, +190,253, 30,222,191,194,194,112,192,180, 55,208,245,159,224, 14,132,126, 3,255,191,170,240,131,192,131,134,210,192,124,198,200, +226,130,165, 58,170,185, 3,255, 64, 64, 32,141,192,129,250, 84,192, 61,126,166, 66,214,167,244,191,123, 3,255,189, 40,121,238, +192,161,158,120,192, 61,126,170,253,175,145,123,191,123, 3,255, 63,165,172, 68, 63,112,187,235,192,180, 55,208, 27, 45, 19,190, +132,126, 3,255, 64, 95,196,100, 64, 34,147, 15,192,124,198,189, 77, 56, 56, 26,170,185, 3,255, 64,153, 77, 89,191,204,199,236, +192, 61,126,133,104,100,219,165,191,123, 3,255, 64,153, 77, 89, 63,204,199,238,192, 61,126,133,104,100, 36, 91,191,123, 3,255, +191,204,200,173, 52,121,143,111,192,180, 55,199,222,105, 0, 0,132,126, 3,255,192,138, 75,191, 52, 47, 4,116,192,124,198, 84, +160,142, 0, 0,170,184, 3,255,192, 59,220,246,192,131,134,225,192, 61,126,162,192,235,165, 58,191,123, 3,255,192,154, 29,197, +191,194,194,172,192, 61,126, 91,150, 45,224, 14,191,123, 3,255,190,253, 30,222, 63,194,194,116,192,180, 55,208,245,159, 31,242, +132,126, 3,255,191,170,240,131, 64,131,134,211,192,124,198,197,226,130, 90,198,170,185, 3,255,192,154, 29,197, 63,194,194,174, +192, 61,126, 91,150, 45, 31,242,191,123, 3,255,192, 59,220,246, 64,131,134,225,192, 61,126,160,192,235, 90,198,191,123, 3,255, +189, 40,121,203, 64,161,158,120,192, 61,126,168,253,175,110,133,191,123, 3,255, 64, 64, 32,144, 64,129,250, 84,192, 61,126,164, + 66,214, 88, 12,191,123, 3,255, 64,163, 20,153, 64, 34,147, 37,191,174, 51,154,110,207, 56, 26,225, 18, 3,255, 64,179,182,246, + 63,112,188, 61, 63,174, 51, 96,122,159, 19,190, 30,237, 3,255, 64,163, 20,153,192, 34,147, 37,191,174, 51,156,110,207,199,230, +225, 19, 3,255, 64,179,182,246,191,112,188, 63, 63,174, 51, 96,122,159,236, 66, 30,237, 3,255, 64,127,104,189,192,129,250,128, +191,174, 51,162, 87,153,167,244,225, 19, 3,255, 64, 40, 78,241,192,161,158,170, 63,174, 51,166, 56,171,145,123, 30,237, 3,255, +191, 87, 81,103,192,180, 55,196,191,174, 51,160,236,227,133, 71,225, 19, 3,255, 63, 87, 81,103,192,180, 55,196, 63,174, 51,154, + 19, 29,133, 71, 30,237, 3,255,192, 40, 78,241,192,161,158,170,191,174, 51,170,199, 85,145,123,225, 19, 3,255,192,127,104,189, +192,129,250,128, 63,174, 51,160,168,103,167,244, 30,237, 3,255,192,179,182,246,191,112,188, 61,191,174, 51, 96,133, 97,236, 66, +225, 19, 3,255,192,163, 20,153,192, 34,147, 37, 63,174, 51,154,145, 49,199,230, 30,238, 3,255,192,179,182,246, 63,112,188, 63, +191,174, 51, 96,133, 97, 19,190,225, 19, 3,255,192,163, 20,153, 64, 34,147, 37, 63,174, 51,156,145, 49, 56, 26, 30,237, 3,255, +192, 40, 78,241, 64,161,158,170,191,174, 51,166,199, 85,110,133,225, 19, 3,255,192,127,104,189, 64,129,250,128, 63,174, 51,162, +168,103, 88, 12, 30,237, 3,255,191, 87, 81,103, 64,180, 55,196,191,174, 51,154,236,227,122,185,225, 19, 3,255, 63, 87, 81,103, + 64,180, 55,196, 63,174, 51,160, 19, 29,122,185, 30,237, 3,255, 64,127,104,189, 64,129,250,128,191,174, 51,160, 87,153, 88, 12, +225, 19, 3,255, 64, 40, 78,241, 64,161,158,170, 63,174, 51,170, 56,171,110,133, 30,237, 3,255, 64, 59,220,246,192,131,134,225, + 64, 61,126,160, 63, 21,165, 58, 64,133, 3,255, 64,154, 29,197,191,194,194,174, 64, 61,126, 91,105,211,224, 14, 64,133, 3,255, + 61, 40,121,203,192,161,158,120, 64, 61,126,168, 2, 81,145,123, 64,133, 3,255,192, 64, 32,144,192,129,250, 84, 64, 61,126,164, +189, 42,167,244, 64,133, 3,255,192,153, 77, 89,191,204,199,238, 64, 61,126,133,151,156,219,165, 64,133, 3,255,192,153, 77, 89, + 63,204,199,236, 64, 61,126,133,151,156, 36, 91, 64,133, 3,255,192, 64, 32,141, 64,129,250, 84, 64, 61,126,166,189, 42, 88, 12, + 64,133, 3,255, 61, 40,121,238, 64,161,158,120, 64, 61,126,170, 2, 81,110,133, 64,133, 3,255, 64, 59,220,246, 64,131,134,225, + 64, 61,126,162, 63, 21, 90,198, 64,133, 3,255, 64,154, 29,197, 63,194,194,172, 64, 61,126, 91,105,211, 31,242, 64,133, 3,255, + 64,138, 75,191,180, 47, 4,116, 64,124,198, 84, 95,114, 0, 0, 85, 72, 3,255, 63,204,200,173,180,121,143,111, 64,180, 55,199, + 33,151, 0, 0,123,130, 3,255, 63,170,240,131,192,131,134,211, 64,124,198,197, 29,126,165, 58, 85, 71, 3,255, 62,253, 30,222, +191,194,194,116, 64,180, 55,208, 10, 97,224, 14,123,130, 3,255,192, 95,196,100,192, 34,147, 15, 64,124,198,189,178,200,199,230, + 85, 71, 3,255,191,165,172, 68,191,112,187,235, 64,180, 55,208,228,211,236, 66,123,130, 3,255,192, 95,196,100, 64, 34,147, 13, + 64,124,198,189,178,200, 56, 26, 85, 71, 3,255,191,165,172, 68, 63,112,187,226, 64,180, 55,208,228,211, 19,190,123,130, 3,255, + 63,170,240,131, 64,131,134,210, 64,124,198,200, 29,126, 90,198, 85, 71, 3,255, 62,253, 30,222, 63,194,194,112, 64,180, 55,208, + 10, 97, 31,242,123,130, 3,255, 64, 7,145, 25,192, 92, 61, 64,192,135,145, 82, 44,235,180,198,162,178, 3,255, 63, 79, 32,238, +192, 31, 93,182,192,167,145,250, 18, 29,200, 63,142, 56, 3,255, 62,158, 62, 68,192,128,238, 59,192,135,145, 83, 7,224,168,189, +162,178, 3,255, 64,123, 90,114,191,115,125, 12,192,135,145, 70, 85,109,236,135,162,178, 3,255, 64, 39,145,127, 52,104, 11,198, +192,167,145,240, 58,159, 0, 0,142, 56, 3,255, 64,123, 90,114, 63,115,125, 17,192,135,145, 70, 85,109, 19,121,162,178, 3,255, +192, 39,145,142,192, 68,253, 15,192,135,145, 80,198, 86,190, 9,162,178, 3,255,192, 7,144,204,191,196,252,242,192,167,145,242, +208,147,221,139,142, 56, 3,255,192,111, 33, 55,191,196,253, 22,192,135,145, 53,175,113,221,139,162,178, 3,255,192,111, 33, 55, + 63,196,253, 25,192,135,145, 53,175,113, 34,117,162,178, 3,255,192, 7,144,204, 63,196,252,247,192,167,145,242,208,147, 34,117, +142, 56, 3,255,192, 39,145,142, 64, 68,253, 17,192,135,145, 80,198, 86, 65,247,162,178, 3,255, 62,158, 62, 72, 64,128,238, 60, +192,135,145, 83, 7,224, 87, 67,162,178, 3,255, 63, 79, 32,238, 64, 31, 93,184,192,167,145,250, 18, 29, 55,193,142, 56, 3,255, + 64, 7,145, 25, 64, 92, 61, 64,192,135,145, 81, 44,235, 75, 58,162,178, 3,255, 64,177,117,134,191,115,125, 94,191,207, 33, 40, +121,168,236,135,221, 82, 3,255, 64,177,117,134, 63,115,125, 96,191,207, 33, 40,121,168, 19,121,221, 82, 3,255, 64,187, 89, 64, + 0, 0, 0, 0, 0, 0, 0, 0,127,252, 0, 0,254,116, 3,255, 63, 79, 33,102,192,178, 45,204,191,207, 33,104, 19, 18,134, 72, +221, 82, 3,255, 64, 39,146, 16,192,159, 94, 42,191,207, 33, 92, 56, 29,146, 81,221, 82, 3,255, 63,231,147,105,192,178, 45,219, +180,118,188,176, 39,140,134, 72,254,116, 3,255,192,161,117, 52,192, 31, 93,241,191,207, 33, 58,146, 34,200, 63,221, 82, 3,255, +192,123, 90,196,192,128,238,114,191,207, 33, 58,169, 6,168,189,221, 82, 3,255,192,151,145,138,192, 92, 61,163,180, 24,125,204, +152,117,180,198,254,116, 3,255,192,123, 90,196, 64,128,238,114,191,207, 33, 56,169, 6, 87, 67,221, 82, 3,255,192,161,117, 52, + 64, 31, 93,241,191,207, 33, 56,146, 34, 55,193,221, 82, 3,255,192,151,145,138, 64, 92, 61,163, 52, 24,125,204,152,117, 75, 58, +254,116, 3,255, 64, 39,146, 17, 64,159, 94, 42,191,207, 33, 90, 56, 29,109,175,221, 82, 3,255, 63, 79, 33,103, 64,178, 45,202, +191,207, 33, 99, 19, 18,121,184,221, 82, 3,255, 63,231,147,105, 64,178, 45,219, 52,118,188,176, 39,140,121,184,254,116, 3,255, + 64,161,117, 52,192, 31, 93,241, 63,207, 33, 56,109,222,200, 63, 34,174, 3,255, 64,151,145,138,192, 92, 61,163,180, 24,125,204, +103,139,180,198, 1,140, 3,255, 64,123, 90,196,192,128,238,114, 63,207, 33, 56, 86,250,168,189, 34,174, 3,255,191, 79, 33,103, +192,178, 45,202, 63,207, 33, 99,236,238,134, 72, 34,174, 3,255,191,231,147,105,192,178, 45,219,180,118,188,176,216,116,134, 72, + 1,140, 3,255,192, 39,146, 17,192,159, 94, 42, 63,207, 33, 90,199,227,146, 81, 34,174, 3,255,192,177,117,134,191,115,125, 96, + 63,207, 33, 40,134, 88,236,135, 34,174, 3,255,192,187, 89, 64, 0, 0, 0, 0, 0, 0, 0, 0,128, 4, 0, 0, 1,140, 3,255, +192,177,117,134, 63,115,125, 94, 63,207, 33, 40,134, 88, 19,121, 34,174, 3,255,192, 39,146, 16, 64,159, 94, 42, 63,207, 33, 92, +199,227,109,175, 34,174, 3,255,191,231,147,105, 64,178, 45,219, 52,118,188,176,216,116,121,184, 1,140, 3,255,191, 79, 33,102, + 64,178, 45,204, 63,207, 33,104,236,238,121,184, 34,174, 3,255, 64,123, 90,196, 64,128,238,114, 63,207, 33, 58, 86,250, 87, 67, + 34,174, 3,255, 64,151,145,138, 64, 92, 61,163, 52, 24,125,204,103,139, 75, 58, 1,140, 3,255, 64,161,117, 52, 64, 31, 93,241, + 63,207, 33, 58,109,222, 55,193, 34,174, 3,255, 64, 39,145,142,192, 68,253, 17, 64,135,145, 80, 57,170,190, 9, 93, 78, 3,255, + 64,111, 33, 55,191,196,253, 25, 64,135,145, 53, 80,143,221,139, 93, 78, 3,255, 64, 7,144,204,191,196,252,247, 64,167,145,242, + 47,109,221,139,113,200, 3,255,192, 7,145, 25,192, 92, 61, 64, 64,135,145, 81,211, 21,180,198, 93, 78, 3,255,190,158, 62, 76, +192,128,238, 60, 64,135,145, 83,248, 32,168,189, 93, 78, 3,255,191, 79, 32,238,192, 31, 93,184, 64,167,145,250,237,227,200, 63, +113,200, 3,255,192,123, 90,114, 63,115,125, 12, 64,135,145, 70,170,147, 19,121, 93, 78, 3,255,192,123, 90,114,191,115,125, 17, + 64,135,145, 70,170,147,236,135, 93, 78, 3,255,192, 39,145,127,180,104, 11,198, 64,167,145,240,197, 97, 0, 0,113,200, 3,255, +190,158, 62, 68, 64,128,238, 59, 64,135,145, 83,248, 32, 87, 67, 93, 78, 3,255,192, 7,145, 25, 64, 92, 61, 64, 64,135,145, 82, +211, 21, 75, 58, 93, 78, 3,255,191, 79, 32,238, 64, 31, 93,182, 64,167,145,250,237,227, 55,193,113,200, 3,255, 64,111, 33, 55, + 63,196,253, 22, 64,135,145, 53, 80,143, 34,117, 93, 78, 3,255, 64, 39,145,142, 64, 68,253, 15, 64,135,145, 80, 57,170, 65,247, + 93, 78, 3,255, 64, 7,144,204, 63,196,252,242, 64,167,145,242, 47,109, 34,117,113,200, 3,255, 63, 39, 66,179,190,243, 10, 91, +192,185,187,205, 13, 92,246, 76,129, 19, 3,255, 63,244,239,138,191,177,244, 56,192,171,199,156, 41, 94,225,242,138,170, 3,255, + 64,122, 24, 18,192, 53,179,169,192, 84, 91, 86, 85,223,193,157,184,120, 3,255, 64, 65,212,177,192, 12,211, 32,192,144,133,164, + 66,103,207,193,157,202, 3,255,190,127,139,187,191, 68,160, 51,192,185,187,205,250,230,240, 76,129, 19, 3,255,191, 59, 28, 68, +192, 15,248, 27,192,171,199,160,240, 52,207, 95,138,170, 3,255,191,191, 13, 15,192,147, 0, 76,192, 84, 91, 95,223, 52,155, 14, +184,121, 3,255,191,148, 18, 19,192, 99,220,112,192,144,133,165,230,163,177,240,157,202, 3,255, 64,106, 31, 84,192,102,219,243, +192, 52,105,160, 80,197,177,233,194,173, 3,255, 64, 19, 13,184,192,142,101,215,192, 67,124,168, 50,154,159, 32,189,101, 3,255, +191, 86,214,196,192,162, 49, 8,192, 52,105,161,236,143,145, 89,194,173, 3,255, 63, 65,187,181,192,158,107,124,192, 67,124,164, + 16, 0,147,226,189,101, 3,255, 63, 39, 66,179, 62,243, 10,108,192,185,187,205, 13, 92, 9,180,129, 19, 3,255, 63,244,239,138, + 63,177,244, 60,192,171,199,156, 41, 94, 30, 14,138,170, 3,255, 64,122, 24, 36, 64, 53,179,185,192, 84, 91, 93, 85,223, 62, 99, +184,120, 3,255, 64, 65,212,177, 64, 12,211, 34,192,144,133,164, 66,103, 48, 63,157,202, 3,255, 64,145,244,108,192, 23, 82, 63, +192, 52,105,140, 99, 58,203, 81,194,173, 3,255, 64,158, 38, 86,191, 79, 99,171,192, 67,124,124,107,198,237,208,189,101, 3,255, + 64,145,244,110, 64, 23, 82, 67,192, 52,105,139, 99, 58, 52,175,194,173, 3,255, 64,158, 38, 86, 63, 79, 99,175,192, 67,124,124, +107,198, 18, 48,189,101, 3,255,191, 78,191, 25, 52,126,127, 94,192,185,187,208,239,125, 0, 0,129, 19, 3,255,192, 23, 97, 18, + 52,107, 31,218,192,171,199,134,204,222, 0, 0,138,170, 3,255,192,154,145, 70, 52, 17,133, 48,192, 84, 91, 36,149,220, 0, 0, +184,120, 3,255,192,111,150,175, 52, 69,218, 93,192,144,133,120,173,235, 0, 0,157,202, 3,255,192, 19, 54,137,192,147, 0, 88, +192, 52,105,166,206,177,155, 14,194,173, 3,255,192, 97,106,126,192, 99,220,148,192, 67,124,143,179,129,177,240,189,101, 3,255, +192,162,141,165,191, 68,160,121,192, 52,105,115,144,194,240, 76,194,173, 3,255,192,143, 47, 14,192, 15,248, 68,192, 67,124,117, +158, 30,207, 95,189,101, 3,255,190,127,139,187, 63, 68,160, 59,192,185,187,205,250,230, 15,180,129, 19, 3,255,191, 59, 28, 68, + 64, 15,248, 30,192,171,199,160,240, 52, 48,161,138,170, 3,255,191,191, 13, 15, 64,147, 0, 76,192, 84, 91, 93,223, 52,100,242, +184,121, 3,255,191,148, 18, 19, 64, 99,220,115,192,144,133,164,230,163, 78, 16,157,202, 3,255,192,162,141,165, 63, 68,160,125, +192, 52,105,115,144,194, 15,180,194,173, 3,255,192,143, 47, 14, 64, 15,248, 70,192, 67,124,117,158, 30, 48,161,189,101, 3,255, +192, 19, 54,137, 64,147, 0, 88,192, 52,105,164,206,177,100,242,194,173, 3,255,192, 97,106,126, 64, 99,220,149,192, 67,124,142, +179,129, 78, 16,189,101, 3,255,191, 86,214,195, 64,162, 49, 8,192, 52,105,159,236,143,110,167,194,173, 3,255, 63, 65,187,185, + 64,158,107,124,192, 67,124,161, 16, 0,108, 30,189,101, 3,255, 64,106, 31, 90, 64,102,219,246,192, 52,105,157, 80,197, 78, 23, +194,173, 3,255, 64, 19, 13,186, 64,142,101,215,192, 67,124,165, 50,154, 96,224,189,101, 3,255, 64,150,228, 3, 64, 53,179,167, +192, 0,185,129,102, 97, 62, 99,211, 47, 3,255, 64,172,155, 50, 64, 12,211, 68,191, 48,107,191,117,138, 48, 63,240,135, 3,255, + 64,175,121,166, 62,243, 10,215, 64, 0,185,124,119,128, 9,180, 44,208, 3,255, 64,181, 7,115, 63,177,244,113, 63, 48,107, 94, +123,115, 30, 14, 15,121, 3,255, 64,150,228, 12,192, 53,179,179,192, 0,185,145,102, 97,193,157,211, 47, 3,255, 64,172,155, 50, +192, 12,211, 68,191, 48,107,193,117,138,207,193,240,135, 3,255, 64,175,121,166,190,243, 10,221, 64, 0,185,124,119,128,246, 76, + 44,208, 3,255, 64,181, 7,115,191,177,244,114, 63, 48,107, 94,123,115,225,242, 15,121, 3,255, 64,133, 8,140,192,102,220, 34, +192, 0,185,151, 90,249,177,233,211, 47, 3,255, 64,112,156,117,192,142,102, 25,191, 48,107,199, 82, 53,159, 32,240,135, 3,255, + 64, 9, 87,134,192,162, 49, 39, 64, 0,185,151, 46, 40,145, 89, 44,209, 3,255, 64, 68,129,119,192,158,107,189, 63, 48,107,200, + 66,187,147,225, 15,121, 3,255,191,159, 27,126,192,171,148,137,192, 0,185,149,228, 78,139, 90,211, 47, 3,255,190,218, 15,112, +192,185,234,179,191, 48,107,180,246,112,129, 78,240,135, 3,255, 63,159, 27,126,192,171,148,137, 64, 0,185,146, 27,178,139, 90, + 44,209, 3,255, 62,218, 15,112,192,185,234,179, 63, 48,107,170, 9,144,129, 78, 15,121, 3,255,192, 9, 87,134,192,162, 49, 39, +192, 0,185,153,209,216,145, 89,211, 47, 3,255,192, 68,129,119,192,158,107,189,191, 48,107,206,189, 69,147,225,240,135, 3,255, +192,133, 8,132,192,102,220, 22, 64, 0,185,135,165, 7,177,233, 44,209, 3,255,192,112,156,117,192,142,102, 25, 63, 48,107,195, +173,203,159, 32, 15,121, 3,255,192,175,121,166,190,243, 10,215,192, 0,185,124,136,128,246, 76,211, 48, 3,255,192,181, 7,115, +191,177,244,113,191, 48,107, 94,132,141,225,242,240,135, 3,255,192,150,228, 3,192, 53,179,167, 64, 0,185,129,153,159,193,157, + 44,209, 3,255,192,172,155, 50,192, 12,211, 68, 63, 48,107,191,138,118,207,193, 15,121, 3,255,192,175,121,166, 62,243, 10,221, +192, 0,185,124,136,128, 9,180,211, 48, 3,255,192,181, 7,115, 63,177,244,114,191, 48,107, 94,132,141, 30, 14,240,135, 3,255, +192,150,228, 12, 64, 53,179,179, 64, 0,185,145,153,159, 62, 99, 44,209, 3,255,192,172,155, 50, 64, 12,211, 68, 63, 48,107,193, +138,118, 48, 63, 15,121, 3,255,192, 9, 87,134, 64,162, 49, 39,192, 0,185,151,209,216,110,167,211, 47, 3,255,192, 68,129,119, + 64,158,107,189,191, 48,107,200,189, 69,108, 31,240,135, 3,255,192,133, 8,140, 64,102,220, 34, 64, 0,185,151,165, 7, 78, 23, + 44,209, 3,255,192,112,156,117, 64,142,102, 25, 63, 48,107,199,173,203, 96,224, 15,121, 3,255,191,159, 27,126, 64,171,148,137, +192, 0,185,146,228, 78,116,166,211, 47, 3,255,190,218, 15,112, 64,185,234,179,191, 48,107,170,246,112,126,178,240,135, 3,255, + 63,159, 27,126, 64,171,148,137, 64, 0,185,149, 27,178,116,166, 44,209, 3,255, 62,218, 15,112, 64,185,234,179, 63, 48,107,180, + 9,144,126,178, 15,121, 3,255, 64,133, 8,132, 64,102,220, 22,192, 0,185,135, 90,249, 78, 23,211, 47, 3,255, 64,112,156,117, + 64,142,102, 25,191, 48,107,195, 82, 53, 96,224,240,135, 3,255, 64, 9, 87,134, 64,162, 49, 39, 64, 0,185,153, 46, 40,110,167, + 44,209, 3,255, 64, 68,129,119, 64,158,107,189, 63, 48,107,206, 66,187,108, 31, 15,121, 3,255, 64, 19, 54,137,192,147, 0, 88, + 64, 52,105,164, 49, 79,155, 14, 61, 83, 3,255, 64, 97,106,126,192, 99,220,149, 64, 67,124,142, 76,127,177,240, 66,155, 3,255, + 64,162,141,165,191, 68,160,125, 64, 52,105,115,111, 62,240, 76, 61, 83, 3,255, 64,143, 47, 14,192, 15,248, 70, 64, 67,124,117, + 97,226,207, 95, 66,155, 3,255, 63, 86,214,195,192,162, 49, 8, 64, 52,105,159, 19,113,145, 89, 61, 83, 3,255,191, 65,187,185, +192,158,107,124, 64, 67,124,161,240, 0,147,226, 66,155, 3,255,192,106, 31, 90,192,102,219,246, 64, 52,105,157,175, 59,177,233, + 61, 83, 3,255,192, 19, 13,186,192,142,101,215, 64, 67,124,165,205,102,159, 32, 66,155, 3,255,192,145,244,110,192, 23, 82, 67, + 64, 52,105,139,156,198,203, 81, 61, 83, 3,255,192,158, 38, 86,191, 79, 99,175, 64, 67,124,124,148, 58,237,208, 66,155, 3,255, +192,145,244,108, 64, 23, 82, 63, 64, 52,105,140,156,198, 52,175, 61, 83, 3,255,192,158, 38, 86, 63, 79, 99,171, 64, 67,124,124, +148, 58, 18, 48, 66,155, 3,255,192,106, 31, 84, 64,102,219,243, 64, 52,105,160,175, 59, 78, 23, 61, 83, 3,255,192, 19, 13,184, + 64,142,101,215, 64, 67,124,168,205,102, 96,224, 66,155, 3,255, 63, 86,214,196, 64,162, 49, 8, 64, 52,105,161, 19,113,110,167, + 61, 83, 3,255,191, 65,187,181, 64,158,107,124, 64, 67,124,164,240, 0,108, 30, 66,155, 3,255, 64, 19, 54,137, 64,147, 0, 88, + 64, 52,105,166, 49, 79,100,242, 61, 83, 3,255, 64, 97,106,126, 64, 99,220,148, 64, 67,124,143, 76,127, 78, 16, 66,155, 3,255, + 64,162,141,165, 63, 68,160,121, 64, 52,105,115,111, 62, 15,180, 61, 83, 3,255, 64,143, 47, 14, 64, 15,248, 68, 64, 67,124,117, + 97,226, 48,161, 66,155, 3,255, 64,154,145, 70,180, 17,133, 48, 64, 84, 91, 36,106, 36, 0, 0, 71,136, 3,255, 64,111,150,175, +180, 69,218, 93, 64,144,133,120, 82, 21, 0, 0, 98, 54, 3,255, 63, 78,191, 25,180,126,127, 94, 64,185,187,208, 16,131, 0, 0, +126,237, 3,255, 64, 23, 97, 18,180,107, 31,218, 64,171,199,134, 51, 34, 0, 0,117, 86, 3,255, 63,191, 13, 15,192,147, 0, 76, + 64, 84, 91, 93, 32,204,155, 14, 71,135, 3,255, 63,148, 18, 19,192, 99,220,115, 64,144,133,164, 25, 93,177,240, 98, 54, 3,255, + 62,127,139,187,191, 68,160, 59, 64,185,187,205, 5, 26,240, 76,126,237, 3,255, 63, 59, 28, 68,192, 15,248, 30, 64,171,199,160, + 15,204,207, 95,117, 86, 3,255,192,122, 24, 36,192, 53,179,185, 64, 84, 91, 93,170, 33,193,157, 71,136, 3,255,192, 65,212,177, +192, 12,211, 34, 64,144,133,164,189,153,207,193, 98, 54, 3,255,191, 39, 66,179,190,243, 10,108, 64,185,187,205,242,164,246, 76, +126,237, 3,255,191,244,239,138,191,177,244, 60, 64,171,199,156,214,162,225,242,117, 86, 3,255,192,122, 24, 18, 64, 53,179,169, + 64, 84, 91, 86,170, 33, 62, 99, 71,136, 3,255,192, 65,212,177, 64, 12,211, 32, 64,144,133,164,189,153, 48, 63, 98, 54, 3,255, +191, 39, 66,179, 62,243, 10, 91, 64,185,187,205,242,164, 9,180,126,237, 3,255,191,244,239,138, 63,177,244, 56, 64,171,199,156, +214,162, 30, 14,117, 86, 3,255, 63,191, 13, 15, 64,147, 0, 76, 64, 84, 91, 95, 32,204,100,242, 71,135, 3,255, 63,148, 18, 19, + 64, 99,220,112, 64,144,133,165, 25, 93, 78, 16, 98, 54, 3,255, 62,127,139,187, 63, 68,160, 51, 64,185,187,205, 5, 26, 15,180, +126,237, 3,255, 63, 59, 28, 68, 64, 15,248, 27, 64,171,199,160, 15,204, 48,161,117, 86, 3,255, 64, 21,138,248,192, 42,105,206, +192,149,149, 95, 49,236,198, 3,153,102, 3,255, 63,237, 88, 66,192,132,182,148,192,109,108,160, 39, 84,165,105,174,149, 3,255, + 63,214, 47,159,192, 11,146, 94,192,165,204, 53, 36,248,207,108,143,129, 3,255,189,147, 52, 95,192, 47,221, 3,192,165,204, 33, +254,166,194,248,143,129, 3,255,190,166,130,182,192, 97,196, 44,192,149,149, 90,249,179,179,190,153,102, 3,255, 63,112, 9, 19, +192,142, 62,107,192,109,108,166, 21,110,159,152,174,149, 3,255, 64, 80, 72,241,191,179, 31, 82,192,149,149, 86, 70,148,226,113, +153,102, 3,255, 64,144,141,216,190,246,186, 92,192,109,108,135, 98, 80,246,151,174,149, 3,255, 64, 37,213,194,191,106,225,102, +192,165,204, 35, 57,160,235,218,143,129, 3,255, 64, 37,213,194, 63,106,225,110,192,165,204, 35, 57,160, 20, 38,143,129, 3,255, + 64, 80, 72,241, 63,179, 31, 85,192,149,149, 86, 70,148, 29,143,153,102, 3,255, 64,144,141,216, 62,246,186,101,192,109,108,135, + 98, 80, 9,105,174,149, 3,255,191,231,185, 68,192, 66,226, 56,192,149,149, 91,216, 71,190,154,153,102, 3,255,192, 87,195,219, +192, 66,226, 86,192,109,108,146,181,255,190,154,174,150, 3,255,191,199, 75,140,192, 16,251, 51,192,165,204, 49,221, 58,205,212, +143,129, 3,255,192, 40,173,206,191, 71,224, 82,192,165,204, 20,197,138,238,110,143,129, 3,255,192, 93, 38, 96,191, 71,224,102, +192,149,149, 54,181,135,238,110,153,102, 3,255,192,124, 5,156,192, 16,251, 86,192,109,108,129,170,239,205,212,174,149, 3,255, +192, 93, 38, 96, 63, 71,224,107,192,149,149, 54,181,135, 17,146,153,102, 3,255,192,124, 5,156, 64, 16,251, 87,192,109,108,129, +170,239, 50, 44,174,149, 3,255,192, 40,173,206, 63, 71,224, 89,192,165,204, 20,197,138, 17,146,143,129, 3,255,191,199, 75,140, + 64, 16,251, 53,192,165,204, 49,221, 58, 50, 44,143,129, 3,255,191,231,185, 68, 64, 66,226, 59,192,149,149, 91,216, 71, 65,102, +153,102, 3,255,192, 87,195,219, 64, 66,226, 87,192,109,108,146,181,255, 65,102,174,150, 3,255,190,166,130,180, 64, 97,196, 46, +192,149,149, 90,249,179, 76, 66,153,102, 3,255, 63,112, 9, 23, 64,142, 62,108,192,109,108,165, 21,110, 96,104,174,149, 3,255, + 63,214, 47,159, 64, 11,146, 96,192,165,204, 53, 36,248, 48,148,143,129, 3,255,189,147, 52, 96, 64, 47,221, 5,192,165,204, 33, +254,166, 61, 8,143,129, 3,255, 64, 21,138,248, 64, 42,105,207,192,149,149, 94, 49,236, 57,253,153,102, 3,255, 63,237, 88, 68, + 64,132,182,148,192,109,108,158, 39, 84, 90,151,174,149, 3,255, 64,170,211, 33,190,246,186,163,192, 24,104,236,116,202,246,151, +204,122, 3,255, 64,180, 93,120,191,179, 31,134,191, 82, 6,178,123, 86,226,113,238,194, 3,255, 64,170,211, 33, 62,246,186,169, +192, 24,104,236,116,202, 9,105,204,122, 3,255, 64,180, 93,120, 63,179, 31,134,191, 82, 6,178,123, 86, 29,143,238,194, 3,255, + 64,185, 96, 37, 63,106,225,166,186, 15,228,112,126,100, 20, 38,254,197, 3,255, 64,185, 96, 37,191,106,225,166,186, 15,233,114, +126,100,235,218,254,197, 3,255, 63,152,125, 62,192,167, 58,164,192, 24,105, 27, 27, 35,142, 5,204,122, 3,255, 62,210, 87,126, +192,185, 96, 33,191, 82, 6,240, 9,255,129,145,238,194, 3,255, 64, 6,232,178,192,157,178,203,192, 24,105, 26, 45, 10,147,214, +204,122, 3,255, 64, 68,166,195,192,157,178,228,191, 82, 6,223, 66, 58,147,214,238,194, 3,255, 64, 42,106, 94,192,167, 58,200, +186, 15,249, 32, 58, 56,142, 5,254,197, 3,255, 63,106,226, 91,192,185, 96, 31,186, 15,243,211, 19,229,129,145,254,197, 3,255, +192,147, 67,187,192, 47,221, 76,192, 24,105, 1,155,252,194,248,204,122, 3,255,192,172, 61,143,192, 11,146,133,191, 82, 6,184, +138,216,207,108,238,194, 3,255,192,129, 34,217,192, 97,196,126,192, 24,104,250,167, 13,179,190,204,122, 3,255,192,111, 49,112, +192,142, 62,171,191, 82, 6,194,173,153,159,151,238,194, 3,255,192,132,182,227,192,132,182,213,186, 15,241, 17,165,151,165,105, +254,197, 3,255,192,167, 58,235,192, 42,106, 25,186, 15,241, 48,141,231,198, 3,254,197, 3,255,192,129, 34,217, 64, 97,196,126, +192, 24,104,249,167, 13, 76, 66,204,122, 3,255,192,111, 49,112, 64,142, 62,171,191, 82, 6,190,173,153, 96,105,238,194, 3,255, +192,147, 67,187, 64, 47,221, 76,192, 24,105, 0,155,252, 61, 8,204,122, 3,255,192,172, 61,143, 64, 11,146,133,191, 82, 6,182, +138,216, 48,148,238,194, 3,255,192,167, 58,235, 64, 42,106, 25,186, 15,226,166,141,231, 57,253,254,197, 3,255,192,132,182,227, + 64,132,182,213,186, 15,218,107,165,151, 90,151,254,197, 3,255, 64, 6,232,180, 64,157,178,203,192, 24,105, 24, 45, 10,108, 42, +204,122, 3,255, 64, 68,166,196, 64,157,178,228,191, 82, 6,219, 66, 58,108, 42,238,194, 3,255, 63,152,125, 64, 64,167, 58,163, +192, 24,105, 24, 27, 35,113,251,204,122, 3,255, 62,210, 87,126, 64,185, 96, 32,191, 82, 6,230, 9,255,126,111,238,194, 3,255, + 63,106,226, 91, 64,185, 96, 31,186, 15,212, 49, 19,229,126,111,254,197, 3,255, 64, 42,106, 94, 64,167, 58,200,186, 15,220,150, + 58, 56,113,251,254,197, 3,255, 64,172, 61,143,192, 11,146,133, 63, 82, 6,182,117, 40,207,108, 17, 62, 3,255, 64,147, 67,187, +192, 47,221, 76, 64, 24,105, 0,100, 4,194,248, 51,134, 3,255, 64,167, 58,235,192, 42,106, 25, 58, 15,226,166,114, 25,198, 3, + 1, 59, 3,255, 64,132,182,227,192,132,182,213, 58, 15,218,107, 90,105,165,105, 1, 59, 3,255, 64,111, 49,112,192,142, 62,171, + 63, 82, 6,190, 82,103,159,151, 17, 62, 3,255, 64,129, 34,217,192, 97,196,126, 64, 24,104,249, 88,243,179,190, 51,134, 3,255, +190,210, 87,126,192,185, 96, 32, 63, 82, 6,230,246, 1,129,145, 17, 62, 3,255,191,152,125, 64,192,167, 58,163, 64, 24,105, 24, +228,221,142, 5, 51,134, 3,255,191,106,226, 91,192,185, 96, 31, 58, 15,212, 49,236, 27,129,145, 1, 59, 3,255,192, 42,106, 94, +192,167, 58,200, 58, 15,220,150,197,200,142, 5, 1, 59, 3,255,192, 68,166,196,192,157,178,228, 63, 82, 6,219,189,198,147,214, + 17, 62, 3,255,192, 6,232,180,192,157,178,203, 64, 24,105, 24,210,246,147,214, 51,134, 3,255,192,180, 93,120,191,179, 31,134, + 63, 82, 6,178,132,170,226,113, 17, 62, 3,255,192,170,211, 33,190,246,186,169, 64, 24,104,236,139, 54,246,151, 51,134, 3,255, +192,185, 96, 37,191,106,225,166, 58, 15,228,112,129,156,235,218, 1, 59, 3,255,192,185, 96, 37, 63,106,225,166, 58, 15,233,114, +129,156, 20, 38, 1, 59, 3,255,192,180, 93,120, 63,179, 31,134, 63, 82, 6,178,132,170, 29,143, 17, 62, 3,255,192,170,211, 33, + 62,246,186,163, 64, 24,104,236,139, 54, 9,105, 51,134, 3,255,192, 68,166,195, 64,157,178,228, 63, 82, 6,223,189,198,108, 42, + 17, 62, 3,255,192, 6,232,178, 64,157,178,203, 64, 24,105, 26,210,246,108, 42, 51,134, 3,255,192, 42,106, 94, 64,167, 58,200, + 58, 15,249, 32,197,200,113,251, 1, 59, 3,255,191,106,226, 91, 64,185, 96, 31, 58, 15,243,211,236, 27,126,111, 1, 59, 3,255, +190,210, 87,126, 64,185, 96, 33, 63, 82, 6,240,246, 1,126,111, 17, 62, 3,255,191,152,125, 62, 64,167, 58,164, 64, 24,105, 27, +228,221,113,251, 51,134, 3,255, 64,111, 49,112, 64,142, 62,171, 63, 82, 6,194, 82,103, 96,105, 17, 62, 3,255, 64,129, 34,217, + 64, 97,196,126, 64, 24,104,250, 88,243, 76, 66, 51,134, 3,255, 64,167, 58,235, 64, 42,106, 25, 58, 15,241, 48,114, 25, 57,253, + 1, 59, 3,255, 64,132,182,227, 64,132,182,213, 58, 15,241, 17, 90,105, 90,151, 1, 59, 3,255, 64,172, 61,143, 64, 11,146,133, + 63, 82, 6,184,117, 40, 48,148, 17, 62, 3,255, 64,147, 67,187, 64, 47,221, 76, 64, 24,105, 1,100, 4, 61, 8, 51,134, 3,255, + 64, 87,195,219,192, 66,226, 87, 64,109,108,146, 74, 1,190,154, 81,106, 3,255, 63,231,185, 68,192, 66,226, 59, 64,149,149, 91, + 39,185,190,154,102,154, 3,255, 64,124, 5,156,192, 16,251, 87, 64,109,108,129, 85, 17,205,212, 81,106, 3,255, 64, 93, 38, 96, +191, 71,224,107, 64,149,149, 54, 74,121,238,110,102,154, 3,255, 64, 40,173,206,191, 71,224, 89, 64,165,204, 20, 58,118,238,110, +112,127, 3,255, 63,199, 75,140,192, 16,251, 53, 64,165,204, 49, 34,198,205,212,112,127, 3,255,191,237, 88, 68,192,132,182,148, + 64,109,108,158,216,172,165,105, 81,107, 3,255,192, 21,138,248,192, 42,105,207, 64,149,149, 94,206, 20,198, 3,102,154, 3,255, +191,112, 9, 24,192,142, 62,108, 64,109,108,165,234,146,159,152, 81,107, 3,255, 62,166,130,178,192, 97,196, 46, 64,149,149, 90, + 6, 77,179,190,102,154, 3,255, 61,147, 52, 96,192, 47,221, 5, 64,165,204, 33, 1, 90,194,248,112,127, 3,255,191,214, 47,159, +192, 11,146, 96, 64,165,204, 53,219, 8,207,108,112,127, 3,255,192,144,141,216, 62,246,186, 92, 64,109,108,135,157,176, 9,105, + 81,107, 3,255,192, 80, 72,241, 63,179, 31, 82, 64,149,149, 86,185,108, 29,143,102,154, 3,255,192,144,141,216,190,246,186,101, + 64,109,108,135,157,176,246,151, 81,107, 3,255,192, 80, 72,241,191,179, 31, 85, 64,149,149, 86,185,108,226,113,102,154, 3,255, +192, 37,213,194,191,106,225,110, 64,165,204, 35,198, 96,235,218,112,127, 3,255,192, 37,213,194, 63,106,225,102, 64,165,204, 35, +198, 96, 20, 38,112,127, 3,255,191,112, 9, 19, 64,142, 62,107, 64,109,108,166,234,146, 96,104, 81,107, 3,255, 62,166,130,182, + 64, 97,196, 44, 64,149,149, 90, 6, 77, 76, 66,102,154, 3,255,191,237, 88, 66, 64,132,182,148, 64,109,108,160,216,172, 90,151, + 81,107, 3,255,192, 21,138,248, 64, 42,105,206, 64,149,149, 95,206, 20, 57,253,102,154, 3,255,191,214, 47,159, 64, 11,146, 94, + 64,165,204, 53,219, 8, 48,148,112,127, 3,255, 61,147, 52, 95, 64, 47,221, 3, 64,165,204, 33, 1, 90, 61, 8,112,127, 3,255, + 64,124, 5,156, 64, 16,251, 86, 64,109,108,129, 85, 17, 50, 44, 81,107, 3,255, 64, 93, 38, 96, 63, 71,224,102, 64,149,149, 54, + 74,121, 17,146,102,154, 3,255, 64, 87,195,219, 64, 66,226, 86, 64,109,108,146, 74, 1, 65,102, 81,106, 3,255, 63,231,185, 68, + 64, 66,226, 56, 64,149,149, 91, 39,185, 65,102,102,154, 3,255, 64, 40,173,206, 63, 71,224, 82, 64,165,204, 20, 58,118, 17,146, +112,127, 3,255, 63,199, 75,140, 64, 16,251, 51, 64,165,204, 49, 34,198, 50, 44,112,127, 3,255, 64, 37,228,132,192,115, 22,142, +192,105, 57, 50, 56,212,173, 76,176,140, 3,255, 64, 82,251,148,192, 86, 75, 93,192, 96, 71,141, 72, 81,182,242,179,189, 3,255, + 64, 53,229,224,192, 65,211,158,192,132,158, 20, 62, 49,189,205,165,210, 3,255, 63,189,254, 99,192, 64,142,120,192,153,190,125, + 31,245,189,207,151, 55, 3,255, 63, 17, 81,228,192, 83,158, 90,192,153,190,111, 13, 13,183,171,151, 55, 3,255, 63,157,144,120, +192,114,118, 71,192,137,135,100, 26,187,173,186,161,170, 3,255,191, 50,231,197,192,148,176,195,192, 96, 71,159,240,112,154,100, +179,189, 3,255, 62, 10,212,139,192,147, 21,246,192,105, 57, 57, 2,163,155,176,176,140, 3,255,191, 4,232,193,192,131,220,246, +192,132,158, 26,244,154,165,227,165,210, 3,255, 62, 35,154,206,192, 1,253, 58,192,176, 18, 9, 3,147,211,253,135,221, 3,255, + 63,136, 68,236,191,222, 88,175,192,176, 18, 33, 22,250,218, 75,135,221, 3,255, 62,207,150,238,191,159,184, 77,192,182,208,203, + 8,185,229, 37,131, 41, 3,255, 64,141, 58, 69,191,165, 78, 36,192,105, 57, 29, 96, 56,227,131,176,140, 3,255, 64,134,128,163, +192, 6,110,247,192, 96, 71,136, 91,211,209,205,179,189, 3,255, 64,112,141, 26,191,226, 49,224,192,132,158, 23, 82, 45,217, 80, +165,210, 3,255, 64, 84,124,245,190,246,189,198,192,153,190, 97, 72,212,246, 16,151, 55, 3,255, 64, 84,124,245, 62,246,189,210, +192,153,190, 97, 72,212, 9,240,151, 55, 3,255, 64,126,240,177, 52, 0, 0, 0,192,137,135, 73, 86,129, 0, 0,161,170, 3,255, + 64,134,128,163, 64, 6,110,248,192, 96, 71,136, 91,211, 46, 51,179,189, 3,255, 64,141, 58, 69, 63,165, 78, 38,192,105, 57, 29, + 96, 56, 28,125,176,140, 3,255, 64,112,141, 26, 63,226, 49,227,192,132,158, 23, 82, 45, 38,176,165,210, 3,255, 63,253,147, 30, + 62,243,142, 49,192,176, 18, 8, 42,247, 10, 51,135,221, 3,255, 63,253,147, 30,190,243,142, 32,192,176, 18, 8, 42,247,245,205, +135,221, 3,255, 63,167,240,198, 52,128, 0, 0,192,182,208,181, 28, 61, 0, 0,131, 41, 3,255,192, 51,237,147,192,104,228, 14, +192,105, 57, 55,194,232,176,101,176,140, 3,255,192, 10,156, 9,192,133,112, 59,192, 96, 71,154,208,223,164,166,179,189, 3,255, +192, 0, 33,148,192,104,227,254,192,132,158, 29,212, 66,176,101,165,210, 3,255,192, 25,198,253,192, 21,217,132,192,153,190,111, +202,237,205, 39,151, 55, 3,255,192, 62, 9, 62,191,199,227,165,192,153,190,101,191, 62,221, 60,151, 55, 3,255,192, 78, 64,100, +192, 21,217,149,192,137,135, 89,186, 4,205, 39,161,170, 3,255,192,148, 83, 9,191, 69,109, 36,192, 96, 71, 57,154,143,239,103, +179,189, 3,255,192,138,140, 12,191,198, 79, 2,192,105, 56,245,161,106,222,127,176,140, 3,255,192,130,139, 63,191, 71,146,193, +192,132,157,232,166,198,239, 0,165,210, 3,255,191,240,239,195,191, 71,146,150,192,176, 18, 3,215, 63,239, 0,135,221, 3,255, +191,169, 91, 0,191,198, 78,203,192,176, 18, 21,227, 61,222,127,135,221, 3,255,191,135,221,228,191, 69,108,244,192,182,208,206, +233, 40,239,103,131, 41, 3,255,192,138,140, 12, 63,198, 79, 5,192,105, 56,245,161,106, 33,129,176,140, 3,255,192,148, 83, 9, + 63, 69,109, 42,192, 96, 71, 57,154,143, 16,153,179,189, 3,255,192,130,139, 63, 63, 71,146,200,192,132,157,231,166,198, 17, 0, +165,210, 3,255,192, 62, 9, 62, 63,199,227,169,192,153,190,101,191, 62, 34,196,151, 55, 3,255,192, 25,198,253, 64, 21,217,134, +192,153,190,111,202,237, 50,217,151, 55, 3,255,192, 78, 64,100, 64, 21,217,151,192,137,135, 89,186, 4, 50,217,161,170, 3,255, +192, 10,156, 9, 64,133,112, 59,192, 96, 71,151,208,223, 91, 90,179,189, 3,255,192, 51,237,147, 64,104,228, 16,192,105, 57, 54, +194,232, 79,155,176,140, 3,255,192, 0, 33,148, 64,104,228, 0,192,132,158, 28,212, 66, 79,155,165,210, 3,255,191,169, 91, 0, + 63,198, 78,208,192,176, 18, 21,227, 61, 33,129,135,221, 3,255,191,240,239,195, 63, 71,146,159,192,176, 18, 3,215, 63, 17, 0, +135,221, 3,255,191,135,221,228, 63, 69,108,252,192,182,208,206,233, 40, 16,153,131, 41, 3,255, 62, 10,212,148, 64,147, 21,246, +192,105, 57, 56, 2,163,100, 80,176,140, 3,255,191, 50,231,196, 64,148,176,196,192, 96, 71,156,240,112,101,156,179,189, 3,255, +191, 4,232,191, 64,131,220,248,192,132,158, 25,244,154, 90, 29,165,210, 3,255, 63, 17, 81,229, 64, 83,158, 92,192,153,190,111, + 13, 13, 72, 85,151, 55, 3,255, 63,189,254, 98, 64, 64,142,121,192,153,190,125, 31,245, 66, 49,151, 55, 3,255, 63,157,144,120, + 64,114,118, 72,192,137,135,100, 26,187, 82, 70,161,170, 3,255, 64, 82,251,150, 64, 86, 75, 95,192, 96, 71,139, 72, 80, 73, 14, +179,189, 3,255, 64, 37,228,133, 64,115, 22,142,192,105, 57, 48, 56,212, 82,180,176,140, 3,255, 64, 53,229,224, 64, 65,211,160, +192,132,158, 20, 62, 49, 66, 51,165,210, 3,255, 63,136, 68,236, 63,222, 88,179,192,176, 18, 33, 22,250, 37,181,135,221, 3,255, + 62, 35,154,206, 64, 1,253, 60,192,176, 18, 9, 3,147, 44, 3,135,221, 3,255, 62,207,150,238, 63,159,184, 82,192,182,208,203, + 8,185, 26,219,131, 41, 3,255, 64,172,103,184,191,226, 50, 13,191,193, 21, 59,117,105,217, 80,222,212, 3,255, 64,160,115,141, +192, 6,111, 1,192, 12, 78,195,109, 71,209,205,207,249, 3,255, 64,167,117,111,191,165, 78, 66,192, 20, 86,160,114, 24,227,131, +205,121, 3,255, 64,180, 3,220, 51,128, 0, 0,191,210, 9,202,123, 16, 0, 0,220,208, 3,255, 64,185, 6,190, 62,246,190, 47, +191, 82, 45,247,126, 75, 9,240,237,185, 3,255, 64,185, 6,190,190,246,190, 45,191, 82, 45,247,126, 75,246, 16,237,185, 3,255, + 64,182, 74,149,179,128, 0, 0, 63,176,209,130,124, 74, 0, 0, 30,146, 3,255, 64,185,213, 38,190,243,142,111, 63, 48, 81, 0, +126,171,245,205, 15, 76, 3,255, 64,185,213, 38, 62,243,142,109, 63, 48, 81, 0,126,171, 10, 51, 15, 76, 3,255, 64,172,103,184, + 63,226, 50, 14,191,193, 21, 58,117,105, 38,176,222,212, 3,255, 64,167,117,111, 63,165, 78, 67,192, 20, 86,160,114, 24, 28,125, +205,121, 3,255, 64,160,115,141, 64, 6,111, 1,192, 12, 78,194,109, 71, 46, 51,207,249, 3,255,188,129, 88,227,192,181,112,251, +191,193, 21, 76,255,125,132, 98,222,212, 3,255,190,229,132, 59,192,173, 94,142,192, 12, 78,213,245,213,137,204,207,249, 3,255, + 62,199, 26,166,192,172, 8,123,192, 20, 86,191, 8, 41,138,175,205,121, 3,255, 63,222,131, 86,192,171, 52, 96,191,210, 10, 28, + 38, 7,138,246,220,208, 3,255, 64, 15,175,214,192,171, 52,115,191, 82, 46, 55, 48,122,138,246,237,185, 3,255, 63,170, 9,210, +192,180,188,102,191, 82, 46, 65, 29,146,132,209,237,185, 3,255, 63,225, 82,188,192,173, 94,178, 63,176,210, 0, 38,104,137,203, + 30,147, 3,255, 63,171,202,104,192,181,113, 16, 63, 48, 81,129, 29,112,132, 97, 15, 76, 3,255, 64, 15,206, 77,192,172, 8,151, + 63, 48, 81,125, 48,216,138,175, 15, 76, 3,255, 64, 86, 29,211,192,146,125,223,191,193, 21, 84, 73, 20,156, 75,222,212, 3,255, + 64, 54, 26,206,192,146,125,208,192, 20, 86,191, 62, 90,156, 75,205,121, 3,255, 64, 99, 5, 62,192,131,211,129,192, 12, 78,211, + 77,181,166, 90,207,249, 3,255,192,172,183,192,191,222, 88,251,191,193, 21, 30,138, 70,218, 75,222,212, 3,255,192,169, 81, 83, +191,159,184,152,192, 12, 78,161,140,112,229, 37,207,250, 3,255,192,159,196,184,192, 1,253,119,192, 20, 86,141,146,243,211,253, +205,121, 3,255,192,145,162,193,192, 83,158,188,191,210, 9,250,156,113,183,171,220,208, 3,255,192,140,159,254,192,114,118,183, +191, 82, 46, 18,159,172,173,186,237,185, 3,255,192,158,193, 35,192, 64,142,207,191, 82, 46, 27,147,252,189,207,237,185, 3,255, +192,147,122, 46,192, 86, 75,147, 63,176,209,233,155,115,182,242, 30,147, 3,255,192,159, 74, 54,192, 65,211,225, 63, 48, 81,112, +147,136,189,205, 15, 76, 3,255,192,141,100,255,192,115, 22,230, 63, 48, 81,119,159,133,173, 76, 15, 76, 3,255,192, 84,122,147, +192,147, 22, 43,191,193, 21, 73,183,194,155,176,222,212, 3,255,192, 94, 94,244,192,131,221, 35,192, 20, 86,180,180,113,165,227, +205,121, 3,255,192, 52,152,140,192,148,176,228,192, 12, 78,213,194,192,154,100,207,249, 3,255,192, 84,122,147, 64,147, 22, 43, +191,193, 21, 70,183,194,100, 80,222,212, 3,255,192, 52,152,140, 64,148,176,228,192, 12, 78,211,194,192,101,156,207,249, 3,255, +192, 94, 94,244, 64,131,221, 35,192, 20, 86,178,180,113, 90, 29,205,121, 3,255,192,145,162,193, 64, 83,158,188,191,210, 9,248, +156,113, 72, 85,220,208, 3,255,192,158,193, 35, 64, 64,142,207,191, 82, 46, 23,147,252, 66, 49,237,185, 3,255,192,140,159,254, + 64,114,118,183,191, 82, 46, 14,159,172, 82, 70,237,185, 3,255,192,147,122, 46, 64, 86, 75,147, 63,176,209,235,155,115, 73, 14, + 30,147, 3,255,192,141,100,255, 64,115, 22,230, 63, 48, 81,123,159,133, 82,180, 15, 76, 3,255,192,159, 74, 54, 64, 65,211,225, + 63, 48, 81,116,147,136, 66, 51, 15, 76, 3,255,192,172,183,192, 63,222, 88,251,191,193, 21, 29,138, 70, 37,181,222,212, 3,255, +192,159,196,184, 64, 1,253,119,192, 20, 86,141,146,243, 44, 3,205,121, 3,255,192,169, 81, 83, 63,159,184,154,192, 12, 78,161, +140,112, 26,219,207,250, 3,255, 64, 86, 29,212, 64,146,125,223,191,193, 21, 82, 73, 20, 99,181,222,212, 3,255, 64, 99, 5, 63, + 64,131,211,129,192, 12, 78,209, 77,181, 89,166,207,249, 3,255, 64, 54, 26,208, 64,146,125,208,192, 20, 86,189, 62, 90, 99,181, +205,121, 3,255, 63,222,131, 88, 64,171, 52, 95,191,210, 10, 24, 38, 7,117, 10,220,208, 3,255, 63,170, 9,210, 64,180,188,100, +191, 82, 46, 55, 29,146,123, 47,237,185, 3,255, 64, 15,175,215, 64,171, 52,115,191, 82, 46, 49, 48,122,117, 10,237,185, 3,255, + 63,225, 82,187, 64,173, 94,178, 63,176,210, 5, 38,104,118, 53, 30,147, 3,255, 64, 15,206, 77, 64,172, 8,151, 63, 48, 81,133, + 48,216,117, 81, 15, 76, 3,255, 63,171,202,104, 64,181,113, 16, 63, 48, 81,139, 29,112,123,159, 15, 76, 3,255,188,129, 88,216, + 64,181,112,250,191,193, 21, 70,255,125,123,158,222,212, 3,255, 62,199, 26,169, 64,172, 8,122,192, 20, 86,189, 8, 41,117, 81, +205,121, 3,255,190,229,132, 56, 64,173, 94,142,192, 12, 78,210,245,213,118, 52,207,249, 3,255, 64,159,196,184,192, 1,253,119, + 64, 20, 86,141,109, 13,211,253, 50,135, 3,255, 64,169, 81, 83,191,159,184,154, 64, 12, 78,161,115,144,229, 37, 48, 6, 3,255, + 64,172,183,192,191,222, 88,251, 63,193, 21, 29,117,186,218, 75, 33, 44, 3,255, 64,158,193, 35,192, 64,142,207, 63, 82, 46, 23, +108, 4,189,207, 18, 71, 3,255, 64,140,159,254,192,114,118,183, 63, 82, 46, 14, 96, 84,173,186, 18, 71, 3,255, 64,145,162,193, +192, 83,158,188, 63,210, 9,248, 99,143,183,171, 35, 48, 3,255, 64, 52,152,140,192,148,176,228, 64, 12, 78,211, 61, 64,154,100, + 48, 7, 3,255, 64, 94, 94,244,192,131,221, 35, 64, 20, 86,178, 75,143,165,227, 50,135, 3,255, 64, 84,122,147,192,147, 22, 43, + 63,193, 21, 70, 72, 62,155,176, 33, 44, 3,255, 64,141,100,255,192,115, 22,230,191, 48, 81,123, 96,123,173, 76,240,180, 3,255, + 64,159, 74, 54,192, 65,211,225,191, 48, 81,116,108,120,189,205,240,180, 3,255, 64,147,122, 46,192, 86, 75,147,191,176,209,235, +100,141,182,242,225,109, 3,255,190,199, 26,169,192,172, 8,122, 64, 20, 86,189,247,215,138,175, 50,135, 3,255, 62,229,132, 57, +192,173, 94,142, 64, 12, 78,210, 10, 43,137,204, 48, 7, 3,255, 60,129, 88,216,192,181,112,250, 63,193, 21, 70, 0,131,132, 98, + 33, 44, 3,255,191,170, 9,210,192,180,188,100, 63, 82, 46, 55,226,110,132,209, 18, 71, 3,255,192, 15,175,215,192,171, 52,115, + 63, 82, 46, 49,207,134,138,246, 18, 71, 3,255,191,222,131, 87,192,171, 52, 95, 63,210, 10, 24,217,249,138,246, 35, 48, 3,255, +192, 99, 5, 63,192,131,211,129, 64, 12, 78,209,178, 75,166, 90, 48, 7, 3,255,192, 54, 26,208,192,146,125,208, 64, 20, 86,189, +193,166,156, 75, 50,135, 3,255,192, 86, 29,212,192,146,125,223, 63,193, 21, 82,182,236,156, 75, 33, 44, 3,255,192, 15,206, 77, +192,172, 8,151,191, 48, 81,133,207, 40,138,175,240,180, 3,255,191,171,202,104,192,181,113, 16,191, 48, 81,139,226,144,132, 97, +240,180, 3,255,191,225, 82,187,192,173, 94,178,191,176,210, 5,217,152,137,203,225,109, 3,255,192,167,117,111,191,165, 78, 67, + 64, 20, 86,160,141,232,227,131, 50,135, 3,255,192,160,115,141,192, 6,111, 1, 64, 12, 78,194,146,185,209,205, 48, 7, 3,255, +192,172,103,184,191,226, 50, 14, 63,193, 21, 58,138,151,217, 80, 33, 44, 3,255,192,185, 6,190,190,246,190, 47, 63, 82, 45,247, +129,181,246, 16, 18, 71, 3,255,192,185, 6,190, 62,246,190, 45, 63, 82, 45,247,129,181, 9,240, 18, 71, 3,255,192,180, 3,220, +179,128, 0, 0, 63,210, 9,202,132,240, 0, 0, 35, 48, 3,255,192,160,115,141, 64, 6,111, 1, 64, 12, 78,195,146,185, 46, 51, + 48, 7, 3,255,192,167,117,111, 63,165, 78, 66, 64, 20, 86,160,141,232, 28,125, 50,135, 3,255,192,172,103,184, 63,226, 50, 13, + 63,193, 21, 59,138,151, 38,176, 33, 44, 3,255,192,185,213, 38, 62,243,142,111,191, 48, 81, 0,129, 85, 10, 51,240,180, 3,255, +192,185,213, 38,190,243,142,109,191, 48, 81, 0,129, 85,245,205,240,180, 3,255,192,182, 74,149, 51,128, 0, 0,191,176,209,130, +131,182, 0, 0,225,110, 3,255,192, 54, 26,206, 64,146,125,208, 64, 20, 86,191,193,166, 99,181, 50,135, 3,255,192, 99, 5, 62, + 64,131,211,129, 64, 12, 78,211,178, 75, 89,166, 48, 7, 3,255,192, 86, 29,211, 64,146,125,223, 63,193, 21, 84,182,236, 99,181, + 33, 44, 3,255,192, 15,175,214, 64,171, 52,115, 63, 82, 46, 55,207,134,117, 10, 18, 71, 3,255,191,170, 9,210, 64,180,188,102, + 63, 82, 46, 65,226,110,123, 47, 18, 71, 3,255,191,222,131, 86, 64,171, 52, 96, 63,210, 10, 28,217,249,117, 10, 35, 48, 3,255, + 62,229,132, 59, 64,173, 94,142, 64, 12, 78,213, 10, 43,118, 52, 48, 7, 3,255,190,199, 26,166, 64,172, 8,123, 64, 20, 86,191, +247,215,117, 81, 50,135, 3,255, 60,129, 88,227, 64,181,112,251, 63,193, 21, 76, 0,131,123,158, 33, 44, 3,255,191,171,202,104, + 64,181,113, 16,191, 48, 81,129,226,144,123,159,240,180, 3,255,192, 15,206, 77, 64,172, 8,151,191, 48, 81,125,207, 40,117, 81, +240,180, 3,255,191,225, 82,188, 64,173, 94,178,191,176,210, 0,217,152,118, 53,225,109, 3,255, 64, 94, 94,244, 64,131,221, 35, + 64, 20, 86,180, 75,143, 90, 29, 50,135, 3,255, 64, 52,152,140, 64,148,176,228, 64, 12, 78,213, 61, 64,101,156, 48, 7, 3,255, + 64, 84,122,147, 64,147, 22, 43, 63,193, 21, 73, 72, 62,100, 80, 33, 44, 3,255, 64,140,159,254, 64,114,118,183, 63, 82, 46, 18, + 96, 84, 82, 70, 18, 71, 3,255, 64,158,193, 35, 64, 64,142,207, 63, 82, 46, 27,108, 4, 66, 49, 18, 71, 3,255, 64,145,162,193, + 64, 83,158,188, 63,210, 9,250, 99,143, 72, 85, 35, 48, 3,255, 64,169, 81, 83, 63,159,184,152, 64, 12, 78,161,115,144, 26,219, + 48, 6, 3,255, 64,159,196,184, 64, 1,253,119, 64, 20, 86,141,109, 13, 44, 3, 50,135, 3,255, 64,172,183,192, 63,222, 88,251, + 63,193, 21, 30,117,186, 37,181, 33, 44, 3,255, 64,159, 74, 54, 64, 65,211,225,191, 48, 81,112,108,120, 66, 51,240,180, 3,255, + 64,141,100,255, 64,115, 22,230,191, 48, 81,119, 96,123, 82,180,240,180, 3,255, 64,147,122, 46, 64, 86, 75,147,191,176,209,233, +100,141, 73, 14,225,109, 3,255, 64, 0, 33,148,192,104,228, 0, 64,132,158, 28, 43,190,176,101, 90, 46, 3,255, 64, 10,156, 9, +192,133,112, 59, 64, 96, 71,151, 47, 33,164,166, 76, 67, 3,255, 64, 51,237,147,192,104,228, 16, 64,105, 57, 54, 61, 24,176,101, + 79,116, 3,255, 64, 78, 64,100,192, 21,217,151, 64,137,135, 89, 69,252,205, 39, 94, 86, 3,255, 64, 62, 9, 62,191,199,227,169, + 64,153,190,101, 64,194,221, 60,104,201, 3,255, 64, 25,198,253,192, 21,217,134, 64,153,190,111, 53, 19,205, 39,104,201, 3,255, + 63,135,221,228,191, 69,108,252, 64,182,208,206, 22,216,239,103,124,215, 3,255, 63,169, 91, 0,191,198, 78,208, 64,176, 18, 21, + 28,195,222,127,120, 35, 3,255, 63,240,239,195,191, 71,146,159, 64,176, 18, 3, 40,193,239, 0,120, 35, 3,255, 64,130,139, 63, +191, 71,146,200, 64,132,157,231, 89, 58,239, 0, 90, 46, 3,255, 64,138,140, 12,191,198, 79, 5, 64,105, 56,245, 94,150,222,127, + 79,116, 3,255, 64,148, 83, 9,191, 69,109, 41, 64, 96, 71, 57,101,113,239,103, 76, 67, 3,255,192, 53,229,224,192, 65,211,160, + 64,132,158, 20,193,207,189,205, 90, 46, 3,255,192, 82,251,150,192, 86, 75, 95, 64, 96, 71,139,183,176,182,242, 76, 67, 3,255, +192, 37,228,133,192,115, 22,142, 64,105, 57, 48,199, 44,173, 76, 79,116, 3,255,191,157,144,120,192,114,118, 72, 64,137,135,100, +229, 69,173,186, 94, 86, 3,255,191, 17, 81,230,192, 83,158, 92, 64,153,190,111,242,243,183,171,104,201, 3,255,191,189,254, 98, +192, 64,142,121, 64,153,190,125,224, 11,189,207,104,201, 3,255,190,207,150,240,191,159,184, 82, 64,182,208,203,247, 71,229, 37, +124,215, 3,255,191,136, 68,236,191,222, 88,179, 64,176, 18, 33,233, 6,218, 75,120, 35, 3,255,190, 35,154,206,192, 1,253, 60, + 64,176, 18, 9,252,109,211,253,120, 35, 3,255, 63, 4,232,190,192,131,220,248, 64,132,158, 25, 11,102,165,227, 90, 46, 3,255, +190, 10,212,152,192,147, 21,246, 64,105, 57, 56,253, 93,155,176, 79,116, 3,255, 63, 50,231,197,192,148,176,196, 64, 96, 71,156, + 15,144,154,100, 76, 67, 3,255,192,112,141, 26, 63,226, 49,224, 64,132,158, 23,173,211, 38,176, 90, 46, 3,255,192,134,128,163, + 64, 6,110,247, 64, 96, 71,136,164, 45, 46, 51, 76, 67, 3,255,192,141, 58, 69, 63,165, 78, 36, 64,105, 57, 29,159,200, 28,125, + 79,116, 3,255,192,126,240,177,180, 0, 0, 0, 64,137,135, 73,169,127, 0, 0, 94, 86, 3,255,192, 84,124,245,190,246,189,211, + 64,153,190, 97,183, 44,246, 16,104,201, 3,255,192, 84,124,245, 62,246,189,198, 64,153,190, 97,183, 44, 9,240,104,201, 3,255, +191,167,240,198,180,160, 0, 0, 64,182,208,181,227,195, 0, 0,124,215, 3,255,191,253,147, 30, 62,243,142, 32, 64,176, 18, 8, +213, 9, 10, 51,120, 35, 3,255,191,253,147, 30,190,243,142, 49, 64,176, 18, 8,213, 9,245,205,120, 35, 3,255,192,112,141, 26, +191,226, 49,227, 64,132,158, 23,173,211,217, 80, 90, 46, 3,255,192,141, 58, 69,191,165, 78, 38, 64,105, 57, 29,159,200,227,131, + 79,116, 3,255,192,134,128,163,192, 6,110,248, 64, 96, 71,136,164, 45,209,205, 76, 67, 3,255, 63, 4,232,193, 64,131,220,246, + 64,132,158, 26, 11,102, 90, 29, 90, 46, 3,255, 63, 50,231,198, 64,148,176,195, 64, 96, 71,159, 15,144,101,156, 76, 67, 3,255, +190, 10,212,139, 64,147, 21,246, 64,105, 57, 57,253, 93,100, 80, 79,116, 3,255,191,157,144,120, 64,114,118, 71, 64,137,135,100, +229, 69, 82, 70, 94, 86, 3,255,191,189,254, 99, 64, 64,142,120, 64,153,190,125,224, 11, 66, 49,104,201, 3,255,191, 17, 81,228, + 64, 83,158, 90, 64,153,190,111,242,243, 72, 85,104,201, 3,255,190,207,150,238, 63,159,184, 77, 64,182,208,203,247, 71, 26,219, +124,215, 3,255,190, 35,154,206, 64, 1,253, 58, 64,176, 18, 9,252,109, 44, 3,120, 35, 3,255,191,136, 68,236, 63,222, 88,175, + 64,176, 18, 33,233, 6, 37,181,120, 35, 3,255,192, 53,229,224, 64, 65,211,158, 64,132,158, 20,193,207, 66, 51, 90, 46, 3,255, +192, 37,228,132, 64,115, 22,142, 64,105, 57, 50,199, 44, 82,180, 79,116, 3,255,192, 82,251,148, 64, 86, 75, 93, 64, 96, 71,141, +183,175, 73, 14, 76, 67, 3,255, 64,130,139, 63, 63, 71,146,193, 64,132,157,232, 89, 58, 17, 0, 90, 46, 3,255, 64,148, 83, 9, + 63, 69,109, 37, 64, 96, 71, 57,101,113, 16,153, 76, 67, 3,255, 64,138,140, 12, 63,198, 79, 2, 64,105, 56,245, 94,150, 33,129, + 79,116, 3,255, 64, 78, 64,100, 64, 21,217,149, 64,137,135, 89, 69,252, 50,217, 94, 86, 3,255, 64, 25,198,253, 64, 21,217,132, + 64,153,190,111, 53, 19, 50,217,104,201, 3,255, 64, 62, 9, 62, 63,199,227,165, 64,153,190,101, 64,194, 34,196,104,201, 3,255, + 63,135,221,228, 63, 69,108,244, 64,182,208,206, 22,216, 16,153,124,215, 3,255, 63,240,239,195, 63, 71,146,150, 64,176, 18, 3, + 40,193, 17, 0,120, 35, 3,255, 63,169, 91, 0, 63,198, 78,203, 64,176, 18, 21, 28,195, 33,129,120, 35, 3,255, 64, 0, 33,148, + 64,104,227,254, 64,132,158, 29, 43,190, 79,155, 90, 46, 3,255, 64, 51,237,147, 64,104,228, 14, 64,105, 57, 55, 61, 24, 79,155, + 79,116, 3,255, 64, 10,156, 9, 64,133,112, 59, 64, 96, 71,154, 47, 33, 91, 90, 76, 67, 3,255, 68, 65, 84, 65, 0, 0, 90, 0, + 7, 83,144, 32, 0, 0, 0, 49, 0, 0, 7,128, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0, 42, + 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 0, 42, 0, 0, 0, 35, 0, 0, 0,164, + 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 0, 12, 0, 0, 0, 35, + 0, 0, 0,165, 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0, 44, + 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0, 13, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 0,168, + 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0, 45, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 0, 13, 0, 0, 0, 35, + 0, 0, 0,169, 0, 0, 0, 45, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 0, 46, + 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 0,172, + 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 0, 14, 0, 0, 0, 35, + 0, 0, 0,173, 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 0, 48, + 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 0, 48, 0, 0, 0, 35, 0, 0, 0,176, + 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0, 49, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 0, 15, 0, 0, 0, 35, + 0, 0, 0,177, 0, 0, 0, 49, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 0, 50, + 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 0, 50, 0, 0, 0, 35, 0, 0, 0,180, + 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 0, 51, 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 0, 16, 0, 0, 0, 35, + 0, 0, 0,181, 0, 0, 0, 51, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 0, 52, + 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 0,184, + 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 0, 17, 0, 0, 0, 35, + 0, 0, 0,185, 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 0, 54, + 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 0, 54, 0, 0, 0, 35, 0, 0, 0,188, + 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 0, 55, 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 0, 18, 0, 0, 0, 35, + 0, 0, 0,189, 0, 0, 0, 55, 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 0, 56, + 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 0, 56, 0, 0, 0, 35, 0, 0, 0,192, + 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 0, 19, 0, 0, 0, 35, + 0, 0, 0,193, 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0, 58, + 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 0,196, + 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 0, 59, 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 0, 20, 0, 0, 0, 35, + 0, 0, 0,197, 0, 0, 0, 59, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0, 60, + 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 0,200, + 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 0, 21, 0, 0, 0, 35, + 0, 0, 0,201, 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0, 62, + 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 0,204, + 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 0, 22, 0, 0, 0, 35, + 0, 0, 0,205, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0, 64, + 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 0, 23, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 0,208, + 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 0, 23, 0, 0, 0, 35, + 0, 0, 0,209, 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 0, 66, + 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 0, 24, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 0, 66, 0, 0, 0, 35, 0, 0, 0,212, + 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 0, 67, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 0, 24, 0, 0, 0, 35, + 0, 0, 0,213, 0, 0, 0, 67, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 0, 68, + 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 0, 68, 0, 0, 0, 35, 0, 0, 0,216, + 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 0, 69, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 0, 25, 0, 0, 0, 35, + 0, 0, 0,217, 0, 0, 0, 69, 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 0, 70, + 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 0, 70, 0, 0, 0, 35, 0, 0, 0,220, + 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 0, 71, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 0, 26, 0, 0, 0, 35, + 0, 0, 0,221, 0, 0, 0, 71, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 0, 72, + 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 0, 27, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 0, 72, 0, 0, 0, 35, 0, 0, 0,224, + 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 0, 73, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 0, 27, 0, 0, 0, 35, + 0, 0, 0,225, 0, 0, 0, 73, 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 0, 74, + 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 0, 74, 0, 0, 0, 35, 0, 0, 0,228, + 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0, 75, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 0, 28, 0, 0, 0, 35, + 0, 0, 0,229, 0, 0, 0, 75, 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 0, 76, + 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 0, 76, 0, 0, 0, 35, 0, 0, 0,232, + 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 0, 77, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 0, 29, 0, 0, 0, 35, + 0, 0, 0,233, 0, 0, 0, 77, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 0, 78, + 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 0, 78, 0, 0, 0, 35, 0, 0, 0,236, + 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 0, 79, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 0, 30, 0, 0, 0, 35, + 0, 0, 0,237, 0, 0, 0, 79, 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 0, 80, + 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 0, 31, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 0, 80, 0, 0, 0, 35, 0, 0, 0,240, + 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 0, 81, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 0, 31, 0, 0, 0, 35, + 0, 0, 0,241, 0, 0, 0, 81, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 0, 82, + 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 0, 82, 0, 0, 0, 35, 0, 0, 0,244, + 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 0, 32, 0, 0, 0, 35, + 0, 0, 0,245, 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 0, 84, + 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 0, 84, 0, 0, 0, 35, 0, 0, 0,248, + 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 0, 85, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 0, 33, 0, 0, 0, 35, + 0, 0, 0,249, 0, 0, 0, 85, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 0, 86, + 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 0, 86, 0, 0, 0, 35, 0, 0, 0,252, + 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 0, 87, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 0, 35, + 0, 0, 0,253, 0, 0, 0, 87, 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 0, 88, + 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 0, 88, 0, 0, 0, 35, 0, 0, 1, 0, + 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 0, 89, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 0, 35, 0, 0, 0, 35, + 0, 0, 1, 1, 0, 0, 0, 89, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 0, 90, + 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 0, 90, 0, 0, 0, 35, 0, 0, 1, 4, + 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 0, 91, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 0, 36, 0, 0, 0, 35, + 0, 0, 1, 5, 0, 0, 0, 91, 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 0, 92, + 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 0, 92, 0, 0, 0, 35, 0, 0, 1, 8, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 0, 93, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 0, 37, 0, 0, 0, 35, + 0, 0, 1, 9, 0, 0, 0, 93, 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 0, 94, + 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 0, 38, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 0, 94, 0, 0, 0, 35, 0, 0, 1, 12, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 0, 95, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 0, 38, 0, 0, 0, 35, + 0, 0, 1, 13, 0, 0, 0, 95, 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 0, 96, + 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 0, 96, 0, 0, 0, 35, 0, 0, 1, 16, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 0, 39, 0, 0, 0, 35, + 0, 0, 1, 17, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 0, 98, + 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 0, 98, 0, 0, 0, 35, 0, 0, 1, 20, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 0, 99, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 0, 40, 0, 0, 0, 35, + 0, 0, 1, 21, 0, 0, 0, 99, 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 0,100, + 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 0,100, 0, 0, 0, 35, 0, 0, 1, 24, + 0, 0, 0, 11, 0, 0, 0, 35, 0, 0, 1, 24, 0, 0, 0,101, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 0, 41, 0, 0, 0, 35, + 0, 0, 1, 25, 0, 0, 0,101, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 0,102, + 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 0,102, 0, 0, 0, 35, 0, 0, 1, 28, + 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 1, 28, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 0, 13, 0, 0, 0, 35, + 0, 0, 1, 29, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1, 30, 0, 0, 0, 13, 0, 0, 0, 35, 0, 0, 1, 30, 0, 0, 0,104, + 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 0,104, 0, 0, 0, 35, 0, 0, 1, 32, + 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 1, 32, 0, 0, 0,105, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 0, 16, 0, 0, 0, 35, + 0, 0, 1, 33, 0, 0, 0,105, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 0, 12, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 0,106, + 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 1, 36, + 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 1, 36, 0, 0, 0,107, 0, 0, 0, 35, 0, 0, 1, 37, 0, 0, 0, 16, 0, 0, 0, 35, + 0, 0, 1, 37, 0, 0, 0,107, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 0, 13, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 0,108, + 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 0,108, 0, 0, 0, 35, 0, 0, 1, 40, + 0, 0, 0, 13, 0, 0, 0, 35, 0, 0, 1, 40, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 0, 17, 0, 0, 0, 35, + 0, 0, 1, 41, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 0,110, + 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 0,110, 0, 0, 0, 35, 0, 0, 1, 44, + 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 0,111, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 0, 20, 0, 0, 0, 35, + 0, 0, 1, 45, 0, 0, 0,111, 0, 0, 0, 35, 0, 0, 1, 46, 0, 0, 0, 17, 0, 0, 0, 35, 0, 0, 1, 46, 0, 0, 0,112, + 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 1, 48, + 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 1, 48, 0, 0, 0,113, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 0, 20, 0, 0, 0, 35, + 0, 0, 1, 49, 0, 0, 0,113, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 0, 19, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 0,114, + 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 0,114, 0, 0, 0, 35, 0, 0, 1, 52, + 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 0, 19, 0, 0, 0, 35, + 0, 0, 1, 53, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 0, 15, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 0,116, + 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 0,116, 0, 0, 0, 35, 0, 0, 1, 56, + 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 1, 56, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 0, 23, 0, 0, 0, 35, + 0, 0, 1, 57, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 0, 16, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 0,118, + 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 1, 60, + 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 0,119, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 0, 23, 0, 0, 0, 35, + 0, 0, 1, 61, 0, 0, 0,119, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 0,120, + 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 0,120, 0, 0, 0, 35, 0, 0, 1, 64, + 0, 0, 0, 14, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 0, 24, 0, 0, 0, 35, + 0, 0, 1, 65, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 0, 24, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 0,122, + 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 0,122, 0, 0, 0, 35, 0, 0, 1, 68, + 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 0,123, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 0, 27, 0, 0, 0, 35, + 0, 0, 1, 69, 0, 0, 0,123, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 0, 18, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 0,124, + 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 1, 72, + 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 1, 72, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 0, 27, 0, 0, 0, 35, + 0, 0, 1, 73, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 0,126, + 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 0,126, 0, 0, 0, 35, 0, 0, 1, 76, + 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 1, 76, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 0, 28, 0, 0, 0, 35, + 0, 0, 1, 77, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 0,128, + 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 0,128, 0, 0, 0, 35, 0, 0, 1, 80, + 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 1, 80, 0, 0, 0,129, 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 0, 31, 0, 0, 0, 35, + 0, 0, 1, 81, 0, 0, 0,129, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 0,130, + 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 1, 84, + 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 1, 84, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 0, 31, 0, 0, 0, 35, + 0, 0, 1, 85, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 0, 23, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 0,132, + 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 1, 88, + 0, 0, 0, 23, 0, 0, 0, 35, 0, 0, 1, 88, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 1, 89, 0, 0, 0, 24, 0, 0, 0, 35, + 0, 0, 1, 89, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 1, 90, 0, 0, 0, 24, 0, 0, 0, 35, 0, 0, 1, 90, 0, 0, 0,134, + 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 0,134, 0, 0, 0, 35, 0, 0, 1, 92, + 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 0, 33, 0, 0, 0, 35, + 0, 0, 1, 93, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 1, 94, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 1, 94, 0, 0, 0,136, + 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 1, 96, + 0, 0, 0, 26, 0, 0, 0, 35, 0, 0, 1, 96, 0, 0, 0,137, 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 0, 33, 0, 0, 0, 35, + 0, 0, 1, 97, 0, 0, 0,137, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 0, 27, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 0,138, + 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 0,138, 0, 0, 0, 35, 0, 0, 1,100, + 0, 0, 0, 27, 0, 0, 0, 35, 0, 0, 1,100, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 0, 28, 0, 0, 0, 35, + 0, 0, 1,101, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 0, 28, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 0,140, + 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 0,140, 0, 0, 0, 35, 0, 0, 1,104, + 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 1,104, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 0, 35, + 0, 0, 1,105, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 0, 29, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 0,142, + 0, 0, 0, 35, 0, 0, 1,107, 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 1,107, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 1,108, + 0, 0, 0, 30, 0, 0, 0, 35, 0, 0, 1,108, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 0, 35, + 0, 0, 1,109, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 0, 31, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 0,144, + 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 0,144, 0, 0, 0, 35, 0, 0, 1,112, + 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 1,113, 0, 0, 0, 31, 0, 0, 0, 35, + 0, 0, 1,113, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 0, 22, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 0,146, + 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 1,116, + 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 1,116, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 0, 38, 0, 0, 0, 35, + 0, 0, 1,117, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 0, 32, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 0,148, + 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 1,120, + 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 1,120, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 1,121, 0, 0, 0, 38, 0, 0, 0, 35, + 0, 0, 1,121, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 0,150, + 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 0,150, 0, 0, 0, 35, 0, 0, 1,124, + 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 0, 38, 0, 0, 0, 35, + 0, 0, 1,125, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 1,126, 0, 0, 0, 38, 0, 0, 0, 35, 0, 0, 1,126, 0, 0, 0,152, + 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 1,128, + 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 1,128, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 0, 40, 0, 0, 0, 35, + 0, 0, 1,129, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 0,154, + 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 1,132, + 0, 0, 0, 39, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 0, 40, 0, 0, 0, 35, + 0, 0, 1,133, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 0,156, + 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 1,136, + 0, 0, 0, 35, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 0, 40, 0, 0, 0, 35, + 0, 0, 1,137, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 0,158, + 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 1,140, + 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 0, 37, 0, 0, 0, 35, + 0, 0, 1,141, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 0,160, + 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 0, 41, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 1,144, + 0, 0, 0, 37, 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 1,145, 0, 0, 0, 41, 0, 0, 0, 35, + 0, 0, 1,145, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 0,102, + 0, 0, 0, 35, 0, 0, 1,147, 0, 0, 0, 43, 0, 0, 0, 33, 0, 0, 1,147, 0, 0, 0, 46, 0, 0, 0, 33, 0, 0, 1,148, + 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 1,148, 0, 0, 0,102, 0, 0, 0, 35, 0, 0, 1,149, 0, 0, 0,102, 0, 0, 0, 35, + 0, 0, 1,149, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1,150, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1,150, 0, 0, 0,104, + 0, 0, 0, 35, 0, 0, 1,151, 0, 0, 0,102, 0, 0, 0, 35, 0, 0, 1,151, 0, 0, 0,104, 0, 0, 0, 35, 0, 0, 1,152, + 0, 0, 0, 45, 0, 0, 0, 33, 0, 0, 1,152, 0, 0, 0, 47, 0, 0, 0, 33, 0, 0, 1,153, 0, 0, 0, 47, 0, 0, 0, 35, + 0, 0, 1,153, 0, 0, 0,104, 0, 0, 0, 35, 0, 0, 1,154, 0, 0, 0, 45, 0, 0, 0, 35, 0, 0, 1,154, 0, 0, 0,104, + 0, 0, 0, 35, 0, 0, 1,155, 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 1,155, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1,156, + 0, 0, 0, 42, 0, 0, 0, 35, 0, 0, 1,156, 0, 0, 0,103, 0, 0, 0, 35, 0, 0, 1,157, 0, 0, 0, 42, 0, 0, 0, 33, + 0, 0, 1,157, 0, 0, 0, 44, 0, 0, 0, 33, 0, 0, 1,158, 0, 0, 0, 50, 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 0,105, + 0, 0, 0, 35, 0, 0, 1,159, 0, 0, 0, 43, 0, 0, 0, 33, 0, 0, 1,159, 0, 0, 0, 50, 0, 0, 0, 33, 0, 0, 1,160, + 0, 0, 0, 43, 0, 0, 0, 35, 0, 0, 1,160, 0, 0, 0,105, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 0,105, 0, 0, 0, 35, + 0, 0, 1,161, 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 1,162, 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 1,162, 0, 0, 0,107, + 0, 0, 0, 35, 0, 0, 1,163, 0, 0, 0,105, 0, 0, 0, 35, 0, 0, 1,163, 0, 0, 0,107, 0, 0, 0, 35, 0, 0, 1,164, + 0, 0, 0, 49, 0, 0, 0, 33, 0, 0, 1,164, 0, 0, 0, 51, 0, 0, 0, 33, 0, 0, 1,165, 0, 0, 0, 51, 0, 0, 0, 35, + 0, 0, 1,165, 0, 0, 0,107, 0, 0, 0, 35, 0, 0, 1,166, 0, 0, 0, 49, 0, 0, 0, 35, 0, 0, 1,166, 0, 0, 0,107, + 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 0, 48, 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 1,168, + 0, 0, 0, 42, 0, 0, 0, 35, 0, 0, 1,168, 0, 0, 0,106, 0, 0, 0, 35, 0, 0, 1,169, 0, 0, 0, 42, 0, 0, 0, 33, + 0, 0, 1,169, 0, 0, 0, 48, 0, 0, 0, 33, 0, 0, 1,170, 0, 0, 0, 54, 0, 0, 0, 35, 0, 0, 1,170, 0, 0, 0,108, + 0, 0, 0, 35, 0, 0, 1,171, 0, 0, 0, 45, 0, 0, 0, 33, 0, 0, 1,171, 0, 0, 0, 54, 0, 0, 0, 33, 0, 0, 1,172, + 0, 0, 0, 45, 0, 0, 0, 35, 0, 0, 1,172, 0, 0, 0,108, 0, 0, 0, 35, 0, 0, 1,173, 0, 0, 0,108, 0, 0, 0, 35, + 0, 0, 1,173, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1,174, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1,174, 0, 0, 0,110, + 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 0,108, 0, 0, 0, 35, 0, 0, 1,175, 0, 0, 0,110, 0, 0, 0, 35, 0, 0, 1,176, + 0, 0, 0, 53, 0, 0, 0, 33, 0, 0, 1,176, 0, 0, 0, 55, 0, 0, 0, 33, 0, 0, 1,177, 0, 0, 0, 55, 0, 0, 0, 35, + 0, 0, 1,177, 0, 0, 0,110, 0, 0, 0, 35, 0, 0, 1,178, 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 1,178, 0, 0, 0,110, + 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1,180, + 0, 0, 0, 44, 0, 0, 0, 35, 0, 0, 1,180, 0, 0, 0,109, 0, 0, 0, 35, 0, 0, 1,181, 0, 0, 0, 44, 0, 0, 0, 33, + 0, 0, 1,181, 0, 0, 0, 52, 0, 0, 0, 33, 0, 0, 1,182, 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 1,182, 0, 0, 0,111, + 0, 0, 0, 35, 0, 0, 1,183, 0, 0, 0, 53, 0, 0, 0, 33, 0, 0, 1,183, 0, 0, 0, 58, 0, 0, 0, 33, 0, 0, 1,184, + 0, 0, 0, 53, 0, 0, 0, 35, 0, 0, 1,184, 0, 0, 0,111, 0, 0, 0, 35, 0, 0, 1,185, 0, 0, 0,111, 0, 0, 0, 35, + 0, 0, 1,185, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 1,186, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 1,186, 0, 0, 0,113, + 0, 0, 0, 35, 0, 0, 1,187, 0, 0, 0,111, 0, 0, 0, 35, 0, 0, 1,187, 0, 0, 0,113, 0, 0, 0, 35, 0, 0, 1,188, + 0, 0, 0, 57, 0, 0, 0, 33, 0, 0, 1,188, 0, 0, 0, 59, 0, 0, 0, 33, 0, 0, 1,189, 0, 0, 0, 59, 0, 0, 0, 35, + 0, 0, 1,189, 0, 0, 0,113, 0, 0, 0, 35, 0, 0, 1,190, 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 1,190, 0, 0, 0,113, + 0, 0, 0, 35, 0, 0, 1,191, 0, 0, 0, 56, 0, 0, 0, 35, 0, 0, 1,191, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 1,192, + 0, 0, 0, 52, 0, 0, 0, 35, 0, 0, 1,192, 0, 0, 0,112, 0, 0, 0, 35, 0, 0, 1,193, 0, 0, 0, 52, 0, 0, 0, 33, + 0, 0, 1,193, 0, 0, 0, 56, 0, 0, 0, 33, 0, 0, 1,194, 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 1,194, 0, 0, 0,114, + 0, 0, 0, 35, 0, 0, 1,195, 0, 0, 0, 57, 0, 0, 0, 33, 0, 0, 1,195, 0, 0, 0, 60, 0, 0, 0, 33, 0, 0, 1,196, + 0, 0, 0, 57, 0, 0, 0, 35, 0, 0, 1,196, 0, 0, 0,114, 0, 0, 0, 35, 0, 0, 1,197, 0, 0, 0,114, 0, 0, 0, 35, + 0, 0, 1,197, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 0,116, + 0, 0, 0, 35, 0, 0, 1,199, 0, 0, 0,114, 0, 0, 0, 35, 0, 0, 1,199, 0, 0, 0,116, 0, 0, 0, 35, 0, 0, 1,200, + 0, 0, 0, 49, 0, 0, 0, 33, 0, 0, 1,200, 0, 0, 0, 61, 0, 0, 0, 33, 0, 0, 1,201, 0, 0, 0, 61, 0, 0, 0, 35, + 0, 0, 1,201, 0, 0, 0,116, 0, 0, 0, 35, 0, 0, 1,202, 0, 0, 0, 49, 0, 0, 0, 35, 0, 0, 1,202, 0, 0, 0,116, + 0, 0, 0, 35, 0, 0, 1,203, 0, 0, 0, 48, 0, 0, 0, 35, 0, 0, 1,203, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1,204, + 0, 0, 0, 56, 0, 0, 0, 35, 0, 0, 1,204, 0, 0, 0,115, 0, 0, 0, 35, 0, 0, 1,205, 0, 0, 0, 48, 0, 0, 0, 33, + 0, 0, 1,205, 0, 0, 0, 56, 0, 0, 0, 33, 0, 0, 1,206, 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 1,206, 0, 0, 0,117, + 0, 0, 0, 35, 0, 0, 1,207, 0, 0, 0, 50, 0, 0, 0, 33, 0, 0, 1,207, 0, 0, 0, 64, 0, 0, 0, 33, 0, 0, 1,208, + 0, 0, 0, 50, 0, 0, 0, 35, 0, 0, 1,208, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 1,209, 0, 0, 0,117, 0, 0, 0, 35, + 0, 0, 1,209, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 1,210, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 1,210, 0, 0, 0,119, + 0, 0, 0, 35, 0, 0, 1,211, 0, 0, 0,117, 0, 0, 0, 35, 0, 0, 1,211, 0, 0, 0,119, 0, 0, 0, 35, 0, 0, 1,212, + 0, 0, 0, 63, 0, 0, 0, 33, 0, 0, 1,212, 0, 0, 0, 65, 0, 0, 0, 33, 0, 0, 1,213, 0, 0, 0, 65, 0, 0, 0, 35, + 0, 0, 1,213, 0, 0, 0,119, 0, 0, 0, 35, 0, 0, 1,214, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 1,214, 0, 0, 0,119, + 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 1,216, + 0, 0, 0, 51, 0, 0, 0, 35, 0, 0, 1,216, 0, 0, 0,118, 0, 0, 0, 35, 0, 0, 1,217, 0, 0, 0, 51, 0, 0, 0, 33, + 0, 0, 1,217, 0, 0, 0, 62, 0, 0, 0, 33, 0, 0, 1,218, 0, 0, 0, 68, 0, 0, 0, 35, 0, 0, 1,218, 0, 0, 0,120, + 0, 0, 0, 35, 0, 0, 1,219, 0, 0, 0, 47, 0, 0, 0, 33, 0, 0, 1,219, 0, 0, 0, 68, 0, 0, 0, 33, 0, 0, 1,220, + 0, 0, 0, 47, 0, 0, 0, 35, 0, 0, 1,220, 0, 0, 0,120, 0, 0, 0, 35, 0, 0, 1,221, 0, 0, 0,120, 0, 0, 0, 35, + 0, 0, 1,221, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1,222, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1,222, 0, 0, 0,122, + 0, 0, 0, 35, 0, 0, 1,223, 0, 0, 0,120, 0, 0, 0, 35, 0, 0, 1,223, 0, 0, 0,122, 0, 0, 0, 35, 0, 0, 1,224, + 0, 0, 0, 67, 0, 0, 0, 33, 0, 0, 1,224, 0, 0, 0, 69, 0, 0, 0, 33, 0, 0, 1,225, 0, 0, 0, 69, 0, 0, 0, 35, + 0, 0, 1,225, 0, 0, 0,122, 0, 0, 0, 35, 0, 0, 1,226, 0, 0, 0, 67, 0, 0, 0, 35, 0, 0, 1,226, 0, 0, 0,122, + 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 0, 66, 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1,228, + 0, 0, 0, 46, 0, 0, 0, 35, 0, 0, 1,228, 0, 0, 0,121, 0, 0, 0, 35, 0, 0, 1,229, 0, 0, 0, 46, 0, 0, 0, 33, + 0, 0, 1,229, 0, 0, 0, 66, 0, 0, 0, 33, 0, 0, 1,230, 0, 0, 0, 72, 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 0,123, + 0, 0, 0, 35, 0, 0, 1,231, 0, 0, 0, 55, 0, 0, 0, 33, 0, 0, 1,231, 0, 0, 0, 72, 0, 0, 0, 33, 0, 0, 1,232, + 0, 0, 0, 55, 0, 0, 0, 35, 0, 0, 1,232, 0, 0, 0,123, 0, 0, 0, 35, 0, 0, 1,233, 0, 0, 0,123, 0, 0, 0, 35, + 0, 0, 1,233, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 1,234, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 1,234, 0, 0, 0,125, + 0, 0, 0, 35, 0, 0, 1,235, 0, 0, 0,123, 0, 0, 0, 35, 0, 0, 1,235, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 1,236, + 0, 0, 0, 71, 0, 0, 0, 33, 0, 0, 1,236, 0, 0, 0, 73, 0, 0, 0, 33, 0, 0, 1,237, 0, 0, 0, 73, 0, 0, 0, 35, + 0, 0, 1,237, 0, 0, 0,125, 0, 0, 0, 35, 0, 0, 1,238, 0, 0, 0, 71, 0, 0, 0, 35, 0, 0, 1,238, 0, 0, 0,125, + 0, 0, 0, 35, 0, 0, 1,239, 0, 0, 0, 70, 0, 0, 0, 35, 0, 0, 1,239, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 1,240, + 0, 0, 0, 54, 0, 0, 0, 35, 0, 0, 1,240, 0, 0, 0,124, 0, 0, 0, 35, 0, 0, 1,241, 0, 0, 0, 54, 0, 0, 0, 33, + 0, 0, 1,241, 0, 0, 0, 70, 0, 0, 0, 33, 0, 0, 1,242, 0, 0, 0, 76, 0, 0, 0, 35, 0, 0, 1,242, 0, 0, 0,126, + 0, 0, 0, 35, 0, 0, 1,243, 0, 0, 0, 59, 0, 0, 0, 33, 0, 0, 1,243, 0, 0, 0, 76, 0, 0, 0, 33, 0, 0, 1,244, + 0, 0, 0, 59, 0, 0, 0, 35, 0, 0, 1,244, 0, 0, 0,126, 0, 0, 0, 35, 0, 0, 1,245, 0, 0, 0,126, 0, 0, 0, 35, + 0, 0, 1,245, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1,246, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1,246, 0, 0, 0,128, + 0, 0, 0, 35, 0, 0, 1,247, 0, 0, 0,126, 0, 0, 0, 35, 0, 0, 1,247, 0, 0, 0,128, 0, 0, 0, 35, 0, 0, 1,248, + 0, 0, 0, 75, 0, 0, 0, 33, 0, 0, 1,248, 0, 0, 0, 77, 0, 0, 0, 33, 0, 0, 1,249, 0, 0, 0, 77, 0, 0, 0, 35, + 0, 0, 1,249, 0, 0, 0,128, 0, 0, 0, 35, 0, 0, 1,250, 0, 0, 0, 75, 0, 0, 0, 35, 0, 0, 1,250, 0, 0, 0,128, + 0, 0, 0, 35, 0, 0, 1,251, 0, 0, 0, 74, 0, 0, 0, 35, 0, 0, 1,251, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1,252, + 0, 0, 0, 58, 0, 0, 0, 35, 0, 0, 1,252, 0, 0, 0,127, 0, 0, 0, 35, 0, 0, 1,253, 0, 0, 0, 58, 0, 0, 0, 33, + 0, 0, 1,253, 0, 0, 0, 74, 0, 0, 0, 33, 0, 0, 1,254, 0, 0, 0, 80, 0, 0, 0, 35, 0, 0, 1,254, 0, 0, 0,129, + 0, 0, 0, 35, 0, 0, 1,255, 0, 0, 0, 61, 0, 0, 0, 33, 0, 0, 1,255, 0, 0, 0, 80, 0, 0, 0, 33, 0, 0, 2, 0, + 0, 0, 0, 61, 0, 0, 0, 35, 0, 0, 2, 0, 0, 0, 0,129, 0, 0, 0, 35, 0, 0, 2, 1, 0, 0, 0,129, 0, 0, 0, 35, + 0, 0, 2, 1, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 2, 2, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 2, 2, 0, 0, 0,131, + 0, 0, 0, 35, 0, 0, 2, 3, 0, 0, 0,129, 0, 0, 0, 35, 0, 0, 2, 3, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 2, 4, + 0, 0, 0, 79, 0, 0, 0, 33, 0, 0, 2, 4, 0, 0, 0, 81, 0, 0, 0, 33, 0, 0, 2, 5, 0, 0, 0, 81, 0, 0, 0, 35, + 0, 0, 2, 5, 0, 0, 0,131, 0, 0, 0, 35, 0, 0, 2, 6, 0, 0, 0, 79, 0, 0, 0, 35, 0, 0, 2, 6, 0, 0, 0,131, + 0, 0, 0, 35, 0, 0, 2, 7, 0, 0, 0, 78, 0, 0, 0, 35, 0, 0, 2, 7, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 2, 8, + 0, 0, 0, 60, 0, 0, 0, 35, 0, 0, 2, 8, 0, 0, 0,130, 0, 0, 0, 35, 0, 0, 2, 9, 0, 0, 0, 60, 0, 0, 0, 33, + 0, 0, 2, 9, 0, 0, 0, 78, 0, 0, 0, 33, 0, 0, 2, 10, 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 2, 10, 0, 0, 0,132, + 0, 0, 0, 35, 0, 0, 2, 11, 0, 0, 0, 65, 0, 0, 0, 33, 0, 0, 2, 11, 0, 0, 0, 83, 0, 0, 0, 33, 0, 0, 2, 12, + 0, 0, 0, 65, 0, 0, 0, 35, 0, 0, 2, 12, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 2, 13, 0, 0, 0,132, 0, 0, 0, 35, + 0, 0, 2, 13, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 2, 14, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 2, 14, 0, 0, 0,134, + 0, 0, 0, 35, 0, 0, 2, 15, 0, 0, 0,132, 0, 0, 0, 35, 0, 0, 2, 15, 0, 0, 0,134, 0, 0, 0, 35, 0, 0, 2, 16, + 0, 0, 0, 67, 0, 0, 0, 33, 0, 0, 2, 16, 0, 0, 0, 82, 0, 0, 0, 33, 0, 0, 2, 17, 0, 0, 0, 82, 0, 0, 0, 35, + 0, 0, 2, 17, 0, 0, 0,134, 0, 0, 0, 35, 0, 0, 2, 18, 0, 0, 0, 67, 0, 0, 0, 35, 0, 0, 2, 18, 0, 0, 0,134, + 0, 0, 0, 35, 0, 0, 2, 19, 0, 0, 0, 66, 0, 0, 0, 35, 0, 0, 2, 19, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 2, 20, + 0, 0, 0, 64, 0, 0, 0, 35, 0, 0, 2, 20, 0, 0, 0,133, 0, 0, 0, 35, 0, 0, 2, 21, 0, 0, 0, 64, 0, 0, 0, 33, + 0, 0, 2, 21, 0, 0, 0, 66, 0, 0, 0, 33, 0, 0, 2, 22, 0, 0, 0, 84, 0, 0, 0, 35, 0, 0, 2, 22, 0, 0, 0,135, + 0, 0, 0, 35, 0, 0, 2, 23, 0, 0, 0, 69, 0, 0, 0, 33, 0, 0, 2, 23, 0, 0, 0, 84, 0, 0, 0, 33, 0, 0, 2, 24, + 0, 0, 0, 69, 0, 0, 0, 35, 0, 0, 2, 24, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 2, 25, 0, 0, 0,135, 0, 0, 0, 35, + 0, 0, 2, 25, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 2, 26, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 2, 26, 0, 0, 0,137, + 0, 0, 0, 35, 0, 0, 2, 27, 0, 0, 0,135, 0, 0, 0, 35, 0, 0, 2, 27, 0, 0, 0,137, 0, 0, 0, 35, 0, 0, 2, 28, + 0, 0, 0, 71, 0, 0, 0, 33, 0, 0, 2, 28, 0, 0, 0, 85, 0, 0, 0, 33, 0, 0, 2, 29, 0, 0, 0, 85, 0, 0, 0, 35, + 0, 0, 2, 29, 0, 0, 0,137, 0, 0, 0, 35, 0, 0, 2, 30, 0, 0, 0, 71, 0, 0, 0, 35, 0, 0, 2, 30, 0, 0, 0,137, + 0, 0, 0, 35, 0, 0, 2, 31, 0, 0, 0, 70, 0, 0, 0, 35, 0, 0, 2, 31, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 2, 32, + 0, 0, 0, 68, 0, 0, 0, 35, 0, 0, 2, 32, 0, 0, 0,136, 0, 0, 0, 35, 0, 0, 2, 33, 0, 0, 0, 68, 0, 0, 0, 33, + 0, 0, 2, 33, 0, 0, 0, 70, 0, 0, 0, 33, 0, 0, 2, 34, 0, 0, 0, 86, 0, 0, 0, 35, 0, 0, 2, 34, 0, 0, 0,138, + 0, 0, 0, 35, 0, 0, 2, 35, 0, 0, 0, 73, 0, 0, 0, 33, 0, 0, 2, 35, 0, 0, 0, 86, 0, 0, 0, 33, 0, 0, 2, 36, + 0, 0, 0, 73, 0, 0, 0, 35, 0, 0, 2, 36, 0, 0, 0,138, 0, 0, 0, 35, 0, 0, 2, 37, 0, 0, 0,138, 0, 0, 0, 35, + 0, 0, 2, 37, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 2, 38, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 2, 38, 0, 0, 0,140, + 0, 0, 0, 35, 0, 0, 2, 39, 0, 0, 0,138, 0, 0, 0, 35, 0, 0, 2, 39, 0, 0, 0,140, 0, 0, 0, 35, 0, 0, 2, 40, + 0, 0, 0, 75, 0, 0, 0, 33, 0, 0, 2, 40, 0, 0, 0, 87, 0, 0, 0, 33, 0, 0, 2, 41, 0, 0, 0, 87, 0, 0, 0, 35, + 0, 0, 2, 41, 0, 0, 0,140, 0, 0, 0, 35, 0, 0, 2, 42, 0, 0, 0, 75, 0, 0, 0, 35, 0, 0, 2, 42, 0, 0, 0,140, + 0, 0, 0, 35, 0, 0, 2, 43, 0, 0, 0, 74, 0, 0, 0, 35, 0, 0, 2, 43, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 2, 44, + 0, 0, 0, 72, 0, 0, 0, 35, 0, 0, 2, 44, 0, 0, 0,139, 0, 0, 0, 35, 0, 0, 2, 45, 0, 0, 0, 72, 0, 0, 0, 33, + 0, 0, 2, 45, 0, 0, 0, 74, 0, 0, 0, 33, 0, 0, 2, 46, 0, 0, 0, 88, 0, 0, 0, 35, 0, 0, 2, 46, 0, 0, 0,141, + 0, 0, 0, 35, 0, 0, 2, 47, 0, 0, 0, 77, 0, 0, 0, 33, 0, 0, 2, 47, 0, 0, 0, 88, 0, 0, 0, 33, 0, 0, 2, 48, + 0, 0, 0, 77, 0, 0, 0, 35, 0, 0, 2, 48, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 2, 49, 0, 0, 0,141, 0, 0, 0, 35, + 0, 0, 2, 49, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 2, 50, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 2, 50, 0, 0, 0,143, + 0, 0, 0, 35, 0, 0, 2, 51, 0, 0, 0,141, 0, 0, 0, 35, 0, 0, 2, 51, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 2, 52, + 0, 0, 0, 79, 0, 0, 0, 33, 0, 0, 2, 52, 0, 0, 0, 89, 0, 0, 0, 33, 0, 0, 2, 53, 0, 0, 0, 89, 0, 0, 0, 35, + 0, 0, 2, 53, 0, 0, 0,143, 0, 0, 0, 35, 0, 0, 2, 54, 0, 0, 0, 79, 0, 0, 0, 35, 0, 0, 2, 54, 0, 0, 0,143, + 0, 0, 0, 35, 0, 0, 2, 55, 0, 0, 0, 78, 0, 0, 0, 35, 0, 0, 2, 55, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 2, 56, + 0, 0, 0, 76, 0, 0, 0, 35, 0, 0, 2, 56, 0, 0, 0,142, 0, 0, 0, 35, 0, 0, 2, 57, 0, 0, 0, 76, 0, 0, 0, 33, + 0, 0, 2, 57, 0, 0, 0, 78, 0, 0, 0, 33, 0, 0, 2, 58, 0, 0, 0, 90, 0, 0, 0, 35, 0, 0, 2, 58, 0, 0, 0,144, + 0, 0, 0, 35, 0, 0, 2, 59, 0, 0, 0, 81, 0, 0, 0, 33, 0, 0, 2, 59, 0, 0, 0, 90, 0, 0, 0, 33, 0, 0, 2, 60, + 0, 0, 0, 81, 0, 0, 0, 35, 0, 0, 2, 60, 0, 0, 0,144, 0, 0, 0, 35, 0, 0, 2, 61, 0, 0, 0,144, 0, 0, 0, 35, + 0, 0, 2, 61, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 2, 62, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 2, 62, 0, 0, 0,146, + 0, 0, 0, 35, 0, 0, 2, 63, 0, 0, 0,144, 0, 0, 0, 35, 0, 0, 2, 63, 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 2, 64, + 0, 0, 0, 63, 0, 0, 0, 33, 0, 0, 2, 64, 0, 0, 0, 91, 0, 0, 0, 33, 0, 0, 2, 65, 0, 0, 0, 91, 0, 0, 0, 35, + 0, 0, 2, 65, 0, 0, 0,146, 0, 0, 0, 35, 0, 0, 2, 66, 0, 0, 0, 63, 0, 0, 0, 35, 0, 0, 2, 66, 0, 0, 0,146, + 0, 0, 0, 35, 0, 0, 2, 67, 0, 0, 0, 62, 0, 0, 0, 35, 0, 0, 2, 67, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 2, 68, + 0, 0, 0, 80, 0, 0, 0, 35, 0, 0, 2, 68, 0, 0, 0,145, 0, 0, 0, 35, 0, 0, 2, 69, 0, 0, 0, 62, 0, 0, 0, 33, + 0, 0, 2, 69, 0, 0, 0, 80, 0, 0, 0, 33, 0, 0, 2, 70, 0, 0, 0, 94, 0, 0, 0, 35, 0, 0, 2, 70, 0, 0, 0,147, + 0, 0, 0, 35, 0, 0, 2, 71, 0, 0, 0, 82, 0, 0, 0, 33, 0, 0, 2, 71, 0, 0, 0, 94, 0, 0, 0, 33, 0, 0, 2, 72, + 0, 0, 0, 82, 0, 0, 0, 35, 0, 0, 2, 72, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 2, 73, 0, 0, 0,147, 0, 0, 0, 35, + 0, 0, 2, 73, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 2, 74, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 2, 74, 0, 0, 0,149, + 0, 0, 0, 35, 0, 0, 2, 75, 0, 0, 0,147, 0, 0, 0, 35, 0, 0, 2, 75, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 2, 76, + 0, 0, 0, 93, 0, 0, 0, 33, 0, 0, 2, 76, 0, 0, 0, 95, 0, 0, 0, 33, 0, 0, 2, 77, 0, 0, 0, 95, 0, 0, 0, 35, + 0, 0, 2, 77, 0, 0, 0,149, 0, 0, 0, 35, 0, 0, 2, 78, 0, 0, 0, 93, 0, 0, 0, 35, 0, 0, 2, 78, 0, 0, 0,149, + 0, 0, 0, 35, 0, 0, 2, 79, 0, 0, 0, 92, 0, 0, 0, 35, 0, 0, 2, 79, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 2, 80, + 0, 0, 0, 83, 0, 0, 0, 35, 0, 0, 2, 80, 0, 0, 0,148, 0, 0, 0, 35, 0, 0, 2, 81, 0, 0, 0, 83, 0, 0, 0, 33, + 0, 0, 2, 81, 0, 0, 0, 92, 0, 0, 0, 33, 0, 0, 2, 82, 0, 0, 0, 96, 0, 0, 0, 35, 0, 0, 2, 82, 0, 0, 0,150, + 0, 0, 0, 35, 0, 0, 2, 83, 0, 0, 0, 85, 0, 0, 0, 33, 0, 0, 2, 83, 0, 0, 0, 96, 0, 0, 0, 33, 0, 0, 2, 84, + 0, 0, 0, 85, 0, 0, 0, 35, 0, 0, 2, 84, 0, 0, 0,150, 0, 0, 0, 35, 0, 0, 2, 85, 0, 0, 0,150, 0, 0, 0, 35, + 0, 0, 2, 85, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 2, 86, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 2, 86, 0, 0, 0,152, + 0, 0, 0, 35, 0, 0, 2, 87, 0, 0, 0,150, 0, 0, 0, 35, 0, 0, 2, 87, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 2, 88, + 0, 0, 0, 95, 0, 0, 0, 33, 0, 0, 2, 88, 0, 0, 0, 97, 0, 0, 0, 33, 0, 0, 2, 89, 0, 0, 0, 97, 0, 0, 0, 35, + 0, 0, 2, 89, 0, 0, 0,152, 0, 0, 0, 35, 0, 0, 2, 90, 0, 0, 0, 95, 0, 0, 0, 35, 0, 0, 2, 90, 0, 0, 0,152, + 0, 0, 0, 35, 0, 0, 2, 91, 0, 0, 0, 94, 0, 0, 0, 35, 0, 0, 2, 91, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 2, 92, + 0, 0, 0, 84, 0, 0, 0, 35, 0, 0, 2, 92, 0, 0, 0,151, 0, 0, 0, 35, 0, 0, 2, 93, 0, 0, 0, 84, 0, 0, 0, 33, + 0, 0, 2, 93, 0, 0, 0, 94, 0, 0, 0, 33, 0, 0, 2, 94, 0, 0, 0, 98, 0, 0, 0, 35, 0, 0, 2, 94, 0, 0, 0,153, + 0, 0, 0, 35, 0, 0, 2, 95, 0, 0, 0, 87, 0, 0, 0, 33, 0, 0, 2, 95, 0, 0, 0, 98, 0, 0, 0, 33, 0, 0, 2, 96, + 0, 0, 0, 87, 0, 0, 0, 35, 0, 0, 2, 96, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 2, 97, 0, 0, 0,153, 0, 0, 0, 35, + 0, 0, 2, 97, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 2, 98, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 2, 98, 0, 0, 0,155, + 0, 0, 0, 35, 0, 0, 2, 99, 0, 0, 0,153, 0, 0, 0, 35, 0, 0, 2, 99, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 2,100, + 0, 0, 0, 97, 0, 0, 0, 33, 0, 0, 2,100, 0, 0, 0, 99, 0, 0, 0, 33, 0, 0, 2,101, 0, 0, 0, 99, 0, 0, 0, 35, + 0, 0, 2,101, 0, 0, 0,155, 0, 0, 0, 35, 0, 0, 2,102, 0, 0, 0, 97, 0, 0, 0, 35, 0, 0, 2,102, 0, 0, 0,155, + 0, 0, 0, 35, 0, 0, 2,103, 0, 0, 0, 96, 0, 0, 0, 35, 0, 0, 2,103, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 2,104, + 0, 0, 0, 86, 0, 0, 0, 35, 0, 0, 2,104, 0, 0, 0,154, 0, 0, 0, 35, 0, 0, 2,105, 0, 0, 0, 86, 0, 0, 0, 33, + 0, 0, 2,105, 0, 0, 0, 96, 0, 0, 0, 33, 0, 0, 2,106, 0, 0, 0,100, 0, 0, 0, 35, 0, 0, 2,106, 0, 0, 0,156, + 0, 0, 0, 35, 0, 0, 2,107, 0, 0, 0, 89, 0, 0, 0, 33, 0, 0, 2,107, 0, 0, 0,100, 0, 0, 0, 33, 0, 0, 2,108, + 0, 0, 0, 89, 0, 0, 0, 35, 0, 0, 2,108, 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 2,109, 0, 0, 0,156, 0, 0, 0, 35, + 0, 0, 2,109, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 2,110, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 2,110, 0, 0, 0,158, + 0, 0, 0, 35, 0, 0, 2,111, 0, 0, 0,156, 0, 0, 0, 35, 0, 0, 2,111, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 2,112, + 0, 0, 0, 99, 0, 0, 0, 33, 0, 0, 2,112, 0, 0, 0,101, 0, 0, 0, 33, 0, 0, 2,113, 0, 0, 0,101, 0, 0, 0, 35, + 0, 0, 2,113, 0, 0, 0,158, 0, 0, 0, 35, 0, 0, 2,114, 0, 0, 0, 99, 0, 0, 0, 35, 0, 0, 2,114, 0, 0, 0,158, + 0, 0, 0, 35, 0, 0, 2,115, 0, 0, 0, 98, 0, 0, 0, 35, 0, 0, 2,115, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 2,116, + 0, 0, 0, 88, 0, 0, 0, 35, 0, 0, 2,116, 0, 0, 0,157, 0, 0, 0, 35, 0, 0, 2,117, 0, 0, 0, 88, 0, 0, 0, 33, + 0, 0, 2,117, 0, 0, 0, 98, 0, 0, 0, 33, 0, 0, 2,118, 0, 0, 0, 92, 0, 0, 0, 35, 0, 0, 2,118, 0, 0, 0,159, + 0, 0, 0, 35, 0, 0, 2,119, 0, 0, 0, 91, 0, 0, 0, 33, 0, 0, 2,119, 0, 0, 0, 92, 0, 0, 0, 33, 0, 0, 2,120, + 0, 0, 0, 91, 0, 0, 0, 35, 0, 0, 2,120, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 2,121, 0, 0, 0,159, 0, 0, 0, 35, + 0, 0, 2,121, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 2,122, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 2,122, 0, 0, 0,161, + 0, 0, 0, 35, 0, 0, 2,123, 0, 0, 0,159, 0, 0, 0, 35, 0, 0, 2,123, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 2,124, + 0, 0, 0, 93, 0, 0, 0, 33, 0, 0, 2,124, 0, 0, 0,101, 0, 0, 0, 33, 0, 0, 2,125, 0, 0, 0, 93, 0, 0, 0, 35, + 0, 0, 2,125, 0, 0, 0,161, 0, 0, 0, 35, 0, 0, 2,126, 0, 0, 0,101, 0, 0, 0, 35, 0, 0, 2,126, 0, 0, 0,161, + 0, 0, 0, 35, 0, 0, 2,127, 0, 0, 0,100, 0, 0, 0, 35, 0, 0, 2,127, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 2,128, + 0, 0, 0, 90, 0, 0, 0, 35, 0, 0, 2,128, 0, 0, 0,160, 0, 0, 0, 35, 0, 0, 2,129, 0, 0, 0, 90, 0, 0, 0, 33, + 0, 0, 2,129, 0, 0, 0,100, 0, 0, 0, 33, 0, 0, 1, 27, 0, 0, 1,146, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1,146, + 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1, 27, 0, 0, 0, 35, 0, 0, 1,146, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1,146, + 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 1,147, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1, 26, 0, 0, 0, 35, + 0, 0, 0,165, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 1,148, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 1,147, + 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 1,147, 0, 0, 0, 35, 0, 0, 1, 26, + 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1, 28, 0, 0, 1,149, 0, 0, 0, 35, 0, 0, 1, 26, 0, 0, 1, 28, 0, 0, 0, 35, + 0, 0, 1,149, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1,150, 0, 0, 1,151, + 0, 0, 0, 35, 0, 0, 1, 27, 0, 0, 1, 31, 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1, 27, + 0, 0, 1,151, 0, 0, 0, 35, 0, 0, 1, 30, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 1, 30, 0, 0, 0, 35, + 0, 0, 1, 29, 0, 0, 1,150, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 1,152, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 1,152, + 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,172, 0, 0, 0, 35, 0, 0, 1,152, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 1,152, + 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 1,153, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1, 30, 0, 0, 0, 35, + 0, 0, 1, 30, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1,154, 0, 0, 0, 35, 0, 0, 1, 31, 0, 0, 1,153, + 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1, 31, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1,153, 0, 0, 0, 35, 0, 0, 0,167, + 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 1, 29, 0, 0, 1,155, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1, 29, 0, 0, 0, 35, + 0, 0, 1,155, 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 1,155, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 1,156, 0, 0, 1,157, + 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,166, 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 0,166, + 0, 0, 1,157, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 1, 28, 0, 0, 0, 35, + 0, 0, 1, 28, 0, 0, 1,156, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1, 33, + 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1,158, 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 1,159, 0, 0, 0, 35, 0, 0, 1,159, + 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 1,158, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1, 32, 0, 0, 0, 35, + 0, 0, 1, 32, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,165, 0, 0, 1,160, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 1,159, + 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 1,159, 0, 0, 0, 35, 0, 0, 0,164, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 1, 32, + 0, 0, 1,161, 0, 0, 0, 35, 0, 0, 1, 32, 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 1,161, 0, 0, 0, 35, + 0, 0, 1,161, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 1,162, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1,161, 0, 0, 1,163, + 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 1, 33, 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1, 37, + 0, 0, 1,163, 0, 0, 0, 35, 0, 0, 1, 36, 0, 0, 1,162, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1,162, 0, 0, 0, 35, + 0, 0, 1, 35, 0, 0, 1, 36, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 1,164, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 0,180, + 0, 0, 0, 35, 0, 0, 0,180, 0, 0, 1,164, 0, 0, 0, 35, 0, 0, 1,164, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 1,165, + 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1,164, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1, 36, 0, 0, 0, 35, + 0, 0, 0,177, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1, 36, 0, 0, 1,166, 0, 0, 0, 35, 0, 0, 1, 37, 0, 0, 1,165, + 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1,165, 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1, 37, 0, 0, 0, 35, 0, 0, 0,175, + 0, 0, 1,167, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 1, 35, 0, 0, 0, 35, 0, 0, 1, 35, 0, 0, 1,167, 0, 0, 0, 35, + 0, 0, 1,167, 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 1,168, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 1,167, 0, 0, 1,169, + 0, 0, 0, 35, 0, 0, 0,162, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,174, 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 0,162, + 0, 0, 1,169, 0, 0, 0, 35, 0, 0, 0,163, 0, 0, 1,168, 0, 0, 0, 35, 0, 0, 1, 34, 0, 0, 1,168, 0, 0, 0, 35, + 0, 0, 0,163, 0, 0, 1, 34, 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 1,170, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1,170, + 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1, 39, 0, 0, 0, 35, 0, 0, 1,170, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1,170, + 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 1,171, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,169, 0, 0, 1, 38, 0, 0, 0, 35, + 0, 0, 0,169, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 1,172, 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 1,171, + 0, 0, 0, 35, 0, 0, 0,168, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0,186, 0, 0, 1,171, 0, 0, 0, 35, 0, 0, 1, 38, + 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 1, 40, 0, 0, 1,173, 0, 0, 0, 35, 0, 0, 1, 38, 0, 0, 1, 40, 0, 0, 0, 35, + 0, 0, 1,173, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 1,173, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1,174, 0, 0, 1,175, + 0, 0, 0, 35, 0, 0, 1, 39, 0, 0, 1, 43, 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1, 39, + 0, 0, 1,175, 0, 0, 0, 35, 0, 0, 1, 42, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1, 42, 0, 0, 0, 35, + 0, 0, 1, 41, 0, 0, 1,174, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 1,176, 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 1,176, + 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 1,176, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 1,176, + 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 1,177, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1, 42, 0, 0, 0, 35, + 0, 0, 1, 42, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1,178, 0, 0, 0, 35, 0, 0, 1, 43, 0, 0, 1,177, + 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1, 43, 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1,177, 0, 0, 0, 35, 0, 0, 0,183, + 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 1, 41, 0, 0, 1,179, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1, 41, 0, 0, 0, 35, + 0, 0, 1,179, 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 1,179, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 1,180, 0, 0, 1,181, + 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0,166, 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 0,182, + 0, 0, 1,181, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 0,167, 0, 0, 1, 40, 0, 0, 0, 35, + 0, 0, 1, 40, 0, 0, 1,180, 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1,182, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1,182, + 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1, 45, 0, 0, 0, 35, 0, 0, 1,182, 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 1,182, + 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 1,183, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,185, 0, 0, 1, 44, 0, 0, 0, 35, + 0, 0, 0,185, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1,184, 0, 0, 0, 35, 0, 0, 0,184, 0, 0, 1,183, + 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0,184, 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 1,183, 0, 0, 0, 35, 0, 0, 1, 44, + 0, 0, 1,185, 0, 0, 0, 35, 0, 0, 1, 46, 0, 0, 1,185, 0, 0, 0, 35, 0, 0, 1, 44, 0, 0, 1, 46, 0, 0, 0, 35, + 0, 0, 1,185, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1,186, 0, 0, 1,187, + 0, 0, 0, 35, 0, 0, 1, 45, 0, 0, 1, 49, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 45, + 0, 0, 1,187, 0, 0, 0, 35, 0, 0, 1, 48, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1, 48, 0, 0, 0, 35, + 0, 0, 1, 47, 0, 0, 1,186, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 1,188, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 1,188, + 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 1,188, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 1,188, + 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1,189, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1, 48, 0, 0, 0, 35, + 0, 0, 1, 48, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1,190, 0, 0, 0, 35, 0, 0, 1, 49, 0, 0, 1,189, + 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1, 49, 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1,189, 0, 0, 0, 35, 0, 0, 0,191, + 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 1, 47, 0, 0, 1,191, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1, 47, 0, 0, 0, 35, + 0, 0, 1,191, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 1,191, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 1,192, 0, 0, 1,193, + 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 0,182, 0, 0, 0, 35, 0, 0, 0,182, 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 0,190, + 0, 0, 1,193, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 0,183, 0, 0, 1, 46, 0, 0, 0, 35, + 0, 0, 1, 46, 0, 0, 1,192, 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 1,194, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 1,194, + 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 1, 51, 0, 0, 0, 35, 0, 0, 1,194, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 1,194, + 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 1,195, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,193, 0, 0, 1, 50, 0, 0, 0, 35, + 0, 0, 0,193, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1,196, 0, 0, 0, 35, 0, 0, 0,192, 0, 0, 1,195, + 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,192, 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 1,195, 0, 0, 0, 35, 0, 0, 1, 50, + 0, 0, 1,197, 0, 0, 0, 35, 0, 0, 1, 53, 0, 0, 1,197, 0, 0, 0, 35, 0, 0, 1, 50, 0, 0, 1, 53, 0, 0, 0, 35, + 0, 0, 1,197, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 1,197, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1,198, 0, 0, 1,199, + 0, 0, 0, 35, 0, 0, 1, 51, 0, 0, 1, 55, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1, 51, + 0, 0, 1,199, 0, 0, 0, 35, 0, 0, 1, 54, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1, 54, 0, 0, 0, 35, + 0, 0, 1, 52, 0, 0, 1,198, 0, 0, 0, 35, 0, 0, 0,176, 0, 0, 1,200, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 1,200, + 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 0,176, 0, 0, 0, 35, 0, 0, 1,200, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 1,200, + 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1,201, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1, 54, 0, 0, 0, 35, + 0, 0, 1, 54, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 0,177, 0, 0, 1,202, 0, 0, 0, 35, 0, 0, 1, 55, 0, 0, 1,201, + 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1, 55, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1,201, 0, 0, 0, 35, 0, 0, 0,175, + 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 1, 52, 0, 0, 1,203, 0, 0, 0, 35, 0, 0, 0,175, 0, 0, 1, 52, 0, 0, 0, 35, + 0, 0, 1,203, 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 1,203, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 1,204, 0, 0, 1,205, + 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 0,174, 0, 0, 0, 35, 0, 0, 0,190, 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 0,174, + 0, 0, 1,205, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 0,191, 0, 0, 1, 53, 0, 0, 0, 35, + 0, 0, 1, 53, 0, 0, 1,204, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1, 57, + 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1,206, 0, 0, 0, 35, 0, 0, 1,206, 0, 0, 1,207, 0, 0, 0, 35, 0, 0, 1,207, + 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 1,206, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1, 56, 0, 0, 0, 35, + 0, 0, 1, 56, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,179, 0, 0, 1,208, 0, 0, 0, 35, 0, 0, 0,178, 0, 0, 1,207, + 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 1,207, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0,178, 0, 0, 0, 35, 0, 0, 1, 56, + 0, 0, 1,209, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1, 56, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,209, 0, 0, 0, 35, + 0, 0, 1,209, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1,210, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1,209, 0, 0, 1,211, + 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1, 57, 0, 0, 0, 35, 0, 0, 1, 57, 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1, 61, + 0, 0, 1,211, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 1,210, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1,210, 0, 0, 0, 35, + 0, 0, 1, 59, 0, 0, 1, 60, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 1,212, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 0,208, + 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 1,212, 0, 0, 0, 35, 0, 0, 1,212, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 1,213, + 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1,212, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 0,205, 0, 0, 0, 35, + 0, 0, 0,205, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1, 60, 0, 0, 1,214, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 1,213, + 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1,213, 0, 0, 0, 35, 0, 0, 1, 61, 0, 0, 0,209, 0, 0, 0, 35, 0, 0, 0,203, + 0, 0, 1,215, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 0,203, 0, 0, 0, 35, 0, 0, 1, 59, 0, 0, 1,215, 0, 0, 0, 35, + 0, 0, 1,215, 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 1,216, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 1,215, 0, 0, 1,217, + 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0,180, 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 0,180, + 0, 0, 1,217, 0, 0, 0, 35, 0, 0, 0,181, 0, 0, 1,216, 0, 0, 0, 35, 0, 0, 1, 58, 0, 0, 1,216, 0, 0, 0, 35, + 0, 0, 1, 58, 0, 0, 0,181, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 0,215, + 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1,218, 0, 0, 0, 35, 0, 0, 1,218, 0, 0, 1,219, 0, 0, 0, 35, 0, 0, 1,219, + 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 1,218, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 0,173, 0, 0, 0, 35, + 0, 0, 1, 62, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,173, 0, 0, 1,220, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 1,219, + 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 1,219, 0, 0, 0, 35, 0, 0, 0,172, 0, 0, 0,214, 0, 0, 0, 35, 0, 0, 1, 62, + 0, 0, 1,221, 0, 0, 0, 35, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 1,221, 0, 0, 0, 35, + 0, 0, 1,221, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1,222, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1,221, 0, 0, 1,223, + 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1, 67, 0, 0, 0, 35, 0, 0, 1, 63, 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1, 67, + 0, 0, 1,223, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 1,222, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1,222, 0, 0, 0, 35, + 0, 0, 1, 65, 0, 0, 1, 66, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 1,224, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 0,216, + 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 1,224, 0, 0, 0, 35, 0, 0, 1,224, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 1,225, + 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1,224, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 0,213, 0, 0, 0, 35, + 0, 0, 0,213, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1, 66, 0, 0, 1,226, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 1,225, + 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 1,225, 0, 0, 0, 35, 0, 0, 1, 67, 0, 0, 0,217, 0, 0, 0, 35, 0, 0, 0,211, + 0, 0, 1,227, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 0,211, 0, 0, 0, 35, 0, 0, 1, 65, 0, 0, 1,227, 0, 0, 0, 35, + 0, 0, 1,227, 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 1,228, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 1,227, 0, 0, 1,229, + 0, 0, 0, 35, 0, 0, 0,170, 0, 0, 0,210, 0, 0, 0, 35, 0, 0, 0,210, 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 0,170, + 0, 0, 1,229, 0, 0, 0, 35, 0, 0, 0,171, 0, 0, 1,228, 0, 0, 0, 35, 0, 0, 1, 64, 0, 0, 1,228, 0, 0, 0, 35, + 0, 0, 1, 64, 0, 0, 0,171, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 0,223, + 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 1,230, 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 1,231, + 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 1,230, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 0,189, 0, 0, 0, 35, + 0, 0, 1, 68, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,189, 0, 0, 1,232, 0, 0, 0, 35, 0, 0, 0,188, 0, 0, 1,231, + 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 1,231, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 0,188, 0, 0, 0, 35, 0, 0, 1, 68, + 0, 0, 1,233, 0, 0, 0, 35, 0, 0, 1, 68, 0, 0, 1, 70, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1,233, 0, 0, 0, 35, + 0, 0, 1,233, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 1,234, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1,233, 0, 0, 1,235, + 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1, 73, 0, 0, 0, 35, 0, 0, 1, 69, 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1, 73, + 0, 0, 1,235, 0, 0, 0, 35, 0, 0, 1, 72, 0, 0, 1,234, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1,234, 0, 0, 0, 35, + 0, 0, 1, 71, 0, 0, 1, 72, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 0,224, + 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 1,236, 0, 0, 0, 35, 0, 0, 1,236, 0, 0, 1,237, 0, 0, 0, 35, 0, 0, 1,237, + 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1,236, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1, 72, 0, 0, 0,221, 0, 0, 0, 35, + 0, 0, 0,221, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1, 72, 0, 0, 1,238, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 1,237, + 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 1,237, 0, 0, 0, 35, 0, 0, 1, 73, 0, 0, 0,225, 0, 0, 0, 35, 0, 0, 0,219, + 0, 0, 1,239, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 0,219, 0, 0, 0, 35, 0, 0, 1, 71, 0, 0, 1,239, 0, 0, 0, 35, + 0, 0, 1,239, 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 1,240, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 1,239, 0, 0, 1,241, + 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 0,186, 0, 0, 0, 35, 0, 0, 0,218, 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 0,186, + 0, 0, 1,241, 0, 0, 0, 35, 0, 0, 0,187, 0, 0, 1,240, 0, 0, 0, 35, 0, 0, 1, 70, 0, 0, 1,240, 0, 0, 0, 35, + 0, 0, 1, 70, 0, 0, 0,187, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 0,231, + 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1,242, 0, 0, 0, 35, 0, 0, 1,242, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 1,243, + 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 1,242, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 0,197, 0, 0, 0, 35, + 0, 0, 1, 74, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,197, 0, 0, 1,244, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 1,243, + 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 1,243, 0, 0, 0, 35, 0, 0, 0,196, 0, 0, 0,230, 0, 0, 0, 35, 0, 0, 1, 74, + 0, 0, 1,245, 0, 0, 0, 35, 0, 0, 1, 74, 0, 0, 1, 76, 0, 0, 0, 35, 0, 0, 1, 76, 0, 0, 1,245, 0, 0, 0, 35, + 0, 0, 1,245, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1,246, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1,245, 0, 0, 1,247, + 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1, 79, 0, 0, 0, 35, 0, 0, 1, 75, 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 79, + 0, 0, 1,247, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 1,246, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1,246, 0, 0, 0, 35, + 0, 0, 1, 77, 0, 0, 1, 78, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 1,248, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0,232, + 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 1,248, 0, 0, 0, 35, 0, 0, 1,248, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 1,249, + 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1,248, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 0,229, 0, 0, 0, 35, + 0, 0, 0,229, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1, 78, 0, 0, 1,250, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 1,249, + 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1,249, 0, 0, 0, 35, 0, 0, 1, 79, 0, 0, 0,233, 0, 0, 0, 35, 0, 0, 0,227, + 0, 0, 1,251, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 0,227, 0, 0, 0, 35, 0, 0, 1, 77, 0, 0, 1,251, 0, 0, 0, 35, + 0, 0, 1,251, 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 1,252, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 1,251, 0, 0, 1,253, + 0, 0, 0, 35, 0, 0, 0,194, 0, 0, 0,226, 0, 0, 0, 35, 0, 0, 0,226, 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 0,194, + 0, 0, 1,253, 0, 0, 0, 35, 0, 0, 0,195, 0, 0, 1,252, 0, 0, 0, 35, 0, 0, 1, 76, 0, 0, 1,252, 0, 0, 0, 35, + 0, 0, 1, 76, 0, 0, 0,195, 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 1,254, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1, 81, + 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1,254, 0, 0, 0, 35, 0, 0, 1,254, 0, 0, 1,255, 0, 0, 0, 35, 0, 0, 1,255, + 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 1,254, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 1, 80, 0, 0, 0, 35, + 0, 0, 1, 80, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,201, 0, 0, 2, 0, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 1,255, + 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 1,255, 0, 0, 0, 35, 0, 0, 0,200, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 1, 80, + 0, 0, 2, 1, 0, 0, 0, 35, 0, 0, 1, 80, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 2, 1, 0, 0, 0, 35, + 0, 0, 2, 1, 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 2, 2, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 2, 1, 0, 0, 2, 3, + 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 1, 85, 0, 0, 0, 35, 0, 0, 1, 81, 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 1, 85, + 0, 0, 2, 3, 0, 0, 0, 35, 0, 0, 1, 84, 0, 0, 2, 2, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 2, 2, 0, 0, 0, 35, + 0, 0, 1, 83, 0, 0, 1, 84, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 2, 4, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 0,240, + 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 2, 4, 0, 0, 0, 35, 0, 0, 2, 4, 0, 0, 2, 5, 0, 0, 0, 35, 0, 0, 2, 5, + 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 2, 4, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 1, 84, 0, 0, 0, 35, + 0, 0, 0,237, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 1, 84, 0, 0, 2, 6, 0, 0, 0, 35, 0, 0, 1, 85, 0, 0, 2, 5, + 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 2, 5, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 1, 85, 0, 0, 0, 35, 0, 0, 0,235, + 0, 0, 2, 7, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 1, 83, 0, 0, 0, 35, 0, 0, 1, 83, 0, 0, 2, 7, 0, 0, 0, 35, + 0, 0, 2, 7, 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 2, 8, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 2, 7, 0, 0, 2, 9, + 0, 0, 0, 35, 0, 0, 0,198, 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0,234, 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 0,198, + 0, 0, 2, 9, 0, 0, 0, 35, 0, 0, 0,199, 0, 0, 2, 8, 0, 0, 0, 35, 0, 0, 1, 82, 0, 0, 2, 8, 0, 0, 0, 35, + 0, 0, 0,199, 0, 0, 1, 82, 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 2, 10, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 2, 10, + 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 1, 87, 0, 0, 0, 35, 0, 0, 2, 10, 0, 0, 2, 11, 0, 0, 0, 35, 0, 0, 2, 10, + 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 2, 11, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,209, 0, 0, 1, 86, 0, 0, 0, 35, + 0, 0, 0,209, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 2, 12, 0, 0, 0, 35, 0, 0, 0,208, 0, 0, 2, 11, + 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 0,208, 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 2, 11, 0, 0, 0, 35, 0, 0, 1, 86, + 0, 0, 2, 13, 0, 0, 0, 35, 0, 0, 1, 88, 0, 0, 2, 13, 0, 0, 0, 35, 0, 0, 1, 86, 0, 0, 1, 88, 0, 0, 0, 35, + 0, 0, 2, 13, 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 2, 13, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 2, 14, 0, 0, 2, 15, + 0, 0, 0, 35, 0, 0, 1, 87, 0, 0, 1, 91, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 1, 87, + 0, 0, 2, 15, 0, 0, 0, 35, 0, 0, 1, 90, 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 1, 89, 0, 0, 1, 90, 0, 0, 0, 35, + 0, 0, 1, 89, 0, 0, 2, 14, 0, 0, 0, 35, 0, 0, 0,212, 0, 0, 2, 16, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 2, 16, + 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 0,212, 0, 0, 0, 35, 0, 0, 2, 16, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 2, 16, + 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 2, 17, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 1, 90, 0, 0, 0, 35, + 0, 0, 1, 90, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 0,213, 0, 0, 2, 18, 0, 0, 0, 35, 0, 0, 1, 91, 0, 0, 2, 17, + 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 1, 91, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 2, 17, 0, 0, 0, 35, 0, 0, 0,211, + 0, 0, 2, 19, 0, 0, 0, 35, 0, 0, 1, 89, 0, 0, 2, 19, 0, 0, 0, 35, 0, 0, 0,211, 0, 0, 1, 89, 0, 0, 0, 35, + 0, 0, 2, 19, 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 2, 19, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 2, 20, 0, 0, 2, 21, + 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 0,210, 0, 0, 0, 35, 0, 0, 0,206, 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 0,210, + 0, 0, 2, 21, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 0,207, 0, 0, 1, 88, 0, 0, 0, 35, + 0, 0, 1, 88, 0, 0, 2, 20, 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 2, 22, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 2, 22, + 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 1, 93, 0, 0, 0, 35, 0, 0, 2, 22, 0, 0, 2, 23, 0, 0, 0, 35, 0, 0, 2, 22, + 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 2, 23, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,217, 0, 0, 1, 92, 0, 0, 0, 35, + 0, 0, 0,217, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 2, 24, 0, 0, 0, 35, 0, 0, 0,216, 0, 0, 2, 23, + 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 0,216, 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 2, 23, 0, 0, 0, 35, 0, 0, 1, 92, + 0, 0, 2, 25, 0, 0, 0, 35, 0, 0, 1, 94, 0, 0, 2, 25, 0, 0, 0, 35, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 35, + 0, 0, 2, 25, 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 2, 25, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 2, 26, 0, 0, 2, 27, + 0, 0, 0, 35, 0, 0, 1, 93, 0, 0, 1, 97, 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 1, 93, + 0, 0, 2, 27, 0, 0, 0, 35, 0, 0, 1, 96, 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 1, 96, 0, 0, 0, 35, + 0, 0, 1, 95, 0, 0, 2, 26, 0, 0, 0, 35, 0, 0, 0,220, 0, 0, 2, 28, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 2, 28, + 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 0,220, 0, 0, 0, 35, 0, 0, 2, 28, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 2, 28, + 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 2, 29, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 1, 96, 0, 0, 0, 35, + 0, 0, 1, 96, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 0,221, 0, 0, 2, 30, 0, 0, 0, 35, 0, 0, 1, 97, 0, 0, 2, 29, + 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 1, 97, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 2, 29, 0, 0, 0, 35, 0, 0, 0,219, + 0, 0, 2, 31, 0, 0, 0, 35, 0, 0, 1, 95, 0, 0, 2, 31, 0, 0, 0, 35, 0, 0, 0,219, 0, 0, 1, 95, 0, 0, 0, 35, + 0, 0, 2, 31, 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 2, 31, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 2, 32, 0, 0, 2, 33, + 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 0,218, 0, 0, 0, 35, 0, 0, 0,214, 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 0,218, + 0, 0, 2, 33, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 0,215, 0, 0, 1, 94, 0, 0, 0, 35, + 0, 0, 1, 94, 0, 0, 2, 32, 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 2, 34, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 2, 34, + 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 1, 99, 0, 0, 0, 35, 0, 0, 2, 34, 0, 0, 2, 35, 0, 0, 0, 35, 0, 0, 2, 34, + 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 2, 35, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,225, 0, 0, 1, 98, 0, 0, 0, 35, + 0, 0, 0,225, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 2, 36, 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 2, 35, + 0, 0, 0, 35, 0, 0, 0,224, 0, 0, 0,250, 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 2, 35, 0, 0, 0, 35, 0, 0, 1, 98, + 0, 0, 2, 37, 0, 0, 0, 35, 0, 0, 1,100, 0, 0, 2, 37, 0, 0, 0, 35, 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 0, 35, + 0, 0, 2, 37, 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 2, 37, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 2, 38, 0, 0, 2, 39, + 0, 0, 0, 35, 0, 0, 1, 99, 0, 0, 1,103, 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 1, 99, + 0, 0, 2, 39, 0, 0, 0, 35, 0, 0, 1,102, 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 1,102, 0, 0, 0, 35, + 0, 0, 1,101, 0, 0, 2, 38, 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 2, 40, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 2, 40, + 0, 0, 0, 35, 0, 0, 0,228, 0, 0, 0,252, 0, 0, 0, 35, 0, 0, 2, 40, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 2, 40, + 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 2, 41, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 1,102, 0, 0, 0, 35, + 0, 0, 1,102, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 0,229, 0, 0, 2, 42, 0, 0, 0, 35, 0, 0, 1,103, 0, 0, 2, 41, + 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 1,103, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 2, 41, 0, 0, 0, 35, 0, 0, 0,227, + 0, 0, 2, 43, 0, 0, 0, 35, 0, 0, 1,101, 0, 0, 2, 43, 0, 0, 0, 35, 0, 0, 0,227, 0, 0, 1,101, 0, 0, 0, 35, + 0, 0, 2, 43, 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 2, 43, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 2, 44, 0, 0, 2, 45, + 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 0,226, 0, 0, 0, 35, 0, 0, 0,222, 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 0,226, + 0, 0, 2, 45, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 0,223, 0, 0, 1,100, 0, 0, 0, 35, + 0, 0, 1,100, 0, 0, 2, 44, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 2, 46, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 2, 46, + 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 2, 46, 0, 0, 2, 47, 0, 0, 0, 35, 0, 0, 2, 46, + 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 2, 47, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,233, 0, 0, 1,104, 0, 0, 0, 35, + 0, 0, 0,233, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 1,104, 0, 0, 2, 48, 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 2, 47, + 0, 0, 0, 35, 0, 0, 0,232, 0, 0, 0,254, 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 2, 47, 0, 0, 0, 35, 0, 0, 1,104, + 0, 0, 2, 49, 0, 0, 0, 35, 0, 0, 1,106, 0, 0, 2, 49, 0, 0, 0, 35, 0, 0, 1,104, 0, 0, 1,106, 0, 0, 0, 35, + 0, 0, 2, 49, 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 2, 49, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 2, 50, 0, 0, 2, 51, + 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 1,105, + 0, 0, 2, 51, 0, 0, 0, 35, 0, 0, 1,108, 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 1,108, 0, 0, 1,107, 0, 0, 0, 35, + 0, 0, 1,107, 0, 0, 2, 50, 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 2, 52, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 2, 52, + 0, 0, 0, 35, 0, 0, 0,236, 0, 0, 1, 0, 0, 0, 0, 35, 0, 0, 2, 52, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 2, 52, + 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 2, 53, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 1,108, 0, 0, 0, 35, + 0, 0, 1,108, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 0,237, 0, 0, 2, 54, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 2, 53, + 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 2, 53, 0, 0, 0, 35, 0, 0, 0,235, + 0, 0, 2, 55, 0, 0, 0, 35, 0, 0, 1,107, 0, 0, 2, 55, 0, 0, 0, 35, 0, 0, 0,235, 0, 0, 1,107, 0, 0, 0, 35, + 0, 0, 2, 55, 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 2, 55, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 2, 56, 0, 0, 2, 57, + 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 0,234, 0, 0, 0, 35, 0, 0, 0,230, 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 0,234, + 0, 0, 2, 57, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 0,231, 0, 0, 1,106, 0, 0, 0, 35, + 0, 0, 1,106, 0, 0, 2, 56, 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 2, 58, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 2, 58, + 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 1,111, 0, 0, 0, 35, 0, 0, 2, 58, 0, 0, 2, 59, 0, 0, 0, 35, 0, 0, 2, 58, + 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 2, 59, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,241, 0, 0, 1,110, 0, 0, 0, 35, + 0, 0, 0,241, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 2, 60, 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 2, 59, + 0, 0, 0, 35, 0, 0, 0,240, 0, 0, 1, 2, 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 2, 59, 0, 0, 0, 35, 0, 0, 1,110, + 0, 0, 2, 61, 0, 0, 0, 35, 0, 0, 1,113, 0, 0, 2, 61, 0, 0, 0, 35, 0, 0, 1,110, 0, 0, 1,113, 0, 0, 0, 35, + 0, 0, 2, 61, 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 2, 61, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 2, 62, 0, 0, 2, 63, + 0, 0, 0, 35, 0, 0, 1,111, 0, 0, 1,115, 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 1,111, + 0, 0, 2, 63, 0, 0, 0, 35, 0, 0, 1,114, 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 0, 35, + 0, 0, 1,112, 0, 0, 2, 62, 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 2, 64, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 2, 64, + 0, 0, 0, 35, 0, 0, 0,204, 0, 0, 1, 4, 0, 0, 0, 35, 0, 0, 2, 64, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 2, 64, + 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 2, 65, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 1,114, 0, 0, 0, 35, + 0, 0, 1,114, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 0,205, 0, 0, 2, 66, 0, 0, 0, 35, 0, 0, 1,115, 0, 0, 2, 65, + 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1,115, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 2, 65, 0, 0, 0, 35, 0, 0, 0,203, + 0, 0, 2, 67, 0, 0, 0, 35, 0, 0, 1,112, 0, 0, 2, 67, 0, 0, 0, 35, 0, 0, 0,203, 0, 0, 1,112, 0, 0, 0, 35, + 0, 0, 2, 67, 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 2, 67, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 2, 68, 0, 0, 2, 69, + 0, 0, 0, 35, 0, 0, 0,202, 0, 0, 0,238, 0, 0, 0, 35, 0, 0, 0,238, 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 0,202, + 0, 0, 2, 69, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 0,239, 0, 0, 1,113, 0, 0, 0, 35, + 0, 0, 1,113, 0, 0, 2, 68, 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 2, 70, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 1,117, + 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 2, 70, 0, 0, 0, 35, 0, 0, 2, 70, 0, 0, 2, 71, 0, 0, 0, 35, 0, 0, 2, 71, + 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 2, 70, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 1,116, 0, 0, 0, 35, + 0, 0, 1,116, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,243, 0, 0, 2, 72, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 2, 71, + 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 2, 71, 0, 0, 0, 35, 0, 0, 0,242, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 1,116, + 0, 0, 2, 73, 0, 0, 0, 35, 0, 0, 1,116, 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 2, 73, 0, 0, 0, 35, + 0, 0, 2, 73, 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 2, 74, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 2, 73, 0, 0, 2, 75, + 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1,117, 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 1,121, + 0, 0, 2, 75, 0, 0, 0, 35, 0, 0, 1,120, 0, 0, 2, 74, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 2, 74, 0, 0, 0, 35, + 0, 0, 1,119, 0, 0, 1,120, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 2, 76, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 1, 12, + 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 2, 76, 0, 0, 0, 35, 0, 0, 2, 76, 0, 0, 2, 77, 0, 0, 0, 35, 0, 0, 2, 77, + 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 2, 76, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 1,120, 0, 0, 0, 35, + 0, 0, 1, 9, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 1,120, 0, 0, 2, 78, 0, 0, 0, 35, 0, 0, 1,121, 0, 0, 2, 77, + 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 2, 77, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 1,121, 0, 0, 0, 35, 0, 0, 1, 7, + 0, 0, 2, 79, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 1,119, 0, 0, 0, 35, 0, 0, 1,119, 0, 0, 2, 79, 0, 0, 0, 35, + 0, 0, 2, 79, 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 2, 80, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 2, 79, 0, 0, 2, 81, + 0, 0, 0, 35, 0, 0, 0,244, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 0,244, + 0, 0, 2, 81, 0, 0, 0, 35, 0, 0, 0,245, 0, 0, 2, 80, 0, 0, 0, 35, 0, 0, 1,118, 0, 0, 2, 80, 0, 0, 0, 35, + 0, 0, 0,245, 0, 0, 1,118, 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 2, 82, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 1,123, + 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 2, 82, 0, 0, 0, 35, 0, 0, 2, 82, 0, 0, 2, 83, 0, 0, 0, 35, 0, 0, 2, 83, + 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 2, 82, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 1,122, 0, 0, 0, 35, + 0, 0, 1,122, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,249, 0, 0, 2, 84, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 2, 83, + 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 2, 83, 0, 0, 0, 35, 0, 0, 0,248, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 1,122, + 0, 0, 2, 85, 0, 0, 0, 35, 0, 0, 1,122, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 2, 85, 0, 0, 0, 35, + 0, 0, 2, 85, 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 2, 86, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 2, 85, 0, 0, 2, 87, + 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1,123, 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 1,127, + 0, 0, 2, 87, 0, 0, 0, 35, 0, 0, 1,126, 0, 0, 2, 86, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 2, 86, 0, 0, 0, 35, + 0, 0, 1,125, 0, 0, 1,126, 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 2, 88, 0, 0, 0, 35, 0, 0, 1, 12, 0, 0, 1, 16, + 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 2, 88, 0, 0, 0, 35, 0, 0, 2, 88, 0, 0, 2, 89, 0, 0, 0, 35, 0, 0, 2, 89, + 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 2, 88, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 1, 13, 0, 0, 1,126, 0, 0, 0, 35, + 0, 0, 1, 13, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 1,126, 0, 0, 2, 90, 0, 0, 0, 35, 0, 0, 1,127, 0, 0, 2, 89, + 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 2, 89, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 1,127, 0, 0, 0, 35, 0, 0, 1, 11, + 0, 0, 2, 91, 0, 0, 0, 35, 0, 0, 1, 11, 0, 0, 1,125, 0, 0, 0, 35, 0, 0, 1,125, 0, 0, 2, 91, 0, 0, 0, 35, + 0, 0, 2, 91, 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 2, 92, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 2, 91, 0, 0, 2, 93, + 0, 0, 0, 35, 0, 0, 0,246, 0, 0, 1, 10, 0, 0, 0, 35, 0, 0, 1, 10, 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 0,246, + 0, 0, 2, 93, 0, 0, 0, 35, 0, 0, 0,247, 0, 0, 2, 92, 0, 0, 0, 35, 0, 0, 1,124, 0, 0, 2, 92, 0, 0, 0, 35, + 0, 0, 0,247, 0, 0, 1,124, 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 2, 94, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 1,129, + 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 2, 94, 0, 0, 0, 35, 0, 0, 2, 94, 0, 0, 2, 95, 0, 0, 0, 35, 0, 0, 2, 95, + 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 2, 94, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 1,128, 0, 0, 0, 35, + 0, 0, 1,128, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,253, 0, 0, 2, 96, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 2, 95, + 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 2, 95, 0, 0, 0, 35, 0, 0, 0,252, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 1,128, + 0, 0, 2, 97, 0, 0, 0, 35, 0, 0, 1,128, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 2, 97, 0, 0, 0, 35, + 0, 0, 2, 97, 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 2, 98, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 2, 97, 0, 0, 2, 99, + 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 1,133, 0, 0, 0, 35, 0, 0, 1,129, 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 1,133, + 0, 0, 2, 99, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 2, 98, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 2, 98, 0, 0, 0, 35, + 0, 0, 1,131, 0, 0, 1,132, 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 2,100, 0, 0, 0, 35, 0, 0, 1, 16, 0, 0, 1, 20, + 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 2,100, 0, 0, 0, 35, 0, 0, 2,100, 0, 0, 2,101, 0, 0, 0, 35, 0, 0, 2,101, + 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 2,100, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 1, 17, 0, 0, 1,132, 0, 0, 0, 35, + 0, 0, 1, 17, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 1,132, 0, 0, 2,102, 0, 0, 0, 35, 0, 0, 1,133, 0, 0, 2,101, + 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 2,101, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 1,133, 0, 0, 0, 35, 0, 0, 1, 15, + 0, 0, 2,103, 0, 0, 0, 35, 0, 0, 1, 15, 0, 0, 1,131, 0, 0, 0, 35, 0, 0, 1,131, 0, 0, 2,103, 0, 0, 0, 35, + 0, 0, 2,103, 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 2,104, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 2,103, 0, 0, 2,105, + 0, 0, 0, 35, 0, 0, 0,250, 0, 0, 1, 14, 0, 0, 0, 35, 0, 0, 1, 14, 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 0,250, + 0, 0, 2,105, 0, 0, 0, 35, 0, 0, 0,251, 0, 0, 2,104, 0, 0, 0, 35, 0, 0, 1,130, 0, 0, 2,104, 0, 0, 0, 35, + 0, 0, 0,251, 0, 0, 1,130, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 2,106, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 1,135, + 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 2,106, 0, 0, 0, 35, 0, 0, 2,106, 0, 0, 2,107, 0, 0, 0, 35, 0, 0, 2,107, + 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 2,106, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 1,134, 0, 0, 0, 35, + 0, 0, 1,134, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 1, 1, 0, 0, 2,108, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 2,107, + 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 2,107, 0, 0, 0, 35, 0, 0, 1, 0, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1,134, + 0, 0, 2,109, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 2,109, 0, 0, 0, 35, + 0, 0, 2,109, 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 2,110, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 2,109, 0, 0, 2,111, + 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 1,139, 0, 0, 0, 35, 0, 0, 1,135, 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 1,139, + 0, 0, 2,111, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 2,110, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 2,110, 0, 0, 0, 35, + 0, 0, 1,137, 0, 0, 1,138, 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 2,112, 0, 0, 0, 35, 0, 0, 1, 20, 0, 0, 1, 24, + 0, 0, 0, 35, 0, 0, 1, 24, 0, 0, 2,112, 0, 0, 0, 35, 0, 0, 2,112, 0, 0, 2,113, 0, 0, 0, 35, 0, 0, 2,113, + 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 2,112, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 1, 21, 0, 0, 1,138, 0, 0, 0, 35, + 0, 0, 1, 21, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 1,138, 0, 0, 2,114, 0, 0, 0, 35, 0, 0, 1,139, 0, 0, 2,113, + 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 2,113, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 1,139, 0, 0, 0, 35, 0, 0, 1, 19, + 0, 0, 2,115, 0, 0, 0, 35, 0, 0, 1, 19, 0, 0, 1,137, 0, 0, 0, 35, 0, 0, 1,137, 0, 0, 2,115, 0, 0, 0, 35, + 0, 0, 2,115, 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 2,116, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 2,115, 0, 0, 2,117, + 0, 0, 0, 35, 0, 0, 0,254, 0, 0, 1, 18, 0, 0, 0, 35, 0, 0, 1, 18, 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 0,254, + 0, 0, 2,117, 0, 0, 0, 35, 0, 0, 0,255, 0, 0, 2,116, 0, 0, 0, 35, 0, 0, 1,136, 0, 0, 2,116, 0, 0, 0, 35, + 0, 0, 0,255, 0, 0, 1,136, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 2,118, 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 1,141, + 0, 0, 0, 35, 0, 0, 1, 7, 0, 0, 2,118, 0, 0, 0, 35, 0, 0, 2,118, 0, 0, 2,119, 0, 0, 0, 35, 0, 0, 2,119, + 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 2,118, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 1,140, 0, 0, 0, 35, + 0, 0, 1,140, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 1, 5, 0, 0, 2,120, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 2,119, + 0, 0, 0, 35, 0, 0, 1, 6, 0, 0, 2,119, 0, 0, 0, 35, 0, 0, 1, 4, 0, 0, 1, 6, 0, 0, 0, 35, 0, 0, 1,140, + 0, 0, 2,121, 0, 0, 0, 35, 0, 0, 1,140, 0, 0, 1,142, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 2,121, 0, 0, 0, 35, + 0, 0, 2,121, 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 2,122, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 2,121, 0, 0, 2,123, + 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 1,141, 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 1,144, + 0, 0, 2,123, 0, 0, 0, 35, 0, 0, 1,145, 0, 0, 2,122, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 2,122, 0, 0, 0, 35, + 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 35, 0, 0, 1, 24, 0, 0, 2,124, 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 1, 24, + 0, 0, 0, 35, 0, 0, 1, 8, 0, 0, 2,124, 0, 0, 0, 35, 0, 0, 2,124, 0, 0, 2,125, 0, 0, 0, 35, 0, 0, 2,125, + 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 2,124, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 1, 25, 0, 0, 1,145, 0, 0, 0, 35, + 0, 0, 1, 25, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 1,145, 0, 0, 2,126, 0, 0, 0, 35, 0, 0, 1,144, 0, 0, 2,125, + 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 2,125, 0, 0, 0, 35, 0, 0, 1, 9, 0, 0, 1,144, 0, 0, 0, 35, 0, 0, 1, 23, + 0, 0, 2,127, 0, 0, 0, 35, 0, 0, 1, 23, 0, 0, 1,143, 0, 0, 0, 35, 0, 0, 1,143, 0, 0, 2,127, 0, 0, 0, 35, + 0, 0, 2,127, 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 2,128, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 2,127, 0, 0, 2,129, + 0, 0, 0, 35, 0, 0, 1, 2, 0, 0, 1, 22, 0, 0, 0, 35, 0, 0, 1, 22, 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 1, 2, + 0, 0, 2,129, 0, 0, 0, 35, 0, 0, 1, 3, 0, 0, 2,128, 0, 0, 0, 35, 0, 0, 1,142, 0, 0, 2,128, 0, 0, 0, 35, + 0, 0, 1, 3, 0, 0, 1,142, 0, 0, 0, 35, 68, 65, 84, 65, 0, 0,100, 0, 7, 83,240, 32, 0, 0, 0, 48, 0, 0, 5, 0, + 0, 0, 1, 27, 0, 0, 0,102, 0, 0, 1,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,146, 0, 0, 0,171, 0, 0, 1, 27, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 1, 27, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,171, + 0, 0, 1,146, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,147, 0, 0, 0, 46, 0, 0, 1,146, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,146, 0, 0, 1,148, 0, 0, 1,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 1,147, + 0, 0, 1,148, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,148, 0, 0, 1,146, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 26, 0, 0, 0, 12, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,165, 0, 0, 1,148, 0, 0, 1, 26, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,102, 0, 0, 1, 26, 0, 0, 1,148, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,148, + 0, 0, 0,165, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,147, 0, 0, 0, 43, 0, 0, 0,164, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,164, 0, 0, 0,170, 0, 0, 1,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 46, 0, 0, 1,147, + 0, 0, 0,170, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,170, 0, 0, 0,164, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 26, 0, 0, 0,102, 0, 0, 1,149, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,149, 0, 0, 1, 28, 0, 0, 1, 26, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 1, 26, 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 28, + 0, 0, 1,149, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,150, 0, 0, 0,103, 0, 0, 1,149, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,149, 0, 0, 1,151, 0, 0, 1,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,104, 0, 0, 1,150, + 0, 0, 1,151, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,151, 0, 0, 1,149, 0, 0, 0,102, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 27, 0, 0, 0, 14, 0, 0, 1, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 31, 0, 0, 1,151, 0, 0, 1, 27, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,102, 0, 0, 1, 27, 0, 0, 1,151, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,151, + 0, 0, 1, 31, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,150, 0, 0, 0,104, 0, 0, 1, 30, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 30, 0, 0, 1, 29, 0, 0, 1,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 1,150, + 0, 0, 1, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 29, 0, 0, 1, 30, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,168, 0, 0, 0, 45, 0, 0, 1,152, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,152, 0, 0, 0,172, 0, 0, 0,168, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,168, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,172, + 0, 0, 1,152, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,153, 0, 0, 0, 47, 0, 0, 1,152, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,152, 0, 0, 1,154, 0, 0, 1,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,104, 0, 0, 1,153, + 0, 0, 1,154, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,154, 0, 0, 1,152, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,169, 0, 0, 0, 13, 0, 0, 1, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 30, 0, 0, 1,154, 0, 0, 0,169, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0,169, 0, 0, 1,154, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,154, + 0, 0, 1, 30, 0, 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,153, 0, 0, 0,104, 0, 0, 1, 31, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 31, 0, 0, 0,173, 0, 0, 1,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 1,153, + 0, 0, 0,173, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,173, 0, 0, 1, 31, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,167, 0, 0, 0, 44, 0, 0, 1,155, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,155, 0, 0, 1, 29, 0, 0, 0,167, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0,167, 0, 0, 1, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 29, + 0, 0, 1,155, 0, 0, 0,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,156, 0, 0, 0,103, 0, 0, 1,155, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,155, 0, 0, 1,157, 0, 0, 1,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 1,156, + 0, 0, 1,157, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,157, 0, 0, 1,155, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,162, 0, 0, 1,157, 0, 0, 0,166, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0,166, 0, 0, 1,157, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,157, + 0, 0, 0,162, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,156, 0, 0, 0, 42, 0, 0, 0,163, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,163, 0, 0, 1, 28, 0, 0, 1,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,103, 0, 0, 1,156, + 0, 0, 1, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 28, 0, 0, 0,163, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,158, 0, 0, 0,105, 0, 0, 1, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 33, 0, 0, 0,179, 0, 0, 1,158, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 1,158, 0, 0, 0,179, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,179, + 0, 0, 1, 33, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,158, 0, 0, 0, 50, 0, 0, 1,159, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,159, 0, 0, 1,160, 0, 0, 1,158, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,105, 0, 0, 1,158, + 0, 0, 1,160, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,160, 0, 0, 1,159, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,165, 0, 0, 0, 12, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 32, 0, 0, 1,160, 0, 0, 0,165, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0,165, 0, 0, 1,160, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,160, + 0, 0, 1, 32, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,164, 0, 0, 0, 43, 0, 0, 1,159, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,159, 0, 0, 0,178, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0,164, + 0, 0, 0,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,178, 0, 0, 1,159, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,161, 0, 0, 0,105, 0, 0, 1, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 32, 0, 0, 1, 34, 0, 0, 1,161, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,106, 0, 0, 1,161, 0, 0, 1, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 34, + 0, 0, 1, 32, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,161, 0, 0, 0,106, 0, 0, 1,162, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,162, 0, 0, 1,163, 0, 0, 1,161, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,105, 0, 0, 1,161, + 0, 0, 1,163, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,163, 0, 0, 1,162, 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 37, 0, 0, 0, 16, 0, 0, 1, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 33, 0, 0, 1,163, 0, 0, 1, 37, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 1, 37, 0, 0, 1,163, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,163, + 0, 0, 1, 33, 0, 0, 0,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 36, 0, 0, 0,107, 0, 0, 1,162, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,162, 0, 0, 1, 35, 0, 0, 1, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 1, 36, + 0, 0, 1, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 35, 0, 0, 1,162, 0, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,164, 0, 0, 0, 49, 0, 0, 0,176, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,176, 0, 0, 0,180, 0, 0, 1,164, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 1,164, 0, 0, 0,180, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,180, + 0, 0, 0,176, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,164, 0, 0, 0, 51, 0, 0, 1,165, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,165, 0, 0, 1,166, 0, 0, 1,164, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 1,164, + 0, 0, 1,166, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,166, 0, 0, 1,165, 0, 0, 0,107, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 36, 0, 0, 0, 15, 0, 0, 0,177, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,177, 0, 0, 1,166, 0, 0, 1, 36, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,107, 0, 0, 1, 36, 0, 0, 1,166, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,166, + 0, 0, 0,177, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 37, 0, 0, 0,107, 0, 0, 1,165, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,165, 0, 0, 0,181, 0, 0, 1, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 1, 37, + 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,181, 0, 0, 1,165, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,167, 0, 0, 0, 48, 0, 0, 0,175, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,175, 0, 0, 1, 35, 0, 0, 1,167, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,106, 0, 0, 1,167, 0, 0, 1, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 35, + 0, 0, 0,175, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,167, 0, 0, 0,106, 0, 0, 1,168, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,168, 0, 0, 1,169, 0, 0, 1,167, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 0, 0, 1,167, + 0, 0, 1,169, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,169, 0, 0, 1,168, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,162, 0, 0, 0, 0, 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,174, 0, 0, 1,169, 0, 0, 0,162, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0,162, 0, 0, 1,169, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,169, + 0, 0, 0,174, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,163, 0, 0, 0, 42, 0, 0, 1,168, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,168, 0, 0, 1, 34, 0, 0, 0,163, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 12, 0, 0, 0,163, + 0, 0, 1, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 34, 0, 0, 1,168, 0, 0, 0,106, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 39, 0, 0, 0,108, 0, 0, 1,170, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,170, 0, 0, 0,187, 0, 0, 1, 39, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 0, 0, 1, 39, 0, 0, 0,187, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,187, + 0, 0, 1,170, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,171, 0, 0, 0, 54, 0, 0, 1,170, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,170, 0, 0, 1,172, 0, 0, 1,171, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 1,171, + 0, 0, 1,172, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,172, 0, 0, 1,170, 0, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 38, 0, 0, 0, 13, 0, 0, 0,169, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,169, 0, 0, 1,172, 0, 0, 1, 38, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,108, 0, 0, 1, 38, 0, 0, 1,172, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,172, + 0, 0, 0,169, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,171, 0, 0, 0, 45, 0, 0, 0,168, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,168, 0, 0, 0,186, 0, 0, 1,171, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 1,171, + 0, 0, 0,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,186, 0, 0, 0,168, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 38, 0, 0, 0,108, 0, 0, 1,173, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,173, 0, 0, 1, 40, 0, 0, 1, 38, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 1, 38, 0, 0, 1, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 40, + 0, 0, 1,173, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,174, 0, 0, 0,109, 0, 0, 1,173, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,173, 0, 0, 1,175, 0, 0, 1,174, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,110, 0, 0, 1,174, + 0, 0, 1,175, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,175, 0, 0, 1,173, 0, 0, 0,108, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 39, 0, 0, 0, 18, 0, 0, 1, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 43, 0, 0, 1,175, 0, 0, 1, 39, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,108, 0, 0, 1, 39, 0, 0, 1,175, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,175, + 0, 0, 1, 43, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,174, 0, 0, 0,110, 0, 0, 1, 42, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 42, 0, 0, 1, 41, 0, 0, 1,174, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 1,174, + 0, 0, 1, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 41, 0, 0, 1, 42, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,184, 0, 0, 0, 53, 0, 0, 1,176, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,176, 0, 0, 0,188, 0, 0, 0,184, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0,188, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,188, + 0, 0, 1,176, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,177, 0, 0, 0, 55, 0, 0, 1,176, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,176, 0, 0, 1,178, 0, 0, 1,177, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,110, 0, 0, 1,177, + 0, 0, 1,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,178, 0, 0, 1,176, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,185, 0, 0, 0, 17, 0, 0, 1, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 42, 0, 0, 1,178, 0, 0, 0,185, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 0,185, 0, 0, 1,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,178, + 0, 0, 1, 42, 0, 0, 0,110, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,177, 0, 0, 0,110, 0, 0, 1, 43, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 43, 0, 0, 0,189, 0, 0, 1,177, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 1,177, + 0, 0, 0,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,189, 0, 0, 1, 43, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,183, 0, 0, 0, 52, 0, 0, 1,179, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,179, 0, 0, 1, 41, 0, 0, 0,183, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 0,183, 0, 0, 1, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 41, + 0, 0, 1,179, 0, 0, 0,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,180, 0, 0, 0,109, 0, 0, 1,179, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,179, 0, 0, 1,181, 0, 0, 1,180, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 1,180, + 0, 0, 1,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,181, 0, 0, 1,179, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,166, 0, 0, 1,181, 0, 0, 0,182, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 0,182, 0, 0, 1,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,181, + 0, 0, 0,166, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,180, 0, 0, 0, 44, 0, 0, 0,167, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,167, 0, 0, 1, 40, 0, 0, 1,180, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,109, 0, 0, 1,180, + 0, 0, 1, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 40, 0, 0, 0,167, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 45, 0, 0, 0,111, 0, 0, 1,182, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,182, 0, 0, 0,195, 0, 0, 1, 45, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 1, 45, 0, 0, 0,195, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,195, + 0, 0, 1,182, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,183, 0, 0, 0, 58, 0, 0, 1,182, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,182, 0, 0, 1,184, 0, 0, 1,183, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 53, 0, 0, 1,183, + 0, 0, 1,184, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,184, 0, 0, 1,182, 0, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 44, 0, 0, 0, 17, 0, 0, 0,185, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,185, 0, 0, 1,184, 0, 0, 1, 44, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 1, 44, 0, 0, 1,184, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,184, + 0, 0, 0,185, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,183, 0, 0, 0, 53, 0, 0, 0,184, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,184, 0, 0, 0,194, 0, 0, 1,183, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 0, 1,183, + 0, 0, 0,194, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,194, 0, 0, 0,184, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 44, 0, 0, 0,111, 0, 0, 1,185, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,185, 0, 0, 1, 46, 0, 0, 1, 44, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 17, 0, 0, 1, 44, 0, 0, 1, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 46, + 0, 0, 1,185, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,186, 0, 0, 0,112, 0, 0, 1,185, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,185, 0, 0, 1,187, 0, 0, 1,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 1,186, + 0, 0, 1,187, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,187, 0, 0, 1,185, 0, 0, 0,111, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 45, 0, 0, 0, 20, 0, 0, 1, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 49, 0, 0, 1,187, 0, 0, 1, 45, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,111, 0, 0, 1, 45, 0, 0, 1,187, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,187, + 0, 0, 1, 49, 0, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,186, 0, 0, 0,113, 0, 0, 1, 48, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 48, 0, 0, 1, 47, 0, 0, 1,186, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,112, 0, 0, 1,186, + 0, 0, 1, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 47, 0, 0, 1, 48, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,192, 0, 0, 0, 57, 0, 0, 1,188, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,188, 0, 0, 0,196, 0, 0, 0,192, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0,192, 0, 0, 0,196, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,196, + 0, 0, 1,188, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,189, 0, 0, 0, 59, 0, 0, 1,188, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,188, 0, 0, 1,190, 0, 0, 1,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,113, 0, 0, 1,189, + 0, 0, 1,190, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,190, 0, 0, 1,188, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,193, 0, 0, 0, 19, 0, 0, 1, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 48, 0, 0, 1,190, 0, 0, 0,193, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 0,193, 0, 0, 1,190, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,190, + 0, 0, 1, 48, 0, 0, 0,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,189, 0, 0, 0,113, 0, 0, 1, 49, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 49, 0, 0, 0,197, 0, 0, 1,189, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 1,189, + 0, 0, 0,197, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,197, 0, 0, 1, 49, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,191, 0, 0, 0, 56, 0, 0, 1,191, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,191, 0, 0, 1, 47, 0, 0, 0,191, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 19, 0, 0, 0,191, 0, 0, 1, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 47, + 0, 0, 1,191, 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,192, 0, 0, 0,112, 0, 0, 1,191, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,191, 0, 0, 1,193, 0, 0, 1,192, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 52, 0, 0, 1,192, + 0, 0, 1,193, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,193, 0, 0, 1,191, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0,182, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,182, 0, 0, 1,193, 0, 0, 0,190, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 56, 0, 0, 0,190, 0, 0, 1,193, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,193, + 0, 0, 0,182, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,192, 0, 0, 0, 52, 0, 0, 0,183, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,183, 0, 0, 1, 46, 0, 0, 1,192, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,112, 0, 0, 1,192, + 0, 0, 1, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 46, 0, 0, 0,183, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 51, 0, 0, 0,114, 0, 0, 1,194, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,194, 0, 0, 0,199, 0, 0, 1, 51, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 1, 51, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,199, + 0, 0, 1,194, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,195, 0, 0, 0, 60, 0, 0, 1,194, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,194, 0, 0, 1,196, 0, 0, 1,195, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 57, 0, 0, 1,195, + 0, 0, 1,196, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,196, 0, 0, 1,194, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 50, 0, 0, 0, 19, 0, 0, 0,193, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,193, 0, 0, 1,196, 0, 0, 1, 50, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,114, 0, 0, 1, 50, 0, 0, 1,196, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,196, + 0, 0, 0,193, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,195, 0, 0, 0, 57, 0, 0, 0,192, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,192, 0, 0, 0,198, 0, 0, 1,195, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 1,195, + 0, 0, 0,198, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,198, 0, 0, 0,192, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 50, 0, 0, 0,114, 0, 0, 1,197, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,197, 0, 0, 1, 53, 0, 0, 1, 50, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 19, 0, 0, 1, 50, 0, 0, 1, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 53, + 0, 0, 1,197, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,198, 0, 0, 0,115, 0, 0, 1,197, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,197, 0, 0, 1,199, 0, 0, 1,198, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,116, 0, 0, 1,198, + 0, 0, 1,199, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,199, 0, 0, 1,197, 0, 0, 0,114, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 51, 0, 0, 0, 21, 0, 0, 1, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 55, 0, 0, 1,199, 0, 0, 1, 51, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,114, 0, 0, 1, 51, 0, 0, 1,199, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,199, + 0, 0, 1, 55, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,198, 0, 0, 0,116, 0, 0, 1, 54, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 54, 0, 0, 1, 52, 0, 0, 1,198, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 1,198, + 0, 0, 1, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 52, 0, 0, 1, 54, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,176, 0, 0, 0, 49, 0, 0, 1,200, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,200, 0, 0, 0,200, 0, 0, 0,176, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0,176, 0, 0, 0,200, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,200, + 0, 0, 1,200, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,201, 0, 0, 0, 61, 0, 0, 1,200, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,200, 0, 0, 1,202, 0, 0, 1,201, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,116, 0, 0, 1,201, + 0, 0, 1,202, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,202, 0, 0, 1,200, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,177, 0, 0, 0, 15, 0, 0, 1, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 54, 0, 0, 1,202, 0, 0, 0,177, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 49, 0, 0, 0,177, 0, 0, 1,202, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,202, + 0, 0, 1, 54, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,201, 0, 0, 0,116, 0, 0, 1, 55, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 55, 0, 0, 0,201, 0, 0, 1,201, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 1,201, + 0, 0, 0,201, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,201, 0, 0, 1, 55, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,175, 0, 0, 0, 48, 0, 0, 1,203, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,203, 0, 0, 1, 52, 0, 0, 0,175, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0,175, 0, 0, 1, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 52, + 0, 0, 1,203, 0, 0, 0,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,204, 0, 0, 0,115, 0, 0, 1,203, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,203, 0, 0, 1,205, 0, 0, 1,204, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 56, 0, 0, 1,204, + 0, 0, 1,205, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,205, 0, 0, 1,203, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,174, 0, 0, 0, 0, 0, 0, 0,190, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,190, 0, 0, 1,205, 0, 0, 0,174, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 48, 0, 0, 0,174, 0, 0, 1,205, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,205, + 0, 0, 0,190, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,204, 0, 0, 0, 56, 0, 0, 0,191, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,191, 0, 0, 1, 53, 0, 0, 1,204, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,115, 0, 0, 1,204, + 0, 0, 1, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 53, 0, 0, 0,191, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,206, 0, 0, 0,117, 0, 0, 1, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 57, 0, 0, 0,207, 0, 0, 1,206, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 1,206, 0, 0, 0,207, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,207, + 0, 0, 1, 57, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,206, 0, 0, 0, 64, 0, 0, 1,207, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,207, 0, 0, 1,208, 0, 0, 1,206, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,117, 0, 0, 1,206, + 0, 0, 1,208, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,208, 0, 0, 1,207, 0, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,179, 0, 0, 0, 16, 0, 0, 1, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 56, 0, 0, 1,208, 0, 0, 0,179, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 0,179, 0, 0, 1,208, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,208, + 0, 0, 1, 56, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,178, 0, 0, 0, 50, 0, 0, 1,207, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,207, 0, 0, 0,206, 0, 0, 0,178, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0,178, + 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 1,207, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,209, 0, 0, 0,117, 0, 0, 1, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 56, 0, 0, 1, 58, 0, 0, 1,209, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,118, 0, 0, 1,209, 0, 0, 1, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 58, + 0, 0, 1, 56, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,209, 0, 0, 0,118, 0, 0, 1,210, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1,211, 0, 0, 1,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,117, 0, 0, 1,209, + 0, 0, 1,211, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,211, 0, 0, 1,210, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 61, 0, 0, 0, 23, 0, 0, 1, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 57, 0, 0, 1,211, 0, 0, 1, 61, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 1, 61, 0, 0, 1,211, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,211, + 0, 0, 1, 57, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 60, 0, 0, 0,119, 0, 0, 1,210, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,210, 0, 0, 1, 59, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 1, 60, + 0, 0, 1, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 59, 0, 0, 1,210, 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,212, 0, 0, 0, 63, 0, 0, 0,204, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,204, 0, 0, 0,208, 0, 0, 1,212, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 65, 0, 0, 1,212, 0, 0, 0,208, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,208, + 0, 0, 0,204, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,212, 0, 0, 0, 65, 0, 0, 1,213, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,213, 0, 0, 1,214, 0, 0, 1,212, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 63, 0, 0, 1,212, + 0, 0, 1,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,214, 0, 0, 1,213, 0, 0, 0,119, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 60, 0, 0, 0, 22, 0, 0, 0,205, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,205, 0, 0, 1,214, 0, 0, 1, 60, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,119, 0, 0, 1, 60, 0, 0, 1,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,214, + 0, 0, 0,205, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 61, 0, 0, 0,119, 0, 0, 1,213, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,213, 0, 0, 0,209, 0, 0, 1, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 23, 0, 0, 1, 61, + 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,209, 0, 0, 1,213, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,215, 0, 0, 0, 62, 0, 0, 0,203, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,203, 0, 0, 1, 59, 0, 0, 1,215, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,118, 0, 0, 1,215, 0, 0, 1, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 59, + 0, 0, 0,203, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,215, 0, 0, 0,118, 0, 0, 1,216, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,216, 0, 0, 1,217, 0, 0, 1,215, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1,215, + 0, 0, 1,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,217, 0, 0, 1,216, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,180, 0, 0, 0, 5, 0, 0, 0,202, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,202, 0, 0, 1,217, 0, 0, 0,180, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 51, 0, 0, 0,180, 0, 0, 1,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,217, + 0, 0, 0,202, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,181, 0, 0, 0, 51, 0, 0, 1,216, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,216, 0, 0, 1, 58, 0, 0, 0,181, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0,181, + 0, 0, 1, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 58, 0, 0, 1,216, 0, 0, 0,118, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,218, 0, 0, 0,120, 0, 0, 1, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 63, 0, 0, 0,215, 0, 0, 1,218, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 68, 0, 0, 1,218, 0, 0, 0,215, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,215, + 0, 0, 1, 63, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,218, 0, 0, 0, 68, 0, 0, 1,219, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,219, 0, 0, 1,220, 0, 0, 1,218, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,120, 0, 0, 1,218, + 0, 0, 1,220, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,220, 0, 0, 1,219, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,173, 0, 0, 0, 14, 0, 0, 1, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 62, 0, 0, 1,220, 0, 0, 0,173, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 47, 0, 0, 0,173, 0, 0, 1,220, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,220, + 0, 0, 1, 62, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,172, 0, 0, 0, 47, 0, 0, 1,219, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,219, 0, 0, 0,214, 0, 0, 0,172, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,172, + 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,214, 0, 0, 1,219, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,221, 0, 0, 0,120, 0, 0, 1, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 62, 0, 0, 1, 64, 0, 0, 1,221, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,121, 0, 0, 1,221, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 64, + 0, 0, 1, 62, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,221, 0, 0, 0,121, 0, 0, 1,222, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,222, 0, 0, 1,223, 0, 0, 1,221, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,120, 0, 0, 1,221, + 0, 0, 1,223, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,223, 0, 0, 1,222, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 67, 0, 0, 0, 25, 0, 0, 1, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 63, 0, 0, 1,223, 0, 0, 1, 67, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,122, 0, 0, 1, 67, 0, 0, 1,223, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,223, + 0, 0, 1, 63, 0, 0, 0,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 66, 0, 0, 0,122, 0, 0, 1,222, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,222, 0, 0, 1, 65, 0, 0, 1, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 1, 66, + 0, 0, 1, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 65, 0, 0, 1,222, 0, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,224, 0, 0, 0, 67, 0, 0, 0,212, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,212, 0, 0, 0,216, 0, 0, 1,224, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 1,224, 0, 0, 0,216, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,216, + 0, 0, 0,212, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,224, 0, 0, 0, 69, 0, 0, 1,225, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,225, 0, 0, 1,226, 0, 0, 1,224, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 67, 0, 0, 1,224, + 0, 0, 1,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,226, 0, 0, 1,225, 0, 0, 0,122, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 66, 0, 0, 0, 24, 0, 0, 0,213, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,213, 0, 0, 1,226, 0, 0, 1, 66, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,122, 0, 0, 1, 66, 0, 0, 1,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,226, + 0, 0, 0,213, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 67, 0, 0, 0,122, 0, 0, 1,225, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,225, 0, 0, 0,217, 0, 0, 1, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 25, 0, 0, 1, 67, + 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,217, 0, 0, 1,225, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,227, 0, 0, 0, 66, 0, 0, 0,211, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,211, 0, 0, 1, 65, 0, 0, 1,227, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,121, 0, 0, 1,227, 0, 0, 1, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 65, + 0, 0, 0,211, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,227, 0, 0, 0,121, 0, 0, 1,228, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,228, 0, 0, 1,229, 0, 0, 1,227, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 66, 0, 0, 1,227, + 0, 0, 1,229, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,229, 0, 0, 1,228, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,170, 0, 0, 0, 1, 0, 0, 0,210, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,210, 0, 0, 1,229, 0, 0, 0,170, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 46, 0, 0, 0,170, 0, 0, 1,229, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,229, + 0, 0, 0,210, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,171, 0, 0, 0, 46, 0, 0, 1,228, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,228, 0, 0, 1, 64, 0, 0, 0,171, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0,171, + 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 64, 0, 0, 1,228, 0, 0, 0,121, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,230, 0, 0, 0,123, 0, 0, 1, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 69, 0, 0, 0,223, 0, 0, 1,230, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 1,230, 0, 0, 0,223, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,223, + 0, 0, 1, 69, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,230, 0, 0, 0, 72, 0, 0, 1,231, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,231, 0, 0, 1,232, 0, 0, 1,230, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 1,230, + 0, 0, 1,232, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,232, 0, 0, 1,231, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,189, 0, 0, 0, 18, 0, 0, 1, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 68, 0, 0, 1,232, 0, 0, 0,189, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 55, 0, 0, 0,189, 0, 0, 1,232, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,232, + 0, 0, 1, 68, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,188, 0, 0, 0, 55, 0, 0, 1,231, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,231, 0, 0, 0,222, 0, 0, 0,188, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0,188, + 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 1,231, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,233, 0, 0, 0,123, 0, 0, 1, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 68, 0, 0, 1, 70, 0, 0, 1,233, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,124, 0, 0, 1,233, 0, 0, 1, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 70, + 0, 0, 1, 68, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,233, 0, 0, 0,124, 0, 0, 1,234, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1,235, 0, 0, 1,233, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,123, 0, 0, 1,233, + 0, 0, 1,235, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,235, 0, 0, 1,234, 0, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 73, 0, 0, 0, 27, 0, 0, 1, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 69, 0, 0, 1,235, 0, 0, 1, 73, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,125, 0, 0, 1, 73, 0, 0, 1,235, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,235, + 0, 0, 1, 69, 0, 0, 0,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 72, 0, 0, 0,125, 0, 0, 1,234, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,234, 0, 0, 1, 71, 0, 0, 1, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 1, 72, + 0, 0, 1, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 71, 0, 0, 1,234, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,236, 0, 0, 0, 71, 0, 0, 0,220, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,220, 0, 0, 0,224, 0, 0, 1,236, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 73, 0, 0, 1,236, 0, 0, 0,224, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,224, + 0, 0, 0,220, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,236, 0, 0, 0, 73, 0, 0, 1,237, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,237, 0, 0, 1,238, 0, 0, 1,236, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 71, 0, 0, 1,236, + 0, 0, 1,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,238, 0, 0, 1,237, 0, 0, 0,125, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 72, 0, 0, 0, 26, 0, 0, 0,221, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,221, 0, 0, 1,238, 0, 0, 1, 72, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,125, 0, 0, 1, 72, 0, 0, 1,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,238, + 0, 0, 0,221, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 73, 0, 0, 0,125, 0, 0, 1,237, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,237, 0, 0, 0,225, 0, 0, 1, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 1, 73, + 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,225, 0, 0, 1,237, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,239, 0, 0, 0, 70, 0, 0, 0,219, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,219, 0, 0, 1, 71, 0, 0, 1,239, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,124, 0, 0, 1,239, 0, 0, 1, 71, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 71, + 0, 0, 0,219, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,239, 0, 0, 0,124, 0, 0, 1,240, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,240, 0, 0, 1,241, 0, 0, 1,239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 70, 0, 0, 1,239, + 0, 0, 1,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,241, 0, 0, 1,240, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,186, 0, 0, 0, 2, 0, 0, 0,218, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,218, 0, 0, 1,241, 0, 0, 0,186, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 0,186, 0, 0, 1,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,241, + 0, 0, 0,218, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,187, 0, 0, 0, 54, 0, 0, 1,240, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,240, 0, 0, 1, 70, 0, 0, 0,187, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 0, 0, 0,187, + 0, 0, 1, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 70, 0, 0, 1,240, 0, 0, 0,124, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,242, 0, 0, 0,126, 0, 0, 1, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 75, 0, 0, 0,231, 0, 0, 1,242, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 1,242, 0, 0, 0,231, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,231, + 0, 0, 1, 75, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,242, 0, 0, 0, 76, 0, 0, 1,243, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,243, 0, 0, 1,244, 0, 0, 1,242, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,126, 0, 0, 1,242, + 0, 0, 1,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,244, 0, 0, 1,243, 0, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,197, 0, 0, 0, 20, 0, 0, 1, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 74, 0, 0, 1,244, 0, 0, 0,197, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 59, 0, 0, 0,197, 0, 0, 1,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,244, + 0, 0, 1, 74, 0, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,196, 0, 0, 0, 59, 0, 0, 1,243, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,243, 0, 0, 0,230, 0, 0, 0,196, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0,196, + 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,230, 0, 0, 1,243, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,245, 0, 0, 0,126, 0, 0, 1, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 74, 0, 0, 1, 76, 0, 0, 1,245, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,127, 0, 0, 1,245, 0, 0, 1, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 76, + 0, 0, 1, 74, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,245, 0, 0, 0,127, 0, 0, 1,246, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,246, 0, 0, 1,247, 0, 0, 1,245, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,126, 0, 0, 1,245, + 0, 0, 1,247, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,247, 0, 0, 1,246, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 79, 0, 0, 0, 29, 0, 0, 1, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 75, 0, 0, 1,247, 0, 0, 1, 79, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,128, 0, 0, 1, 79, 0, 0, 1,247, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,247, + 0, 0, 1, 75, 0, 0, 0,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 78, 0, 0, 0,128, 0, 0, 1,246, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,246, 0, 0, 1, 77, 0, 0, 1, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 1, 78, + 0, 0, 1, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 77, 0, 0, 1,246, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,248, 0, 0, 0, 75, 0, 0, 0,228, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,228, 0, 0, 0,232, 0, 0, 1,248, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 77, 0, 0, 1,248, 0, 0, 0,232, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,232, + 0, 0, 0,228, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,248, 0, 0, 0, 77, 0, 0, 1,249, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,249, 0, 0, 1,250, 0, 0, 1,248, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 75, 0, 0, 1,248, + 0, 0, 1,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,250, 0, 0, 1,249, 0, 0, 0,128, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 78, 0, 0, 0, 28, 0, 0, 0,229, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,229, 0, 0, 1,250, 0, 0, 1, 78, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,128, 0, 0, 1, 78, 0, 0, 1,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,250, + 0, 0, 0,229, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 79, 0, 0, 0,128, 0, 0, 1,249, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,249, 0, 0, 0,233, 0, 0, 1, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 1, 79, + 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,233, 0, 0, 1,249, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,251, 0, 0, 0, 74, 0, 0, 0,227, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,227, 0, 0, 1, 77, 0, 0, 1,251, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,127, 0, 0, 1,251, 0, 0, 1, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 77, + 0, 0, 0,227, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,251, 0, 0, 0,127, 0, 0, 1,252, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,252, 0, 0, 1,253, 0, 0, 1,251, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 74, 0, 0, 1,251, + 0, 0, 1,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,253, 0, 0, 1,252, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,194, 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,226, 0, 0, 1,253, 0, 0, 0,194, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 0, 0,194, 0, 0, 1,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,253, + 0, 0, 0,226, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,195, 0, 0, 0, 58, 0, 0, 1,252, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,252, 0, 0, 1, 76, 0, 0, 0,195, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0,195, + 0, 0, 1, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 76, 0, 0, 1,252, 0, 0, 0,127, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,254, 0, 0, 0,129, 0, 0, 1, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 81, 0, 0, 0,239, 0, 0, 1,254, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 1,254, 0, 0, 0,239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,239, + 0, 0, 1, 81, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,254, 0, 0, 0, 80, 0, 0, 1,255, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,255, 0, 0, 2, 0, 0, 0, 1,254, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,129, 0, 0, 1,254, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 1,255, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,201, 0, 0, 0, 21, 0, 0, 1, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 80, 0, 0, 2, 0, 0, 0, 0,201, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 61, 0, 0, 0,201, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, + 0, 0, 1, 80, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,200, 0, 0, 0, 61, 0, 0, 1,255, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,255, 0, 0, 0,238, 0, 0, 0,200, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0,200, + 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,238, 0, 0, 1,255, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 1, 0, 0, 0,129, 0, 0, 1, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 80, 0, 0, 1, 82, 0, 0, 2, 1, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 2, 1, 0, 0, 1, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 82, + 0, 0, 1, 80, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 1, 0, 0, 0,130, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 2, 0, 0, 2, 3, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,129, 0, 0, 2, 1, + 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, 0, 0, 2, 2, 0, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 85, 0, 0, 0, 31, 0, 0, 1, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 81, 0, 0, 2, 3, 0, 0, 1, 85, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,131, 0, 0, 1, 85, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, + 0, 0, 1, 81, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 84, 0, 0, 0,131, 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 2, 0, 0, 1, 83, 0, 0, 1, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 1, 84, + 0, 0, 1, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 83, 0, 0, 2, 2, 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 4, 0, 0, 0, 79, 0, 0, 0,236, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,236, 0, 0, 0,240, 0, 0, 2, 4, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 81, 0, 0, 2, 4, 0, 0, 0,240, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,240, + 0, 0, 0,236, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 4, 0, 0, 0, 81, 0, 0, 2, 5, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 5, 0, 0, 2, 6, 0, 0, 2, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 79, 0, 0, 2, 4, + 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 6, 0, 0, 2, 5, 0, 0, 0,131, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 84, 0, 0, 0, 30, 0, 0, 0,237, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,237, 0, 0, 2, 6, 0, 0, 1, 84, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,131, 0, 0, 1, 84, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 6, + 0, 0, 0,237, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 85, 0, 0, 0,131, 0, 0, 2, 5, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 5, 0, 0, 0,241, 0, 0, 1, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 1, 85, + 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,241, 0, 0, 2, 5, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 7, 0, 0, 0, 78, 0, 0, 0,235, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,235, 0, 0, 1, 83, 0, 0, 2, 7, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,130, 0, 0, 2, 7, 0, 0, 1, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 83, + 0, 0, 0,235, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 7, 0, 0, 0,130, 0, 0, 2, 8, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 8, 0, 0, 2, 9, 0, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 2, 7, + 0, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 9, 0, 0, 2, 8, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,198, 0, 0, 0, 4, 0, 0, 0,234, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,234, 0, 0, 2, 9, 0, 0, 0,198, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0,198, 0, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 9, + 0, 0, 0,234, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,199, 0, 0, 0, 60, 0, 0, 2, 8, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 8, 0, 0, 1, 82, 0, 0, 0,199, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 21, 0, 0, 0,199, + 0, 0, 1, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 82, 0, 0, 2, 8, 0, 0, 0,130, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 87, 0, 0, 0,132, 0, 0, 2, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 10, 0, 0, 0,245, 0, 0, 1, 87, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 1, 87, 0, 0, 0,245, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,245, + 0, 0, 2, 10, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 11, 0, 0, 0, 83, 0, 0, 2, 10, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 10, 0, 0, 2, 12, 0, 0, 2, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 65, 0, 0, 2, 11, + 0, 0, 2, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 12, 0, 0, 2, 10, 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 86, 0, 0, 0, 23, 0, 0, 0,209, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,209, 0, 0, 2, 12, 0, 0, 1, 86, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,132, 0, 0, 1, 86, 0, 0, 2, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 12, + 0, 0, 0,209, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 11, 0, 0, 0, 65, 0, 0, 0,208, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,208, 0, 0, 0,244, 0, 0, 2, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 83, 0, 0, 2, 11, + 0, 0, 0,244, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,244, 0, 0, 0,208, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 86, 0, 0, 0,132, 0, 0, 2, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 13, 0, 0, 1, 88, 0, 0, 1, 86, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 23, 0, 0, 1, 86, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 88, + 0, 0, 2, 13, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 14, 0, 0, 0,133, 0, 0, 2, 13, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 13, 0, 0, 2, 15, 0, 0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,134, 0, 0, 2, 14, + 0, 0, 2, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 15, 0, 0, 2, 13, 0, 0, 0,132, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 87, 0, 0, 0, 32, 0, 0, 1, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 91, 0, 0, 2, 15, 0, 0, 1, 87, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,132, 0, 0, 1, 87, 0, 0, 2, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 15, + 0, 0, 1, 91, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 14, 0, 0, 0,134, 0, 0, 1, 90, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 90, 0, 0, 1, 89, 0, 0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,133, 0, 0, 2, 14, + 0, 0, 1, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 89, 0, 0, 1, 90, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,212, 0, 0, 0, 67, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 16, 0, 0, 0,242, 0, 0, 0,212, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0,212, 0, 0, 0,242, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,242, + 0, 0, 2, 16, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 17, 0, 0, 0, 82, 0, 0, 2, 16, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 16, 0, 0, 2, 18, 0, 0, 2, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,134, 0, 0, 2, 17, + 0, 0, 2, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 18, 0, 0, 2, 16, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,213, 0, 0, 0, 24, 0, 0, 1, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 90, 0, 0, 2, 18, 0, 0, 0,213, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 67, 0, 0, 0,213, 0, 0, 2, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 18, + 0, 0, 1, 90, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 17, 0, 0, 0,134, 0, 0, 1, 91, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 91, 0, 0, 0,243, 0, 0, 2, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 2, 17, + 0, 0, 0,243, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,243, 0, 0, 1, 91, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,211, 0, 0, 0, 66, 0, 0, 2, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 19, 0, 0, 1, 89, 0, 0, 0,211, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 24, 0, 0, 0,211, 0, 0, 1, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 89, + 0, 0, 2, 19, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 20, 0, 0, 0,133, 0, 0, 2, 19, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 19, 0, 0, 2, 21, 0, 0, 2, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 64, 0, 0, 2, 20, + 0, 0, 2, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 21, 0, 0, 2, 19, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,210, 0, 0, 0, 1, 0, 0, 0,206, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,206, 0, 0, 2, 21, 0, 0, 0,210, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 66, 0, 0, 0,210, 0, 0, 2, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 21, + 0, 0, 0,206, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 20, 0, 0, 0, 64, 0, 0, 0,207, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,207, 0, 0, 1, 88, 0, 0, 2, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,133, 0, 0, 2, 20, + 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 88, 0, 0, 0,207, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 93, 0, 0, 0,135, 0, 0, 2, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 22, 0, 0, 0,247, 0, 0, 1, 93, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 1, 93, 0, 0, 0,247, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,247, + 0, 0, 2, 22, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 23, 0, 0, 0, 84, 0, 0, 2, 22, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 22, 0, 0, 2, 24, 0, 0, 2, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 69, 0, 0, 2, 23, + 0, 0, 2, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 24, 0, 0, 2, 22, 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 92, 0, 0, 0, 25, 0, 0, 0,217, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,217, 0, 0, 2, 24, 0, 0, 1, 92, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,135, 0, 0, 1, 92, 0, 0, 2, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 24, + 0, 0, 0,217, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 23, 0, 0, 0, 69, 0, 0, 0,216, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,216, 0, 0, 0,246, 0, 0, 2, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 2, 23, + 0, 0, 0,246, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,246, 0, 0, 0,216, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 92, 0, 0, 0,135, 0, 0, 2, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 25, 0, 0, 1, 94, 0, 0, 1, 92, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 25, 0, 0, 1, 92, 0, 0, 1, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 94, + 0, 0, 2, 25, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 26, 0, 0, 0,136, 0, 0, 2, 25, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 25, 0, 0, 2, 27, 0, 0, 2, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,137, 0, 0, 2, 26, + 0, 0, 2, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 27, 0, 0, 2, 25, 0, 0, 0,135, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 93, 0, 0, 0, 33, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 97, 0, 0, 2, 27, 0, 0, 1, 93, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,135, 0, 0, 1, 93, 0, 0, 2, 27, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 27, + 0, 0, 1, 97, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 26, 0, 0, 0,137, 0, 0, 1, 96, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 96, 0, 0, 1, 95, 0, 0, 2, 26, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,136, 0, 0, 2, 26, + 0, 0, 1, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 95, 0, 0, 1, 96, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,220, 0, 0, 0, 71, 0, 0, 2, 28, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 28, 0, 0, 0,248, 0, 0, 0,220, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0,220, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,248, + 0, 0, 2, 28, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 29, 0, 0, 0, 85, 0, 0, 2, 28, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 28, 0, 0, 2, 30, 0, 0, 2, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,137, 0, 0, 2, 29, + 0, 0, 2, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 30, 0, 0, 2, 28, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,221, 0, 0, 0, 26, 0, 0, 1, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 96, 0, 0, 2, 30, 0, 0, 0,221, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 71, 0, 0, 0,221, 0, 0, 2, 30, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 30, + 0, 0, 1, 96, 0, 0, 0,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 29, 0, 0, 0,137, 0, 0, 1, 97, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1, 97, 0, 0, 0,249, 0, 0, 2, 29, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 2, 29, + 0, 0, 0,249, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,249, 0, 0, 1, 97, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,219, 0, 0, 0, 70, 0, 0, 2, 31, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 31, 0, 0, 1, 95, 0, 0, 0,219, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0,219, 0, 0, 1, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 95, + 0, 0, 2, 31, 0, 0, 0,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 32, 0, 0, 0,136, 0, 0, 2, 31, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 31, 0, 0, 2, 33, 0, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 68, 0, 0, 2, 32, + 0, 0, 2, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 33, 0, 0, 2, 31, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,218, 0, 0, 0, 2, 0, 0, 0,214, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,214, 0, 0, 2, 33, 0, 0, 0,218, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 70, 0, 0, 0,218, 0, 0, 2, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 33, + 0, 0, 0,214, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 32, 0, 0, 0, 68, 0, 0, 0,215, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,215, 0, 0, 1, 94, 0, 0, 2, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,136, 0, 0, 2, 32, + 0, 0, 1, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 94, 0, 0, 0,215, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 99, 0, 0, 0,138, 0, 0, 2, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 34, 0, 0, 0,251, 0, 0, 1, 99, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 1, 99, 0, 0, 0,251, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,251, + 0, 0, 2, 34, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 35, 0, 0, 0, 86, 0, 0, 2, 34, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 34, 0, 0, 2, 36, 0, 0, 2, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 73, 0, 0, 2, 35, + 0, 0, 2, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 36, 0, 0, 2, 34, 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 98, 0, 0, 0, 27, 0, 0, 0,225, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,225, 0, 0, 2, 36, 0, 0, 1, 98, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 1, 98, 0, 0, 2, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 36, + 0, 0, 0,225, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 35, 0, 0, 0, 73, 0, 0, 0,224, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,224, 0, 0, 0,250, 0, 0, 2, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 2, 35, + 0, 0, 0,250, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,250, 0, 0, 0,224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 98, 0, 0, 0,138, 0, 0, 2, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 37, 0, 0, 1,100, 0, 0, 1, 98, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 1, 98, 0, 0, 1,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,100, + 0, 0, 2, 37, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 38, 0, 0, 0,139, 0, 0, 2, 37, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 37, 0, 0, 2, 39, 0, 0, 2, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,140, 0, 0, 2, 38, + 0, 0, 2, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 39, 0, 0, 2, 37, 0, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 99, 0, 0, 0, 34, 0, 0, 1,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,103, 0, 0, 2, 39, 0, 0, 1, 99, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,138, 0, 0, 1, 99, 0, 0, 2, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 39, + 0, 0, 1,103, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 38, 0, 0, 0,140, 0, 0, 1,102, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,102, 0, 0, 1,101, 0, 0, 2, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,139, 0, 0, 2, 38, + 0, 0, 1,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,101, 0, 0, 1,102, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,228, 0, 0, 0, 75, 0, 0, 2, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 40, 0, 0, 0,252, 0, 0, 0,228, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,228, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,252, + 0, 0, 2, 40, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 41, 0, 0, 0, 87, 0, 0, 2, 40, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 40, 0, 0, 2, 42, 0, 0, 2, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,140, 0, 0, 2, 41, + 0, 0, 2, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 42, 0, 0, 2, 40, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,229, 0, 0, 0, 28, 0, 0, 1,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,102, 0, 0, 2, 42, 0, 0, 0,229, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 75, 0, 0, 0,229, 0, 0, 2, 42, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 42, + 0, 0, 1,102, 0, 0, 0,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 41, 0, 0, 0,140, 0, 0, 1,103, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,103, 0, 0, 0,253, 0, 0, 2, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 2, 41, + 0, 0, 0,253, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,253, 0, 0, 1,103, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,227, 0, 0, 0, 74, 0, 0, 2, 43, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 43, 0, 0, 1,101, 0, 0, 0,227, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0,227, 0, 0, 1,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,101, + 0, 0, 2, 43, 0, 0, 0,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 44, 0, 0, 0,139, 0, 0, 2, 43, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 43, 0, 0, 2, 45, 0, 0, 2, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 2, 44, + 0, 0, 2, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 45, 0, 0, 2, 43, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,226, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,222, 0, 0, 2, 45, 0, 0, 0,226, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 74, 0, 0, 0,226, 0, 0, 2, 45, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 45, + 0, 0, 0,222, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 44, 0, 0, 0, 72, 0, 0, 0,223, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,223, 0, 0, 1,100, 0, 0, 2, 44, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,139, 0, 0, 2, 44, + 0, 0, 1,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,100, 0, 0, 0,223, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,105, 0, 0, 0,141, 0, 0, 2, 46, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 46, 0, 0, 0,255, 0, 0, 1,105, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 1,105, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255, + 0, 0, 2, 46, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 47, 0, 0, 0, 88, 0, 0, 2, 46, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 46, 0, 0, 2, 48, 0, 0, 2, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 77, 0, 0, 2, 47, + 0, 0, 2, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 48, 0, 0, 2, 46, 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,104, 0, 0, 0, 29, 0, 0, 0,233, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,233, 0, 0, 2, 48, 0, 0, 1,104, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 1,104, 0, 0, 2, 48, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 48, + 0, 0, 0,233, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 47, 0, 0, 0, 77, 0, 0, 0,232, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,232, 0, 0, 0,254, 0, 0, 2, 47, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 2, 47, + 0, 0, 0,254, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,254, 0, 0, 0,232, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,104, 0, 0, 0,141, 0, 0, 2, 49, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 49, 0, 0, 1,106, 0, 0, 1,104, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 1,104, 0, 0, 1,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,106, + 0, 0, 2, 49, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 50, 0, 0, 0,142, 0, 0, 2, 49, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 49, 0, 0, 2, 51, 0, 0, 2, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,143, 0, 0, 2, 50, + 0, 0, 2, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 51, 0, 0, 2, 49, 0, 0, 0,141, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,105, 0, 0, 0, 35, 0, 0, 1,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,109, 0, 0, 2, 51, 0, 0, 1,105, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,141, 0, 0, 1,105, 0, 0, 2, 51, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 51, + 0, 0, 1,109, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 50, 0, 0, 0,143, 0, 0, 1,108, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,108, 0, 0, 1,107, 0, 0, 2, 50, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,142, 0, 0, 2, 50, + 0, 0, 1,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,107, 0, 0, 1,108, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,236, 0, 0, 0, 79, 0, 0, 2, 52, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 52, 0, 0, 1, 0, 0, 0, 0,236, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 0,236, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, + 0, 0, 2, 52, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 53, 0, 0, 0, 89, 0, 0, 2, 52, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 52, 0, 0, 2, 54, 0, 0, 2, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,143, 0, 0, 2, 53, + 0, 0, 2, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 54, 0, 0, 2, 52, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,237, 0, 0, 0, 30, 0, 0, 1,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,108, 0, 0, 2, 54, 0, 0, 0,237, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 79, 0, 0, 0,237, 0, 0, 2, 54, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 54, + 0, 0, 1,108, 0, 0, 0,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 53, 0, 0, 0,143, 0, 0, 1,109, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,109, 0, 0, 1, 1, 0, 0, 2, 53, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 2, 53, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 1,109, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,235, 0, 0, 0, 78, 0, 0, 2, 55, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 55, 0, 0, 1,107, 0, 0, 0,235, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0,235, 0, 0, 1,107, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,107, + 0, 0, 2, 55, 0, 0, 0,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 56, 0, 0, 0,142, 0, 0, 2, 55, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 55, 0, 0, 2, 57, 0, 0, 2, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 76, 0, 0, 2, 56, + 0, 0, 2, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 57, 0, 0, 2, 55, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,234, 0, 0, 0, 4, 0, 0, 0,230, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,230, 0, 0, 2, 57, 0, 0, 0,234, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0, 0,234, 0, 0, 2, 57, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 57, + 0, 0, 0,230, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 56, 0, 0, 0, 76, 0, 0, 0,231, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,231, 0, 0, 1,106, 0, 0, 2, 56, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,142, 0, 0, 2, 56, + 0, 0, 1,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,106, 0, 0, 0,231, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,111, 0, 0, 0,144, 0, 0, 2, 58, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 58, 0, 0, 1, 3, 0, 0, 1,111, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 1,111, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3, + 0, 0, 2, 58, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 59, 0, 0, 0, 90, 0, 0, 2, 58, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 58, 0, 0, 2, 60, 0, 0, 2, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 81, 0, 0, 2, 59, + 0, 0, 2, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 60, 0, 0, 2, 58, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,110, 0, 0, 0, 31, 0, 0, 0,241, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,241, 0, 0, 2, 60, 0, 0, 1,110, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,144, 0, 0, 1,110, 0, 0, 2, 60, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 60, + 0, 0, 0,241, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 59, 0, 0, 0, 81, 0, 0, 0,240, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,240, 0, 0, 1, 2, 0, 0, 2, 59, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 90, 0, 0, 2, 59, + 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 2, 0, 0, 0,240, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,110, 0, 0, 0,144, 0, 0, 2, 61, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 61, 0, 0, 1,113, 0, 0, 1,110, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 1,110, 0, 0, 1,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,113, + 0, 0, 2, 61, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 62, 0, 0, 0,145, 0, 0, 2, 61, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 61, 0, 0, 2, 63, 0, 0, 2, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 2, 62, + 0, 0, 2, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 63, 0, 0, 2, 61, 0, 0, 0,144, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,111, 0, 0, 0, 36, 0, 0, 1,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,115, 0, 0, 2, 63, 0, 0, 1,111, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,144, 0, 0, 1,111, 0, 0, 2, 63, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 63, + 0, 0, 1,115, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 62, 0, 0, 0,146, 0, 0, 1,114, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,114, 0, 0, 1,112, 0, 0, 2, 62, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,145, 0, 0, 2, 62, + 0, 0, 1,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,112, 0, 0, 1,114, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,204, 0, 0, 0, 63, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 64, 0, 0, 1, 4, 0, 0, 0,204, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 0,204, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 4, + 0, 0, 2, 64, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 65, 0, 0, 0, 91, 0, 0, 2, 64, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 64, 0, 0, 2, 66, 0, 0, 2, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,146, 0, 0, 2, 65, + 0, 0, 2, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 66, 0, 0, 2, 64, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,205, 0, 0, 0, 22, 0, 0, 1,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,114, 0, 0, 2, 66, 0, 0, 0,205, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 63, 0, 0, 0,205, 0, 0, 2, 66, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 66, + 0, 0, 1,114, 0, 0, 0,146, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 65, 0, 0, 0,146, 0, 0, 1,115, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 1,115, 0, 0, 1, 5, 0, 0, 2, 65, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 91, 0, 0, 2, 65, + 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 5, 0, 0, 1,115, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,203, 0, 0, 0, 62, 0, 0, 2, 67, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 67, 0, 0, 1,112, 0, 0, 0,203, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 22, 0, 0, 0,203, 0, 0, 1,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,112, + 0, 0, 2, 67, 0, 0, 0,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 68, 0, 0, 0,145, 0, 0, 2, 67, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 67, 0, 0, 2, 69, 0, 0, 2, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 80, 0, 0, 2, 68, + 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 69, 0, 0, 2, 67, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,202, 0, 0, 0, 5, 0, 0, 0,238, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,238, 0, 0, 2, 69, 0, 0, 0,202, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 0,202, 0, 0, 2, 69, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 69, + 0, 0, 0,238, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 68, 0, 0, 0, 80, 0, 0, 0,239, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0,239, 0, 0, 1,113, 0, 0, 2, 68, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,145, 0, 0, 2, 68, + 0, 0, 1,113, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,113, 0, 0, 0,239, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 70, 0, 0, 0,147, 0, 0, 1,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,117, 0, 0, 1, 11, 0, 0, 2, 70, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 94, 0, 0, 2, 70, 0, 0, 1, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 11, + 0, 0, 1,117, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 70, 0, 0, 0, 94, 0, 0, 2, 71, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 71, 0, 0, 2, 72, 0, 0, 2, 70, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,147, 0, 0, 2, 70, + 0, 0, 2, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 72, 0, 0, 2, 71, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,243, 0, 0, 0, 32, 0, 0, 1,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,116, 0, 0, 2, 72, 0, 0, 0,243, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 82, 0, 0, 0,243, 0, 0, 2, 72, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 72, + 0, 0, 1,116, 0, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,242, 0, 0, 0, 82, 0, 0, 2, 71, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 71, 0, 0, 1, 10, 0, 0, 0,242, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0,242, + 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 10, 0, 0, 2, 71, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 73, 0, 0, 0,147, 0, 0, 1,116, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,116, 0, 0, 1,118, 0, 0, 2, 73, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,148, 0, 0, 2, 73, 0, 0, 1,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,118, + 0, 0, 1,116, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 73, 0, 0, 0,148, 0, 0, 2, 74, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 74, 0, 0, 2, 75, 0, 0, 2, 73, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,147, 0, 0, 2, 73, + 0, 0, 2, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 75, 0, 0, 2, 74, 0, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,121, 0, 0, 0, 38, 0, 0, 1,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,117, 0, 0, 2, 75, 0, 0, 1,121, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,149, 0, 0, 1,121, 0, 0, 2, 75, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 75, + 0, 0, 1,117, 0, 0, 0,147, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,120, 0, 0, 0,149, 0, 0, 2, 74, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 74, 0, 0, 1,119, 0, 0, 1,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 1,120, + 0, 0, 1,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,119, 0, 0, 2, 74, 0, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 76, 0, 0, 0, 93, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 8, 0, 0, 1, 12, 0, 0, 2, 76, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 2, 76, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 12, + 0, 0, 1, 8, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 76, 0, 0, 0, 95, 0, 0, 2, 77, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 77, 0, 0, 2, 78, 0, 0, 2, 76, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 2, 76, + 0, 0, 2, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 78, 0, 0, 2, 77, 0, 0, 0,149, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,120, 0, 0, 0, 37, 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 9, 0, 0, 2, 78, 0, 0, 1,120, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,149, 0, 0, 1,120, 0, 0, 2, 78, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 78, + 0, 0, 1, 9, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,121, 0, 0, 0,149, 0, 0, 2, 77, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 77, 0, 0, 1, 13, 0, 0, 1,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 1,121, + 0, 0, 1, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 13, 0, 0, 2, 77, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 79, 0, 0, 0, 92, 0, 0, 1, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 7, 0, 0, 1,119, 0, 0, 2, 79, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,148, 0, 0, 2, 79, 0, 0, 1,119, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,119, + 0, 0, 1, 7, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 79, 0, 0, 0,148, 0, 0, 2, 80, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 80, 0, 0, 2, 81, 0, 0, 2, 79, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 92, 0, 0, 2, 79, + 0, 0, 2, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 81, 0, 0, 2, 80, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,244, 0, 0, 0, 10, 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 6, 0, 0, 2, 81, 0, 0, 0,244, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 83, 0, 0, 0,244, 0, 0, 2, 81, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 81, + 0, 0, 1, 6, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,245, 0, 0, 0, 83, 0, 0, 2, 80, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 80, 0, 0, 1,118, 0, 0, 0,245, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0,245, + 0, 0, 1,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,118, 0, 0, 2, 80, 0, 0, 0,148, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 82, 0, 0, 0,150, 0, 0, 1,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,123, 0, 0, 1, 15, 0, 0, 2, 82, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 96, 0, 0, 2, 82, 0, 0, 1, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 15, + 0, 0, 1,123, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 82, 0, 0, 0, 96, 0, 0, 2, 83, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 83, 0, 0, 2, 84, 0, 0, 2, 82, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 2, 82, + 0, 0, 2, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 84, 0, 0, 2, 83, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,249, 0, 0, 0, 33, 0, 0, 1,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,122, 0, 0, 2, 84, 0, 0, 0,249, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 85, 0, 0, 0,249, 0, 0, 2, 84, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 84, + 0, 0, 1,122, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,248, 0, 0, 0, 85, 0, 0, 2, 83, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 83, 0, 0, 1, 14, 0, 0, 0,248, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0,248, + 0, 0, 1, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 14, 0, 0, 2, 83, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 85, 0, 0, 0,150, 0, 0, 1,122, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,122, 0, 0, 1,124, 0, 0, 2, 85, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,151, 0, 0, 2, 85, 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,124, + 0, 0, 1,122, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 85, 0, 0, 0,151, 0, 0, 2, 86, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 86, 0, 0, 2, 87, 0, 0, 2, 85, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,150, 0, 0, 2, 85, + 0, 0, 2, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 87, 0, 0, 2, 86, 0, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,127, 0, 0, 0, 39, 0, 0, 1,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,123, 0, 0, 2, 87, 0, 0, 1,127, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 1,127, 0, 0, 2, 87, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 87, + 0, 0, 1,123, 0, 0, 0,150, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,126, 0, 0, 0,152, 0, 0, 2, 86, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 86, 0, 0, 1,125, 0, 0, 1,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 1,126, + 0, 0, 1,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,125, 0, 0, 2, 86, 0, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 88, 0, 0, 0, 95, 0, 0, 1, 12, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 12, 0, 0, 1, 16, 0, 0, 2, 88, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 97, 0, 0, 2, 88, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 16, + 0, 0, 1, 12, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 88, 0, 0, 0, 97, 0, 0, 2, 89, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 89, 0, 0, 2, 90, 0, 0, 2, 88, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 95, 0, 0, 2, 88, + 0, 0, 2, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 90, 0, 0, 2, 89, 0, 0, 0,152, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,126, 0, 0, 0, 38, 0, 0, 1, 13, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 13, 0, 0, 2, 90, 0, 0, 1,126, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,152, 0, 0, 1,126, 0, 0, 2, 90, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 90, + 0, 0, 1, 13, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,127, 0, 0, 0,152, 0, 0, 2, 89, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 89, 0, 0, 1, 17, 0, 0, 1,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 1,127, + 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 17, 0, 0, 2, 89, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 91, 0, 0, 0, 94, 0, 0, 1, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 11, 0, 0, 1,125, 0, 0, 2, 91, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,151, 0, 0, 2, 91, 0, 0, 1,125, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,125, + 0, 0, 1, 11, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 91, 0, 0, 0,151, 0, 0, 2, 92, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 92, 0, 0, 2, 93, 0, 0, 2, 91, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 94, 0, 0, 2, 91, + 0, 0, 2, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 93, 0, 0, 2, 92, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,246, 0, 0, 0, 6, 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 10, 0, 0, 2, 93, 0, 0, 0,246, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 84, 0, 0, 0,246, 0, 0, 2, 93, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 93, + 0, 0, 1, 10, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,247, 0, 0, 0, 84, 0, 0, 2, 92, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 92, 0, 0, 1,124, 0, 0, 0,247, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0,247, + 0, 0, 1,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,124, 0, 0, 2, 92, 0, 0, 0,151, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 94, 0, 0, 0,153, 0, 0, 1,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,129, 0, 0, 1, 19, 0, 0, 2, 94, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 2, 94, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 19, + 0, 0, 1,129, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 94, 0, 0, 0, 98, 0, 0, 2, 95, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 95, 0, 0, 2, 96, 0, 0, 2, 94, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,153, 0, 0, 2, 94, + 0, 0, 2, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 96, 0, 0, 2, 95, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,253, 0, 0, 0, 34, 0, 0, 1,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,128, 0, 0, 2, 96, 0, 0, 0,253, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 87, 0, 0, 0,253, 0, 0, 2, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 96, + 0, 0, 1,128, 0, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,252, 0, 0, 0, 87, 0, 0, 2, 95, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 95, 0, 0, 1, 18, 0, 0, 0,252, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,252, + 0, 0, 1, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 18, 0, 0, 2, 95, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2, 97, 0, 0, 0,153, 0, 0, 1,128, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,128, 0, 0, 1,130, 0, 0, 2, 97, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 2, 97, 0, 0, 1,130, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,130, + 0, 0, 1,128, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 97, 0, 0, 0,154, 0, 0, 2, 98, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 98, 0, 0, 2, 99, 0, 0, 2, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,153, 0, 0, 2, 97, + 0, 0, 2, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 99, 0, 0, 2, 98, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,133, 0, 0, 0, 40, 0, 0, 1,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,129, 0, 0, 2, 99, 0, 0, 1,133, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,155, 0, 0, 1,133, 0, 0, 2, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 99, + 0, 0, 1,129, 0, 0, 0,153, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,132, 0, 0, 0,155, 0, 0, 2, 98, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2, 98, 0, 0, 1,131, 0, 0, 1,132, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 1,132, + 0, 0, 1,131, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,131, 0, 0, 2, 98, 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,100, 0, 0, 0, 97, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 16, 0, 0, 1, 20, 0, 0, 2,100, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 2,100, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 20, + 0, 0, 1, 16, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,100, 0, 0, 0, 99, 0, 0, 2,101, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,101, 0, 0, 2,102, 0, 0, 2,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 97, 0, 0, 2,100, + 0, 0, 2,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,102, 0, 0, 2,101, 0, 0, 0,155, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,132, 0, 0, 0, 39, 0, 0, 1, 17, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 17, 0, 0, 2,102, 0, 0, 1,132, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,155, 0, 0, 1,132, 0, 0, 2,102, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,102, + 0, 0, 1, 17, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,133, 0, 0, 0,155, 0, 0, 2,101, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,101, 0, 0, 1, 21, 0, 0, 1,133, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 1,133, + 0, 0, 1, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 21, 0, 0, 2,101, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,103, 0, 0, 0, 96, 0, 0, 1, 15, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 15, 0, 0, 1,131, 0, 0, 2,103, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,154, 0, 0, 2,103, 0, 0, 1,131, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,131, + 0, 0, 1, 15, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,103, 0, 0, 0,154, 0, 0, 2,104, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,104, 0, 0, 2,105, 0, 0, 2,103, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 96, 0, 0, 2,103, + 0, 0, 2,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,105, 0, 0, 2,104, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,250, 0, 0, 0, 7, 0, 0, 1, 14, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 14, 0, 0, 2,105, 0, 0, 0,250, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 86, 0, 0, 0,250, 0, 0, 2,105, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,105, + 0, 0, 1, 14, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,251, 0, 0, 0, 86, 0, 0, 2,104, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,104, 0, 0, 1,130, 0, 0, 0,251, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0,251, + 0, 0, 1,130, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,130, 0, 0, 2,104, 0, 0, 0,154, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,106, 0, 0, 0,156, 0, 0, 1,135, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,135, 0, 0, 1, 23, 0, 0, 2,106, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,100, 0, 0, 2,106, 0, 0, 1, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 23, + 0, 0, 1,135, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,106, 0, 0, 0,100, 0, 0, 2,107, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,107, 0, 0, 2,108, 0, 0, 2,106, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,156, 0, 0, 2,106, + 0, 0, 2,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,108, 0, 0, 2,107, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 1, 0, 0, 0, 35, 0, 0, 1,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,134, 0, 0, 2,108, 0, 0, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 89, 0, 0, 1, 1, 0, 0, 2,108, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,108, + 0, 0, 1,134, 0, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 89, 0, 0, 2,107, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,107, 0, 0, 1, 22, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 9, 0, 0, 1, 0, + 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 22, 0, 0, 2,107, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,109, 0, 0, 0,156, 0, 0, 1,134, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,134, 0, 0, 1,136, 0, 0, 2,109, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,157, 0, 0, 2,109, 0, 0, 1,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,136, + 0, 0, 1,134, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,109, 0, 0, 0,157, 0, 0, 2,110, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,110, 0, 0, 2,111, 0, 0, 2,109, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,156, 0, 0, 2,109, + 0, 0, 2,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,111, 0, 0, 2,110, 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,139, 0, 0, 0, 41, 0, 0, 1,135, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,135, 0, 0, 2,111, 0, 0, 1,139, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 1,139, 0, 0, 2,111, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,111, + 0, 0, 1,135, 0, 0, 0,156, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,138, 0, 0, 0,158, 0, 0, 2,110, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,110, 0, 0, 1,137, 0, 0, 1,138, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 1,138, + 0, 0, 1,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,137, 0, 0, 2,110, 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,112, 0, 0, 0, 99, 0, 0, 1, 20, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 20, 0, 0, 1, 24, 0, 0, 2,112, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 2,112, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 24, + 0, 0, 1, 20, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,112, 0, 0, 0,101, 0, 0, 2,113, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,113, 0, 0, 2,114, 0, 0, 2,112, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 99, 0, 0, 2,112, + 0, 0, 2,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,114, 0, 0, 2,113, 0, 0, 0,158, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,138, 0, 0, 0, 40, 0, 0, 1, 21, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 21, 0, 0, 2,114, 0, 0, 1,138, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,158, 0, 0, 1,138, 0, 0, 2,114, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,114, + 0, 0, 1, 21, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,139, 0, 0, 0,158, 0, 0, 2,113, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,113, 0, 0, 1, 25, 0, 0, 1,139, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 1,139, + 0, 0, 1, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 25, 0, 0, 2,113, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,115, 0, 0, 0, 98, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 19, 0, 0, 1,137, 0, 0, 2,115, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,157, 0, 0, 2,115, 0, 0, 1,137, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,137, + 0, 0, 1, 19, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,115, 0, 0, 0,157, 0, 0, 2,116, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,116, 0, 0, 2,117, 0, 0, 2,115, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 2,115, + 0, 0, 2,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,117, 0, 0, 2,116, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0,254, 0, 0, 0, 8, 0, 0, 1, 18, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 18, 0, 0, 2,117, 0, 0, 0,254, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 0, 0, 0,254, 0, 0, 2,117, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,117, + 0, 0, 1, 18, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,255, 0, 0, 0, 88, 0, 0, 2,116, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,116, 0, 0, 1,136, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0,255, + 0, 0, 1,136, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,136, 0, 0, 2,116, 0, 0, 0,157, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,118, 0, 0, 0,159, 0, 0, 1,141, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,141, 0, 0, 1, 7, 0, 0, 2,118, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 92, 0, 0, 2,118, 0, 0, 1, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 7, + 0, 0, 1,141, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,118, 0, 0, 0, 92, 0, 0, 2,119, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,119, 0, 0, 2,120, 0, 0, 2,118, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,159, 0, 0, 2,118, + 0, 0, 2,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,120, 0, 0, 2,119, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 5, 0, 0, 0, 36, 0, 0, 1,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,140, 0, 0, 2,120, 0, 0, 1, 5, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 91, 0, 0, 1, 5, 0, 0, 2,120, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,120, + 0, 0, 1,140, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 4, 0, 0, 0, 91, 0, 0, 2,119, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,119, 0, 0, 1, 6, 0, 0, 1, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 10, 0, 0, 1, 4, + 0, 0, 1, 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 6, 0, 0, 2,119, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,121, 0, 0, 0,159, 0, 0, 1,140, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,140, 0, 0, 1,142, 0, 0, 2,121, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 2,121, 0, 0, 1,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,142, + 0, 0, 1,140, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,121, 0, 0, 0,160, 0, 0, 2,122, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,122, 0, 0, 2,123, 0, 0, 2,121, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,159, 0, 0, 2,121, + 0, 0, 2,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,123, 0, 0, 2,122, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,144, 0, 0, 0, 37, 0, 0, 1,141, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,141, 0, 0, 2,123, 0, 0, 1,144, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,161, 0, 0, 1,144, 0, 0, 2,123, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,123, + 0, 0, 1,141, 0, 0, 0,159, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,145, 0, 0, 0,161, 0, 0, 2,122, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,122, 0, 0, 1,143, 0, 0, 1,145, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 1,145, + 0, 0, 1,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,143, 0, 0, 2,122, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,124, 0, 0, 0,101, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 24, 0, 0, 1, 8, 0, 0, 2,124, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 93, 0, 0, 2,124, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 8, + 0, 0, 1, 24, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,124, 0, 0, 0, 93, 0, 0, 2,125, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,125, 0, 0, 2,126, 0, 0, 2,124, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,101, 0, 0, 2,124, + 0, 0, 2,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,126, 0, 0, 2,125, 0, 0, 0,161, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1,145, 0, 0, 0, 41, 0, 0, 1, 25, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 25, 0, 0, 2,126, 0, 0, 1,145, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,161, 0, 0, 1,145, 0, 0, 2,126, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,126, + 0, 0, 1, 25, 0, 0, 0,101, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,144, 0, 0, 0,161, 0, 0, 2,125, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,125, 0, 0, 1, 9, 0, 0, 1,144, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 1,144, + 0, 0, 1, 9, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 9, 0, 0, 2,125, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 2,127, 0, 0, 0,100, 0, 0, 1, 23, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 23, 0, 0, 1,143, 0, 0, 2,127, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,160, 0, 0, 2,127, 0, 0, 1,143, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,143, + 0, 0, 1, 23, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,127, 0, 0, 0,160, 0, 0, 2,128, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,128, 0, 0, 2,129, 0, 0, 2,127, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,100, 0, 0, 2,127, + 0, 0, 2,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,129, 0, 0, 2,128, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 1, 2, 0, 0, 0, 9, 0, 0, 1, 22, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 22, 0, 0, 2,129, 0, 0, 1, 2, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 90, 0, 0, 1, 2, 0, 0, 2,129, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2,129, + 0, 0, 1, 22, 0, 0, 0,100, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 3, 0, 0, 0, 90, 0, 0, 2,128, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 2,128, 0, 0, 1,142, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 1, 3, + 0, 0, 1,142, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1,142, 0, 0, 2,128, 0, 0, 0,160, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 77, 69, 0, 0, 0,188, 3, 59,134,176, 0, 0, 0, 47, 0, 0, 0, 1, 3, 59,137,208, 3, 59,133,192, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 46, 48, 48, 49, 0, 48, 48, 50, 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, 3, 58,138, 16, 3, 59,137, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 59,135,160, 3, 59,136,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, 8, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 1, 51,128, 0, 0,180, 0, 0, 0, + 0, 0, 0, 0, 63,128, 0, 4, 63,128, 0, 4, 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 68, 65, 84, 65, 0, 0, 0, 4, 3, 58,138, 16, 0, 0, 0, 0, + 0, 0, 0, 1, 3, 59,124,192, 68, 65, 84, 65, 0, 0, 0,160, 3, 59,135,160, 0, 0, 0, 52, 0, 0, 0, 8, 63,128, 0, 0, + 63,127,255,255,191,128, 0, 0, 73,230, 73,230,182, 26, 3,255, 63,128, 0, 0,191,128, 0, 0,191,128, 0, 0, 73,230,182, 26, +182, 26, 3,255,191,128, 0, 1,191,127,255,253,191,128, 0, 0,182, 26,182, 26,182, 26, 3,255,191,127,255,250, 63,128, 0, 3, +191,128, 0, 0,182, 26, 73,230,182, 26, 3,255, 63,128, 0, 4, 63,127,255,247, 63,128, 0, 0, 73,230, 73,230, 73,230, 3,255, + 63,127,255,245,191,128, 0, 5, 63,128, 0, 0, 73,230,182, 26, 73,230, 3,255,191,128, 0, 3,191,127,255,250, 63,128, 0, 0, +182, 26,182, 26, 73,230, 3,255,191,127,255,255, 63,128, 0, 0, 63,128, 0, 0,182, 26, 73,230, 73,230, 3,255, 68, 65, 84, 65, + 0, 0, 0,144, 3, 59,136,112, 0, 0, 0, 49, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 35, + 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 35, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 35, + 68, 65, 84, 65, 0, 0, 0,120, 3, 59,137, 48, 0, 0, 0, 48, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 2, + 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 77, 69, 0, 0, 0,188, 3, 59,137,208, 0, 0, 0, 47, 0, 0, 0, 1, + 0, 0, 0, 0, 3, 59,134,176, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69,112,114,101,118,105,101,119, 46, 48, 48, 50, 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, 3, 57,233,208, 3, 59,139,160, 3, 59,139,224, 0, 0, 0, 0, 3, 59,138,192, 3, 59,139, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, + 0, 0, 0, 1,179,128, 0, 0, 52, 64, 0, 0, 28,192, 0, 0, 63,128, 0, 0, 63,128, 0, 2, 55, 39,197,172, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 4, 0, 0, 0, 0, 0, 1, 0, 0, 68, 65, 84, 65, + 0, 0, 0, 4, 3, 57,233,208, 0, 0, 0, 0, 0, 0, 0, 1, 3, 59,124,192, 68, 65, 84, 65, 0, 0, 0, 80, 3, 59,138,192, + 0, 0, 0, 52, 0, 0, 0, 4, 63,128, 0, 0, 63,127,255,255, 39,251,255,255, 0, 0, 0, 0,127,255, 3,255, 63,128, 0, 0, +191,128, 0, 0,168, 2, 0, 0, 0, 0, 0, 0,127,255, 3,255,191,128, 0, 1,191,127,255,253,167,251,255,253, 0, 0, 0, 0, +127,255, 3,255,191,127,255,250, 63,128, 0, 3, 40, 2, 0, 3, 0, 0, 0, 0,127,255, 3,255, 68, 65, 84, 65, 0, 0, 0, 48, + 3, 59,139, 64, 0, 0, 0, 49, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 35, 68, 65, 84, 65, + 0, 0, 0, 20, 3, 59,139,160, 0, 0, 0, 48, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, + 0, 0, 0, 2, 68, 65, 84, 65, 0, 0, 0, 60, 3, 59,139,224, 0, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 63,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 0, 0, 0, 0, 63,128, 0, 0, 63,128, 0, 0,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255, 1, 0, 0, 1, 0, 0, 0, 0, 71, 76, 79, 66, 0, 0, 0, 24,191,255,243, 16, + 0, 0, 0,116, 0, 0, 0, 1, 3, 59, 65,112, 3,152,218, 32, 0, 1, 1, 0, 0, 0, 0, 0, 0, 4, 0,128, 0, 0, 0, 10, + 68, 78, 65, 49, 0, 0,104, 56, 7, 80, 16, 32, 0, 0, 0, 0, 0, 0, 0, 1, 83, 68, 78, 65, 78, 65, 77, 69, 0, 0, 5,255, + 42,110,101,120,116, 0, 42,112,114,101,118, 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,110,101,119,105,100, 0, 42,108,105, 98, + 0,110, 97,109,101, 91, 50, 52, 93, 0,117,115, 0,102,108, 97,103, 0,105, 99,111,110, 95,105,100, 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, 99,117,114,118,101, 0, 99,117,114, 0, 98,108,111, 99,107,116, +121,112,101, 0,115,104,111,119,107,101,121, 0,112,111,115, 0, 99,117,114,118, 97,108, 0,116,121,112,101, 0, 97,100,114, 99, +111,100,101, 0,116,111,116,101,108,101,109, 0, 42,100, 97,116, 97, 0, 42,119,101,105,103,104,116,115, 0,110, 97,109,101, 91, + 51, 50, 93, 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,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, + 42,115, 99,114,105,112,116,115, 0, 42,102,108, 97,103, 0, 97, 99,116,115, 99,114,105,112,116, 0,116,111,116,115, 99,114,105, +112,116, 0, 42,108,105,110,101, 0, 42,102,111,114,109, 97,116, 0,108,101,110, 0, 98,108,101,110, 0, 42,110, 97,109,101, 0, +102,108, 97,103,115, 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, 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,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,112, 97,100, 49, 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, 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,115, 99,114,105,112,116,108,105,110,107, 0,110, 97,109,101, 91, 49, 54, + 48, 93, 0, 42, 97,110,105,109, 0, 42,105, 98,117,102, 0, 42,109,105,112,109, 97,112, 91, 49, 48, 93, 0,111,107, 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,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,114,101,115,101,114,118,101,100, 49, 0,114,101,115,101,114,118,101,100, 50, 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,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,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, 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, 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,100, 97,116, 97, 91, 49, 54, 93, 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,115,116,121,112,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,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,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, 42,112,108,117,103,105,110, 0, 42, 99,111, 98, 97, 0, 42,101,110,118, 0,102,114, 97, +100,117,114, 91, 52, 93, 91, 50, 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, 42,111, 98, 0,109,111,100,101, 0,116,111,116,101,120, 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, 98,117,102,115,105,122,101, 0,115, 97,109,112, 0,115,104, 97,100,115, +112,111,116,115,105,122,101, 0, 98,105, 97,115, 0,115,111,102,116, 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,116,101,120, 97, 99,116, 0,115,104, 97,100,104, 97,108,111,115,116,101,112, 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,112, 97,100, 51, 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, 48, 93, 0,108, 97,121, 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,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,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, 98,105, 97,115, 0,114,103, + 98,115,101,108, 0,112,114, 95,116,121,112,101, 0,117,115,101, 95,110,111,100,101,115, 0,112,114, 95, 98, 97, 99,107, 0,112, +114, 95,108, 97,109,112, 0,115,101,112,116,101,120, 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,110,111,100,101,116,114,101,101, 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,112, 97,100, 50, 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,110, 97,109,101, 91, 50, 53, 54, 93, 0,115, 99, 97,108,101, 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, 42,109, 97,116, 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,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, 42, 98,112, 0, 42, 98,101,122, +116, 0, 99,104, 97,114,105,100,120, 0,107,101,114,110, 0,104, 0,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,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,102, 97,109,105, +108,121, 91, 50, 52, 93, 0, 42,118,102,111,110,116, 0, 42,118,102,111,110,116, 98, 0, 42,118,102,111,110,116,105, 0, 42,118, +102,111,110,116, 98,105, 0,115,101,112, 99,104, 97,114, 0,116,111,116, 98,111,120, 0, 97, 99,116, 98,111,120, 0, 42,116, 98, + 0,115,101,108,115,116, 97,114,116, 0,115,101,108,101,110,100, 0, 42,115,116,114,105,110,102,111, 0, 99,117,114,105,110,102, +111, 0,110, 97,109,101, 91, 49, 50, 56, 93, 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, + 42,100,114,105,118,101,114, 0, 42,116,112, 97,103,101, 0,117,118, 91, 52, 93, 91, 50, 93, 0, 99,111,108, 91, 52, 93, 0,116, +114, 97,110,115,112, 0,116,105,108,101, 0,117,110,119,114, 97,112, 0,101,102,102,101, 99,116, 0, 42,109,102, 97, 99,101, 0, + 42,116,102, 97, 99,101, 0, 42,100,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,111, 99, + 0, 42,115,117,109,111,104, 97,110,100,108,101, 0,116,111,116,101,100,103,101, 0,116,111,116,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,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,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, 99,111, 91, 50, 93, 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,108,101,118,101,108,115, 0,114,101,110,100,101,114, 76,101,118,101,108,115, 0, 42, +101,109, 67, 97, 99,104,101, 0, 42,109, 67, 97, 99,104,101, 0,115,116, 97,114,116, 0,108,101,110,103,116,104, 0,114, 97,110, +100,111,109,105,122,101, 0,115,101,101,100, 0, 97,120,105,115, 0,116,111,108,101,114, 97,110, 99,101, 0,112,101,114, 99,101, +110,116, 0,102, 97, 99,101, 67,111,117,110,116, 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,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,112, 97,114,101,110,116,105,110,118, 91, 52, 93, 91, 52, 93, + 0, 99,101,110,116, 91, 51, 93, 0,102, 97,108,108,111,102,102, 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,111,112,101,114, 97,116,105,111,110, 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,118,101, 99, 91, 56, 93, 91, 51, 93, + 0,100,118,101, 99, 91, 51, 93, 0,109, 97,120, 0, 42, 42,111, 98, 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,112, 97,114,100, 97,116, 97, 0, + 42,112, 97,114,101,110,116, 0, 42,116,114, 97, 99,107, 0, 42, 97, 99,116,105,111,110, 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,110,101,116,119,111,114,107, 0,100,101,102, 98, 97,115,101, 0, +109,111,100,105,102,105,101,114,115, 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,108, 98,105,116,115, 0,116,114, 97,110,115,102,108, 97,103, 0,105,112,111,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,112,114,111,116,101, 99,116,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, 99,116,105,109,101, 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,115,111,102,116,116,105,109,101, 0,114,100, 97,109,112,105,110,103, 0,115,105,122,101,102, 97, 99, + 0,100,116, 0,100,116,120, 0, 97, 99,116, 99,111,108, 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,100,102,114, 97, +115, 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,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, 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,115,104, 97,112,101,110, +114, 0,115,104, 97,112,101,102,108, 97,103, 0, 42,102,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 42,100, +101,114,105,118,101,100, 68,101,102,111,114,109, 0, 42,100,101,114,105,118,101,100, 70,105,110, 97,108, 0, 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,102, 95,115, +116,114,101,110,103,116,104, 0,102, 95,112,111,119,101,114, 0,109, 97,120,100,105,115,116, 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,116,111,116,112,111,105, +110,116, 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,110,111, +100,101,109, 97,115,115, 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,105,110,115,112,114,105,110,103, 0,105,110,102,114,105, 99,116, 0,101,102,114, 97, 0,105,110,116,101,114,118, + 97,108, 0, 42, 42,107,101,121,115, 0,116,111,116,112,111,105,110,116,107,101,121, 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,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,112,104,121,115,105, 99,115, 69,110,103,105,110,101, 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, 42, 97,111,115,112,104,101,114, +101, 0,104,101,109,105,114,101,115, 0,109, 97,120,105,116,101,114, 0,100,114, 97,119,116,121,112,101, 0,115,117, 98,115,104, +111,111,116,112, 0,115,117, 98,115,104,111,111,116,101, 0,110,111,100,101,108,105,109, 0,109, 97,120,115,117, 98,108, 97,109, +112, 0,112, 97,109, 97, 0,112, 97,109,105, 0,101,108,109, 97, 0,101,108,109,105, 0,109, 97,120,110,111,100,101, 0, 99,111, +110,118,101,114,103,101,110, 99,101, 0,114, 97,100,102, 97, 99, 0,103, 97,109,109, 97, 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,109,105,120,114, 97,116,101, 0, +109, 97,105,110, 0,112, 97,100, 91, 51, 93, 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, 99,102,114, 97, 0,105,109, 97,103,101,115, 0,102,114, 97,109, 97,112,116,111, 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,102,105,108,116,101,114,116,121,112,101, 0,109, 97,120,105,109,115,105,122,101, 0,120, +115, 99,104, 0,121,115, 99,104, 0,120, 97,115,112, 0,121, 97,115,112, 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, + 98,117,102,102,108, 97,103, 0,113,117, 97,108,105,116,121, 0,115, 99,101,109,111,100,101, 0,114,101,110,100,101,114,101,114, + 0,111, 99,114,101,115, 0,114,112, 97,100, 91, 50, 93, 0, 97,108,112,104, 97,109,111,100,101, 0,100,111,103, 97,109,109, 97, + 0,111,115, 97, 0,102,114,115, 95,115,101, 99, 0,101,100,103,101,105,110,116, 0,115, 97,109,101, 95,109, 97,116, 95,114,101, +100,117,120, 0,115, 97,102,101,116,121, 0, 98,111,114,100,101,114, 0,103, 97,117,115,115, 0,112,111,115,116,109,117,108, 0, +112,111,115,116,103, 97,109,109, 97, 0,112,111,115,116, 97,100,100, 0,112,111,115,116,105,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,122,109, +105,110, 0,102,111, 99,117,115, 0,122,103, 97,109,109, 97, 0,122,115,105,103,109, 97, 0,122, 98,108,117,114, 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,110,117,109,112,114,111, 99,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, 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,102,116,121,112,101, 91, 49, 54, 48, 93, 0, 99,111,108, 91, 51, 93, 0,102,114, 97,109,101, 0,110, 97,109,101, 91, 54, 52, + 93, 0, 99,111,114,110,101,114,116,121,112,101, 0,101,100,105,116, 98,117,116,102,108, 97,103, 0,100,101,103,114, 0,115,116, +101,112, 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,115,101,103,109, +101,110,116,115, 0,114,105,110,103,115, 0,118,101,114,116,105, 99,101,115, 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, 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,101,100,105,116, 98, +117,116,115,105,122,101, 0,115,101,108,101, 99,116,109,111,100,101, 0,112,114,111,112,111,114,116,105,111,110, 97,108, 0,112, +114,111,112, 95,109,111,100,101, 0, 42,101,100, 0, 42,114, 97,100,105,111, 0,102,114, 97,109,105,110,103, 0, 42,116,111,111, +108,115,101,116,116,105,110,103,115, 0, 97,117,100,105,111, 0,109, 97,114,107,101,114,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,100,105,114,116,121, 0,122,111,111,109, 0, 98, +108,101,110,100, 0,120,105,109, 0,121,105,109, 0, 42,114,101, 99,116, 0,115,112, 97, 99,101,116,121,112,101, 0, 98,108,111, + 99,107,115, 99, 97,108,101, 0, 42, 97,114,101, 97, 0, 98,108,111, 99,107,104, 97,110,100,108,101,114, 91, 56, 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,119,105,110,109, 97,116, 49, 91, 52, 93, + 91, 52, 93, 0,118,105,101,119,109, 97,116, 49, 91, 52, 93, 91, 52, 93, 0,118,105,101,119,113,117, 97,116, 91, 52, 93, 0,112, +101,114,115,112, 0,118,105,101,119, 0, 42, 98,103,112,105, 99, 0, 42,108,111, 99, 97,108,118,100, 0, 42,114,105, 0,108,111, + 99, 97,108,118,105,101,119, 0,108, 97,121, 97, 99,116, 0,115, 99,101,110,101,108,111, 99,107, 0, 97,114,111,117,110,100, 0, + 99, 97,109,122,111,111,109, 0,103,114,105,100, 0,103,114,105,100,118,105,101,119, 0,112,105,120,115,105,122,101, 0,110,101, + 97,114, 0,102, 97,114, 0, 99, 97,109,100,120, 0, 99, 97,109,100,121, 0,103,114,105,100,108,105,110,101,115, 0,118,105,101, +119, 98,117,116, 0,103,114,105,100,102,108, 97,103, 0,109,111,100,101,115,101,108,101, 99,116, 0,109,101,110,117,110,114, 0, +116,101,120,110,114, 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,116,119,109, 97,116, 91, 52, 93, 91, 52, 93, 0, 99,108,105,112, 91, 52, 93, 91, 52, 93, 0, 42, 99,108, +105,112, 98, 98, 0, 97,102,116,101,114,100,114, 97,119, 0,122, 98,117,102, 0,120,114, 97,121, 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,107,101,101,112,116,111,116, 0,107,101,101,112, 97,115,112,101, 99,116, 0,107, +101,101,112,122,111,111,109, 0,111,108,100,119,105,110,120, 0,111,108,100,119,105,110,121, 0,114,111,119, 98,117,116, 0,118, + 50,100, 0, 42,101,100,105,116,105,112,111, 0,105,112,111,107,101,121, 0, 97, 99,116,110, 97,109,101, 91, 51, 50, 93, 0, 99, +111,110,115,116,110, 97,109,101, 91, 51, 50, 93, 0,116,111,116,105,112,111, 0,112,105,110, 0, 98,117,116,111,102,115, 0, 99, +104, 97,110,110,101,108, 0,108,111, 99,107, 0,109,101,100,105, 97,110, 91, 51, 93, 0, 99,117,114,115,101,110,115, 0, 99,117, +114, 97, 99,116, 0, 97,108,105,103,110, 0,116, 97, 98,111, 0,109, 97,105,110, 98, 0,109, 97,105,110, 98,111, 0, 42,108,111, + 99,107,112,111,105,110, 0,116,101,120,102,114,111,109, 0,115,104,111,119,103,114,111,117,112, 0,109,111,100,101,108,116,121, +112,101, 0,115, 99,114,105,112,116, 98,108,111, 99,107, 0,114,101, 95, 97,108,105,103,110, 0,111,108,100,107,101,121,112,114, +101,115,115, 0,116, 97, 98, 91, 55, 93, 0, 42,102,105,108,101,108,105,115,116, 0,116,111,116,102,105,108,101, 0,116,105,116, +108,101, 91, 50, 52, 93, 0,100,105,114, 91, 49, 54, 48, 93, 0,102,105,108,101, 91, 56, 48, 93, 0,111,102,115, 0,115,111,114, +116, 0,109, 97,120,110, 97,109,101,108,101,110, 0, 99,111,108,108,117,109,115, 0, 42,108,105, 98,102,105,108,101,100, 97,116, + 97, 0,114,101,116,118, 97,108, 0,109,101,110,117, 0, 97, 99,116, 0, 40, 42,114,101,116,117,114,110,102,117,110, 99, 41, 40, + 41, 0, 42,109,101,110,117,112, 0,111,111,112,115, 0,118,105,115,105,102,108, 97,103, 0,116,114,101,101, 0, 42,116,114,101, +101,115,116,111,114,101, 0,111,117,116,108,105,110,101,118,105,115, 0,115,116,111,114,101,102,108, 97,103, 0,100,101,112,115, + 95,102,108, 97,103,115, 0, 42,105,109, 97,103,101, 0, 42, 99,117,109, 97,112, 0,105,109, 97,110,114, 0, 99,117,114,116,105, +108,101, 0, 42,116,101,120,116, 0,116,111,112, 0,118,105,101,119,108,105,110,101,115, 0,102,111,110,116, 95,105,100, 0,108, +104,101,105,103,104,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, 99,117,114,114,116, 97, 98, 95,115,101,116, 0,115,104,111,119,115,121,110,116, 97,120, 0,117,110,117,115,101,100, 95, +112, 97,100,100, 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, 42,115, 99,114,105,112,116, 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, 42,101,100,105,116,116,114,101,101, 0,116,114,101,101,116,121,112,101, 0,116,105,116,108,101, 91, + 50, 56, 93, 0,102, 97,115,101, 0,115,117, 98,102, 97,115,101, 0,109,111,117,115,101, 95,109,111,118,101, 95,114,101,100,114, + 97,119, 0,105,109, 97,102, 97,115,101, 0,109,120, 0,109,121, 0,100,105,114,115,108,105, 0,100,105,114,115,108,105, 95,108, +105,110,101,115, 0,100,105,114,115,108,105, 95,115,120, 0,100,105,114,115,108,105, 95,101,121, 0,100,105,114,115,108,105, 95, +101,120, 0,100,105,114,115,108,105, 95,104, 0,105,109, 97,115,108,105, 0,102,105,108,101,115,101,108,109,101,110,117,105,116, +101,109, 0,105,109, 97,115,108,105, 95,115,120, 0,105,109, 97,115,108,105, 95,101,121, 0,105,109, 97,115,108,105, 95,101,120, + 0,105,109, 97,115,108,105, 95,104, 0,100,115,115,120, 0,100,115,115,121, 0,100,115,101,120, 0,100,115,101,121, 0,100,101, +115,120, 0,100,101,115,121, 0,100,101,101,120, 0,100,101,101,121, 0,102,115,115,120, 0,102,115,115,121, 0,102,115,101,120, + 0,102,115,101,121, 0,100,115,100,104, 0,102,115,100,104, 0,102,101,115,120, 0,102,101,115,121, 0,102,101,101,120, 0,102, +101,101,121, 0,105,110,102,115,120, 0,105,110,102,115,121, 0,105,110,102,101,120, 0,105,110,102,101,121, 0,100,110,115,120, + 0,100,110,115,121, 0,100,110,119, 0,100,110,104, 0,102,110,115,120, 0,102,110,115,121, 0,102,110,119, 0,102,110,104, 0, +102,111,108,101, 91, 49, 50, 56, 93, 0,100,111,114, 91, 49, 50, 56, 93, 0,102,105,108,101, 91, 49, 50, 56, 93, 0,100,105,114, + 91, 49, 50, 56, 93, 0, 42,102,105,114,115,116,100,105,114, 0, 42,102,105,114,115,116,102,105,108,101, 0,116,111,112,100,105, +114, 0,116,111,116, 97,108,100,105,114,115, 0,104,105,108,105,116,101, 0,116,111,112,102,105,108,101, 0,116,111,116, 97,108, +102,105,108,101,115, 0,105,109, 97,103,101, 95,115,108,105,100,101,114, 0,115,108,105,100,101,114, 95,104,101,105,103,104,116, + 0,115,108,105,100,101,114, 95,115,112, 97, 99,101, 0,116,111,112,105,109, 97, 0,116,111,116, 97,108,105,109, 97, 0, 99,117, +114,105,109, 97,120, 0, 99,117,114,105,109, 97,121, 0, 42,102,105,114,115,116, 95,115,101,108, 95,105,109, 97, 0, 42,104,105, +108,105,116,101, 95,105,109, 97, 0,116,111,116, 97,108, 95,115,101,108,101, 99,116,101,100, 0,105,109, 97, 95,114,101,100,114, + 97,119, 0, 42, 99,109, 97,112, 0, 42, 97,114,103, 49, 0,111,117,116,108,105,110,101, 91, 52, 93, 0,110,101,117,116,114, 97, +108, 91, 52, 93, 0, 97, 99,116,105,111,110, 91, 52, 93, 0,115,101,116,116,105,110,103, 91, 52, 93, 0,115,101,116,116,105,110, +103, 49, 91, 52, 93, 0,115,101,116,116,105,110,103, 50, 91, 52, 93, 0,110,117,109, 91, 52, 93, 0,116,101,120,116,102,105,101, +108,100, 91, 52, 93, 0,116,101,120,116,102,105,101,108,100, 95,104,105, 91, 52, 93, 0,112,111,112,117,112, 91, 52, 93, 0,116, +101,120,116, 91, 52, 93, 0,116,101,120,116, 95,104,105, 91, 52, 93, 0,109,101,110,117, 95, 98, 97, 99,107, 91, 52, 93, 0,109, +101,110,117, 95,105,116,101,109, 91, 52, 93, 0,109,101,110,117, 95,104,105,108,105,116,101, 91, 52, 93, 0,109,101,110,117, 95, +116,101,120,116, 91, 52, 93, 0,109,101,110,117, 95,116,101,120,116, 95,104,105, 91, 52, 93, 0, 98,117,116, 95,100,114, 97,119, +116,121,112,101, 0,112, 97,100, 49, 91, 51, 93, 0, 98, 97, 99,107, 91, 52, 93, 0,104,101, 97,100,101,114, 91, 52, 93, 0,112, + 97,110,101,108, 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,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,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,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,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,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,118,114,109,108,102,108, 97,103, 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, 99,111,110,115,111,108,101, 95, 98,117,102,102,101,114, 0, 99,111,110,115,111,108, +101, 95,111,117,116, 0,109,105,120, 98,117,102,115,105,122,101, 0,102,111,110,116,115,105,122,101, 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,102,111,110,116,110, 97,109,101, 91, 50, 53, 54, 93, 0,116,104,101,109,101,115, 0, +117,110,100,111,115,116,101,112,115, 0, 99,117,114,115,115,105,122,101, 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,111, 98, 99,101,110,116, +101,114, 95,100,105, 97, 0,118,101,114,116, 98, 97,115,101, 0,101,100,103,101, 98, 97,115,101, 0, 97,114,101, 97, 98, 97,115, +101, 0, 42,115, 99,101,110,101, 0,101,110,100,120, 0,101,110,100,121, 0,115,105,122,101,120, 0,115,105,122,101,121, 0,115, + 99,101,110,101,110,114, 0,115, 99,114,101,101,110,110,114, 0,102,117,108,108, 0,109, 97,105,110,119,105,110, 0,119,105,110, + 97,107,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,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,111,102,115,120, 0, +111,102,115,121, 0, 99,111,110,116,114,111,108, 0,111,108,100, 95,111,102,115,120, 0,111,108,100, 95,111,102,115,121, 0,115, +111,114,116, 99,111,117,110,116,101,114, 0, 42,112, 97,110,101,108,116, 97, 98, 0, 42,118, 51, 0, 42,118, 52, 0, 42,102,117, +108,108, 0,119,105,110,109, 97,116, 91, 52, 93, 91, 52, 93, 0,104,101, 97,100,114, 99,116, 0,119,105,110,114, 99,116, 0,104, +101, 97,100,119,105,110, 0,119,105,110, 0,104,101, 97,100,101,114,116,121,112,101, 0, 98,117,116,115,112, 97, 99,101,116,121, +112,101, 0,119,105,110,120, 0,119,105,110,121, 0,104,101, 97,100, 95,115,119, 97,112, 0,104,101, 97,100, 95,101,113,117, 97, +108, 0,119,105,110, 95,115,119, 97,112, 0,119,105,110, 95,101,113,117, 97,108, 0,104,101, 97,100, 98,117,116,108,101,110, 0, +104,101, 97,100, 98,117,116,111,102,115, 0, 99,117,114,115,111,114, 0,115,112, 97, 99,101,100, 97,116, 97, 0,117,105, 98,108, +111, 99,107,115, 0,112, 97,110,101,108,115, 0, 42, 99,117,114,115, 99,114,101,101,110, 0, 42, 99,117,114,115, 99,101,110,101, + 0,100,105,115,112,108, 97,121,109,111,100,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,115,101, 49, 0, 42,115,101, 50, 0, 42,115,101, 51, 0,110,114, 0,100,111,110,101, 0, 42, +115,116,114,105,112,100, 97,116, 97, 0,111,114,120, 0,111,114,121, 0, 42,110,101,119,115,101,113, 0,115,116, 97,114,116,111, +102,115, 0,101,110,100,111,102,115, 0,115,116, 97,114,116,115,116,105,108,108, 0,101,110,100,115,116,105,108,108, 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,109,117,108, 0,104, 97,110,100, +115,105,122,101, 0, 42,115,116,114,105,112, 0, 42, 99,117,114,101,108,101,109, 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,108,101,118,101,108, 0,112, 97,110, 0, 99,117,114,112,111,115, 0,115,116,114,111, 98,101, 0, 42,101,102,102,101, 99, +116,100, 97,116, 97, 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,101,100,103,101, 87,105,100,116,104, 0, 97,110,103,108,101, 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, 98,117,116,116,121,112,101, 0, +117,115,101,114,106,105,116, 0,115,116, 97, 0,101,110,100, 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,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, 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, +100,120, 0,100,121, 0,108,105,110,107, 0,111,116,121,112,101, 0,100, 97,116, 97, 0,111,108,100, 0, 42,112,111,105,110, 0, + 42,111,108,100,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,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,100,101, +108, 97,121, 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,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,105,110,118,101,114,116, 0,102,114,101,113, 50, 0, 97,120,105,115,102, 0, 98,117,116,116,111,110, 0, 98,117,116, +116,111,110,102, 0,104, 97,116, 0,104, 97,116,102, 0,112,114,101, 99,105,115,105,111,110, 0,115,116,114, 91, 49, 50, 56, 93, + 0, 42,109,121,110,101,119, 0,105,110,112,117,116,115, 0,116,111,116,115,108,105,110,107,115, 0, 42, 42,115,108,105,110,107, +115, 0,118, 97,108, 0,118, 97,108,111, 0,112, 97,100, 53, 0,116,105,109,101, 0, 42, 97, 99,116, 0, 98,108,101,110,100,105, +110, 0,112,114,105,111,114,105,116,121, 0,115,116,114,105,100,101,108,101,110,103,116,104, 0,115,116,114,105,100,101, 97,120, +105,115, 0,114,101,115,101,114,118,101,100, 51, 0,115,110,100,110,114, 0,109, 97,107,101, 99,111,112,121, 0, 99,111,112,121, +109, 97,100,101, 0,112, 97,100, 91, 49, 93, 0,116,114, 97, 99,107, 0,118,111,108,117,109,101, 0, 42,109,101, 0,108,105,110, + 86,101,108,111, 99,105,116,121, 91, 51, 93, 0,108,111, 99, 97,108,102,108, 97,103, 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, 97,100,100,101,100,108,105,110,101, 97,114,118,101, +108,111, 99,105,116,121, 91, 51, 93, 0, 97,110,111,116,104,101,114,112, 97,100, 91, 52, 93, 0, 98,117,116,115,116, 97, 0, 98, +117,116,101,110,100, 0,109,105,110, 0,102, 97, 99, 0,118,105,115,105,102, 97, 99, 0,115,108,111,119, 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,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,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,114,111,116,100, 97,109,112, 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,108,111,111,112,115,116, 97,114,116, 0,108,111,111,112, +101,110,100, 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,108, 97,109,112,114,101,110, 0,103,111, 98,106,101, 99,116, 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,108, 97,121,101,114, 0, 98,111,110, +101, 98, 97,115,101, 0, 99,104, 97,105,110, 98, 97,115,101, 0,103,104,111,115,116,101,112, 0,103,104,111,115,116,115,105,122, +101, 0, 99,111,110,115,116,102,108, 97,103, 0,105,107,102,108, 97,103, 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, 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,115,116,114,105,100,101, 95,111,102,102,115,101,116, 91, 51, 93, 0, 97, 99,116, +110,114, 0,116,105,109,101,115,108,105,100,101, 0,110, 97,109,101, 91, 51, 48, 93, 0,101,110,102,111,114, 99,101, 0, 42,116, + 97,114, 0,105,116,101,114, 97,116,105,111,110,115, 0,114,111,111,116, 98,111,110,101, 0,115,117, 98,116, 97,114,103,101,116, + 91, 51, 50, 93, 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, +109,105,110,109, 97,120,102,108, 97,103, 0,115,116,105, 99,107,121, 0,115,116,117, 99,107, 0, 99, 97, 99,104,101, 91, 51, 93, + 0,108,111, 99, 97,108, 0,108,111, 99,107,102,108, 97,103, 0,102,111,108,108,111,119,102,108, 97,103, 0,111,102,102,115,101, +116, 91, 51, 93, 0,122,109, 97,120, 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,115,116,114,105,100,101, 95, 97,120,105,115, 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,112, 97,100,102, 0,115,116,114,105,100,101,108,101,110, 0,114,101,112,101, 97, +116, 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,104, 97,115, +105,110,112,117,116, 0,100, 97,116, 97,116,121,112,101, 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, 0,108, 97,115,116,121, 0,111,117,116,112,117,116,115, 0, 42,115,116,111,114, 97,103, +101, 0, 42, 98,108,111, 99,107, 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,116,111,116,114, 0, 98,117,116,114, 0,112,114,118,114, 0, 42,112,114,101,118,105,101,119, 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,115,116, 97, 99,107, 49, 0,105,110,105,116, + 0, 99,117,114, 95,105,110,100,101,120, 0, 42, 42, 97,108,108,116,121,112,101,115, 0, 42,111,119,110,116,121,112,101, 0,115, +104,111,114,116,121, 0,109,105,110,116, 97, 98,108,101, 0,109, 97,120,116, 97, 98,108,101, 0, 42, 99,117,114,118,101, 0, 42, +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, 0, 0, 84, 89, 80, 69, 0, 0, 0,230, 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,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, 0, 76,105, 98,114, 97,114,121, 0, 70,105,108,101, 68, 97,116, 97, 0, 73,112,111, + 0, 75,101,121, 66,108,111, 99,107, 0, 75,101,121, 0, 83, 99,114,105,112,116, 76,105,110,107, 0, 84,101,120,116, 76,105,110, +101, 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, 0, 97, +110,105,109, 0, 73,109, 66,117,102, 0, 77, 84,101,120, 0, 79, 98,106,101, 99,116, 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, 84,101,120, 77, + 97,112,112,105,110,103, 0, 76, 97,109,112, 0, 87, 97,118,101, 0, 77, 97,116,101,114,105, 97,108, 0, 98, 78,111,100,101, 84, +114,101,101, 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, 66,101,122, 84,114,105,112,108,101, 0, 66, + 80,111,105,110,116, 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, 73,112,111, 68,114,105,118,101,114, 0, 73,112,111, 67,117,114,118,101, 0, 84, 70, 97, 99,101, 0, + 77,101,115,104, 0, 77, 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, 79, 99, 73,110,102,111, 0, 77, 68,101,102,111,114,109, 87,101, +105,103,104,116, 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,105, +114,114,111,114, 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, 87, 97,118,101, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 65,114,109, 97,116,117,114,101, 77, +111,100,105,102,105,101,114, 68, 97,116, 97, 0, 72,111,111,107, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 83,111,102, +116, 98,111,100,121, 77,111,100,105,102,105,101,114, 68, 97,116, 97, 0, 66,111,111,108,101, 97,110, 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, 76, 66,117,102, 0, + 98, 65, 99,116,105,111,110, 0, 98, 80,111,115,101, 0, 80, 97,114,116, 68,101,102,108,101, 99,116, 0, 83,111,102,116, 66,111, +100,121, 0, 70,108,117,105,100,115,105,109, 83,101,116,116,105,110,103,115, 0, 68,101,114,105,118,101,100, 77,101,115,104, 0, + 79, 98, 72,111,111,107, 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, 87,111,114,108,100, 0, 82, 97,100,105,111, 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, 65,117,100,105,111, 68, 97,116, 97, 0, + 82,101,110,100,101,114, 68, 97,116, 97, 0, 71, 97,109,101, 70,114, 97,109,105,110,103, 0, 84,105,109,101, 77, 97,114,107,101, +114, 0, 84,111,111,108, 83,101,116,116,105,110,103,115, 0, 83, 99,101,110,101, 0, 68, 97,103, 70,111,114,101,115,116, 0, 66, + 71,112,105, 99, 0, 86,105,101,119, 51, 68, 0, 83,112, 97, 99,101, 76,105,110,107, 0, 83, 99,114, 65,114,101, 97, 0, 82,101, +110,100,101,114, 73,110,102,111, 0, 86,105,101,119, 50, 68, 0, 83,112, 97, 99,101, 73,110,102,111, 0, 83,112, 97, 99,101, 73, +112,111, 0, 83,112, 97, 99,101, 66,117,116,115, 0, 83,112, 97, 99,101, 83,101,113, 0, 83,112, 97, 99,101, 70,105,108,101, 0, +100,105,114,101,110,116,114,121, 0, 66,108,101,110,100, 72, 97,110,100,108,101, 0, 83,112, 97, 99,101, 79,111,112,115, 0, 84, +114,101,101, 83,116,111,114,101, 0, 83,112, 97, 99,101, 73,109, 97,103,101, 0, 67,117,114,118,101, 77, 97,112,112,105,110,103, + 0, 83,112, 97, 99,101, 78,108, 97, 0, 83,112, 97, 99,101, 84,101,120,116, 0, 83,112, 97, 99,101, 83, 99,114,105,112,116, 0, + 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, + 73,109, 97, 83,101,108, 0, 73,109, 97, 68,105,114, 0, 79,110,101, 83,101,108,101, 99,116, 97, 98,108,101, 73,109, 97, 0, 84, +104,101,109,101, 85, 73, 0, 84,104,101,109,101, 83,112, 97, 99,101, 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, 98, 83, 99,114,101,101,110, 0, 83, 99,114, 86,101,114,116, 0, 83, 99,114, 69, +100,103,101, 0, 80, 97,110,101,108, 0, 70,105,108,101, 71,108,111, 98, 97,108, 0, 83,116,114,105,112, 69,108,101,109, 0, 83, +116,114,105,112, 0, 80,108,117,103,105,110, 83,101,113, 0, 83,101,113,117,101,110, 99,101, 0, 98, 83,111,117,110,100, 0, 77, +101,116, 97, 83,116, 97, 99,107, 0, 69,100,105,116,105,110,103, 0, 87,105,112,101, 86, 97,114,115, 0, 71,108,111,119, 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, 84,114,101,101, 83,116,111,114,101, 69,108,101,109, 0, 79,111,112,115, 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, 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, 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, 67,104, 97,110,110,101,108, 0, 83,112, 97, 99,101, 65, 99,116,105,111,110, 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, 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, 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, 68,105,115,116, 97,110, 99,101, + 76,105,109,105,116, 67,111,110,115,116,114, 97,105,110,116, 0, 98, 82,111,116, 97,116,105,111,110, 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, 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,117,105, 66,108,111, 99,107, 0, 98, 78,111,100,101, 80,114,101,118,105,101, +119, 0, 98, 78,111,100,101, 84,121,112,101, 0, 67,117,114,118,101, 77, 97,112, 80,111,105,110,116, 0, 67,117,114,118,101, 77, + 97,112, 0, 0, 84, 76, 69, 78, 0, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 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, 48, 2, 32, 0, 0, 0, 80, + 0,104, 0,116, 0, 16, 0, 24, 0,100, 0, 20, 0,116, 1, 48, 0, 0, 0, 0, 0, 88, 2,220, 0,228, 1, 80, 0, 24, 1,136, + 0,128, 0,132, 0,252, 0, 52, 1,164, 0, 96, 0, 56, 1, 64, 0, 0, 0,108, 0, 96, 0,132, 0, 56, 0, 28, 0, 56, 0, 8, + 0, 16, 1, 44, 0, 0, 0,140, 0, 84, 0, 60, 0,188, 0, 20, 0, 20, 0, 12, 0, 12, 0, 4, 0, 8, 0, 24, 0, 8, 0, 52, + 0, 68, 0, 88, 0, 88, 0, 68, 0, 60, 0, 60, 0, 92, 0, 64, 0,180, 0, 52, 0, 64, 0,108, 0, 40, 0, 12, 0, 56, 0, 24, + 0, 44, 0, 92, 1, 84, 0, 0, 0,208, 0, 16, 0, 0, 0, 0, 1, 32, 0, 40, 0, 28, 0,176, 0,144, 0, 16, 3, 16, 0, 16, + 0, 80, 0, 28, 3,244, 0, 0, 0, 36, 2,192, 0, 36, 0,204, 0, 0, 0,120, 0, 36, 1, 40, 0,204, 0,164, 1, 84, 0, 0, + 0, 0, 0,196, 0, 12, 0,188, 0,176, 0,164, 0,120, 0, 32, 0, 0, 0,148, 0,176, 2,224, 0, 0, 0, 0, 0, 72, 0,136, + 8,104, 0, 56, 7,168, 0,116, 0, 20, 0, 24, 0,164, 0, 24, 0,104, 0,188, 1,160, 0,172, 1, 32, 0, 16, 0, 28, 0, 12, + 0, 24, 0, 16, 0, 24, 1, 48, 0, 0, 0, 56, 0, 12, 0, 44, 0, 64, 0, 48, 0, 8, 0, 44, 0, 72, 0,104, 0, 72, 0, 44, + 0, 40, 0,108, 0, 68, 0, 76, 0, 80, 0, 64, 0,128, 0, 4, 0, 60, 0, 12, 0, 60, 0, 20, 0, 16, 0, 64, 0, 16, 0, 76, + 0,120, 0, 48, 0, 28, 0, 56, 0, 52, 0, 56, 0,108, 0,136, 0, 4, 0, 40, 0, 0, 0, 64, 0,160, 0, 24, 1, 4, 0, 80, + 1, 72, 0, 60, 0,176, 0, 44, 0, 52, 0, 76, 0, 44, 0, 44, 0, 44, 0, 60, 0, 56, 0, 44, 0, 20, 0, 60, 0, 24, 0, 52, + 0,100, 0, 36, 0,116, 0, 24, 0,168, 0, 0, 0, 0, 0, 0, 0, 12, 0, 24, 83, 84, 82, 67, 0, 0, 0,200, 0, 10, 0, 2, + 0, 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 2, 0, 9, 0, 2, 0, 9, 0, 3, 0, 12, 0, 2, 0, 2, 0, 4, 0, 2, 0, 5, + 0, 13, 0, 2, 0, 4, 0, 4, 0, 4, 0, 5, 0, 14, 0, 2, 0, 7, 0, 4, 0, 7, 0, 5, 0, 15, 0, 2, 0, 8, 0, 4, + 0, 8, 0, 5, 0, 16, 0, 3, 0, 4, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 17, 0, 3, 0, 7, 0, 4, 0, 7, 0, 5, + 0, 7, 0, 6, 0, 18, 0, 3, 0, 8, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 19, 0, 4, 0, 4, 0, 4, 0, 4, 0, 5, + 0, 4, 0, 6, 0, 4, 0, 7, 0, 20, 0, 4, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 21, 0, 4, + 0, 8, 0, 4, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 22, 0, 4, 0, 4, 0, 8, 0, 4, 0, 9, 0, 4, 0, 10, + 0, 4, 0, 11, 0, 23, 0, 4, 0, 7, 0, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 24, 0, 8, 0, 9, 0, 0, + 0, 9, 0, 1, 0, 24, 0, 12, 0, 25, 0, 13, 0, 0, 0, 14, 0, 2, 0, 15, 0, 2, 0, 16, 0, 4, 0, 17, 0, 25, 0, 7, + 0, 24, 0, 18, 0, 24, 0, 19, 0, 26, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 6, + 0, 24, 0, 18, 0, 11, 0, 25, 0, 23, 0, 26, 0, 2, 0, 27, 0, 2, 0, 28, 0, 4, 0, 24, 0, 28, 0, 13, 0, 28, 0, 0, + 0, 28, 0, 1, 0, 7, 0, 29, 0, 7, 0, 30, 0, 2, 0, 31, 0, 2, 0, 32, 0, 4, 0, 33, 0, 9, 0, 34, 0, 7, 0, 35, + 0, 0, 0, 36, 0, 0, 0, 37, 0, 7, 0, 38, 0, 7, 0, 39, 0, 29, 0, 12, 0, 24, 0, 18, 0, 28, 0, 40, 0, 0, 0, 41, + 0, 4, 0, 42, 0, 7, 0, 30, 0, 11, 0, 43, 0, 27, 0, 44, 0, 24, 0, 45, 0, 2, 0, 31, 0, 2, 0, 46, 0, 2, 0, 47, + 0, 2, 0, 16, 0, 30, 0, 5, 0, 24, 0, 48, 0, 2, 0, 49, 0, 2, 0, 50, 0, 2, 0, 51, 0, 4, 0, 24, 0, 31, 0, 6, + 0, 31, 0, 0, 0, 31, 0, 1, 0, 0, 0, 52, 0, 0, 0, 53, 0, 4, 0, 54, 0, 4, 0, 55, 0, 32, 0, 13, 0, 24, 0, 18, + 0, 0, 0, 56, 0, 4, 0, 57, 0, 4, 0, 58, 0, 11, 0, 59, 0, 31, 0, 60, 0, 31, 0, 61, 0, 4, 0, 62, 0, 4, 0, 63, + 0, 0, 0, 64, 0, 4, 0, 65, 0, 4, 0, 66, 0, 9, 0, 67, 0, 33, 0, 5, 0, 4, 0, 68, 0, 4, 0, 69, 0, 4, 0, 57, + 0, 4, 0, 24, 0, 9, 0, 34, 0, 34, 0, 17, 0, 24, 0, 18, 0, 2, 0, 31, 0, 2, 0, 16, 0, 7, 0, 70, 0, 7, 0, 71, + 0, 7, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, 7, 0, 75, 0, 7, 0, 76, 0, 7, 0, 77, 0, 7, 0, 78, 0, 2, 0, 79, + 0, 2, 0, 80, 0, 7, 0, 81, 0, 27, 0, 44, 0, 30, 0, 82, 0, 35, 0, 23, 0, 24, 0, 18, 0, 0, 0, 83, 0, 36, 0, 84, + 0, 37, 0, 85, 0, 37, 0, 86, 0, 2, 0, 87, 0, 2, 0, 16, 0, 2, 0, 88, 0, 2, 0, 24, 0, 2, 0, 89, 0, 2, 0, 90, + 0, 2, 0, 91, 0, 2, 0, 92, 0, 2, 0, 93, 0, 2, 0, 94, 0, 4, 0, 95, 0, 4, 0, 96, 0, 33, 0, 97, 0, 7, 0, 98, + 0, 4, 0, 99, 0, 2, 0,100, 0, 2, 0,101, 0, 4, 0,102, 0, 38, 0, 24, 0, 2, 0,103, 0, 2, 0,104, 0, 2, 0,105, + 0, 2, 0,106, 0, 39, 0,107, 0, 40, 0,108, 0, 0, 0,109, 0, 0, 0,110, 0, 0, 0,111, 0, 0, 0,112, 0, 7, 0,113, + 0, 7, 0,114, 0, 2, 0,115, 0, 2, 0,116, 0, 7, 0,117, 0, 7, 0,118, 0, 7, 0,119, 0, 7, 0,120, 0, 7, 0,121, + 0, 7, 0,122, 0, 7, 0,123, 0, 7, 0,124, 0, 7, 0,125, 0, 7, 0,126, 0, 41, 0, 14, 0, 0, 0, 83, 0, 9, 0,127, + 0, 0, 0,128, 0, 0, 0,129, 0, 4, 0,130, 0, 4, 0,131, 0, 9, 0,132, 0, 7, 0,133, 0, 7, 0,134, 0, 7, 0,135, + 0, 4, 0,136, 0, 9, 0,137, 0, 4, 0,138, 0, 4, 0, 24, 0, 42, 0, 6, 0, 7, 0,117, 0, 7, 0,118, 0, 7, 0,119, + 0, 7, 0,139, 0, 7, 0, 29, 0, 4, 0, 26, 0, 43, 0, 5, 0, 2, 0, 16, 0, 2, 0, 23, 0, 2, 0, 26, 0, 2, 0,140, + 0, 42, 0,141, 0, 44, 0, 16, 0, 39, 0,107, 0, 35, 0,142, 0, 35, 0,143, 0, 7, 0,144, 0, 2, 0, 31, 0, 2, 0,145, + 0, 7, 0, 72, 0, 7, 0, 73, 0, 4, 0,146, 0, 2, 0,147, 0, 2, 0,148, 0, 2, 0, 87, 0, 2, 0, 88, 0, 2, 0,149, + 0, 2, 0,150, 0, 4, 0, 71, 0, 40, 0, 52, 0, 24, 0, 18, 0, 7, 0,151, 0, 7, 0,152, 0, 7, 0,153, 0, 7, 0,154, + 0, 7, 0,155, 0, 7, 0,156, 0, 7, 0,157, 0, 7, 0,158, 0, 7, 0,159, 0, 7, 0,160, 0, 7, 0,161, 0, 7, 0,162, + 0, 7, 0,163, 0, 7, 0,164, 0, 7, 0,165, 0, 7, 0,166, 0, 7, 0,167, 0, 7, 0,168, 0, 7, 0,169, 0, 7, 0,170, + 0, 2, 0,171, 0, 2, 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, 16, + 0, 2, 0, 31, 0, 2, 0,145, 0, 7, 0,178, 0, 7, 0,179, 0, 7, 0,180, 0, 7, 0,181, 0, 2, 0,182, 0, 2, 0,183, + 0, 2, 0,184, 0, 2, 0, 54, 0, 7, 0,185, 0, 7, 0,186, 0, 2, 0,187, 0, 2, 0,188, 0, 2, 0,189, 0, 2, 0,190, + 0, 7, 0,123, 0, 27, 0, 44, 0, 35, 0,142, 0, 41, 0,191, 0, 43, 0,192, 0, 44, 0,193, 0, 2, 0,194, 0, 45, 0, 8, + 0, 7, 0,195, 0, 7, 0,196, 0, 7, 0,114, 0, 4, 0, 16, 0, 7, 0,197, 0, 7, 0,198, 0, 7, 0,199, 0, 39, 0,200, + 0, 46, 0, 50, 0, 24, 0, 18, 0, 2, 0, 31, 0, 2, 0,201, 0, 2, 0,116, 0, 2, 0,202, 0, 7, 0,117, 0, 7, 0,118, + 0, 7, 0,119, 0, 7, 0,120, 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, 2, 0,210, 0, 2, 0,211, 0, 7, 0, 72, 0, 7, 0, 73, 0, 7, 0,212, 0, 7, 0,213, 0, 7, 0,214, + 0, 2, 0,215, 0, 2, 0,216, 0, 2, 0,217, 0, 2, 0,218, 0, 2, 0,219, 0, 2, 0, 24, 0, 7, 0,220, 0, 7, 0,221, + 0, 7, 0,222, 0, 2, 0,223, 0, 2, 0,224, 0, 4, 0,225, 0, 4, 0,226, 0, 2, 0,227, 0, 2, 0,228, 0, 2, 0,229, + 0, 2, 0,230, 0, 7, 0,231, 0, 7, 0,232, 0, 7, 0,233, 0, 7, 0,234, 0, 7, 0,235, 0, 2, 0,236, 0, 2, 0,237, + 0, 38, 0,238, 0, 27, 0, 44, 0, 30, 0, 82, 0, 47, 0, 2, 0, 24, 0, 18, 0, 27, 0, 44, 0, 48, 0, 97, 0, 24, 0, 18, + 0, 2, 0,116, 0, 2, 0,239, 0, 7, 0,117, 0, 7, 0,118, 0, 7, 0,119, 0, 7, 0,240, 0, 7, 0,241, 0, 7, 0,242, + 0, 7, 0,243, 0, 7, 0,244, 0, 7, 0,245, 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, 1, 0, 0, 7, 1, 1, 0, 7, 1, 2, + 0, 7, 1, 3, 0, 7, 1, 4, 0, 7, 1, 5, 0, 7, 1, 6, 0, 7, 1, 7, 0, 7, 1, 8, 0, 2, 1, 9, 0, 2, 1, 10, + 0, 2, 1, 11, 0, 0, 1, 12, 0, 0, 1, 13, 0, 4, 0,201, 0, 4, 1, 14, 0, 2, 1, 15, 0, 2, 1, 16, 0, 2, 1, 17, + 0, 2, 1, 18, 0, 7, 1, 19, 0, 7, 1, 20, 0, 7, 1, 21, 0, 7, 1, 22, 0, 7, 1, 23, 0, 7, 1, 24, 0, 7, 1, 25, + 0, 7, 1, 26, 0, 0, 1, 27, 0, 0, 0,223, 0, 0, 1, 28, 0, 0, 1, 29, 0, 2, 1, 30, 0, 2, 1, 31, 0, 2, 1, 32, + 0, 2, 1, 33, 0, 2, 1, 34, 0, 2, 1, 35, 0, 7, 1, 36, 0, 7, 1, 37, 0, 7, 1, 38, 0, 7, 1, 39, 0, 7, 1, 40, + 0, 2, 0,103, 0, 2, 0,104, 0, 43, 1, 41, 0, 43, 1, 42, 0, 0, 1, 43, 0, 0, 1, 44, 0, 0, 1, 45, 0, 0, 1, 46, + 0, 2, 1, 47, 0, 2, 1, 48, 0, 7, 1, 49, 0, 7, 1, 50, 0, 38, 0,238, 0, 49, 1, 51, 0, 27, 0, 44, 0, 50, 1, 52, + 0, 7, 1, 53, 0, 7, 1, 54, 0, 7, 1, 55, 0, 7, 1, 56, 0, 7, 1, 57, 0, 2, 1, 58, 0, 2, 1, 59, 0, 7, 1, 60, + 0, 7, 1, 61, 0, 7, 1, 62, 0, 7, 1, 63, 0, 7, 1, 64, 0, 4, 1, 65, 0, 4, 1, 66, 0, 4, 1, 67, 0, 30, 0, 82, + 0, 51, 0, 6, 0, 24, 0, 18, 0, 0, 1, 68, 0, 7, 1, 69, 0, 7, 0, 24, 0, 52, 0, 34, 0, 33, 0, 97, 0, 53, 0, 26, + 0, 53, 0, 0, 0, 53, 0, 1, 0, 54, 1, 70, 0, 4, 1, 71, 0, 4, 1, 72, 0, 4, 1, 73, 0, 4, 1, 74, 0, 4, 1, 75, + 0, 4, 1, 76, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 1, 77, 0, 2, 1, 78, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, + 0, 7, 1, 79, 0, 7, 1, 80, 0, 7, 1, 81, 0, 7, 1, 82, 0, 7, 1, 83, 0, 7, 1, 84, 0, 7, 1, 85, 0, 7, 0, 54, + 0, 7, 1, 86, 0, 7, 1, 87, 0, 55, 0, 15, 0, 24, 0, 18, 0, 54, 1, 70, 0, 11, 1, 88, 0, 11, 1, 89, 0, 27, 0, 44, + 0, 48, 1, 90, 0, 2, 0, 16, 0, 2, 1, 91, 0, 4, 0,115, 0, 7, 0,195, 0, 7, 0,114, 0, 7, 0,196, 0, 7, 1, 92, + 0, 7, 1, 93, 0, 7, 1, 94, 0, 56, 0, 10, 0, 7, 1, 95, 0, 7, 1, 96, 0, 7, 1, 97, 0, 7, 0, 24, 0, 2, 1, 98, + 0, 2, 1, 99, 0, 0, 1,100, 0, 0, 1,101, 0, 0, 1,102, 0, 0, 1,103, 0, 57, 0, 5, 0, 7, 1,104, 0, 7, 1, 96, + 0, 7, 1, 97, 0, 2, 1,100, 0, 2, 1,103, 0, 58, 0, 20, 0, 58, 0, 0, 0, 58, 0, 1, 0, 2, 0, 31, 0, 2, 1,105, + 0, 2, 1,103, 0, 2, 0, 16, 0, 2, 1,106, 0, 2, 1,107, 0, 2, 1,108, 0, 2, 1,109, 0, 2, 1,110, 0, 2, 1,111, + 0, 2, 1,112, 0, 2, 1,113, 0, 7, 1,114, 0, 7, 1,115, 0, 57, 1,116, 0, 56, 1,117, 0, 4, 1,118, 0, 4, 0, 24, + 0, 59, 0, 5, 0, 2, 1,119, 0, 2, 1,105, 0, 0, 0, 16, 0, 0, 0, 24, 0, 2, 1, 59, 0, 60, 0, 4, 0, 7, 0, 4, + 0, 7, 0, 5, 0, 7, 0, 7, 0, 7, 1,120, 0, 61, 0, 54, 0, 24, 0, 18, 0, 54, 1, 70, 0, 11, 1,121, 0, 11, 1, 89, + 0, 39, 1,122, 0, 39, 1,123, 0, 39, 1,124, 0, 27, 0, 44, 0, 62, 1,125, 0, 29, 1,126, 0, 48, 1, 90, 0, 11, 1,127, + 0, 7, 0,195, 0, 7, 0,114, 0, 7, 0,196, 0, 4, 0,115, 0, 2, 1,128, 0, 2, 1, 91, 0, 2, 0, 16, 0, 2, 1,129, + 0, 7, 1,130, 0, 7, 1,131, 0, 7, 1,132, 0, 2, 1,108, 0, 2, 1,109, 0, 2, 0, 54, 0, 2, 0, 59, 0, 2, 0, 29, + 0, 2, 1,133, 0, 7, 1,134, 0, 7, 1,135, 0, 7, 1,136, 0, 7, 1,137, 0, 7, 1,138, 0, 7, 1,139, 0, 7, 1,140, + 0, 7, 1,141, 0, 7, 1,142, 0, 7, 1,143, 0, 0, 1,144, 0, 0, 1,145, 0, 51, 1,146, 0, 51, 1,147, 0, 51, 1,148, + 0, 51, 1,149, 0, 4, 1,150, 0, 4, 1,151, 0, 4, 1,152, 0, 4, 0, 24, 0, 60, 1,153, 0, 4, 1,154, 0, 4, 1,155, + 0, 59, 1,156, 0, 59, 1,157, 0, 63, 0, 6, 0, 39, 0,200, 0, 2, 0, 27, 0, 2, 0, 32, 0, 2, 0, 31, 0, 2, 0, 16, + 0, 0, 1,158, 0, 64, 0, 19, 0, 64, 0, 0, 0, 64, 0, 1, 0, 57, 1,116, 0, 56, 1,117, 0, 23, 1,159, 0, 23, 1,160, + 0, 2, 0, 27, 0, 2, 0, 32, 0, 2, 1,161, 0, 2, 1,162, 0, 2, 1,163, 0, 2, 1,164, 0, 2, 0, 16, 0, 2, 1,165, + 0, 7, 0, 10, 0, 7, 0, 11, 0, 4, 1,166, 0, 7, 0, 30, 0, 63, 1,167, 0, 65, 0, 8, 0, 9, 1,168, 0, 7, 1,169, + 0, 4, 1,170, 0, 0, 0, 16, 0, 0, 1,171, 0, 2, 0,201, 0, 2, 1,172, 0, 2, 1,173, 0, 66, 0, 32, 0, 24, 0, 18, + 0, 54, 1, 70, 0, 11, 1,174, 0, 27, 0, 44, 0, 29, 1,126, 0, 48, 1, 90, 0, 67, 1,175, 0, 65, 1,176, 0, 9, 1,177, + 0, 68, 1,178, 0, 69, 1,179, 0, 70, 1,180, 0, 71, 1,181, 0, 72, 1,182, 0, 66, 1,183, 0, 73, 1,184, 0, 9, 1,185, + 0, 4, 1,162, 0, 4, 1,186, 0, 4, 1,187, 0, 4, 0,115, 0, 7, 0,195, 0, 7, 0,114, 0, 7, 0,196, 0, 7, 1,188, + 0, 7, 0, 24, 0, 2, 1,189, 0, 2, 0, 16, 0, 2, 1,190, 0, 2, 1,191, 0, 2, 1, 91, 0, 2, 1,192, 0, 67, 0, 8, + 0, 4, 1,193, 0, 4, 1,194, 0, 4, 1,195, 0, 4, 1,196, 0, 0, 0, 24, 0, 0, 1,105, 0, 0, 1,197, 0, 0, 0, 16, + 0, 69, 0, 5, 0, 4, 1,193, 0, 4, 1,194, 0, 0, 1,198, 0, 0, 0, 24, 0, 2, 0, 16, 0, 74, 0, 2, 0, 4, 1,199, + 0, 7, 1, 97, 0, 70, 0, 3, 0, 74, 1,200, 0, 4, 1,201, 0, 4, 0, 16, 0, 68, 0, 4, 0, 7, 1,202, 0, 2, 1,203, + 0, 0, 0, 16, 0, 0, 1,105, 0, 71, 0, 4, 0, 0, 0,139, 0, 0, 0,117, 0, 0, 0,118, 0, 0, 0,119, 0, 72, 0, 1, + 0, 7, 1,204, 0, 75, 0, 6, 0, 75, 0, 0, 0, 75, 0, 1, 0, 4, 0, 31, 0, 4, 0,201, 0, 0, 0, 36, 0, 0, 1,205, + 0, 76, 0, 7, 0, 75, 1,206, 0, 2, 1,207, 0, 2, 1,208, 0, 2, 1,209, 0, 2, 0, 57, 0, 9, 1,210, 0, 9, 1,211, + 0, 77, 0, 3, 0, 75, 1,206, 0, 39, 0,107, 0, 0, 0, 36, 0, 78, 0, 3, 0, 75, 1,206, 0, 39, 0,107, 0, 0, 0, 36, + 0, 79, 0, 5, 0, 75, 1,206, 0, 7, 1,212, 0, 7, 1,213, 0, 4, 1,214, 0, 4, 1,215, 0, 80, 0, 4, 0, 75, 1,206, + 0, 2, 1,216, 0, 2, 0, 16, 0, 7, 1,217, 0, 81, 0, 3, 0, 75, 1,206, 0, 7, 1,218, 0, 4, 1,219, 0, 82, 0, 12, + 0, 75, 1,206, 0, 2, 0, 16, 0, 2, 0, 24, 0, 7, 1,220, 0, 7, 1,221, 0, 7, 1,222, 0, 7, 1,130, 0, 7, 1,223, + 0, 7, 1,224, 0, 7, 1,225, 0, 7, 1,226, 0, 7, 1,227, 0, 83, 0, 5, 0, 75, 1,206, 0, 2, 1,228, 0, 2, 0, 71, + 0, 4, 1, 59, 0, 39, 0,107, 0, 84, 0, 9, 0, 75, 1,206, 0, 39, 0,107, 0, 7, 1,229, 0, 7, 1,230, 0, 7, 1,231, + 0, 4, 1,232, 0, 4, 1,233, 0, 7, 1,234, 0, 0, 0, 36, 0, 85, 0, 1, 0, 75, 1,206, 0, 86, 0, 4, 0, 75, 1,206, + 0, 39, 0,107, 0, 4, 1,235, 0, 4, 0, 24, 0, 87, 0, 23, 0, 24, 0, 18, 0, 2, 1,106, 0, 2, 1,107, 0, 2, 1,236, + 0, 2, 0, 16, 0, 2, 1,237, 0, 2, 1,238, 0, 2, 1,239, 0, 2, 1, 59, 0, 0, 1,240, 0, 0, 1,241, 0, 0, 1,242, + 0, 0, 0, 31, 0, 4, 0, 24, 0, 7, 1,243, 0, 7, 1,244, 0, 7, 1,245, 0, 7, 1,246, 0, 7, 1,247, 0, 7, 1,248, + 0, 57, 1,249, 0, 27, 0, 44, 0, 29, 1,126, 0, 88, 0, 3, 0, 88, 0, 0, 0, 88, 0, 1, 0, 0, 0, 36, 0, 54, 0, 1, + 0, 7, 1,250, 0, 73, 0, 2, 0, 7, 1,251, 0, 7, 0,114, 0, 89, 0, 4, 0, 2, 0, 23, 0, 2, 1,252, 0, 4, 0, 24, + 0, 39, 1,253, 0, 39, 0, 93, 0, 24, 0, 18, 0, 2, 0, 31, 0, 2, 1,254, 0, 4, 1,255, 0, 4, 2, 0, 0, 4, 2, 1, + 0, 0, 2, 2, 0, 9, 2, 3, 0, 39, 2, 4, 0, 39, 2, 5, 0, 27, 0, 44, 0, 62, 1,125, 0, 54, 1, 70, 0, 90, 2, 6, + 0, 91, 2, 7, 0, 9, 0, 34, 0, 11, 2, 8, 0, 11, 1,174, 0, 11, 2, 9, 0, 11, 1, 89, 0, 11, 2, 10, 0, 11, 2, 11, + 0, 48, 1, 90, 0, 7, 0,195, 0, 7, 2, 12, 0, 7, 2, 13, 0, 7, 0,114, 0, 7, 2, 14, 0, 7, 0,196, 0, 7, 2, 15, + 0, 7, 1, 79, 0, 7, 2, 16, 0, 7, 2, 17, 0, 7, 1,229, 0, 7, 0,144, 0, 4, 0,239, 0, 2, 0, 16, 0, 2, 2, 18, + 0, 2, 2, 19, 0, 2, 2, 20, 0, 2, 2, 21, 0, 2, 2, 22, 0, 2, 2, 23, 0, 2, 2, 24, 0, 2, 2, 25, 0, 2, 2, 26, + 0, 2, 2, 27, 0, 2, 2, 28, 0, 2, 2, 29, 0, 2, 2, 30, 0, 2, 2, 31, 0, 2, 2, 32, 0, 7, 2, 33, 0, 7, 2, 34, + 0, 7, 2, 35, 0, 7, 2, 36, 0, 7, 2, 37, 0, 7, 2, 38, 0, 7, 2, 39, 0, 7, 2, 40, 0, 7, 2, 41, 0, 0, 2, 42, + 0, 0, 2, 43, 0, 0, 1, 91, 0, 0, 2, 44, 0, 30, 0, 82, 0, 11, 2, 45, 0, 11, 2, 46, 0, 11, 2, 47, 0, 11, 2, 48, + 0, 9, 1,185, 0, 7, 2, 49, 0, 2, 2, 50, 0, 2, 2, 51, 0, 7, 1,170, 0, 4, 2, 52, 0, 4, 2, 53, 0, 2, 2, 54, + 0, 2, 0,149, 0, 7, 2, 55, 0, 11, 2, 56, 0, 11, 2, 57, 0, 11, 2, 58, 0, 92, 2, 59, 0, 93, 2, 60, 0, 50, 2, 61, + 0, 2, 2, 62, 0, 0, 2, 63, 0, 0, 2, 64, 0, 7, 1,189, 0, 94, 2, 65, 0, 95, 2, 66, 0, 95, 2, 67, 0, 96, 0, 14, + 0, 96, 0, 0, 0, 96, 0, 1, 0, 39, 2, 4, 0, 7, 1,229, 0, 7, 0,197, 0, 7, 1,230, 0, 7, 1,231, 0, 0, 0, 36, + 0, 4, 1,232, 0, 4, 1,233, 0, 4, 2, 68, 0, 2, 0, 31, 0, 2, 2, 69, 0, 7, 1,234, 0, 92, 0, 13, 0, 2, 2, 70, + 0, 2, 2, 71, 0, 2, 0, 16, 0, 2, 0, 24, 0, 7, 2, 72, 0, 7, 2, 73, 0, 7, 2, 74, 0, 7, 2, 75, 0, 7, 2, 76, + 0, 7, 2, 77, 0, 7, 2, 78, 0, 7, 2, 79, 0, 7, 2, 80, 0, 97, 0, 1, 0, 7, 1,104, 0, 93, 0, 26, 0, 4, 2, 81, + 0, 4, 2, 82, 0, 98, 2, 83, 0, 99, 2, 84, 0, 7, 2, 34, 0, 7, 2, 85, 0, 7, 2, 86, 0, 7, 2, 87, 0, 7, 2, 88, + 0, 7, 2, 89, 0, 7, 2, 90, 0, 7, 2, 91, 0, 7, 2, 92, 0, 7, 2, 93, 0, 7, 2, 94, 0, 2, 2, 95, 0, 2, 0, 71, + 0, 7, 2, 96, 0, 7, 2, 97, 0, 2, 0,189, 0, 2, 2, 98, 0, 2, 2, 99, 0, 2, 1, 59, 0, 97, 2,100, 0, 4, 2,101, + 0, 4, 0, 46, 0, 94, 0, 26, 0, 2, 0, 31, 0, 2, 2,102, 0, 2, 2,103, 0, 2, 2,104, 0, 7, 2,105, 0, 2, 2,106, + 0, 2, 2,107, 0, 7, 2,108, 0, 2, 2,109, 0, 2, 2,110, 0, 7, 2,111, 0, 7, 2,112, 0, 7, 2,113, 0, 7, 2,114, + 0, 7, 2,115, 0, 7, 2,116, 0, 4, 2,117, 0, 7, 2,118, 0, 7, 2,119, 0, 7, 2,120, 0, 66, 2,121, 0, 66, 2,122, + 0, 66, 2,123, 0, 0, 2,124, 0, 7, 2,125, 0, 7, 2,126, 0,100, 0, 56, 0, 24, 0, 18, 0, 2, 0,116, 0, 2, 0,202, + 0, 2, 0,223, 0, 2, 2,127, 0, 7, 2,128, 0, 7, 2,129, 0, 7, 2,130, 0, 7, 2,131, 0, 7, 2,132, 0, 7, 2,133, + 0, 7, 2,134, 0, 7, 2,135, 0, 7, 0,246, 0, 7, 0,248, 0, 7, 0,247, 0, 7, 2,136, 0, 4, 2,137, 0, 7, 2,138, + 0, 7, 2,139, 0, 7, 2,140, 0, 7, 2,141, 0, 7, 2,142, 0, 7, 2,143, 0, 7, 2,144, 0, 2, 2,145, 0, 2, 0,201, + 0, 4, 2,146, 0, 7, 2,147, 0, 7, 2,148, 0, 7, 2,149, 0, 7, 2,150, 0, 7, 2,151, 0, 7, 2,152, 0, 7, 2,153, + 0, 7, 2,154, 0, 7, 2,155, 0, 7, 2,156, 0, 7, 2,157, 0, 7, 2,158, 0, 2, 2,159, 0, 2, 2,160, 0, 2, 2,161, + 0, 2, 2,162, 0, 7, 2,163, 0, 7, 2,164, 0, 7, 2,165, 0, 7, 2,166, 0, 2, 2,167, 0, 2, 2,168, 0, 2, 2,169, + 0, 2, 2,170, 0, 7, 2,171, 0, 27, 0, 44, 0, 38, 0,238, 0, 30, 0, 82, 0,101, 0, 16, 0, 2, 2,172, 0, 2, 2,173, + 0, 2, 2,174, 0, 2, 0, 16, 0, 2, 2,175, 0, 2, 2,176, 0, 2, 2,177, 0, 2, 2,178, 0, 2, 2,179, 0, 2, 2,180, + 0, 2, 2,181, 0, 2, 2,182, 0, 4, 2,183, 0, 7, 2,184, 0, 7, 2,185, 0, 7, 2,186, 0,102, 0, 8, 0,102, 0, 0, + 0,102, 0, 1, 0, 4, 0,239, 0, 4, 2,187, 0, 4, 0, 16, 0, 2, 2,188, 0, 2, 2,189, 0, 39, 0,107, 0,103, 0, 13, + 0, 9, 2,190, 0, 9, 2,191, 0, 4, 2,192, 0, 4, 2,193, 0, 4, 2,194, 0, 4, 2,195, 0, 4, 2,196, 0, 4, 2,197, + 0, 4, 2,198, 0, 4, 2,199, 0, 4, 2,200, 0, 4, 0, 24, 0, 0, 2,201, 0,104, 0, 5, 0, 9, 2,202, 0, 9, 2,203, + 0, 4, 2,204, 0, 4, 1, 59, 0, 0, 2,205, 0,105, 0, 4, 0, 4, 2,206, 0, 7, 2,207, 0, 2, 0, 16, 0, 2, 2,208, + 0,106, 0, 98, 0,103, 2,209, 0,104, 2,210, 0, 2, 2,211, 0, 2, 0,189, 0, 2, 2, 98, 0, 2, 2,212, 0, 2, 2,213, + 0, 2, 0, 16, 0, 7, 2, 34, 0, 7, 2,214, 0, 7, 2,215, 0, 7, 2,216, 0, 7, 2,217, 0, 7, 2,218, 0, 2, 2,219, + 0, 2, 2,220, 0, 2, 2,221, 0, 2, 2,222, 0, 2, 0,148, 0, 2, 2,223, 0, 2, 2,224, 0, 2, 2,225, 0, 2, 2,226, + 0, 2, 2,227, 0, 2, 2,228, 0, 2, 0, 68, 0, 2, 2,229, 0, 2, 2,230, 0, 2, 2,231, 0, 2, 2,232, 0, 2, 2,233, + 0, 2, 2,234, 0, 2, 2,235, 0, 2, 2,236, 0, 2, 2,237, 0, 2, 2,238, 0, 2, 2,239, 0, 2, 2,240, 0, 2, 2,241, + 0, 2, 2,242, 0, 4, 0,201, 0, 2, 2,243, 0, 2, 2,244, 0, 2, 2,245, 0, 2, 2,246, 0, 2, 2,247, 0, 2, 2,248, + 0, 2, 2,249, 0, 2, 2,250, 0, 2, 2,251, 0, 23, 2,252, 0, 23, 2,253, 0, 7, 2,186, 0, 7, 2,254, 0, 7, 2,255, + 0, 7, 3, 0, 0, 7, 3, 1, 0, 7, 3, 2, 0, 7, 3, 3, 0, 7, 3, 4, 0, 7, 3, 5, 0, 7, 3, 6, 0, 7, 3, 7, + 0, 7, 3, 8, 0, 7, 3, 9, 0, 7, 3, 10, 0, 2, 3, 11, 0, 2, 3, 12, 0, 2, 3, 13, 0, 2, 3, 14, 0, 2, 3, 15, + 0, 2, 3, 16, 0, 2, 3, 17, 0, 2, 3, 18, 0, 2, 3, 19, 0, 2, 3, 20, 0, 4, 3, 21, 0, 4, 3, 22, 0, 4, 3, 23, + 0, 4, 3, 24, 0, 4, 3, 25, 0, 7, 3, 26, 0, 4, 3, 27, 0, 4, 3, 28, 0, 4, 3, 29, 0, 4, 3, 30, 0, 7, 3, 31, + 0, 7, 3, 32, 0, 7, 3, 33, 0, 7, 3, 34, 0, 7, 3, 35, 0, 7, 3, 36, 0, 7, 3, 37, 0, 7, 3, 38, 0, 7, 3, 39, + 0, 0, 3, 40, 0, 0, 3, 41, 0, 0, 3, 42, 0,107, 0, 5, 0, 7, 3, 43, 0, 0, 0, 31, 0, 0, 0, 71, 0, 0, 1, 59, + 0, 0, 1, 48, 0,108, 0, 5, 0,108, 0, 0, 0,108, 0, 1, 0, 4, 3, 44, 0, 0, 3, 45, 0, 4, 0, 16, 0,109, 0, 13, + 0, 2, 3, 46, 0, 2, 3, 47, 0, 2, 3, 48, 0, 2, 3, 49, 0, 2, 3, 50, 0, 2, 0, 71, 0, 7, 3, 51, 0, 7, 3, 52, + 0, 2, 3, 53, 0, 2, 3, 54, 0, 2, 3, 55, 0, 0, 1, 59, 0, 0, 1, 48, 0,110, 0, 32, 0, 24, 0, 18, 0, 39, 3, 56, + 0,100, 3, 57, 0,110, 3, 58, 0, 35, 0,142, 0, 11, 3, 59, 0,102, 3, 60, 0, 7, 3, 61, 0, 7, 3, 62, 0, 7, 3, 63, + 0, 7, 3, 64, 0, 4, 0,239, 0, 7, 3, 65, 0, 2, 3, 66, 0, 2, 3, 67, 0, 2, 3, 68, 0, 2, 1, 29, 0, 49, 1, 51, + 0, 9, 3, 69, 0,101, 3, 70, 0, 9, 1,185, 0,107, 3, 71, 0,109, 3, 72, 0,106, 0,117, 0,105, 3, 73, 0, 30, 0, 82, + 0, 11, 3, 74, 0,111, 3, 75, 0, 2, 3, 76, 0, 2, 3, 77, 0, 2, 3, 78, 0, 2, 0,149, 0,112, 0, 10, 0, 35, 0,142, + 0, 40, 0,108, 0, 7, 1,141, 0, 7, 1,142, 0, 7, 0, 68, 0, 7, 3, 79, 0, 7, 3, 80, 0, 2, 3, 81, 0, 2, 3, 82, + 0, 4, 3, 83, 0,113, 0, 56, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, + 0, 7, 3, 88, 0, 7, 3, 89, 0, 7, 3, 90, 0, 7, 3, 91, 0, 7, 3, 92, 0, 7, 3, 93, 0, 7, 3, 94, 0, 7, 0,204, + 0, 2, 3, 95, 0, 2, 3, 96, 0, 39, 3, 56, 0,112, 3, 97, 0,113, 3, 98, 0,116, 3, 99, 0, 2, 2,174, 0, 2, 3,100, + 0, 4, 0,239, 0, 4, 3,101, 0, 2, 3,102, 0, 2, 3,103, 0, 2, 3,104, 0, 2, 0, 16, 0, 7, 0, 74, 0, 7, 3,105, + 0, 7, 3,106, 0, 7, 3,107, 0, 7, 3,108, 0, 7, 3,109, 0, 7, 3,110, 0, 7, 3,111, 0, 7, 0,113, 0, 7, 3, 61, + 0, 2, 3,112, 0, 2, 3,113, 0, 2, 3,114, 0, 2, 3,115, 0, 2, 3,116, 0, 2, 3,117, 0, 2, 3,118, 0, 2, 3,119, + 0, 2, 3,120, 0, 2, 3,121, 0, 7, 3,122, 0, 7, 3,123, 0, 54, 3,124, 0, 11, 3,125, 0, 2, 3,126, 0, 2, 1,171, + 0, 2, 3,127, 0, 2, 1, 59, 0,117, 0, 16, 0, 23, 0, 23, 0, 23, 0, 26, 0, 22, 3,128, 0, 22, 3,129, 0, 22, 3,130, + 0, 7, 3,131, 0, 7, 3,132, 0, 7, 3,133, 0, 7, 3,134, 0, 2, 3,135, 0, 2, 3,136, 0, 2, 3,137, 0, 2, 3,138, + 0, 2, 3,139, 0, 2, 3,140, 0, 4, 0, 16, 0,114, 0, 6, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, + 0,115, 3, 86, 0, 2, 3, 87, 0,118, 0, 6, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, + 0, 2, 3, 87, 0,119, 0, 26, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, + 0, 4, 3,141, 0, 4, 1, 59, 0,117, 3,142, 0, 9, 3,143, 0, 11, 3,144, 0, 27, 0, 44, 0, 24, 0, 45, 0, 0, 3,145, + 0, 0, 3,146, 0, 2, 3,147, 0, 2, 3,148, 0, 2, 3,149, 0, 2, 3,150, 0, 2, 0, 28, 0, 2, 0, 27, 0, 2, 3,116, + 0, 2, 3,151, 0, 4, 0, 16, 0, 7, 3,152, 0, 23, 0, 23, 0,120, 0, 29, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, + 0, 7, 3, 85, 0,115, 3, 86, 0,116, 3, 99, 0, 2, 3, 87, 0, 2, 3,153, 0, 2, 3,154, 0, 2, 3,155, 0, 2, 3,156, + 0,117, 3,142, 0, 2, 3,157, 0, 2, 3,116, 0, 2, 3,148, 0, 2, 3,158, 0, 9, 3,159, 0, 2, 3,117, 0, 0, 3,160, + 0, 0, 3,161, 0, 2, 3,162, 0, 2, 3,163, 0, 2, 2, 26, 0, 2, 3,164, 0, 2, 3,165, 0, 0, 1, 29, 0, 0, 0, 24, + 0, 0, 0,223, 0, 0, 3,166, 0,121, 0, 10, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, + 0, 2, 3, 87, 0,117, 3,142, 0, 2, 3,157, 0, 2, 3, 79, 0, 4, 1, 59, 0,122, 0, 24, 0,114, 0, 0, 0,114, 0, 1, + 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, 0,123, 3,167, 0, 4, 3,168, 0, 0, 3,169, 0, 0, 3,170, + 0, 0, 3,171, 0, 2, 0, 31, 0, 2, 3,172, 0, 2, 0, 16, 0, 2, 3,173, 0, 2, 3,174, 0, 2, 3,175, 0,124, 3,176, + 0, 2, 3,177, 0, 2, 0,140, 0, 2, 3,178, 0, 2, 3,179, 0, 9, 3,180, 0, 2, 3,181, 0,125, 0, 19, 0,114, 0, 0, + 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, 0,117, 3,142, 0, 11, 3,182, 0, 2, 3,148, + 0, 2, 3,183, 0, 2, 0, 16, 0, 2, 1,165, 0, 9, 3,159, 0, 11, 3,184, 0,126, 3,185, 0, 2, 0, 31, 0, 2, 3,186, + 0, 2, 3,187, 0, 2, 3,188, 0,127, 0, 18, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, + 0, 2, 3, 87, 0,117, 3,142, 0, 35, 3,189, 0,128, 3,190, 0, 7, 3, 79, 0, 2, 0,201, 0, 2, 3,116, 0, 2, 3,191, + 0, 2, 3,192, 0, 7, 1,141, 0, 7, 1,142, 0, 2, 0, 16, 0, 2, 3,151, 0,129, 0, 10, 0,114, 0, 0, 0,114, 0, 1, + 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, 0, 2, 3,116, 0, 2, 3,151, 0, 4, 0, 24, 0,117, 3,142, + 0,130, 0, 22, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, 0, 32, 3,193, + 0, 4, 3,194, 0, 4, 3,195, 0, 2, 0, 57, 0, 2, 3,116, 0, 4, 3,196, 0, 4, 3,197, 0, 4, 3,198, 0, 4, 3,199, + 0, 4, 3,200, 0, 4, 3,201, 0, 4, 3,202, 0, 4, 3,203, 0, 7, 3,204, 0, 22, 3,205, 0, 22, 3,206, 0,131, 0, 9, + 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0,132, 3,207, 0, 4, 1, 59, 0, 2, 0, 57, + 0, 2, 3,116, 0,133, 0, 8, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0,117, 3,142, + 0, 4, 0, 16, 0, 4, 3,208, 0,134, 0, 16, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, + 0,117, 3,142, 0, 24, 3,209, 0, 24, 0, 45, 0, 2, 0, 16, 0, 2, 3,116, 0, 7, 3,210, 0, 9, 3,211, 0, 49, 1, 51, + 0, 49, 3,212, 0, 4, 3,213, 0, 4, 0, 24, 0,135, 0, 81, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, + 0,115, 3, 86, 0, 0, 3,214, 0, 4, 3,215, 0, 2, 0,201, 0, 2, 3,216, 0, 2, 3,217, 0, 2, 3,218, 0, 2, 3,219, + 0, 2, 3,220, 0, 2, 3,221, 0, 2, 3,222, 0, 2, 3,223, 0, 2, 3,224, 0, 2, 3,225, 0, 2, 3,226, 0, 2, 3,227, + 0, 2, 3,228, 0, 2, 3,229, 0, 2, 3,230, 0, 2, 3,231, 0, 2, 3,232, 0, 2, 3,233, 0, 2, 3,234, 0, 2, 3,235, + 0, 2, 3,236, 0, 2, 3,237, 0, 2, 3,238, 0, 2, 3,239, 0, 2, 3,240, 0, 2, 3,241, 0, 2, 3,242, 0, 2, 3,243, + 0, 2, 3,244, 0, 2, 3,245, 0, 2, 3,246, 0, 2, 3,247, 0, 2, 3,248, 0, 2, 3,249, 0, 2, 3,250, 0, 2, 3,251, + 0, 2, 3,252, 0, 2, 3,253, 0, 2, 3,254, 0, 2, 3,255, 0, 2, 4, 0, 0, 2, 4, 1, 0, 2, 4, 2, 0, 2, 4, 3, + 0, 2, 4, 4, 0, 2, 4, 5, 0, 2, 4, 6, 0, 0, 4, 7, 0, 0, 4, 8, 0, 0, 4, 9, 0, 0, 4, 10, 0,136, 4, 11, + 0,136, 4, 12, 0, 4, 4, 13, 0, 4, 4, 14, 0, 4, 4, 15, 0, 4, 4, 16, 0, 4, 4, 17, 0, 7, 4, 18, 0, 7, 4, 19, + 0, 7, 4, 20, 0, 2, 4, 21, 0, 2, 4, 22, 0, 2, 4, 23, 0, 2, 4, 24, 0,137, 4, 25, 0,137, 4, 26, 0, 2, 4, 27, + 0, 2, 4, 28, 0, 4, 1, 59, 0, 37, 4, 29, 0, 9, 3,180, 0, 9, 4, 30, 0,138, 0, 19, 0, 0, 4, 31, 0, 0, 4, 32, + 0, 0, 4, 33, 0, 0, 4, 34, 0, 0, 4, 35, 0, 0, 4, 36, 0, 0, 4, 37, 0, 0, 4, 38, 0, 0, 4, 39, 0, 0, 4, 40, + 0, 0, 4, 41, 0, 0, 4, 42, 0, 0, 4, 43, 0, 0, 4, 44, 0, 0, 4, 45, 0, 0, 4, 46, 0, 0, 4, 47, 0, 0, 4, 48, + 0, 0, 4, 49, 0,139, 0, 36, 0, 0, 4, 50, 0, 0, 4, 41, 0, 0, 4, 42, 0, 0, 4, 51, 0, 0, 4, 52, 0, 0, 4, 53, + 0, 0, 4, 54, 0, 0, 4, 55, 0, 0, 4, 56, 0, 0, 4, 57, 0, 0, 4, 58, 0, 0, 4, 59, 0, 0, 4, 60, 0, 0, 4, 61, + 0, 0, 4, 62, 0, 0, 4, 63, 0, 0, 4, 64, 0, 0, 4, 65, 0, 0, 4, 66, 0, 0, 4, 67, 0, 0, 4, 68, 0, 0, 4, 69, + 0, 0, 4, 70, 0, 0, 4, 71, 0, 0, 4, 72, 0, 0, 4, 73, 0, 0, 4, 74, 0, 0, 4, 75, 0, 0, 4, 76, 0, 0, 4, 77, + 0, 0, 4, 78, 0, 0, 4, 79, 0, 0, 4, 80, 0, 0, 4, 81, 0, 0, 4, 82, 0, 0, 4, 83, 0,140, 0, 19, 0,140, 0, 0, + 0,140, 0, 1, 0, 0, 0, 36, 0,138, 4, 84, 0,139, 4, 85, 0,139, 4, 86, 0,139, 4, 87, 0,139, 4, 88, 0,139, 4, 89, + 0,139, 4, 90, 0,139, 4, 91, 0,139, 4, 92, 0,139, 4, 93, 0,139, 4, 94, 0,139, 4, 95, 0,139, 4, 96, 0,139, 4, 97, + 0,139, 4, 98, 0,139, 4, 99, 0,141, 0, 5, 0, 4, 0, 16, 0, 4, 0, 24, 0, 7, 1,170, 0, 7, 4,100, 0, 7, 1,104, + 0,142, 0, 45, 0, 4, 0, 16, 0, 4, 4,101, 0, 4, 4,102, 0, 0, 4,103, 0, 0, 4,104, 0, 0, 4,105, 0, 0, 4,106, + 0, 0, 4,107, 0, 0, 4,108, 0, 0, 4,109, 0, 0, 4,110, 0, 0, 4,111, 0, 2, 4,112, 0, 2, 4,113, 0, 4, 4,114, + 0, 4, 4,115, 0, 4, 4,116, 0, 4, 4,117, 0, 2, 4,118, 0, 2, 4,119, 0, 2, 4,120, 0, 2, 4,121, 0, 4, 4,122, + 0, 4, 4,123, 0, 2, 4,124, 0, 2, 4,125, 0, 2, 4,126, 0, 2, 4,127, 0, 0, 4,128, 0, 11, 4,129, 0, 2, 4,130, + 0, 2, 4,131, 0, 2, 4,132, 0, 2, 4,133, 0,141, 4,134, 0, 2, 4,135, 0, 2, 4,136, 0, 2, 4,137, 0, 2, 4,138, + 0, 4, 4,139, 0, 4, 4,140, 0, 2, 4,141, 0, 2, 0, 71, 0, 2, 1, 59, 0, 2, 1, 48, 0,143, 0, 18, 0, 24, 0, 18, + 0, 11, 4,142, 0, 11, 4,143, 0, 11, 4,144, 0,110, 4,145, 0, 2, 1,220, 0, 2, 4,146, 0, 2, 1,221, 0, 2, 4,147, + 0, 2, 4,148, 0, 2, 4,149, 0, 2, 4,150, 0, 2, 4,151, 0, 2, 4,152, 0, 2, 0, 24, 0, 2, 4,153, 0, 2, 4,154, + 0, 2, 4,155, 0,144, 0, 5, 0,144, 0, 0, 0,144, 0, 1, 0,144, 4,156, 0, 12, 4,157, 0, 4, 0, 16, 0,145, 0, 7, + 0,145, 0, 0, 0,145, 0, 1, 0,144, 4,158, 0,144, 4,159, 0, 2, 2,253, 0, 2, 0, 16, 0, 4, 0, 24, 0,146, 0, 16, + 0,146, 0, 0, 0,146, 0, 1, 0, 0, 4,160, 0, 0, 4,161, 0, 2, 4,162, 0, 2, 4,163, 0, 2, 4,148, 0, 2, 4,149, + 0, 2, 0, 16, 0, 2, 2, 69, 0, 2, 4,164, 0, 2, 0, 24, 0, 2, 4,165, 0, 2, 4,166, 0, 4, 4,167, 0,146, 4,168, + 0,115, 0, 30, 0,115, 0, 0, 0,115, 0, 1, 0,144, 4,158, 0,144, 4,159, 0,144, 4,169, 0,144, 4,170, 0,143, 4,171, + 0, 7, 4,172, 0, 22, 1,160, 0, 22, 4,173, 0, 22, 4,174, 0, 2, 4,175, 0, 2, 4,176, 0, 2, 4,177, 0, 0, 3, 84, + 0, 0, 4,178, 0, 2, 4,179, 0, 2, 4,180, 0, 0, 4,181, 0, 0, 4,182, 0, 0, 4,183, 0, 0, 4,184, 0, 2, 4,185, + 0, 2, 4,186, 0, 2, 4,187, 0, 2, 0, 16, 0, 30, 0, 82, 0, 11, 4,188, 0, 11, 4,189, 0, 11, 4,190, 0,147, 0, 7, + 0, 9, 4,191, 0, 9, 4,192, 0, 2, 4,193, 0, 2, 2,236, 0, 4, 4,194, 0, 4, 4,195, 0, 4, 0, 24, 0,148, 0, 8, + 0, 0, 4,196, 0, 37, 0, 85, 0,148, 4,197, 0,148, 4,198, 0,148, 4,199, 0, 2, 0, 87, 0, 2, 4,200, 0, 4, 0, 24, + 0,149, 0, 11, 0,149, 0, 0, 0,149, 0, 1, 0, 2, 1,165, 0, 2, 0, 54, 0, 2, 0, 15, 0, 2, 4,201, 0,148, 4,202, + 0, 0, 3,170, 0, 2, 4,203, 0, 2, 4,204, 0, 4, 0, 24, 0,150, 0, 10, 0, 0, 1, 68, 0, 9, 0,127, 0, 0, 0,128, + 0, 4, 0,131, 0, 4, 0,138, 0, 9, 0,132, 0, 7, 0,134, 0, 7, 0,135, 0, 9, 0,136, 0, 9, 0,137, 0,151, 0, 38, + 0,151, 0, 0, 0,151, 0, 1, 0,151, 4,205, 0, 9, 0, 13, 0, 0, 0, 14, 0, 2, 0, 16, 0, 2, 0, 31, 0, 4, 0, 54, + 0, 4, 1,212, 0, 4, 4,206, 0, 4, 4,207, 0, 4, 4,208, 0, 4, 4,209, 0, 4, 4,210, 0, 4, 0,148, 0, 4, 4,211, + 0, 4, 4,212, 0, 7, 4,213, 0, 7, 4,214, 0, 4, 0,189, 0,149, 4,215, 0,148, 4,216, 0, 27, 0, 44, 0,110, 4,145, + 0, 36, 0, 84, 0, 7, 4,217, 0, 7, 4,218, 0,150, 0,191, 0,151, 4,219, 0,151, 4,220, 0,151, 4,221, 0, 11, 4,222, + 0,152, 4,223, 0, 7, 4,224, 0, 7, 4,225, 0, 4, 4,226, 0, 7, 4,227, 0, 9, 4,228, 0,153, 0, 4, 0,153, 0, 0, + 0,153, 0, 1, 0, 11, 4,229, 0,151, 4,230, 0,154, 0, 6, 0, 11, 4,231, 0, 11, 4,222, 0, 11, 4,232, 0, 2, 0, 16, + 0, 2, 1,165, 0, 4, 0, 24, 0,155, 0, 4, 0, 7, 4,233, 0, 7, 4,234, 0, 2, 4,235, 0, 2, 4,236, 0,156, 0, 6, + 0, 7, 4,237, 0, 7, 4,238, 0, 7, 4,239, 0, 7, 4,240, 0, 4, 4,241, 0, 4, 4,242, 0,157, 0, 6, 0,157, 0, 0, + 0,157, 0, 1, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,243, 0, 2, 1,165, 0,158, 0, 8, 0,158, 0, 0, 0,158, 0, 1, + 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,243, 0, 2, 1,165, 0, 7, 0, 54, 0, 7, 0,189, 0,159, 0, 43, 0,159, 0, 0, + 0,159, 0, 1, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,243, 0, 2, 0,145, 0, 2, 2, 95, 0, 2, 4,244, 0, 7, 4,245, + 0, 7, 4,246, 0, 7, 1,227, 0, 4, 4,247, 0, 4, 0, 46, 0, 4, 1,215, 0, 7, 4,248, 0, 7, 4,249, 0, 7, 4,250, + 0, 7, 4,251, 0, 7, 4,252, 0, 7, 4,253, 0, 7, 1,225, 0, 7, 0,186, 0, 7, 4,254, 0, 7, 4,255, 0, 7, 5, 0, + 0, 7, 5, 1, 0, 2, 5, 2, 0, 2, 5, 3, 0, 2, 5, 4, 0, 2, 5, 5, 0, 2, 5, 6, 0, 2, 5, 7, 0, 2, 5, 8, + 0, 2, 5, 9, 0, 2, 5, 10, 0, 2, 5, 11, 0, 2, 1, 89, 0, 2, 5, 12, 0, 0, 5, 13, 0, 0, 5, 14, 0, 7, 0,144, + 0,160, 5, 15, 0, 50, 1, 52, 0,161, 0, 16, 0,161, 0, 0, 0,161, 0, 1, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,243, + 0, 2, 0,145, 0, 7, 1,220, 0, 7, 1,221, 0, 7, 1,222, 0, 7, 1,130, 0, 7, 1,223, 0, 7, 1,224, 0, 7, 5, 16, + 0, 7, 1,225, 0, 7, 1,226, 0, 7, 1,227, 0,162, 0, 5, 0, 2, 0, 31, 0, 2, 4,200, 0, 2, 0, 16, 0, 2, 5, 17, + 0, 24, 3,209, 0,126, 0, 3, 0, 4, 0, 33, 0, 4, 5, 18, 0,162, 0, 34, 0,163, 0, 12, 0,163, 0, 0, 0,163, 0, 1, + 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 2, 42, 0, 2, 1,103, 0, 7, 0, 4, 0, 7, 0, 5, 0, 7, 5, 19, 0, 7, 5, 20, + 0, 24, 3,209, 0, 11, 5, 21, 0,164, 0, 11, 0,164, 0, 0, 0,164, 0, 1, 0, 0, 0, 36, 0, 2, 0, 31, 0, 2, 5, 22, + 0, 4, 5, 23, 0, 4, 5, 24, 0, 2, 0, 16, 0, 2, 0, 24, 0, 9, 5, 25, 0, 9, 5, 26, 0,165, 0, 5, 0, 0, 0, 36, + 0, 7, 0,204, 0, 7, 5, 27, 0, 4, 5, 28, 0, 4, 0, 24, 0,166, 0, 4, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 0, 71, + 0, 2, 1, 59, 0,167, 0, 4, 0, 0, 0, 36, 0, 48, 5, 29, 0, 7, 0,204, 0, 7, 0, 24, 0,168, 0, 6, 0, 2, 5, 30, + 0, 2, 5, 31, 0, 2, 0, 31, 0, 2, 5, 32, 0, 0, 5, 33, 0, 0, 5, 34, 0,169, 0, 5, 0, 4, 0, 31, 0, 4, 0, 24, + 0, 0, 0, 36, 0, 0, 5, 35, 0, 0, 5, 36, 0,170, 0, 6, 0, 0, 0, 36, 0, 0, 5, 37, 0, 2, 5, 38, 0, 2, 1,225, + 0, 2, 0,201, 0, 2, 1, 59, 0,171, 0, 5, 0, 0, 0, 36, 0, 7, 4,234, 0, 7, 2,140, 0, 2, 0, 16, 0, 2, 1,216, + 0,172, 0, 3, 0, 0, 0, 36, 0, 4, 1,215, 0, 4, 5, 39, 0,173, 0, 7, 0, 0, 0, 36, 0, 7, 2,140, 0, 0, 5, 40, + 0, 0, 5, 41, 0, 2, 0,201, 0, 2, 0, 71, 0, 4, 5, 42, 0,174, 0, 3, 0, 39, 5, 43, 0, 0, 5, 44, 0, 0, 5, 45, + 0,175, 0, 17, 0,175, 0, 0, 0,175, 0, 1, 0, 2, 0, 31, 0, 2, 5, 22, 0, 2, 0, 16, 0, 2, 5, 46, 0, 2, 5, 47, + 0, 2, 5, 48, 0, 2, 0, 71, 0, 2, 1, 59, 0, 0, 0, 36, 0, 9, 0, 34, 0,176, 5, 49, 0, 39, 0,200, 0, 2, 5, 50, + 0, 2, 5, 51, 0, 4, 0, 24, 0,177, 0, 10, 0, 0, 0, 36, 0, 2, 0, 31, 0, 2, 0, 24, 0, 4, 1,216, 0, 4, 5, 52, + 0, 4, 5, 53, 0, 4, 5, 54, 0, 4, 5, 55, 0, 4, 5, 56, 0, 4, 5, 57, 0,178, 0, 1, 0, 0, 5, 58, 0,179, 0, 1, + 0, 32, 3,193, 0,176, 0, 18, 0,176, 0, 0, 0,176, 0, 1, 0,176, 5, 59, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 5, 60, + 0, 2, 5, 48, 0, 2, 5, 22, 0, 2, 5, 61, 0, 2, 1, 59, 0, 2, 1, 48, 0, 0, 0, 36, 0, 9, 0, 34, 0,180, 5, 49, + 0,175, 5, 62, 0, 2, 5, 63, 0, 2, 5, 64, 0, 4, 5, 65, 0,181, 0, 3, 0, 4, 5, 66, 0, 4, 0, 24, 0, 39, 0,200, + 0,182, 0, 13, 0, 90, 5, 67, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,245, 0, 2, 4,246, 0, 0, 0, 36, 0, 2, 5, 68, + 0, 2, 5, 69, 0, 7, 5, 70, 0, 2, 5, 71, 0, 2, 0,101, 0, 2, 0,102, 0, 2, 5, 72, 0,183, 0, 9, 0, 2, 0, 16, + 0, 2, 5, 73, 0, 2, 4,245, 0, 2, 4,246, 0,152, 4,223, 0, 2, 0, 31, 0, 2, 5, 74, 0, 2, 5, 75, 0, 2, 5, 76, + 0,184, 0, 7, 0, 2, 0, 16, 0, 2, 5, 73, 0, 2, 4,245, 0, 2, 4,246, 0, 2, 0, 31, 0, 2, 5, 77, 0, 7, 5, 78, + 0,185, 0, 9, 0, 4, 5, 66, 0, 2, 0, 31, 0, 2, 0, 16, 0, 39, 0,200, 0, 66, 5, 79, 0, 0, 0, 36, 0, 7, 5, 80, + 0, 2, 5, 81, 0, 2, 0, 24, 0,186, 0, 5, 0, 2, 0, 31, 0, 2, 0, 16, 0, 4, 0, 24, 0,110, 4,145, 0, 39, 3, 56, + 0,187, 0, 5, 0, 4, 0, 16, 0, 4, 0, 31, 0, 0, 0, 36, 0, 0, 5, 35, 0, 39, 0,200, 0,188, 0, 12, 0, 4, 0, 16, + 0, 4, 0, 31, 0, 7, 5, 82, 0, 7, 5, 83, 0, 7, 0,195, 0, 7, 0,196, 0, 7, 2, 12, 0, 7, 2, 15, 0, 7, 5, 84, + 0, 7, 5, 85, 0, 7, 5, 86, 0, 0, 5, 87, 0,189, 0, 9, 0, 2, 0, 16, 0, 2, 0, 31, 0, 2, 4,245, 0, 2, 4,246, + 0, 0, 0, 36, 0, 2, 0, 71, 0, 2, 0, 26, 0, 2, 5, 88, 0, 2, 5, 89, 0,190, 0, 8, 0, 39, 0,200, 0, 7, 1,222, + 0, 7, 5, 90, 0, 7, 1,252, 0, 7, 5, 91, 0, 2, 0, 16, 0, 2, 1,216, 0, 7, 5, 92, 0,191, 0, 7, 0, 2, 0, 16, + 0, 2, 1,225, 0, 7, 5, 93, 0, 7, 5, 94, 0, 7, 5, 95, 0, 7, 5, 96, 0, 7, 5, 97, 0,192, 0, 10, 0, 2, 0, 16, + 0, 2, 0, 31, 0, 2, 4,245, 0, 2, 4,246, 0, 0, 0, 36, 0, 2, 0, 71, 0, 2, 0, 26, 0, 2, 5, 88, 0, 2, 5, 89, + 0, 50, 1, 52, 0,193, 0, 7, 0, 4, 1,215, 0, 4, 5, 98, 0, 4, 5, 99, 0, 4, 5,100, 0, 7, 5,101, 0, 7, 5,102, + 0, 0, 5, 40, 0,194, 0, 7, 0, 0, 5,103, 0, 39, 5,104, 0, 0, 5, 44, 0, 2, 5,105, 0, 2, 0, 71, 0, 4, 1, 59, + 0, 0, 5, 45, 0,195, 0, 6, 0, 2, 0, 16, 0, 2, 0, 31, 0, 2, 4,245, 0, 2, 4,246, 0, 0, 5,106, 0, 0, 5,107, + 0,196, 0, 1, 0, 4, 0, 16, 0,180, 0, 10, 0,180, 0, 0, 0,180, 0, 1, 0,180, 5, 59, 0, 2, 0, 31, 0, 2, 0, 16, + 0, 2, 5, 22, 0, 2, 5,108, 0, 0, 0, 36, 0, 9, 0, 34, 0, 39, 0,200, 0,197, 0, 10, 0, 7, 2, 35, 0, 7, 5,109, + 0, 7, 5,110, 0, 7, 5,111, 0, 7, 5,112, 0, 4, 0, 16, 0, 7, 5,113, 0, 7, 5,114, 0, 7, 5,115, 0, 7, 0, 24, + 0,152, 0, 22, 0, 24, 0, 18, 0, 0, 0, 83, 0,198, 5,116, 0, 9, 5,117, 0, 33, 0, 97, 0, 33, 5,118, 0, 9, 5,119, + 0, 27, 0, 44, 0, 7, 5, 78, 0, 7, 5,120, 0, 7, 5,121, 0, 7, 5,122, 0, 7, 5,123, 0, 7, 5,124, 0, 7, 5,125, + 0, 4, 0, 57, 0, 4, 5,126, 0, 4, 5,127, 0, 4, 5,128, 0, 0, 5,129, 0, 0, 5,130, 0, 0, 5,131, 0,199, 0, 6, + 0, 24, 0, 18, 0, 7, 5,132, 0, 7, 5,133, 0, 7, 5,134, 0, 2, 5,135, 0, 2, 5,136, 0,200, 0, 14, 0,114, 0, 0, + 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0,117, 3,142, 0,152, 4,223, 0, 2, 0,201, 0, 2, 5, 73, + 0, 2, 1,141, 0, 2, 1,142, 0, 2, 0, 16, 0, 2, 3,151, 0, 4, 1, 59, 0,201, 0, 6, 0,201, 0, 0, 0,201, 0, 1, + 0, 39, 0,200, 0, 9, 5,137, 0, 4, 0,149, 0, 4, 0, 24, 0, 50, 0, 2, 0, 24, 0, 18, 0, 11, 5,138, 0,202, 0, 25, + 0,202, 0, 0, 0,202, 0, 1, 0,202, 2, 4, 0, 11, 5,139, 0, 0, 0, 36, 0, 7, 5,140, 0, 7, 5,141, 0, 7, 5,142, + 0, 7, 5,143, 0, 4, 0, 16, 0, 7, 5,144, 0, 7, 5,145, 0, 7, 5,146, 0, 7, 0,204, 0, 7, 1, 97, 0, 7, 5,147, + 0, 7, 1,213, 0, 7, 5,148, 0, 7, 5,149, 0, 7, 5,150, 0, 7, 5,151, 0, 7, 5,152, 0, 7, 0,114, 0, 2, 5,153, + 0, 2, 3, 53, 0,203, 0, 9, 0, 24, 0, 18, 0, 11, 5,154, 0, 11, 5,155, 0, 4, 0, 16, 0, 4, 2,174, 0, 2, 1,228, + 0, 2, 5,153, 0, 2, 5,156, 0, 2, 5,157, 0,204, 0, 30, 0,204, 0, 0, 0,204, 0, 1, 0, 11, 2, 56, 0, 0, 0, 36, + 0, 2, 0, 16, 0, 2, 5,158, 0, 2, 5,159, 0, 2, 1,128, 0, 2, 2, 24, 0, 2, 0, 24, 0, 2, 0, 71, 0, 2, 1, 59, + 0,202, 5,160, 0,204, 2, 4, 0,204, 5,161, 0, 11, 5,162, 0, 9, 5,163, 0, 7, 0,195, 0, 7, 0,114, 0, 7, 1, 79, + 0, 7, 5,164, 0, 7, 5,165, 0, 7, 5,166, 0, 7, 5,167, 0, 7, 5,168, 0, 7, 5,169, 0, 7, 5,170, 0, 7, 5,171, + 0, 7, 1,125, 0, 39, 5,172, 0, 91, 0, 3, 0, 11, 5,173, 0, 4, 0, 16, 0, 7, 5,174, 0,205, 0, 7, 0,205, 0, 0, + 0,205, 0, 1, 0, 27, 0, 44, 0, 11, 2, 8, 0, 4, 0, 16, 0, 0, 0, 36, 0, 4, 0,101, 0, 90, 0, 2, 0, 24, 0, 18, + 0, 11, 5,173, 0,206, 0, 14, 0,114, 0, 0, 0,114, 0, 1, 0, 4, 3, 84, 0, 7, 3, 85, 0,115, 3, 86, 0, 2, 3, 87, + 0,117, 3,142, 0, 90, 2, 6, 0, 4, 0, 16, 0, 2, 3,148, 0, 2, 5,175, 0, 2, 3,151, 0, 2, 0, 24, 0, 7, 5,176, + 0,207, 0, 5, 0,207, 0, 0, 0,207, 0, 1, 0, 27, 0, 44, 0, 2, 0, 16, 0, 0, 5,177, 0,208, 0, 8, 0,208, 0, 0, + 0,208, 0, 1, 0, 9, 0, 34, 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 0,101, 0, 0, 5,177, 0, 7, 5,178, 0,209, 0, 11, + 0, 39, 5,179, 0, 7, 1,217, 0, 2, 5,180, 0, 2, 0, 16, 0, 4, 5,181, 0, 4, 0, 24, 0, 0, 5,182, 0, 7, 1, 97, + 0, 7, 5,183, 0, 7, 5,184, 0, 7, 1, 59, 0,210, 0, 4, 0, 39, 5,179, 0, 4, 0,101, 0, 4, 0,102, 0, 0, 5,182, + 0,211, 0, 4, 0, 39, 5,179, 0, 4, 0, 16, 0, 4, 0,101, 0, 0, 5,182, 0,212, 0, 4, 0, 39, 5,179, 0, 4, 0, 16, + 0, 4, 0,101, 0, 0, 5,182, 0,213, 0, 7, 0, 39, 5,179, 0, 4, 5,185, 0, 7, 0,188, 0, 2, 5,186, 0, 2, 5,187, + 0, 7, 5,188, 0, 0, 5,182, 0,214, 0, 9, 0, 39, 5,179, 0, 2, 0, 31, 0, 2, 5,189, 0, 2, 1,212, 0, 2, 4,246, + 0, 7, 5, 90, 0, 7, 1,252, 0, 90, 5, 67, 0, 0, 5,182, 0,215, 0, 4, 0, 39, 5,179, 0, 4, 2, 21, 0, 4, 5,190, + 0, 0, 5,182, 0,216, 0, 5, 0, 39, 5,179, 0, 7, 0,188, 0, 4, 5,191, 0, 4, 2, 21, 0, 4, 2, 22, 0,217, 0, 6, + 0, 39, 5,179, 0, 0, 5,182, 0, 7, 0, 71, 0, 7, 1, 59, 0, 7, 5,125, 0, 7, 5,192, 0,218, 0, 6, 0, 7, 0, 8, + 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 3, 6, 0, 7, 5,193, 0,219, 0, 6, 0, 39, 5,179, 0, 4, 5,194, + 0, 4, 5,195, 0, 7, 5,196, 0, 7, 5,197, 0, 0, 5,182, 0,220, 0, 20, 0,220, 0, 0, 0,220, 0, 1, 0, 2, 0, 16, + 0, 2, 0,201, 0, 2, 5,198, 0, 2, 0, 24, 0, 27, 0, 44, 0, 90, 5, 67, 0, 39, 0,107, 0, 7, 1,212, 0, 7, 4,246, + 0, 7, 5,199, 0, 7, 5,200, 0, 7, 5,201, 0, 7, 5,202, 0, 7, 5,203, 0, 7, 5,204, 0, 7, 5, 68, 0, 7, 5,205, + 0, 0, 5,206, 0,221, 0, 7, 0, 7, 1,104, 0, 7, 5, 90, 0, 7, 1,252, 0, 9, 0, 34, 0, 2, 5,207, 0, 2, 5,208, + 0, 4, 0, 71, 0,222, 0, 17, 0,222, 0, 0, 0,222, 0, 1, 0, 0, 0, 36, 0,221, 5,209, 0, 2, 0, 31, 0, 2, 0, 16, + 0, 2, 5,210, 0, 2, 5,211, 0, 2, 5,212, 0, 2, 5,213, 0, 4, 0, 71, 0, 7, 5,214, 0, 7, 5,215, 0, 4, 5,216, + 0, 4, 5,217, 0,222, 5,218, 0,223, 5,219, 0,224, 0, 29, 0,224, 0, 0, 0,224, 0, 1, 0,224, 5,220, 0, 0, 0, 36, + 0, 2, 0, 31, 0, 2, 0, 16, 0, 2, 4,201, 0, 2, 4,224, 0, 2, 5,221, 0, 2, 3,116, 0, 2, 5,211, 0, 2, 0, 24, + 0, 11, 5, 60, 0, 11, 5,222, 0, 24, 3,209, 0, 9, 5,223, 0,225, 5,224, 0, 7, 5,214, 0, 7, 5,215, 0, 7, 1,130, + 0, 7, 5,225, 0, 2, 5,226, 0, 2, 5,227, 0, 4, 0, 71, 0, 23, 5,228, 0, 23, 5,229, 0, 23, 5,230, 0,226, 5,231, + 0,227, 5,232, 0,223, 0, 6, 0,223, 0, 0, 0,223, 0, 1, 0,224, 5,233, 0,224, 5,234, 0,222, 5,235, 0,222, 5,218, + 0, 49, 0, 11, 0, 24, 0, 18, 0, 11, 5,236, 0, 11, 5,237, 0,221, 5,238, 0,221, 5,239, 0, 4, 0, 31, 0, 4, 5,240, + 0, 4, 5,241, 0, 4, 0, 24, 0,227, 5,242, 0,227, 5,243, 0,228, 0, 4, 0, 7, 0, 4, 0, 7, 0, 5, 0, 2, 0, 16, + 0, 2, 5,244, 0,229, 0, 7, 0, 2, 2, 81, 0, 2, 0, 16, 0, 7, 2,140, 0, 7, 5,245, 0, 7, 5,246, 0,228, 5,247, + 0,228, 5,248, 0,128, 0, 9, 0, 4, 0, 16, 0, 4, 0, 26, 0, 23, 5,249, 0, 23, 5,250, 0,229, 5,251, 0, 7, 5,252, + 0, 7, 5,253, 0, 7, 5,254, 0, 7, 5,202, 69, 78, 68, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 5761d0af36c..0109d0d146c 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -1,7 +1,4 @@ -/* previewrender.c GRAPHICS - * - * maart 95 - * +/* * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** @@ -49,33 +46,43 @@ #include #endif #include "MEM_guardedalloc.h" + #include "BLI_arithb.h" -#include "BKE_utildefines.h" +#include "BLI_blenlib.h" #include "MTC_matrixops.h" -#include "render.h" -#include "mydevice.h" - #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "DNA_camera_types.h" #include "DNA_image_types.h" #include "DNA_material_types.h" +#include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_lamp_types.h" #include "DNA_space_types.h" +#include "DNA_view3d_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "BKE_global.h" #include "BKE_image.h" +#include "BKE_icons.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_texture.h" #include "BKE_material.h" +#include "BKE_node.h" #include "BKE_world.h" #include "BKE_texture.h" +#include "BKE_utildefines.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" #include "BSE_headerbuttons.h" +#include "BSE_node.h" +#include "BSE_view.h" #include "BIF_gl.h" #include "BIF_screen.h" @@ -89,175 +96,30 @@ #include "PIL_time.h" -#include "RE_renderconverter.h" +#include "RE_pipeline.h" +#include "BLO_readfile.h" #include "blendef.h" /* CLAMP */ -#include "interface.h" /* ui_graphics_to_window() SOLVE! (ton) */ +#include "interface.h" /* ui_graphics_to_window(), SOLVE! (ton) */ +#include "mydevice.h" + -#define PR_RECTX 141 -#define PR_RECTY 141 #define PR_XMIN 10 #define PR_YMIN 5 #define PR_XMAX 200 #define PR_YMAX 195 -#define PR_FACY (PR_YMAX-PR_YMIN-4)/(PR_RECTY) -static rctf prerect; -static float pr_facx, pr_facy; - - -/* implementation */ - -static short snijpunt(float *v1, float *v2, float *v3, float *rtlabda, float *ray1, float *ray2) +void set_previewrect(RenderInfo *ri, int win) { - float x0,x1,x2,t00,t01,t02,t10,t11,t12,t20,t21,t22; - float m0,m1,m2,deeldet,det1,det2,det3; - float rtu, rtv; + rctf viewplane; - t00= v3[0]-v1[0]; - t01= v3[1]-v1[1]; - t02= v3[2]-v1[2]; - t10= v3[0]-v2[0]; - t11= v3[1]-v2[1]; - t12= v3[2]-v2[2]; - t20= ray1[0]-ray2[0]; - t21= ray1[1]-ray2[1]; - t22= ray1[2]-ray2[2]; + BLI_init_rctf(&viewplane, PR_XMIN, PR_XMAX, PR_YMIN, PR_YMAX); + + ui_graphics_to_window_rct(win, &viewplane, &ri->disprect); - x0= t11*t22-t12*t21; - x1= t12*t20-t10*t22; - x2= t10*t21-t11*t20; - - deeldet= t00*x0+t01*x1+t02*x2; - if(deeldet!=0.0) { - m0= ray1[0]-v3[0]; - m1= ray1[1]-v3[1]; - m2= ray1[2]-v3[2]; - det1= m0*x0+m1*x1+m2*x2; - rtu= det1/deeldet; - if(rtu<=0.0) { - det2= t00*(m1*t22-m2*t21); - det2+= t01*(m2*t20-m0*t22); - det2+= t02*(m0*t21-m1*t20); - rtv= det2/deeldet; - if(rtv<=0.0) { - if(rtu+rtv>= -1.0) { - - det3= m0*(t12*t01-t11*t02); - det3+= m1*(t10*t02-t12*t00); - det3+= m2*(t11*t00-t10*t01); - *rtlabda= det3/deeldet; - - if(*rtlabda>=0.0 && *rtlabda<=1.0) { - return 1; - } - } - } - } - } - return 0; -} - -static float rcubev[7][3]= { - {-0.002055, 6.627364, -3.369742}, - {-6.031684, -3.750204, -1.992980}, - {-6.049086, 3.817431, 1.969788}, - { 6.031685, 3.833064, 1.992979}, - { 6.049086, -3.734571, -1.969787}, - { 0.002054, -6.544502, 3.369744}, - {-0.015348, 1.023131, 7.332510} }; - -static int rcubi[3][4]= { - {3, 6, 5, 4}, - {1, 5, 6, 2}, - {3, 0, 2, 6} }; - - -static int ray_previewrender(int x, int y, float *vec, float *vn) -{ - float scalef= 10.0/100.0; - float ray1[3], ray2[3]; - float minlabda, labda; - int totface= 3, hitface= -1; - int a; - - ray1[0]= ray2[0]= x*scalef; - ray1[1]= ray2[1]= y*scalef; - ray1[2]= -10.0; - ray2[2]= 10.0; - - minlabda= 1.0; - for(a=0; a -1) { - - CalcNormFloat(rcubev[rcubi[hitface][0]], rcubev[rcubi[hitface][1]], rcubev[rcubi[hitface][2]], vn); - - vec[0]= (minlabda*(ray1[0]-ray2[0])+ray2[0])/4.1; - vec[1]= (minlabda*(ray1[1]-ray2[1])+ray2[1])/4.1; - vec[2]= (minlabda*(ray1[2]-ray2[2])+ray2[2])/4.1; - - return 1; - } - return 0; -} - - -static unsigned int previewback(int type, int x, int y) -{ - - /* checkerboard, for later - x+= PR_RECTX/2; - y+= PR_RECTX/2; - if( ((x/24) + (y/24)) & 1) return 0x40404040; - else return 0xa0a0a0a0; - */ - - if(type & MA_DARK) { - if(abs(x)>abs(y)) return 0; - else return 0x40404040; - } - else { - if(abs(x)>abs(y)) return 0x40404040; - else return 0xa0a0a0a0; - } -} - -static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax) -{ - float pr_sizex, pr_sizey; - - prerect.xmin= xmin; - prerect.ymin= ymin; - prerect.xmax= xmax; - prerect.ymax= ymax; - - ui_graphics_to_window(win, &prerect.xmin, &prerect.ymin); - ui_graphics_to_window(win, &prerect.xmax, &prerect.ymax); - - pr_sizex= (prerect.xmax-prerect.xmin); - pr_sizey= (prerect.ymax-prerect.ymin); - - pr_facx= ( pr_sizex-1.0)/PR_RECTX; - pr_facy= ( pr_sizey-1.0)/PR_RECTY; - /* correction for gla draw */ - prerect.xmin-= curarea->winrct.xmin; - prerect.ymin-= curarea->winrct.ymin; + BLI_translate_rcti(&ri->disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -266,8 +128,8 @@ static void set_previewrect(int win, int xmin, int ymin, int xmax, int ymax) glaDefine2DArea(&curarea->winrct); - glPixelZoom(pr_facx, pr_facy); - + ri->pr_rectx= (ri->disprect.xmax-ri->disprect.xmin); + ri->pr_recty= (ri->disprect.ymax-ri->disprect.ymin); } static void end_previewrect(void) @@ -277,31 +139,14 @@ static void end_previewrect(void) glMatrixMode(GL_MODELVIEW); glPopMatrix(); - glPixelZoom(1.0, 1.0); - // restore viewport / scissor which was set by glaDefine2DArea glViewport(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy); glScissor(curarea->winrct.xmin, curarea->winrct.ymin, curarea->winx, curarea->winy); } -static void display_pr_scanline(unsigned int *rect, int recty) -{ - - /* we do steps of 4 scanlines. but draw 5, because of errors in some gfx cards (nvidia geforce, ati...) */ - if( (recty & 3)==3) { - - if(recty == 3) { - glaDrawPixelsSafe(prerect.xmin, prerect.ymin, PR_RECTX, 4, rect); - } - else { - rect+= (recty-4)*PR_RECTX; - glaDrawPixelsSafe(prerect.xmin, prerect.ymin + (((float)recty-4.0)*pr_facy), PR_RECTX, 5, rect); - } - } -} - -static void draw_tex_crop(Tex *tex) +/* unused now */ +void draw_tex_crop(Tex *tex) { rcti rct; int ret= 0; @@ -309,10 +154,10 @@ static void draw_tex_crop(Tex *tex) if(tex==0) return; if(tex->type==TEX_IMAGE) { - if(tex->cropxmin==0.0) ret++; - if(tex->cropymin==0.0) ret++; - if(tex->cropxmax==1.0) ret++; - if(tex->cropymax==1.0) ret++; + if(tex->cropxmin==0.0f) ret++; + if(tex->cropymin==0.0f) ret++; + if(tex->cropxmax==1.0f) ret++; + if(tex->cropymax==1.0f) ret++; if(ret==4) return; rct.xmin= PR_XMIN+2+tex->cropxmin*(PR_XMAX-PR_XMIN-4); @@ -333,1011 +178,596 @@ static void draw_tex_crop(Tex *tex) } -void BIF_all_preview_changed(void) +/* temporal abuse; if id_code is -1 it only does texture.... solve! */ +void BIF_preview_changed(short id_code) { ScrArea *sa; - SpaceButs *sbuts; - sa= G.curscreen->areabase.first; - while(sa) { + for(sa= G.curscreen->areabase.first; sa; sa= sa->next) { if(sa->spacetype==SPACE_BUTS) { - sbuts= sa->spacedata.first; - sbuts->cury= 0; - addafterqueue(sa->win, RENDERPREVIEW, 1); - } - sa= sa->next; - } -} - -/* signal all previews in current screen of current type */ -void BIF_preview_changed(SpaceButs *sbuts) -{ - - /* can be called when no buttonswindow visible */ - if(sbuts) { - ScrArea *sa; - short mainb= sbuts->mainb; - short tab= sbuts->tab[mainb]; - - sa= G.curscreen->areabase.first; - while(sa) { - if(sa->spacetype==SPACE_BUTS) { - sbuts= sa->spacedata.first; - if(sbuts->mainb==mainb && sbuts->tab[mainb]==tab) { - sbuts->cury= 0; - addafterqueue(sbuts->area->win, RENDERPREVIEW, 1); + SpaceButs *sbuts= sa->spacedata.first; + if(sbuts->mainb==CONTEXT_SHADING) { + int tab= sbuts->tab[CONTEXT_SHADING]; + if(tab==TAB_SHADING_MAT && (id_code==ID_MA || id_code==ID_TE)) { + if (sbuts->ri) sbuts->ri->cury= 0; + addafterqueue(sa->win, RENDERPREVIEW, 1); + } + else if(tab==TAB_SHADING_TEX && (id_code==ID_TE || id_code==-1)) { + if (sbuts->ri) sbuts->ri->cury= 0; + addafterqueue(sa->win, RENDERPREVIEW, 1); + } + else if(tab==TAB_SHADING_LAMP && (id_code==ID_LA || id_code==ID_TE)) { + if (sbuts->ri) sbuts->ri->cury= 0; + addafterqueue(sa->win, RENDERPREVIEW, 1); + } + else if(tab==TAB_SHADING_WORLD && (id_code==ID_WO || id_code==ID_TE)) { + if (sbuts->ri) sbuts->ri->cury= 0; + addafterqueue(sa->win, RENDERPREVIEW, 1); } } - sa= sa->next; + } + else if(sa->spacetype==SPACE_NODE) { + SpaceNode *snode= sa->spacedata.first; + if(snode->treetype==NTREE_SHADER && (id_code==ID_MA || id_code==ID_TE)) { + snode_tag_dirty(snode); + } + } + else if(sa->spacetype==SPACE_VIEW3D) { + View3D *vd= sa->spacedata.first; + /* if is has a renderinfo, we consider that reason for signalling */ + if (vd->ri) { + vd->ri->cury= 0; + addafterqueue(sa->win, RENDERPREVIEW, 1); + } } } } -/* is panel callback, supposed to be called with correct panel offset matrix */ -void BIF_previewdraw(void) +/* *************************** Preview for buttons *********************** */ + +static Main *pr_main= NULL; + +void BIF_preview_init_dbase(void) { - SpaceButs *sbuts= curarea->spacedata.first; + BlendReadError bre; + BlendFileData *bfd; + extern int datatoc_preview_blend_size; + extern char datatoc_preview_blend[]; - if (sbuts->rect==0) BIF_preview_changed(sbuts); - else { - int y; - - set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); + G.fileflags |= G_FILE_NO_UI; + bfd= BLO_read_from_memory(datatoc_preview_blend, datatoc_preview_blend_size, &bre); + if (bfd) { + pr_main= bfd->main; - for (y=0; yrect, y); - } - - end_previewrect(); - - if (sbuts->mainb==CONTEXT_SHADING && sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_TEX) { - draw_tex_crop(sbuts->lockpoin); - } + MEM_freeN(bfd); } - if(sbuts->cury==0) BIF_preview_changed(sbuts); - + G.fileflags &= ~G_FILE_NO_UI; } -static void sky_preview_pixel(float lens, int x, int y, char *rect) +void BIF_preview_free_dbase(void) { - float view[3]; - - if(R.wrld.skytype & WO_SKYPAPER) { - view[0]= (2*x)/(float)PR_RECTX; - view[1]= (2*y)/(float)PR_RECTY; - view[2]= 0.0; - } - else { - view[0]= x; - view[1]= y; - view[2]= -lens*PR_RECTX/32.0; - Normalise(view); - } - RE_sky_char(view, rect); + if(pr_main) + free_main(pr_main); } -static void lamp_preview_pixel(ShadeInput *shi, LampRen *la, int x, int y, char *rect) +static Scene *preview_prepare_scene(RenderInfo *ri, ID *id, int pr_method) { - float inpr, i, t, dist, distkw, vec[3], lacol[3]; - int col; + Scene *sce; + Base *base; - shi->co[0]= (float)x/(PR_RECTX/4); - shi->co[1]= (float)y/(PR_RECTX/4); - shi->co[2]= 0; + if(pr_main==NULL) return NULL; - vec[0]= 0.02*x; - vec[1]= 0.02*y; - vec[2]= 0.005*PR_RECTX; - VECCOPY(shi->view, vec); - dist= Normalise(shi->view); - - lacol[0]= la->r; - lacol[1]= la->g; - lacol[2]= la->b; - - if(la->mode & LA_TEXTURE) do_lamp_tex(la, vec, shi, lacol); - - if(la->type==LA_SUN || la->type==LA_HEMI) { - dist= 1.0; - } - else { - - if(la->mode & LA_QUAD) { + sce= pr_main->scene.first; + if(sce) { + if(GS(id->name)==ID_MA) { + Material *mat= (Material *)id; - t= 1.0; - if(la->ld1>0.0) - t= la->dist/(la->dist+la->ld1*dist); - if(la->ld2>0.0) { - distkw= la->dist*la->dist; - t= t*distkw/(t*distkw+la->ld2*dist*dist); + if(pr_method==PR_ICON_RENDER) { + sce->lay= 1<dist/(la->dist+dist)); - } - } - - /* yafray: preview shade as spot, sufficient */ - if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) { - - - if(la->mode & LA_SQUARE) { - /* slightly smaller... */ - inpr= 1.7*cos(MAX2(fabs(shi->view[0]/shi->view[2]) , fabs(shi->view[1]/shi->view[2]) )); - } - else { - inpr= shi->view[2]; - } - - t= la->spotsi; - if(inprspotbl && la->spotbl!=0.0) { - /* soft area */ - i= t/la->spotbl; - t= i*i; - i= t*i; - inpr*=(3.0*t-2.0*i); + else { + sce->lay= 1<pr_type; + if(mat->nodetree) + ntreeInitPreview(mat->nodetree, ri->pr_rectx, ri->pr_recty); + } + + 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); + } } } - dist*=inpr; + return sce; } - else if ELEM(la->type, LA_LOCAL, LA_AREA) dist*= shi->view[2]; - col= 255.0*dist*lacol[0]; - if(col<=0) rect[0]= 0; else if(col>=255) rect[0]= 255; else rect[0]= col; - - col= 255.0*dist*lacol[1]; - if(col<=0) rect[1]= 0; else if(col>=255) rect[1]= 255; else rect[1]= col; - - col= 255.0*dist*lacol[2]; - if(col<=0) rect[2]= 0; else if(col>=255) rect[2]= 255; else rect[2]= col; + return NULL; } -static void init_previewhalo(HaloRen *har, Material *mat) +/* prevent pointer from being 'hanging' in preview dbase */ +static void preview_exit_scene(RenderInfo *ri, ID *id) { + Scene *sce; + Base *base; - har->type= 0; - if(mat->mode & MA_HALO_XALPHA) har->type |= HA_XALPHA; - har->mat= mat; - har->hard= mat->har; - har->rad= PR_RECTX/2.0; - har->radsq= PR_RECTX*PR_RECTX/4.0; - har->alfa= mat->alpha; - har->add= 255.0*mat->add; - har->r= mat->r; - har->g= mat->g; - har->b= mat->b; - har->xs= PR_RECTX/2.0; - har->ys= PR_RECTX/2.0; - har->zs= har->zd= 0; - har->seed= (mat->seed1 % 256); + if(pr_main==NULL) return; - if( (mat->mode & MA_HALOTEX) && mat->mtex[0] ) har->tex= 1; else har->tex=0; - - if(mat->mode & MA_STAR) har->starpoints= mat->starc; else har->starpoints= 0; - if(mat->mode & MA_HALO_LINES) har->linec= mat->linec; else har->linec= 0; - if(mat->mode & MA_HALO_RINGS) har->ringc= mat->ringc; else har->ringc= 0; - if(mat->mode & MA_HALO_FLARE) har->flarec= mat->flarec; else har->flarec= 0; - - if(har->flarec) { - har->xs-= PR_RECTX/3; - har->ys+= PR_RECTX/3; - - har->rad*= 0.3; - har->radsq= har->rad*har->rad; - - har->pixels= har->rad*har->rad*har->rad; - } -} - -static void halo_preview_pixel(HaloRen *har, int startx, int endx, int y, char *rect) -{ - float dist, xn, yn, xsq, ysq, colf[4]; - int x; - char front[4]; - - if(har->flarec) yn= y-PR_RECTX/3; - else yn= y; - ysq= yn*yn; - - for(x=startx; xflarec) xn= x+PR_RECTX/3; - else xn= x; - - xsq= xn*xn; - dist= xsq+ysq; - - if(distradsq) { - RE_shadehalo(har, front, colf, 0, dist, xn, yn, har->flarec); - RE_addalphaAddfac(rect, front, har->add); + sce= pr_main->scene.first; + if(sce) { + if(GS(id->name)==ID_MA) { + 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, NULL, base->object->actcol); + } + } } - rect+= 4; } } -static void previewflare(SpaceButs *sbuts, HaloRen *har, unsigned int *rect) +static void previewrender_progress(RenderResult *rr, rcti *unused) +{ + RenderLayer *rl; + RenderInfo *ri= G.buts->ri; + float ofsx, ofsy; + + rl= rr->layers.first; + + ofsx= ri->disprect.xmin + rr->tilerect.xmin; + ofsy= ri->disprect.ymin + rr->tilerect.ymin; + + glDrawBuffer(GL_FRONT); + glaDrawPixelsSafe(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_FLOAT, rl->rectf); + glFlush(); + glDrawBuffer(GL_BACK); +} + + +/* called by interface_icons.c, or by BIF_previewrender_buts or by nodes... */ +void BIF_previewrender(struct ID *id, struct RenderInfo *ri, struct ScrArea *area, int pr_method) +{ + Render *re; + RenderStats *rstats; + Scene *sce; + char name [32]; + + if(ri->cury>=ri->pr_recty) return; + + if(ri->rect==NULL) { + ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "butsrect"); + } + + /* 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(ri, id, pr_method); + if(sce==NULL) return; + + /* just create new render always now */ + sprintf(name, "ButsPreview %d", area?area->win: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; + } + else if(pr_method==PR_DO_RENDER) { + RE_test_break_cb(re, qtest); + sce->r.scemode |= R_NODE_PREVIEW; + } + else { /* PR_ICON_RENDER */ + sce->r.scemode &= ~R_NODE_PREVIEW; + } + + /* entire cycle for render engine */ + RE_InitState(re, &sce->r, ri->pr_rectx, ri->pr_recty, NULL); + RE_SetCamera(re, sce->camera); + RE_Database_FromScene(re, sce, 1); + RE_TileProcessor(re); // actual render engine + RE_Database_Free(re); + + /* handle results */ + if(pr_method==PR_ICON_RENDER) { + RE_ResultGet32(re, ri->rect); + } + else { + rstats= RE_GetStats(re); + if(rstats->totpart==rstats->partsdone && rstats->partsdone) { + ri->cury= ri->pr_recty; + RE_ResultGet32(re, ri->rect); + if(GS(id->name)==ID_MA && ((Material *)id)->use_nodes) + allqueue(REDRAWNODE, 0); + } + else { + if(pr_method==PR_DRAW_RENDER && qtest()) { + addafterqueue(area->win, RENDERPREVIEW, 1); + } + } + } + preview_exit_scene(ri, id); + RE_FreeRender(re); +} + + +/* afterqueue call */ +void BIF_previewrender_buts(SpaceButs *sbuts) { uiBlock *block; - float ycor; - unsigned int *rectot; - int afmx, afmy, rectx, recty, y; - - block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Preview"); - if(block==NULL) return; - - /* temps */ - ycor= R.ycor; - rectx= R.rectx; - recty= R.recty; - afmx= R.afmx; - afmy= R.afmy; - rectot= R.rectot; - - R.r.postmul= R.r.postgamma= R.r.postsat= 1.0; - R.r.posthue= R.r.postadd= 0.0; - R.ycor= 1.0; - R.rectx= PR_RECTX; - R.recty= PR_RECTY; - R.afmx= PR_RECTX/2; - R.afmy= PR_RECTY/2; - R.rectot= rect; - - waitcursor(1); - RE_renderflare(har); - waitcursor(0); - // not sure why, either waitcursor or renderflare screws up (disabled then) - //areawinset(curarea->win); - - /* draw can just be this way, all settings are OK */ - for (y=0; yrect, y); - } - - /* temps */ - R.ycor= ycor; - R.rectx= rectx; - R.recty= recty; - R.afmx= afmx; - R.afmy= afmy; - R.rectot= rectot; -} - -static void texture_preview_pixel(Tex *tex, int x, int y, char *rect) -{ - float i, v1, xsq, ysq, texvec[3]; - float tin=1.0, tr, tg, tb, ta; - int rgbnor, tracol, skip=0; - - if(tex->type==TEX_IMAGE) { - v1= 1.0/PR_RECTX; - - texvec[0]= 0.5+v1*x; - texvec[1]= 0.5+v1*y; - - /* no coordinate mapping, exception: repeat */ - if(tex->extend==TEX_REPEAT) { - if(tex->xrepeat>1) { - texvec[0] *= tex->xrepeat; - if(texvec[0]>1.0) texvec[0] -= (int)(texvec[0]); - } - if(tex->yrepeat>1) { - texvec[1] *= tex->yrepeat; - if(texvec[1]>1.0) texvec[1] -= (int)(texvec[1]); - } - } - else if(tex->extend==TEX_CHECKER) { - texvec[0]= 0.5+1.6*v1*x; - texvec[1]= 0.5+1.6*v1*y; - } - } - else if(tex->type==TEX_ENVMAP) { - if(tex->env) { - ysq= y*y; - xsq= x*x; - if(xsq+ysq < (PR_RECTX/2)*(PR_RECTY/2)) { - texvec[2]= sqrt( (float)((PR_RECTX/2)*(PR_RECTY/2)-xsq-ysq) ); - texvec[0]= -x; - texvec[1]= -y; - Normalise(texvec); - - i= 2.0*(texvec[2]); - texvec[0]= (i*texvec[0]); - texvec[1]= (i*texvec[1]); - texvec[2]= (-1.0+i*texvec[2]); - - } - else { - skip= 1; - tr= tg= tb= ta= 0.0; - } - } - else { - skip= 1; - tr= tg= tb= ta= 0.0; - } - } - else { - v1= 2.0/PR_RECTX; - - texvec[0]= v1*x; - texvec[1]= v1*y; - texvec[2]= 0.0; - } - - if(skip==0) rgbnor= multitex_ext(tex, texvec, &tin, &tr, &tg, &tb, &ta); - else rgbnor= 1; - - if(rgbnor & 1) { - - v1= 255.0*tr; - rect[0]= CLAMPIS(v1, 0, 255); - v1= 255.0*tg; - rect[1]= CLAMPIS(v1, 0, 255); - v1= 255.0*tb; - rect[2]= CLAMPIS(v1, 0, 255); - - if(ta!=1.0) { - tracol= 64+100*(abs(x)>abs(y)); - tracol= (1.0-ta)*tracol; - - rect[0]= tracol+ (rect[0]*ta) ; - rect[1]= tracol+ (rect[1]*ta) ; - rect[2]= tracol+ (rect[2]*ta) ; - - } - } - else { - rect[0]= 255.0*tin; - rect[1]= 255.0*tin; - rect[2]= 255.0*tin; - } -} - -static float pr1_lamp[3]= {2.3, -2.4, -4.6}; -static float pr2_lamp[3]= {-8.8, -5.6, -1.5}; -static float pr1_col[3]= {0.8, 0.8, 0.8}; -static float pr2_col[3]= {0.5, 0.6, 0.7}; - -static void refraction_prv(int *x, int *y, float *n, float index) -{ - float dot, fac, view[3], len; - - index= 1.0/index; - - view[0]= index*(float)*x; - view[1]= ((float)*y)/index; - view[2]= 20.0; - len= Normalise(view); - - dot= view[0]*n[0] + view[1]*n[1] + view[2]*n[2]; - - if(dot>0.0) { - fac= 1.0 - (1.0 - dot*dot)*index*index; - if(fac<= 0.0) return; - fac= -dot*index + sqrt(fac); - } - else { - index = 1.0/index; - fac= 1.0 - (1.0 - dot*dot)*index*index; - if(fac<= 0.0) return; - fac= -dot*index - sqrt(fac); - } - - *x= (int)(len*(index*view[0] + fac*n[0])); - *y= (int)(len*(index*view[1] + fac*n[1])); -} - - -static void shade_preview_pixel(ShadeInput *shi, float *vec, int x, int y,char *rect, int smooth) -{ - extern float fresnel_fac(float *view, float *vn, float ior, float fac); - Material *mat; - float v1,inp, is, inprspec=0, isr=0.0, isb=0.0, isg=0.0; - float diff[3]={0.0, 0.0, 0.0}; - float lv[3], *la, alpha; - float eul[3], tmat[3][3], imat[3][3]; - int temp, a; - char tracol; - - mat= shi->mat; - - // copy all relevant material vars, note, keep this synced with render_types.h - memcpy(&shi->r, &mat->r, 23*sizeof(float)); - // set special cases: - shi->har= mat->har; - if((mat->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0; - - v1= 1.0/PR_RECTX; - shi->view[0]= v1*x; - shi->view[1]= v1*y; - shi->view[2]= 1.0; - Normalise(shi->view); - - shi->xs= (float)x; - shi->ys= (float)y; - - shi->refcol[0]= shi->refcol[1]= shi->refcol[2]= shi->refcol[3]= 0.0; - - /* texture handling */ - if(mat->texco) { - - VECCOPY(shi->lo, vec); - - if(mat->pr_type==MA_CUBE) { - - eul[0]= (297)*M_PI/180.0; - eul[1]= 0.0; - eul[2]= (45)*M_PI/180.0; - EulToMat3(eul, tmat); - - MTC_Mat3MulVecfl(tmat, shi->lo); - MTC_Mat3MulVecfl(tmat, shi->vn); - /* hack for cubemap, why!!! */ - SWAP(float, shi->vn[0], shi->vn[1]); - } - /* textures otherwise upside down */ - if(mat->pr_type==MA_CUBE || mat->pr_type==MA_SPHERE) - shi->lo[2]= -shi->lo[2]; - - if(mat->texco & TEXCO_GLOB) { - VECCOPY(shi->gl, shi->lo); - } - if(mat->texco & TEXCO_WINDOW) { - VECCOPY(shi->winco, shi->lo); - } - if(mat->texco & TEXCO_STICKY) { - VECCOPY(shi->sticky, shi->lo); - } - if(mat->texco & TEXCO_UV) { - VECCOPY(shi->uv, shi->lo); - } - if(mat->texco & TEXCO_STRAND) { - shi->strand= shi->lo[0]; - } - if(mat->texco & TEXCO_OBJECT) { - VECCOPY(shi->co, shi->lo); - } - if(mat->texco & (TEXCO_NORM)) { - shi->orn[0]= shi->vn[0]; - shi->orn[1]= shi->vn[1]; - shi->orn[2]= shi->vn[2]; - } - if(mat->texco & TEXCO_REFL) { - - inp= -2.0*(shi->vn[0]*shi->view[0]+shi->vn[1]*shi->view[1]+shi->vn[2]*shi->view[2]); - shi->ref[0]= (shi->view[0]+inp*shi->vn[0]); - shi->ref[1]= (shi->view[1]+inp*shi->vn[1]); - shi->ref[2]= (shi->view[2]+inp*shi->vn[2]); - } - - /* Clear displase vec for preview */ - shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; - - /* normals flipped in render for smooth... */ - if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0); - - do_material_tex(shi); - - /* normals flipped in render... */ - if( (mat->mapto & MAP_NORM)) VecMulf(shi->vn, -1.0); - - if(mat->texco & TEXCO_REFL) { - /* normals in render are pointing different... rhm */ - if(smooth) shi->ref[1]= -shi->ref[1]; - } - - if(mat->pr_type==MA_CUBE) { - /* rotate normal back for normals texture */ - SWAP(float, shi->vn[0], shi->vn[1]); - MTC_Mat3Inv(imat, tmat); - MTC_Mat3MulVecfl(imat, shi->vn); - } - - } - /* set it here, because ray_mirror will affect it */ - alpha= shi->alpha; - - if(mat->mapto & MAP_DISPLACE) { /* Quick hack of fake displacement preview */ - shi->vn[0]-=2.0*shi->displace[2]; - shi->vn[1]-=2.0*shi->displace[0]; - shi->vn[2]+=2.0*shi->displace[1]; - Normalise(shi->vn); - } - - if(mat->mode & (MA_ZTRA|MA_RAYTRANSP)) - if(mat->fresnel_tra!=0.0) - alpha*= fresnel_fac(shi->view, shi->vn, mat->fresnel_tra_i, mat->fresnel_tra); - - if(mat->mode & MA_SHLESS) { - temp= 255.0*(shi->r); - if(temp>255) rect[0]= 255; else if(temp<0) rect[0]= 0; else rect[0]= temp; - - temp= 255.0*(shi->g); - if(temp>255) rect[1]= 255; else if(temp<0) rect[1]= 0; else rect[1]= temp; - - temp= 255.0*(shi->b); - if(temp>255) rect[2]= 255; else if(temp<0) rect[2]= 0; else rect[2]= temp; - } - else { - - for(a=0; a<2; a++) { - - if((mat->pr_lamp & (1<vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; - if(is<0.0) is= 0.0; - - if(shi->spec>0.0) { - - if(is>0.0) { - /* specular shaders */ - float specfac; - - if(mat->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(shi->vn, lv, shi->view, shi->har, 0); - else if(mat->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(shi->vn, lv, shi->view, shi->har, 0); - else if(mat->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(shi->vn, lv, shi->view, mat->refrac, (float)shi->har, 0); - else if(mat->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec(shi->vn, lv, shi->view, mat->rms, 0); - else - specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3], 0); - - inprspec= specfac*shi->spec; - - if(mat->mode & MA_RAMP_SPEC) { - float spec[3]; - do_specular_ramp(shi, specfac, inprspec, spec); - isr+= inprspec*spec[0]; - isg+= inprspec*spec[1]; - isb+= inprspec*spec[2]; - } - else { - isr+= inprspec*shi->specr; - isg+= inprspec*shi->specg; - isb+= inprspec*shi->specb; - } - } - } - /* diffuse shaders */ - if(mat->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(shi->vn, lv, shi->view, mat->roughness); - else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(shi->vn, lv, shi->view, mat->param[0], mat->param[1]); - else if(mat->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, shi->vn, shi->view, mat->darkness); - // else Lambert - - inp= (shi->refl*is + shi->emit); - - if(a==0) la= pr1_col; - else la= pr2_col; - - add_to_diffuse(diff, shi, is, inp*la[0], inp*la[1], inp*la[2]); - //ir+= inp*la[0]; - //ig+= inp*la[1]; - //ib+= inp*la[2]; - } - - /* drawing checkerboard and sky */ - if(mat->mode & MA_RAYMIRROR) { - float col, div, y, z; - int fac; - - /* rotate a bit in x */ - y= shi->ref[1]; z= shi->ref[2]; - shi->ref[1]= 0.98*y - 0.17*z; - shi->ref[2]= 0.17*y + 0.98*z; - - /* scale */ - div= (0.85*shi->ref[1]); - - shi->refcol[0]= shi->ray_mirror*fresnel_fac(shi->view, shi->vn, mat->fresnel_mir_i, mat->fresnel_mir); - /* not real 'alpha', but mirror overriding transparency */ - if(mat->mode & MA_RAYTRANSP) { - float fac= sqrt(shi->refcol[0]); - alpha= alpha*(1.0-fac) + fac; - } - else alpha= alpha*(1.0-shi->refcol[0]) + shi->refcol[0]; - - if(div<0.0) { - /* minus 0.5 prevents too many small tiles in distance */ - fac= (int)(shi->ref[0]/(div-0.1) ) + (int)(shi->ref[2]/(div-0.1) ); - if(fac & 1) col= 0.8; - else col= 0.3; - - shi->refcol[1]= shi->refcol[0]*col; - shi->refcol[2]= shi->refcol[1]; - shi->refcol[3]= shi->refcol[2]; - } - else { - shi->refcol[1]= 0.0; - shi->refcol[2]= shi->refcol[0]*0.3*div; - shi->refcol[3]= shi->refcol[0]*0.8*div; - } - } - - if(mat->mode & MA_RAMP_COL) ramp_diffuse_result(diff, shi); - if(mat->mode & MA_RAMP_SPEC) ramp_spec_result(&isr, &isg, &isb, shi); - - if(shi->refcol[0]==0.0) { - a= 255.0*(diff[0] +shi->ambr +isr); - if(a>255) a=255; else if(a<0) a= 0; - rect[0]= a; - a= 255.0*(diff[1] +shi->ambg +isg); - if(a>255) a=255; else if(a<0) a= 0; - rect[1]= a; - a= 255*(diff[2] +shi->ambb +isb); - if(a>255) a=255; else if(a<0) a= 0; - rect[2]= a; - } - else { - a= 255.0*( shi->mirr*shi->refcol[1] + (1.0 - shi->mirr*shi->refcol[0])*(diff[0] +shi->ambr) +isr); - if(a>255) a=255; else if(a<0) a= 0; - rect[0]= a; - a= 255.0*( shi->mirg*shi->refcol[2] + (1.0 - shi->mirg*shi->refcol[0])*(diff[1] +shi->ambg) +isg); - if(a>255) a=255; else if(a<0) a= 0; - rect[1]= a; - a= 255.0*( shi->mirb*shi->refcol[3] + (1.0 - shi->mirb*shi->refcol[0])*(diff[2] +shi->ambb) +isb); - if(a>255) a=255; else if(a<0) a= 0; - rect[2]= a; - } - } - - /* ztra shade */ - if(shi->spectra!=0.0) { - inp = MAX3(isr, isg, isb); - inp *= shi->spectra; - if(inp>1.0) inp= 1.0; - alpha= (1.0-inp)*alpha+inp; - } - - if(alpha!=1.0) { - if(mat->mode & MA_RAYTRANSP) { - refraction_prv(&x, &y, shi->vn, shi->ang); - } - - tracol= previewback(mat->pr_back, x, y) & 255; - - tracol= (1.0-alpha)*tracol; - - if((mat->mode & MA_RAYTRANSP) && mat->filter!=0.0) { - float fr= 1.0+ mat->filter*(shi->r-1.0); - rect[0]= fr*tracol+ (rect[0]*alpha) ; - fr= 1.0+ mat->filter*(shi->g-1.0); - rect[1]= fr*tracol+ (rect[1]*alpha) ; - fr= 1.0+ mat->filter*(shi->b-1.0); - rect[2]= fr*tracol+ (rect[2]*alpha) ; - } - else { - rect[0]= tracol+ (rect[0]*alpha) ; - rect[1]= tracol+ (rect[1]*alpha) ; - rect[2]= tracol+ (rect[2]*alpha) ; - } - } -} - - -void BIF_previewrender(SpaceButs *sbuts) -{ - static double lasttime= 0; - ID *id, *idfrom; - Material *mat= NULL; - Tex *tex= NULL; - Lamp *la= NULL; - World *wrld= NULL; - LampRen *lar= NULL; - Image *ima; - HaloRen har; + struct ID* id = 0; + struct ID* idfrom = 0; + struct ID* idshow = 0; Object *ob; - uiBlock *block; - ShadeInput shi; - float lens = 0.0, vec[3]; - int x, y, starty, startx, endy, endx, radsq, xsq, ysq, last = 0; - unsigned int *rect; - - if(sbuts->cury>=PR_RECTY) return; + + if (!sbuts->ri) return; /* we safely assume curarea has panel "preview" */ /* quick hack for now, later on preview should become uiBlock itself */ block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Preview"); if(block==NULL) return; - + ob= ((G.scene->basact)? (G.scene->basact)->object: 0); /* we cant trust this global lockpoin.. for example with headerless window */ buttons_active_id(&id, &idfrom); G.buts->lockpoin= id; - + if(sbuts->mainb==CONTEXT_SHADING) { int tab= sbuts->tab[CONTEXT_SHADING]; if(tab==TAB_SHADING_MAT) - mat= sbuts->lockpoin; + idshow = sbuts->lockpoin; else if(tab==TAB_SHADING_TEX) - tex= sbuts->lockpoin; + idshow = sbuts->lockpoin; else if(tab==TAB_SHADING_LAMP) { - if(ob && ob->type==OB_LAMP) la= ob->data; + if(ob && ob->type==OB_LAMP) idshow= ob->data; } else if(tab==TAB_SHADING_WORLD) - wrld= sbuts->lockpoin; + idshow = sbuts->lockpoin; } else if(sbuts->mainb==CONTEXT_OBJECT) { - if(ob && ob->type==OB_LAMP) la= ob->data; + if(ob && ob->type==OB_LAMP) idshow = ob->data; } - /* return: when no active block to render. but we do draw black if possible */ - if(mat==NULL && tex==NULL && la==NULL && wrld==NULL) { - if(sbuts->rect) { - memset(sbuts->rect, 0, sizeof(int)*PR_RECTX*PR_RECTY); - sbuts->cury= PR_RECTY; + if (idshow) { + BKE_icon_changed(BKE_icon_getid(idshow)); + uiPanelPush(block); + set_previewrect(sbuts->ri, sbuts->area->win); // uses UImat + BIF_previewrender(idshow, sbuts->ri, sbuts->area, PR_DRAW_RENDER); + uiPanelPop(block); + end_previewrect(); + } + 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->cury= sbuts->ri->pr_recty; addqueue(curarea->win, REDRAW, 1); } return; } +} + + +/* is panel callback, supposed to be called with correct panel offset matrix */ +void BIF_previewdraw(ScrArea *sa, uiBlock *block) +{ + SpaceButs *sbuts= sa->spacedata.first; + short id_code= 0; - har.flarec= 0; /* below is a test for postrender flare */ + if(sbuts->lockpoin) { + ID *id= sbuts->lockpoin; + id_code= GS(id->name); + } + if (!sbuts->ri) { + sbuts->ri= MEM_callocN(sizeof(RenderInfo), "butsrenderinfo"); + sbuts->ri->cury = 0; + sbuts->ri->rect = NULL; + } + + if (sbuts->ri->rect==NULL) BIF_preview_changed(id_code); + else { + RenderInfo *ri= sbuts->ri; + int oldx= ri->pr_rectx, oldy= ri->pr_recty; + + /* we now do scalable previews! */ + set_previewrect(ri, sa->win); + if(oldx==ri->pr_rectx && oldy==ri->pr_recty) + glaDrawPixelsSafe(ri->disprect.xmin, ri->disprect.ymin, ri->pr_rectx, ri->pr_recty, ri->pr_rectx, GL_RGBA, GL_UNSIGNED_BYTE, ri->rect); + else { + MEM_freeN(ri->rect); + ri->rect= NULL; + sbuts->ri->cury= 0; + } + end_previewrect(); + } + if(sbuts->ri->cury==0) BIF_preview_changed(id_code); + +} + +/* *************************** Preview for 3d window *********************** */ +static void view3d_previewrender_stats(RenderStats *rs) +{ + printf("rendered %.3f\n", rs->lastframetime); +} + +static void view3d_previewrender_progress(RenderResult *rr, rcti *unused) +{ + RenderLayer *rl; + int ofsx, ofsy; + + rl= rr->layers.first; + + /* this case is when we render envmaps... */ + if(rr->rectx>G.vd->ri->pr_rectx || rr->recty>G.vd->ri->pr_recty) + return; + + ofsx= G.vd->ri->disprect.xmin + rr->tilerect.xmin; + ofsy= G.vd->ri->disprect.ymin + rr->tilerect.ymin; + + glDrawBuffer(GL_FRONT); + glaDefine2DArea(&curarea->winrct); + glaDrawPixelsSafe(ofsx, ofsy, rr->rectx, rr->recty, rr->rectx, GL_RGBA, GL_FLOAT, rl->rectf); + glFlush(); + glDrawBuffer(GL_BACK); + +} + +void BIF_view3d_previewrender_signal(ScrArea *sa, short signal) +{ + View3D *v3d= sa->spacedata.first; + + /* this can be called from other window... solve! */ + if(sa->spacetype!=SPACE_VIEW3D) + v3d= G.vd; + + if(v3d && v3d->ri) { + RenderInfo *ri= v3d->ri; + ri->status &= ~signal; + ri->cury= 0; + if(ri->re && (signal & PR_DBASE)) + RE_Database_Free(ri->re); + + addafterqueue(sa->win, RENDERPREVIEW, 1); + } +} + +void BIF_view3d_previewrender_free(ScrArea *sa) +{ + View3D *v3d= sa->spacedata.first; + + if(v3d->ri) { + RenderInfo *ri= v3d->ri; + if(ri->re) { +// printf("free render\n"); + RE_Database_Free(ri->re); + RE_FreeRender(ri->re); + ri->re= NULL; + } + ri->status= 0; + ri->cury= 0; + } +} + +/* returns 1 if OK, do not call while in panel space! */ +static int view3d_previewrender_get_rects(ScrArea *sa, rctf *viewplane, RenderInfo *ri, float *clipsta, float *clipend, int *ortho) +{ + int rectx, recty; + uiBlock *block; + + block= uiFindOpenPanelBlockName(&curarea->uiblocks, "Preview"); + if(block==NULL) return 0; + + /* calculate preview rect size */ + BLI_init_rctf(viewplane, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); + uiPanelPush(block); + ui_graphics_to_window_rct(sa->win, viewplane, &ri->disprect); + uiPanelPop(block); + + /* correction for gla draw */ + BLI_translate_rcti(&ri->disprect, -sa->winrct.xmin, -sa->winrct.ymin); + + *ortho= get_view3d_viewplane(sa->winx, sa->winy, viewplane, clipsta, clipend); + + rectx= ri->disprect.xmax - ri->disprect.xmin; + recty= ri->disprect.ymax - ri->disprect.ymin; + + if(rectx<4 || recty<4) return 0; + + if(ri->rect && (rectx!=ri->pr_rectx || recty!=ri->pr_recty)) { + MEM_freeN(ri->rect); + ri->rect= NULL; + } + ri->pr_rectx= rectx; + ri->pr_recty= recty; + + return 1; +} + +/* called before a panel gets moved/scaled, makes sure we can see through */ +void BIF_view3d_previewrender_clear(ScrArea *sa) +{ + View3D *v3d= sa->spacedata.first; + + if(v3d->ri) { + RenderInfo *ri= v3d->ri; + ri->cury= 0; + if(ri->rect) + MEM_freeN(ri->rect); + ri->rect= NULL; + } +} + +/* afterqueue call */ +void BIF_view3d_previewrender(ScrArea *sa) +{ + View3D *v3d= sa->spacedata.first; + Render *re; + RenderInfo *ri; /* preview struct! */ + RenderStats *rstats; + RenderData rdata; + rctf viewplane; + float clipsta, clipend; + int orth; + + /* first get the render info right */ + if (!v3d->ri) + ri= v3d->ri= MEM_callocN(sizeof(RenderInfo), "butsrenderinfo"); + ri= v3d->ri; + + if(0==view3d_previewrender_get_rects(sa, &viewplane, ri, &clipsta, &clipend, &orth)) + return; + + /* render is finished, so return */ + if(ri->cury>=ri->pr_rectx) return; + + /* or return with a new event */ if(qtest()) { addafterqueue(curarea->win, RENDERPREVIEW, 1); return; } - - MTC_Mat4One(R.viewmat); - MTC_Mat4One(R.viewinv); - shi.osatex= 0; - - if(mat) { - /* rendervars */ - init_render_world(); - init_render_material(mat); + /* ok, are we rendering all over? */ + if(ri->re==NULL) { + char name[32]; - /* clear imats, flip normal... (hack because everything is inverted here) */ - for(x=0; xmtex[x]) { - if(mat->mtex[x]->tex) { - init_render_texture(mat->mtex[x]->tex); - - if(mat->mtex[x]->tex->env && mat->mtex[x]->tex->env->object) - MTC_Mat4One(mat->mtex[x]->tex->env->object->imat); - - mat->mtex[x]->maptoneg ^= MAP_NORM; - } - if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); - if(mat->mtex[x]->object) MTC_Mat4One(mat->mtex[x]->object->imat); + ri->status= 0; + + sprintf(name, "View3dPreview %d", sa->win); + re= ri->re= RE_NewRender(name); + RE_display_draw_cb(re, view3d_previewrender_progress); + RE_stats_draw_cb(re, view3d_previewrender_stats); + RE_test_break_cb(re, qtest); + + /* no osa, blur, seq, for preview render */ + rdata= G.scene->r; + rdata.mode &= ~(R_OSA|R_MBLUR|R_DOSEQ); + rdata.layers.first= rdata.layers.last= NULL; + + RE_InitState(re, &rdata, sa->winx, sa->winy, &ri->disprect); + + if(orth) + RE_SetOrtho(re, &viewplane, clipsta, clipend); + else + RE_SetWindow(re, &viewplane, clipsta, clipend); + + /* until here are no escapes */ + ri->status |= PR_DISPRECT; + } + + re= ri->re; + + PIL_sleep_ms(100); /* wait 0.1 second if theres really no event... */ + if(qtest()==0) { + + /* check status */ + if((ri->status & PR_DISPRECT)==0) { + RE_SetDispRect(ri->re, &ri->disprect); + if(orth) + RE_SetOrtho(ri->re, &viewplane, clipsta, clipend); + else + RE_SetWindow(ri->re, &viewplane, clipsta, clipend); + ri->status |= PR_DISPRECT; + } + if((ri->status & PR_DBASE)==0) { + unsigned int lay= G.scene->lay; + + RE_SetView(re, G.vd->viewmat); + + /* allow localview render for objects with lights in normal layers */ + if(v3d->lay & 0xFF000000) + G.scene->lay |= v3d->lay; + else G.scene->lay= v3d->lay; + + RE_Database_FromScene(re, G.scene, 0); // 0= dont use camera view + G.scene->lay= lay; + + rstats= RE_GetStats(re); + if(rstats->convertdone) + ri->status |= PR_DBASE|PR_PROJECTED|PR_ROTATED; + } + if((ri->status & PR_PROJECTED)==0) { + if(ri->status & PR_DBASE) { + if(orth) + RE_SetOrtho(ri->re, &viewplane, clipsta, clipend); + else + RE_SetWindow(ri->re, &viewplane, clipsta, clipend); + RE_DataBase_ApplyWindow(re); + ri->status |= PR_PROJECTED; } } - shi.vlr= 0; - - shi.mat= mat; - - if(mat->mode & MA_HALO) init_previewhalo(&har, mat); - } - else if(tex) { - - ima= tex->ima; - if(ima) last= ima->lastframe; - init_render_texture(tex); - free_unused_animimages(); - if(tex->ima) { - if(tex->ima!=ima) allqueue(REDRAWBUTSSHADING, 0); - else if(last!=ima->lastframe) allqueue(REDRAWBUTSSHADING, 0); + + /* OK, can we enter render code? */ + if(ri->status==(PR_DISPRECT|PR_DBASE|PR_PROJECTED|PR_ROTATED)) { + RE_TileProcessor(ri->re); + + if(ri->rect==NULL) + ri->rect= MEM_callocN(sizeof(int)*ri->pr_rectx*ri->pr_recty, "preview view3d rect"); + + RE_ResultGet32(ri->re, ri->rect); } - if(tex->env && tex->env->object) - MTC_Mat4Invert(tex->env->object->imat, tex->env->object->obmat); - } - else if(la) { - - init_render_world(); - init_render_textures(); /* do not do it twice!! (brightness) */ - R.totlamp= 0; - RE_add_render_lamp(ob, 0); /* 0=no shadbuf or tables */ - lar= R.la[0]; - /* exceptions: */ - lar->spottexfac= 1.0; - lar->spotsi= cos( M_PI/3.0 ); - lar->spotbl= (1.0-lar->spotsi)*la->spotblend; - - MTC_Mat3One(lar->imat); - } - else if(wrld) { - - lens= 35.0; - if(G.scene->camera) { - lens= ( (Camera *)G.scene->camera->data)->lens; - - /* needed for init_render_world */ - MTC_Mat4CpyMat4(R.viewinv, G.scene->camera->obmat); - MTC_Mat4Ortho(R.viewinv); - MTC_Mat4Invert(R.viewmat, R.viewinv); - } - init_render_world(); - init_render_textures(); /* dont do it twice!! (brightness) */ - } - - uiPanelPush(block); // sets UImat - - set_previewrect(sbuts->area->win, PR_XMIN, PR_YMIN, PR_XMAX, PR_YMAX); // uses UImat - - if(sbuts->rect==NULL) { - sbuts->rect= MEM_callocN(sizeof(int)*PR_RECTX*PR_RECTY, "butsrect"); - - /* built in emboss */ - rect= sbuts->rect; - for(y=0; yrect + PR_RECTX-1; - for(y=0; ycury; - - /* offset +1 for emboss */ - startx= -PR_RECTX/2 +1; - endx= startx+PR_RECTX -2; - - radsq= (PR_RECTX/2)*(PR_RECTY/2); - - if(mat) { - if(mat->pr_type==MA_SPHERE) { - pr1_lamp[0]= 2.3; pr1_lamp[1]= -2.4; pr1_lamp[2]= -4.6; - pr2_lamp[0]= -8.8; pr2_lamp[1]= -5.6; pr2_lamp[2]= -1.5; + rstats= RE_GetStats(ri->re); + if(rstats->totpart==rstats->partsdone && rstats->partsdone) { + ri->cury= 12000; /* arbitrary... */ + addqueue(sa->win, REDRAW, 1); } else { - pr1_lamp[0]= 1.9; pr1_lamp[1]= 3.1; pr1_lamp[2]= -8.5; - pr2_lamp[0]= 1.2; pr2_lamp[1]= -18; pr2_lamp[2]= 3.2; + addafterqueue(curarea->win, RENDERPREVIEW, 1); + ri->cury= 0; } } - - /* here it starts! */ - glDrawBuffer(GL_FRONT); - - for(y=starty; yrect + 1 + PR_RECTX*sbuts->cury; - - if(y== -PR_RECTY/2 || y==endy-1); /* emboss */ - else if(mat) { - - if(mat->mode & MA_HALO) { - for(x=startx; xpr_back, x, y); - } - - if(har.flarec) { - if(y==endy-2) previewflare(sbuts, &har, sbuts->rect); - } - else { - halo_preview_pixel(&har, startx, endx, y, (char *) (rect-PR_RECTX)); - } - } - else { - ysq= y*y; - for(x=startx; xpr_type==MA_SPHERE) { - - if(xsq+ysq <= radsq) { - shi.vn[0]= x; - shi.vn[1]= y; - shi.vn[2]= sqrt( (float)(radsq-xsq-ysq) ); - Normalise(shi.vn); - - vec[0]= shi.vn[0]; - vec[1]= shi.vn[2]; - vec[2]= -shi.vn[1]; - - shade_preview_pixel(&shi, vec, x, y, (char *)rect, 1); - } - else { - rect[0]= previewback(mat->pr_back, x, y); - } - } - else if(mat->pr_type==MA_CUBE) { - if( ray_previewrender(x, y, vec, shi.vn) ) { - - shade_preview_pixel(&shi, vec, x, y, (char *)rect, 0); - } - else { - rect[0]= previewback(mat->pr_back, x, y); - } - } - else { - vec[0]= x*(2.0/PR_RECTX); - vec[1]= y*(2.0/PR_RECTX); - vec[2]= 0.0; - - shi.vn[0]= shi.vn[1]= 0.0; - shi.vn[2]= 1.0; - - shade_preview_pixel(&shi, vec, x, y, (char *)rect, 0); - } - } - } - } - else if(tex) { - for(x=startx; xwin, RENDERPREVIEW, 1); - break; - } - } - - display_pr_scanline(sbuts->rect, sbuts->cury); - - /* flush opengl for cards with frontbuffer slowness */ - if(sbuts->cury==PR_RECTY-1 || (PIL_check_seconds_timer() - lasttime > 0.05)) { - lasttime= PIL_check_seconds_timer(); - glFlush(); - } - - sbuts->cury++; - } - - end_previewrect(); - - if(sbuts->cury>=PR_RECTY && tex) - if (sbuts->tab[CONTEXT_SHADING]==TAB_SHADING_TEX) - draw_tex_crop(sbuts->lockpoin); - - glDrawBuffer(GL_BACK); - /* draw again for clean swapbufers */ - BIF_previewdraw(); - - uiPanelPop(block); - - if(mat) { - end_render_material(mat); - for(x=0; xmtex[x] && mat->mtex[x]->tex) { - end_render_texture(mat->mtex[x]->tex); - mat->mtex[x]->maptoneg ^= MAP_NORM; - } - } - } - else if(tex) { - end_render_texture(tex); - } - else if(la) { - if(R.totlamp) { - MEM_freeN(R.la[0]); - } - R.totlamp= 0; - end_render_textures(); - } - else if(wrld) { - end_render_textures(); + else { + addafterqueue(curarea->win, RENDERPREVIEW, 1); + ri->cury= 0; + } +} + +/* in panel space! */ +static void view3d_previewdraw_rect(ScrArea *sa, uiBlock *block, RenderInfo *ri) +{ + rctf dispf; + + if(ri->rect==NULL) + return; + + BLI_init_rctf(&dispf, 15.0f, (block->maxx - block->minx)-15.0f, 15.0f, (block->maxy - block->miny)-15.0f); + ui_graphics_to_window_rct(sa->win, &dispf, &ri->disprect); + + /* correction for gla draw */ + BLI_translate_rcti(&ri->disprect, -curarea->winrct.xmin, -curarea->winrct.ymin); + + /* when panel scale changed, free rect */ + if(ri->disprect.xmax-ri->disprect.xmin != ri->pr_rectx || + ri->disprect.ymax-ri->disprect.ymin != ri->pr_recty) { + MEM_freeN(ri->rect); + ri->rect= NULL; + } + else { + glaDefine2DArea(&sa->winrct); + glaDrawPixelsSafe(ri->disprect.xmin, ri->disprect.ymin, ri->pr_rectx, ri->pr_recty, ri->pr_rectx, GL_RGBA, GL_UNSIGNED_BYTE, ri->rect); + } +} + +/* is panel callback, supposed to be called with correct panel offset matrix */ +void BIF_view3d_previewdraw(struct ScrArea *sa, struct uiBlock *block) +{ + View3D *v3d= sa->spacedata.first; + + if (v3d->ri==NULL || v3d->ri->rect==NULL) + addafterqueue(sa->win, RENDERPREVIEW, 1); + else { + view3d_previewdraw_rect(sa, block, v3d->ri); + if(v3d->ri->cury==0) + addafterqueue(sa->win, RENDERPREVIEW, 1); } } diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 87b4e0654b3..921048ff3b0 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -63,11 +63,13 @@ #include "DNA_view3d_types.h" #include "DNA_screen_types.h" +#include "DNA_scene_types.h" #include "DNA_vec_types.h" #include "BKE_global.h" #include "BKE_scene.h" #include "BKE_utildefines.h" +#include "BKE_writeavi.h" /* movie handle */ #include "BIF_gl.h" #include "BIF_glutil.h" @@ -75,10 +77,10 @@ #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_mywindow.h" -#include "BIF_previewrender.h" #include "BIF_renderwin.h" #include "BIF_resources.h" #include "BIF_toets.h" +#include "BIF_writeimage.h" #include "BDR_editobject.h" #include "BPY_extern.h" /* for BPY_do_all_scripts */ @@ -88,10 +90,11 @@ #include "BSE_filesel.h" #include "BSE_headerbuttons.h" +#include "RE_pipeline.h" + #include "blendef.h" #include "mydevice.h" #include "winlay.h" -#include "render.h" /* ------------ renderwin struct, to prevent too much global vars --------- */ /* ------------ only used for display in a 2nd window --------- */ @@ -123,6 +126,7 @@ typedef struct { Window *win; + int rectx, recty; /* size of image */ float zoom, zoomofs[2]; int active; @@ -172,7 +176,7 @@ static void renderwin_reshape(RenderWin *rw) ; } -static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2]) +static void renderwin_get_fullrect(RenderWin *rw, float fullrect_r[2][2]) { float display_w, display_h; float cent_x, cent_y; @@ -181,15 +185,15 @@ static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2]) window_get_size(rw->win, &w, &h); h-= RW_HEADERY; - display_w= R.rectx*rw->zoom; - display_h= R.recty*rw->zoom; - cent_x= (rw->zoomofs[0] + R.rectx/2)*rw->zoom; - cent_y= (rw->zoomofs[1] + R.recty/2)*rw->zoom; + display_w= rw->rectx*rw->zoom; + display_h= rw->recty*rw->zoom; + cent_x= (rw->zoomofs[0] + rw->rectx/2)*rw->zoom; + cent_y= (rw->zoomofs[1] + rw->recty/2)*rw->zoom; - disprect_r[0][0]= w/2 - cent_x; - disprect_r[0][1]= h/2 - cent_y; - disprect_r[1][0]= disprect_r[0][0] + display_w; - disprect_r[1][1]= disprect_r[0][1] + display_h; + fullrect_r[0][0]= w/2 - cent_x; + fullrect_r[0][1]= h/2 - cent_y; + fullrect_r[1][0]= fullrect_r[0][0] + display_w; + fullrect_r[1][1]= fullrect_r[0][1] + display_h; } /** @@ -198,14 +202,14 @@ static void renderwin_get_disprect(RenderWin *rw, float disprect_r[2][2]) */ static int renderwin_win_to_image_co(RenderWin *rw, int winco[2], int imgco_r[2]) { - float disprect[2][2]; + float fullrect[2][2]; - renderwin_get_disprect(rw, disprect); + renderwin_get_fullrect(rw, fullrect); - imgco_r[0]= (int) ((winco[0]-disprect[0][0])/rw->zoom); - imgco_r[1]= (int) ((winco[1]-disprect[0][1])/rw->zoom); + imgco_r[0]= (int) ((winco[0]-fullrect[0][0])/rw->zoom); + imgco_r[1]= (int) ((winco[1]-fullrect[0][1])/rw->zoom); - return (imgco_r[0]>=0 && imgco_r[1]>=0 && imgco_r[0]=0 && imgco_r[1]>=0 && imgco_r[0]rectx && imgco_r[1]recty); } /** @@ -233,29 +237,17 @@ static void renderwin_set_infotext(RenderWin *rw, char *info_text) static void renderwin_reset_view(RenderWin *rw) { - int w, h, rectx, recty; + int w, h; if (rw->info_text) renderwin_set_infotext(rw, NULL); /* now calculate a zoom for when image is larger than window */ window_get_size(rw->win, &w, &h); h-= RW_HEADERY; - - /* at this point the r.rectx/y values are not correct yet */ - rectx= (G.scene->r.size*G.scene->r.xsch)/100; - recty= (G.scene->r.size*G.scene->r.ysch)/100; - - /* crop option makes image smaller */ - if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) { - if(!(G.scene->r.scemode & R_OGL)) { - rectx= (int) (rectx*(G.scene->r.border.xmax-G.scene->r.border.xmin)); - recty= (int) (recty*(G.scene->r.border.ymax-G.scene->r.border.ymin)); - } - } - - if(rectx>w || recty>h) { - if(rectx-w > recty-h) rw->zoom= ((float)w)/((float)rectx); - else rw->zoom= ((float)h)/((float)recty); + + if(rw->rectx>w || rw->recty>h) { + if(rw->rectx-w > rw->recty-h) rw->zoom= ((float)w)/((float)rw->rectx); + else rw->zoom= ((float)h)/((float)rw->recty); } else rw->zoom= 1.0; @@ -295,13 +287,13 @@ static void renderwin_draw_render_info(RenderWin *rw) static void renderwin_draw(RenderWin *rw, int just_clear) { - float disprect[2][2]; + float fullrect[2][2]; int set_back_mainwindow; rcti rect; - + /* since renderwin uses callbacks (controlled by ghost) it can - mess up active window output with redraw events after a render. - this is patchy, still WIP */ + mess up active window output with redraw events after a render. + this is patchy, still WIP */ set_back_mainwindow = (winlay_get_active_window() != rw->win); window_make_active(rw->win); @@ -309,7 +301,7 @@ static void renderwin_draw(RenderWin *rw, int just_clear) window_get_size(rw->win, &rect.xmax, &rect.ymax); rect.ymax-= RW_HEADERY; - renderwin_get_disprect(rw, disprect); + renderwin_get_fullrect(rw, fullrect); /* do this first, so window ends with correct scissor */ renderwin_draw_render_info(rw); @@ -320,27 +312,30 @@ static void renderwin_draw(RenderWin *rw, int just_clear) glClearColor(.1875, .1875, .1875, 1.0); glClear(GL_COLOR_BUFFER_BIT); - if (just_clear || !R.rectot) { + if (just_clear) { glColor3ub(0, 0, 0); - glRectfv(disprect[0], disprect[1]); + glRectfv(fullrect[0], fullrect[1]); } else { - glPixelZoom(rw->zoom, rw->zoom); - if(rw->flags & RW_FLAGS_ALPHA) { - char *rect= (char *)R.rectot; - - glColorMask(1, 0, 0, 0); - glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+3); - glColorMask(0, 1, 0, 0); - glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+2); - glColorMask(0, 0, 1, 0); - glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, rect+1); - glColorMask(1, 1, 1, 1); + RenderResult rres; + + RE_GetResultImage(RE_GetRender("Render"), &rres); + if(rres.rectf) { + glPixelZoom(rw->zoom, rw->zoom); + if(rw->flags & RW_FLAGS_ALPHA) { + /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ + // glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); + // glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx, rr->recty, GL_LUMINANCE, GL_UNSIGNED_INT, R.rectot); + // glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); + } + else { + if(rres.rect32) + glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rres.rect32); + else if(rres.rectf) + glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_FLOAT, rres.rectf); + } + glPixelZoom(1.0, 1.0); } - else { - glaDrawPixelsSafe(disprect[0][0], disprect[0][1], R.rectx, R.recty, R.rectot); - } - glPixelZoom(1.0, 1.0); } /* info text is overlayed on bottom */ @@ -366,21 +361,27 @@ static void renderwin_draw(RenderWin *rw, int just_clear) static void renderwin_mouse_moved(RenderWin *rw) { + RenderResult rres; + + RE_GetResultImage(RE_GetRender("Render"), &rres); + if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) { - int imgco[2]; - char buf[64]; - int *pxlz; // zbuffer is signed + int imgco[2], ofs=0; + char buf[128]; char *pxl; - if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) { - pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]]; - - if (R.rectz) { - pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]]; - sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) ); + if (renderwin_win_to_image_co(rw, rw->lmouse, imgco)) { + if (rres.rect32) { + pxl= (char*) &rres.rect32[rres.rectx*imgco[1] + imgco[0]]; + ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]); } - else { - sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]); + if (rres.rectf) { + float *pxlf= rres.rectf + 4*(rres.rectx*imgco[1] + imgco[0]); + ofs+= sprintf(buf+ofs, " | R: %.3f G: %.3f B: %.3f A: %.3f ", pxlf[0], pxlf[1], pxlf[2], pxlf[3]); + } + if (rres.rectz) { + float *pxlz= &rres.rectz[rres.rectx*imgco[1] + imgco[0]]; + sprintf(buf+ofs, "| Z: %.3f", *pxlz ); } renderwin_set_infotext(rw, buf); @@ -396,8 +397,8 @@ static void renderwin_mouse_moved(RenderWin *rw) rw->zoomofs[0]= rw->pan_ofs_start[0] - delta_x/rw->zoom; rw->zoomofs[1]= rw->pan_ofs_start[1] - delta_y/rw->zoom; - rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -R.rectx/2, R.rectx/2); - rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -R.recty/2, R.recty/2); + rw->zoomofs[0]= CLAMPIS(rw->zoomofs[0], -rres.rectx/2, rres.rectx/2); + rw->zoomofs[1]= CLAMPIS(rw->zoomofs[1], -rres.recty/2, rres.recty/2); renderwin_queue_redraw(rw); } @@ -409,8 +410,8 @@ static void renderwin_mouse_moved(RenderWin *rw) h-= RW_HEADERY; renderwin_win_to_ndc(rw, rw->lmouse, ndc); - rw->zoomofs[0]= -0.5*ndc[0]*(w-R.rectx*rw->zoom)/rw->zoom; - rw->zoomofs[1]= -0.5*ndc[1]*(h-R.recty*rw->zoom)/rw->zoom; + rw->zoomofs[0]= -0.5*ndc[0]*(w-rres.rectx*rw->zoom)/rw->zoom; + rw->zoomofs[1]= -0.5*ndc[1]*(h-rres.recty*rw->zoom)/rw->zoom; renderwin_queue_redraw(rw); } @@ -448,7 +449,7 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val RenderWin *rw= user_data; // added this for safety, while render it's just creating bezerk results - if(R.flag & R_RENDERING) { + if(G.rendering) { if(evt==ESCKEY && val) rw->flags|= RW_FLAGS_ESCAPE; return; @@ -498,7 +499,7 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val renderwin_queue_redraw(render_win); } else if (evt==JKEY) { - if(R.flag==0) BIF_swap_render_rects(); +// if(R.flag==0) BIF_swap_render_rects(); } else if (evt==ZKEY) { if (rw->flags&RW_FLAGS_OLDZOOM) { @@ -531,20 +532,20 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val renderwin_reset_view(rw); } else if (evt==F3KEY) { - if(R.flag==0) { - mainwindow_raise(); - mainwindow_make_active(); - rw->active= 0; - areawinset(find_biggest_area()->win); - BIF_save_rendered_image(); - } +// if(R.flag==0) { +// mainwindow_raise(); +// mainwindow_make_active(); +// rw->active= 0; +// areawinset(find_biggest_area()->win); +// BIF_save_rendered_image_fs(); +// } } else if (evt==F11KEY) { BIF_toggle_render_display(); } else if (evt==F12KEY) { /* if it's rendering, this flag is set */ - if(R.flag==0) BIF_do_render(0); +// if(R.flag==0) BIF_do_render(0); } } } @@ -569,7 +570,7 @@ static char *renderwin_get_title(int doswap) } /* opens window and allocs struct */ -static void open_renderwin(int winpos[2], int winsize[2]) +static void open_renderwin(int winpos[2], int winsize[2], int imagesize[2]) { extern void mywindow_build_and_set_renderwin( int orx, int ory, int sizex, int sizey); // mywindow.c Window *win; @@ -579,7 +580,9 @@ static void open_renderwin(int winpos[2], int winsize[2]) win= window_open(title, winpos[0], winpos[1], winsize[0], winsize[1]+RW_HEADERY, 0); render_win= renderwin_alloc(win); - + render_win->rectx= imagesize[0]; + render_win->recty= imagesize[1]; + /* Ghost calls handler */ window_set_handler(win, renderwin_handler, render_win); @@ -599,26 +602,15 @@ static void open_renderwin(int winpos[2], int winsize[2]) /* -------------- callbacks for render loop: Window (RenderWin) ----------------------- */ /* calculations for window size and position */ -void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[2]) +void calc_renderwin_rectangle(int rectx, int recty, int posmask, int renderpos_r[2], int rendersize_r[2]) { int scr_w, scr_h, x, y, div= 0; float ndc_x= 0.0, ndc_y= 0.0; winlay_get_screensize(&scr_w, &scr_h); - rendersize_r[0]= (G.scene->r.size*G.scene->r.xsch)/100; - rendersize_r[1]= (G.scene->r.size*G.scene->r.ysch)/100; - - /* crop option makes image smaller */ - if ((G.scene->r.mode & R_BORDER) && (G.scene->r.mode & R_MOVIECROP)) { - rendersize_r[0]*= (G.scene->r.border.xmax-G.scene->r.border.xmin); - rendersize_r[1]*= (G.scene->r.border.ymax-G.scene->r.border.ymin); - } - - if(G.scene->r.mode & R_PANORAMA) { - rendersize_r[0]*= G.scene->r.xparts; - rendersize_r[1]*= G.scene->r.yparts; - } + rendersize_r[0]= rectx; + rendersize_r[1]= recty; rendersize_r[0]= CLAMPIS(rendersize_r[0], 0, scr_w); rendersize_r[1]= CLAMPIS(rendersize_r[1], 0, scr_h-RW_HEADERY); @@ -649,15 +641,18 @@ void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[ } /* init renderwin, alloc/open/resize */ -static void renderwin_init_display_cb(void) +static void renderwin_init_display_cb(RenderResult *rr) { if (G.afbreek == 0) { - int rendersize[2], renderpos[2]; + int rendersize[2], renderpos[2], imagesize[2]; - calc_renderwin_rectangle(G.winpos, renderpos, rendersize); + calc_renderwin_rectangle(rr->rectx, rr->recty, G.winpos, renderpos, rendersize); + + imagesize[0]= rr->rectx; + imagesize[1]= rr->recty; if (!render_win) { - open_renderwin(renderpos, rendersize); + open_renderwin(renderpos, rendersize, imagesize); renderwin_reset_view(render_win); // incl. autozoom for large images } else { int win_x, win_y; @@ -680,7 +675,7 @@ static void renderwin_init_display_cb(void) */ if(rendersize[0]!= win_w || rendersize[1]!= win_h) { BIF_close_render_display(); - open_renderwin(renderpos, rendersize); + open_renderwin(renderpos, rendersize, imagesize); } else { window_raise(render_win->win); @@ -702,14 +697,16 @@ static void renderwin_init_display_cb(void) } /* make sure we are in normal draw again */ render_win->flags &= ~RW_FLAGS_ALPHA; + + glFinish(); } } /* callback for redraw render win */ -static void renderwin_clear_display_cb(short ignore) +static void renderwin_clear_display_cb(RenderResult *rr) { if (render_win) { - window_make_active(render_win->win); + window_make_active(render_win->win); renderwin_draw(render_win, 1); } } @@ -723,27 +720,41 @@ static void renderwin_clear_display_cb(short ignore) * Note: blocked queue handling while rendering to prevent that (ton) */ -/* in render window; display a couple of scanlines of rendered image (see callback below) */ -static void renderwin_progress(RenderWin *rw, int start_y, int nlines, int rect_w, int rect_h, unsigned char *rect) +/* can get as well the full picture, as the parts while rendering */ +static void renderwin_progress(RenderWin *rw, RenderResult *rr, rcti *unused) { - float disprect[2][2]; rcti win_rct; - + float *rectf, fullrect[2][2]; + + /* renderwindow cruft */ win_rct.xmin= win_rct.ymin= 0; window_get_size(rw->win, &win_rct.xmax, &win_rct.ymax); win_rct.ymax-= RW_HEADERY; + renderwin_get_fullrect(rw, fullrect); - renderwin_get_disprect(rw, disprect); + /* find current float rect for display, first case is after composit... still weak */ + if(rr->rectf) + rectf= rr->rectf; + else { + RenderLayer *rl= BLI_findlink(&rr->layers, rr->actlay); + rectf= rl->rectf; + } + /* when rendering more pixels than needed, we crop away cruft */ + if(rr->crop) + rectf+= 4*(rr->crop*rr->rectx + rr->crop); - /* for efficiency & speed; not drawing in Blender UI while rendering */ - //window_make_active(rw->win); + /* tilerect defines drawing offset from (0,0) */ + /* however, tilerect (xmin, ymin) is first pixel */ + fullrect[0][0] += (rr->tilerect.xmin+rr->crop)*rw->zoom; + fullrect[0][1] += (rr->tilerect.ymin+rr->crop)*rw->zoom; glEnable(GL_SCISSOR_TEST); glaDefine2DArea(&win_rct); glDrawBuffer(GL_FRONT); glPixelZoom(rw->zoom, rw->zoom); - glaDrawPixelsSafe(disprect[0][0], disprect[0][1] + start_y*rw->zoom, rect_w, nlines, &rect[start_y*rect_w*4]); + glaDrawPixelsSafe(fullrect[0][0], fullrect[0][1], rr->rectx-2*rr->crop, rr->recty-2*rr->crop, rr->rectx, + GL_RGBA, GL_FLOAT, rectf); glPixelZoom(1.0, 1.0); glFlush(); glDrawBuffer(GL_BACK); @@ -751,177 +762,44 @@ static void renderwin_progress(RenderWin *rw, int start_y, int nlines, int rect_ /* in render window; display a couple of scanlines of rendered image */ -static void renderwin_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect) +static void renderwin_progress_display_cb(RenderResult *rr, rcti *rect) { if (render_win) { - renderwin_progress(render_win, y1, y2-y1+1, w, h, (unsigned char*) rect); + renderwin_progress(render_win, rr, rect); } } - -/* -------------- callbacks for render loop: in View3D ----------------------- */ - - -static View3D *render_view3d = NULL; - -/* init Render view callback */ -static void renderview_init_display_cb(void) -{ - ScrArea *sa; - - /* Choose the first view with a persp camera, - * if one doesn't exist we will get the first - * View3D window. - */ - render_view3d= NULL; - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - if (sa->win && sa->spacetype==SPACE_VIEW3D) { - View3D *vd= sa->spacedata.first; - - if (vd->persp==2 && vd->camera==G.scene->camera) { - render_view3d= vd; - break; - } else if (!render_view3d) { - render_view3d= vd; - } - } - } -} - - -/* in 3d view; display a couple of scanlines of rendered image */ -static void renderview_progress_display_cb(int y1, int y2, int w, int h, unsigned int *rect) -{ - if (render_view3d) { - View3D *v3d= render_view3d; - int nlines= y2-y1+1; - float sx, sy, facx, facy; - rcti win_rct, vb; - - calc_viewborder(v3d, &vb); - - /* if border render */ - if(G.scene->r.mode & R_BORDER) { - - /* but, if image is full (at end of border render, without crop) we don't */ - if(R.rectx != (G.scene->r.size*G.scene->r.xsch)/100 || - R.recty != (G.scene->r.size*G.scene->r.ysch)/100 ) { - - facx= (float) (vb.xmax-vb.xmin); - facy= (float) (vb.ymax-vb.ymin); - - vb.xmax= vb.xmin + facx*G.scene->r.border.xmax; - vb.ymax= vb.ymin + facy*G.scene->r.border.ymax; - vb.xmin+= facx*G.scene->r.border.xmin; - vb.ymin+= facy*G.scene->r.border.ymin; - } - } - - facx= (float) (vb.xmax-vb.xmin)/R.rectx; - facy= (float) (vb.ymax-vb.ymin)/R.recty; - - bwin_get_rect(v3d->area->win, &win_rct); - - glaDefine2DArea(&win_rct); - - glDrawBuffer(GL_FRONT); - - sx= vb.xmin; - sy= vb.ymin + facy*y1; - - glPixelZoom(facx, facy); - glaDrawPixelsSafe(sx, sy, w, nlines, rect+w*y1); - glPixelZoom(1.0, 1.0); - - glFlush(); - glDrawBuffer(GL_BACK); - v3d->flag |= V3D_DISPIMAGE; - v3d->area->win_swap= WIN_FRONT_OK; - - } -} - -/* in 3d view; display stats of rendered image */ -static void renderview_draw_render_info(char *str) -{ - if (render_view3d) { - View3D *v3d= render_view3d; - rcti vb, win_rct; - - calc_viewborder(v3d, &vb); - - bwin_get_rect(v3d->area->win, &win_rct); - glaDefine2DArea(&win_rct); - - glDrawBuffer(GL_FRONT); - - /* clear header rect */ - BIF_ThemeColor(TH_HEADER); - glRecti(vb.xmin, vb.ymax, vb.xmax, vb.ymax+RW_HEADERY); - - if(str) { - BIF_ThemeColor(TH_TEXT); - glRasterPos2i(vb.xmin+12, vb.ymax+5); - BMF_DrawString(G.fonts, str); - } - - glFlush(); - glDrawBuffer(GL_BACK); - - v3d->area->win_swap= WIN_FRONT_OK; - - } -} - - /* -------------- callbacks for render loop: interactivity ----------------------- */ /* callback for print info in top header of renderwin */ -/* time is only not zero on last call, we then don't update the other stats */ -static void printrenderinfo_cb(double time, int sample) +static void printrenderinfo_cb(RenderStats *rs) { + extern char info_time_str[32]; // header_info.c extern int mem_in_use; - static int totvert=0, totvlak=0, tothalo=0, totlamp=0; - static float megs_used_memory=0.0; + static float megs_used_memory; char str[300], *spos= str; - if(time==0.0) { - megs_used_memory= mem_in_use/(1024.0*1024.0); - totvert= R.totvert; - totvlak= R.totvlak; - totlamp= R.totlamp; - tothalo= R.tothalo; - } - - if(tothalo) - spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, tothalo, totlamp, megs_used_memory); - else - spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM", (G.scene->r.cfra), totvert, totvlak, totlamp, megs_used_memory); - - if(time==0.0) { - if (R.r.mode & R_FIELDS) { - spos+= sprintf(spos, "Field %c ", (R.flag&R_SEC_FIELD)?'B':'A'); - } - if (sample!=-1) { - spos+= sprintf(spos, "Sample: %d ", sample); - } - } - else { - extern char info_time_str[32]; // header_info.c - timestr(time, info_time_str); - spos+= sprintf(spos, " Time:%s ", info_time_str); - } - if(render_win) { - if(render_win->render_text) MEM_freeN(render_win->render_text); - render_win->render_text= BLI_strdup(str); - glDrawBuffer(GL_FRONT); - renderwin_draw_render_info(render_win); - glFlush(); - glDrawBuffer(GL_BACK); + megs_used_memory= mem_in_use/(1024.0*1024.0); + + if(rs->tothalo) + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d Ha:%d La:%d Mem:%.2fM", (G.scene->r.cfra), rs->totvert, rs->totface, rs->tothalo, rs->totlamp, megs_used_memory); + else + spos+= sprintf(spos, "Fra:%d Ve:%d Fa:%d La:%d Mem:%.2fM", (G.scene->r.cfra), rs->totvert, rs->totface, rs->totlamp, megs_used_memory); + + BLI_timestr(rs->lastframetime, info_time_str); + spos+= sprintf(spos, " Time:%s ", info_time_str); + + if(render_win) { + if(render_win->render_text) MEM_freeN(render_win->render_text); + render_win->render_text= BLI_strdup(str); + glDrawBuffer(GL_FRONT); + renderwin_draw_render_info(render_win); + glFlush(); + glDrawBuffer(GL_BACK); + } } - else renderview_draw_render_info(str); } /* -------------- callback system to allow ESC from rendering ----------------------- */ @@ -1025,98 +903,61 @@ static void end_test_break_callback() /* - initialize displays - - both opengl render as blender render - set callbacks - cleanup */ -static void do_render(View3D *ogl_render_view3d, int anim, int force_dispwin) +static void do_render(int anim) { + Render *re= RE_NewRender("Render"); /* we set this flag to prevent renderwindow queue to execute another render */ - R.flag= R_RENDERING; + G.rendering= 1; G.afbreek= 0; - if (G.displaymode == R_DISPLAYWIN || force_dispwin) { - RE_set_initrenderdisplay_callback(NULL); - RE_set_clearrenderdisplay_callback(renderwin_clear_display_cb); - RE_set_renderdisplay_callback(renderwin_progress_display_cb); - - renderwin_init_display_cb(); - } - else { - BIF_close_render_display(); - RE_set_initrenderdisplay_callback(renderview_init_display_cb); - RE_set_clearrenderdisplay_callback(NULL); - RE_set_renderdisplay_callback(renderview_progress_display_cb); - } - + /* set callbacks */ + RE_display_init_cb(re, renderwin_init_display_cb); + RE_display_draw_cb(re, renderwin_progress_display_cb); + RE_display_clear_cb(re, renderwin_clear_display_cb); init_test_break_callback(); - RE_set_test_break_callback(test_break); + RE_test_break_cb(re, test_break); + RE_timecursor_cb(re, set_timecursor); + RE_stats_draw_cb(re, printrenderinfo_cb); - RE_set_timecursor_callback(set_timecursor); - RE_set_printrenderinfo_callback(printrenderinfo_cb); - - if (render_win) { - window_set_cursor(render_win->win, CURSOR_WAIT); - // when opening new window... not cross platform identical behaviour, so - // for now call it each time - // if(ogl_render_view3d) init_gl_stuff(); - } + if(render_win) window_set_cursor(render_win->win, CURSOR_WAIT); waitcursor(1); - if(G.obedit && !(G.scene->r.scemode & R_OGL)) { + if(G.obedit) exit_editmode(0); /* 0 = no free data */ - } - if(anim) { - RE_animrender(ogl_render_view3d); - } - else { - RE_initrender(ogl_render_view3d); - } + if(anim) + RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); + else + RE_BlenderFrame(re, G.scene, G.scene->r.cfra); - if (render_win) window_set_cursor(render_win->win, CURSOR_STD); + if(render_win) window_set_cursor(render_win->win, CURSOR_STD); free_filesel_spec(G.scene->r.pic); G.afbreek= 0; end_test_break_callback(); - /* in dispiew it will destroy the image otherwise - window_make_active() raises window at osx and sends redraws */ - if(G.displaymode==R_DISPLAYWIN) { - mainwindow_make_active(); + mainwindow_make_active(); - /* after an envmap creation... */ - if(R.flag & R_REDRAW_PRV) { - BIF_all_preview_changed(); - } - allqueue(REDRAWBUTSSCENE, 0); // visualize fbuf for example - } + /* after an envmap creation... */ +// if(R.flag & R_REDRAW_PRV) { +// BIF_preview_changed(ID_TE); +// } + allqueue(REDRAWBUTSSCENE, 0); // visualize fbuf for example - R.flag= 0; // before scene update! + // before scene update! + G.rendering= 0; scene_update_for_newframe(G.scene, G.scene->lay); // no redraw needed, this restores to view as we left it waitcursor(0); // waitcursor checks rendering R.flag... } -/* finds area with a 'dispview' set */ -static ScrArea *find_dispimage_v3d(void) -{ - ScrArea *sa; - - for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { - if (sa->spacetype==SPACE_VIEW3D) { - View3D *vd= sa->spacedata.first; - if (vd->flag & V3D_DISPIMAGE) - return sa; - } - } - - return NULL; -} /* used for swapping with spare buffer, when images are different size */ static void scalefastrect(unsigned int *recto, unsigned int *rectn, int oldx, int oldy, int newx, int newy) @@ -1182,42 +1023,88 @@ void BIF_do_render(int anim) G.scene->lay= G.vd->lay; } - do_render(NULL, anim, 0); + do_render(anim); G.scene->lay= lay; } - else do_render(NULL, anim, 0); + else do_render(anim); + if(G.scene->use_nodes) + allqueue(REDRAWNODE, 1); if (slink_flag) G.f |= G_DOSCRIPTLINKS; if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER); } /* set up display, render the current area view in an image */ -void BIF_do_ogl_render(View3D *ogl_render_view3d, int anim) +/* the RE_Render is only used to make sure we got the picture in the result */ +void BIF_do_ogl_render(View3D *v3d, int anim) { - G.scene->r.scemode |= R_OGL; - do_render(ogl_render_view3d, anim, 1); - G.scene->r.scemode &= ~R_OGL; + Render *re= RE_NewRender("Render"); + RenderResult *rr; + int winx, winy; + + G.afbreek= 0; + init_test_break_callback(); + + winx= (G.scene->r.size*G.scene->r.xsch)/100; + winy= (G.scene->r.size*G.scene->r.ysch)/100; + + RE_InitState(re, &G.scene->r, winx, winy, NULL); + + /* for now, result is defaulting to floats still... */ + rr= RE_GetResult(re); + if(rr->rect32==NULL) + rr->rect32= MEM_mallocN(sizeof(int)*winx*winy, "32 bits rects"); + + /* open window */ + renderwin_init_display_cb(rr); + init_gl_stuff(); + + waitcursor(1); + + if(anim) { + bMovieHandle *mh= BKE_get_movie_handle(G.scene->r.imtype); + int cfrao= CFRA; + + mh->start_movie(&G.scene->r, winx, winy); + + for(CFRA= SFRA; CFRA<=EFRA; CFRA++) { + drawview3d_render(v3d, winx, winy); + glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32); + window_swap_buffers(render_win->win); + + mh->append_movie(CFRA, rr->rect32, winx, winy); + if(test_break()) break; + } + mh->end_movie(); + CFRA= cfrao; + } + else { + drawview3d_render(v3d, winx, winy); + glReadPixels(0, 0, winx, winy, GL_RGBA, GL_UNSIGNED_BYTE, rr->rect32); + window_swap_buffers(render_win->win); + } + + mainwindow_make_active(); + + if(anim) + scene_update_for_newframe(G.scene, G.scene->lay); // no redraw needed, this restores to view as we left it + + end_test_break_callback(); + waitcursor(0); } void BIF_redraw_render_rect(void) { - /* redraw */ - if (G.displaymode == R_DISPLAYWIN) { - // don't open render_win if rendering has been - // canceled or the render_win has been actively closed - if (render_win) { - renderwin_queue_redraw(render_win); - } - } else { - renderview_init_display_cb(); - renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); + if (render_win) { + renderwin_queue_redraw(render_win); } } void BIF_swap_render_rects(void) { +#if 0 unsigned int *temp; if(R.rectspare==0) { @@ -1240,26 +1127,24 @@ void BIF_swap_render_rects(void) R.rectot= R.rectspare; R.rectspare= temp; - if (G.displaymode == R_DISPLAYWIN) { - if (render_win) { - char *tmp= render_win->render_text_spare; - render_win->render_text_spare= render_win->render_text; - render_win->render_text= tmp; - - window_set_title(render_win->win, renderwin_get_title(1)); - - } + if (render_win) { + char *tmp= render_win->render_text_spare; + render_win->render_text_spare= render_win->render_text; + render_win->render_text= tmp; + + window_set_title(render_win->win, renderwin_get_title(1)); + } /* redraw */ BIF_redraw_render_rect(); +#endif } /* called from usiblender.c too, to free and close renderwin */ void BIF_close_render_display(void) { if (render_win) { - if (render_win->info_text) MEM_freeN(render_win->info_text); if (render_win->render_text) MEM_freeN(render_win->render_text); if (render_win->render_text_spare) MEM_freeN(render_win->render_text_spare); @@ -1275,10 +1160,8 @@ void BIF_close_render_display(void) /* typical with F11 key, show image or hide/close */ void BIF_toggle_render_display(void) { - ScrArea *sa= find_dispimage_v3d(); - if(R.rectot==NULL); // do nothing - else if (render_win && G.displaymode==R_DISPLAYWIN) { + if (render_win) { if(render_win->active) { mainwindow_raise(); mainwindow_make_active(); @@ -1290,21 +1173,9 @@ void BIF_toggle_render_display(void) render_win->active= 1; } } - else if (sa && G.displaymode==R_DISPLAYVIEW) { - View3D *vd= sa->spacedata.first; - vd->flag &= ~V3D_DISPIMAGE; - scrarea_queue_winredraw(sa); - } else { - if (G.displaymode == R_DISPLAYWIN) { - renderwin_init_display_cb(); - } else { - if (render_win) { - BIF_close_render_display(); - } - renderview_init_display_cb(); - renderview_progress_display_cb(0, R.recty-1, R.rectx, R.recty, R.rectot); - } + RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + if(rr) renderwin_init_display_cb(rr); } } diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c index 078bcec2aaa..a5dbe1a5ba2 100644 --- a/source/blender/src/resources.c +++ b/source/blender/src/resources.c @@ -52,6 +52,7 @@ #include "BIF_gl.h" #include "BIF_resources.h" +#include "BIF_interface_icons.h" #include "BLI_blenlib.h" #include "blendef.h" // CLAMP @@ -63,578 +64,15 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha); static bTheme *theme_active=NULL; static int theme_spacetype= SPACE_VIEW3D; -typedef struct { - /* If drawFunc is defined then it is a vector icon, otherwise use data */ - VectorDrawFunc drawFunc; - - int w, h; - - /* Data for image icons */ - unsigned char *data; - float uv[4][2]; - GLuint texid; -} Icon; - -static Icon *icon_new_vector(VectorDrawFunc drawFunc, int w, int h) -{ - Icon *icon= MEM_callocN(sizeof(*icon), "internicon"); - icon->drawFunc = drawFunc; - icon->w = w; - icon->h = h; - - return icon; -} - -static Icon *icon_from_data(unsigned char *rect, GLuint texid, int xofs, int yofs, int w, int h, int rowstride) -{ - Icon *icon= MEM_mallocN(sizeof(*icon), "internicon"); - int y; - - icon->drawFunc = NULL; - icon->texid= texid; - icon->uv[0][0]= ((float)xofs)/512.0; - icon->uv[0][1]= ((float)yofs)/256.0; - icon->uv[1][0]= icon->uv[0][0] + ((float)w)/512.0; - icon->uv[1][1]= icon->uv[0][1]; - icon->uv[2][0]= icon->uv[0][0] + ((float)w)/512.0; - icon->uv[2][1]= icon->uv[0][1] + ((float)w)/256.0; - icon->uv[3][0]= icon->uv[0][0]; - icon->uv[3][1]= icon->uv[0][1] + ((float)w)/256.0; - - icon->w= w; - icon->h= h; - - icon->data= MEM_mallocN(w*h*4, "icon->data"); - for (y=0; ydata[y*w*4], &rect[y*rowstride], w*4); - - return icon; -} - -#if 0 -static float icon_x=0.0, icon_y=0.0; -void BIF_icon_pos(float xs, float ys) -{ - icon_x= xs; icon_y= ys; -} - -static GLuint init_icon_texture(ImBuf *bbuf) -{ - GLuint texid; - - glGenTextures(1, &texid); - glBindTexture(GL_TEXTURE_2D, texid); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - return texid; -} - -/* texture version for drawpixels */ -static void icon_draw_tex(Icon *icon) -{ - glBindTexture(GL_TEXTURE_2D, icon->texid); - - /* drawing it */ - glColor3ub(255, 255, 255); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - - glTexCoord2fv(icon->uv[0]); - glVertex2f(icon_x, icon_y); - glTexCoord2fv(icon->uv[1]); - glVertex2f(icon_x+icon->w, icon_y); - glTexCoord2fv(icon->uv[2]); - glVertex2f(icon_x+icon->w, icon_y+icon->h); - glTexCoord2fv(icon->uv[3]); - glVertex2f(icon_x, icon_y+icon->h); - - glEnd(); - glDisable(GL_TEXTURE_2D); -} -#endif - - -static void icon_draw(float x, float y, Icon *icon) -{ - if (icon->drawFunc) { - icon->drawFunc(x, y, icon->w, icon->h, 1.0); - } else { - glRasterPos2f(x, y); - glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data); - } -} - - -static void icon_draw_blended(float x, float y, Icon *icon, char *blendcol, int shade) -{ - if (icon->drawFunc) { - icon->drawFunc(x, y, icon->w, icon->h, shade<0?((128+shade)/128.0):1.0); - } else { - if(shade < 0) { - float r= (128+shade)/128.0; - glPixelTransferf(GL_ALPHA_SCALE, r); - } - glRasterPos2f(x, y); - glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data); - glPixelTransferf(GL_ALPHA_SCALE, 1.0); - } -} - - -static void icon_free(Icon *icon) -{ - if (icon->data) MEM_freeN(icon->data); - MEM_freeN(icon); -} - - -static Icon **common_icons_arr= NULL; - -static Icon *get_icon(BIFIconID icon) -{ - int iconidx= icon-BIFICONID_FIRST; - if (iconidx>=0 && iconidxw; -} - -int BIF_get_icon_height(BIFIconID icon) -{ - return get_icon(icon)->h; -} - -static void def_icon(ImBuf *bbuf, GLuint texid, BIFIconID icon, int xidx, int yidx, int w, int h, int offsx, int offsy) -{ - int iconidx= icon-BIFICONID_FIRST; - - if (iconidx>=0 && iconidxx*4; - unsigned char *start= ((unsigned char*) bbuf->rect) + (yidx*21 + 3 + offsy)*rowstride + (xidx*20 + 3 + offsx)*4; - - common_icons_arr[iconidx]= - icon_from_data(start, texid, (xidx*20 + 3 + offsx), (yidx*21 + 3 + offsy), w, h, rowstride); - - } else { - printf("def_icon: Internal error, bad icon ID: %d\n", icon); - } -} - -static void def_vicon(BIFIconID icon, int w, int h, VectorDrawFunc drawFunc) -{ - int iconidx= icon-BIFICONID_FIRST; - - if (iconidx>=0 && iconidxval) pxl[0]-= val; else pxl[0]= 0; - if(pxl[1]>val) pxl[1]-= val; else pxl[1]= 0; - if(pxl[2]>val) pxl[2]-= val; else pxl[2]= 0; - - pxl[3]= 128; - } - } - } - } - } -} - - -static void clear_transp_rect(unsigned char *transp, unsigned char *rect, int w, int h, int rowstride) -{ - int x,y; - for (y=0; yx*4; - unsigned char *start= ((unsigned char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4; - unsigned char transp[4]; - /* this sets backdrop of icon to zero alpha */ - transp[0]= start[0]; - transp[1]= start[1]; - transp[2]= start[2]; - transp[3]= start[3]; - clear_transp_rect(transp, start, 20, 21, rowstride); - clear_transp_rect_soft(transp, start, 20, 21, rowstride); - - /* this sets outside of icon to zero alpha */ - start= ((unsigned char*) bbuf->rect) + (y*21)*rowstride + (x*20)*4; - QUATCOPY(transp, start); - clear_transp_rect(transp, start, 20, 21, rowstride); - - - } - } - - // disabled for now (ton) - // texid= init_icon_texture(bbuf); - - /* hack! */ - for (y=0; y<12; y++) { - for (x=0; x<21; x++) { - if (x==11 && y==6) { - def_icon(bbuf, texid, ICON_BEVELBUT_HLT, x, y, 7, 13, 4, 2); - } else if (x==12 && y==6) { - def_icon(bbuf, texid, ICON_BEVELBUT_DEHLT, x, y, 7, 13, 4, 2); - } else { - def_icon(bbuf, texid, BIFICONID_FIRST + y*21 + x, x, y, 15, 16, 0, 0); - } - } - } - - def_vicon(VICON_VIEW3D, 16, 16, vicon_view3d_draw); - def_vicon(VICON_EDIT, 16, 16, vicon_edit_draw); - def_vicon(VICON_EDITMODE_DEHLT, 16, 16, vicon_editmode_dehlt_draw); - def_vicon(VICON_EDITMODE_HLT, 16, 16, vicon_editmode_hlt_draw); - def_vicon(VICON_DISCLOSURE_TRI_RIGHT, 16, 16, vicon_disclosure_tri_right_draw); - def_vicon(VICON_DISCLOSURE_TRI_DOWN, 16, 16, vicon_disclosure_tri_down_draw); - def_vicon(VICON_MOVE_UP, 16, 16, vicon_move_up_draw); - def_vicon(VICON_MOVE_DOWN, 16, 16, vicon_move_down_draw); - def_vicon(VICON_X, 16, 16, vicon_x_draw); - - IMB_freeImBuf(bbuf); + BIF_icons_init(BIFICONID_LAST+1); } void BIF_resources_free(void) { - free_common_icons(); - - MEM_freeN(common_icons_arr); - + BIF_icons_free(); } @@ -747,6 +185,9 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) case SPACE_TIME: ts= &btheme->ttime; break; + case SPACE_NODE: + ts= &btheme->tnode; + break; default: ts= &btheme->tv3d; break; @@ -834,6 +275,17 @@ char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) case TH_SYNTAX_N: cp= ts->syntaxn; break; + case TH_NODE: + cp= ts->syntaxl; break; + case TH_NODE_IN_OUT: + cp= ts->syntaxn; break; + case TH_NODE_OPERATOR: + cp= ts->syntaxb; break; + case TH_NODE_GENERATOR: + cp= ts->syntaxv; break; + case TH_NODE_GROUP: + cp= ts->syntaxc; break; + } } @@ -1025,6 +477,16 @@ void BIF_InitTheme(void) /* space time */ btheme->ttime= btheme->tsnd; // same as sound space + + /* 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, 95, 110, 145, 255); /* in/output */ + SETCOL(btheme->tnode.syntaxb, 135, 125, 120, 255); /* operator */ + SETCOL(btheme->tnode.syntaxv, 120, 120, 120, 255); /* generator */ + SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */ + } char *BIF_ThemeColorsPup(int spacetype) @@ -1152,6 +614,16 @@ char *BIF_ThemeColorsPup(int spacetype) else if(spacetype==SPACE_TIME) { sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str); } + else if(spacetype==SPACE_NODE) { + sprintf(str, "Wires %%x%d|", TH_WIRE); strcat(cp, str); + sprintf(str, "Wires Select %%x%d|", TH_EDGE_SELECT); strcat(cp, str); + strcat(cp,"%l|"); + sprintf(str, "Node Backdrop %%x%d|", TH_NODE); strcat(cp, str); + sprintf(str, "In/Out Node %%x%d|", TH_NODE_IN_OUT); strcat(cp, str); + sprintf(str, "Generator Node %%x%d|", TH_NODE_GENERATOR); strcat(cp, str); + sprintf(str, "Operator Node %%x%d|", TH_NODE_OPERATOR); strcat(cp, str); + sprintf(str, "Group Node %%x%d|", TH_NODE_GROUP); strcat(cp, str); + } } return cp; } diff --git a/source/blender/src/screendump.c b/source/blender/src/screendump.c index ebc5bad88c6..fc17d0a5759 100644 --- a/source/blender/src/screendump.c +++ b/source/blender/src/screendump.c @@ -55,6 +55,7 @@ #include "BIF_screen.h" #include "BIF_toets.h" #include "BIF_interface.h" +#include "BIF_writeimage.h" #include "BSE_filesel.h" @@ -87,6 +88,14 @@ void write_screendump(char *name) else if(G.scene->r.imtype==R_PNG) ibuf->ftype= PNG; else if((G.have_libtiff) && (G.scene->r.imtype==R_TIFF)) ibuf->ftype= TIF; +#ifdef WITH_OPENEXR + else if(G.scene->r.imtype==R_OPENEXR) { + ibuf->ftype= OPENEXR; + if(G.scene->r.subimtype & R_OPENEXR_HALF) + ibuf->ftype |= OPENEXR_HALF; + ibuf->ftype |= (G.scene->r.quality & OPENEXR_COMPRESS); + } +#endif else if(G.scene->r.imtype==R_HAMX) ibuf->ftype= AN_hamx; else if(ELEM5(G.scene->r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { ibuf->ftype= JPG|G.scene->r.quality; diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c index dc6c10f9b17..699d442080f 100644 --- a/source/blender/src/seqaudio.c +++ b/source/blender/src/seqaudio.c @@ -82,7 +82,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" // RE_make_existing_file() void audio_fill(void *mixdown, Uint8 *sstream, int len); @@ -106,7 +105,7 @@ static void makewavstring (char *string) strcpy(string, G.scene->r.pic); BLI_convertstringcode(string, G.sce, G.scene->r.cfra); - RE_make_existing_file(string); + BLI_make_existing_file(string); if (BLI_strcasecmp(string + strlen(string) - 4, ".wav")) { sprintf(txt, "%04d_%04d.wav", (G.scene->r.sfra) , (G.scene->r.efra) ); diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 17b6e4d90b0..cc39294231f 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -34,10 +34,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #include "MEM_guardedalloc.h" #include "PIL_dynlib.h" @@ -48,6 +44,7 @@ #include "IMB_imbuf.h" #include "DNA_ipo_types.h" +#include "DNA_scene_types.h" #include "DNA_sequence_types.h" #include "DNA_view3d_types.h" @@ -69,8 +66,9 @@ #include "BSE_sequence.h" +#include "RE_pipeline.h" // talks to entire render API + #include "blendef.h" -#include "render.h" // talks to entire render API, and igamtab Sequence *seq_arr[MAXSEQ+1]; int seqrectx, seqrecty; @@ -622,15 +620,47 @@ void do_cross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1 } } +/* copied code from initrender.c */ +static unsigned short *gamtab, *igamtab1; + +static void gamtabs(float gamma) +{ + float val, igamma= 1.0f/gamma; + int a; + + gamtab= MEM_mallocN(65536*sizeof(short), "initGaus2"); + igamtab1= MEM_mallocN(256*sizeof(short), "initGaus2"); + + /* gamtab: in short, out short */ + for(a=0; a<65536; a++) { + val= a; + val/= 65535.0; + + if(gamma==2.0) val= sqrt(val); + else if(gamma!=1.0) val= pow(val, igamma); + + gamtab[a]= (65535.99*val); + } + /* inverse gamtab1 : in byte, out short */ + for(a=1; a<=256; a++) { + if(gamma==2.0) igamtab1[a-1]= a*a-1; + else if(gamma==1.0) igamtab1[a-1]= 256*a-1; + else { + val= a/256.0; + igamtab1[a-1]= (65535.0*pow(val, gamma)) -1 ; + } + } + +} + void do_gammacross_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) { - extern void init_filt_mask(void); // initrender.c, bad level call... int fac1, fac2, col; int xo; char *rt1, *rt2, *rt; - init_filt_mask(); // nasty call to render code... but it uses gamtabs here - + gamtabs(2.0f); + xo= x; rt1= (char *)rect1; rt2= (char *)rect2; @@ -673,8 +703,10 @@ void do_gammacross_effect(float facf0, float facf1, int x, int y, unsigned int * rt1+= 4; rt2+= 4; rt+= 4; } - } + + MEM_freeN(gamtab); + MEM_freeN(igamtab1); } void do_add_effect(float facf0, float facf1, int x, int y, unsigned int *rect1, unsigned int *rect2, unsigned int *out) @@ -1655,19 +1687,19 @@ void do_effect(int cfra, Sequence *seq, StripElem *se) if(cp) strncpy(cp, seq->name+2, 22); if (seq->plugin->version<=2) { - if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf->x*se1->ibuf->y, se1->ibuf->rect); - if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf->x*se2->ibuf->y, se2->ibuf->rect); - if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf->x*se3->ibuf->y, se3->ibuf->rect); + if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf); + if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf); + if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf); } ((SeqDoit)seq->plugin->doit)(seq->plugin->data, fac, facf, x, y, se1->ibuf, se2->ibuf, se->ibuf, se3->ibuf); if (seq->plugin->version<=2) { - if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf->x*se1->ibuf->y, se1->ibuf->rect); - if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf->x*se2->ibuf->y, se2->ibuf->rect); - if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf->x*se3->ibuf->y, se3->ibuf->rect); - IMB_convert_rgba_to_abgr(se->ibuf->x*se->ibuf->y, se->ibuf->rect); + if(se1->ibuf) IMB_convert_rgba_to_abgr(se1->ibuf); + if(se2->ibuf) IMB_convert_rgba_to_abgr(se2->ibuf); + if(se3->ibuf) IMB_convert_rgba_to_abgr(se3->ibuf); + IMB_convert_rgba_to_abgr(se->ibuf); } if((G.f & G_PLAYANIM)==0) waitcursor(0); @@ -1814,9 +1846,6 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) { Sequence *seq; StripElem *se; - Scene *oldsce; - unsigned int *rectot; - int oldx, oldy, oldcfra, doseq; char name[FILE_MAXDIR+FILE_MAXFILE]; if(seqar==NULL) return; @@ -1955,8 +1984,13 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) } } else if(seq->type==SEQ_SCENE && se->ibuf==0 && seq->scene) { // scene can be NULL after deletions + printf("Sorry, sequence scene is not yet back...\n"); +#if 0 View3D *vd; - int redisplay= (!G.background && !(R.flag & R_RENDERING)); + Scene *oldsce; + unsigned int *rectot; + int oldcfra, doseq; + int redisplay= (!G.background && !(G.rendering)); oldsce= G.scene; if(seq->scene!=G.scene) set_scene_bg(seq->scene); /* set_scene does full dep updates */ @@ -1972,57 +2006,57 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) waitcursor(1); - rectot= R.rectot; R.rectot= NULL; - oldx= R.rectx; oldy= R.recty; +// rectot= R.rectot; R.rectot= NULL; +// oldx= R.rectx; oldy= R.recty; /* needed because current 3D window cannot define the layers, like in a background render */ vd= G.vd; G.vd= NULL; - RE_initrender(NULL); +// RE_initrender(NULL); if (redisplay) { mainwindow_make_active(); - if(R.r.mode & R_FIELDS) update_for_newframe_muted(); - R.flag= 0; +// if(R.r.mode & R_FIELDS) update_for_newframe_muted(); +// R.flag= 0; free_filesel_spec(G.scene->r.pic); } - se->ibuf= IMB_allocImBuf(R.rectx, R.recty, 32, IB_rect, 0); - if(R.rectot) memcpy(se->ibuf->rect, R.rectot, 4*R.rectx*R.recty); - if(R.rectz) { - se->ibuf->zbuf= (int *)R.rectz; +// se->ibuf= IMB_allocImBuf(R.rectx, R.recty, 32, IB_rect, 0); +// if(R.rectot) memcpy(se->ibuf->rect, R.rectot, 4*R.rectx*R.recty); +// if(R.rectz) { +// se->ibuf->zbuf= (int *)R.rectz; /* make sure ibuf frees it */ - se->ibuf->mall |= IB_zbuf; - R.rectz= NULL; - } +// se->ibuf->mall |= IB_zbuf; +// R.rectz= NULL; +// } /* and restore */ G.vd= vd; if((G.f & G_PLAYANIM)==0) waitcursor(0); CFRA= oldcfra; - if(R.rectot) MEM_freeN(R.rectot); - R.rectot= rectot; - R.rectx=oldx; R.recty=oldy; +// if(R.rectot) MEM_freeN(R.rectot); +// R.rectot= rectot; +// R.rectx=oldx; R.recty=oldy; G.scene->r.scemode |= doseq; if(seq->scene!=oldsce) set_scene_bg(oldsce); /* set_scene does full dep updates */ /* restore!! */ - R.rectx= seqrectx; - R.recty= seqrecty; +// R.rectx= seqrectx; +// R.recty= seqrecty; /* added because this flag is checked for * movie writing when rendering an anim. * very convoluted. fix. -zr */ - R.r.imtype= G.scene->r.imtype; +// R.r.imtype= G.scene->r.imtype; +#endif } - /* size test */ if(se->ibuf) { if(se->ibuf->x != seqrectx || se->ibuf->y != seqrecty ) { - if (G.scene->r.mode & R_FIELDS) { + if (0) { //G.scene->r.mode & R_FIELDS) { if (seqrecty > 288) IMB_scalefieldImBuf(se->ibuf, (short)seqrectx, (short)seqrecty); else { @@ -2050,7 +2084,7 @@ void do_build_seqar_cfra(ListBase *seqbase, Sequence ***seqar, int cfra) } } -ImBuf *give_ibuf_seq(int cfra) +ImBuf *give_ibuf_seq(int rectx, int recty, int cfra) { Sequence **tseqar, **seqar; Sequence *seq, *seqfirst=0;/* , *effirst=0; */ @@ -2070,12 +2104,10 @@ ImBuf *give_ibuf_seq(int cfra) if(totseq==0) return 0; - seqrectx= (G.scene->r.size*G.scene->r.xsch)/100; - if(G.scene->r.mode & R_PANORAMA) seqrectx*= G.scene->r.xparts; - seqrecty= (G.scene->r.size*G.scene->r.ysch)/100; + seqrectx= rectx; /* bad bad global! */ + seqrecty= recty; - - /* tseqar is neede because in do_build_... the pointer changes */ + /* tseqar is needed because in do_build_... the pointer changes */ seqar= tseqar= MEM_callocN(sizeof(void *)*totseq, "seqar"); /* this call loads and makes the ibufs */ @@ -2236,19 +2268,17 @@ void free_imbuf_seq() END_SEQ } -void do_render_seq() +/* bad levell call... renderer makes a 32 bits rect to put result in */ +void do_render_seq(RenderResult *rr) { -/* static ImBuf *lastibuf=0; */ ImBuf *ibuf; - /* copy image into R.rectot */ - G.f |= G_PLAYANIM; /* waitcursor patch */ - ibuf= give_ibuf_seq(CFRA); - if(ibuf) { - - memcpy(R.rectot, ibuf->rect, 4*R.rectx*R.recty); + ibuf= give_ibuf_seq(rr->rectx, rr->recty, CFRA); + if(ibuf && rr->rect32) { + printf("copied\n"); + memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty); /* if (ibuf->zbuf) { */ /* if (R.rectz) freeN(R.rectz); */ diff --git a/source/blender/src/space.c b/source/blender/src/space.c index d8dcfb9b78c..4faa1a4a035 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -70,12 +70,14 @@ #include "DNA_view3d_types.h" #include "BKE_blender.h" +#include "BKE_colortools.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_main.h" +#include "BKE_node.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -89,6 +91,7 @@ #include "BIF_editarmature.h" #include "BIF_editconstraint.h" #include "BIF_editfont.h" +#include "BIF_editgroup.h" #include "BIF_editkey.h" #include "BIF_editlattice.h" #include "BIF_editmesh.h" @@ -212,6 +215,11 @@ void toggle_blockhandler(ScrArea *sa, short eventcode, short val) for(a=0; ablockhandler[a]==eventcode ) { sl->blockhandler[a]= 0; + + /* specific free calls */ + if(eventcode==VIEW3D_HANDLER_PREVIEW) + BIF_view3d_previewrender_free(sa); + addnew= 0; } } @@ -509,7 +517,7 @@ void start_game(void) static void changeview3dspace(ScrArea *sa, void *spacedata) { - setwinmatrixview3d(0); /* 0= no pick rect */ + setwinmatrixview3d(sa->winx, sa->winy, NULL); /* 0= no pick rect */ } /* Callable from editmode and faceselect mode from the @@ -580,8 +588,32 @@ static void select_parent(void) /* Makes parent active and de-selected OBACT */ } } +void select_grouped(short nr) +{ + Base *base; + + if(nr==4) { + base= FIRSTBASE; + while(base) { + if (base->lay & OBACT->lay) { + base->flag |= SELECT; + base->object->flag |= SELECT; + } + base= base->next; + } + } + else if(nr==2) select_children(OBACT, 0); + else if(nr==1) select_children(OBACT, 1); + else if(nr==3) select_parent(); + + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); +} -void select_group_menu(void) +static void select_grouped_menu(void) { char *str; short nr; @@ -598,7 +630,7 @@ void select_group_menu(void) nr= pupmenu(str); MEM_freeN(str); - select_group(nr); + select_grouped(nr); } void join_menu(void) @@ -622,36 +654,6 @@ void join_menu(void) } } -void select_group(short nr) -{ - Base *base; - - if(nr==4) { - base= FIRSTBASE; - while(base) { - if (base->lay & OBACT->lay) { - base->flag |= SELECT; - base->object->flag |= SELECT; - } - base= base->next; - } - } - else if(nr==2) select_children(OBACT, 0); - else if(nr==1) select_children(OBACT, 1); - else if(nr==3) select_parent(); - - countall(); - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allspace(REMAKEIPO, 0); - allqueue(REDRAWIPO, 0); -} - - - - - - static unsigned short convert_for_nonumpad(unsigned short event) { if (event>=ZEROKEY && event<=NINEKEY) { @@ -708,7 +710,10 @@ void BIF_undo(void) else if(curarea->spacetype==SPACE_IMAGE && (G.sima->flag & SI_DRAWTOOL)); else { /* now also in faceselect mode */ - if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(1); + if(U.uiflag & USER_GLOBALUNDO) { + BKE_undo_step(1); + sound_initialize_sounds(); + } } } } @@ -726,7 +731,10 @@ void BIF_redo(void) vpaint_undo(); else { /* includes faceselect now */ - if(U.uiflag & USER_GLOBALUNDO) BKE_undo_step(-1); + if(U.uiflag & USER_GLOBALUNDO) { + BKE_undo_step(-1); + sound_initialize_sounds(); + } } } } @@ -918,10 +926,14 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) switch(event) { + /* Afterqueue events */ case BACKBUFDRAW: backdrawview3d(1); break; - + case RENDERPREVIEW: + BIF_view3d_previewrender(sa); + break; + /* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above, * based on user preference USER_LMOUSESELECT */ @@ -1272,6 +1284,11 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) edge_flip(); else if (G.qual==0) addedgeface_mesh(); + else if ( G.qual == + (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) { + select_linked_flat_faces(); + } + } else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) addsegment_nurb(); } @@ -1291,10 +1308,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) break; case GKEY: - /* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group(); - else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */ - if((G.qual==LR_SHIFTKEY)) - select_group_menu(); + if(G.qual & LR_CTRLKEY) group_operation_with_menu(); + else if((G.qual==LR_SHIFTKEY)) + select_grouped_menu(); else if(G.qual==LR_ALTKEY) { if(okee("Clear location")) { clear_object('g'); @@ -1484,7 +1500,10 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) mirrormenu(); } else if(G.qual==0) { - movetolayer(); + if(ob && (ob->flag & OB_POSEMODE)) + pose_movetolayer(); + else + movetolayer(); } break; case NKEY: @@ -1578,7 +1597,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) else if(G.qual==LR_ALTKEY) clear_parent(); else if((G.qual==0)) { - start_game(); + toggle_blockhandler(curarea, VIEW3D_HANDLER_PREVIEW, 0); + doredraw= 1; + //start_game(); } break; case RKEY: @@ -1650,7 +1671,9 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) initTransform(TFM_TOSPHERE, CTX_NONE); Transform(); } - + if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) { + if(G.obedit->type==OB_MESH) select_sharp_edges(); + } } else if(G.qual==LR_ALTKEY) { if(G.f & G_WEIGHTPAINT) @@ -2260,7 +2283,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3) /* main choices pup */ uiDefButS(block, MENU, B_CHANGE_THEME, "UI and Buttons %x1|%l|3D View %x2|%l|Ipo Curve Editor %x3|Action Editor %x4|" - "NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Timeline %x15|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|" + "NLA Editor %x5|%l|UV/Image Editor %x6|Video Sequence Editor %x7|Node Editor %x16|Timeline %x15|Audio Window %x8|Text Editor %x9|%l|User Preferences %x10|" "Outliner %x11|Buttons Window %x12|%l|File Browser %x13|Image Browser %x14", 255,y2,200,20, &curmain, 0, 0, 0, 0, "Specify theme for..."); if(curmain==1) spacetype= 0; @@ -2278,6 +2301,7 @@ static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3) else if(curmain==13) spacetype= SPACE_FILE; else if(curmain==14) spacetype= SPACE_IMASEL; else if(curmain==15) spacetype= SPACE_TIME; + else if(curmain==16) spacetype= SPACE_NODE; else return; // only needed while coding... when adding themes for more windows /* color choices pup */ @@ -2696,10 +2720,15 @@ void drawinfospace(ScrArea *sa, void *spacedata) uiDefBut(block, LABEL,0,"Auto keyframe", (xpos+(2*edgsp)+(2*mpref)+midsp),y3label,mpref,buth, 0, 0, 0, 0, 0, ""); + uiDefButBitI(block, TOG, G_RECORDKEYS, REDRAWTIME, "Action and Object", (xpos+edgsp+(2*mpref)+(2*midsp)),y2,mpref, buth, &(G.flags), 0, 0, 0, 0, "Automatic keyframe insertion in Object and Action Ipo curves"); + uiDefButBitI(block, TOG, USER_KEYINSERTAVAI, REDRAWTIME, "Available", + (xpos+edgsp+(2*mpref)+(2*midsp)),y1,mpref, buth, + &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in available curves"); + // uiDefButBitS(block, TOG, USER_KEYINSERTACT, 0, "Action", // (xpos+edgsp+(2*mpref)+(2*midsp)),y2,(spref+edgsp),buth, // &(U.uiflag), 0, 0, 0, 0, "Automatic keyframe insertion in Action Ipo curve"); @@ -3246,7 +3275,7 @@ static void winqreadbutspace(ScrArea *sa, void *spacedata, BWinEvent *evt) scrarea_queue_winredraw(curarea); break; case RENDERPREVIEW: - BIF_previewrender(sbuts); + BIF_previewrender_buts(sbuts); break; case HOMEKEY: @@ -3331,6 +3360,8 @@ static void init_butspace(ScrArea *sa) /* set_rects only does defaults, so after reading a file the cur has not changed */ set_rects_butspace(buts); buts->v2d.cur= buts->v2d.tot; + + buts->ri = NULL; } void extern_set_butspace(int fkey) @@ -3391,11 +3422,12 @@ void extern_set_butspace(int fkey) sbuts->mainb= CONTEXT_SHADING; sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_MAT; } - + BIF_preview_changed(ID_TE); } else if(fkey==F6KEY) { sbuts->mainb= CONTEXT_SHADING; sbuts->tab[CONTEXT_SHADING]= TAB_SHADING_TEX; + BIF_preview_changed(ID_TE); } else if(fkey==F7KEY) { /* if it's already in object context, cycle between tabs with the same key */ @@ -3432,7 +3464,6 @@ void extern_set_butspace(int fkey) scrarea_queue_headredraw(sa); scrarea_queue_winredraw(sa); - BIF_preview_changed(sbuts); } /* ******************** SPACE: SEQUENCE ********************** */ @@ -3897,8 +3928,16 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) /* Draw tool is inactive */ switch(event) { case LEFTMOUSE: - if(G.qual & LR_SHIFTKEY) mouseco_to_curtile(); - else gesture(); + if(G.qual & LR_SHIFTKEY) { + if(G.sima->image && G.sima->image->tpageflag & IMA_TILES) + mouseco_to_curtile(); + else + sima_sample_color(); + } + else if(G.f & G_FACESELECT) + gesture(); + else + sima_sample_color(); break; case RIGHTMOUSE: if(G.f & G_FACESELECT) @@ -3907,8 +3946,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) sample_vpaint(); break; case AKEY: - if((G.qual==0)) - select_swap_tface_uv(); + select_swap_tface_uv(); break; case BKEY: if(G.qual==LR_SHIFTKEY) @@ -3996,6 +4034,8 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) stitch_uv_tface(0); else if(G.qual==LR_SHIFTKEY) stitch_uv_tface(1); + else if(G.qual==LR_CTRLKEY) + minimize_stretch_tface_uv(); break; case WKEY: weld_align_menu_tface_uv(); @@ -4459,6 +4499,47 @@ static void init_timespace(ScrArea *sa) } +/* ******************** SPACE: Time ********************** */ + +extern void drawnodespace(ScrArea *sa, void *spacedata); +extern void winqreadnodespace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt); + +static void init_nodespace(ScrArea *sa) +{ + SpaceNode *snode; + + snode= MEM_callocN(sizeof(SpaceNode), "init nodespace"); + BLI_addhead(&sa->spacedata, snode); + + snode->spacetype= SPACE_NODE; + snode->blockscale= 0.7; + + snode->v2d.tot.xmin= -10.0; + snode->v2d.tot.ymin= -10.0; + snode->v2d.tot.xmax= (float)sa->winx + 10.0f; + snode->v2d.tot.ymax= (float)sa->winy + 10.0f; + + snode->v2d.cur.xmin= 0.0; + snode->v2d.cur.ymin= 0.0; + snode->v2d.cur.xmax= (float)sa->winx; + snode->v2d.cur.ymax= (float)sa->winy; + + snode->v2d.min[0]= 1.0; + snode->v2d.min[1]= 1.0; + + snode->v2d.max[0]= 32000.0f; + snode->v2d.max[1]= 32000.0f; + + snode->v2d.minzoom= 0.5f; + snode->v2d.maxzoom= 1.21f; + + snode->v2d.scroll= 0; + snode->v2d.keepaspect= 1; + snode->v2d.keepzoom= 1; + snode->v2d.keeptot= 0; +} + + /* ******************** SPACE: GENERAL ********************** */ @@ -4526,6 +4607,8 @@ void newspace(ScrArea *sa, int type) init_nlaspace(sa); else if(type==SPACE_TIME) init_timespace(sa); + else if(type==SPACE_NODE) + init_nodespace(sa); sl= sa->spacedata.first; sl->area= sa; @@ -4565,11 +4648,11 @@ void newspace(ScrArea *sa, int type) } } -void freespacelist(ListBase *lb) +void freespacelist(ScrArea *sa) { SpaceLink *sl; - for (sl= lb->first; sl; sl= sl->next) { + for (sl= sa->spacedata.first; sl; sl= sl->next) { if(sl->spacetype==SPACE_FILE) { SpaceFile *sfile= (SpaceFile*) sl; if(sfile->libfiledata) @@ -4579,7 +4662,10 @@ void freespacelist(ListBase *lb) } else if(sl->spacetype==SPACE_BUTS) { SpaceButs *buts= (SpaceButs*) sl; - if(buts->rect) MEM_freeN(buts->rect); + if(buts->ri) { + if (buts->ri->rect) MEM_freeN(buts->ri->rect); + MEM_freeN(buts->ri); + } if(G.buts==buts) G.buts= NULL; } else if(sl->spacetype==SPACE_IPO) { @@ -4598,6 +4684,11 @@ void freespacelist(ListBase *lb) if(vd->localvd) MEM_freeN(vd->localvd); if(vd->clipbb) MEM_freeN(vd->clipbb); if(G.vd==vd) G.vd= NULL; + if(vd->ri) { + BIF_view3d_previewrender_free(sa); + if (vd->ri->rect) MEM_freeN(vd->ri->rect); + MEM_freeN(vd->ri); + } } else if(sl->spacetype==SPACE_OOPS) { free_oopspace((SpaceOops *)sl); @@ -4620,9 +4711,17 @@ void freespacelist(ListBase *lb) else if(sl->spacetype==SPACE_SOUND) { free_soundspace((SpaceSound *)sl); } + else if(sl->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sl; + if(sima->cumap) + curvemapping_free(sima->cumap); + } + else if(sl->spacetype==SPACE_NODE) { +/* SpaceNode *snode= (SpaceNode *)sl; */ + } } - BLI_freelistN(lb); + BLI_freelistN(&sa->spacedata); } void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) @@ -4649,7 +4748,9 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) else if(sl->spacetype==SPACE_IMASEL) { check_imasel_copy((SpaceImaSel *) sl); } - else if(sl->spacetype==SPACE_TEXT) { + else if(sl->spacetype==SPACE_NODE) { + SpaceNode *snode= (SpaceNode *)sl; + snode->nodetree= NULL; } /* __PINFAKE */ /* else if(sfile->spacetype==SPACE_ACTION) { @@ -4670,7 +4771,7 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) if(sl->spacetype==SPACE_BUTS) { SpaceButs *buts= (SpaceButs *)sl; - buts->rect= NULL; + buts->ri= NULL; } else if(sl->spacetype==SPACE_IPO) { SpaceIpo *si= (SpaceIpo *)sl; @@ -4685,6 +4786,12 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) if(vd->bgpic->ima) vd->bgpic->ima->id.us++; } vd->clipbb= MEM_dupallocN(vd->clipbb); + vd->ri= NULL; + } + else if(sl->spacetype==SPACE_IMAGE) { + SpaceImage *sima= (SpaceImage *)sl; + if(sima->cumap) + sima->cumap= curvemapping_copy(sima->cumap); } sl= sl->next; } @@ -4906,6 +5013,12 @@ void allqueue(unsigned short event, short val) scrarea_queue_winredraw(sa); } break; + case REDRAWNODE: + if(sa->spacetype==SPACE_NODE) { + scrarea_queue_headredraw(sa); + scrarea_queue_winredraw(sa); + } + break; case REDRAWANIM: if ELEM6(sa->spacetype, SPACE_IPO, SPACE_SOUND, SPACE_TIME, SPACE_NLA, SPACE_ACTION, SPACE_SEQ) { scrarea_queue_winredraw(sa); @@ -5213,3 +5326,15 @@ SpaceType *spacetime_get_type(void) return st; } + +SpaceType *spacenode_get_type(void) +{ + static SpaceType *st= NULL; + + if (!st) { + st= spacetype_new("Node"); + spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace); + } + + return st; +} diff --git a/source/blender/src/spacetypes.c b/source/blender/src/spacetypes.c index 6509aee6982..3a4c09e9e1a 100644 --- a/source/blender/src/spacetypes.c +++ b/source/blender/src/spacetypes.c @@ -96,6 +96,7 @@ static SpaceType *spacetype_from_area(ScrArea *area) case SPACE_SCRIPT: return spacescript_get_type(); case SPACE_VIEW3D: return spaceview3d_get_type(); case SPACE_TIME: return spacetime_get_type(); + case SPACE_NODE: return spacenode_get_type(); default: newspace(area, SPACE_VIEW3D); return spaceview3d_get_type(); diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index a99355359f1..0770c05cff5 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -53,6 +53,7 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" @@ -76,12 +77,14 @@ #include "BIF_interface.h" #include "BKE_object.h" #include "BIF_poseobject.h" +#include "BIF_previewrender.h" #include "BIF_renderwin.h" #include "BIF_screen.h" #include "BIF_space.h" #include "BIF_toets.h" #include "BIF_toolbox.h" #include "BIF_usiblender.h" +#include "BIF_writeimage.h" #include "BDR_vpaint.h" #include "BDR_editobject.h" @@ -96,7 +99,6 @@ #include "BSE_seqaudio.h" #include "blendef.h" -#include "render.h" // darn schrijfplaatje() (ton) #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -105,158 +107,6 @@ #include "BIF_poseobject.h" -/* only used in toets.c and initrender.c */ -/* this function doesn't really belong here */ -/* ripped from render module */ -void schrijfplaatje(char *name); - - -static void write_imag(char *name) -{ - /* from file select */ - char str[256]; - - /* addImageExtension() checks for if extension was already set */ - if(G.scene->r.scemode & R_EXTENSION) - if(strlen(name)r.cfra); - - if(saveover(str)) { - if(BLI_testextensie(str,".blend")) { - error("Wrong filename"); - return; - } - waitcursor(1); /* from screen.c */ - schrijfplaatje(str); - strcpy(G.ima, name); - waitcursor(0); - } -} - - -/* From matrix.h: it's really a [4][4]! */ -/* originally in initrender... maybe add fileControl thingy? */ - -/* should be called write_image(char *name) :-) */ -void schrijfplaatje(char *name) -{ - struct ImBuf *ibuf=0; - unsigned int *temprect=0; - char str[FILE_MAXDIR+FILE_MAXFILE]; - - /* radhdr: temporary call for direct float buffer save for HDR format */ - if ((R.r.imtype==R_RADHDR) && (R.rectftot)) - { - imb_savehdr_fromfloat(R.rectftot, name, R.rectx, R.recty); - return; - } - - /* has RGBA been set? If so: use alpha channel for color zero */ - IMB_alpha_to_col0(FALSE); - - if(R.r.planes == 32) { - /* everything with less than 50 % alpha -> col 0 */ - if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2); - /* only when 0 alpha -> col 0 */ - else IMB_alpha_to_col0(1); - } - - /* Seems to me this is also superfluous.... */ - if (R.r.imtype==R_FTYPE) { - strcpy(str, R.r.ftype); - BLI_convertstringcode(str, G.sce, G.scene->r.cfra); - - ibuf = IMB_loadiffname(str, IB_test); - if(ibuf) { - ibuf->x = R.rectx; - ibuf->y = R.recty; - } - else { - error("Can't find filetype"); - G.afbreek= 1; - return; - } - /* setdither(2); */ - } - - if(ibuf == 0) { - ibuf= IMB_allocImBuf(R.rectx, R.recty, (char) R.r.planes, 0, 0); - } - - if(ibuf) { - ibuf->rect= (unsigned int *) R.rectot; -// ibuf->rect_float = R.rectftot; - - if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw); - - if(R.r.imtype== R_IRIS) { - ibuf->ftype= IMAGIC; - } - else if(R.r.imtype==R_IRIZ) { - ibuf->ftype= IMAGIC; - if (ibuf->zbuf == 0) { - if (R.rectz) { - ibuf->zbuf = (int *)R.rectz; - } - else printf("no zbuf\n"); - } - } - else if(R.r.imtype==R_RADHDR) { - /* radhdr: save hdr from rgba buffer, not really recommended, probably mistake, so warn user */ - error("Will save, but you might want to enable the floatbuffer to save a real HDRI..."); - ibuf->ftype= RADHDR; - } - else if(R.r.imtype==R_PNG) { - ibuf->ftype= PNG; - } - else if(R.r.imtype==R_BMP) { - ibuf->ftype= BMP; - } - else if((G.have_libtiff) && (R.r.imtype==R_TIFF)) { - ibuf->ftype= TIF; - } - else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) { - ibuf->ftype= TGA; - } - else if(R.r.imtype==R_RAWTGA) { - ibuf->ftype= RAWTGA; - } - else if(R.r.imtype==R_HAMX) { - /* make copy */ - temprect= MEM_dupallocN(R.rectot); - ibuf->ftype= AN_hamx; - } - else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) { - if(R.r.quality < 10) R.r.quality= 90; - - if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality; - else ibuf->ftype= JPG|R.r.quality; - } - - RE_make_existing_file(name); - - if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) { - perror(name); - G.afbreek= 1; - } - - IMB_freeImBuf(ibuf); - - if (R.r.imtype==R_HAMX) { - MEM_freeN(R.rectot); - R.rectot= temprect; - } - } - else { - G.afbreek= 1; - } -} - - - /* ------------------------------------------------------------------------- */ static int is_an_active_object(void *ob) { @@ -274,6 +124,7 @@ void persptoetsen(unsigned short event) static Object *oldcamera=0; float phi, si, q1[4], vec[3]; static int perspo=1; + int preview3d_event= 1; if(event==PADENTER) { if (G.qual == LR_SHIFTKEY) { @@ -320,15 +171,15 @@ void persptoetsen(unsigned short event) else if(event==PADMINUS) { /* this min and max is also in viewmove() */ if(G.vd->persp==2) { - G.vd->camzoom-= 10; - if(G.vd->camzoom<-30) G.vd->camzoom= -30; - } + G.vd->camzoom-= 10; + if(G.vd->camzoom<-30) G.vd->camzoom= -30; + } else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; } else if(event==PADPLUSKEY) { if(G.vd->persp==2) { - G.vd->camzoom+= 10; - if(G.vd->camzoom>300) G.vd->camzoom= 300; + G.vd->camzoom+= 10; + if(G.vd->camzoom>300) G.vd->camzoom= 300; } else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; } @@ -380,12 +231,14 @@ void persptoetsen(unsigned short event) G.vd->camzoom= MAX2(-30, G.vd->camzoom-5); } else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f; + if(G.vd->persp!=1) preview3d_event= 0; } else if(event==PADPLUSKEY) { if(G.vd->persp==2) { G.vd->camzoom= MIN2(300, G.vd->camzoom+5); } else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f; + if(G.vd->persp!=1) preview3d_event= 0; } else if(event==PAD5) { if(G.vd->persp==1) G.vd->persp=0; @@ -468,6 +321,12 @@ void persptoetsen(unsigned short event) if(G.vd->persp<2) perspo= G.vd->persp; } + + if(preview3d_event) + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); + else + BIF_view3d_previewrender_signal(curarea, PR_PROJECTED); + scrarea_queue_redraw(curarea); } @@ -487,62 +346,6 @@ int untitled(char * name) return(FALSE); } -int save_image_filesel_str(char *str) -{ - switch(G.scene->r.imtype) { - case R_RADHDR: - strcpy(str, "Save Radiance HDR"); return 1; - case R_PNG: - strcpy(str, "Save PNG"); return 1; - case R_BMP: - strcpy(str, "Save BMP"); return 1; - case R_TIFF: - if (G.have_libtiff) { - strcpy(str, "Save TIFF"); return 1; - } - case R_TARGA: - strcpy(str, "Save Targa"); return 1; - case R_RAWTGA: - strcpy(str, "Save Raw Targa"); return 1; - case R_IRIS: - strcpy(str, "Save IRIS"); return 1; - case R_IRIZ: - strcpy(str, "Save IRIS"); return 1; - case R_HAMX: - strcpy(str, "Save HAMX"); return 1; - case R_FTYPE: - strcpy(str, "Save Ftype"); return 1; - case R_JPEG90: - strcpy(str, "Save JPEG"); return 1; - default: - strcpy(str, "Save Image"); return 0; - } -} - -void BIF_save_rendered_image(void) -{ - if(!R.rectot) { - error("No image rendered"); - } else { - char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2]; - - if(G.ima[0]==0) { - strcpy(dir, G.sce); - BLI_splitdirstring(dir, str); - strcpy(G.ima, dir); - } - - R.r.imtype= G.scene->r.imtype; - R.r.quality= G.scene->r.quality; - R.r.planes= G.scene->r.planes; - - if (!save_image_filesel_str(str)) { - error("Select an image type in DisplayButtons(F10)"); - } else { - activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag); - } - } -} int blenderqread(unsigned short event, short val) { @@ -600,7 +403,7 @@ int blenderqread(unsigned short event, short val) break; case F3KEY: if(G.qual==0) { - BIF_save_rendered_image(); + BIF_save_rendered_image_fs(); return 0; } else if(G.qual & LR_CTRLKEY) { @@ -799,6 +602,8 @@ int blenderqread(unsigned short event, short val) set_editflag_editipo(); else if(curarea->spacetype==SPACE_SEQ) enter_meta(); + else if(curarea->spacetype==SPACE_NODE) + return 1; else if(G.vd) { /* also when Alt-E */ if(G.obedit==NULL) { @@ -879,10 +684,10 @@ int blenderqread(unsigned short event, short val) break; case JKEY: if(textediting==0 && textspace==0) { - if(R.rectot && G.qual==0) { +// if(R.rectot && G.qual==0) { BIF_swap_render_rects(); return 0; - } +// } } break; @@ -983,7 +788,8 @@ int blenderqread(unsigned short event, short val) screen_swapbuffers(); } else if(event==3) { - BKE_write_undo("10 timer"); + BIF_undo(); + BIF_redo(); } } @@ -991,8 +797,7 @@ int blenderqread(unsigned short event, short val) if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time); if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time); - if(event==3) sprintf(tmpstr, "displist %%t|%d ms", time); - if(event==4) sprintf(tmpstr, "undo %%t|%d ms", time); + if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time); waitcursor(0); pupmenu(tmpstr); diff --git a/source/blender/src/toolbox.c b/source/blender/src/toolbox.c index 973a01d9187..88ad8ae4e3e 100644 --- a/source/blender/src/toolbox.c +++ b/source/blender/src/toolbox.c @@ -55,10 +55,11 @@ #include "BIF_language.h" #include "BIF_resources.h" +#include "DNA_group_types.h" #include "DNA_image_types.h" -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" #include "DNA_lamp_types.h" +#include "DNA_mesh_types.h" +#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" @@ -67,13 +68,14 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BKE_displist.h" #include "BKE_depsgraph.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_mesh.h" +#include "BKE_main.h" #include "BKE_plugin_types.h" #include "BKE_utildefines.h" -#include "BKE_mesh.h" -#include "BKE_displist.h" -#include "BKE_global.h" -#include "BKE_main.h" #include "BIF_editnla.h" #include "BIF_editarmature.h" @@ -103,7 +105,6 @@ #include "BDR_editmball.h" #include "BSE_editipo.h" -#include "BSE_buttons.h" #include "BSE_filesel.h" #include "BSE_edit.h" #include "BSE_headerbuttons.h" @@ -112,7 +113,6 @@ #include "mydevice.h" #include "blendef.h" -#include "render.h" // R.flag static int tbx1, tbx2, tby1, tby2, tbfontyofs, tbmain=0; static int tbmemx=TBOXX/2, tbmemy=(TBOXEL-0.5)*TBOXH, tboldwin, addmode= 0; @@ -1101,7 +1101,7 @@ void error(char *fmt, ...) sprintf(nfmt, "%s", fmt); va_start(ap, fmt); - if (G.background || !G.curscreen || (R.flag & R_RENDERING)) { + if (G.background || !G.curscreen || (G.rendering)) { vprintf(nfmt, ap); printf("\n"); } else { @@ -1274,6 +1274,55 @@ int movetolayer_buts(unsigned int *lay) return 0; } +int movetolayer_short_buts(short *lay) +{ + uiBlock *block; + ListBase listb={0, 0}; + int dx, dy, a, x1, y1, sizex=120, sizey=30; + short pivot[2], mval[2], ret=0; + + getmouseco_sc(mval); + + pivot[0]= CLAMPIS(mval[0], (sizex+10), G.curscreen->sizex-30); + pivot[1]= CLAMPIS(mval[1], (sizey/2)+10, G.curscreen->sizey-(sizey/2)-10); + + if (pivot[0]!=mval[0] || pivot[1]!=mval[1]) + warp_pointer(pivot[0], pivot[1]); + + mywinset(G.curscreen->mainwin); + + x1= pivot[0]-sizex+10; + y1= pivot[1]-sizey/2; + + block= uiNewBlock(&listb, "button", UI_EMBOSS, UI_HELV, G.curscreen->mainwin); + uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT|UI_BLOCK_ENTER_OK); + + dx= (sizex-5)/10; + dy= sizey/2; + + /* buttons have 0 as return event, to prevent menu to close on hotkeys */ + + uiBlockBeginAlign(block); + for(a=0; a<8; a++) + uiDefButBitS(block, TOGR, 1<spacetype==SPACE_IMASEL) { clever_numbuts_imasel(); } - else if(curarea->spacetype==SPACE_BUTS){ - clever_numbuts_buts(); - } else if(curarea->spacetype==SPACE_OOPS) { clever_numbuts_oops(); } @@ -1681,6 +1727,8 @@ static TBitem tb_mesh_select[]= { { 0, "SEPR", 0, NULL}, { 0, "Random...", 5, NULL}, { 0, "Non-Manifold|Shift Ctrl Alt M", 9, NULL}, +{ 0, "Sharp Edges|Shift Ctrl Alt S", 14, NULL}, +{ 0, "Linked Flat Faces|Shift Ctrl Alt F", 15, NULL}, { 0, "Triangles|Shift Ctrl Alt 3", 11, NULL}, { 0, "Quads|Shift Ctrl Alt 4", 12, NULL}, { 0, "Non-Triangles/Quads|Shift Ctrl Alt 5", 13, NULL}, @@ -2220,6 +2268,10 @@ static TBitem addmenu_armature[]= { { 0, "Bone", 8, NULL}, { -1, "", 0, do_info_addmenu}}; +/* dynamic items */ +#define TB_ADD_GROUP 7 +#define TB_ADD_LAMP 10 + static TBitem tb_add[]= { { 0, "Mesh", 0, addmenu_mesh}, { 0, "Curve", 1, addmenu_curve}, @@ -2228,6 +2280,8 @@ static TBitem tb_add[]= { { 0, "Text", 4, NULL}, { 0, "Empty", 5, NULL}, { 0, "SEPR", 0, NULL}, +{ 0, "Group", 10, NULL}, +{ 0, "SEPR", 0, NULL}, { 0, "Camera", 6, NULL}, { 0, "Lamp", 7, addmenu_lamp}, { 0, "SEPR", 0, NULL}, @@ -2235,21 +2289,6 @@ static TBitem tb_add[]= { { 0, "Lattice", 9, NULL}, { -1, "", 0, do_info_addmenu}}; -static TBitem tb_add_YF[]= { -{ 0, "Mesh", 0, addmenu_mesh}, -{ 0, "Curve", 1, addmenu_curve}, -{ 0, "Surface", 2, addmenu_surf}, -{ 0, "Meta", 3, addmenu_meta}, -{ 0, "Text", 4, NULL}, -{ 0, "Empty", 5, NULL}, -{ 0, "SEPR", 0, NULL}, -{ 0, "Camera", 6, NULL}, -{ 0, "Lamp", 7, addmenu_YF_lamp}, -{ 0, "SEPR", 0, NULL}, -{ 0, "Armature", 8, NULL}, -{ 0, "Lattice", 9, NULL}, -{ -1, "", 0, do_info_addmenu}}; - static TBitem tb_empty[]= { { 0, "Nothing...", 0, NULL}, { -1, "", 0, NULL}}; @@ -2340,13 +2379,58 @@ static void store_main(void *arg1, void *arg2) tb_mainy= (int)arg2; } +static void do_group_addmenu(void *arg, int event) +{ + Object *ob; + + add_object_draw(OB_EMPTY); + ob= OBACT; + + ob->dup_group= BLI_findlink(&G.main->group, event); + if(ob->dup_group) { + id_us_plus((ID *)ob->dup_group); + ob->transflag |= OB_DUPLIGROUP; + DAG_scene_sort(G.scene); + } +} + +/* example of dynamic toolbox sublevel */ +static TBitem *create_group_sublevel(void) +{ + static TBitem addmenu[]= { { 0, "No Groups", 0, NULL}, { -1, "", 0, NULL}}; + TBitem *groupmenu; + Group *group; + int a; + + int tot= BLI_countlist(&G.main->group); + + if(tot==0) { + tb_add[TB_ADD_GROUP].poin= addmenu; + return NULL; + } + + groupmenu= MEM_callocN(sizeof(TBitem)*(tot+1), "group menu"); + for(a=0, group= G.main->group.first; group; group= group->id.next, a++) { + groupmenu[a].name= group->id.name+2; + groupmenu[a].retval= a; + } + groupmenu[a].icon= -1; /* end signal */ + groupmenu[a].name= ""; + groupmenu[a].retval= a; + groupmenu[a].poin= do_group_addmenu; + + tb_add[TB_ADD_GROUP].poin= groupmenu; + + return groupmenu; +} + void toolbox_n(void) { uiBlock *block; uiBut *but; TBitem *menu1=NULL, *menu2=NULL, *menu3=NULL; TBitem *menu4=NULL, *menu5=NULL, *menu6=NULL; - TBitem *menu7=NULL; + TBitem *menu7=NULL, *groupmenu; int dx=0; short event, mval[2], tot=0; char *str1=NULL, *str2=NULL, *str3=NULL, *str4=NULL, *str5=NULL, *str6=NULL, *str7=NULL; @@ -2368,16 +2452,19 @@ void toolbox_n(void) uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1); uiBlockSetCol(block, TH_MENU_ITEM); + /* dynamic menu entries */ + groupmenu= create_group_sublevel(); + + if (G.scene->r.renderer==R_YAFRAY) + tb_add[TB_ADD_LAMP].poin= addmenu_YF_lamp; + else + tb_add[TB_ADD_LAMP].poin= addmenu_lamp; + /* select context for main items */ if(curarea->spacetype==SPACE_VIEW3D) { if(U.uiflag & USER_PLAINMENUS) { - /* column layout menu */ - if (G.scene->r.renderer==R_YAFRAY) { - menu1= tb_add_YF; str1= "Add"; - } else { - menu1= tb_add; str1= "Add"; - } + menu1= tb_add; str1= "Add"; menu2= tb_object_edit; str2= "Edit"; menu3= tb_object_select; str3= "Select"; menu4= tb_transform; str4= "Transform"; @@ -2390,11 +2477,7 @@ void toolbox_n(void) } else { /* 3x2 layout menu */ menu1= tb_object; str1= "Object"; - if (G.scene->r.renderer==R_YAFRAY) { - menu2= tb_add_YF; str2= "Add"; - } else { - menu2= tb_add; str2= "Add"; - } + menu2= tb_add; str2= "Add"; menu3= tb_object_select; str3= "Select"; menu4= tb_object_edit; str4= "Edit"; menu5= tb_transform; str5= "Transform"; @@ -2578,6 +2661,8 @@ void toolbox_n(void) uiBoundsBlock(block, 2); event= uiDoBlocks(&tb_listb, 0); + if(groupmenu) MEM_freeN(groupmenu); + mywinset(curarea->win); } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 65bf0a597ba..7e085389b8c 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -100,6 +100,7 @@ #include "BIF_editsima.h" #include "BIF_gl.h" #include "BIF_poseobject.h" +#include "BIF_meshtools.h" #include "BIF_mywindow.h" #include "BIF_resources.h" #include "BIF_screen.h" @@ -112,6 +113,7 @@ #include "BSE_editipo_types.h" #include "BDR_editobject.h" // reset_slowparents() +#include "BDR_unwrapper.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -371,31 +373,6 @@ static void createTransEdge(TransInfo *t) { /* ********************* pose mode ************* */ -/* recursive, make sure it's identical structured as next one */ -/* only counts the parent selection, and tags transform flag */ -/* exported for manipulator */ -void count_bone_select(TransInfo *t, ListBase *lb, int do_it) -{ - Bone *bone; - int do_next; - - for(bone= lb->first; bone; bone= bone->next) { - bone->flag &= ~BONE_TRANSFORM; - do_next= do_it; - if(do_it) { - if (bone->flag & BONE_SELECTED) { - /* We don't let connected children get "grabbed" */ - if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) { - bone->flag |= BONE_TRANSFORM; - t->total++; - do_next= 0; // no transform on children if one parent bone is selected - } - } - } - count_bone_select(t, &bone->childbase, do_next); - } -} - static bKinematicConstraint *has_targetless_ik(bPoseChannel *pchan) { bConstraint *con= pchan->constraints.first; @@ -615,6 +592,7 @@ static void bone_children_clear_transflag(ListBase *lb) /* sets transform flags in the bones, returns total */ static void set_pose_transflags(TransInfo *t, Object *ob) { + bArmature *arm= ob->data; bPoseChannel *pchan; Bone *bone; @@ -622,10 +600,12 @@ static void set_pose_transflags(TransInfo *t, Object *ob) for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { bone= pchan->bone; - if(bone->flag & BONE_SELECTED) - bone->flag |= BONE_TRANSFORM; - else - bone->flag &= ~BONE_TRANSFORM; + if(bone->layer & arm->layer) { + if(bone->flag & BONE_SELECTED) + bone->flag |= BONE_TRANSFORM; + else + bone->flag &= ~BONE_TRANSFORM; + } } /* make sure no bone can be transformed when a parent is transformed */ @@ -734,6 +714,7 @@ static void pose_grab_with_ik_children(bPose *pose, Bone *bone) /* main call which adds temporal IK chains */ static void pose_grab_with_ik(Object *ob) { + bArmature *arm= ob->data; bPoseChannel *pchan, *pchansel= NULL; if(ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0) @@ -741,10 +722,12 @@ static void pose_grab_with_ik(Object *ob) /* rule: only one Bone */ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & BONE_SELECTED) { - if(pchansel) - break; - pchansel= pchan; + if(pchan->bone->layer & arm->layer) { + if(pchan->bone->flag & BONE_SELECTED) { + if(pchansel) + break; + pchansel= pchan; + } } } if(pchan || pchansel==NULL) return; @@ -834,15 +817,17 @@ static void createTransArmatureVerts(TransInfo *t) t->total = 0; for (ebo=G.edbo.first;ebo;ebo=ebo->next) { - if (t->mode==TFM_BONESIZE) { - if (ebo->flag & BONE_SELECTED) - t->total++; - } - else { - if (ebo->flag & BONE_TIPSEL) - t->total++; - if (ebo->flag & BONE_ROOTSEL) - t->total++; + if(ebo->layer & arm->layer) { + if (t->mode==TFM_BONESIZE) { + if (ebo->flag & BONE_SELECTED) + t->total++; + } + else { + if (ebo->flag & BONE_TIPSEL) + t->total++; + if (ebo->flag & BONE_ROOTSEL) + t->total++; + } } } @@ -854,105 +839,106 @@ static void createTransArmatureVerts(TransInfo *t) td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone"); for (ebo=G.edbo.first;ebo;ebo=ebo->next){ - ebo->oldlength= ebo->length; // length==0.0 on extrude, used for scaling radius of bone points - if (t->mode==TFM_BONE_ENVELOPE) { - - if (ebo->flag & BONE_ROOTSEL){ - td->val= &ebo->rad_head; - td->ival= *td->val; + if(ebo->layer & arm->layer) { + if (t->mode==TFM_BONE_ENVELOPE) { - VECCOPY (td->center, ebo->head); - td->flag= TD_SELECTED; - - Mat3CpyMat3(td->smtx, smtx); - Mat3CpyMat3(td->mtx, mtx); - - td->loc = NULL; - td->ext = NULL; - td->tdi = NULL; - - td++; - } - if (ebo->flag & BONE_TIPSEL){ - td->val= &ebo->rad_tail; - td->ival= *td->val; - VECCOPY (td->center, ebo->tail); - td->flag= TD_SELECTED; - - Mat3CpyMat3(td->smtx, smtx); - Mat3CpyMat3(td->mtx, mtx); - - td->loc = NULL; - td->ext = NULL; - td->tdi = NULL; - - td++; - } - - } - else if (t->mode==TFM_BONESIZE) { - if (ebo->flag & BONE_SELECTED) { - if(arm->drawtype==ARM_ENVELOPE) { - td->loc= NULL; - td->val= &ebo->dist; - td->ival= ebo->dist; + if (ebo->flag & BONE_ROOTSEL){ + td->val= &ebo->rad_head; + td->ival= *td->val; + + VECCOPY (td->center, ebo->head); + td->flag= TD_SELECTED; + + Mat3CpyMat3(td->smtx, smtx); + Mat3CpyMat3(td->mtx, mtx); + + td->loc = NULL; + td->ext = NULL; + td->tdi = NULL; + + td++; } - else { - // abusive storage of scale in the loc pointer :) - td->loc= &ebo->xwidth; - VECCOPY (td->iloc, td->loc); - td->val= NULL; + if (ebo->flag & BONE_TIPSEL){ + td->val= &ebo->rad_tail; + td->ival= *td->val; + VECCOPY (td->center, ebo->tail); + td->flag= TD_SELECTED; + + Mat3CpyMat3(td->smtx, smtx); + Mat3CpyMat3(td->mtx, mtx); + + td->loc = NULL; + td->ext = NULL; + td->tdi = NULL; + + td++; } - VECCOPY (td->center, ebo->head); - td->flag= TD_SELECTED; - /* use local bone matrix */ - VecSubf(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, bonemat); - Mat3MulMat3(td->mtx, mtx, bonemat); - Mat3Inv(td->smtx, td->mtx); - - Mat3CpyMat3(td->axismtx, td->mtx); - Mat3Ortho(td->axismtx); - - td->ext = NULL; - td->tdi = NULL; - - td++; } - } - else { - if (ebo->flag & BONE_TIPSEL){ - VECCOPY (td->iloc, ebo->tail); - VECCOPY (td->center, td->iloc); - td->loc= ebo->tail; - td->flag= TD_SELECTED; + else if (t->mode==TFM_BONESIZE) { + if (ebo->flag & BONE_SELECTED) { + if(arm->drawtype==ARM_ENVELOPE) { + td->loc= NULL; + td->val= &ebo->dist; + td->ival= ebo->dist; + } + else { + // abusive storage of scale in the loc pointer :) + td->loc= &ebo->xwidth; + VECCOPY (td->iloc, td->loc); + td->val= NULL; + } + VECCOPY (td->center, ebo->head); + td->flag= TD_SELECTED; + + /* use local bone matrix */ + VecSubf(delta, ebo->tail, ebo->head); + vec_roll_to_mat3(delta, ebo->roll, bonemat); + Mat3MulMat3(td->mtx, mtx, bonemat); + Mat3Inv(td->smtx, td->mtx); + + Mat3CpyMat3(td->axismtx, td->mtx); + Mat3Ortho(td->axismtx); - Mat3CpyMat3(td->smtx, smtx); - Mat3CpyMat3(td->mtx, mtx); - - td->ext = NULL; - td->tdi = NULL; - td->val = NULL; - - td++; + td->ext = NULL; + td->tdi = NULL; + + td++; + } } - if (ebo->flag & BONE_ROOTSEL){ - VECCOPY (td->iloc, ebo->head); - VECCOPY (td->center, td->iloc); - td->loc= ebo->head; - td->flag= TD_SELECTED; + else { + if (ebo->flag & BONE_TIPSEL){ + VECCOPY (td->iloc, ebo->tail); + VECCOPY (td->center, td->iloc); + td->loc= ebo->tail; + td->flag= TD_SELECTED; - Mat3CpyMat3(td->smtx, smtx); - Mat3CpyMat3(td->mtx, mtx); + Mat3CpyMat3(td->smtx, smtx); + Mat3CpyMat3(td->mtx, mtx); - td->ext = NULL; - td->tdi = NULL; - td->val = NULL; + td->ext = NULL; + td->tdi = NULL; + td->val = NULL; - td++; + td++; + } + if (ebo->flag & BONE_ROOTSEL){ + VECCOPY (td->iloc, ebo->head); + VECCOPY (td->center, td->iloc); + td->loc= ebo->head; + td->flag= TD_SELECTED; + + Mat3CpyMat3(td->smtx, smtx); + Mat3CpyMat3(td->mtx, mtx); + + td->ext = NULL; + td->tdi = NULL; + td->val = NULL; + + td++; + } } } } @@ -1282,8 +1268,8 @@ static void createTransLatticeVerts(TransInfo *t) /* ********************* mesh ****************** */ /* proportional distance based on connectivity */ -#define E_VEC(a) (vectors + (3 * (int)(a)->vn)) -#define E_NEAR(a) (nears[((int)(a)->vn)]) +#define E_VEC(a) (vectors + (3 * (a)->tmp.l)) +#define E_NEAR(a) (nears[((a)->tmp.l)]) static void editmesh_set_connectivity_distance(int total, float *vectors, EditVert **nears) { EditMesh *em = G.editMesh; @@ -1292,10 +1278,10 @@ static void editmesh_set_connectivity_distance(int total, float *vectors, EditVe int i= 0, done= 1; /* f2 flag is used for 'selection' */ - /* vn is offset on scratch array */ + /* tmp.l is offset on scratch array */ for(eve= em->verts.first; eve; eve= eve->next) { if(eve->h==0) { - eve->vn = (EditVert *)(i++); + eve->tmp.l = i++; if(eve->f & SELECT) { eve->f2= 2; @@ -1409,6 +1395,7 @@ static void VertsToTransData(TransData *td, EditVert *eve) td->ext = NULL; td->tdi = NULL; td->val = NULL; + td->tdmir= NULL; } /* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */ @@ -1503,7 +1490,7 @@ static void set_crazyspace_quats(float *mappedcos, float *quats) /* two abused locations in vertices */ for(eve= em->verts.first; eve; eve= eve->next, index++) { - eve->vn= NULL; + eve->tmp.fp = NULL; eve->prev= (EditVert *)index; } @@ -1515,40 +1502,40 @@ static void set_crazyspace_quats(float *mappedcos, float *quats) v2= mappedcos + 3*( (int)(efa->v2->prev) ); v3= mappedcos + 3*( (int)(efa->v3->prev) ); - if(efa->v2->vn==NULL && efa->v2->f1) { + if(efa->v2->tmp.fp==NULL && efa->v2->f1) { set_crazy_vertex_quat(quats, efa->v2->co, efa->v3->co, efa->v1->co, v2, v3, v1); - efa->v2->vn= (EditVert *)(quats); + efa->v2->tmp.fp= quats; quats+= 4; } if(efa->v4) { v4= mappedcos + 3*( (int)(efa->v4->prev) ); - if(efa->v1->vn==NULL && efa->v1->f1) { + if(efa->v1->tmp.fp==NULL && efa->v1->f1) { set_crazy_vertex_quat(quats, efa->v1->co, efa->v2->co, efa->v4->co, v1, v2, v4); - efa->v1->vn= (EditVert *)(quats); + efa->v1->tmp.fp= quats; quats+= 4; } - if(efa->v3->vn==NULL && efa->v3->f1) { + if(efa->v3->tmp.fp==NULL && efa->v3->f1) { set_crazy_vertex_quat(quats, efa->v3->co, efa->v4->co, efa->v2->co, v3, v4, v2); - efa->v3->vn= (EditVert *)(quats); + efa->v3->tmp.fp= quats; quats+= 4; } - if(efa->v4->vn==NULL && efa->v4->f1) { + if(efa->v4->tmp.fp==NULL && efa->v4->f1) { set_crazy_vertex_quat(quats, efa->v4->co, efa->v1->co, efa->v3->co, v4, v1, v3); - efa->v4->vn= (EditVert *)(quats); + efa->v4->tmp.fp= quats; quats+= 4; } } else { - if(efa->v1->vn==NULL && efa->v1->f1) { + if(efa->v1->tmp.fp==NULL && efa->v1->f1) { set_crazy_vertex_quat(quats, efa->v1->co, efa->v2->co, efa->v3->co, v1, v2, v3); - efa->v1->vn= (EditVert *)(quats); + efa->v1->tmp.fp= quats; quats+= 4; } - if(efa->v3->vn==NULL && efa->v3->f1) { + if(efa->v3->tmp.fp==NULL && efa->v3->f1) { set_crazy_vertex_quat(quats, efa->v3->co, efa->v1->co, efa->v2->co, v3, v1, v2); - efa->v3->vn= (EditVert *)(quats); + efa->v3->tmp.fp= quats; quats+= 4; } } @@ -1570,7 +1557,8 @@ static void createTransEditVerts(TransInfo *t) float mtx[3][3], smtx[3][3]; int count=0, countsel=0; int propmode = t->flag & T_PROP_EDIT; - + int mirror= (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR); + // transform now requires awareness for select mode, so we tag the f1 flags in verts if(G.scene->selectmode & SCE_SELECT_VERTEX) { for(eve= em->verts.first; eve; eve= eve->next) { @@ -1637,6 +1625,17 @@ static void createTransEditVerts(TransInfo *t) } } + /* find out which half we do */ + if(mirror) { + 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) + mirror = -1; + break; + } + } + } + for (eve=em->verts.first; eve; eve=eve->next) { if(eve->h==0) { if(propmode || eve->f1) { @@ -1657,10 +1656,10 @@ static void createTransEditVerts(TransInfo *t) } /* CrazySpace */ - if(quats && eve->vn) { + if(quats && eve->tmp.fp) { float mat[3][3], imat[3][3], qmat[3][3]; - QuatToMat3((float *)eve->vn, qmat); + QuatToMat3(eve->tmp.fp, qmat); Mat3MulMat3(mat, mtx, qmat); Mat3Inv(imat, mat); @@ -1671,6 +1670,12 @@ static void createTransEditVerts(TransInfo *t) Mat3CpyMat3(tob->smtx, smtx); Mat3CpyMat3(tob->mtx, mtx); } + + /* Mirror? */ + if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) { + EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc); /* initializes octree on first call */ + if(vmir!=eve) tob->tdmir= vmir; + } tob++; } } @@ -1780,6 +1785,9 @@ static void createTransUVs(TransInfo *t) UVsToTransData(td++, td2d++, tf->uv[3], (tf->flag & TF_SEL4)); } } + + if (G.sima->flag & SI_LSCM_LIVE) + unwrap_lscm_live_begin(); } void flushTransUVs(TransInfo *t) @@ -2086,12 +2094,16 @@ void special_aftertrans_update(TransInfo *t) { Object *ob; Base *base; + IpoCurve *icu; int redrawipo=0; int cancelled= (t->state == TRANS_CANCEL); if(G.obedit) { if(t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE) allqueue(REDRAWBUTSEDIT, 0); + + /* table needs to be created for each edit command, since vertices can move etc */ + mesh_octree_table(G.obedit, NULL, 'e'); } else if( (t->flag & T_POSE) && t->poseobj) { bArmature *arm; @@ -2129,19 +2141,36 @@ void special_aftertrans_update(TransInfo *t) for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){ if (pchan->bone->flag & BONE_TRANSFORM){ - - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z); - - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z); - - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y); - insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z); + + if(U.uiflag & USER_KEYINSERTAVAI) { + bActionChannel *achan; + + for (achan = act->chanbase.first; achan; achan=achan->next){ + + if (achan->ipo && !strcmp (achan->name, pchan->name)){ + for (icu = achan->ipo->curve.first; icu; icu=icu->next){ + insertkey(&ob->id, ID_PO, pchan->name, NULL, icu->adrcode); + } + + break; + } + } + } + else{ + + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_X); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Y); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_SIZE_Z); + + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_W); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_X); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Y); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_QUAT_Z); + + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_X); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Y); + insertkey(&ob->id, ID_PO, pchan->name, NULL, AC_LOC_Z); + } } } @@ -2150,6 +2179,7 @@ void special_aftertrans_update(TransInfo *t) allqueue(REDRAWACTION, 0); allqueue(REDRAWIPO, 0); allqueue(REDRAWNLA, 0); + allqueue(REDRAWTIME, 0); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } @@ -2178,27 +2208,42 @@ void special_aftertrans_update(TransInfo *t) /* Set autokey if necessary */ if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){ char *actname=""; - + if(ob->ipoflag & OB_ACTION_OB) actname= "Object"; - - insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z); - - insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z); - - insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y); - insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z); - + + if(U.uiflag & USER_KEYINSERTAVAI) { + if(base->object->ipo) { + ID* id= (ID *)(base->object); + icu= base->object->ipo->curve.first; + while(icu) { + icu->flag &= ~IPO_SELECT; + insertkey(id, ID_OB, actname, NULL, icu->adrcode); + icu= icu->next; + } + } + } + else { + + insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_X); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Y); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_ROT_Z); + + insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_X); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Y); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_LOC_Z); + + insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_X); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Y); + insertkey(&base->object->id, ID_OB, actname, NULL, OB_SIZE_Z); + } + remake_object_ipos (ob); allqueue(REDRAWIPO, 0); allspace(REMAKEIPO, 0); allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWNLA, 0); + allqueue(REDRAWTIME, 0); } base= base->next; @@ -2433,5 +2478,8 @@ void createTransData(TransInfo *t) if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) { t->flag |= T_CAMERA; } + + /* temporal...? */ + G.scene->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */ } diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 7be86bd34b3..71ccfd4acea 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -57,6 +57,7 @@ #include "BIF_editarmature.h" #include "BIF_editmesh.h" #include "BIF_editsima.h" +#include "BIF_meshtools.h" #include "BKE_action.h" #include "BKE_anim.h" @@ -78,6 +79,7 @@ #include "BLI_arithb.h" #include "BLI_blenlib.h" +#include "BLI_editVert.h" #include "blendef.h" @@ -174,6 +176,28 @@ static void clipMirrorModifier(TransInfo *t, Object *ob) } } +/* assumes G.obedit set to mesh object */ +static void editmesh_apply_to_mirror(TransInfo *t) +{ + TransData *td = t->data; + EditVert *eve; + int i; + + for(i = 0 ; i < t->total; i++, td++) { + if (td->flag & TD_NOACTION) + break; + if (td->loc==NULL) + break; + + eve= td->tdmir; + if(eve) { + eve->co[0]= -td->loc[0]; + eve->co[1]= td->loc[1]; + eve->co[2]= td->loc[2]; + } + } +} + /* called for updating while transform acts, once per redraw */ void recalcData(TransInfo *t) { @@ -186,6 +210,9 @@ void recalcData(TransInfo *t) if(t->state != TRANS_CANCEL) clipMirrorModifier(t, G.obedit); + if(G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR) + editmesh_apply_to_mirror(t); + DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); /* sets recalc flags */ recalc_editnormals(); @@ -273,7 +300,8 @@ void recalcData(TransInfo *t) } else if(t->spacetype==SPACE_IMAGE) { flushTransUVs(t); - if (G.sima->flag & SI_LSCM_LIVE) unwrap_lscm_live(); + if (G.sima->flag & SI_LSCM_LIVE) + unwrap_lscm_live_re_solve(); } else { for(base= FIRSTBASE; base; base= base->next) { @@ -454,6 +482,11 @@ void postTrans (TransInfo *t) MEM_freeN(t->data2d); t->data2d= NULL; } + + if(t->spacetype==SPACE_IMAGE) { + if (G.sima->flag & SI_LSCM_LIVE) + unwrap_lscm_live_end(); + } } static void apply_grid3(TransInfo *t, float *val, int max_index, float fac1, float fac2, float fac3) diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c index 953ca53482d..e354fa0ff7b 100644 --- a/source/blender/src/transform_manipulator.c +++ b/source/blender/src/transform_manipulator.c @@ -172,6 +172,32 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan, float *normal, float *p } } +/* only counts the parent selection, and tags transform flag */ +/* bad call... should re-use method from transform_conversion once */ +static void count_bone_select(TransInfo *t, bArmature *arm, ListBase *lb, int do_it) +{ + Bone *bone; + int do_next; + + for(bone= lb->first; bone; bone= bone->next) { + bone->flag &= ~BONE_TRANSFORM; + do_next= do_it; + if(do_it) { + if(bone->layer & arm->layer) { + if (bone->flag & BONE_SELECTED) { + /* We don't let connected children get "grabbed" */ + if ( (t->mode!=TFM_TRANSLATION) || (bone->flag & BONE_CONNECTED)==0 ) { + bone->flag |= BONE_TRANSFORM; + t->total++; + do_next= 0; // no transform on children if one parent bone is selected + } + } + } + } + count_bone_select(t, arm, &bone->childbase, do_next); + } +} + /* centroid, boundbox, of selection */ /* returns total items selected */ int calc_manipulator_stats(ScrArea *sa) @@ -243,15 +269,18 @@ int calc_manipulator_stats(ScrArea *sa) } } else if (G.obedit->type==OB_ARMATURE){ + bArmature *arm= G.obedit->data; EditBone *ebo; for (ebo=G.edbo.first;ebo;ebo=ebo->next){ - if (ebo->flag & BONE_TIPSEL) { - calc_tw_center(ebo->tail); - totsel++; - } - if (ebo->flag & BONE_ROOTSEL) { - calc_tw_center(ebo->head); - totsel++; + if(ebo->layer & arm->layer) { + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(ebo->tail); + totsel++; + } + if (ebo->flag & BONE_ROOTSEL) { + calc_tw_center(ebo->head); + totsel++; + } } } } @@ -366,7 +395,7 @@ int calc_manipulator_stats(ScrArea *sa) /* count total, we use same method as transform will do */ Trans.total= 0; - count_bone_select(&Trans, &arm->bonebase, 1); + count_bone_select(&Trans, arm, &arm->bonebase, 1); totsel= Trans.total; if(totsel) { /* use channels to get stats */ @@ -1459,7 +1488,7 @@ static int manipulator_selectbuf(ScrArea *sa, float hotspot) /* get rid of overlay button matrix */ persp(PERSP_VIEW); - setwinmatrixview3d(&rect); + setwinmatrixview3d(sa->winx, sa->winy, &rect); Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat); glSelectBuffer( 64, buffer); @@ -1481,7 +1510,7 @@ static int manipulator_selectbuf(ScrArea *sa, float hotspot) hits= glRenderMode(GL_RENDER); G.f &= ~G_PICKSEL; - setwinmatrixview3d(0); + setwinmatrixview3d(sa->winx, sa->winy, NULL); Mat4MulMat4(v3d->persmat, v3d->viewmat, sa->winmat); persp(PERSP_WIN); diff --git a/source/blender/src/unwrapper.c b/source/blender/src/unwrapper.c index 045eea31625..52f3fcc77f1 100644 --- a/source/blender/src/unwrapper.c +++ b/source/blender/src/unwrapper.c @@ -43,6 +43,8 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_global.h" #include "BKE_mesh.h" @@ -53,6 +55,7 @@ #include "BIF_editsima.h" #include "BIF_space.h" +#include "BIF_screen.h" #include "blendef.h" #include "mydevice.h" @@ -60,6 +63,12 @@ #include "ONL_opennl.h" #include "BDR_unwrapper.h" +#include "PIL_time.h" + +#include "parametrizer.h" + +short CurrentUnwrapper = 0; + /* Implementation Least Squares Conformal Maps parameterization, based on * chapter 2 of: * Bruno Levy, Sylvain Petitjean, Nicolas Ray, Jerome Maillot. Least Squares @@ -903,9 +912,9 @@ static int unwrap_lscm_face_group(Mesh *me, int *groups, int gid) lscm_build_matrix(me, lscmvert, groups, gid, center, radius); nlEnd(NL_SYSTEM); - + /* LSCM solver magic! */ - nlSolve(); + nlSolve(NULL, NL_FALSE); /* load new uv's: will be projected uv's if solving failed */ lscm_load_solution(me, lscmvert, groups, gid); @@ -1133,6 +1142,11 @@ void unwrap_lscm(void) int res; Mesh *me; int totgroup, *groups=NULL, a; + + if (CurrentUnwrapper == 1) { + unwrap_lscm_new(); + return; + } me= get_mesh(OBACT); if(me==0 || me->tface==0) return; @@ -1336,3 +1350,246 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index) object_tface_flags_changed(OBACT, 0); } +/* Parametrizer */ + +ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill) +{ + int a; + TFace *tf; + MFace *mf; + MVert *mv; + MEdge *medge; + ParamHandle *handle; + + handle = param_construct_begin(); + + mv= me->mvert; + mf= me->mface; + tf= me->tface; + for (a=0; atotface; a++, mf++, tf++) { + ParamKey key, vkeys[4]; + ParamBool pin[4], select[4]; + float *co[4]; + float *uv[4]; + int nverts; + + if ((tf->flag & TF_HIDE) || !(tf->flag & TF_SELECT)) + continue; + + if (implicit && !(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))) + continue; + + key = (ParamKey)mf; + vkeys[0] = (ParamKey)mf->v1; + vkeys[1] = (ParamKey)mf->v2; + vkeys[2] = (ParamKey)mf->v3; + + co[0] = (mv+mf->v1)->co; + co[1] = (mv+mf->v2)->co; + co[2] = (mv+mf->v3)->co; + + uv[0] = tf->uv[0]; + uv[1] = tf->uv[1]; + uv[2] = tf->uv[2]; + + pin[0] = ((tf->unwrap & TF_PIN1) != 0); + pin[1] = ((tf->unwrap & TF_PIN2) != 0); + pin[2] = ((tf->unwrap & TF_PIN3) != 0); + + select[0] = ((tf->flag & TF_SEL1) != 0); + select[1] = ((tf->flag & TF_SEL2) != 0); + select[2] = ((tf->flag & TF_SEL3) != 0); + + if (mf->v4) { + vkeys[3] = (ParamKey)mf->v4; + co[3] = (mv+mf->v4)->co; + uv[3] = tf->uv[3]; + pin[3] = ((tf->unwrap & TF_PIN4) != 0); + select[3] = ((tf->flag & TF_SEL4) != 0); + nverts = 4; + } + else + nverts = 3; + + param_face_add(handle, key, nverts, vkeys, co, uv, pin, select); + } + + if (!implicit) { + for(medge=me->medge, a=me->totedge; a>0; a--, medge++) { + if(medge->flag & ME_SEAM) { + ParamKey vkeys[2]; + + vkeys[0] = (ParamKey)medge->v1; + vkeys[1] = (ParamKey)medge->v2; + param_edge_set_seam(handle, vkeys); + } + } + } + + param_construct_end(handle, fill, implicit); + + return handle; +} + +void unwrap_lscm_new(void) +{ + Mesh *me; + ParamHandle *handle; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + handle = construct_param_handle(me, 0, 1); + + param_lscm_begin(handle, PARAM_FALSE); + param_lscm_solve(handle); + param_lscm_end(handle); + + param_pack(handle); + param_flush(handle); + + param_delete(handle); + + BIF_undo_push("UV lscm unwrap"); + + object_uvs_changed(OBACT); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); +} + +void minimize_stretch_tface_uv(void) +{ + Mesh *me; + ParamHandle *handle; + double lasttime; + short doit = 1, escape = 0, val, blend = 0; + unsigned short event = 0; + + me = get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + handle = construct_param_handle(me, 1, 0); + + lasttime = PIL_check_seconds_timer(); + + param_stretch_begin(handle); + + while (doit) { + param_stretch_iter(handle); + + while (qtest()) { + event= extern_qread(&val); + + if (val) { + switch (event) { + case ESCKEY: + escape = 1; + case RETKEY: + case PADENTER: + doit = 0; + break; + case PADPLUSKEY: + case WHEELUPMOUSE: + if (blend < 10) { + blend++; + param_stretch_blend(handle, blend*0.1f); + param_flush(handle); + lasttime = 0.0f; + } + break; + case PADMINUS: + case WHEELDOWNMOUSE: + if (blend > 0) { + blend--; + param_stretch_blend(handle, blend*0.1f); + param_flush(handle); + lasttime = 0.0f; + } + break; + } + } + else if ((event == LEFTMOUSE) || (event == RIGHTMOUSE)) { + escape = (event == RIGHTMOUSE); + doit = 0; + } + } + + if (!doit) + break; + + if (PIL_check_seconds_timer() - lasttime > 0.5) { + char str[100]; + + param_flush(handle); + + sprintf(str, "Stretch minimize. Blend %.2f.", blend*0.1f); + headerprint(str); + + lasttime = PIL_check_seconds_timer(); + if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0); + else force_draw(0); + } + } + + if (escape) + param_flush_restore(handle); + else + param_flush(handle); + + param_stretch_end(handle); + + param_delete(handle); + + BIF_undo_push("UV stretch minimize"); + + object_uvs_changed(OBACT); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); +} + +/* LSCM live mode */ + +static ParamHandle *liveHandle = NULL; + +void unwrap_lscm_live_begin(void) +{ + Mesh *me; + + if (CurrentUnwrapper == 0) + return; + + me= get_mesh(OBACT); + if(me==0 || me->tface==0) return; + + liveHandle = construct_param_handle(me, 0, 0); + + param_lscm_begin(liveHandle, PARAM_TRUE); +} + +void unwrap_lscm_live_re_solve(void) +{ + if (CurrentUnwrapper == 0) { + unwrap_lscm(); + return; + } + + if (liveHandle) { + param_lscm_solve(liveHandle); + param_flush(liveHandle); + } +} + +void unwrap_lscm_live_end(void) +{ + if (CurrentUnwrapper == 0) + return; + + if (liveHandle) { + param_lscm_end(liveHandle); + param_delete(liveHandle); + liveHandle = NULL; + } +} + diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index a6f51f92c2d..a834f790141 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -62,6 +62,7 @@ #include "DNA_space_types.h" #include "DNA_userdef_types.h" #include "DNA_sound_types.h" +#include "DNA_scene_types.h" #include "BKE_blender.h" #include "BKE_curve.h" @@ -88,6 +89,7 @@ #include "BIF_editmode_undo.h" #include "BIF_editsound.h" #include "BIF_poseobject.h" +#include "BIF_previewrender.h" #include "BIF_renderwin.h" #include "BIF_resources.h" #include "BIF_screen.h" @@ -96,10 +98,11 @@ #include "BIF_cursors.h" #include "BSE_drawview.h" -#include "BSE_headerbuttons.h" +#include "BSE_edit.h" #include "BSE_editipo.h" #include "BSE_filesel.h" -#include "BSE_edit.h" +#include "BSE_headerbuttons.h" +#include "BSE_node.h" #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -113,8 +116,9 @@ #include "blendef.h" +#include "RE_pipeline.h" /* RE_ free stuff */ + #include "radio.h" -#include "render.h" /* RE_ free stuff */ #include "datatoc.h" #include "SYS_System.h" @@ -265,10 +269,24 @@ static void init_userdef_file(void) 255); } } - if(U.obcenter_dia==0) U.obcenter_dia= 6; } - + if (G.main->versionfile <= 240) { + bTheme *btheme; + for(btheme= U.themes.first; btheme; btheme= btheme->next) { + /* Node editor theme, check for alpha==0 is safe, then color was never set */ + if(btheme->tnode.syntaxn[3]==0) { + /* 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, 95, 110, 145, 255); /* in/output */ + SETCOL(btheme->tnode.syntaxb, 135, 125, 120, 255); /* operator */ + SETCOL(btheme->tnode.syntaxv, 120, 120, 120, 255); /* generator */ + SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */ + } + } + } if (U.undosteps==0) U.undosteps=32; @@ -642,6 +660,8 @@ static void initbuttons(void) G.fontss= BMF_GetFont(BMF_kHelveticaBold8); clear_matcopybuf(); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } @@ -660,8 +680,11 @@ void BIF_init(void) initbuttons(); InitCursorData(); sound_init_listener(); + init_node_butfuncs(); + BIF_preview_init_dbase(); BIF_read_homefile(); + init_gl_stuff(); /* drawview.c, after homefile */ readBlog(); strcpy(G.lib, G.sce); @@ -718,7 +741,7 @@ void exit_usiblender(void) free_languagemenu(); #endif - RE_free_render_data(); + RE_FreeAllRender(); free_txt_data(); @@ -754,7 +777,8 @@ void exit_usiblender(void) BKE_reset_undo(); BLI_freelistN(&U.themes); - + BIF_preview_free_dbase(); + if(totblock!=0) { printf("Error Totblock: %d\n",totblock); MEM_printmemlist(); diff --git a/source/blender/src/view.c b/source/blender/src/view.c index 8d39a0c9eef..38703ef322f 100644 --- a/source/blender/src/view.c +++ b/source/blender/src/view.c @@ -61,14 +61,16 @@ #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" -#include "BKE_utildefines.h" -#include "BKE_object.h" +#include "BKE_anim.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" #include "BIF_gl.h" #include "BIF_space.h" #include "BIF_mywindow.h" +#include "BIF_previewrender.h" #include "BIF_screen.h" #include "BIF_toolbox.h" @@ -82,9 +84,6 @@ #include "mydevice.h" #include "blendef.h" -/* Modules used */ -#include "render.h" /* R. stuff for ogl view render */ - #define TRACKBALLSIZE (1.1) #define BL_NEAR_CLIP 0.001 @@ -535,6 +534,7 @@ void viewmove(int mode) int firsttime=1; short mvalball[2], mval[2], mvalo[2]; short use_sel = 0; + short preview3d_event= 1; /* 3D window may not be defined */ if( !G.vd ) { @@ -591,7 +591,7 @@ void viewmove(int mode) G.vd->view= 0; } - if(G.vd->persp==2 || (G.vd->persp==3 && mode!=1)) { + if(G.vd->persp==2 && mode!=1) { G.vd->persp= 1; scrarea_do_windraw(curarea); scrarea_queue_headredraw(curarea); @@ -700,16 +700,14 @@ void viewmove(int mode) } } else if(mode==1) { /* translate */ - if(G.vd->persp==3) { - /* zoom= 0.5+0.5*(float)(2<rt1); */ - /* dx-= (mval[0]-mvalo[0])/zoom; */ - /* dy-= (mval[1]-mvalo[1])/zoom; */ - /* G.vd->rt2= dx; */ - /* G.vd->rt3= dy; */ - /* if(G.vd->rt2<-320) G.vd->rt2= -320; */ - /* if(G.vd->rt2> 320) G.vd->rt2= 320; */ - /* if(G.vd->rt3<-250) G.vd->rt3= -250; */ - /* if(G.vd->rt3> 250) G.vd->rt3= 250; */ + if(G.vd->persp==2) { + float max= (float)MAX2(curarea->winx, curarea->winy); + + G.vd->camdx += (mvalo[0]-mval[0])/(max); + G.vd->camdy += (mvalo[1]-mval[1])/(max); + CLAMP(G.vd->camdx, -1.0f, 1.0f); + CLAMP(G.vd->camdy, -1.0f, 1.0f); + preview3d_event= 0; } else { window_to_3d(dvec, mval[0]-mvalo[0], mval[1]-mvalo[1]); @@ -746,6 +744,8 @@ void viewmove(int mode) mval[1]= mvalo[1]; /* preserve first value */ mval[0]= mvalo[0]; + + if(G.vd->persp==0 || G.vd->persp==2) preview3d_event= 0; } mvalo[0]= mval[0]; @@ -769,26 +769,29 @@ void viewmove(int mode) /* this in the end, otherwise get_mbut does not work on a PC... */ if( !(get_mbut() & (L_MOUSE|M_MOUSE))) break; } + + if(preview3d_event) + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); + else + BIF_view3d_previewrender_signal(curarea, PR_PROJECTED); + } -short v3d_windowmode=0; - -/* important to not set windows active in here, can be renderwin for example */ -void setwinmatrixview3d(rctf *rect) /* rect: for picking */ +int get_view3d_viewplane(int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend) { - Camera *cam=0; - float near, far, winx = 0.0, winy = 0.0; + Camera *cam=NULL; float lens, fac, x1, y1, x2, y2; - short orth; + float winx= (float)winxi, winy= (float)winyi; + int orth= 0; lens= G.vd->lens; - near= G.vd->near; - far= G.vd->far; + *clipsta= G.vd->near; + *clipend= G.vd->far; if(G.vd->persp==2) { - near= G.vd->near; - far= G.vd->far; + *clipsta= G.vd->near; + *clipend= G.vd->far; if(G.vd->camera) { if(G.vd->camera->type==OB_LAMP ) { Lamp *la; @@ -799,27 +802,18 @@ void setwinmatrixview3d(rctf *rect) /* rect: for picking */ x1= saacos(fac); lens= 16.0*fac/sin(x1); - near= la->clipsta; - far= la->clipend; + *clipsta= la->clipsta; + *clipend= la->clipend; } else if(G.vd->camera->type==OB_CAMERA) { cam= G.vd->camera->data; lens= cam->lens; - near= cam->clipsta; - far= cam->clipend; + *clipsta= cam->clipsta; + *clipend= cam->clipend; } } } - if(v3d_windowmode) { // hackish - winx= R.rectx; - winy= R.recty; - } - else { - winx= curarea->winx; - winy= curarea->winy; - } - if(G.vd->persp==0) { if(winx>winy) x1= -G.vd->dist; else x1= -winx*G.vd->dist/winy; @@ -829,8 +823,8 @@ void setwinmatrixview3d(rctf *rect) /* rect: for picking */ else y1= -G.vd->dist; y2= -y1; - far*= 0.5; // otherwise too extreme low zbuffer quality - near= -far; + *clipend *= 0.5; // otherwise too extreme low zbuffer quality + *clipsta= - *clipend; orth= 1; } else { @@ -860,46 +854,69 @@ void setwinmatrixview3d(rctf *rect) /* rect: for picking */ if(winx>winy) dfac= 64.0/(fac*winx*lens); else dfac= 64.0/(fac*winy*lens); - x1= - near*winx*dfac; + x1= - *clipsta * winx*dfac; x2= -x1; - y1= - near*winy*dfac; + y1= - *clipsta * winy*dfac; y2= -y1; orth= 0; } - } - - if(rect) { /* picking */ - rect->xmin/= winx; - rect->xmin= x1+rect->xmin*(x2-x1); - rect->ymin/= winy; - rect->ymin= y1+rect->ymin*(y2-y1); - rect->xmax/= winx; - rect->xmax= x1+rect->xmax*(x2-x1); - rect->ymax/= winy; - rect->ymax= y1+rect->ymax*(y2-y1); - - if(orth) myortho(rect->xmin, rect->xmax, rect->ymin, rect->ymax, -far, far); - else mywindow(rect->xmin, rect->xmax, rect->ymin, rect->ymax, near, far); - - } - else { - if(v3d_windowmode) { - if(orth) i_ortho(x1, x2, y1, y2, near, far, R.winmat); - else i_window(x1, x2, y1, y2, near, far, R.winmat); - } - else { - if(orth) myortho(x1, x2, y1, y2, near, far); - else mywindow(x1, x2, y1, y2, near, far); + /* cam view offset */ + if(cam) { + float dx= G.vd->camdx*(x2-x1); + float dy= G.vd->camdy*(y2-y1); + x1+= dx; + x2+= dx; + y1+= dy; + y2+= dy; } } - - if(v3d_windowmode==0) { - glMatrixMode(GL_PROJECTION); - mygetmatrix(curarea->winmat); - glMatrixMode(GL_MODELVIEW); - } + + viewplane->xmin= x1; + viewplane->ymin= y1; + viewplane->xmax= x2; + viewplane->ymax= y2; + + return orth; } +/* important to not set windows active in here, can be renderwin for example */ +void setwinmatrixview3d(int winx, int winy, rctf *rect) /* rect: for picking */ +{ + rctf viewplane; + float clipsta, clipend, x1, y1, x2, y2; + int orth; + + orth= get_view3d_viewplane(winx, winy, &viewplane, &clipsta, &clipend); +// printf("%d %d %f %f %f %f %f %f\n", winx, winy, viewplane.xmin, viewplane.ymin, viewplane.xmax, viewplane.ymax, clipsta, clipend); + x1= viewplane.xmin; + y1= viewplane.ymin; + x2= viewplane.xmax; + y2= viewplane.ymax; + + if(rect) { /* picking */ + rect->xmin/= (float)curarea->winx; + rect->xmin= x1+rect->xmin*(x2-x1); + rect->ymin/= (float)curarea->winy; + rect->ymin= y1+rect->ymin*(y2-y1); + rect->xmax/= (float)curarea->winx; + rect->xmax= x1+rect->xmax*(x2-x1); + rect->ymax/= (float)curarea->winy; + rect->ymax= y1+rect->ymax*(y2-y1); + + if(orth) myortho(rect->xmin, rect->xmax, rect->ymin, rect->ymax, -clipend, clipend); + else mywindow(rect->xmin, rect->xmax, rect->ymin, rect->ymax, clipsta, clipend); + + } + else { + if(orth) myortho(x1, x2, y1, y2, clipsta, clipend); + else mywindow(x1, x2, y1, y2, clipsta, clipend); + } + + /* not sure what this was for? (ton) */ + glMatrixMode(GL_PROJECTION); + mygetmatrix(curarea->winmat); + glMatrixMode(GL_MODELVIEW); +} void obmat_to_viewmat(Object *ob) { @@ -987,7 +1004,7 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1 } /* get rid of overlay button matrix */ persp(PERSP_VIEW); - setwinmatrixview3d(&rect); + setwinmatrixview3d(curarea->winx, curarea->winy, &rect); Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); if(G.vd->drawtype > OB_WIRE) { @@ -1019,6 +1036,27 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1 base->selcol= code; glLoadName(code); draw_object(base, DRAW_PICKING|DRAW_CONSTCOLOR); + + /* we draw group-duplicators for selection too */ + if((base->object->transflag & OB_DUPLI) && base->object->dup_group) { + ListBase *lb; + DupliObject *dob; + Base tbase; + + tbase.flag= OB_FROMDUPLI; + lb= object_duplilist(G.scene, base->object); + + for(dob= lb->first; dob; dob= dob->next) { + tbase.object= dob->ob; + Mat4CpyMat4(dob->ob->obmat, dob->mat); + + draw_object(&tbase, DRAW_PICKING|DRAW_CONSTCOLOR); + + Mat4CpyMat4(dob->ob->obmat, dob->omat); + } + BLI_freelistN(lb); + } + code++; } } @@ -1030,7 +1068,7 @@ short view3d_opengl_select(unsigned int *buffer, unsigned int bufsize, short x1 if(hits<0) error("Too many objects in select buffer"); G.f &= ~G_PICKSEL; - setwinmatrixview3d(0); + setwinmatrixview3d(curarea->winx, curarea->winy, NULL); Mat4MulMat4(G.vd->persmat, G.vd->viewmat, curarea->winmat); if(G.vd->drawtype > OB_WIRE) { @@ -1185,6 +1223,7 @@ void initlocalview() G.vd->localview= 0; } + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); } void centreview() /* like a localview without local! */ @@ -1202,17 +1241,21 @@ void centreview() /* like a localview without local! */ } else if(ob && (ob->flag & OB_POSEMODE)) { if(ob->pose) { + bArmature *arm= ob->data; bPoseChannel *pchan; float vec[3]; + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { if(pchan->bone->flag & BONE_SELECTED) { - ok= 1; - VECCOPY(vec, pchan->pose_head); - Mat4MulVecfl(ob->obmat, vec); - DO_MINMAX(vec, min, max); - VECCOPY(vec, pchan->pose_tail); - Mat4MulVecfl(ob->obmat, vec); - DO_MINMAX(vec, min, max); + if(pchan->bone->layer & arm->layer) { + ok= 1; + VECCOPY(vec, pchan->pose_head); + Mat4MulVecfl(ob->obmat, vec); + DO_MINMAX(vec, min, max); + VECCOPY(vec, pchan->pose_tail); + Mat4MulVecfl(ob->obmat, vec); + DO_MINMAX(vec, min, max); + } } } } @@ -1263,6 +1306,7 @@ void centreview() /* like a localview without local! */ G.vd->cursor[2]= -G.vd->ofs[2]; scrarea_queue_winredraw(curarea); + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); } @@ -1324,7 +1368,7 @@ void endlocalview(ScrArea *sa) countall(); allqueue(REDRAWVIEW3D, 0); /* because of select */ allqueue(REDRAWOOPS, 0); /* because of select */ - + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); } } @@ -1379,6 +1423,8 @@ void view3d_home(int centre) scrarea_queue_winredraw(curarea); } + BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); + } diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index ad62f6c0dc0..498fd4195f8 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -33,10 +33,6 @@ #include #include -#ifdef HAVE_CONFIG_H -#include -#endif - #ifdef WIN32 #include #else @@ -46,6 +42,7 @@ #include "MEM_guardedalloc.h" #include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" @@ -599,7 +596,8 @@ static void vpaint_blend( unsigned int *col, unsigned int *colorig, unsigned int static int sample_backbuf_area(int x, int y, float size) { - unsigned int rect[129*129], *rt; + unsigned int *rt; + struct ImBuf *ibuf; int x1, y1, x2, y2, a, tot=0, index; if(totvpaintundo>=MAXINDEX) return 0; @@ -617,12 +615,15 @@ static int sample_backbuf_area(int x, int y, float size) #ifdef __APPLE__ glReadBuffer(GL_AUX0); #endif - glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, rect); + ibuf = IMB_allocImBuf(2*size + 1, 2*size + 1, 32, IB_rect, 0); + glReadPixels(x1+curarea->winrct.xmin, y1+curarea->winrct.ymin, x2-x1+1, y2-y1+1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glReadBuffer(GL_BACK); - if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr( (int)(4*size*size), rect); + if(G.order==B_ENDIAN) { + IMB_convert_rgba_to_abgr(ibuf); + } - rt= rect; + rt= ibuf->rect; size= (y2-y1)*(x2-x1); if(size<=0) return 0; @@ -642,6 +643,8 @@ static int sample_backbuf_area(int x, int y, float size) for(a=1; a<=totvpaintundo; a++) { if(indexar[a]) indexar[tot++]= a; } + + IMB_freeImBuf(ibuf); return tot; } diff --git a/source/blender/src/writeavicodec.c b/source/blender/src/writeavicodec.c index 8e9ee8932aa..ace6ac8bf25 100644 --- a/source/blender/src/writeavicodec.c +++ b/source/blender/src/writeavicodec.c @@ -55,9 +55,6 @@ #include "BLI_blenlib.h" #include "DNA_userdef_types.h" -#include "render_types.h" -#include "render.h" // lotsof R. stuff - #include "BKE_global.h" #include "BKE_scene.h" #include "BKE_writeavi.h" @@ -646,6 +643,7 @@ static int open_avi_codec_file(char * name) void end_avi_codec(void) { +#if 0 free_opts_data(); if (psUncompressed) { @@ -667,11 +665,13 @@ void end_avi_codec(void) AVIFileExit(); avifileinitdone--; } +#endif } void start_avi_codec(void) { +#if 0 HRESULT hr; BITMAPINFOHEADER bmi; char name[2048]; @@ -731,11 +731,13 @@ void start_avi_codec(void) BLI_move(bakname, name); } } +#endif } void append_avi_codec(int frame) { +#if 0 HRESULT hr; BITMAPINFOHEADER bmi; RGBTRIPLE *buffer, *to; @@ -777,11 +779,13 @@ void append_avi_codec(int frame) printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); } } +#endif } int get_avicodec_settings(void) { +#if 0 int ret_val = 0; AVICOMPRESSOPTIONS *aopts[1] = {&opts}; AviCodecData *acd = G.scene->r.avicodecdata; @@ -824,6 +828,7 @@ int get_avicodec_settings(void) } return(ret_val); +#endif } #endif // _WIN32 diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c index f386ea3ecf0..808c10c4a17 100644 --- a/source/blender/src/writeimage.c +++ b/source/blender/src/writeimage.c @@ -30,69 +30,35 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ +#include + +#include "MEM_guardedalloc.h" + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" // ImBuf{} +#include "BLI_blenlib.h" + #include "DNA_scene_types.h" +#include "DNA_space_types.h" #include "DNA_texture_types.h" // EnvMap{} #include "DNA_image_types.h" // Image{} #include "BKE_global.h" // struct G +#include "BKE_image.h" #include "BKE_utildefines.h" // ELEM +#include "BIF_screen.h" // waitcursor +#include "BIF_toolbox.h" #include "BIF_writeimage.h" -#include "render.h" // RE_make_existing_file, R. stuff - -int BIF_write_ibuf(ImBuf *ibuf, char *name) -{ - int ok; - - /* to be used for e.g. envmap, not rendered images */ - - if(G.scene->r.imtype== R_IRIS) ibuf->ftype= IMAGIC; - else if ((G.scene->r.imtype==R_RADHDR)) { - ibuf->ftype= RADHDR; - } - else if ((G.scene->r.imtype==R_PNG)) { - ibuf->ftype= PNG; - } - else if ((G.scene->r.imtype==R_BMP)) { - ibuf->ftype= BMP; - } - else if ((G.have_libtiff) && (G.scene->r.imtype==R_TIFF)) { - ibuf->ftype= TIF; - } - else if ((G.scene->r.imtype==R_TARGA) || (G.scene->r.imtype==R_PNG)) { - // fall back to Targa if PNG writing is not supported - ibuf->ftype= TGA; - } - else if(G.scene->r.imtype==R_RAWTGA) { - ibuf->ftype= RAWTGA; - } - else if(G.scene->r.imtype==R_HAMX) { - ibuf->ftype= AN_hamx; - } - else if ELEM(G.scene->r.imtype, R_JPEG90, R_MOVIE) { - if(G.scene->r.quality < 10) G.scene->r.quality= 90; - - ibuf->ftype= JPG|G.scene->r.quality; - } - else ibuf->ftype= TGA; - - RE_make_existing_file(name); - - ok = IMB_saveiff(ibuf, name, IB_rect); - if (ok == 0) { - perror(name); - } - - return(ok); -} +#include "BSE_filesel.h" +#include "RE_pipeline.h" /* ------------------------------------------------------------------------- */ + void BIF_save_envmap(EnvMap *env, char *str) { ImBuf *ibuf; @@ -105,19 +71,124 @@ void BIF_save_envmap(EnvMap *env, char *str) dx= env->cube[0]->ibuf->x; ibuf= IMB_allocImBuf(3*dx, 2*dx, 24, IB_rect, 0); - IMB_rectop(ibuf, env->cube[0]->ibuf, - 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(ibuf, env->cube[1]->ibuf, - dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(ibuf, env->cube[2]->ibuf, - 2*dx, 0, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(ibuf, env->cube[3]->ibuf, - 0, dx, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(ibuf, env->cube[4]->ibuf, - dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(ibuf, env->cube[5]->ibuf, - 2*dx, dx, 0, 0, dx, dx, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, env->cube[0]->ibuf, 0, 0, 0, 0, dx, dx); + IMB_rectcpy(ibuf, env->cube[1]->ibuf, dx, 0, 0, 0, dx, dx); + IMB_rectcpy(ibuf, env->cube[2]->ibuf, 2*dx, 0, 0, 0, dx, dx); + IMB_rectcpy(ibuf, env->cube[3]->ibuf, 0, dx, 0, 0, dx, dx); + IMB_rectcpy(ibuf, env->cube[4]->ibuf, dx, dx, 0, 0, dx, dx); + IMB_rectcpy(ibuf, env->cube[5]->ibuf, 2*dx, dx, 0, 0, dx, dx); - BIF_write_ibuf(ibuf, str); + BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality); IMB_freeImBuf(ibuf); } + + +/* callback for fileselect to save rendered image, renderresult was checked to exist */ +static void save_rendered_image_cb(char *name) +{ + char str[FILE_MAXDIR+FILE_MAXFILE]; + + if(BLI_testextensie(name,".blend")) { + error("Wrong filename"); + return; + } + + /* BKE_add_image_extension() checks for if extension was already set */ + if(G.scene->r.scemode & R_EXTENSION) + if(strlen(name)r.imtype); + + strcpy(str, name); + BLI_convertstringcode(str, G.sce, G.scene->r.cfra); + + if(saveover(str)) { + RenderResult rres; + ImBuf *ibuf; + + RE_GetResultImage(RE_GetRender("Render"), &rres); + + waitcursor(1); /* from screen.c */ + + ibuf= IMB_allocImBuf(rres.rectx, rres.recty, G.scene->r.planes, 0, 0); + ibuf->rect= rres.rect32; + ibuf->rect_float= rres.rectf; + ibuf->zbuf_float= rres.rectz; + + BKE_write_ibuf(ibuf, str, G.scene->r.imtype, G.scene->r.subimtype, G.scene->r.quality); + IMB_freeImBuf(ibuf); /* imbuf knows rects are not part of ibuf */ + + strcpy(G.ima, name); + + waitcursor(0); + } +} + +void save_image_filesel_str(char *str) +{ + switch(G.scene->r.imtype) { + case R_RADHDR: + strcpy(str, "Save Radiance HDR"); + break; + case R_PNG: + strcpy(str, "Save PNG"); + break; + case R_BMP: + strcpy(str, "Save BMP"); + break; + case R_TIFF: + if (G.have_libtiff) + strcpy(str, "Save TIFF"); + break; +#ifdef WITH_OPENEXR + case R_OPENEXR: + strcpy(str, "Save OpenEXR"); + break; +#endif + case R_RAWTGA: + strcpy(str, "Save Raw Targa"); + break; + case R_IRIS: + strcpy(str, "Save IRIS"); + break; + case R_IRIZ: + strcpy(str, "Save IRIS"); + break; + case R_HAMX: + strcpy(str, "Save HAMX"); + break; + case R_JPEG90: + case R_MOVIE: + case R_AVICODEC: + case R_AVIRAW: + case R_AVIJPEG: + strcpy(str, "Save JPEG"); + break; + + case R_TARGA: /* default targa */ + default: + strcpy(str, "Save Targa"); + break; + } +} + +/* calls fileselect */ +void BIF_save_rendered_image_fs(void) +{ + RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + + if(!rr) { + error("No image rendered"); + } else { + char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2]; + + if(G.ima[0]==0) { + strcpy(dir, G.sce); + BLI_splitdirstring(dir, str); + strcpy(G.ima, dir); + } + + save_image_filesel_str(str); + activate_fileselect(FILE_SPECIAL, str, G.ima, save_rendered_image_cb); + } +} + diff --git a/source/blender/src/writemovie.c b/source/blender/src/writemovie.c index f27f7ffd7e3..3491f4f0f60 100644 --- a/source/blender/src/writemovie.c +++ b/source/blender/src/writemovie.c @@ -30,10 +30,6 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -#ifdef HAVE_CONFIG_H -#include -#endif - #ifdef __sgi #include @@ -106,7 +102,7 @@ static void make_movie_name(char *string) BLI_convertstringcode(string, G.sce, G.scene->r.cfra); len= strlen(string); - RE_make_existing_file(string); + BLI_make_existing_file(string); if (BLI_strcasecmp(string + len - 3, ".mv")) { sprintf(txt, "%04d_%04d.mv", sfra, efra); @@ -364,6 +360,7 @@ void append_movie(int cfra) char name[FILE_MAXDIR+FILE_MAXFILE]; const char *string; int fd; + float col[4] = {0.0,0.0,0.0,0.0}; set_sfra_efra(); make_movie_name(name); @@ -377,28 +374,28 @@ void append_movie(int cfra) if (ibuf->x != mv_outx || ibuf->y != mv_outy) { tbuf = IMB_allocImBuf(mv_outx, mv_outy, 32, IB_rect, 0); - IMB_rectoptot(tbuf, 0, IMB_rectfill, 0x00); + IMB_rectfill(tbuf,col); ofsx = (tbuf->x - ibuf->x) / 2; ofsy = (tbuf->y - ibuf->y) / 2; if (numfields == 2) ofsy &= ~1; - IMB_rectop(tbuf, ibuf, ofsx, ofsy, 0, 0, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(tbuf, ibuf, ofsx, ofsy, 0, 0, ibuf->x, ibuf->y); IMB_freeImBuf(ibuf); strcpy(tbuf->name, ibuf->name); ibuf = tbuf; } - IMB_convert_rgba_to_abgr(ibuf->x*ibuf->y, ibuf->rect); + IMB_convert_rgba_to_abgr(ibuf); if (numfields == 2) { if (ntsc) { - IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, ibuf, 0, 0, 0, 1, ibuf->x, ibuf->y); IMB_flipy(ibuf); IMB_de_interlace(ibuf); - if (ntsc) IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + if (ntsc) IMB_rectcpy(ibuf, ibuf, 0, 0, 0, 1, ibuf->x, ibuf->y); } else { IMB_flipy(ibuf); - IMB_rectop(ibuf, ibuf, 0, 0, 0, 1, 32767, 32767, IMB_rectcpy, 0); + IMB_rectcpy(ibuf, ibuf, 0, 0, 0, 1, ibuf->x, ibuf->y); IMB_de_interlace(ibuf); } } diff --git a/source/blender/yafray/intern/export_File.cpp b/source/blender/yafray/intern/export_File.cpp index 79e83704ee9..d9124c902c2 100755 --- a/source/blender/yafray/intern/export_File.cpp +++ b/source/blender/yafray/intern/export_File.cpp @@ -291,7 +291,7 @@ void yafrayFileRender_t::displayImage() // read data directly into buffer, picture is upside down for (unsigned short y=0;ynext, i++) { + LampRen* lamp = (LampRen *)go->lampren; + ostr.str(""); - LampRen* lamp = R.la[i]; if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } diff --git a/source/blender/yafray/intern/export_Plugin.cpp b/source/blender/yafray/intern/export_Plugin.cpp index fc587bab2e0..26de34dd488 100644 --- a/source/blender/yafray/intern/export_Plugin.cpp +++ b/source/blender/yafray/intern/export_Plugin.cpp @@ -190,14 +190,14 @@ bool yafrayPluginRender_t::initExport() } // all buffers allocated in initrender.c - unsigned int *bpt=R.rectot, count=R.rectx*R.recty; - while (--count) bpt[count] = 0xff800000; - cout << "Image initialized" << endl; +// unsigned int *bpt=R.rectot, count=R.rectx*R.recty; +// while (--count) bpt[count] = 0xff800000; +// cout << "Image initialized" << endl; - int *zbuf=R.rectz; - count = R.rectx*R.recty; - while (--count) zbuf[count] = 0x7fffffff; - cout << "Zbuffer initialized" << endl; +// int *zbuf=R.rectz; +// count = R.rectx*R.recty; +// while (--count) zbuf[count] = 0x7fffffff; +// cout << "Zbuffer initialized" << endl; // no need to fill ftot @@ -275,7 +275,7 @@ void yafrayPluginRender_t::displayImage() // maybe it is best to just do a read here, for now the yafray output is always a raw tga anyway // rectot already freed in initrender - R.rectot = (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); +// R.rectot = (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); FILE* fp = fopen(imgout.c_str(), "rb"); if (fp==NULL) { @@ -294,7 +294,7 @@ void yafrayPluginRender_t::displayImage() // read data directly into buffer, picture is upside down for (unsigned short y=0;ynext, i++) { + LampRen* lamp = (LampRen *)go->lampren; + yafray::paramMap_t params; string type=""; - LampRen* lamp = R.la[i]; if (lamp->type==LA_AREA) { writeAreaLamp(lamp, i, iview); continue; } @@ -1905,13 +1909,11 @@ bool yafrayPluginRender_t::writeWorld() return true; } -#include "RE_callbacks.h" - bool blenderYafrayOutput_t::putPixel(int x, int y, const yafray::color_t &c, yafray::CFLOAT alpha, yafray::PFLOAT depth) { unsigned int px = ((R.recty-1)-y)*R.rectx; - unsigned char* bpt = (unsigned char*)R.rectot + (px<<2); + unsigned char* bpt = NULL; //(unsigned char*)R.rectot + (px<<2); int x4 = x<<2; int temp = (int)(c.R*255.f+0.5f); if (temp>255) temp=255; @@ -1927,29 +1929,29 @@ bool blenderYafrayOutput_t::putPixel(int x, int y, const yafray::color_t &c, bpt[x4+3] = temp; // float buffer - if ((R.r.mode & R_FBUF) && R.rectftot) { - float* fpt = R.rectftot + (px<<2); - fpt[x4] = c.R; - fpt[x4+1] = c.G; - fpt[x4+2] = c.B; - fpt[x4+3] = alpha; - } +// if ((R.r.mode & R_FBUF) && R.rectftot) { +// float* fpt = R.rectftot + (px<<2); +// fpt[x4] = c.R; +// fpt[x4+1] = c.G; +// fpt[x4+2] = c.B; +// fpt[x4+3] = alpha; +// } // depth values - int* zbuf = R.rectz + px; - depth -= R.near; - float mz = R.far - R.near; - if (depth<0) depth=0; else if (depth>mz) depth=mz; - if (mz!=0.f) mz = 2147483647.f/mz; - zbuf[x] = (int)(depth*mz); +// int* zbuf = R.rectz + px; +// depth -= R.clipsta; +// float mz = R.clipend - R.clipsta; +// if (depth<0) depth=0; else if (depth>mz) depth=mz; +// if (mz!=0.f) mz = 2147483647.f/mz; +// zbuf[x] = (int)(depth*mz); out++; if (out==4096) { - RE_local_render_display(0, R.recty-1, R.rectx, R.recty, R.rectot); + R.display_draw(R.result, NULL); out = 0; } - if (RE_local_test_break()) return false; + if (R.test_break()) return false; return true; } diff --git a/source/blender/yafray/intern/yafray_Render.h b/source/blender/yafray/intern/yafray_Render.h index e1a63e90bb7..a50954d2ed4 100644 --- a/source/blender/yafray/intern/yafray_Render.h +++ b/source/blender/yafray/intern/yafray_Render.h @@ -9,6 +9,7 @@ extern "C" { #include "IMB_imbuf_types.h" #include "DNA_camera_types.h" +#include "DNA_group_types.h" #include "DNA_image_types.h" #include "DNA_lamp_types.h" #include "DNA_material_types.h" @@ -22,8 +23,10 @@ extern "C" { #include "BKE_global.h" #include "BKE_image.h" -#include "render.h" +#include "render_types.h" +extern struct Render R; /* only to get it compile for now */ + /* useful matrix & vector operations */ #include "MTC_matrixops.h" #include "MTC_vectorops.h" diff --git a/source/creator/SConscript b/source/creator/SConscript index 11e2c835be3..412bb82e854 100644 --- a/source/creator/SConscript +++ b/source/creator/SConscript @@ -12,7 +12,6 @@ creator_env.Append (CPPPATH = ['#/intern/guardedalloc', '../blender/include', '../blender/blenloader', '../blender/imbuf', - '../blender/renderconverter', '../blender/render/extern/include', '../blender/python', '../blender/makesdna', diff --git a/source/creator/creator.c b/source/creator/creator.c index 627bbce3e2e..3a47fbaa5e9 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -43,6 +43,7 @@ #include "GEN_messaging.h" #include "DNA_ID.h" +#include "DNA_scene_types.h" #include "BLI_blenlib.h" @@ -51,6 +52,7 @@ #include "BKE_font.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_packedFile.h" #include "BKE_scene.h" @@ -72,13 +74,12 @@ #include "IMB_imbuf.h" // for quicktime_init -#include "RE_renderconverter.h" - #include "BPY_extern.h" +#include "RE_pipeline.h" + #include "playanim_ext.h" #include "mydevice.h" -#include "render.h" #include "nla.h" #include "datatoc.h" @@ -350,8 +351,8 @@ int main(int argc, char **argv) /* background render uses this font too */ BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size); - /* init struct R, Osa, defmaterial, filters */ - RE_init_render_data(); + + init_def_material(); if(G.background==0) { for(a=1; ar.sfra) = atoi(argv[a]); - (G.scene->r.efra) = (G.scene->r.sfra); - RE_animrender(NULL); + Render *re= RE_NewRender("Render"); + RE_BlenderAnim(re, G.scene, atoi(argv[a]), atoi(argv[a])); } break; case 'a': if (G.scene) { - RE_animrender(NULL); + Render *re= RE_NewRender("Render"); + RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); } break; case 'S': @@ -577,8 +578,8 @@ int main(int argc, char **argv) } } - if(G.background) - { + if(G.background) { + /* actually incorrect, but works for now (ton) */ exit_usiblender(); } @@ -615,7 +616,4 @@ void setCallbacks(void) BLI_setErrorCallBack(error_cb); /* */ BLI_setInterruptCallBack(blender_test_break); - /* render module: execution flow, timers, cursors and display. */ - RE_set_getrenderdata_callback(RE_rotateBlenderScene); - RE_set_freerenderdata_callback(RE_freeRotateBlenderScene); } diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp index 2b01d3df560..7cabb65a3ba 100644 --- a/source/gameengine/Ketsji/BL_Texture.cpp +++ b/source/gameengine/Ketsji/BL_Texture.cpp @@ -346,18 +346,18 @@ void my_envmap_split_ima(EnvMap *env) ima->ok= 1; env->cube[part]= ima; } - IMB_rectop(env->cube[0]->ibuf, env->ima->ibuf, - 0, 0, 0, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[1]->ibuf, env->ima->ibuf, - 0, 0, dx, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[2]->ibuf, env->ima->ibuf, - 0, 0, 2*dx, 0, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[3]->ibuf, env->ima->ibuf, - 0, 0, 0, dx, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[4]->ibuf, env->ima->ibuf, - 0, 0, dx, dx, dx, dx, IMB_rectcpy, 0); - IMB_rectop(env->cube[5]->ibuf, env->ima->ibuf, - 0, 0, 2*dx, dx, dx, dx, IMB_rectcpy, 0); + IMB_rectcpy(env->cube[0]->ibuf, env->ima->ibuf, + 0, 0, 0, 0, dx, dx); + IMB_rectcpy(env->cube[1]->ibuf, env->ima->ibuf, + 0, 0, dx, 0, dx, dx); + IMB_rectcpy(env->cube[2]->ibuf, env->ima->ibuf, + 0, 0, 2*dx, 0, dx, dx); + IMB_rectcpy(env->cube[3]->ibuf, env->ima->ibuf, + 0, 0, 0, dx, dx, dx); + IMB_rectcpy(env->cube[4]->ibuf, env->ima->ibuf, + 0, 0, dx, dx, dx, dx); + IMB_rectcpy(env->cube[5]->ibuf, env->ima->ibuf, + 0, 0, 2*dx, dx, dx, dx); env->ok= 2; } } diff --git a/source/nan_compile.mk b/source/nan_compile.mk index f64be26b621..241d1946738 100644 --- a/source/nan_compile.mk +++ b/source/nan_compile.mk @@ -82,8 +82,8 @@ ifeq ($(OS),darwin) CCC = g++ CFLAGS += -pipe -fPIC -ffast-math -mcpu=7450 -mtune=G5 CCFLAGS += -pipe -fPIC - REL_CFLAGS += -O2 - REL_CCFLAGS += -O2 +# REL_CFLAGS += -O2 +# REL_CCFLAGS += -O2 CPPFLAGS += -D_THREAD_SAFE NAN_DEPEND = true OPENGL_HEADERS = /System/Library/Frameworks/OpenGL.framework diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk index 7a29aa2e724..c7822683521 100644 --- a/source/nan_definitions.mk +++ b/source/nan_definitions.mk @@ -93,6 +93,22 @@ endif export NAN_FTGL ?= $(LCGDIR)/ftgl endif + export WITH_OPENEXR ?= true + ifeq ($(OS),windows) + ifeq ($(FREE_WINDOWS), true) + export NAN_OPENEXR ?= $(LCGDIR)/gcc/openexr + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a + export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR + else + export NAN_OPENEXR ?= $(LCGDIR)/openexr + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/IlmImf.lib $(NAN_OPENEXR)/lib/Half.lib $(NAN_OPENEXR)/lib/Iex.lib + export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/IlmImf -I$(NAN_OPENEXR)/include/Imath -I$(NAN_OPENEXR)/include/Iex + endif + else + export NAN_OPENEXR ?= /usr/local + export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR + export NAN_OPENEXR_LIBS ?= $(NAN_OPENEXR)/lib/libIlmImf.a $(NAN_OPENEXR)/lib/libHalf.a $(NAN_OPENEXR)/lib/libIex.a + endif # Platform Dependent settings go below: ifeq ($(OS),beos) diff --git a/source/nan_link.mk b/source/nan_link.mk index e8f852c94aa..c201b79a412 100644 --- a/source/nan_link.mk +++ b/source/nan_link.mk @@ -59,7 +59,7 @@ ifeq ($(OS),darwin) LLIBS += -lGLU -lGL LLIBS += -lz -lstdc++ ifdef USE_OSX10.4STUBS - LLIBS +=-lSystemStubs + LLIBS +=-lSystemStubs endif LLIBS += -framework Carbon -framework AGL -framework OpenGL LLIBS += -framework QuickTime -framework CoreAudio diff --git a/tools/scons/bs/bs_dirs.py b/tools/scons/bs/bs_dirs.py index 3449ca679ef..598eafb9f98 100644 --- a/tools/scons/bs/bs_dirs.py +++ b/tools/scons/bs/bs_dirs.py @@ -62,7 +62,6 @@ def preparedist(): shutil.copy("../lib/windows/python/lib/python24.dll", "dist/python24.dll") shutil.copy("../lib/windows/sdl/lib/SDL.dll", "dist/SDL.dll") shutil.copy("../lib/windows/gettext/lib/gnu_gettext.dll", "dist/gnu_gettext.dll") - shutil.copy("../lib/windows/tiff/lib/libtiff.dll", "dist/libtiff.dll") elif sys.platform in ['linux2', 'linux-i386', 'freebsd4', 'freebsd5']: shutil.copy("blender", "dist/blender") if bs_globals.user_options_dict['BUILD_BLENDER_PLAYER'] == 1: diff --git a/tools/scons/bs/bs_libs.py b/tools/scons/bs/bs_libs.py index b8a88d4d245..1ccfccf41be 100644 --- a/tools/scons/bs/bs_libs.py +++ b/tools/scons/bs/bs_libs.py @@ -33,6 +33,9 @@ def common_libs(env): 'soundsystem']) if bs_globals.user_options_dict['USE_QUICKTIME'] == 1: env.Append (LIBS=['blender_quicktime']) + if bs_globals.user_options_dict['USE_OPENEXR'] == 1: + env.Append (LIBS=['blender_openexr']) + env.Append (LIBS=['Half', 'Iex', 'IlmImf', 'Imath']) def international_libs(env): """ @@ -57,7 +60,7 @@ def blender_libs(env): 'blender_blendersrc', 'blender_render', 'blender_yafray', - 'blender_renderconverter', +# 'blender_renderconverter', 'blender_radiosity', 'blender_BSP', 'blender_blenkernel',