Sunday sync of Orange with bf-blender
authorTon Roosendaal <ton@blender.org>
Sun, 4 Dec 2005 17:22:36 +0000 (17:22 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 4 Dec 2005 17:22:36 +0000 (17:22 +0000)
90 files changed:
intern/bmfont/intern/BMF_BitmapFont.cpp
intern/boolop/intern/BOP_Face2Face.cpp
intern/boolop/intern/BOP_Interface.cpp
intern/boolop/intern/BOP_Mesh.cpp
intern/boolop/intern/BOP_Mesh.h
intern/bsp/intern/CSG_BooleanOps.cpp
intern/elbeem/SConscript
intern/elbeem/intern/blenderdummy.cpp
intern/elbeem/make/msvc_7_0/elbeem.vcproj
intern/ghost/intern/GHOST_SystemCarbon.cpp
intern/opennl/extern/ONL_opennl.h
intern/opennl/intern/opennl.c
projectfiles/blender/imbuf/BL_imbuf.dsp
projectfiles_vc7/blender/blender.vcproj
projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj
release/scripts/bevel_center.py
release/scripts/lightwave_import.py
release/scripts/uv_export.py
source/blender/blenkernel/BKE_bad_level_calls.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/material.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BDR_unwrapper.h
source/blender/include/BIF_meshtools.h
source/blender/include/blendef.h
source/blender/include/butspace.h
source/blender/include/transform.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/render/extern/include/render.h
source/blender/render/extern/include/render_types.h
source/blender/render/intern/include/pixelshading.h
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/include/texture.h
source/blender/render/intern/source/initrender.c
source/blender/render/intern/source/pixelshading.c
source/blender/render/intern/source/ray.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/texture.c
source/blender/render/intern/source/vanillaRenderPipe.c
source/blender/render/intern/source/zbuf.c
source/blender/renderconverter/intern/convertBlenderScene.c
source/blender/src/SConscript
source/blender/src/buttons_editing.c
source/blender/src/buttons_shading.c
source/blender/src/drawview.c
source/blender/src/editmesh.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/header_buttonswin.c
source/blender/src/header_image.c
source/blender/src/headerbuttons.c
source/blender/src/interface_panel.c
source/blender/src/meshtools.c
source/blender/src/parametrizer.c [new file with mode: 0644]
source/blender/src/parametrizer.h [new file with mode: 0644]
source/blender/src/parametrizer_intern.h [new file with mode: 0644]
source/blender/src/previewrender.c
source/blender/src/space.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/unwrapper.c
source/gameengine/Expressions/KX_HashedPtr.cpp
source/gameengine/Expressions/KX_HashedPtr.h
source/gameengine/Ketsji/KX_CameraIpoSGController.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_IPO_SGController.cpp
source/gameengine/Ketsji/KX_LightIpoSGController.cpp
source/gameengine/Ketsji/KX_ObColorIpoSGController.cpp
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/gameengine/Ketsji/KX_WorldIpoController.cpp
source/gameengine/Physics/BlOde/OdePhysicsEnvironment.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
source/kernel/gen_system/GEN_HashedPtr.cpp
source/kernel/gen_system/GEN_HashedPtr.h
source/nan_definitions.mk
tools/scons/bs/bs_dirs.py

index 7997a94344b93d0f0df68f2bdd9bde38fda6c811..bbba2c978dd71597ab4d6568bb089b87e17af3c5 100644 (file)
 #include "BMF_BitmapFont.h"
 
 
-#ifdef __APPLE__        
-#include <stdio.h>
-
-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++) ) {
index bdd3637a5986bcbe0c918a1eb115874a245cf1c2..08928935f33da85c5869a70a4687746dc3c4ad26 100644 (file)
@@ -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;idxFaceA<facesA->size();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)
                        idxFaceB<facesB->size() && (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++;
                }
        }
        
index 1ef394963ac03387033464336286ff408c2ef6f6..02945340d55e25dd34c0405a764e154955b1597f 100644 (file)
@@ -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;
 }
index a7e7ef61e435e2fa2d84942187eb1ed2b73db347..24d5b3fb6a90b64df4cadd8865750a8ab36d99b8 100644 (file)
@@ -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; i<m_edges.size(); i++) {
-               BOP_Edge *edge = m_edges[i];
-               BOP_Indexs faces = edge->getFaces();
-               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;
-}
 
 
 /** ***************************************************************************
index adc92c915594e9d50523b4173257fdc89ea6c258..6751df7c4e76058f12db0be546c4111acd447290 100644 (file)
@@ -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();
index a677c9c6e94a9029e43a382a510f52ff4c99efec..6c9fecd88e14feb7703b5061cf10b350ae5b7757 100755 (executable)
@@ -103,15 +103,15 @@ 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<BSP_MeshInfo *>(operation->CSG_info);
@@ -128,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
index 5d30b58a98230ac8a14332934360deeb08912632..3ef20b9be3af4aa302a94a4ce6d510c2135d82cb 100644 (file)
@@ -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",
index 3111c9359dd6264b509e94420cf9f86d0413d023..4d672dee528bcecf9d2b9a944aeb0bf030bd5b8f 100644 (file)
@@ -9,30 +9,11 @@
  *
  *****************************************************************************/
  
-#ifdef ELBEEM_DUMMIES
-
 #include <stdlib.h>
-#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
 
index f2c4451233848a38188d54d08d5cc5af238620ac..afd4c345ccd4680787c443526642d34352988845 100644 (file)
@@ -273,9 +273,6 @@ ECHO Done
                        <File
                                RelativePath="..\..\intern\ntl_scene.cpp">
                        </File>
-                       <File
-                               RelativePath="..\..\intern\ntl_world.cpp">
-                       </File>
                        <File
                                RelativePath="..\..\intern\parametrizer.cpp">
                        </File>
@@ -285,18 +282,6 @@ ECHO Done
                        <File
                                RelativePath="..\..\intern\simulation_object.cpp">
                        </File>
-                       <File
-                               RelativePath="..\..\intern\solver_init.cpp">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_interface.cpp">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_main.cpp">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_util.cpp">
-                       </File>
                        <File
                                RelativePath="..\..\intern\utilities.cpp">
                        </File>
@@ -311,9 +296,6 @@ ECHO Done
                        <File
                                RelativePath="..\..\intern\cfgparser.h">
                        </File>
-                       <File
-                               RelativePath="..\..\intern\elbeem.h">
-                       </File>
                        <File
                                RelativePath="..\..\intern\globals.h">
                        </File>
@@ -368,9 +350,6 @@ ECHO Done
                        <File
                                RelativePath="..\..\intern\ntl_vector3dim.h">
                        </File>
-                       <File
-                               RelativePath="..\..\intern\ntl_world.h">
-                       </File>
                        <File
                                RelativePath="..\..\intern\parametrizer.h">
                        </File>
@@ -380,18 +359,6 @@ ECHO Done
                        <File
                                RelativePath="..\..\intern\simulation_object.h">
                        </File>
-                       <File
-                               RelativePath="..\..\intern\solver_class.h">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_dimenions.h">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_interface.h">
-                       </File>
-                       <File
-                               RelativePath="..\..\intern\solver_relax.h">
-                       </File>
                        <File
                                RelativePath="..\..\intern\utilities.h">
                        </File>
index ee76349ededded616172d377408535fed415fcf0..d1caadab219edcf7f5d180fbe1c71d9f930f8b0d 100644 (file)
@@ -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:
index 128f1b137bcfb12550dc2e2ba5182165948c9981..345cf0dc7170f8f77b9a98b57a6a375277f24c0b 100644 (file)
@@ -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
 }
