Wednesday merger of Orange branch and bf-blender
authorTon Roosendaal <ton@blender.org>
Wed, 14 Dec 2005 14:24:23 +0000 (14:24 +0000)
committerTon Roosendaal <ton@blender.org>
Wed, 14 Dec 2005 14:24:23 +0000 (14:24 +0000)
168 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_6_0/elbeem.dsp
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/Makefile
release/scripts/bevel_center.py
release/scripts/bvh_import.py
release/scripts/console.py
release/scripts/lightwave_import.py
release/scripts/uv_export.py
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_bad_level_calls.h
source/blender/blenkernel/BKE_depsgraph.h
source/blender/blenkernel/BKE_displist.h
source/blender/blenkernel/BKE_effect.h
source/blender/blenkernel/BKE_font.h
source/blender/blenkernel/BKE_group.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/BKE_utildefines.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/font.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/nla.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/intern/util.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BDR_drawobject.h
source/blender/include/BDR_unwrapper.h
source/blender/include/BIF_editarmature.h
source/blender/include/BIF_editgroup.h
source/blender/include/BIF_meshtools.h
source/blender/include/BIF_outliner.h
source/blender/include/BIF_poseobject.h
source/blender/include/BIF_resources.h
source/blender/include/BIF_space.h
source/blender/include/BIF_toolbox.h
source/blender/include/BSE_drawview.h
source/blender/include/BSE_filesel.h
source/blender/include/blendef.h
source/blender/include/butspace.h
source/blender/include/transform.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_effect_types.h
source/blender/makesdna/DNA_group_types.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_nla_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/python/api2_2x/Armature.c
source/blender/python/api2_2x/Bone.h
source/blender/radiosity/intern/source/radrender.c
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/envmap.c
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/renderHelp.c
source/blender/render/intern/source/renderPreAndPost.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/butspace.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/buttons_shading.c
source/blender/src/drawaction.c
source/blender/src/drawarmature.c
source/blender/src/drawimasel.c
source/blender/src/drawnla.c
source/blender/src/drawobject.c
source/blender/src/drawview.c
source/blender/src/edit.c
source/blender/src/editaction.c
source/blender/src/editarmature.c
source/blender/src/editconstraint.c
source/blender/src/editgroup.c
source/blender/src/editimasel.c
source/blender/src/editipo.c
source/blender/src/editmesh.c
source/blender/src/editmesh_mods.c
source/blender/src/editnla.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/editview.c
source/blender/src/filesel.c
source/blender/src/header_buttonswin.c
source/blender/src/header_image.c
source/blender/src/header_info.c
source/blender/src/header_oops.c
source/blender/src/header_view3d.c
source/blender/src/headerbuttons.c
source/blender/src/interface_panel.c
source/blender/src/meshtools.c
source/blender/src/outliner.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/poseobject.c
source/blender/src/previewrender.c
source/blender/src/space.c
source/blender/src/toolbox.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/transform_manipulator.c
source/blender/src/unwrapper.c
source/blender/src/view.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 ec6e094efef4b6f8ac7adfb8f5853155bd1d0a24..78b3282b7662f8d4458531fd81c5a9157872abbd 100644 (file)
@@ -70,7 +70,7 @@ PostBuild_Cmds=ECHO copy to lib ...   xcopy /Y .\release\blender_elbeem.lib ..\..\
 # PROP Target_Dir ""
 LINK32=link.exe -lib
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../../../lib/windows/sdl/include" /I "../../../../../lib/windows/zlib/include" /I "../../../../../lib/windows/png/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "NOGUI" /D "ELBEEM_BLENDER" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../../../lib/windows/sdl/include" /I "../../../../../lib/windows/zlib/include" /I "../../../../../lib/windows/png/include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "NOGUI" /D "ELBEEM_BLENDER" /YX /FD /GZ /c
 # ADD BASE RSC /l 0x407 /d "_DEBUG"
 # ADD RSC /l 0x407 /d "_DEBUG"
 BSC32=bscmake.exe
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 d9f7af1bdef6045366aa8fb8f393fc25c4ba6393..31a7f04dbb07b20f5c2fafdb5d6cdf1096dd51d9 100644 (file)
@@ -55,7 +55,14 @@ all:
       ifeq ($(CPU),alpha)
        @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
            COMPRESS="gzip -f --best" EXT2=".gz"
-      else
+      endif
+      ifeq ($(CPU),i386)
+       @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
+           COMPRESS="gzip -f --best" EXT2=".gz"
+       @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
+           COMPRESS="gzip -f --best" EXT2=".gz"
+      endif
+      ifeq ($(CPU),powerpc)
        @$(MAKE) pkg TYPE="" TAR="tar cf" EXT1=".tar" \
            COMPRESS="gzip -f --best" EXT2=".gz"
        @$(MAKE) pkg TYPE="-static" TAR="tar cf" EXT1=".tar" \
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 05f40f018dc71af8ba678816eb70908bba8362ab..17ce01c0cabc871001c9d1b19a5c3d736c3601ef 100644 (file)
@@ -2,14 +2,14 @@
 
 """
 Name: 'Motion Capture (.bvh)...'
-Blender: 239
+Blender: 236
 Group: 'Import'
 Tip: 'Import a (.bvh) motion capture file'
 """
 
 __author__ = "Campbell Barton"
-__url__ = ("blender", "elysiun")
-__version__ = "1.0.4 05/12/04"
+__url__ = ("blender", "elysiun", "http://jmsoler.free.fr/util/blenderfile/py/bvh_import.py")
+__version__ = "1.0.2 04/12/28"
 
 __bpydoc__ = """\
 This script imports BVH motion capture data to Blender.
@@ -21,52 +21,32 @@ Missing:<br>
 Known issues:<br>
 
 Notes:<br>
-        Jean-Michel Soler improved importer to support Poser 3.01 files;<br>
-        Jean-Baptiste Perin wrote a script to create an armature out of the
+   Jean-Michel Soler improved importer to support Poser 3.01 files;<br>
+   Jean-Baptiste Perin wrote a script to create an armature out of the
 Empties created by this importer, it's in the Scripts window -> Scripts -> Animation menu.
 """
 
 # $Id$
 #
 
-#===============================================#
-# BVH Import script 1.05 patched by Campbell    #
-# Modified to use Mathutils for matrix math,    #
-# Fixed possible joint naming bug,              #
-# Imports BVH's with bad EOF gracefully         #
-# Fixed duplicate joint names, make them unique #
-# Use \r as well as \n for newlines             #
-# Added suppot for nodes with 0 motion channels #
-# Rotation IPOs never cross more then 180d      #
-#    fixes sub frame tweening and time scaling  #
-# 5x overall speedup.                           #
-# 06/12/2005,                                   #      
-#===============================================#
-
-#===============================================#
-# BVH Import script 1.04 patched by jms         #
-# Small modif for blender 2.40                  #
-# 04/12/2005,                                   #      
-#===============================================#
-
 #===============================================#
 # BVH Import script 1.03 patched by Campbell    #
 # Small optimizations and scale input           #
-# 01/01/2005,                                   #      
+# 01/01/2005,                                   #  
 #===============================================#
 
 #===============================================#
 # BVH Import script 1.02 patched by Jm Soler    #
-# to the Poser 3.01 bvh file                    #
-# 28/12/2004,                                   #      
+# to the Poser 3.01 bvh file                    # 
+# 28/12/2004,                                   #  
 #===============================================#
 
 #===============================================#
 # BVH Import script 1.0 by Campbell Barton      #
 # 25/03/2004, euler rotation code taken from    #
 # Reevan Mckay's BVH import script v1.1         #
-# if you have any questions about this scrip.   #
-# email me cbarton@metavr.com                   #
+# if you have any questions about this script   #
+# email me ideasman@linuxmail.org               #
 #===============================================#
 
 #===============================================#
@@ -77,7 +57,7 @@ Empties created by this importer, it's in the Scripts window -> Scripts -> Anima
 #===============================================#
 
 # -------------------------------------------------------------------------- 
-# BVH Import v1.05 by Campbell Barton (AKA Ideasman) 
+# BVH Import v0.9 by Campbell Barton (AKA Ideasman) 
 # -------------------------------------------------------------------------- 
 # ***** BEGIN GPL LICENSE BLOCK ***** 
 # 
@@ -88,410 +68,457 @@ Empties created by this importer, it's in the Scripts window -> Scripts -> Anima
 # 
 # This program is distributed in the hope that it will be useful, 
 # but WITHOUT ANY WARRANTY; without even the implied warranty of 
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 # GNU General Public License for more details. 
 # 
 # You should have received a copy of the GNU General Public License 
 # along with this program; if not, write to the Free Software Foundation, 
-# Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA. 
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 # 
 # ***** END GPL LICENCE BLOCK ***** 
 # -------------------------------------------------------------------------- 
 
+
+import string
+import math
 import Blender
 from Blender import Window, Object, Scene, Ipo, Draw
 from Blender.Scene import Render
 
 