index 7773582e0272932262883ea2424bc18b7c5d29c3..c5518731c6bccf3e106cebbde1ad36d9715ad2f8 100644 (file)
  *
  *  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. 
 
 
 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; i<c->size; 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; i<c->size; 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; i<n; i++) {
-            __nlRowColumnConstruct(&(M->row[i]));
-        }
-    } else {
-        M->row = NULL;
-    }
-
-    if(storage & __NL_COLUMNS) {
-        M->column = __NL_NEW_ARRAY(__NLRowColumn, n);
-        for(i=0; i<n; i++) {
-            __nlRowColumnConstruct(&(M->column[i]));
-        }
-    } else {
-        M->column = NULL;
-    }
-
-    M->diag_size = MIN(m,n);
-    M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size);
+       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; i<n; i++) {
+                       __nlRowColumnConstruct(&(M->row[i]));
+               }
+       } else {
+               M->row = NULL;
+       }
+
+       if(storage & __NL_COLUMNS) {
+               M->column = __NL_NEW_ARRAY(__NLRowColumn, n);
+               for(i=0; i<n; i++) {
+                       __nlRowColumnConstruct(&(M->column[i]));
+               }
+       } else {
+               M->column = NULL;
+       }
+
+       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; i<M->m; i++) {
-            __nlRowColumnDestroy(&(M->row[i]));
-        }
-        __NL_DELETE_ARRAY(M->row);
-    }
-    if(M->storage & __NL_COLUMNS) {
-        for(i=0; i<M->n; 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; i<M->m; i++) {
+                       __nlRowColumnDestroy(&(M->row[i]));
+               }
+               __NL_DELETE_ARRAY(M->row);
+       }
+       if(M->storage & __NL_COLUMNS) {
+               for(i=0; i<M->n; 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; i<M->m; i++) {
-            __nlRowColumnClear(&(M->row[i]));
-        }
-    }
-    if(M->storage & __NL_COLUMNS) {
-        for(i=0; i<M->n; i++) {
-            __nlRowColumnClear(&(M->column[i]));
-        }
-    }
-    __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size);    
+       NLuint i;
+       if(M->storage & __NL_ROWS) {
+               for(i=0; i<M->m; i++) {
+                       __nlRowColumnClear(&(M->row[i]));
+               }
+       }
+       if(M->storage & __NL_COLUMNS) {
+               for(i=0; i<M->n; 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; i<M->m; i++) {
-            nnz += M->row[i].size;
-        }
-    } else if (M->storage & __NL_COLUMNS) {
-        for(i = 0; i<M->n; 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; i<M->m; i++) {
+                       nnz += M->row[i].size;
+               }
+       } else if (M->storage & __NL_COLUMNS) {
+               for(i = 0; i<M->n; 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; i<m; i++) {
-        y[i] = 0;
-        Ri = &(A->row[i]);
-        for(ij=0; ij<Ri->size; 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; i<m; i++) {
+               y[i] = 0;
+               Ri = &(A->row[i]);
+               for(ij=0; ij<Ri->size; 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; i<m; i++) {
-        y[i] = 0;
-        Ri = &(A->row[i]);
-        for(ij=0; ij<Ri->size; 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; i<m; i++) {
+               y[i] = 0;
+               Ri = &(A->row[i]);
+               for(ij=0; ij<Ri->size; 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; j<n; j++) {
-        y[j] = 0;
-        Cj = &(A->column[j]);
-        for(ii=0; ii<Cj->size; 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; j<n; j++) {
+               y[j] = 0;
+               Cj = &(A->column[j]);
+               for(ii=0; ii<Cj->size; 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; j<n; j++) {
-        Cj = &(A->column[j]);
-        for(ii=0; ii<Cj->size; 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; j<n; j++) {
+               Cj = &(A->column[j]);
+               for(ii=0; ii<Cj->size; 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;
-
-    __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;
-        }
-    }
-
-    __nlCurrentContext->n = n;
-
-    /* a least squares problem results in a symmetric matrix */
-    if(__nlCurrentContext->least_squares) {
-        __nlCurrentContext->symmetric = NL_TRUE;
-    }
-
-    if(__nlCurrentContext->symmetric) {
-        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;
-
-    __nlCurrentContext->x = __NL_NEW_ARRAY(NLfloat, n);
-    __nlCurrentContext->alloc_x = NL_TRUE;
-    
-    __nlCurrentContext->b = __NL_NEW_ARRAY(NLfloat, n);
-    __nlCurrentContext->alloc_b = NL_TRUE;
-
-    __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;
-
-    __nlCurrentContext->current_row = 0;
+       NLuint i;
+       NLuint n = 0;
+       NLenum storage = __NL_ROWS;
+
+       __nlTransition(__NL_STATE_SYSTEM, __NL_STATE_MATRIX);
+
+       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;
+
+               /* a least squares problem results in a symmetric matrix */
+               if(__nlCurrentContext->least_squares)
+                       __nlCurrentContext->symmetric = NL_TRUE;
+
+               if(__nlCurrentContext->symmetric)
+                       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;
+
+               __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();
+
+       __nlRowColumnConstruct(&__nlCurrentContext->af);
+       __nlCurrentContext->alloc_af = NL_TRUE;
+       __nlRowColumnConstruct(&__nlCurrentContext->al);
+       __nlCurrentContext->alloc_al = NL_TRUE;
+
+       __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; i<nf; i++) {
-        af->coeff[i].value *= s;
-    }
-    for(i=0; i<nl; i++) {
-        al->coeff[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; i<nf; i++) {
-        norm += af->coeff[i].value * af->coeff[i].value;
-    }
-    for(i=0; i<nl; i++) {
-        norm += al->coeff[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);
-
-    if(__nlCurrentContext->normalize_rows) {
-        __nlNormalizeRow(__nlCurrentContext->row_scaling);
-    } else {
-        __nlScaleRow(__nlCurrentContext->row_scaling);
-    }
-
-    if(__nlCurrentContext->least_squares) {
-        for(i=0; i<nf; i++) {
-            for(j=0; j<nf; j++) {
-                __nlSparseMatrixAdd(
-                    M, af->coeff[i].index, af->coeff[j].index,
-                    af->coeff[i].value * af->coeff[j].value
-                );
-            }
-        }
-        S = -__nlCurrentContext->right_hand_side;
-        for(j=0; j<nl; j++) {
-            S += al->coeff[j].value * xl->coeff[j].value;
-        }
-        for(i=0; i<nf; i++) {
-            b[ af->coeff[i].index ] -= af->coeff[i].value * S;
-        }
-    } else {
-        for(i=0; i<nf; i++) {
-            __nlSparseMatrixAdd(
-                M, current_row, af->coeff[i].index, af->coeff[i].value
-            );
-        }
-        b[current_row] = -__nlCurrentContext->right_hand_side;
-        for(i=0; i<nl; i++) {
-            b[current_row] -= al->coeff[i].value * xl->coeff[i].value;
-        }
-    }
-    __nlCurrentContext->current_row++;
-    __nlCurrentContext->right_hand_side = 0.0;    
-    __nlCurrentContext->row_scaling     = 1.0;
+       __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->least_squares) {
+               if (!__nlCurrentContext->solve_again) {
+                       for(i=0; i<nf; i++) {
+                               for(j=0; j<nf; j++) {
+                                       __nlSparseMatrixAdd(
+                                               M, af->coeff[i].index, af->coeff[j].index,
+                                               af->coeff[i].value * af->coeff[j].value
+                                       );
+                               }
+                       }
+               }
+
+               S = -__nlCurrentContext->right_hand_side;
+               for(j=0; j<nl; j++)
+                       S += al->coeff[j].value;
+
+               for(i=0; i<nf; i++)
+                       b[ af->coeff[i].index ] -= af->coeff[i].value * S;
+       } else {
+               if (!__nlCurrentContext->solve_again) {
+                       for(i=0; i<nf; i++) {
+                               __nlSparseMatrixAdd(
+                                       M, current_row, af->coeff[i].index, af->coeff[i].value
+                               );
+                       }
+               }
+               b[current_row] = -__nlCurrentContext->right_hand_side;
+               for(i=0; i<nl; i++) {
+                       b[current_row] -= al->coeff[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) {
-
-    /* OpenNL Context */
-    __NLSparseMatrix* M  = &(__nlCurrentContext->M);
-    NLfloat* b          = __nlCurrentContext->b;
-    NLfloat* x          = __nlCurrentContext->x;
-
-    /* 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);
-
-    /* Permutation vector */
-    NLint*    perm_r  = __NL_NEW_ARRAY(NLint, n);
-    NLint*    perm    = __NL_NEW_ARRAY(NLint, n);
-
-    /* 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 */
-
-    /* SuperLU options and stats */
-    superlu_options_t options;
-    SuperLUStat_t     stat;
-
-
-    /* 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.
-     * -------------------------------------------------------
-     */
-
-    count = 0;
-    for(i=0; i<n; i++) {
-        Ri = &(M->row[i]);
-        xa[i] = count;
-        for(jj=0; jj<Ri->size; jj++) {
-            a[count]    = Ri->coeff[jj].value;
-            asub[count] = Ri->coeff[jj].index;
-            count++;
-        }
-    }
-    xa[n] = nnz;
-
-    /* Save memory for SuperLU */
-    __nlSparseMatrixClear(M);
-
-
-    /*
-     * 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        */
-    );
-
-    /* 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                          */
-    );
-            
-
-    /* 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);
-
-    /* Step 4: call SuperLU main routine
-     * ---------------------------------
-     */
-
-    set_default_options(&options);
-    options.ColPerm = MY_PERMC;
-    StatInit(&stat);
-
-    sgssv(&options, &A, perm, perm_r, &L, &U, &B, &stat, &info);
-
-    /* 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];
-        }
-    }
-
-    /* Step 6: cleanup
-     * ---------------
-     */
-
-    /*
-     *  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);
-
-    
-    /*
-     *   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);
+static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation) {
+
+       /* OpenNL Context */
+       __NLSparseMatrix* M = &(context->M);
+       NLuint n = context->n;
+       NLuint nnz = __nlSparseMatrixNNZ(M); /* number of non-zero coeffs */
+
+       /* 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);
+
+       /* SuperLU variables */
+       SuperMatrix At, AtP;
+       NLint info, panel_size, relax;
+       superlu_options_t options;
+
+       /* 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; i<n; i++) {
+               __NLRowColumn *Ri = M->row + i;
+               xa[i] = count;
+
+               for(jj=0; jj<Ri->size; 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);
+
+       /* 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 */
+       );
+
+       /* Set superlu options */
+       set_default_options(&options);
+       options.ColPerm = MY_PERMC;
+       options.Fact = DOFACT;
+
+       StatInit(&(context->slu.stat));
+
+       panel_size = sp_ienv(1); /* sp_ienv give us the defaults */
+       relax = sp_ienv(2);
+
+       /* Compute permutation and permuted matrix */
+       context->slu.perm_r = __NL_NEW_ARRAY(NLint, n);
+       context->slu.perm_c = __NL_NEW_ARRAY(NLint, n);
+
+       if ((permutation == NULL) || (*permutation == -1)) {
+               get_perm_c(3, &At, context->slu.perm_c);
+
+               if (permutation)
+                       memcpy(permutation, context->slu.perm_c, sizeof(NLint)*n);
+       }
+       else
+               memcpy(context->slu.perm_c, permutation, sizeof(NLint)*n);
+
+       sp_preorder(&options, &At, context->slu.perm_c, etree, &AtP);
+
+       /* 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);
+
+       /* Cleanup */
+
+       Destroy_SuperMatrix_Store(&At);
+       Destroy_SuperMatrix_Store(&AtP);
+
+       __NL_DELETE_ARRAY(etree);
+       __NL_DELETE_ARRAY(xa);
+       __NL_DELETE_ARRAY(rhs);
+       __NL_DELETE_ARRAY(a);
+       __NL_DELETE_ARRAY(asub);
+
+       context->slu.alloc_slu = NL_TRUE;
+
+       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; i<n; i++) {
+               Ri = &(M->row[i]);
+
+               memset(value, 0.0, sizeof(*value)*n);
+               for(jj=0; jj<Ri->size; jj++)
+                       value[Ri->coeff[jj].index] = Ri->coeff[jj].value;
+
+               for (k = 0; k<n; k++)
+                       printf("%.3f ", value[k]);
+               printf("\n");
+       }
+
+       printf("b:\n");
+       for(i=0; i<n; i++)
+               printf("%f ", b[i]);
+       printf("\n");
+
+       free(value);
+}
 
 /************************************************************************/
 /* nlSolve() driver routine */
 
-NLboolean nlSolve(void) {
-    NLboolean result = NL_TRUE;
+NLboolean nlSolveAdvanced(NLint *permutation, NLboolean solveAgain) {
+       NLboolean result = NL_TRUE;
+
+       __nlCheckState(__NL_STATE_SYSTEM_CONSTRUCTED);
+
+       if (!__nlCurrentContext->solve_again)
+               result = __nlFactorize_SUPERLU(__nlCurrentContext, permutation);
+
+       if (result) {
+               result = __nlInvert_SUPERLU(__nlCurrentContext);
 
-    __nlCheckState(__NL_STATE_SYSTEM_CONSTRUCTED);
-    result = __nlSolve_SUPERLU(NL_TRUE);
+               if (result) {
+                       __nlVectorToVariables();
 
-    __nlVectorToVariables();
-    __nlTransition(__NL_STATE_SYSTEM_CONSTRUCTED, __NL_STATE_SOLVED);
+                       if (solveAgain)
+                               __nlCurrentContext->solve_again = NL_TRUE;
+
+                       __nlTransition(__NL_STATE_SYSTEM_CONSTRUCTED, __NL_STATE_SYSTEM_SOLVED);
+               }
+       }
+
+       return result;
+}
 
-    return result;
+NLboolean nlSolve() {
+       return nlSolveAdvanced(NULL, NL_FALSE);
 }
 
index b6134b5d805db97204934854e205b9ce46003f15..ef99a25239c64eb39f645d60edc8b9ac9b6fd33c 100644 (file)
@@ -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..\..\..\lib\windows\\" /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 BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
index e8a8580bb590551d6e77f5f12602ff786a4f220e..7da591109f5c53604035edb1ab2308a3012c3759 100644 (file)
@@ -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
index 2ce865373dc3ba25f1adfbb80d4a150ce02523bc..c608b3044eae7fbefe09265b0e0a57d6fd5b1d68 100644 (file)
@@ -21,7 +21,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
@@ -73,7 +73,7 @@
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="3"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
                                StringPooling="TRUE"
                                RuntimeLibrary="2"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
                        <Tool
                                Name="VCCLCompilerTool"
                                Optimization="0"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="_DEBUG,WIN32,_LIB,WITH_QUICKTIME"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                        <Tool
                                Name="VCCLCompilerTool"
                                InlineFunctionExpansion="1"
-                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\lib\windows\tiff\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
+                               AdditionalIncludeDirectories="..\..\..\..\lib\windows\jpeg\include;..\..\..\..\lib\windows\zlib\include;..\..\..\..\lib\windows\png\include;..\..\..\..\lib\windows\QTDevWin\CIncludes;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\source\blender\avi;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\quicktime;..\..\..\source\blender\blenkernel;..\..\..\source\blender\blenloader;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf\intern;..\..\..\source\blender\readstreamglue;..\..\..\source\blender\render\extern\include"
                                PreprocessorDefinitions="NDEBUG,WIN32,_LIB,WITH_QUICKTIME"
                                StringPooling="TRUE"
                                RuntimeLibrary="0"
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\divers.c">
                        </File>
-                       <File
-                               RelativePath="..\..\..\source\blender\imbuf\intern\dynlibtiff.c">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\filter.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\targa.c">
                        </File>
-                       <File
-                               RelativePath="..\..\..\source\blender\imbuf\intern\tiff.c">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\util.c">
                        </File>
                <Filter
                        Name="Header Files"
                        Filter="h;hpp;hxx;hm;inl">
-                       <File
-                               RelativePath="..\..\..\source\blender\imbuf\intern\dynlibtiff.h">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\IMB_allocimbuf.h">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\IMB_targa.h">
                        </File>
-                       <File
-                               RelativePath="..\..\..\source\blender\imbuf\intern\IMB_tiff.h">
-                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\imbuf.h">
                        </File>
index 3a0169f2dfb3050af484dedf794a55cbc3e5292c..6025cef7f0e11f1e41da9a25e143542dbb005928 100644 (file)
@@ -123,7 +123,7 @@ def parall_coord(old, dir):
        return (nco,vec)
 
 def get_vert(old, dir):
-       """ Look in NV if a vertex corresponding to the vertex old and the
+       """ 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)
@@ -315,7 +315,7 @@ def make_corners():
                        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 vertex is selected.
+                       # 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]
index 8dadbf3c01c7822364e2bf1d269dd482202cacc0..8680890b0ced49a5bd3175b24b8b745d9ee7424c 100644 (file)
@@ -245,8 +245,8 @@ def read_lwo2(file, filename, typ="LWO2"):
     # init value is: object_list = [[None, {}, [], [], {}, {}, 0, {}, {}]]
     #0 - objname                    #original name
     #1 - obj_dict = {TAG}           #objects created
-    #2 - verts = []                 #object vertices
-    #3 - faces = []                 #object faces (associations poly -> vertices)
+    #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 polygon mapping
     #6 - patch_flag                 #0 = surf; 1 = patch (subdivision surface) - it was the image list
@@ -286,7 +286,7 @@ def read_lwo2(file, filename, typ="LWO2"):
                 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 vertices
+                                        copy.deepcopy(object_list[object_index][2]),   #same vertexes
                                         [],                                            #no faces
                                         {},                                            #no need to copy - filled at runtime
                                         {},                                            #polygon tagging will follow
@@ -363,7 +363,7 @@ def read_verts(lwochunk):
             Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
         x, y, z = struct.unpack(">fff", data.read(12))
         verts[i] = (x, z, y)
-    tobj.pprint("read %d vertices" % (i+1))
+    tobj.pprint("read %d vertexes" % (i+1))
     return verts
 # enddef read_verts
 
@@ -444,7 +444,7 @@ def read_vx(data):
 # ======================
 def read_vmap(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk):
     if maxvertnum == 0:
-        tobj.pprint ("Found VMAP but no vertices to map!")
+        tobj.pprint ("Found VMAP but no vertexes to map!")
         return uvcoords_dict, facesuv_dict
     data = cStringIO.StringIO(lwochunk.read())
     map_type = data.read(4)
@@ -460,7 +460,7 @@ def read_vmap(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk):
         vertnum, vnum_size = read_vx(data)
         u, v = struct.unpack(">ff", data.read(8))
         if vertnum >= maxvertnum:
-            tobj.pprint ("Hem: more uvmap than vertices? ignoring uv data for vertex %d" % vertnum)
+            tobj.pprint ("Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum)
         else:
             my_uv_list[vertnum] = (u, v)
         i += 8 + vnum_size
@@ -483,7 +483,7 @@ def read_vmap(uvcoords_dict, facesuv_dict, faces, 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 vertices to map!")
+        tobj.pprint ("Found VMAD but no vertexes to map!")
         return uvcoords_dict, facesuv_dict
     data = cStringIO.StringIO(lwochunk.read())
     map_type = data.read(4)
@@ -508,19 +508,19 @@ def read_vmad(uvcoords_dict, facesuv_dict, faces, maxvertnum, lwochunk):
         i += vnum_size
         u, v = struct.unpack(">ff", data.read(8))
         if polynum >= maxfacenum or vertnum >= maxvertnum:
-            tobj.pprint ("Hem: more uvmap than vertices? ignorig uv data for vertex %d" % vertnum)
+            tobj.pprint ("Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum)
         else:
             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 vertices
+            #end loop on current face vertexes
         i += 8
     #end loop on uv pairs
     uvcoords_dict[name] = my_uv_list
     facesuv_dict[name] = my_facesuv_list
-    tobj.pprint ("updated %d vertices data" % (newindex-lastindex))
+    tobj.pprint ("updated %d vertexes data" % (newindex-lastindex))
     return uvcoords_dict, facesuv_dict
 
 
@@ -916,7 +916,7 @@ def dist_vector (head, tail): #vector from head to tail
 # ================
 def find_ear(normal, list_dict, verts, face):
     nv = len(list_dict['MF'])
-    #looping through vertices trying to find an ear
+    #looping through vertexes trying to find an ear
     #most likely in case of panic
     mlc = 0
     mla = 1
@@ -974,10 +974,10 @@ def find_ear(normal, list_dict, verts, face):
                         concave_inside = 1
                         break
                 #endif found a concave vertex
-            #end loop looking for concave vertices
+            #end loop looking for concave vertexes
             if (concave == 0) or (concave_inside == 0):
-                #no concave vertices in polygon (should not be): return immediately
-                #looped all concave vertices and no one inside found
+                #no concave vertexes in polygon (should not be): return immediately
+                #looped all concave vertexes and no one inside found
                 return [c, a, b]
         #no convex vertex, try another one
     #end loop to find a suitable base vertex for ear
@@ -1003,12 +1003,12 @@ def reduce_face(verts, face):
     list_dict['P'] = [None] * nv
     #list of distances
     for mvi in list_dict['MF']:
-        #vector between two vertices
+        #vector between two vertexes
         mvi_hiend = (mvi+1) % nv      #last-to-first
         vi_hiend = face[mvi_hiend] #vertex
         vi = face[mvi]
         list_dict['D'][mvi] = dist_vector(verts[vi_hiend], verts[vi])
-    #list of cross products - normals evaluated into vertices
+    #list of cross products - normals evaluated into vertexes
     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]])
@@ -1050,8 +1050,8 @@ def reduce_face(verts, face):
             list_dict['P'].pop(ct[1])
             one_concave = reduce(lambda x, y: (x) or (y<0.0), list_dict['P'], 0)
             nv -=1
-        else: #here if no more concave vertices
-            if nv == 4: break  #quads only if no concave vertices
+        else: #here if no more concave vertexes
+            if nv == 4: break  #quads only if no concave vertexes
             decomposition_list.append([list_dict['MF'][0], list_dict['MF'][1], list_dict['MF'][2]])
             #physical removal
             list_dict['MF'].pop(1)
@@ -1152,7 +1152,7 @@ def my_create_mesh(complete_vertlist, complete_facelist, current_facelist, objna
 
     mesh = Blender.NMesh.GetRaw()
 
-    #append vertices
+    #append vertexes
     jj = 0
     for i in range(len(complete_vertlist)):
         if vertex_map[i] == 1:
@@ -1161,7 +1161,7 @@ def my_create_mesh(complete_vertlist, complete_facelist, current_facelist, objna
             mesh.verts.append(Blender.NMesh.Vert(x, y, z))
             vertex_map[i] = jj
             jj += 1
-    #end sweep over vertices
+    #end sweep over vertexes
 
     #append faces
     for i in range(len(cur_ptag_faces)):
@@ -1172,7 +1172,7 @@ def my_create_mesh(complete_vertlist, complete_facelist, current_facelist, objna
         #for vi in cur_ptag_faces[i]:
             index = vertex_map[vi]
             face.v.append(mesh.verts[index])
-        #end sweep over vertices
+        #end sweep over vertexes
         mesh.faces.append(face)
     #end sweep over faces
 
index bf02c323f61d90ca97352bffd6f4b83746adb0a0..78d173d88fb0363c445df8b0762d0fee7193460e 100644 (file)
@@ -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:<br>
-        Jean-Michel Soler (jms) wrote TGA functions used by this script.<br>
-        Zaz added the default path code and Selected Face option.<br>
-        Macouno fixed a rounding error in the step calculations<br>
+    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:<br>
 # 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)
index 905b6d3bf74c9f5840349744741eaaf8dd47a035..a8d9693f62f118dd00ada5648dd7415a9b66a081 100644 (file)
@@ -158,7 +158,6 @@ 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);
index fcdbed10ffa6b83b287066044cfaee2b95fcc981..16a320010eca9b76d603de62c7bd6a1fd71d0e53 100644 (file)
@@ -48,16 +48,18 @@ 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);
+
+struct Material *get_active_matlayer(struct Material *ma);
 void init_render_material(struct Material *ma);
 void init_render_materials(void);
-void end_render_material(struct Material *ma);
-void end_render_materials(void);
+
 void automatname(struct Material *ma);
 void delete_material_index(void);            
 
index a18a43fb7b8e6458b6bed188dd41cfaef9027579..f0b05802e97e22c51d6d47862076ee7fe2d4093c 100644 (file)
 #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) )
index 457c6a2d7e58a0b43ee0d054dd6112a60abf8122..778cb71f99a6592c6a03efb41f758fc21f9477a4 100644 (file)
@@ -206,8 +206,6 @@ int BPY_call_importloader(char *name)
 
 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;}
index 9273bd8eb712a43ce01b115fa4904003db85d8b2..b143def9f322b2c41429b290e1b9f46b8b745bfe 100644 (file)
@@ -726,15 +726,6 @@ static void init_fastshade_for_ob(Object *ob, int *need_orco_r, float mat[4][4],
                }
        }
 }
-static void end_fastshade_for_ob(Object *ob)
-{
-       int a;
-
-       for(a=0; a<ob->totcol; 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)
 {
@@ -846,7 +837,6 @@ 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)
@@ -986,8 +976,6 @@ void shadeDispList(Object *ob)
                        dl= dl->next;
                }
        }
-       
-       end_fastshade_for_ob(ob);
 }
 
 void reshadeall_displist(void)
@@ -1999,8 +1987,6 @@ void imagestodisplist(void)
                base= base->next;
        }
        
-       end_render_textures();
-       
        allqueue(REDRAWVIEW3D, 0);
 }
 
index d303a7ed5bd59c250778937d1db6db2ff480131e..ef5a29020d4f7b99e3b44eca82e7c929e057dd61 100644 (file)
 #include <string.h>
 #include "MEM_guardedalloc.h"
 
+#include "DNA_curve_types.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_meta_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_blender.h"
+#include "BKE_displist.h"
 #include "BKE_global.h"
-#include "BKE_main.h"
-
-#include "BKE_mesh.h"
 #include "BKE_library.h"
-#include "BKE_displist.h"
+#include "BKE_main.h"
 #include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_utildefines.h"
 
 #include "BPY_extern.h"
 
+/* not material itself */
 void free_material(Material *ma)
 {
-       int a;
+       MaterialLayer *ml;
        MTex *mtex;
+       int a;
 
        BPY_free_scriptlink(&ma->scriptlink);
        
@@ -74,6 +75,11 @@ void free_material(Material *ma)
        
        if(ma->ramp_col) MEM_freeN(ma->ramp_col);
        if(ma->ramp_spec) MEM_freeN(ma->ramp_spec);
+       
+       for(ml= ma->layers.first; ml; ml= ml->next)
+               if(ml->mat) ml->mat->id.us--;
+       
+       BLI_freelistN(&ma->layers);
 }
 
 void init_material(Material *ma)
@@ -115,8 +121,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->pr_lamp= 3;                 /* two lamps, is bits */
+       ma->ml_flag= ML_RENDER; /* default render base material for layers */
+
        ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_TANGENT_STR;
 }
 
@@ -134,6 +141,7 @@ Material *add_material(char *name)
 Material *copy_material(Material *ma)
 {
        Material *man;
+       MaterialLayer *ml;
        int a;
        
        man= copy_libblock(ma);
@@ -149,9 +157,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);
        
+       duplicatelist(&man->layers, &ma->layers);
+       for(ml= man->layers.first; ml; ml= ml->next)
+               id_us_plus((ID *)ml->mat);
+
        return man;
 }
 
@@ -245,9 +258,25 @@ void make_local_material(Material *ma)
                new_id(0, (ID *)ma, 0);
        }
        else if(local && lib) {
+               Material *mat;
+               MaterialLayer *ml;
+               
                man= copy_material(ma);
                man->id.us= 0;
                
+               /* do material layers */
+               for(mat= G.main->mat.first; mat; mat= mat->id.next) {
+                       if(mat->id.lib==NULL) {
+                               for(ml= mat->layers.first; ml; ml= ml->next) {
+                                       if(ml->mat==ma) {
+                                               ml->mat= man;
+                                               man->id.us++;
+                                               ma->id.us--;
+                                       }
+                               }
+                       }
+               }
+               
                /* do objects */
                ob= G.main->object.first;
                while(ob) {
@@ -534,6 +563,18 @@ void new_material_to_objectdata(Object *ob)
        ob->actcol= ob->totcol;
 }
 
+Material *get_active_matlayer(Material *ma)
+{
+       MaterialLayer *ml;
+       
+       if(ma==NULL) return NULL;
+       
+       for(ml= ma->layers.first; ml; ml= ml->next)
+               if(ml->flag & ML_ACTIVE) break;
+       if(ml)
+               return ml->mat;
+       return ma;
+}
 
 void init_render_material(Material *ma)
 {
@@ -586,43 +627,30 @@ void init_render_material(Material *ma)
        ma->ambg= ma->amb*R.wrld.ambg;
        ma->ambb= ma->amb*R.wrld.ambb;
        
+       /* will become or-ed result of all layer modes */
+       ma->mode_l= ma->mode;
 }
 
 void init_render_materials()
 {
        Material *ma;
+       MaterialLayer *ml;
        
-       ma= G.main->mat.first;
-       while(ma) {
+       /* 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);
-               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;
+       for(ma= G.main->mat.first; ma; ma= ma->id.next) {
+               for(ml= ma->layers.first; ml; ml= ml->next) {
+                       if(ml->mat) {
+                               ma->texco |= ml->mat->texco;
+                               ma->mode_l |= ml->mat->mode;
+                       }
                }
-       }
-}
-
-void end_render_materials()
-{
-       Material *ma;
-       
-       ma= G.main->mat.first;
-       while(ma) {
-               if(ma->id.us) end_render_material(ma);
-               ma= ma->id.next;
-       }
-       
+       }       
 }
 
-
 /* ****************** */
 
 char colname_array[125][20]= {
index 1fb001636444c91f476e3f3480bc08b295b61b62..5207c79b0cad3765d7ef1d7db92fdecc3452f10a 100644 (file)
@@ -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 *****
  *
  */
 
@@ -1983,6 +1976,7 @@ static void direct_link_texture(FileData *fd, Tex *tex)
 static void lib_link_material(FileData *fd, Main *main)
 {
        Material *ma;
+       MaterialLayer *ml;
        MTex *mtex;
        int a;
 
@@ -2000,6 +1994,10 @@ static void lib_link_material(FileData *fd, Main *main)
                                }
                        }
                        lib_link_scriptlink(fd, &ma->id, &ma->scriptlink);
+                       
+                       for (ml=ma->layers.first; ml; ml=ml->next)
+                               ml->mat= newlibadr_us(fd, ma->id.lib, ml->mat);
+                               
                        ma->id.flag -= LIB_NEEDLINK;
                }
                ma= ma->id.next;
@@ -2010,8 +2008,6 @@ static void direct_link_material(FileData *fd, Material *ma)
 {
        int a;
 
-       direct_link_scriptlink(fd, &ma->scriptlink);
-
        for(a=0; a<MAX_MTEX; a++) {
                ma->mtex[a]= newdataadr(fd, ma->mtex[a]);
        }
@@ -2019,6 +2015,10 @@ 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);
+       
+       link_list(fd, &ma->layers);
+
 }
 
 /* ************ READ MESH ***************** */
@@ -5082,6 +5082,10 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF;
                                ma->pad= 1;
                        }