-# Attempt to load psyco, speed things up
-try:
-       import psyco
-       psyco.full()    
-       print 'using psyco to speed up BVH importing'
-except:
-       #print 'psyco is not present on this system'
-       pass
-
-
-
-def main():
-       global scale
-       scale = None
-       
-       # Update as we load?
-       debug = 0
-       
-       def getScale():
-               return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
-       
-       
-       #===============================================#
-       # MAIN FUNCTION - All things are done from here #
-       #===============================================#
-       def loadBVH(filename):
-               global scale
-               print '\nBVH Importer 1.05 by Campbell Barton (Ideasman) - cbarton@metavr.com'
-               
-               objectCurveMapping = {}
-               objectNameMapping = {}
-               objectMotiondataMapping = {}
-               
-               # Here we store the Ipo curves in the order they load.
-               channelCurves = []
-               
-               # Object list
-               # We need this so we can loop through the objects and edit there IPO's 
-               # Chenging there rotation to EULER rotation
-               objectList = []
-               
-               if scale == None:
-                       tempscale = getScale()
-                       if tempscale:
-                               scale = tempscale
-                       else:
-                               scale = 0.01
-               
-               Window.WaitCursor(1)
-               # Unique names, dont reuse any of these names.
-               uniqueObNames = [ob.name for ob in Object.Get()]
-               
-               
-               # FUNCTIONS ====================================#
-               def getUniqueObName(name):
-                       i = 0
-                       newname = name[:min(len(name), 12)] # Concatinate to 12 chars
-                       while newname in uniqueObNames:
-                               newname = name + str(i)
-                               i+=1
-                       return newname
-                       
-               # Change the order rotation is applied.
-               RotationMatrix = Blender.Mathutils.RotationMatrix
-               MATRIX_IDENTITY_3x3 = Blender.Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0])
-               def eulerRotate(x,y,z): 
-                       x,y,z = x%360,y%360,z%360 # Clamp all values between 0 and 360, values outside this raise an error.
-                       xmat = RotationMatrix(x,3,'x')
-                       ymat = RotationMatrix(y,3,'y')
-                       zmat = RotationMatrix(z,3,'z')
-                       # Standard BVH multiplication order, apply the rotation in the order Z,X,Y
-                       return (ymat*(xmat * (zmat * MATRIX_IDENTITY_3x3))).toEuler()
-               
-
-               currentFrame = 1 # Set the initial frame to import all data to.
-               
-               #===============================================#
-               # makeJoint: Here we use the node data          #
-               # from the BVA file to create an empty          #
-               #===============================================#
-               BVH2BLEND_TX_NAME = {'Xposition':'LocX','Yposition':'LocY','Zposition':'LocZ','Xrotation':'RotX','Yrotation':'RotY','Zrotation':'RotZ'}
-               def makeJoint(name, parent, offset, channels):
-                       ob = Object.New('Empty', name) # New object, ob is shorter and nicer to use.
-                       
-                       objectNameMapping[name] = ob
-                       scn.link(ob) # place the object in the current scene
-                       ob.sel = 1
-                       
-                       # Make me a child of another empty.
-                       # Vale of None will make the empty a root node (no parent)
-                       if parent[-1]: # != None
-                               obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
-                               obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
-               
-                       # Offset Empty from BVH's initial joint location.
-                       ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
-               
-                       # Add Ipo's for necessary channels
-                       newIpo = Ipo.New('Object', name)
-                       ob.setIpo(newIpo)
-                       obname = ob.name
-                       for channelType in channels:
-                               channelType = BVH2BLEND_TX_NAME[channelType]
-                               curve = newIpo.addCurve(channelType)
-                               curve.setInterpolation('Linear')
-                               objectCurveMapping[(obname, channelType)] = curve
-               
-                       # Add to object list
-                       objectList.append(ob)
-                       
-                       # Redraw if debugging
-                       if debug: Blender.Redraw()
-                       
-                       
-               #===============================================#
-               # makeEnd: Here we make an end node             #
-               # This is needed when adding the last bone      #
-               #===============================================#
-               def makeEnd(parent, offset):
-                       new_name = parent[-1] + '_end'
-                       ob = Object.New('Empty', new_name) # New object, ob is shorter and nicer to use.
-                       objectNameMapping[new_name] = ob
-                       scn.link(ob)
-                       ob.sel = 1
-                       
-                       # Dont check for a parent, an end node MUST have a parent
-                       obParent = objectNameMapping[parent[-1]] # We use this a bit so refrence it here.
-                       obParent.makeParent([ob], 1, 0) #ojbs, noninverse, 1 = not fast.
-               
-                       # Offset Empty
-                       ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) 
-                       
-                       # Redraw if debugging
-                       if debug: Blender.Redraw()
-               # END FUNCTION DEFINITIONS ====================================#
-                       
-               
-               
-               
-               time1 = Blender.sys.time()
-               
-               # Get the current scene.
-               scn = Scene.GetCurrent()
-               #context = scn.getRenderingContext()
-               
-               # DeSelect All
-               for ob in scn.getChildren():
-                       ob.sel = 0
-               
-               # File loading stuff
-               # Open the file for importing
-               file = open(filename, 'r')      
-               
-               # Seperate into a list of lists, each line a list of words.
-               lines = file.readlines()
-               # Non standard carrage returns?
-               if len(lines) == 1:
-                       lines = lines[0].split('\r')
-               
-               # Split by whitespace.
-               lines =[ll for ll in [ [w for w in l.split() if w != '\n' ] for l in lines] if ll]
-               # End file loading code
-       
-               
-               
-               # Create Hirachy as empties
-               if lines[0][0] == 'HIERARCHY':
-                       print 'Importing the BVH Hierarchy for:', filename
-               else:
-                       return 'ERROR: This is not a BVH file'
-               
-               # A liniar list of ancestors to keep track of a single objects heratage
-               # at any one time, this is appended and removed, dosent store tree- just a liniar list.
-               # ZERO is a place holder that means we are a root node. (no parents)
-               parent = [None] 
-               
-               #channelList, sync with objectList:  [[channelType1, channelType2...],  [channelType1, channelType2...)]
-               channelList = []
-               channelIndex = -1
-               
-               lineIdx = 0 # An index for the file.
-               while lineIdx < len(lines) -1:
-                       #...
-                       if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
-                               
-                               # Join spaces into 1 word with underscores joining it.
-                               if len(lines[lineIdx]) > 2:
-                                       lines[lineIdx][1] = '_'.join(lines[lineIdx][1:])
-                                       lines[lineIdx] = lines[lineIdx][:2]
-                               
-                               # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
-                               
-                               # Make sure the names are unique- Object names will match joint names exactly and both will be unique.
-                               name = getUniqueObName(lines[lineIdx][1])
-                               uniqueObNames.append(name)
-                               
-                               print '%snode: %s, parent: %s' % (len(parent) * '  ', name,  parent[-1])
-                               
-                               lineIdx += 2 # Incriment to the next line (Offset)
-                               offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
-                               lineIdx += 1 # Incriment to the next line (Channels)
-                               
-                               # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
-                               # newChannel references indecies to the motiondata,
-                               # if not assigned then -1 refers to the last value that will be added on loading at a value of zero, this is appended 
-                               # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
-                               newChannel = [-1, -1, -1, -1, -1, -1] 
-                               for channel in lines[lineIdx][2:]:
-                                       channelIndex += 1 # So the index points to the right channel
-                                       if channel == 'Xposition':
-                                               newChannel[0] = channelIndex
-                                       elif channel == 'Yposition':
-                                               newChannel[1] = channelIndex
-                                       elif channel == 'Zposition':
-                                               newChannel[2] = channelIndex
-                                       elif channel == 'Xrotation':
-                                               newChannel[3] = channelIndex
-                                       elif channel == 'Yrotation':
-                                               newChannel[4] = channelIndex
-                                       elif channel == 'Zrotation':
-                                               newChannel[5] = channelIndex
-                               
-                               channelList.append(newChannel)
-                               
-                               channels = lines[lineIdx][2:]
-                               
-                               # Call funtion that uses the gatrhered data to make an empty.
-                               makeJoint(name, parent, offset, channels)
-                               
-                               # If we have another child then we can call ourselves a parent, else 
-                               parent.append(name)
-       
-                       # Account for an end node
-                       if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name after 'End Site' but we will ignore it.
-                               lineIdx += 2 # Incriment to the next line (Offset)
-                               offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
-                               makeEnd(parent, offset)
-                               
-                               # Just so we can remove the Parents in a uniform way- End end never has kids
-                               # so this is a placeholder
-                               parent.append(None)
-                       
-                       if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == '}': # == ['}']
-                               parent.pop() # Remove the last item
-                       
-                       #=============================================#
-                       # BVH Structure loaded, Now import motion     #
-                       #=============================================#         
-                       if len(lines[lineIdx]) == 1 and lines[lineIdx][0] == 'MOTION':
-                               print '\nImporting motion data'
-                               lineIdx += 3 # Set the cursor to the first frame
-                               
-                               #=============================================#
-                               # Add a ZERO keyframe, this keeps the rig     #
-                               # so when we export we know where all the     #
-                               # joints start from                           #
-                               #=============================================#
-                               
-                               for obIdx, ob in enumerate(objectList):
-                                       obname = ob.name
-                                       if channelList[obIdx][0] != -1:
-                                               objectCurveMapping[obname, 'LocX'].addBezier((currentFrame,0))
-                                               objectMotiondataMapping[obname, 'LocX'] = []
-                                       if channelList[obIdx][1] != -1:
-                                               objectCurveMapping[obname, 'LocY'].addBezier((currentFrame,0))
-                                               objectMotiondataMapping[obname, 'LocY'] = []
-                                       if channelList[obIdx][2] != -1:
-                                               objectCurveMapping[obname, 'LocZ'].addBezier((currentFrame,0))
-                                               objectMotiondataMapping[obname, 'LocZ'] = []
-                                       if\
-                                       channelList[obIdx][3] != -1 or\
-                                       channelList[obIdx][4] != -1 or\
-                                       channelList[obIdx][5] != -1:
-                                               objectMotiondataMapping[obname, 'RotX'] = []
-                                               objectMotiondataMapping[obname, 'RotY'] = []
-                                               objectMotiondataMapping[obname, 'RotZ'] = []
-                               
-                               #=============================================#
-                               # Loop through frames, each line a frame      #
-                               #=============================================#                 
-                               MOTION_DATA_LINE_LEN = len(lines[lineIdx])
-                               while lineIdx < len(lines):
-                                       line = lines[lineIdx]
-                                       if MOTION_DATA_LINE_LEN != len(line):
-                                               print 'ERROR: Incomplete motion data on line %i, finishing import.' % lineIdx
-                                               break
-                                               
-                                       # Exit loop if we are past the motiondata.
-                                       # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS'
-                                       # I dont know what they do and I dont care, they'll be ignored here.
-                                       if len(line) < len(objectList):
-                                               print '...ending on unknown tags'
-                                               break
-                                       
-                                       
-                                       currentFrame += 1 # Incriment to next frame
-                                                                       
-                                       #=============================================#
-                                       # Import motion data and assign it to an IPO    #
-                                       #=============================================#
-                                       line.append(0.0) # Use this as a dummy var for objects that dont have a loc/rotate channel.
-                                       
-                                       if debug: Blender.Redraw() 
-                                       for obIdx, ob in enumerate(objectList):
-                                               obname = ob.name
-                                               obChannel = channelList[obIdx] 
-                                               if channelList[obIdx][0] != -1:
-                                                       objectMotiondataMapping[obname, 'LocX'].append((currentFrame, scale * float(  line[obChannel[0]]  )))
-                                                       
-                                               if channelList[obIdx][1] != -1:
-                                                       objectMotiondataMapping[obname, 'LocY'].append((currentFrame, scale * float(  line[obChannel[1]]         )))
-
-                                               if channelList[obIdx][2] != -1:
-                                                       objectMotiondataMapping[obname, 'LocZ'].append((currentFrame, scale * float(  line[obChannel[2]]  )))
-                                               
-                                               if obChannel[3] != -1 or obChannel[4] != -1 or obChannel[5] != -1:                                              
-                                                       x, y, z = eulerRotate(float( line[obChannel[3]] ), float( line[obChannel[4]] ), float( line[obChannel[5]] ))
-                                                       x,y,z = x/10.0, y/10.0, z/10.0 # For IPO's 36 is 360d
-                                                       motionMappingRotX = objectMotiondataMapping[obname, 'RotX']
-                                                       motionMappingRotY = objectMotiondataMapping[obname, 'RotY']
-                                                       motionMappingRotZ = objectMotiondataMapping[obname, 'RotZ']
-                                                       
-                                                       # Make interpolation not cross between 180d, thjis fixes sub frame interpolation and time scaling.
-                                                       # Will go from (355d to 365d) rather then to (355d to 5d) - inbetween these 2 there will now be a correct interpolation.
-                                                       if len(motionMappingRotX) > 1:
-                                                               while (motionMappingRotX[-1][1] - x) > 18: x+=36
-                                                               while (motionMappingRotX[-1][1] - x) < -18: x-=36
-                                                               
-                                                               while (motionMappingRotY[-1][1] - y) > 18: y+=36
-                                                               while (motionMappingRotY[-1][1] - y) < -18: y-=36
-                                                               
-                                                               while (motionMappingRotZ[-1][1] - z) > 18: z+=36
-                                                               while (motionMappingRotZ[-1][1] - z) < -18: z-=36
-                                                       
-                                                       motionMappingRotX.append((currentFrame, x))
-                                                       motionMappingRotY.append((currentFrame, y))
-                                                       motionMappingRotZ.append((currentFrame, z))
-                                               # Done importing motion data #
-                                       
-                                       lineIdx += 1
-                               
-                               #=======================================#
-                               # Now Write the motion to the IPO's     #
-                               #=======================================#
-                               for key, motion_data in objectMotiondataMapping.iteritems():
-                                       
-                                       # Strip the motion data where all the points have the same falue.
-                                       i = len(motion_data) -2
-                                       while i > 0 and len(motion_data) > 2:
-                                               if motion_data[i][1] == motion_data[i-1][1] == motion_data[i+1][1]:
-                                                       motion_data.pop(i)
-                                               i-=1
-                                       # Done stripping.                                               
-                                       
-                                       obname, tx_type = key
-                                       curve = objectCurveMapping[obname, tx_type]
-                                       for point_data in motion_data:
-                                               curve.addBezier( point_data )
-                               # Imported motion to an IPO
-                               
-                               # No point in looking further, when this loop is done
-                               # There is nothine else left to do                      
-                               break
-                               
-                       # Main file loop
-                       lineIdx += 1
-                       
-               print 'bvh import time for %i frames: %.6f' % (currentFrame, Blender.sys.time() - time1)
-               Window.RedrawAll()
-               Window.WaitCursor(0)
-       
-       Blender.Window.FileSelector(loadBVH, "Import BVH")
-       
-       #=============#
-       # TESTING     #
-       #=============#
-       '''
-       #loadBVH('/metavr/mocap/bvh/boxer.bvh')
-       #loadBVH('/metavr/mocap/bvh/dg-306-g.bvh') # Incompleate EOF
-       #loadBVH('/metavr/mocap/bvh/wa8lk.bvh') # duplicate joint names, \r line endings.
-       #loadBVH('/metavr/mocap/bvh/walk4.bvh') # 0 channels
-       scale  = 0.01
-       import os
-       DIR = '/metavr/mocap/bvh/'
-       for f in os.listdir(DIR):
-               if f.endswith('.bvh'):
-                       s = Scene.New(f)
-                       s.makeCurrent()
-                       loadBVH(DIR + f)
-       '''
-if __name__ == '__main__':
-       main()
\ No newline at end of file
+# # PSYCO IS CRASHING ON MY SYSTEM
+# # Attempt to load psyco, speed things up
+# try:
+#   print 'using psyco to speed up BVH importing'
+#   import psyco
+#   psyco.full()
+#  
+# except:
+#   print 'psyco is not present on this system'
+
+# Default scale
+scale = 0.01
+
+# Update as we load?
+debug = 0
+
+# Get the current scene.
+scn = Scene.GetCurrent()
+context = scn.getRenderingContext()
+
+# Here we store the Ipo curves in the order they load.
+channelCurves = []
+
+# Object list
+# We need this so we can loop through the objects and edit there IPO's 
+# Chenging there rotation to EULER rotation
+objectList = []
+
+def getScale():
+       return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
+
+def MAT(m):
+       if len(m) == 3:
+               return Blender.Mathutils.Matrix(m[0], m[1], m[2])
+       elif len(m) == 4:
+               return Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
+
+
+
+#===============================================#
+# eulerRotation: converts X, Y, Z rotation      #
+# to eular Rotation. This entire function       #
+# is copied from Reevan Mckay's BVH script      #
+#===============================================#
+# Vars used in eular rotation funtcion
+DEG_TO_RAD = math.pi/180.0
+RAD_TO_DEG = 180.0/math.pi
+PI=3.14159
+
+def eulerRotate(x,y,z): 
+  #=================================
+  def RVMatMult3 (mat1,mat2):
+  #=================================
+    mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
+    for i in range(3):
+      for k in range(3):
+        for j in range(3):
+          mat3[i][k]=mat3[i][k]+mat1[i][j]*mat2[j][k]
+    return mat3
+  
+  
+  #=================================
+  def  RVAxisAngleToMat3 (rot4):
+  #    Takes a direction vector and
+  #    a rotation (in rads) and
+  #    returns the rotation matrix.
+  #    Graphics Gems I p. 466:
+  #=================================
+    mat3=[[0.0,0.0,0.0],[0.0,0.0,0.0],[0.0,0.0,0.0]]
+    if math.fabs(rot4[3])>0.01:
+      s=math.sin(rot4[3])
+      c=math.cos(rot4[3])
+      t=1.0-math.cos(rot4[3])
+    else:
+      s=rot4[3]
+      c=1.0
+      t=0.0
+
+    x=rot4[0]; y=rot4[1]; z=rot4[2]
+    
+    mat3[0][0]=t*x*x+c
+    mat3[0][1]=t*x*y+s*z
+    mat3[0][2]=t*x*z-s*y 
+    
+    mat3[1][0]=t*x*y-s*z
+    mat3[1][1]=t*y*y+c
+    mat3[1][2]=t*y*z+s*x
+    
+    mat3[2][0]=t*x*z+s*y
+    mat3[2][1]=t*y*z-s*x
+    mat3[2][2]=t*z*z+c
+    
+    return mat3
+  eul = [x,y,z]
+  
+  for jj in range(3):
+    while eul[jj] < 0:
+      eul[jj] = eul[jj] + 360.0
+    while eul[jj] >= 360.0:
+      eul[jj] = eul[jj] - 360.0
+
+  eul[0] = eul[0]*DEG_TO_RAD
+  eul[1] = eul[1]*DEG_TO_RAD
+  eul[2] = eul[2]*DEG_TO_RAD
+  
+  xmat=RVAxisAngleToMat3([1,0,0,eul[0]])
+  ymat=RVAxisAngleToMat3([0,1,0,eul[1]])
+  zmat=RVAxisAngleToMat3([0,0,1,eul[2]])
+  
+  mat=[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]]  
+  
+  # Standard BVH multiplication order
+  mat=RVMatMult3 (zmat,mat)
+  mat=RVMatMult3 (xmat,mat)
+  mat=RVMatMult3 (ymat,mat)
+  
+  
+  '''
+  # Screwy Animation Master BVH multiplcation order
+  mat=RVMatMult3 (ymat,mat)
+  mat=RVMatMult3 (xmat,mat)
+  mat=RVMatMult3 (zmat,mat)
+  '''
+  mat = MAT(mat)
+  
+  eul = mat.toEuler()
+  x =- eul[0]/-10
+  y =- eul[1]/-10
+  z =- eul[2]/-10
+  
+  return x, y, z # Returm euler roration values.
+
+
+
+#===============================================#
+# makeJoint: Here we use the node data          #
+# from the BVA file to create an empty          #
+#===============================================#
+def makeJoint(name, parent, prefix, offset, channels):
+  global scale
+  # Make Empty, with the prefix in front of the name
+  ob = Object.New('Empty', prefix + name) # New object, ob is shorter and nicer to use.
+  scn.link(ob) # place the object in the current scene
+  
+  # Offset Empty
+  ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale)
+
+  # Make me a child of another empty.
+  # Vale of None will make the empty a root node (no parent)
+  if parent[-1] != None:
+    obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here.
+    obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast.
+
+  # Add Ipo's for necessary channels
+  newIpo = Ipo.New('Object', prefix + name)
+  ob.setIpo(newIpo)
+  for channelType in channels:
+    if channelType == 'Xposition':
+      newIpo.addCurve('LocX')
+      newIpo.getCurve('LocX').setInterpolation('Linear')
+    if channelType == 'Yposition':
+      newIpo.addCurve('LocY')
+      newIpo.getCurve('LocY').setInterpolation('Linear')
+    if channelType == 'Zposition':
+      newIpo.addCurve('LocZ')
+      newIpo.getCurve('LocZ').setInterpolation('Linear')
+
+    if channelType == 'Zrotation':
+      newIpo.addCurve('RotZ')
+      newIpo.getCurve('RotZ').setInterpolation('Linear')
+    if channelType == 'Yrotation':
+      newIpo.addCurve('RotY')
+      newIpo.getCurve('RotY').setInterpolation('Linear')
+    if channelType == 'Xrotation':
+      newIpo.addCurve('RotX')
+      newIpo.getCurve('RotX').setInterpolation('Linear')
+
+  # Add to object list
+  objectList.append(ob)
+  
+  # Redraw if debugging
+  if debug: Blender.Redraw()
+  
+
+#===============================================#
+# makeEnd: Here we make an end node             #
+# This is needed when adding the last bone      #
+#===============================================#
+def makeEnd(parent, prefix, offset):
+  # Make Empty, with the prefix in front of the name, end nodes have no name so call it its parents name+'_end'
+  ob = Object.New('Empty', prefix + parent[-1] + '_end') # New object, ob is shorter and nicer to use.
+  scn.link(ob)
+  
+  # Dont check for a parent, an end node MUST have a parent
+  obParent = Object.Get(prefix + parent[-1]) # We use this a bit so refrence it here.
+  obParent.makeParent([ob], 0, 1) #ojbs, noninverse, 1 = not fast.
+
+  # Offset Empty
+  ob.setLocation(offset[0]*scale, offset[1]*scale, offset[2]*scale) 
+  
+  # Redraw if debugging
+  if debug: Blender.Redraw()  
+  
+
+
+
+#===============================================#
+# MAIN FUNCTION - All things are done from here #
+#===============================================#
+def loadBVH(filename):
+  global scale
+  print ''
+  print 'BVH Importer 1.0 by Campbell Barton (Ideasman) - ideasman@linuxmail.org'
+  alpha='abcdefghijklmnopqrstuvewxyz'
+  ALPHA=alpha+alpha.upper()
+  ALPHA+=' 0123456789+-{}. '  
+  time1 = Blender.sys.time()
+  tmpScale = getScale()
+  if tmpScale != None:
+    scale = tmpScale
+  
+  # File loading stuff
+  # Open the file for importing
+  file = open(filename, 'r')  
+  fileData = file.readlines()
+  # Make a list of lines
+  lines = []
+  for fileLine in fileData:
+    fileLine=fileLine.replace('..','.')
+    newLine = string.split(fileLine)
+    if newLine != []:
+      t=[]
+      for n in newLine:
+         for n0 in n:
+           if n0 not in ALPHA:
+              n=n.replace(n0,'')  
+         t.append(n)
+      lines.append(t)
+
+    
+  del fileData
+  # End file loading code
+
+  # Call object names with this prefix, mainly for scenes with multiple BVH's - Can imagine most partr names are the same
+  # So in future
+  #prefix = str(len(lines)) + '_'
+  
+  prefix = '_'
+  
+  # Create Hirachy as empties
+  if lines[0][0] == 'HIERARCHY':
+    print 'Importing the BVH Hierarchy for:', filename
+  else:
+    return 'ERROR: This is not a BVH file'
+  
+  # A liniar list of ancestors to keep track of a single objects heratage
+  # at any one time, this is appended and removed, dosent store tree- just a liniar list.
+  # ZERO is a place holder that means we are a root node. (no parents)
+  parent = [None]  
+  
+  #channelList [(<objectName>, [channelType1, channelType2...]),  (<objectName>, [channelType1, channelType2...)]
+  channelList = []
+  channelIndex = -1
+
+  
+
+  lineIdx = 1 # An index for the file.
+  while lineIdx < len(lines) -1:
+    #...
+    if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
+      if lines[lineIdx][0] == 'JOINT' and len(lines[lineIdx])>2:
+         for j in range(2,len(lines[lineIdx])) :
+             lines[lineIdx][1]+='_'+lines[lineIdx][j]
+
+      # MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
+
+      print len(parent) * '  ' + 'node:',lines[lineIdx][1],' parent:',parent[-1]
+      print lineIdx
+      name = lines[lineIdx][1]
+      print name,lines[lineIdx+1],lines[lineIdx+2]
+      lineIdx += 2 # Incriment to the next line (Offset)
+      offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
+      lineIdx += 1 # Incriment to the next line (Channels)
+      
+      # newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
+      # newChannel has Indecies to the motiondata,
+      # -1 refers to the last value that will be added on loading at a value of zero
+      # We'll add a zero value onto the end of the MotionDATA so this is always refers to a value.
+      newChannel = [-1, -1, -1, -1, -1, -1] 
+      for channel in lines[lineIdx][2:]:
+        channelIndex += 1 # So the index points to the right channel
+        if channel == 'Xposition':
+          newChannel[0] = channelIndex
+        elif channel == 'Yposition':
+          newChannel[1] = channelIndex
+        elif channel == 'Zposition':
+          newChannel[2] = channelIndex
+        elif channel == 'Xrotation':
+          newChannel[3] = channelIndex
+        elif channel == 'Yrotation':
+          newChannel[4] = channelIndex
+        elif channel == 'Zrotation':
+          newChannel[5] = channelIndex
+      
+      channelList.append(newChannel)
+      
+      channels = lines[lineIdx][2:]
+      
+      # Call funtion that uses the gatrhered data to make an empty.
+      makeJoint(name, parent, prefix, offset, channels)
+      
+      # If we have another child then we can call ourselves a parent, else 
+      parent.append(name)
+
+    # Account for an end node
+    if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name afetr 'End Site' but we will ignore it.
+      lineIdx += 2 # Incriment to the next line (Offset)
+      offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
+      makeEnd(parent, prefix, offset)
+
+      # Just so we can remove the Parents in a uniform way- End end never has kids
+      # so this is a placeholder
+      parent.append(None)
+
+    if lines[lineIdx] == ['}']:
+      parent = parent[:-1] # Remove the last item
+
+
+    #=============================================#
+    # BVH Structure loaded, Now import motion     #
+    #=============================================#    
+    if lines[lineIdx] == ['MOTION']:
+      print '\nImporting motion data'
+      lineIdx += 3 # Set the cursor to the forst frame
+      
+      #=============================================#
+      # Loop through frames, each line a frame      #
+      #=============================================#      
+      currentFrame = 1
+      print 'frames: ',
+      
+      
+      #=============================================#
+      # Add a ZERO keyframe, this keeps the rig     #
+      # so when we export we know where all the     #
+      # joints start from                           #
+      #=============================================#  
+      obIdx = 0
+      while obIdx < len(objectList) -1:
+        if channelList[obIdx][0] != -1:
+          objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame,0))
+        if channelList[obIdx][1] != -1:
+          objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame,0))
+        if channelList[obIdx][2] != -1:
+          objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame,0))
+        if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1':
+          objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame,0))
+          objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame,0))
+          objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame,0))
+        obIdx += 1
+      
+      while lineIdx < len(lines):
+        
+        # Exit loop if we are past the motiondata.
+        # Some BVH's have extra tags like 'CONSTRAINTS and MOTIONTAGS'
+        # I dont know what they do and I dont care, they'll be ignored here.
+        if len(lines[lineIdx]) < len(objectList):
+          print '...ending on unknown tags'
+          break
+        
+        
+        currentFrame += 1 # Incriment to next frame
+                
+        #=============================================#
+        # Import motion data and assign it to an IPO  #
+        #=============================================#
+        lines[lineIdx].append('0') # Use this as a dummy var for objects that dont have a rotate channel.
+        obIdx = 0
+        if debug: Blender.Redraw() 
+        while obIdx < len(objectList) -1:
+          if channelList[obIdx][0] != -1:
+            VAL0=lines[lineIdx][channelList[obIdx][0]]  
+            if VAL0.find('.')==-1:
+               VAL0=VAL0[:len(VAL0)-6]+'.'+VAL0[-6:] 
+            objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame, scale * float(VAL0)))
+
+          if channelList[obIdx][1] != -1:
+            VAL1=lines[lineIdx][channelList[obIdx][1]]  
+            if VAL1.find('.')==-1:
+               VAL1=VAL1[:len(VAL1)-6]+'.'+VAL1[-6:] 
+            objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame, scale * float(VAL1)))
+
+          if channelList[obIdx][2] != -1:
+            VAL2=lines[lineIdx][channelList[obIdx][2]]  
+            if VAL2.find('.')==-1:
+               VAL2=VAL2[:len(VAL2)-6]+'.'+VAL2[-6:] 
+            objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame, scale * float(VAL2)))
+          
+          if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1':
+            VAL3=lines[lineIdx][channelList[obIdx][3]]  
+            if VAL3.find('.')==-1:
+               VAL3=VAL3[:len(VAL3)-6]+'.'+VAL3[-6:]
+            VAL4=lines[lineIdx][channelList[obIdx][4]]
+            if VAL4.find('.')==-1:
+               VAL4=VAL4[:len(VAL4)-6]+'.'+VAL4[-6:]
+
+            VAL5=lines[lineIdx][channelList[obIdx][5]] 
+            if VAL5.find('.')==-1:
+               VAL5=VAL5[:len(VAL5)-6]+'.'+VAL5[-6:]
+
+            x, y, z = eulerRotate(float(VAL3), float(VAL4), float(VAL5))
+
+            objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame, x))
+            objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame, y))
+            objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame, z))
+
+          obIdx += 1
+          # Done importing motion data #
+        
+        # lines[lineIdx] = None # Scrap old motion data, save some memory?
+        lineIdx += 1
+      # We have finished now
+      print currentFrame, 'done.'
+     
+      # No point in looking further, when this loop is done
+      # There is nothine else left to do      
+      print 'Imported ', currentFrame, ' frames'
+      break
+      
+    # Main file loop
+    lineIdx += 1
+  print "bvh import time: ", Blender.sys.time() - time1
+
+Blender.Window.FileSelector(loadBVH, "Import BVH")
index c5d2eb5568e24f9934707b450b1f9e4caf9692c9..4ce58e06e10ed387e6d263949507f6d17129d321 100644 (file)
@@ -29,26 +29,6 @@ Usage:<br>
 __author__ = "Campbell Barton AKA Ideasman"
 __url__ = ["http://members.iinet.net.au/~cpbarton/ideasman/", "blender", "elysiun"]
 