+                       /* orange stuff, so should be done for 2.40 too */
+                       if(ma->layers.first==NULL) {
+                               ma->ml_flag= ML_RENDER;
+                       }
                }
        }
        
@@ -5301,6 +5305,7 @@ static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
 
 static void expand_material(FileData *fd, Main *mainvar, Material *ma)
 {
+       MaterialLayer *ml;
        int a;
 
        for(a=0; a<MAX_MTEX; a++) {
@@ -5309,7 +5314,13 @@ static void expand_material(FileData *fd, Main *mainvar, Material *ma)
                        expand_doit(fd, mainvar, ma->mtex[a]->object);
                }
        }
+       
        expand_doit(fd, mainvar, ma->ipo);
+       
+       for (ml=ma->layers.first; ml; ml=ml->next) {
+               if(ml->mat)
+                       expand_doit(fd, mainvar, ml->mat);
+       }
 }
 
 static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la)
index f941b5f77d2d0b12f51ef2b884d2769e0c9cea31..0fd394428e352d1785adaa077b4fe2abbd20dd2a 100644 (file)
@@ -994,6 +994,7 @@ static void write_textures(WriteData *wd, ListBase *idbase)
 static void write_materials(WriteData *wd, ListBase *idbase)
 {
        Material *ma;
+       MaterialLayer *ml;
        int a;
 
        ma= idbase->first;
@@ -1010,6 +1011,10 @@ 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);
+                       
+                       for (ml=ma->layers.first; ml; ml=ml->next)
+                               writestruct(wd, DATA, "MaterialLayer", 1, ml);
+
                }
                ma= ma->id.next;
        }
index 176bf8c8e68f3ec20cc6b39aba2baa020c589918..f8c73dfdea2a67f6b2c5720ab163a1a80e7a94da 100644 (file)
 #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 */
 
index b5f5a91c50c5ab7b5c64d8a1ea09b5c332c48802..8df5e7255a5e8cc38e5643bfecff9ef21ce94a6c 100644 (file)
@@ -34,6 +34,7 @@
 #define BIF_MESHTOOLS_H
 
 struct Object;
+struct EditVert;
 
 extern void 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
 
index ab36972ea18ef8a33d06b1fdc6b1dcdd4a7e6ba2..05e06afca4e953f43714ffaa9943d3a8d005619c 100644 (file)
 #define B_AUTOFGON             32
 #define B_KNIFE                        0x80
 #define B_PERCENTSUBD  0x40
-
+#define B_MESH_X_MIRROR        0x100
 
 /* DISPLAYMODE */
 #define R_DISPLAYVIEW  0
index 33a074ba46d9f8dd58814743140497f9a201d12c..e62eb268ed995e8cee3be98b52cc7b128842cfe8 100644 (file)
@@ -155,6 +155,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
 #define B_SBUFF                        1104
 #define B_SHADBUF              1105
 #define B_SHADRAY              1106
+#define B_LMTEXPASTE   1107
+#define B_LMTEXCOPY            1108
 
 /* *********************** */
 #define B_MATBUTS              1300
@@ -178,6 +180,8 @@ void test_idbutton_cb(void *namev, void *arg2_unused);
 /* yafray: material preset menu event */
 #define B_MAT_YF_PRESET        1217
 
+#define B_MAT_LAYERBROWSE      1218
+
 /* *********************** */
 #define B_TEXBUTS              1400
 
@@ -249,6 +253,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
 
 
 /* *********************** */
index 463fceaa0a1fd26e4d721fd23c0caaecc2dcc848..c8781a75e2eb8ab2a2575f9989cd0a6d067b5436 100755 (executable)
@@ -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;
index 5ef327502e1491ff1afaa534f5b82838946265c4..395c438c6e3c28a60095141dcde99745219bb0fe 100644 (file)
 #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
@@ -48,20 +47,32 @@ struct Ipo;
 struct Material;
 struct ColorBand;
 
+typedef struct MaterialLayer {
+       struct MaterialLayer *next, *prev;
+       
+       struct Material *mat;
+       float blendfac;
+       short flag, blendmethod, menunr, pad;
+       int pad2;
+       
+} MaterialLayer;
+
 /* WATCH IT: change type? also make changes in ipo.h  */
 
 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 +80,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 pad1;
        
        /* for buttons and render*/
        char rgbsel, texact, pr_type, pad;
-       short pr_back, pr_lamp, septex, pad4;
-       int pad5;
+       short pr_back, pr_lamp, septex, ml_flag;        /* ml_flag is for disable base material */
        
        /* shaders */
        short diff_shader, spec_shader;
@@ -97,6 +107,7 @@ typedef struct Material {
        float rampfac_col, rampfac_spec;
 
        struct MTex *mtex[10];
+       ListBase layers;
        struct Ipo *ipo;
        
        /* dynamic properties */
@@ -107,7 +118,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;
 
@@ -161,7 +172,7 @@ 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
 
 /* spec_shader */
 #define MA_SPEC_COOKTORR       0
@@ -224,6 +235,7 @@ 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
@@ -233,5 +245,13 @@ typedef struct Material {
 /* pr_back */
 #define MA_DARK                        1
 
+/* MaterialLayer flag */
+#define ML_ACTIVE              1
+#define ML_RENDER              2
+#define ML_NEG_NORMAL  4
+#define ML_DIFFUSE             8
+#define ML_SPECULAR            16
+#define ML_ALPHA               32
+
 #endif
 
index fe54a631bdd6eb08fa7e2db023298ac0c8a085e7..6323caeda6c5f96c3e47a5f5a58d7f929aa3160f 100644 (file)
@@ -407,33 +407,6 @@ typedef struct Scene {
 #define R_RADHDR       21
 #define R_TIFF         22
 
-/* **************** 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
-
-/* 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
 #define RAD_PHASE_FACES                2
index e284044a633530c00f03094929ceae2be83f2da4..edc621ba7582175231fc046df1e00c988771c405 100644 (file)
@@ -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
 
index e3eb926192c27970f146c0a4b4e8471e7ab9b836..abde461a9355478366ff2a5bd58902425f592c6c 100644 (file)
@@ -148,9 +148,7 @@ 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);
@@ -162,7 +160,6 @@ void externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg,
 /* envmap (4)                                                                   */
 /* ------------------------------------------------------------------------- */
 struct EnvMap;
-struct Tex;
 
 void    RE_free_envmapdata(struct EnvMap *env);
 void    RE_free_envmap(struct EnvMap *env);
@@ -173,6 +170,9 @@ struct EnvMap *RE_copy_envmap(struct EnvMap *env);
 /* --------------------------------------------------------------------- */
 /* rendercore (12)                                                        */
 /* --------------------------------------------------------------------- */
+struct MaterialLayer;
+struct ShadeResult;
+
 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);
@@ -188,6 +188,7 @@ 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 matlayer_blend(struct MaterialLayer *ml, float blendfac, struct ShadeResult *target, struct ShadeResult *src);
 
 /* --------------------------------------------------------------------- */
 /* ray.c (2)                                                        */
index 3a09ba133ef7402e52d160c9a57017f036106047..ea3463f96aeaba49dbcc85527f9a082c31aa3735 100644 (file)
@@ -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 *****
  */
 
 #ifndef RENDER_TYPES_H
@@ -58,6 +55,15 @@ typedef struct TexResult {
        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
 {
@@ -79,10 +85,11 @@ typedef struct ShadeInput
        
        /* 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], facenor[3], view[3], refcol[4], displace[3], strand, tang[3];
+       float vn[3], vno[3], facenor[3], view[3], refcol[4], displace[3], strand, tang[3];
        
        /* dx/dy OSA coordinates */
        float dxco[3], dyco[3];
@@ -194,9 +201,9 @@ typedef struct VertRen
        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 clip;     
        short flag;                             /* in use for clipping ztra parts */
+       float accum;                    /* accum for radio weighting, and for strand texco static particles */
 } VertRen;
 
 /* ------------------------------------------------------------------------- */
@@ -313,6 +320,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 */
 
index 6b9e13c069f20441ef2405b90d1d0de3bd86b918..9f4600209b5d36ce5c678ceeb6d3fbf5352c10f8 100644 (file)
@@ -68,12 +68,11 @@ enum RE_SkyAlphaBlendingType getSkyBlendingMode(void);
 /**
  * Render the sky at pixel (x, y).
  */
-void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y);
+void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco);
+void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco);
+void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview);
 
-/* 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);
 
index 5163b85d8c0a67ffed6f674cfb2aa2469f3959dd..8f236c502f44f5e0d111e30ed13b21bdf334594f 100644 (file)
 struct HaloRen;
 struct ShadeInput;
 
-typedef struct ShadeResult 
-{
-       float diff[3];
-       float spec[3];
-       float alpha;
-
-} ShadeResult;
-
 typedef struct PixStr
 {
        struct PixStr *next;
@@ -103,7 +95,7 @@ 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);
+void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, float *rco);
 
 /**
  * A cryptic but very efficient way of counting the number of bits that 
index 525f8455aa2bb719ad0668d57ff8cae4dee2c0f5..4b7ac102d80840610d76d723ed3776ee0ff44a1f 100644 (file)
@@ -55,7 +55,7 @@ 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 render_realtime_texture(struct ShadeInput *shi);           
 
 /* imagetexture.h */
index 84eb9d9dfca5ac30bf021647b6ed01d1b6d0d3de..54cfc1742e88375a60fb6611e5ab3edb22ebd054 100644 (file)
@@ -536,7 +536,6 @@ void RE_free_render_data()
        R.rectz= NULL;
        R.rectspare= NULL;
        
-       end_render_material(&defmaterial);
        free_filt_mask();
 }
 
index d0c23f6daf389e3c45f8cdf9d818901591e014a2..9d6e7b421d566fae5c7ce343e809b9333b2b8c0a 100644 (file)
@@ -127,10 +127,11 @@ static void *renderHaloPixel(RE_COLBUFTYPE *collector, float x, float y, int hal
 
 void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int mask)
 {
-    void* data = NULL;
+    void *data = NULL;
+       float rco[3];   /* not used (yet?) */
     
     if (obdata[3] & RE_POLY) {
-               data = shadepixel(x, y, obdata[0], obdata[1], mask, collector);
+               data = shadepixel(x, y, obdata[0], obdata[1], mask, collector, rco);
     }
     else if (obdata[3] & RE_HALO) {
         data = renderHaloPixel(collector, x, y, obdata[1]);
@@ -138,7 +139,7 @@ void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int m
        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);
+        data = shadepixel(x, y, obdata[0], obdata[1], mask, collector, rco);
        }
     return data;
    
@@ -148,7 +149,8 @@ void *renderPixel(RE_COLBUFTYPE *collector, float x, float y, int *obdata, int m
 
 void renderSpotHaloPixel(float x, float y, float* fcol)
 {
-       shadepixel(x, y, 0, 0, 0, fcol);        
+       float rco[3];   /* unused */
+       shadepixel(x, y, 0, 0, 0, fcol, rco);
 }
 
 
@@ -551,7 +553,7 @@ enum RE_SkyAlphaBlendingType getSkyBlendingMode() {
 }
 
 /* This one renders into collector, as always.                               */
-void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y)
+void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco)
 {
 
        switch (keyingType) {
@@ -566,7 +568,7 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y)
                break;
        case RE_ALPHA_SKY:
                /* 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:
@@ -579,7 +581,7 @@ 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(RE_COLBUFTYPE *collector, float fx, float fy, float *rco
 {
        float view[3], dxyview[2];
        
@@ -655,13 +657,13 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy)
                }
        
                /* 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 +700,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;
index d9f94c0be60b3cd2900ce86034cfcee2f6430a89..761f4e7fe0bccf79b9c18889b867c4ff8bdb0e03 100644 (file)
@@ -1623,7 +1623,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);
        }
 }
 
@@ -2118,7 +2118,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac)
                                        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];
index 73d57e453b83eeb932857f0754babc2c520570ca..28eca24856e15f84f116b2db55f8e816fb591be8 100644 (file)
@@ -113,6 +113,48 @@ void calc_view_vector(float *view, float x, float y)
        }
 }
 
+#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;
@@ -158,7 +200,7 @@ void RE_sky_char(float *view, char *col)
 
        dither_value = ( (BLI_frand()-0.5)*R.r.dither_intensity)/256.0; 
        
-       shadeSkyPixelFloat(colf, view, NULL);
+       shadeSkyPixelFloat(colf, view, view, NULL);
        
        f= 255.0*(colf[0]+dither_value);
        if(f<=0.0) col[0]= 0; else if(f>255.0) col[0]= 255;
@@ -1065,65 +1107,84 @@ 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)
+/* 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];
-               *g = facm*(*g) + fac*col[1];
-               *b = facm*(*b) + fac*col[2];
+               if(g) {
+                       *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];
+               if(g) {
+                       *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]);
+               if(g) {
+                       *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);
+               *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];
-               *g -= fac*col[1];
-               *b -= fac*col[2];
+               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(col[1]!=0.0)
-                       *g = facm*(*g) + fac*(*g)/col[1];
-               if(col[2]!=0.0)
-                       *b = facm*(*b) + fac*(*b)/col[2];
+               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]);
-               *g = facm*(*g) + fac*fabs(*g-col[1]);
-               *b = facm*(*b) + fac*fabs(*b-col[2]);
+               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; 
-               tmp= fac*col[1];
-               if(tmp < *g) *g= tmp; 
-               tmp= fac*col[2];
-               if(tmp < *b) *b= 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; 
-               tmp= fac*col[1];
-               if(tmp > *g) *g= tmp; 
-               tmp= fac*col[2];
-               if(tmp > *b) *b= tmp; 
+               if(g) {
+                       tmp= fac*col[1];
+                       if(tmp > *g) *g= tmp; 
+                       tmp= fac*col[2];
+                       if(tmp > *b) *b= tmp; 
+               }
                break;
        }
 
@@ -1300,6 +1361,12 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
        
        memset(shr, 0, sizeof(ShadeResult));
        
+       /* copy all relevant material vars, note, keep this synced with render_types.h */
+       memcpy(&shi->r, &ma->r, 23*sizeof(float));
+       /* set special cases */
+       shi->har= ma->har;
+       if((ma->mode & MA_RAYMIRROR)==0) shi->ray_mirror= 0.0;
+       
        /* separate loop */
        if(ma->mode & MA_ONLYSHADOW) {
                float ir;
@@ -1718,21 +1785,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 +1814,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:
@@ -2006,7 +2066,20 @@ 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 0
+                               {       /* tangent derived from UV, comes back later! (ton) */
+                                       //float s1= uv2[0] - uv1[0];
+                                       //float s2= uv3[0] - uv1[0];
+                                       float t1= uv2[1] - uv1[1];
+                                       float t2= uv3[1] - uv1[1];
+                                       
+                                       shi->vn[0]= (t2 * (v2->co[0]-v1->co[0]) - t1 * (v3->co[0]-v1->co[0])); 
+                                       shi->vn[1]= (t2 * (v2->co[1]-v1->co[1]) - t1 * (v3->co[1]-v1->co[1]));
+                                       shi->vn[2]= (t2 * (v2->co[2]-v1->co[2]) - t1 * (v3->co[2]-v1->co[2]));
+                                       Normalise(shi->vn);
+                                       vlr->flag |= R_TANGENT;
+                               }                                       
+#endif
                                if(mode & MA_FACETEXTURE) {
                                        if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) {
                                                shi->vcol[0]= 1.0;
@@ -2080,10 +2153,23 @@ static float isec_view_line(float *view, float *v3, float *v4)
 }
 #endif
 
-  
+void matlayer_blend(MaterialLayer *ml, float blendfac, ShadeResult *target, ShadeResult *src)
+{
+       
+       if(ml->flag & ML_DIFFUSE)
+               ramp_blend(ml->blendmethod, target->diff, target->diff+1, target->diff+2, blendfac*src->alpha, src->diff);
+       
+       if(ml->flag & ML_SPECULAR)
+               ramp_blend(ml->blendmethod, target->spec, target->spec+1, target->spec+2, blendfac*src->alpha, src->spec);
+       
+       if(ml->flag & ML_ALPHA)
+               ramp_blend(ml->blendmethod, &target->alpha, NULL, NULL, blendfac, &src->alpha);
+}
+
+
 /* 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)
+void *shadepixel(float x, float y, int z, int facenr, int mask, float *col, float *rco)
 {
        ShadeResult shr;
        ShadeInput shi;
@@ -2102,21 +2188,19 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col)
        
        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;
+               Material *mat;
+               MaterialLayer *ml;
                float alpha, fac, zcor;
                
                vlr= RE_findOrAddVlak( (facenr-1) & 0x7FFFFF);
                
                shi.vlr= vlr;
-               shi.mat= vlr->mat;
+               mat= 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 */
@@ -2197,6 +2281,8 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col)
                                }
                        }
                }