-# -------------------------------------------------------------------------- 
-# ***** BEGIN GPL LICENSE BLOCK ***** 
-# 
-# This program is free software; you can redistribute it and/or 
-# modify it under the terms of the GNU General Public License 
-# as published by the Free Software Foundation; either version 2 
-# of the License, or (at your option) any later version. 
-# 
-# This program is distributed in the hope that it will be useful, 
-# but WITHOUT ANY WARRANTY; without even the implied warranty of 
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-# GNU General Public License for more details. 
-# 
-# You should have received a copy of the GNU General Public License 
-# along with this program; if not, write to the Free Software Foundation, 
-# Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA. 
-# 
-# ***** END GPL LICENCE BLOCK ***** 
-# -------------------------------------------------------------------------- 
-
 import Blender
 from Blender import *
 import sys as python_sys
@@ -152,7 +132,7 @@ def unzip(list):
                                this function will fail
        """
        
-       if not list: return ()
+       if len(list) == 0: return ()
        l = []
        for t in range(len(list[0])):
                l.append(map( lambda x,t=t: x[t], list ))
@@ -233,7 +213,7 @@ def rdir(dirString, depth=0):
                        # Dont bother with this data.
                        continue
                
-               if type(dirItem) != types.StringType:
+               if type(dirItem) != type('str'):
                        print dirItem, type(dirItem)
                
                if dirItem not in COLLECTED_VAR_NAMES.keys():
@@ -249,17 +229,17 @@ def rdir(dirString, depth=0):
                #print type(dirItem)
                #if type(dirData) == types.ClassType or \
                #        type(dirData) == types.ModuleType:
-               type_dirData = type(dirData)
-               if type_dirData != types.StringType and\
-               type_dirData != types.DictType and\
-               type_dirData != types.DictionaryType and\
-               type_dirData != types.FloatType and\
-               type_dirData != types.IntType and\
-               type_dirData != types.NoneType and\
-               type_dirData != types.StringTypes and\
-               type_dirData != types.TypeType and\
-               type_dirData != types.TupleType and\
-               type_dirData != types.BuiltinFunctionType:
+               
+               if type(dirData) != types.StringType and\
+               type(dirData) != types.DictType and\
+               type(dirData) != types.DictionaryType and\
+               type(dirData) != types.FloatType and\
+               type(dirData) != types.IntType and\
+               type(dirData) != types.NoneType and\
+               type(dirData) != types.StringTypes and\
+               type(dirData) != types.TypeType and\
+               type(dirData) != types.TupleType and\
+               type(dirData) != types.BuiltinFunctionType:
                        # print type(dirData), dirItem
                        # Dont loop up dirs for strings ints etc.
                        if dirItem not in dirStringSplit:
@@ -539,17 +519,16 @@ def handle_event(evt, val):
                                menuList.sort()
                                
                                choice = PupMenuLess( # Menu for the user to choose the autocompleate
-                               'Choices (Shift for local name, Ctrl for Docs)%t|' + # Title Text
+                               'Choices (Shift for Whole name, Ctrl for Docs)%t|' + # Title Text
                                '|'.join(['%s,  %s' % m for m in menuList])) # Use Absolute names m[0]
                                
                                if choice != -1:
                                        if Window.GetKeyQualifiers() & Window.Qual.CTRL:  # Help
                                                cmdBuffer[-1].cmd = ('help(%s%s) ' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0]))    
                                        elif Window.GetKeyQualifiers() & Window.Qual.SHIFT:  # Put in the long name
-                                               cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))    
-                                       else: # Only paste in the Short name
                                                cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][0], cmdBuffer[-1].cmd[cursor:]))    
-                                               
+                                       else: # Only paste in the Short name
+                                               cmdBuffer[-1].cmd = ('%s%s%s' % (cmdBuffer[-1].cmd[:cursor - len(editVar)], menuList[choice-1][1], cmdBuffer[-1].cmd[cursor:]))    
                                                
                else:
                        # print 'NO EDITVAR'
@@ -560,8 +539,11 @@ def handle_event(evt, val):
        # Quit from menu only
        #if (evt == Draw.ESCKEY and not val):
        #       Draw.Exit()
-       if evt == Draw.MOUSEX or evt == Draw.MOUSEY: # AVOID TOO MANY REDRAWS.
-               return  
+       if evt == Draw.MOUSEX: # AVOID TOO MANY REDRAWS.
+               return
+       elif evt == Draw.MOUSEY:
+               return
+       
        
        
        global cursor
@@ -823,4 +805,4 @@ cmdBuffer.append(cmdLine(' ', 0, 0))
 def main():
        Draw.Register(draw_gui, handle_event, handle_button_event)
 
-main()
\ No newline at end of file
+main()
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 eec23b91b9e750cc8e5963af611e16de8158c2d4..1e62dacc1587a28b6f5188a5eb91135ae6faf980 100644 (file)
@@ -47,6 +47,7 @@
 
 struct MVert;
 struct Object;
+struct TFace;
 struct EditMesh;
 struct DispListMesh;
 struct ModifierData;
@@ -143,7 +144,7 @@ struct DerivedMesh {
                        /* Draw all faces uses TFace 
                         *  o Drawing options too complicated to enumerate, look at code.
                         */
-       void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(TFace *tf, int matnr));
+       void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tf, int matnr));
 
                        /* Draw mapped faces (no color, or texture)
                         *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
index 16e8b5652aa0374e55e1563be9974e4623daa854..69fb83aac3075dcdd4f16418ab5309e06cf420d4 100644 (file)
@@ -39,15 +39,18 @@ struct Object;
 struct PartEff;
 struct Scene;
 
+typedef struct DupliObject {
+       struct DupliObject *next, *prev;
+       struct Object *ob;
+       float mat[4][4], omat[4][4];
+} DupliObject;
+
 void free_path(struct Path *path);
 void calc_curvepath(struct Object *ob);
 int interval_test(int min, int max, int p1, int cycl);
 int where_on_path(struct Object *ob, float ctime, float *vec, float *dir);
-void frames_duplilist(struct Object *ob);
-void vertex_duplilist(struct Scene *sce, struct Object *par);
-void particle_duplilist(struct Scene *sce, struct Object *par, struct PartEff *paf);
-void free_duplilist(void);
-void make_duplilist(struct Scene *sce, struct Object *ob);
+
+ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
 int count_duplilist(struct Object *ob);
 
 #endif
index 905b6d3bf74c9f5840349744741eaaf8dd47a035..8a86e88406f4fbddf66b799d755470fc0b89df62 100644 (file)
@@ -88,6 +88,7 @@ float WardIso_Spec(float *n, float *l, float *v, float a, int);
 float Toon_Diff(float *n, float *l, float *v, float a, float b);
 float OrenNayar_Diff(float *n, float *l, float *v, float rough);
 float Minnaert_Diff(float nl, float *n, float *v, float a);
+float Fresnel_Diff(float *vn, float *lv, float *view, float ior, float fac);
 
 void add_to_diffuse(float *, ShadeInput *, float, float, float, float);
 void ramp_diffuse_result(float *diff, ShadeInput *shi);
@@ -158,7 +159,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 5dd820d5a79a7f89a487c526bc98556d7fbb6afb..294f61e54bdc0acb36c3c9441f550b3e0fea883a 100644 (file)
@@ -109,5 +109,5 @@ void        DAG_scene_flush_update(struct Scene *sce, unsigned int lay);
 void   DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag);
 
 void   DAG_pose_sort(struct Object *ob);
-
+               
 #endif
index 2dcf4bfe1be60d100da34b268204c20e2ad219b4..05a1cfc5376941c3025549e80da8d78c8a2257ff 100644 (file)
@@ -75,6 +75,7 @@ if( (cyclv) && a==sizev-1) {                      \
 
 /* prototypes */
 
+struct Base;
 struct Object;
 struct Curve;
 struct ListBase;
@@ -144,7 +145,7 @@ extern void makeDispListMesh(struct Object *ob);
 extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender);
 extern void makeDispListCurveTypes(struct Object *ob, int forOrco);
 extern void makeDispListMBall(struct Object *ob);
-extern void shadeDispList(struct Object *ob);
+extern void shadeDispList(struct Base *base);
 void freefastshade(void);
 void imagestodisplist(void);
 void reshadeall_displist(void);
index c68d4b8b10e57f33c61945ac3f1398ffc7f1abb1..5585735e0b50d22f17a8b8e887b066c5158ca921 100644 (file)
 #ifndef BKE_EFFECT_H
 #define BKE_EFFECT_H
 
+#include "DNA_object_types.h"
+
 struct Effect;
 struct ListBase;
-struct Object;
 struct PartEff;
-struct MTex;
-struct Mesh;
-struct WaveEff;
 struct Particle;
+struct Group;
+
+typedef struct pEffectorCache {
+       struct pEffectorCache *next, *prev;
+       Object *ob;
+       
+       /* precalculated variables */
+       float oldloc[3], oldspeed[3];
+       float scale, time_scale;
+       float guide_dist;
+       
+       Object obcopy;  /* for restoring transformation data */
+} pEffectorCache;
+
 
 struct Effect *add_effect(int type);
 void free_effect(struct Effect *eff);
@@ -57,7 +69,7 @@ void build_particle_system(struct Object *ob);
 /* particle deflector */
 #define PE_WIND_AS_SPEED 0x00000001
 
-struct ListBase *pdInitEffectors(struct Object *ob);
+struct ListBase *pdInitEffectors(struct Object *obsrc, struct Group *group);
 void                   pdEndEffectors(struct ListBase *lb);
 void                   pdDoEffectors(struct ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags);
 
index 00a994672bef1176460ef040debb9f156992664e..05621a4d9b2c53934dc052fa31b7afff75f5aeaa 100644 (file)
@@ -41,6 +41,13 @@ struct Object;
 struct Curve;
 struct objfnt;
 
+struct chartrans {
+       float xof, yof;
+       float rot;
+       short linenr,charnr;
+       char dobreak;
+};
+
 typedef struct SelBox {
        float x, y, w, h;
 } SelBox;
@@ -55,7 +62,7 @@ struct VFont *load_vfont(char *name);
 struct chartrans *text_to_curve(struct Object *ob, int mode);
 int style_to_sel(int style, int toggle);
 int mat_to_sel(void);
-void font_duplilist(struct Object *par);
+
 int getselection(int *start, int *end);
 
 void chtoutf8(unsigned long c, char *o);
index 265d16579c22c136e17d613184d82d4b448aed7a..db4c83040a8d3a3cab096173329d8e2cf2aab17d 100644 (file)
 #define BKE_GROUP_H
 
 struct Group;
-struct GroupKey;
 struct GroupObject;
-struct ObjectKey;
 struct Object;
+struct bAction;
 
-void free_object_key(struct ObjectKey *ok);
-void free_group_object(struct GroupObject *go);
-void free_group(struct Group *group);
+void           free_group_object(struct GroupObject *go);
+void           free_group(struct Group *group);
+void           unlink_group(struct Group *group);
 struct Group *add_group(void);
-void object_to_obkey(struct Object *ob, struct ObjectKey *ok);
-void obkey_to_object(struct ObjectKey *ok, struct Object *ob);
-void add_object_key(struct GroupObject *go, struct GroupKey *gk);
-void add_to_group(struct Group *group, struct Object *ob);
-void rem_from_group(struct Group *group, struct Object *ob);
-void add_group_key(struct Group *group);
-void set_object_key(struct Object *ob, struct ObjectKey *ok);
-void set_group_key(struct Group *group);
+void           add_to_group(struct Group *group, struct Object *ob);
+void           rem_from_group(struct Group *group, struct Object *ob);
 struct Group *find_group(struct Object *ob);
-void set_group_key_name(struct Group *group, char *name);
-void set_group_key_frame(struct Group *group, float frame);
+int                    object_in_group(struct Object *ob, struct Group *group);
+
+void           group_tag_recalc(struct Group *group);
+void           group_handle_recalc_and_update(struct Object *parent, struct Group *group);
+struct Object *group_get_member_with_action(struct Group *group, struct bAction *act);
 
 #endif
 
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 1313ad251e72ea3f61b6f71106e46d15758dc4e6..a7eea6f6393eb8ba04e522861c9ff468bc06a536 100644 (file)
@@ -60,7 +60,7 @@ void free_qtcodecdata(struct QuicktimeCodecData *acd);
 
 void free_scene(struct Scene *me);
 struct Scene *add_scene(char *name);
-int object_in_scene(struct Object *ob, struct Scene *sce);
+struct Base *object_in_scene(struct Object *ob, struct Scene *sce);
 
 void set_scene_bg(struct Scene *sce);
 void set_scene_name(char *name);
index a18a43fb7b8e6458b6bed188dd41cfaef9027579..f784973708d402dc3175f7418b9676302947bbf1 100644 (file)
@@ -1,5 +1,3 @@
-/* util defines  -- might go away ?*/
-
 /* 
        $Id$
 
 #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) )
 
 #define VECADD(v1,v2,v3)       {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);}
 #define VECSUB(v1,v2,v3)       {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);}
+#define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);}
 
 #define INPR(v1, v2)           ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] )
 
index 457c6a2d7e58a0b43ee0d054dd6112a60abf8122..44997480779d7a1b5117d4b09a0f427742599047 100644 (file)
@@ -116,6 +116,7 @@ float WardIso_Spec(float *n, float *l, float *v, float a, int tangent){return 0;
 float Toon_Diff(float *n, float *l, float *v, float a, float b){return 0;}
 float OrenNayar_Diff(float *n, float *l, float *v, float rough){return 0;}
 float Minnaert_Diff(float nl, float *n, float *v, float a){return 0;}
+float Fresnel_Diff(float *vn, float *lv, float *view, float ior, float fac){return 0;}
 
 void add_to_diffuse(float *diff, ShadeInput *shi, float is, float r, float g, float b){}
 void ramp_diffuse_result(float *diff, ShadeInput *shi){}
@@ -206,12 +207,11 @@ 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;}
 void    RE_free_envmapdata(struct EnvMap *env){}
+void init_render_textures(void){}
 
 int     RE_envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt){
    return 0;
index 04c4d180927141d9ed11c37d6f6ede86f8c9eec8..a0713d3a7ddb89aa2d14d1a1489464776be4c74c 100644 (file)
@@ -1823,8 +1823,6 @@ static void mesh_build_data(Object *ob)
        Mesh *me = ob->data;
        float min[3], max[3];
 
-       if(ob->flag&OB_FROMDUPLI) return;
-
        clear_mesh_caches(ob);
 
        if(ob!=G.obedit) {
index 38a07f246dcb4b811b31815a818a0891827df0da..d6bca577013e609949527973e40a742e07bb4fad 100644 (file)
@@ -204,7 +204,7 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name)
        /* If not, create it and add it */
        chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel");
        
-       strcpy (chan->name, name);
+       strncpy (chan->name, name, 31);
        /* init vars to prevent mat errors */
        chan->quat[0] = 1.0F;
        chan->size[0] = chan->size[1] = chan->size[2] = 1.0F;
@@ -346,7 +346,7 @@ bActionChannel *verify_action_channel(bAction *act, const char *name)
        if(chan==NULL) {
                if (!chan) {
                        chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
-                       strcpy (chan->name, name);
+                       strncpy (chan->name, name, 31);
                        BLI_addtail (&act->chanbase, chan);
                }
        }
@@ -831,7 +831,7 @@ static void do_nla(Object *ob, int blocktype)
                        actlength = strip->actend-strip->actstart;
                        striptime = (G.scene->r.cfra-(strip->start)) / length;
                        stripframe = (G.scene->r.cfra-(strip->start)) ;
-
+                       
                        if (striptime>=0.0){
                                
                                if(blocktype==ID_AR) 
@@ -998,6 +998,7 @@ void do_all_pose_actions(Object *ob)
 void do_all_object_actions(Object *ob)
 {
        if(ob==NULL) return;
+       if(ob->dup_group) return;       /* prevent conflicts, might add smarter check later */
        
        /* Do local action */
        if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
index b8178dd98cd07b45945106ed6d81e2025a7887b9..5700be0fcbc6f25e8e7b6b5c6f005457dd6fdf0f 100644 (file)
 #include "BLI_arithb.h"
 #include "DNA_listBase.h"
 
-#include "DNA_object_types.h"
 #include "DNA_curve_types.h"
-#include "DNA_key_types.h"
-#include "DNA_view3d_types.h"
 #include "DNA_effect_types.h"
+#include "DNA_group_types.h"
+#include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_vfont_types.h"
 
+#include "BKE_anim.h"
 #include "BKE_DerivedMesh.h"
+#include "BKE_displist.h"
+#include "BKE_effect.h"
+#include "BKE_font.h"
+#include "BKE_group.h"
 #include "BKE_global.h"
-#include "BKE_utildefines.h"
-#include "BKE_anim.h"
 #include "BKE_ipo.h"
-#include "BKE_object.h"
-#include "BKE_displist.h"
 #include "BKE_key.h"
-#include "BKE_font.h"
-#include "BKE_effect.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
 
 #include "BKE_bad_level_calls.h"
 
@@ -271,32 +275,40 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir)        /* returns OK
        return 1;
 }
 
-static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par)
+/* ****************** DUPLICATOR ************** */
+
+static void new_dupli_object(ListBase *lb, Object *ob, float mat[][4])
 {
-       Object *newob;
-       
-       newob= MEM_mallocN(sizeof(Object), "newobj dupli");
+       DupliObject *dob= MEM_mallocN(sizeof(DupliObject), "dupliobject");
+       BLI_addtail(lb, dob);
+       dob->ob= ob;
+       Mat4CpyMat4(dob->mat, mat);
+       Mat4CpyMat4(dob->omat, ob->obmat);
+}
 
-       memcpy(newob, ob, sizeof(Object));
-       newob->flag |= OB_FROMDUPLI;
-       newob->id.newid= (ID *)par;     /* store duplicator */
+static void group_duplilist(ListBase *lb, Object *ob)
+{
+       GroupObject *go;
+       float mat[4][4];
        
-       /* only basis-ball gets displist */
-       if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL;
-
-       if(ob!=par) {   // dupliverts, particle
-               newob->parent= NULL;
-               newob->track= NULL;
-       }       
-       BLI_addtail(lb, newob);
+       if(ob->dup_group==NULL) return;
        
-       return newob;
+       /* handles animated groups, and */
+       /* we need to check update for objects that are not in scene... */
+       group_handle_recalc_and_update(ob, ob->dup_group);
+       
+       for(go= ob->dup_group->gobject.first; go; go= go->next) {
+               if(go->ob!=ob) {
+                       Mat4MulMat4(mat, go->ob->obmat, ob->obmat);
+                       new_dupli_object(lb, go->ob, mat);
+               }
+       }
 }
 
-void frames_duplilist(Object *ob)
+static void frames_duplilist(ListBase *lb, Object *ob)
 {
        extern int enable_cu_speed;     /* object.c */
-       Object *newob, copyob;
+       Object copyob;
        int cfrao, ok;
        
        cfrao= G.scene->r.cfra;
@@ -315,10 +327,9 @@ void frames_duplilist(Object *ob)
                        else ok= 0;
                }
                if(ok) {
-                       newob= new_dupli_object(&duplilist, ob, ob);
-
-                       do_ob_ipo(newob);
-                       where_is_object_time(newob, (float)G.scene->r.cfra);
+                       do_ob_ipo(ob);
+                       where_is_object_time(ob, (float)G.scene->r.cfra);
+                       new_dupli_object(lb, ob, ob->obmat);
                }
        }
 
@@ -328,6 +339,7 @@ void frames_duplilist(Object *ob)
 }
 
 struct vertexDupliData {
+       ListBase *lb;
        float pmat[4][4];
        Object *ob, *par;
 };
@@ -335,16 +347,15 @@ struct vertexDupliData {
 static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
        struct vertexDupliData *vdd= userData;
-       Object *newob;
-       float vec[3], *q2, mat[3][3], tmat[4][4];
+       float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4];
        
        VECCOPY(vec, co);
        Mat4MulVecfl(vdd->pmat, vec);
        VecSubf(vec, vec, vdd->pmat[3]);
        VecAddf(vec, vec, vdd->ob->obmat[3]);
        
-       newob= new_dupli_object(&duplilist, vdd->ob, vdd->par);
-       VECCOPY(newob->obmat[3], vec);
+       Mat4CpyMat4(obmat, vdd->ob->obmat);
+       VECCOPY(obmat[3], vec);
        
        if(vdd->par->transflag & OB_DUPLIROT) {
                
@@ -353,13 +364,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
                q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag);
                
                QuatToMat3(q2, mat);
-               Mat4CpyMat4(tmat, newob->obmat);
-               Mat4MulMat43(newob->obmat, tmat, mat);
+               Mat4CpyMat4(tmat, obmat);
+               Mat4MulMat43(obmat, tmat, mat);
        }
-       
+       new_dupli_object(vdd->lb, vdd->ob, obmat);
 }
 
-void vertex_duplilist(Scene *sce, Object *par)
+static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par)
 {
        Object *ob;
        Base *base;
@@ -389,6 +400,7 @@ void vertex_duplilist(Scene *sce, Object *par)
                                        struct vertexDupliData vdd;
                                        
                                        ob= base->object;
+                                       vdd.lb= lb;
                                        vdd.ob= ob;
                                        vdd.par= par;
                                        Mat4CpyMat4(vdd.pmat, pmat);
@@ -420,10 +432,9 @@ void vertex_duplilist(Scene *sce, Object *par)
                dm->release(dm);
 }
 
-
-void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
+static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf)
 {
-       Object *ob, *newob;
+       Object *ob, copyob;
        Base *base;
        Particle *pa;
        float ctime, vec1[3];
@@ -439,21 +450,20 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
        }
        
        ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0);
-
+       
        lay= G.scene->lay;
 
-       base= sce->base.first;
-       while(base) {
-               
+       for(base= sce->base.first; base; base= base->next) {
                if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) {
                        ob= base->object->parent;
                        while(ob) {
                                if(ob==par) {
                                
                                        ob= base->object;
+                                       /* temp copy, to have ipos etc to work OK */
+                                       copyob= *ob;
                                        
-                                       pa= paf->keys;
-                                       for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
+                                       for(a=0, pa= paf->keys; a<paf->totpart; a++, pa+=paf->totkey) {
                                                
                                                if(paf->flag & PAF_STATIC) {
                                                        float mtime;
@@ -462,13 +472,12 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
                                                        mtime= pa->time+pa->lifetime;
                                                        
                                                        for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
-                                                               newob= new_dupli_object(&duplilist, ob, par);
                                                                
                                                                /* make sure hair grows until the end.. */ 
                                                                if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
                                                                
                                                                /* to give ipos in object correct offset */
-                                                               where_is_object_time(newob, ctime-pa->time);
+                                                               where_is_object_time(ob, ctime-pa->time);
 
                                                                where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec
                                                                Mat4MulVecfl(par->obmat, vec);
@@ -481,11 +490,12 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
                                                                        q2= vectoquat(vec1, ob->trackflag, ob->upflag);
                                                                        
                                                                        QuatToMat3(q2, mat);
-                                                                       Mat4CpyMat4(tmat, newob->obmat);
-                                                                       Mat4MulMat43(newob->obmat, tmat, mat);
+                                                                       Mat4CpyMat4(tmat, ob->obmat);
+                                                                       Mat4MulMat43(ob->obmat, tmat, mat);
                                                                }
                                                                
-                                                               VECCOPY(newob->obmat[3], vec);
+                                                               VECCOPY(ob->obmat[3], vec);
+                                                               new_dupli_object(lb, ob, ob->obmat);
                                                        }
                                                }
                                                else { // non static particles
@@ -494,10 +504,9 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
                                                        if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue;
 
                                                        //if(ctime < pa->time+pa->lifetime) {
-                                                       newob= new_dupli_object(&duplilist, ob, par);
 
                                                        /* to give ipos in object correct offset */
-                                                       where_is_object_time(newob, ctime-pa->time);
+                                                       where_is_object_time(ob, ctime-pa->time);
                                                        
                                                        where_is_particle(paf, pa, ctime, vec);
                                                        if(paf->stype==PAF_VECT) {
@@ -507,54 +516,129 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
                                                                q2= vectoquat(vec1, ob->trackflag, ob->upflag);
                                        
                                                                QuatToMat3(q2, mat);
-                                                               Mat4CpyMat4(tmat, newob->obmat);
-                                                               Mat4MulMat43(newob->obmat, tmat, mat);
+                                                               Mat4CpyMat4(tmat, ob->obmat);
+                                                               Mat4MulMat43(ob->obmat, tmat, mat);
                                                        }
 
-                                                       VECCOPY(newob->obmat[3], vec);
+                                                       VECCOPY(ob->obmat[3], vec);
+                                                       new_dupli_object(lb, ob, ob->obmat);
                                                }                                       
                                        }
+                                       /* temp copy, to have ipos etc to work OK */
+                                       *ob= copyob;
+                                       
                                        break;
                                }
                                ob= ob->parent;
                        }
                }
-               base= base->next;
        }
 }
 
-
-void free_duplilist()
+static Object *find_family_object(Object **obar, char *family, char ch)
 {
        Object *ob;
+       int flen;
        
-       while( (ob= duplilist.first) ) {
-               BLI_remlink(&duplilist, ob);
-               MEM_freeN(ob);
+       if( obar[ch] ) return obar[ch];
+       
+       flen= strlen(family);
+       
+       ob= G.main->object.first;
+       while(ob) {
+               if( ob->id.name[flen+2]==ch ) {
+                       if( strncmp(ob->id.name+2, family, flen)==0 ) break;
+               }
+               ob= ob->id.next;
        }
        
+       obar[ch]= ob;
+       
+       return ob;
 }
 
-void make_duplilist(Scene *sce, Object *ob)
+
+static void font_duplilist(ListBase *lb, Object *par)
 {
-       PartEff *paf;
+       Object *ob, *obar[256];
+       Curve *cu;
+       struct chartrans *ct, *chartransdata;
+       float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
+       int slen, a;
+       
+       Mat4CpyMat4(pmat, par->obmat);
+       
+       /* in par the family name is stored, use this to find the other objects */
+       
+       chartransdata= text_to_curve(par, FO_DUPLI);
+       if(chartransdata==0) return;
+       
+       memset(obar, 0, 256*sizeof(void *));
+       
+       cu= par->data;
+       slen= strlen(cu->str);
+       fsize= cu->fsize;
+       xof= cu->xof;
+       yof= cu->yof;
+       
+       ct= chartransdata;
+       
+       for(a=0; a<slen; a++, ct++) {
+               
+               ob= find_family_object(obar, cu->family, cu->str[a]);
+               if(ob) {
+                       vec[0]= fsize*(ct->xof - xof);
+                       vec[1]= fsize*(ct->yof - yof);
+                       vec[2]= 0.0;
+                       
+                       Mat4MulVecfl(pmat, vec);
+                       
+                       Mat4CpyMat4(obmat, par->obmat);
+                       VECCOPY(obmat[3], vec);
+                       
+                       new_dupli_object(lb, ob, obmat);
+               }
+               
+       }
+       
+       MEM_freeN(chartransdata);
+}
 
+/* ***************************** */
+
+ListBase *object_duplilist(Scene *sce, Object *ob)
+{
+       static ListBase duplilist={NULL, NULL};
+       
+       if(duplilist.first) {
+               printf("wrong call to object_duplilist\n");
+               return &duplilist;
+       }
+       duplilist.first= duplilist.last= NULL;
+       
        if(ob->transflag & OB_DUPLI) {
                if(ob->transflag & OB_DUPLIVERTS) {
                        if(ob->type==OB_MESH) {
                                if(ob->transflag & OB_DUPLIVERTS) {
-                                       if( (paf=give_parteff(ob)) ) particle_duplilist(sce, ob, paf);
-                                       else vertex_duplilist(sce, ob);
+                                       PartEff *paf;
+                                       if( (paf=give_parteff(ob)) ) particle_duplilist(&duplilist, sce, ob, paf);
+                                       else vertex_duplilist(&duplilist, sce, ob);
                                }
                        }
                        else if(ob->type==OB_FONT) {
-                               font_duplilist(ob);
+                               font_duplilist(&duplilist, ob);
                        }
                }
-               else if(ob->transflag & OB_DUPLIFRAMES) frames_duplilist(ob);
+               else if(ob->transflag & OB_DUPLIFRAMES) 
+                       frames_duplilist(&duplilist, ob);
+               else if(ob->transflag & OB_DUPLIGROUP)
+                       group_duplilist(&duplilist, ob);
        }
+       
+       return &duplilist;
 }
 
+
 int count_duplilist(Object *ob)
 {
        if(ob->transflag & OB_DUPLI) {
index 95a39c29a54faacf0eac8cb92323b01ac91837e7..15116b390cc40aa696efe2f5822e30001d643738 100644 (file)
@@ -84,6 +84,7 @@ bArmature *add_armature()
        
        arm= alloc_libblock (&G.main->armature, ID_AR, "Armature");
        arm->deformflag = ARM_DEF_VGROUP|ARM_DEF_ENVELOPE;
+       arm->layer= 1;
        return arm;
 }
 
index 50ca6bc4fe628a99e86274a50dbccdfec0718902..cdc3bb506c1e0d0e8fbab8609366537b4f193c77 100644 (file)
@@ -46,6 +46,7 @@
 #include "DNA_curve_types.h"
 #include "DNA_ID.h"
 #include "DNA_effect_types.h"
+#include "DNA_group_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_key_types.h"
 #include "DNA_mesh_types.h"
@@ -65,6 +66,7 @@
 #include "BKE_effect.h"
 #include "BKE_global.h"
 #include "BKE_key.h"
+#include "BKE_main.h"
 #include "BKE_mball.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
@@ -310,110 +312,90 @@ static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int
        }
 }
 
-struct DagForest *build_dag(struct Scene *sce, short mask) 
+static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask)
 {
-       Base *base;
-       Object *ob;
        bConstraint *con;
        DagNode * node;
        DagNode * node2;
        DagNode * node3;
-       DagNode * scenenode;
-       DagForest *dag;
-       DagAdjList *itA;
        Key *key;
-
-       dag = sce->theDag;
-       sce->dagisvalid=1;
-       if ( dag)
-               free_forest( dag ); 
-       else {
-               dag = dag_init();
-               sce->theDag = dag;
-       }
+       int addtoroot= 1;
        
-       /* add base node for scene. scene is always the first node in DAG */
-       scenenode = dag_add_node(dag, sce);     
+       node = dag_get_node(dag, ob);
        
-       for(base = sce->base.first; base; base= base->next) {
-               int addtoroot = 1;
-               ob= (Object *) base->object;
-               
-               node = dag_get_node(dag,ob);
-               
-               if ((ob->data) && (mask&DAG_RL_DATA)) {
-                       node2 = dag_get_node(dag,ob->data);
-                       dag_add_relation(dag,node,node2,DAG_RL_DATA);
-                       node2->first_ancestor = ob;
-                       node2->ancestor_count += 1;
-               }
-               
-               if (ob->type == OB_ARMATURE) {
-                       if (ob->pose){
-                               bPoseChannel *pchan;
-                               bConstraint *con;
-                               Object * target;
-                               char *subtarget;
-                               
-                               for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
-                                       for (con = pchan->constraints.first; con; con=con->next){
-                                               if (constraint_has_target(con)) {
+       if ((ob->data) && (mask&DAG_RL_DATA)) {
+               node2 = dag_get_node(dag,ob->data);
+               dag_add_relation(dag,node,node2,DAG_RL_DATA);
+               node2->first_ancestor = ob;
+               node2->ancestor_count += 1;
+       }
+       
+       if (ob->type == OB_ARMATURE) {
+               if (ob->pose){
+                       bPoseChannel *pchan;
+                       bConstraint *con;
+                       Object * target;
+                       char *subtarget;
+                       
+                       for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next){
+                               for (con = pchan->constraints.first; con; con=con->next){
+                                       if (constraint_has_target(con)) {
+                                               
+                                               target = get_constraint_target(con, &subtarget);
+                                               if (target!=ob) {
+                                                       // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
+                                                       node3 = dag_get_node(dag, target);
+                                                       
+                                                       if(subtarget && subtarget[0])
+                                                               dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
+                                                       else
+                                                               dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
                                                        
-                                                       target = get_constraint_target(con, &subtarget);
-                                                       if (target!=ob) {
-                                                               // fprintf(stderr,"armature %s target :%s \n", ob->id.name, target->id.name);
-                                                               node3 = dag_get_node(dag, target);
-                                                               
-                                                               if(subtarget && subtarget[0])
-                                                                       dag_add_relation(dag,node3,node, DAG_RL_OB_DATA|DAG_RL_DATA_DATA);
-                                                               else
-                                                                       dag_add_relation(dag,node3,node, DAG_RL_OB_DATA);
-                                                                       
-                                                       }
                                                }
                                        }
                                }
                        }
                }
-               
-               /* driver dependencies */
-               if(ob->ipo) 
-                       dag_add_driver_relation(ob->ipo, dag, node, 0);
-               
-               key= ob_get_key(ob);
-               if(key && key->ipo)
-                       dag_add_driver_relation(key->ipo, dag, node, 1);
-               
-               if(ob->action) {
-                       bActionChannel *chan;
-                       for (chan = ob->action->chanbase.first; chan; chan=chan->next){
-                               if(chan->ipo)
-                                       dag_add_driver_relation(chan->ipo, dag, node, 1);
-                       }
-               }
-               if(ob->nlastrips.first) {
-                       bActionStrip *strip;
-                       bActionChannel *chan;
-                       for(strip= ob->nlastrips.first; strip; strip= strip->next) {
-                               if(strip->act && strip->act!=ob->action)
-                                       for (chan = strip->act->chanbase.first; chan; chan=chan->next)
-                                               if(chan->ipo)
-                                                       dag_add_driver_relation(chan->ipo, dag, node, 1);
-                       }
+       }
+       
+       /* driver dependencies */
+       if(ob->ipo) 
+               dag_add_driver_relation(ob->ipo, dag, node, 0);
+       
+       key= ob_get_key(ob);
+       if(key && key->ipo)
+               dag_add_driver_relation(key->ipo, dag, node, 1);
+       
+       if(ob->action) {
+               bActionChannel *chan;
+               for (chan = ob->action->chanbase.first; chan; chan=chan->next){
+                       if(chan->ipo)
+                               dag_add_driver_relation(chan->ipo, dag, node, 1);
                }
-               if (ob->modifiers.first) {
-                       ModifierData *md;
-
-                       for(md=ob->modifiers.first; md; md=md->next) {
-                               ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
-                               if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node);
-                       }
+       }
+       if(ob->nlastrips.first) {
+               bActionStrip *strip;
+               bActionChannel *chan;
+               for(strip= ob->nlastrips.first; strip; strip= strip->next) {
+                       if(strip->act && strip->act!=ob->action)
+                               for (chan = strip->act->chanbase.first; chan; chan=chan->next)
+                                       if(chan->ipo)
+                                               dag_add_driver_relation(chan->ipo, dag, node, 1);
                }
-               if (ob->parent) {
-                       node2 = dag_get_node(dag,ob->parent);
+       }
+       if (ob->modifiers.first) {
+               ModifierData *md;
+               
+               for(md=ob->modifiers.first; md; md=md->next) {
+                       ModifierTypeInfo *mti = modifierType_getInfo(md->type);
                        
-                       switch(ob->partype) {
+                       if (mti->updateDepgraph) mti->updateDepgraph(md, dag, ob, node);
+               }
+       }
+       if (ob->parent) {
+               node2 = dag_get_node(dag,ob->parent);
+               
+               switch(ob->partype) {
                        case PARSKEL:
                                dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_OB);
                                break;
@@ -430,89 +412,149 @@ struct DagForest *build_dag(struct Scene *sce, short mask)
                                        else
                                                dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
                                }
-                               else
-                                       dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+                                       else
+                                               dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+               }
+               addtoroot = 0;
+       }
+       if (ob->track) {
+               node2 = dag_get_node(dag,ob->track);
+               dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
+               addtoroot = 0;
+       }
+       
+       if (ob->transflag & OB_DUPLI) {
+               if((ob->transflag & OB_DUPLIGROUP) && ob->dup_group) {
+                       GroupObject *go;
+                       for(go= ob->dup_group->gobject.first; go; go= go->next) {
+                               if(go->ob) {
+                                       node2 = dag_get_node(dag, go->ob);
+                                       /* node2 changes node1, this keeps animations updated in groups?? not logical? */
+                                       dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
+                               }
                        }
-                       addtoroot = 0;
                }
-               if (ob->track) {
-                       node2 = dag_get_node(dag,ob->track);
-                       dag_add_relation(dag,node2,node,DAG_RL_OB_OB);
-                       addtoroot = 0;
+       }
+       
+       if (ob->type==OB_MBALL) {
+               Object *mom= find_basis_mball(ob);
+               if(mom!=ob) {
+                       node2 = dag_get_node(dag, mom);
+                       dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);  // mom depends on children!
                }
-               
-               if (ob->type==OB_MBALL) {
-                       Object *mom= find_basis_mball(ob);
-                       if(mom!=ob) {
-                               node2 = dag_get_node(dag, mom);
-                               dag_add_relation(dag,node,node2,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);  // mom depends on children!
-                       }
+       }
+       else if (ob->type==OB_CURVE) {
+               Curve *cu= ob->data;
+               if(cu->bevobj) {
+                       node2 = dag_get_node(dag, cu->bevobj);
+                       dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
                }
-               else if (ob->type==OB_CURVE) {
-                       Curve *cu= ob->data;
-                       if(cu->bevobj) {
-                               node2 = dag_get_node(dag, cu->bevobj);
-                               dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
-                       }
-                       if(cu->taperobj) {
-                               node2 = dag_get_node(dag, cu->taperobj);
-                               dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
-                       }
+               if(cu->taperobj) {
+                       node2 = dag_get_node(dag, cu->taperobj);
+                       dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
                }
-               else if(ob->type==OB_FONT) {
-                       Curve *cu= ob->data;
-                       if(cu->textoncurve) {
-                               node2 = dag_get_node(dag, cu->textoncurve);
-                               dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
-                       }
+       }
+       else if(ob->type==OB_FONT) {
+               Curve *cu= ob->data;
+               if(cu->textoncurve) {
+                       node2 = dag_get_node(dag, cu->textoncurve);
+                       dag_add_relation(dag,node2,node,DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
                }
-               else if(ob->type==OB_MESH) {
-                       PartEff *paf= give_parteff(ob);
-                       if(paf) {
-                               Base *base1;
-                               
-                               /* ob location depends on itself */
-                               if((paf->flag & PAF_STATIC)==0)
-                                       dag_add_relation(dag, node, node, DAG_RL_OB_DATA);
-                               
-                               /* force fields, warning for loop inside loop... */
-                               for(base1 = G.scene->base.first; base1; base1= base1->next) {
-                                       if( (base1->lay & base->lay) && base1->object->pd) {
-                                               Object *ob1= base1->object;
-                                               PartDeflect *pd= ob1->pd;
+       }
+       else if(ob->type==OB_MESH) {
+               PartEff *paf= give_parteff(ob);
+               if(paf) {
+                       ListBase *listb;
+                       pEffectorCache *ec;
+                       
+                       /* ob location depends on itself */
+                       if((paf->flag & PAF_STATIC)==0)
+                               dag_add_relation(dag, node, node, DAG_RL_OB_DATA);
+                       
+                       listb= pdInitEffectors(ob, paf->group);         /* note, makes copy... */
+                       if(listb) {
+                               for(ec= listb->first; ec; ec= ec->next) {
+                                       Object *ob1= ec->ob;
+                                       PartDeflect *pd= ob1->pd;
                                                
-                                               if(pd->forcefield) {
-                                                       node2 = dag_get_node(dag, ob1);
-                                                       if(pd->forcefield==PFIELD_GUIDE)
-                                                               dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
-                                                       else
-                                                               dag_add_relation(dag, node2, node, DAG_RL_OB_DATA);
-                                               }
+                                       if(pd->forcefield) {
+                                               node2 = dag_get_node(dag, ob1);
+                                               if(pd->forcefield==PFIELD_GUIDE)
+                                                       dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA);
+                                               else
+                                                       dag_add_relation(dag, node2, node, DAG_RL_OB_DATA);
                                        }
                                }
+                               
+                               pdEndEffectors(listb);  /* restores copy... */
                        }
                }
-               
-               for (con = ob->constraints.first; con; con=con->next){
-                       if (constraint_has_target(con)) {
-                               char *str;
-                               Object *obt= get_constraint_target(con, &str);
-
-                               node2 = dag_get_node(dag, obt);
-                               if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
+       }
+       
+       for (con = ob->constraints.first; con; con=con->next){
+               if (constraint_has_target(con)) {
+                       char *str;
+                       Object *obt= get_constraint_target(con, &str);
+                       
+                       node2 = dag_get_node(dag, obt);
+                       if(con->type==CONSTRAINT_TYPE_FOLLOWPATH)
+                               dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
+                       else {
+                               if(obt->type==OB_ARMATURE && str[0])
                                        dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
-                               else {
-                                       if(obt->type==OB_ARMATURE && str[0])
-                                               dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB);
-                                       else
-                                               dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
-                               }
-                               addtoroot = 0;
+                               else
+                                       dag_add_relation(dag, node2, node, DAG_RL_OB_OB);
                        }
+                       addtoroot = 0;
                }
+       }
+
+       if (addtoroot == 1 )
+               dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
+}
+
+struct DagForest *build_dag(struct Scene *sce, short mask) 
+{
+       Base *base;
+       Object *ob;
+       Group *group;
+       GroupObject *go;
+       DagNode *node;
+       DagNode *scenenode;
+       DagForest *dag;
+       DagAdjList *itA;
+
+       dag = sce->theDag;
+       sce->dagisvalid=1;
+       if ( dag)
+               free_forest( dag ); 
+       else {
+               dag = dag_init();
+               sce->theDag = dag;
+       }
+       
+       /* add base node for scene. scene is always the first node in DAG */
+       scenenode = dag_add_node(dag, sce);     
+       
+       /* add current scene objects */
+       for(base = sce->base.first; base; base= base->next) {
+               ob= base->object;
                
-               if (addtoroot == 1 )
-                       dag_add_relation(dag,scenenode,node,DAG_RL_SCENE);
+               build_dag_object(dag, scenenode, ob, mask);
+               
+               /* handled in next loop */
+               if(ob->dup_group) 
+                       ob->dup_group->id.flag |= LIB_DOIT;
+       }
+       
+       /* add groups used in current scene objects */
+       for(group= G.main->group.first; group; group= group->id.next) {
+               if(group->id.flag & LIB_DOIT) {
+                       for(go= group->gobject.first; go; go= go->next) {
+                               build_dag_object(dag, scenenode, go->ob, mask);
+                       }
+                       group->id.flag &= ~LIB_DOIT;
+               }
        }
        
        /* Now all relations were built, but we need to solve 1 exceptional case;
@@ -1314,10 +1356,12 @@ void DAG_scene_sort(struct Scene *sce)
                                
                                time++;
                                base = sce->base.first;
-                               while (base->object != node->ob)
+                               while (base && base->object != node->ob)
                                        base = base->next;
-                               BLI_remlink(&sce->base,base);
-                               BLI_addhead(&tempbase,base);
+                               if(base) {
+                                       BLI_remlink(&sce->base,base);
+                                       BLI_addhead(&tempbase,base);
+                               }
                        }       
                }
        }
@@ -1502,88 +1546,128 @@ static int exists_channel(Object *ob, char *name)
        return 0;
 }
 
+static void dag_object_time_update_flags(Object *ob)
+{
+       
+       if(ob->ipo) ob->recalc |= OB_RECALC_OB;
+       else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
+       else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
+       else if(ob->parent) {
+               /* motion path or bone child */
+               if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB;
+       }
+       
+       if(ob->action || ob->nlastrips.first) {
+               /* since actions now are mixed, we set the recalcs on the safe side */
+               ob->recalc |= OB_RECALC_OB;
+               if(ob->type==OB_ARMATURE)
+                       ob->recalc |= OB_RECALC_DATA;
+               else if(exists_channel(ob, "Shape"))
+                       ob->recalc |= OB_RECALC_DATA;
+               
+       }
+       else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
+       else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
+       else {
+               Mesh *me;
+               Curve *cu;
+               Lattice *lt;
+               
+               switch(ob->type) {
+                       case OB_MESH:
+                               me= ob->data;
+                               if(me->key) {
+                                       if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+                                               ob->recalc |= OB_RECALC_DATA;
+                                               ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+                                       }
+                               }
+                               else if(ob->effect.first) {
+                                       Effect *eff= ob->effect.first;
+                                       PartEff *paf= give_parteff(ob);
+                                       
+                                       if(eff->type==EFF_WAVE) 
+                                               ob->recalc |= OB_RECALC_DATA;
+                                       if(paf && paf->keys==NULL)
+                                               ob->recalc |= OB_RECALC_DATA;
+                               }
+                               if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
+                                       // fluidsimSettings might not be initialized during load...
+                                       if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
+                                               ob->recalc |= OB_RECALC_DATA; // NT
+                                       }
+                               }
+                               break;
+                       case OB_CURVE:
+                       case OB_SURF:
+                               cu= ob->data;
+                               if(cu->key) {
+                                       if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+                                               ob->recalc |= OB_RECALC_DATA;
+                                               ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+                                       }
+                               }
+                                       break;
+                       case OB_LATTICE:
+                               lt= ob->data;
+                               if(lt->key) {
+                                       if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
+                                               ob->recalc |= OB_RECALC_DATA;
+                                               ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+                                       }
+                               }
+                                       break;
+                       case OB_MBALL:
+                               if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
+                               break;
+               }
+       }               
+}
+
 /* flag all objects that need recalc, for changes in time for example */
 void DAG_scene_update_flags(Scene *sce, unsigned int lay)
 {
        Base *base;
        Object *ob;
+       Group *group;
+       GroupObject *go;
        
        /* set ob flags where animated systems are */
        for(base= sce->base.first; base; base= base->next) {
+               ob= base->object;
                
                /* now if DagNode were part of base, the node->lay could be checked... */
                /* we do all now, since the scene_flush checks layers and clears recalc flags even */
-               ob= base->object;
+               dag_object_time_update_flags(ob);
                
-               if(ob->ipo) ob->recalc |= OB_RECALC_OB;
-               else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
-               else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
-               else if(ob->parent) {
-                       if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB;
-               }
+               /* handled in next loop */
+               if(ob->dup_group) 
+                       ob->dup_group->id.flag |= LIB_DOIT;
                
-               if(ob->action || ob->nlastrips.first) {
-                       /* since actions now are mixed, we set the recalcs on the safe side */
-                       ob->recalc |= OB_RECALC_OB;
-                       if(ob->type==OB_ARMATURE)
-                               ob->recalc |= OB_RECALC_DATA;
-                       else if(exists_channel(ob, "Shape"))
-                               ob->recalc |= OB_RECALC_DATA;
-                               
-               }
-               else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
-               else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;
-               else {
-                       Mesh *me;
-                       Curve *cu;
-                       Lattice *lt;
-                       
-                       switch(ob->type) {
-                               case OB_MESH:
-                                       me= ob->data;
-                                       if(me->key) {
-                                               if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-                                                       ob->recalc |= OB_RECALC_DATA;
-                                                       ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
-                                               }
-                                       }
-                                       else if(ob->effect.first) {
-                                               Effect *eff= ob->effect.first;
-                                               if(eff->type==EFF_WAVE) ob->recalc |= OB_RECALC_DATA;
-                                       }
-                                       if((ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) && (ob->fluidsimSettings)) {
-                                               // fluidsimSettings might not be initialized during load...
-                                               if(ob->fluidsimSettings->type & OB_FLUIDSIM_DOMAIN) {
-                                                       ob->recalc |= OB_RECALC_DATA; // NT
-                                               }
-                                       }
-                                       break;
-                               case OB_CURVE:
-                               case OB_SURF:
-                                       cu= ob->data;
-                                       if(cu->key) {
-                                               if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-                                                       ob->recalc |= OB_RECALC_DATA;
-                                                       ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
-                                               }
-                                       }
-                                       break;
-                               case OB_LATTICE:
-                                       lt= ob->data;
-                                       if(lt->key) {
-                                               if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-                                                       ob->recalc |= OB_RECALC_DATA;
-                                                       ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
-                                               }
-                                       }
-                                       break;
-                               case OB_MBALL:
-                                       if(ob->transflag & OB_DUPLI) ob->recalc |= OB_RECALC_DATA;
-                                       break;
+       }
+       
+       /* we do groups each once */
+       for(group= G.main->group.first; group; group= group->id.next) {
+               if(group->id.flag & LIB_DOIT) {
+                       for(go= group->gobject.first; go; go= go->next) {
+                               dag_object_time_update_flags(go->ob);
                        }
                }
        }
+       
        DAG_scene_flush_update(sce, lay);
+       
+       /* and store the info in groubobject */
+       for(group= G.main->group.first; group; group= group->id.next) {
+               if(group->id.flag & LIB_DOIT) {
+                       for(go= group->gobject.first; go; go= go->next) {
+                               go->recalc= go->ob->recalc;
+//                             printf("ob %s recalc %d\n", go->ob->id.name, go->recalc);
+                       }
+                       group->id.flag &= ~LIB_DOIT;
+               }
+       }
+       
 }
 
 /* for depgraph updating, all layers visible in a screen */
index 9273bd8eb712a43ce01b115fa4904003db85d8b2..c27245fc11e1a5fcd774ba9fed816e4b45e424c0 100644 (file)
@@ -537,6 +537,7 @@ static void fastshade(float *co, float *nor, float *orco, Material *ma, char *co
                        if(ma->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(nor, lv, shi.view, ma->roughness);
                        else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]);
                        else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, nor, shi.view, ma->darkness);
+                       else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(nor, lv, shi.view, ma->param[0], ma->param[1]);
                }
                
                back= 0;
@@ -726,15 +727,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);
-         &nbs