+               /* rco might be used for sky texture */
+               VECCOPY(rco, shi.co);
                
                /* cannot normalise earlier, code above needs it at pixel level */
                fac= Normalise(shi.view);
@@ -2280,32 +2366,78 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col)
                        }
                }
                
-               /* ------  main shading loop */
-               shade_lamp_loop(&shi, &shr);
+               /* ------  main shading loop -------- */
+               VECCOPY(shi.vno, shi.vn);
+               
+               if(shi.mat->ml_flag & ML_RENDER) {
 
-               if(shi.translucency!=0.0) {
-                       ShadeResult shr_t;
+                       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);
+                       }
                        
-                       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);
+                       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;
                        }
                }
                else {
-                       // doesnt look 'correct', but is better for preview, plus envmaps dont raytrace this
-                       if(shi.mat->mode & MA_RAYTRANSP) shr.alpha= 1.0;
+                       memset(&shr, 0, sizeof(ShadeResult));
+                       shr.alpha= 1.0f;
                }
                
+               for(ml= shi.mat->layers.first; ml; ml= ml->next) {
+                       if(ml->mat && (ml->flag & ML_RENDER)) {
+                               ShadeResult shrlay;
+                               
+                               shi.mat= ml->mat;
+                               shi.layerfac= ml->blendfac;
+                               VECCOPY(shi.vn, shi.vno);
+                               if(ml->flag & ML_NEG_NORMAL)
+                                       VecMulf(shi.vn, -1.0);
+                               
+                               shade_lamp_loop(&shi, &shrlay); /* clears shrlay */
+                               
+                               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;
+                               }
+                               
+                               matlayer_blend(ml, shi.layerfac, &shr, &shrlay);
+                       }
+               }
+               shi.mat= mat;
+               
+               /* 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);
                
                /* exposure correction */
@@ -2318,7 +2450,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
@@ -2369,15 +2501,15 @@ void *shadepixel(float x, float y, int z, int facenr, int mask, float *col)
 static void shadepixel_sky(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(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);
        }
index ee00396476484256b03f29b87685cb5cc69acb05..b2f7cdfca48230a20836ad0a24a5691272b3577a 100644 (file)
 
 /* ------------------------------------------------------------------------- */
 
+#if 0
+/* proposal for more dynamic allocation of options for render vertices, so we dont
+   have to reserve this space inside vertices */
+typedef struct VertTableNode {
+       VertRen *vert;
+       float *rad;
+       float *sticky;
+       float *strand;
+       float *tangent;
+       float *stress;
+} VertTableNode;
+
+#define RE_STICKY_ELEMS        3
+float *RE_vertren_get_sticky(VertRen *ver, int verify)
+{
+       float *sticky;
+       int a= ver->index>>8;
+       
+       sticky= R.blove[a].sticky;
+       if(sticky==NULL) {
+               if(verify) 
+                       sticky= R.blove[a].sticky= MEM_mallocN(RE_STICKY_ELEMS*sizeof(float), "sticky table");
+               else
+                       return NULL;
+       }
+       sticky+= (nr & 255)*RE_STICKY_ELEMS;
+}
+#endif
+
 VertRen *RE_findOrAddVert(int nr)
 {
        VertRen *v, **temp;
index 55e546a89f93a673504860bb759ffdc1387526aa..344957608fe8795820e1a3a87a4d60743ff76715 100644 (file)
@@ -218,27 +218,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)
@@ -1292,9 +1271,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:
@@ -1825,6 +1804,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;
 
@@ -1965,7 +1951,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;
@@ -2033,6 +2019,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 */                 
index b5b70aa0e0d43d3c497eb22b3aa69e8fda1fb9e8..5ab38b589e832cdfd5682cb172862c8960f1a58c 100644 (file)
@@ -594,7 +594,6 @@ static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector,
        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;
@@ -714,7 +713,7 @@ static int composeStack(int zrow[][RE_PIXELFIELDSIZE], RE_COLBUFTYPE *collector,
        ys= (float)y;
 
        /* code identical for rendering empty sky pixel */
-       renderSkyPixelFloat(collector, xs, ys);
+       renderSkyPixelFloat(collector, xs, ys, NULL);
        cpFloatColV(collector, colbuf);
 
        if(R.flag & R_LAMPHALO) {
@@ -1011,7 +1010,7 @@ 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_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                        */
@@ -1057,7 +1056,7 @@ static void renderZBufLine(int y, RE_COLBUFTYPE *colbuf1, RE_COLBUFTYPE *colbuf2
                        
                        /* This is a bit dirty. Depending on sky-mode, the pixel is      */
                        /* blended in differently.                                       */
-                       renderSkyPixelFloat(collector, x, y);
+                       renderSkyPixelFloat(collector, x, y, NULL);
                        
                        j = sampcol;
                        for(i = 0; i < osaNr; i++, j+=4) { 
index b99f4d8e76876d25e69a75e242483b8a729ead0d..f7480c4cb2f17a57116f7d5cf03c84f65b329476 100644 (file)
@@ -2695,6 +2695,7 @@ int vergzvlak(const void *a1, const void *a2)
  */
 static void shadetrapixel(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));
@@ -2708,7 +2709,7 @@ static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *
                if(vlr->flag & R_FULL_OSA) {
                        for(a=0; a<R.osa; a++) {
                                if(mask & (1<<a)) {
-                                       shadepixel(x+jit[a][0], y+jit[a][1], z, facenr, 1<<a, fcol);
+                                       shadepixel(x+jit[a][0], y+jit[a][1], z, facenr, 1<<a, fcol, rco);
                                        accumcol[0]+= fcol[0];
                                        accumcol[1]+= fcol[1];
                                        accumcol[2]+= fcol[2];
@@ -2729,11 +2730,11 @@ static void shadetrapixel(float x, float y, int z, int facenr, int mask, float *
                        int b= centmask[mask];
                        x= x+centLut[b & 15];
                        y= y+centLut[b>>4];
-                       shadepixel(x, y, z, facenr, mask, fcol);
+                       shadepixel(x, y, z, facenr, mask, fcol, rco);
        
                }
        }
-       else shadepixel(x, y, z, facenr, mask, fcol);
+       else shadepixel(x, y, z, facenr, mask, fcol, rco);
 }
 
 static int addtosampcol(float *sampcol, float *fcol, int mask)
index 07ae6dbcdd2f900b14ec4117ddc8c95782805888..665bd3ce6de1d02342e6ca6e1a203d7c54497ec7 100644 (file)
@@ -2424,8 +2424,6 @@ void RE_freeRotateBlenderScene(void)
 
        free_mesh_orco_hash();
 
-       end_render_textures();
-       end_render_materials();
        end_radio_render();
        if(R.wrld.aosphere) {
                MEM_freeN(R.wrld.aosphere);
index e2deaa475442a1fffed56a9d56c4f83b5864882d..992c4f55902b93c30213e28e68f1ef5ac2a9f3cb 100644 (file)
@@ -105,6 +105,7 @@ source_files = ['B.blend.c',
                 'oops.c',
                 'outliner.c',
                 'splash.jpg.c',
+                'parametrizer.c',
                 'playanim.c',
                 'poseobject.c',
                 'previewrender.c',
index 815282720ea031c729ea4acde259c1c745af2362..8292357698b6eaa7253115c1c53ad874e371a57c 100644 (file)
@@ -3265,6 +3265,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)
index 98d4d5d537ff6e8a9ff47738805704dcf15ac4d4..ca911ee2e79cf24e51b76b1327db61db91c7ad20 100644 (file)
@@ -111,12 +111,9 @@ 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];
@@ -379,17 +376,20 @@ static void drawcolorband_cb(void)
 {
        ID *id, *idfrom;
        
-       buttons_active_id(&id, &idfrom);
+       buttons_active_id(&id, &idfrom);        /* base material, not the matlayer! */
        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);
+               ma= get_active_matlayer(ma);
+               if(ma) {
+                       if(ma->ramp_show==0)
+                               drawcolorband(ma->ramp_col, 10,110,300,30);
+                       else
+                               drawcolorband(ma->ramp_spec, 10,110,300,30);
+               }
        }
 }
 
@@ -759,7 +759,7 @@ void do_texbuts(unsigned short event)
                                do_colorbandbuts(tex->coba, event);
                        }
                        else {
-                               ma= (Material *)id;
+                               ma= get_active_matlayer((Material *)id);
                                if(ma->ramp_show==0) do_colorbandbuts(ma->ramp_col, event);
                                else do_colorbandbuts(ma->ramp_spec, event);
                        }
@@ -1416,7 +1416,7 @@ static void texture_panel_texture(MTex *mtex, Material *ma, World *wrld, Lamp *l
 {
        MTex *mt=NULL;
        uiBlock *block;
-       ID *id, *idfrom;
+       ID *id=NULL, *idfrom;
        int a, yco, loos;
        char str[32];
        
@@ -1425,7 +1425,12 @@ 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;
+       
+       if(ma) idfrom= &ma->id;
+       else if(wrld) idfrom= &wrld->id;
+       else idfrom= &la->id;
 
        uiBlockSetCol(block, TH_BUT_SETTING2);
        if(ma) {
@@ -1726,6 +1731,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;
        
@@ -1743,6 +1750,35 @@ void do_worldbuts(unsigned short event)
                        BIF_preview_changed(G.buts);
                }
                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(G.buts);
+                       scrarea_queue_winredraw(curarea);
+               }
+               break;
        }
 }
 
@@ -1781,10 +1817,10 @@ static void world_panel_mapto(World *wrld)
        
        /* 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_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_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");
        uiBlockEndAlign(block);
 
        uiBlockBeginAlign(block);
@@ -1841,7 +1877,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, "");      
@@ -1854,24 +1890,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_MATPRV, "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_MATPRV, "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_MATPRV, "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_MATPRV, "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_MATPRV, "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_MATPRV, "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_MATPRV, "", 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_MATPRV, "dX",           100,40,100,19, mtex->ofs, -20.0, 20.0, 10, 0, "Fine tunes texture mapping X coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "dY",           100,20,100,19, mtex->ofs+1, -20.0, 20.0, 10, 0, "Fine tunes texture mapping Y coordinate");
+       uiDefButF(block, NUM, B_MATPRV, "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_MATPRV, "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_MATPRV, "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_MATPRV, "sizeZ",        200, 0,100,19, mtex->size+2, -10.0, 10.0, 10, 0, "Sets scaling for the texture's Z size");
        
 }
 
@@ -1977,16 +2020,12 @@ 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 *)wrld, (ID *)G.scene, &(G.buts->menunr), B_WORLDALONE, B_WORLDLOCAL, B_WORLDDELETE, 0, B_KEEPDATA);
 
        if(wrld==NULL) return;
        
@@ -2048,6 +2087,8 @@ static void world_panel_preview(World *wrld)
 
 void do_lampbuts(unsigned short event)
 {
+       static short mtexcopied=0;
+       static MTex mtexcopybuf;
        Lamp *la;
        MTex *mtex;
 
@@ -2091,6 +2132,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(G.buts);
+                       scrarea_queue_winredraw(curarea);
+               }
+               break;
+               
        }
        
        if(event) freefastshade();
@@ -2187,7 +2258,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, "");      
@@ -2198,6 +2269,11 @@ 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);
@@ -2383,7 +2459,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;
        
@@ -2395,11 +2470,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, (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");
@@ -2487,12 +2559,15 @@ 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 */
+       ma = get_active_matlayer(G.buts->lockpoin);
+       
        switch(event) {
        case B_MAT_YF_PRESET: {
-               ma = G.buts->lockpoin;
                switch (ma->YF_preset) {
                        case 0:
                                /* normal mode, no reflection/refraction */
@@ -2572,7 +2647,6 @@ void do_matbuts(unsigned short event)
        case B_MATHALO:
                /* when halo is disabled, clear star flag, this is the same as MA_FACETEXTURE <blush> */
                /* 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);
                }
@@ -2581,7 +2655,6 @@ void do_matbuts(unsigned short event)
                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--;
@@ -2594,7 +2667,6 @@ void do_matbuts(unsigned short event)
                }
                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) {
@@ -2607,9 +2679,12 @@ 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);
@@ -2619,14 +2694,12 @@ void do_matbuts(unsigned short event)
                }
                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;
                        allqueue(REDRAWBUTSSHADING, 0);
@@ -2634,7 +2707,6 @@ void do_matbuts(unsigned short event)
                }
                break;
        case B_MATRAYTRANSP:
-               ma= G.buts->lockpoin;
                if(ma) {
                        ma->mode &= ~MA_ZTRA;
                        allqueue(REDRAWBUTSSHADING, 0);
@@ -2642,7 +2714,6 @@ void do_matbuts(unsigned short event)
                }
                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();
@@ -2654,7 +2725,33 @@ void do_matbuts(unsigned short event)
                        shade_buttons_change_3d();
                }
                break;
-
+       case B_MAT_LAYERBROWSE:
+               ma= G.buts->lockpoin;   /* use base material instead */
+               if(ma) {
+                       MaterialLayer *ml;
+                       
+                       /* the one with a menu set is the browser */
+                       for(ml= ma->layers.first; ml; ml= ml->next) {
+                               if(ml->menunr) {
+                                       if(ml->menunr==32767) {
+                                               if(ml->mat) {
+                                                       ml->mat->id.us--;
+                                                       ml->mat= copy_material(ml->mat);
+                                               }
+                                               else ml->mat= add_material("Layer");
+                                       }
+                                       else {
+                                               ml->mat= BLI_findlink(&G.main->mat, ml->menunr-1);
+                                               ml->mat->id.us++;
+                                       }
+                                       allqueue(REDRAWBUTSSHADING, 0);
+                                       BIF_all_preview_changed();
+                                       
+                                       break;
+                               }
+                       }
+               }
+               break;
        }
 }
 
@@ -2715,7 +2812,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);
        
@@ -3078,9 +3175,188 @@ static void material_panel_shading(Material *ma)
                uiDefButBitI(block, TOG, MA_RADIO, 0,   "Radio",                        245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering");
 
        }
+}
+
+static void matlayer_add(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v, *mlnew;
+       
+       mlnew= MEM_callocN(sizeof(MaterialLayer), "mat layer");
+       
+       if(ml==NULL) 
+               BLI_addhead(&ma->layers, mlnew);
+       else
+               BLI_insertlink(&ma->layers, ml, mlnew);
+       
+       mlnew->blendfac= 0.5f;
+       mlnew->flag= ML_RENDER|ML_DIFFUSE|ML_SPECULAR;
+       
+       BIF_undo_push("Add Material Layer");
+       allqueue(REDRAWBUTSSHADING, 0);
+}
+
+static void matlayer_moveUp(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+
+       if (ml->prev) {
+               BLI_remlink(&ma->layers, ml);
+               BLI_insertlink(&ma->layers, ml->prev->prev, ml);
+       }
+       
+       BIF_undo_push("Move Material Layer");
+}
+
+static void matlayer_moveDown(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+       
+       if (ml->next) {
+               BLI_remlink(&ma->layers, ml);
+               BLI_insertlink(&ma->layers, ml->next, ml);
+       }
+       
+       BIF_undo_push("Move Material Layer");
+}
+
+static void matlayer_del(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml= ml_v;
+       
+       BLI_remlink(&ma->layers, ml);
+       if(ml->mat) ml->mat->id.us--;
+       MEM_freeN(ml);
+
+       BIF_undo_push("Delete Material Layer");
+}
+
+static void matlayer_active(void *ma_v, void *ml_v)
+{
+       Material *ma= ma_v;
+       MaterialLayer *ml;
+       
+       for(ml= ma->layers.first; ml; ml= ml->next) {
+               if(ml==ml_v)
+                       ml->flag |= ML_ACTIVE;
+               else
+                       ml->flag &= ~ML_ACTIVE;
+       }
+       BIF_undo_push("Activate Material Layer");
+}
+
+static void material_panel_layers(Material *ma)
+{
+       uiBlock *block;
+       uiBut *but;
+       MaterialLayer *ml;
+       int yco= 155, rb_col;
+       char *strp;
+       
+       block= uiNewBlock(&curarea->uiblocks, "material_panel_layers", UI_EMBOSS, UI_HELV, curarea->win);
+       uiNewPanelTabbed("Preview", "Material");
+       if(uiNewPanel(curarea, block, "Layers", "Material", 0, 0, 318, 204)==0) return;
+       
+       uiNewPanelHeight(block, 204);
+       
+       /* Active button for current material */
+       uiBlockBeginAlign(block);
+       for(ml= ma->layers.first; ml; ml= ml->next)
+               if(ml->flag & ML_ACTIVE) break;
+       
+       if(ml==NULL)
+               but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL,      10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material");
+       else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ",               10, 180, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate base Material");
+       uiButSetFunc(but, matlayer_active, ma, NULL);
+       
+       /* Enable/disable for current material */
+       if(ma->ml_flag & ML_RENDER)
+               uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT,       30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material");
+       else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, 180, 20, 20, &ma->ml_flag, 0.0, 0.0, 0, 0, "Enable or disable base Material");
+       
+       uiBlockEndAlign(block);
+       /* label */
+       uiDefBut(block, LABEL, B_NOP, ma->id.name+2,                    60, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+       /* add layer */
+       but= uiDefBut(block, BUT, B_NOP, "Add Layer", 200, 180,110,20, NULL, 0, 0, 0, 0, "Add a new Material Layer");
+       uiButSetFunc(but, matlayer_add, ma, NULL);
+
+       
+       for(ml= ma->layers.first; ml; ml= ml->next) {
+               
+               /* rounded header */
+               rb_col= (ml->flag & ML_ACTIVE)?40:20;
+               uiDefBut(block, ROUNDBOX, B_DIFF, "", 8, yco-48, 304, 71, NULL, 5.0, 0.0, 3 , rb_col-20, ""); 
+               
+               /* Active button */
+               uiBlockBeginAlign(block);
+               if(ml->flag & ML_ACTIVE)
+                       but=uiDefIconBut(block, BUT, B_MATPRV_DRAW, ICON_MATERIAL,      10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer");
+               else but=uiDefBut(block, BUT, B_MATPRV_DRAW, " ",               10, yco, 20, 20, NULL, 0.0, 0.0, 0, 0, "Activate this layer");
+               uiButSetFunc(but, matlayer_active, ma, ml);
+               
+               /* enable/disable button */
+               if(ml->flag & ML_RENDER)
+                       uiDefIconButBitS(block, TOG, ML_RENDER, B_MATPRV_DRAW, ICON_CHECKBOX_HLT,       30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer");
+               else uiDefButBitS(block, TOG, ML_RENDER, B_MATPRV, " ", 30, yco, 20, 20, &ml->flag, 0.0, 0.0, 0, 0, "Enable or disable this layer");
+               
+               uiBlockBeginAlign(block);
+               
+               /* browse button */
+               IDnames_to_pupstring(&strp, NULL, "ADD NEW %x32767", &(G.main->mat), (ID *)ma, NULL);
+               ml->menunr= 0;
+               uiDefButS(block, MENU, B_MAT_LAYERBROWSE, strp, 60,yco,20,20, &ml->menunr, 0, 0, 0, 0, "Browses existing choices or adds NEW");
+               if(strp) MEM_freeN(strp);
+                       
+               /* name */
+               if(ml->mat) {
+                       but= uiDefBut(block, TEX, B_IDNAME, "MA:",80, yco, 120, 20, ml->mat->id.name+2, 0.0, 19.0, 0, 0, "Rename Material");
+                       uiButSetFunc(but, test_idbutton_cb, ml->mat->id.name, NULL);
+               }
+               else
+                       uiDefBut(block, LABEL, B_NOP, "No Material",80, yco, 120, 20, NULL, 0.0, 0.0, 0, 0, "");
+                       
+               /* add new */
+               but= uiDefBut(block, BUT, B_NOP, "Add", 200, yco,50,20, NULL, 0, 0, 0, 0, "Add a new Material Layer");
+               uiButSetFunc(but, matlayer_add, ma, ml);
+               
+               /* move up/down/delete */
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_UP, 250, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer up");
+               uiButSetFunc(but, matlayer_moveUp, ma, ml);
+               
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_MOVE_DOWN, 270, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move layer down");
+               uiButSetFunc(but, matlayer_moveDown, ma, ml);
+               
+               but = uiDefIconBut(block, BUT, B_MATPRV_DRAW, VICON_X, 290, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete material layer");
+               uiButSetFunc(but, matlayer_del, ma, ml);
+               
+               /* blend slider and operation */
+               uiBlockBeginAlign(block);
+               yco-= 25;
+               uiDefButS(block, MENU, B_MATPRV, "Mix %x0|Add %x1|Subtract %x3|Multiply %x2|Screen %x4|Divide %x5|Difference %x6|Darken %x7|Lighten %x8",
+                                                                                                       35,yco,100,20, &ml->blendmethod, 0, 0, 0, 0, "Blending method for Ramp (uses alpha in Colorband)");
+               uiDefButF(block, NUMSLI, B_MATPRV, "Blend:",135,yco,175,20, &ml->blendfac, 0.0, 1.0, 100, 0, "Blending factor");
+               
+               /* output */
+               yco-=20;
+               uiDefButBitS(block, TOG, ML_DIFFUSE, B_MATPRV,  "Diff",         35,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Diffuse");
+               uiDefButBitS(block, TOG, ML_SPECULAR, B_MATPRV, "Spec", 85,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Specular");
+               uiDefButBitS(block, TOG, ML_ALPHA, B_MATPRV, "Alpha",           135,yco,50,20, &ml->flag, 0, 0, 0, 0, "This Layer affects Alpha");
+               uiDefButBitS(block, TOG, ML_NEG_NORMAL, B_MATPRV, "Negate Normal",      185,yco,125,20, &ml->flag, 0, 0, 0, 0, "Negate normal for this layer");
+               
+               yco-= 30;
+               
+               uiBlockEndAlign(block);
+       }
+       
+       if(yco < 0) uiNewPanelHeight(block, 204-yco);
 
 }
 
+
 static void material_panel_ramps(Material *ma)
 {
        uiBlock *block;
@@ -3163,7 +3439,7 @@ static void material_panel_material(Object *ob, Material *ma)
        if(uiNewPanel(curarea, block, "Material", "Material", 320, 0, 318, 204)==0) return;
 
        /* first do the browse but */
-       buttons_active_id(&id, &idfrom);
+       buttons_active_id(&id, &idfrom);        /* base material, not the matlayer! */
 
        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);
@@ -3204,8 +3480,8 @@ static void material_panel_material(Object *ob, Material *ma)
        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;       
+       ma= get_active_matlayer(ma);
+       if(ma==NULL) return;    
        
        if(ma->dynamode & MA_DRAW_DYNABUTS) {
                uiBlockBeginAlign(block);
@@ -3324,23 +3600,30 @@ void material_panels()
                material_panel_material(ob, ma);
                
                if(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) {
-                                       ma->YF_ar = ma->YF_ag = ma->YF_ab = 1;
-                                       ma->YF_dscale = 1;
-                               }
-                               material_panel_tramir_yafray(ma);
-                       }
-                       material_panel_texture(ma);
+                       material_panel_layers(ma);
                        
-                       mtex= ma->mtex[ ma->texact ];
-                       if(mtex && mtex->tex) {
-                               material_panel_map_input(ob, ma);
-                               material_panel_map_to(ma);
+                       ma= get_active_matlayer(ma);
+                       if(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) {
+                                               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 ];
+                               if(mtex && mtex->tex) {
+                                       material_panel_map_input(ob, ma);
+                                       material_panel_map_to(ma);
+                               }
                        }
                }
        }
@@ -3401,6 +3684,7 @@ void texture_panels()
        if(G.buts->texfrom==0) {
                if(ob) {
                        ma= give_current_material(ob, ob->actcol);
+                       ma= get_active_matlayer(ma);
                        if(ma) mtex= ma->mtex[ ma->texact ];
                }
        }
@@ -3524,8 +3808,8 @@ void clever_numbuts_buts()
                break;
        case TAB_SHADING_MAT:
 
-               ma= G.buts->lockpoin;
-
+               ma= get_active_matlayer(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));
index b470d2ab6afa1eb93d2742288bc1b42bdc2bc8c0..d4654dd671807332da863d1fd56c4d49e84e2a45 100644 (file)
@@ -343,7 +343,6 @@ static void draw_bgpic(void)
                init_render_texture(bgpic->tex);
                free_unused_animimages();
                ima= bgpic->tex->ima;
-               end_render_texture(bgpic->tex);
        }
        else {
                ima= bgpic->ima;
index 2eb59c146f25dd2f2912842b0b80e3f0c3277390..eb77356ecdc74a716afd2028959b2e760382c418 100644 (file)
@@ -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;
 }
 
index 2d1d20c6b8e94b97a0fa60fb5753c5ab1fe9f572..3c568266c05caef84f1ccbe5f4ea2bca252834f6 100644 (file)
@@ -103,16 +103,6 @@ editmesh_mods.c, UI level access, no geometry changes
 
 /* ****************************** 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 +111,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;
index 811dbd79f23c26e9e9ee0921210a7752add4790d..bb5f66e4932f9fcb1174325109357f702748844e 100644 (file)
@@ -3994,6 +3994,40 @@ void single_user(void)
 
 /* ************************************************************* */
 
+/* helper for below, ma was checked to be not NULL */
+static void make_local_makelocalmaterial(Material *ma)
+{
+       MaterialLayer *ml;
+       ID *id;
+       int b;
+       
+       make_local_material(ma);
+       
+       for(b=0; b<MAX_MTEX; b++) {
+               if(ma->mtex[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);      
+       
+       for(ml=ma->layers.first; ml; ml= ml->next) {
+               if(ml->mat) {
+                       make_local_material(ml->mat);
+                       
+                       for(b=0; b<MAX_MTEX; b++) {
+                               if(ml->mat->mtex[b] && ml->mat->mtex[b]->tex) {
+                                       make_local_texture(ml->mat->mtex[b]->tex);
+                               }
+                       }
+                       
+                       id= (ID *)ml->mat->ipo;
+                       if(id && id->lib) make_local_ipo(ml->mat->ipo); 
+               }
+               
+       }
+}
 
 void make_local(void)
 {
@@ -4116,34 +4150,16 @@ void make_local(void)
                                
                                for(a=0; a<ob->totcol; a++) {
                                        ma= ob->mat[a];
-                                       if(ma) {
-                                               make_local_material(ma);
-                                       
-                                               for(b=0; b<MAX_MTEX; b++) {
-                                                       if(ma->mtex[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(ma)
+                                               make_local_makelocalmaterial(ma);
                                }
                                
                                matarar= (Material ***)give_matarar(ob);
                                
                                for(a=0; a<ob->totcol; a++) {
                                        ma= (*matarar)[a];
-                                       if(ma) {
-                                               make_local_material(ma);
-                                       
-                                               for(b=0; b<MAX_MTEX; b++) {
-                                                       if(ma->mtex[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(ma)
+                                               make_local_makelocalmaterial(ma);
                                }
                        }
                }
index b665c64e0e3e245df3024696a24a937196154c74..b95fc9f11bda1316f1d6a12059229b18b3a13f72 100644 (file)
         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);
index 7b992263bb7f5d45b5b653a48205c32ce04bd280..9d8f05aa835a6d1a6ea90bb38f26d2434bdaefa0 100644 (file)
@@ -62,6 +62,7 @@
 #include "BIF_butspace.h"
 
 #include "BKE_armature.h"
+#include "BKE_blender.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
@@ -72,6 +73,7 @@
 #include "BSE_headerbuttons.h"
 
 #include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
 
 #include "blendef.h"
 #include "mydevice.h"
@@ -98,9 +100,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;
        
+       BLI_freelistN(&matcopybuf.layers);
+       
        default_mtex(&mtexcopybuf);
 }
 
@@ -109,6 +114,7 @@ void do_buts_buttons(short event)
        static short matcopied=0;
        MTex *mtex;
        Material *ma;
+       MaterialLayer *ml;
        ID id;
        int a;
        float dx, dy;
@@ -143,9 +149,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 +162,15 @@ void do_buts_buttons(short event)
                                        matcopybuf.mtex[a]= MEM_dupallocN(mtex);
                                }
                        }
+                       duplicatelist(&matcopybuf.layers, &ma->layers);
+                       
                        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,6 +179,10 @@ void do_buts_buttons(short event)
                                if(mtex && mtex->tex) mtex->tex->id.us--;
                                if(mtex) MEM_freeN(mtex);
                        }
+                       for(ml= ma->layers.first; ml; ml= ml->next)
+                               if(ml->mat) ml->mat->id.us--;
+
+                       BLI_freelistN(&ma->layers);
                        
                        id= (ma->id);
                        memcpy(G.buts->lockpoin, &matcopybuf, sizeof(Material));
@@ -184,6 +198,11 @@ void do_buts_buttons(short event)
                                        if(mtex->tex) id_us_plus((ID *)mtex->tex);
                                }
                        }
+                       duplicatelist(&ma->layers, &matcopybuf.layers);
+
+                       for(ml= ma->layers.first; ml; ml= ml->next)
+                               if(ml->mat) ml->mat->id.us++;
+                       
                        BIF_preview_changed(G.buts);
                        BIF_undo_push("Paste material settings");
                        scrarea_queue_winredraw(curarea);
index e0571e94e4562c53aa7b718ddfd432864a15dbcf..35e7c8e577f610643ac36864415431f477435544 100644 (file)
@@ -1013,6 +1013,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 +1050,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 +1103,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;
                
@@ -1176,6 +1181,9 @@ void image_buttons(void)
 
        /* 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;
index c9383d2dded6e69c56eceb09d569c7e76fb4ab5f..d05904c74a82a2eefe47e25019f23e2cfa1cd3af 100644 (file)
@@ -809,6 +809,7 @@ void do_global_buttons(unsigned short event)
                else {
                        if(G.buts->texfrom==0) {        /* from mat */
                                ma= give_current_material(ob, ob->actcol);
+                               ma= get_active_matlayer(ma);
                                if(ma) {
                                        mtex= ma->mtex[ ma->texact ];
                                        if(mtex) {
@@ -861,6 +862,7 @@ void do_global_buttons(unsigned short event)
                        if(event==B_EXTEXBROWSE) {
                                id= NULL;
                                ma= give_current_material(ob, ob->actcol);
+                               ma= get_active_matlayer(ma);
                                if(ma) {
                                        mtex= ma->mtex[ ma->texact ];
                                        if(mtex) id= (ID *)mtex->tex;
@@ -879,6 +881,7 @@ void do_global_buttons(unsigned short event)
                        id= NULL;
                        
                        ma= give_current_material(ob, ob->actcol);
+                       ma= get_active_matlayer(ma);
                        if(ma) {
                                mtex= ma->mtex[ ma->texact ];
                                if(mtex) id= (ID *)mtex->tex;
@@ -1717,7 +1720,13 @@ void do_global_buttons2(short event)
                        ma= give_current_material(ob, ob->actcol);
                        if(ma && ma->id.lib) {
                                if(okee("Make local")) {
+                                       MaterialLayer *ml;
+                                       
                                        make_local_material(ma);
+                                       for(ml= ma->layers.first; ml; ml= ml->next) {
+                                               if(ml->mat)
+                                                       make_local_material(ml->mat);
+                                       }
                                }
                        }
                }
@@ -1790,6 +1799,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= get_active_matlayer(ma);
                        if(ma && ma->id.lib==0) {
                                mtex= ma->mtex[ ma->texact ];
                                if(mtex->tex && mtex->tex->id.us>1) {
@@ -1830,6 +1840,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= get_active_matlayer(ma);
                        if(ma && ma->id.lib==0) {
                                mtex= ma->mtex[ ma->texact ];
                                if(mtex->tex && mtex->tex->id.lib) {
index 54bab5703a34c78ca01d78c571f41c0cfb71ef38..c9892ed7f1edbcbc71946a104aad485b398514ba 100644 (file)
@@ -652,7 +652,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 +696,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) 
index 1ef7320763c0b2c933a1b7bb9cbc02b642fe3d38..2b96bbc20b6dda1f657ffae1f33fe8e0b2af3c32 100644 (file)
@@ -602,7 +602,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)
@@ -620,7 +620,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");
@@ -652,7 +652,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;
@@ -693,7 +693,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;
@@ -706,15 +706,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;
@@ -728,7 +726,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;
@@ -754,21 +752,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");
@@ -777,12 +777,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);
@@ -815,3 +815,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/parametrizer.c b/source/blender/src/parametrizer.c
new file mode 100644 (file)
index 0000000..9ee7d3f
--- /dev/null
@@ -0,0 +1,1877 @@
+
+#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 <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#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,