Merge from trunk
authorAndre Susano Pinto <andresusanopinto@gmail.com>
Mon, 5 May 2008 17:30:33 +0000 (17:30 +0000)
committerAndre Susano Pinto <andresusanopinto@gmail.com>
Mon, 5 May 2008 17:30:33 +0000 (17:30 +0000)
svn merge -r 14626:14692 https://svn.blender.org/svnroot/bf-blender/trunk/blender

96 files changed:
CMakeLists.txt
SConstruct
config/darwin-config.py
config/win32-vc-config.py
extern/verse/dist/v_bignum.c
intern/ghost/intern/GHOST_SystemCarbon.cpp
projectfiles_vc7/gameengine/blenderhook/KX_blenderhook.vcproj
projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
projectfiles_vc7/gameengine/rasterizer/RAS_rasterizer.vcproj
projectfiles_vc7/gameengine/rasterizer/openglrasterizer/RAS_openglrasterizer.vcproj
release/scripts/console.py
release/scripts/wizard_curve2tree.py
release/scripts/x3d_export.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/packedFile.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/writeavi.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/intern/bpath.c
source/blender/blenlib/intern/util.c
source/blender/blenloader/intern/genfile.c
source/blender/include/BIF_screen.h
source/blender/include/butspace.h
source/blender/nodes/intern/SHD_nodes/SHD_dynamic.c
source/blender/python/BPY_interface.c
source/blender/python/BPY_menus.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Library.c
source/blender/python/api2_2x/Library.h
source/blender/python/api2_2x/Node.c
source/blender/python/api2_2x/Sys.c
source/blender/python/api2_2x/doc/LibData.py
source/blender/python/api2_2x/sceneRender.c
source/blender/quicktime/apple/quicktime_export.c
source/blender/render/intern/source/pipeline.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawimage.c
source/blender/src/drawobject.c
source/blender/src/drawview.c
source/blender/src/editcurve.c
source/blender/src/editdeform.c
source/blender/src/editimasel.c
source/blender/src/editipo.c
source/blender/src/editobject.c
source/blender/src/editscreen.c
source/blender/src/editsima.c
source/blender/src/editsound.c
source/blender/src/filesel.c
source/blender/src/fluidsim.c
source/blender/src/ghostwinlay.c
source/blender/src/header_action.c
source/blender/src/header_ipo.c
source/blender/src/header_nla.c
source/blender/src/interface_draw.c
source/blender/src/outliner.c
source/blender/src/screendump.c
source/blender/src/seqaudio.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/view.c
source/blender/src/writeimage.c
source/blender/src/writemovie.c
source/blender/yafray/intern/export_File.cpp
source/blender/yafray/intern/export_Plugin.cpp
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
source/gameengine/GameLogic/SCA_MouseSensor.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.cpp
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_IRenderTools.h
source/gameengine/Rasterizer/RAS_MaterialBucket.cpp

index 1c34233245a084ee3cd40fd362835a10c79f62a4..b58fe9456639abdd060aa9f9f6812e3083a54bbb 100644 (file)
@@ -250,6 +250,10 @@ IF(WIN32)
   ELSE (MSVC80)
   SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc)
   ENDIF(MSVC80)
+  IF (MSVC90)
+  SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2008)
+  ENDIF(MSVC90)
+
   
   SET(QUICKTIME ${LIBDIR}/QTDevWin)
   SET(QUICKTIME_INC ${QUICKTIME}/CIncludes)
index 942bef078d61c97ae26da8e887fd346ae55a4621..869ba6454c81394fa515a6209c92a63f43b1499a 100644 (file)
@@ -398,9 +398,26 @@ for tp, tn, tf in os.walk('release/plugins'):
     if '.svn' in tn:
         tn.remove('.svn')
     for f in tf:
+        print ">>>", env['BF_INSTALLDIR'], tp, f
         pluglist.append(tp+os.sep+f)
         plugtargetlist.append(env['BF_INSTALLDIR']+tp[7:]+os.sep+f)
 
+# header files for plugins
+pluglist.append('source/blender/blenpluginapi/documentation.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'documentation.h')
+pluglist.append('source/blender/blenpluginapi/externdef.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'externdef.h')
+pluglist.append('source/blender/blenpluginapi/floatpatch.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'floatpatch.h')
+pluglist.append('source/blender/blenpluginapi/iff.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'iff.h')
+pluglist.append('source/blender/blenpluginapi/plugin.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'plugin.h')
+pluglist.append('source/blender/blenpluginapi/util.h')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep +'util.h')
+pluglist.append('source/blender/blenpluginapi/plugin.DEF')
+plugtargetlist.append(env['BF_INSTALLDIR'] + os.sep + 'plugins' + os.sep + 'include' + os.sep + 'plugin.def')
+
 plugininstall = []
 for targetdir,srcfile in zip(plugtargetlist, pluglist):
     td, tf = os.path.split(targetdir)
index 8fec38ac48ebdeff44d7b07a0e137c1730e00325..8fd6c3251ba64b46be82667cea44b90c0ac87f93 100644 (file)
@@ -221,9 +221,10 @@ if USE_SDK=='true':
        CCFLAGS=SDK_FLAGS+CCFLAGS
        CXXFLAGS=SDK_FLAGS+CXXFLAGS
        
+# you can add -mssse3 if gcc >= 4.2
 if MAC_PROC == 'i386':
-       REL_CFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mssse3']
-       REL_CCFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mssse3']
+       REL_CFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3']
+       REL_CCFLAGS = ['-O2','-ftree-vectorize','-msse','-msse2','-msse3']
 else:
        CFLAGS = CFLAGS+['-fno-strict-aliasing']
        CCFLAGS =  CCFLAGS+['-fno-strict-aliasing']
index 1f7e62102af99f21ffbabd55a9b2626455469272..32b6597b5d55eda149f52615642cd376808585cf 100644 (file)
@@ -170,7 +170,6 @@ PLATFORM_LINKFLAGS = '''
                         /NODEFAULTLIB:"libcd.lib"
                         /NODEFAULTLIB:"libcpd.lib" 
                         /NODEFAULTLIB:"libcp.lib" 
-                        /NODEFAULTLIB:"libcmtd.lib"
                     '''
                         
 BF_BUILDDIR = '..\\build\\win32-vc'
index 3f3ea7f9ccc680da36cd288a18829e7d11e59185..3f65af034270ec9354854b7ffc96a0da09b5dd28 100644 (file)
@@ -768,7 +768,7 @@ void v_bignum_square_half(VBigDig *x)
                for(j = i + 1; j < t; j++)
                {
 /*                     printf("computing uv=%X+2*%X*%X+%X\n", w[i + j], x[1 + j], x[1 + i], c);*/
-                       uv = x[1 + j] * x[1 + i];
+                       uv = ((VBigDigs)x[1 + j]) * ((VBigDigs)x[1 + i]);
                        high = (uv & 0x80000000) != 0;
                        uv *= 2;
                        ouv = uv;       /* Addition below might wrap and generate high bit. */
index 568f7ecf9b8a2efd7642b56825f1ddb50e91234a..78c25997806f12792f35635b7f2a0ded5f657a00 100644 (file)
  * @date       May 7, 2001
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
 
+#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
 #include "GHOST_SystemCarbon.h"
 
 #include "GHOST_DisplayManagerCarbon.h"
@@ -52,6 +51,7 @@
 #include "GHOST_WindowManager.h"
 #include "GHOST_WindowCarbon.h"
 #include "GHOST_NDOFManager.h"
+#include "AssertMacros.h"
 
 #define GHOST_KEY_SWITCH(mac, ghost) { case (mac): ghostKey = (ghost); break; }
 
@@ -1121,12 +1121,15 @@ GHOST_TUns8* GHOST_SystemCarbon::getClipboard(int flag) const
        OSStatus err = noErr;
        GHOST_TUns8 * temp_buff;
        CFRange range;
+       OSStatus syncFlags;
        
        err = PasteboardCreate(kPasteboardClipboard, &inPasteboard);
        if(err != noErr) { return NULL;}
 
-       err = PasteboardSynchronize( inPasteboard );
-       if(err != noErr) { return NULL;}
+       syncFlags = PasteboardSynchronize( inPasteboard );
+               /* as we always get in a new string, we can safely ignore sync flags if not an error*/
+       if(syncFlags <0) { return NULL;}
+
 
        err = PasteboardGetItemIdentifier( inPasteboard, 1, &itemID );
        if(err != noErr) { return NULL;}
@@ -1152,15 +1155,18 @@ GHOST_TUns8* GHOST_SystemCarbon::getClipboard(int flag) const
 void GHOST_SystemCarbon::putClipboard(GHOST_TInt8 *buffer, int flag) const
 {
        if(flag == 1) {return;} //If Flag is 1 means the selection and is used on X11
+
        PasteboardRef inPasteboard;
        CFDataRef textData = NULL;
        OSStatus err = noErr; /*For error checking*/
+       OSStatus syncFlags;
        
        err = PasteboardCreate(kPasteboardClipboard, &inPasteboard);
        if(err != noErr) { return;}
        
-       err = PasteboardSynchronize( inPasteboard ); 
-       if(err != noErr) { return;}
+       syncFlags = PasteboardSynchronize( inPasteboard ); 
+       /* as we always put in a new string, we can safely ignore sync flags */
+       if(syncFlags <0) { return;}
        
        err = PasteboardClear( inPasteboard );
        if(err != noErr) { return;}
index 1721062b75cb7edb7f410f49b39791f32046af17..bc4204eaa44685e8e9dbd1042b155e7af5d27641 100644 (file)
@@ -22,7 +22,7 @@
                                Name="VCCLCompilerTool"
                                Optimization="0"
                                AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\bmfont\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include"
-                               PreprocessorDefinitions="WIN32,_LIB,_DEBUG"
+                               PreprocessorDefinitions="WIN32;_LIB;_DEBUG;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                                DefaultCharIsUnsigned="TRUE"
index e73e72316c15af3d7b87e704cc90ae7f9dd8ca90..d85fb6c348241983bd4fc403634609c4b0163f77 100644 (file)
                                Name="VCCLCompilerTool"
                                Optimization="0"
                                AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\build\msvc_7\intern\guardedalloc\include;..\..\..\..\build\msvc_7\extern\bullet\include;..\..\..\..\build\msvc_7\extern\solid\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender\imbuf;..\..\..\source\blender\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\python;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\physics;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\network;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\physics\sumo;..\..\..\source\gameengine\physics\dummy;..\..\..\source\gameengine\physics\BlOde;..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\source\gameengine\physics\common;..\..\..\source\gameengine\physics\sumo\include;..\..\..\source\gameengine\physics\common\dummy;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\physics\sumo\fuzzics\include;..\..\..\source\sumo\include;..\..\..\source\sumo\fuzzics\include;..\..\..\source\gameengine\physics\bullet"
-                               PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID"
+                               PreprocessorDefinitions="JANCODEPANCO;WIN32;_LIB;EXP_PYTHON_EMBEDDING;_DEBUG;USE_SUMO_SOLID;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                                DefaultCharIsUnsigned="TRUE"
index 75a2a8520119da3b99bd63c0856ef1d52caf52ab..f4801b58bc8f338df5db10a78e889c190a684e59 100644 (file)
@@ -22,7 +22,7 @@
                                Name="VCCLCompilerTool"
                                Optimization="0"
                                AdditionalIncludeDirectories="..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\build\msvc_7\intern\string\include;..\..\..\source\kernel\gen_system"
-                               PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
+                               PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                                DefaultCharIsUnsigned="TRUE"
index 6046cc5cac5df3b12f6781bfb6effcabfb313f0e..b96cf78daf509724b5fa6d38ab7a3ed03b871c79 100644 (file)
@@ -74,7 +74,7 @@
                                Name="VCCLCompilerTool"
                                Optimization="0"
                                AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\gameengine\Rasterizer"
-                               PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
+                               PreprocessorDefinitions="_DEBUG;WIN32;_LIB;WITH_GLEXT"
                                BasicRuntimeChecks="3"
                                RuntimeLibrary="1"
                                DefaultCharIsUnsigned="TRUE"
index 6860af4442e194f86fcfd289fbd95606b7305a45..9a18c724d4710ca1bf5f61bbc6ba7d07f619c2a9 100644 (file)
@@ -61,7 +61,7 @@ __LINE_HISTORY__ = 500
 
 global __FONT_SIZE__
 
-__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normal', 14), ('large', 16) )
+__FONT_SIZES__ = ( ('tiny', 10), ('small', 12), ('normalfix', 14), ('large', 16) )
 __FONT_SIZE__ = 2 # index for the list above, normal default.
 
 global __CONSOLE_LINE_OFFSET__
@@ -420,9 +420,13 @@ def handle_event(evt, val):
                global histIndex, cmdBuffer
                if abs(histIndex)+1 >= len(cmdBuffer):
                        histIndex = -1
+               histIndex_orig = histIndex
                histIndex -= 1
-               while cmdBuffer[histIndex].type != 0 and abs(histIndex) < len(cmdBuffer):
+               
+               while   (cmdBuffer[histIndex].type != 0 and abs(histIndex) < len(cmdBuffer)) or \
+                               ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
                        histIndex -= 1
+                       
                if cmdBuffer[histIndex].type == 0: # we found one
                        cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd                    
        
@@ -430,9 +434,13 @@ def handle_event(evt, val):
                global histIndex, cmdBuffer
                if histIndex >= -2:
                        histIndex = -len(cmdBuffer)
+               histIndex_orig = histIndex
                histIndex += 1
-               while cmdBuffer[histIndex].type != 0 and histIndex != -2:
+               while   (cmdBuffer[histIndex].type != 0 and histIndex != -2) or \
+                               ( cmdBuffer[histIndex].cmd == cmdBuffer[histIndex_orig].cmd):
+                       
                        histIndex += 1
+                       
                if cmdBuffer[histIndex].type == 0: # we found one
                        cmdBuffer[-1].cmd = cmdBuffer[histIndex].cmd
        
index 2dcda953a89e25fe1406cb70f71f8917318be96d..eb27f1ca0f566fd704918116a9346f513e2908bd 100644 (file)
@@ -3405,7 +3405,7 @@ def buildTree(ob_curve, single=False):
                if leaf_object:
                        ob_leaf_dupliface.enableDupFaces = True
                        ob_leaf_dupliface.enableDupFacesScale = True
-                       ob_leaf_dupliface.makeParent([leaf_object])
+                       ob_leaf_dupliface.makeParent([leaf_object], 1)
                else:
                        ob_leaf_dupliface.enableDupFaces = False
        
@@ -3637,7 +3637,7 @@ def do_tree_generate(e,v):
                GLOBALS['non_bez_error'] = 0
                
 def do_tree_help(e,v):
-       url = 'http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_fbx'
+       url = 'http://wiki.blender.org/index.php/Scripts/Manual/Wizards/TreeFromCurves'
        print 'Trying to open web browser with documentation at this address...'
        print '\t' + url
        
index eb9d5d35d6c0b792d63b1a5b1616cfff4a1042bf..ac4a8e9ca5be2a0d0e3b6acabc70cf4d35f6070b 100644 (file)
@@ -1,15 +1,12 @@
 #!BPY
 """ Registration info for Blender menus:
 Name: 'X3D Extensible 3D (.x3d)...'
-Blender: 235
+Blender: 245
 Group: 'Export'
-Submenu: 'All Objects...' all
-Submenu: 'All Objects compressed...' comp
-Submenu: 'Selected Objects...' selected
-Tooltip: 'Export to Extensible 3D file (.x3d)'
+Tooltip: 'Export selection to Extensible 3D file (.x3d)'
 """
 
-__author__ = ("Bart")
+__author__ = ("Bart", "Campbell Barton")
 __email__ = ["Bart, bart:neeneenee*de"]
 __url__ = ["Author's (Bart) homepage, http://www.neeneenee.de/vrml"]
 __version__ = "2006/01/17"
@@ -22,10 +19,9 @@ Run this script from "File->Export" menu.  A pop-up will ask whether you
 want to export only selected or all relevant objects.
 
 Known issues:<br>
-    Doesn't handle multiple materials (don't use material indices);<br>
-    Doesn't handle multiple UV textures on a single mesh (create a mesh
-for each texture);<br>
-    Can't get the texture array associated with material * not the UV ones;
+       Doesn't handle multiple materials (don't use material indices);<br>
+       Doesn't handle multiple UV textures on a single mesh (create a mesh for each texture);<br>
+       Can't get the texture array associated with material * not the UV ones;
 """
 
 
@@ -58,953 +54,903 @@ for each texture);<br>
 ####################################
 
 import Blender
-from Blender import Object, NMesh, Lamp, Draw, Image, Text, sys
+from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
 from Blender.Scene import Render
 import math
 
+# 
+DEG2RAD=0.017453292519943295
+MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
+
 ####################################
 # Global Variables
 ####################################
 
-scene = Blender.Scene.GetCurrent()
-world = Blender.World.GetCurrent() 
-worldmat = Blender.Texture.Get()
 filename = Blender.Get('filename')
 _safeOverwrite = True
 ARG=''
 extension = ''
 
-class DrawTypes:
-    """Object DrawTypes enum values
-    BOUNDS - draw only the bounding box of the object
-    WIRE - draw object as a wire frame
-    SOLID - draw object with flat shading
-    SHADED - draw object with OpenGL shading
-"""
-    BOUNDBOX  = 1
-    WIRE      = 2
-    SOLID     = 3
-    SHADED    = 4
-    TEXTURE   = 5
-
-if not hasattr(Blender.Object,'DrawTypes'):
-    Blender.Object.DrawTypes = DrawTypes()
-
 ##########################################################
 # Functions for writing output file
 ##########################################################
 
 class VRML2Export:
 
-    def __init__(self, filename):
-        #--- public you can change these ---
-        self.writingcolor = 0
-        self.writingtexture = 0
-        self.writingcoords = 0
-        self.wire = 0
-        self.proto = 1
-        self.matonly = 0
-        self.share = 0
-        self.billnode = 0
-        self.halonode = 0
-        self.collnode = 0
-        self.tilenode = 0
-        self.verbose=2     # level of verbosity in console 0-none, 1-some, 2-most
-        self.cp=3          # decimals for material color values     0.000 - 1.000
-        self.vp=3          # decimals for vertex coordinate values  0.000 - n.000
-        self.tp=3          # decimals for texture coordinate values 0.000 - 1.000
-        self.it=3
-        
-        #--- class private don't touch ---
-        self.texNames={}   # dictionary of textureNames
-        self.matNames={}   # dictionary of materiaNames
-        self.meshNames={}   # dictionary of meshNames
-        self.indentLevel=0 # keeps track of current indenting
-        self.filename=filename
-        self.file = open(filename, "w")
-        self.bNav=0
-        self.nodeID=0
-        self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard",
-                             "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D",
-                             "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect",
-                             "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator",
-                             "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D",
-                             "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field",
-                             "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid",
-                             "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator",
-                             "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint",
-                             "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet",
-                             "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet",
-                             "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet",
-                             "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger",
-                             "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate",
-                             "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve",
-                             "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface",
-                             "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface",
-                             "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator",
-                             "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D",
-                             "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance",
-                             "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator",
-                             "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup",
-                             "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator",
-                             "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu",
-                             "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor",
-                             "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ]
-        self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005",
-                             "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012",
-                             "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013",
-                             "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012",
-                             "World","World.000","World.001","World.002","World.003","World.004","World.005" ]
-        self.namesFog=[ "","LINEAR","EXPONENTIAL","" ]
+       def __init__(self, filename):
+               #--- public you can change these ---
+               self.writingcolor = 0
+               self.writingtexture = 0
+               self.writingcoords = 0
+               self.proto = 1
+               self.matonly = 0
+               self.share = 0
+               self.billnode = 0
+               self.halonode = 0
+               self.collnode = 0
+               self.tilenode = 0
+               self.verbose=2   # level of verbosity in console 0-none, 1-some, 2-most
+               self.cp=3                 # decimals for material color values   0.000 - 1.000
+               self.vp=3                 # decimals for vertex coordinate values  0.000 - n.000
+               self.tp=3                 # decimals for texture coordinate values 0.000 - 1.000
+               self.it=3
+               
+               #--- class private don't touch ---
+               self.texNames={}   # dictionary of textureNames
+               self.matNames={}   # dictionary of materiaNames
+               self.meshNames={}   # dictionary of meshNames
+               self.indentLevel=0 # keeps track of current indenting
+               self.filename=filename
+               self.file = open(filename, "w")
+               self.bNav=0
+               self.nodeID=0
+               self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard",
+                                                        "BooleanFilter","BooleanSequencer","BooleanToggle","BooleanTrigger","Box","Circle2D",
+                                                        "Collision","Color","ColorInterpolator","ColorRGBA","component","Cone","connect",
+                                                        "Contour2D","ContourPolyline2D","Coordinate","CoordinateDouble","CoordinateInterpolator",
+                                                        "CoordinateInterpolator2D","Cylinder","CylinderSensor","DirectionalLight","Disk2D",
+                                                        "ElevationGrid","EspduTransform","EXPORT","ExternProtoDeclare","Extrusion","field",
+                                                        "fieldValue","FillProperties","Fog","FontStyle","GeoCoordinate","GeoElevationGrid",
+                                                        "GeoLocationLocation","GeoLOD","GeoMetadata","GeoOrigin","GeoPositionInterpolator",
+                                                        "GeoTouchSensor","GeoViewpoint","Group","HAnimDisplacer","HAnimHumanoid","HAnimJoint",
+                                                        "HAnimSegment","HAnimSite","head","ImageTexture","IMPORT","IndexedFaceSet",
+                                                        "IndexedLineSet","IndexedTriangleFanSet","IndexedTriangleSet","IndexedTriangleStripSet",
+                                                        "Inline","IntegerSequencer","IntegerTrigger","IS","KeySensor","LineProperties","LineSet",
+                                                        "LoadSensor","LOD","Material","meta","MetadataDouble","MetadataFloat","MetadataInteger",
+                                                        "MetadataSet","MetadataString","MovieTexture","MultiTexture","MultiTextureCoordinate",
+                                                        "MultiTextureTransform","NavigationInfo","Normal","NormalInterpolator","NurbsCurve",
+                                                        "NurbsCurve2D","NurbsOrientationInterpolator","NurbsPatchSurface",
+                                                        "NurbsPositionInterpolator","NurbsSet","NurbsSurfaceInterpolator","NurbsSweptSurface",
+                                                        "NurbsSwungSurface","NurbsTextureCoordinate","NurbsTrimmedSurface","OrientationInterpolator",
+                                                        "PixelTexture","PlaneSensor","PointLight","PointSet","Polyline2D","Polypoint2D",
+                                                        "PositionInterpolator","PositionInterpolator2D","ProtoBody","ProtoDeclare","ProtoInstance",
+                                                        "ProtoInterface","ProximitySensor","ReceiverPdu","Rectangle2D","ROUTE","ScalarInterpolator",
+                                                        "Scene","Script","Shape","SignalPdu","Sound","Sphere","SphereSensor","SpotLight","StaticGroup",
+                                                        "StringSensor","Switch","Text","TextureBackground","TextureCoordinate","TextureCoordinateGenerator",
+                                                        "TextureTransform","TimeSensor","TimeTrigger","TouchSensor","Transform","TransmitterPdu",
+                                                        "TriangleFanSet","TriangleSet","TriangleSet2D","TriangleStripSet","Viewpoint","VisibilitySensor",
+                                                        "WorldInfo","X3D","XvlShell","VertexShader","FragmentShader","MultiShaderAppearance","ShaderAppearance" ]
+               self.namesStandard=[ "Empty","Empty.000","Empty.001","Empty.002","Empty.003","Empty.004","Empty.005",
+                                                        "Empty.006","Empty.007","Empty.008","Empty.009","Empty.010","Empty.011","Empty.012",
+                                                        "Scene.001","Scene.002","Scene.003","Scene.004","Scene.005","Scene.06","Scene.013",
+                                                        "Scene.006","Scene.007","Scene.008","Scene.009","Scene.010","Scene.011","Scene.012",
+                                                        "World","World.000","World.001","World.002","World.003","World.004","World.005" ]
+               self.namesFog=[ "","LINEAR","EXPONENTIAL","" ]
 
 ##########################################################
 # Writing nodes routines
 ##########################################################
 
-    def writeHeader(self):
-        #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '&lt').replace('>', '&gt')
-        bfile = self.filename.replace('<', '&lt').replace('>', '&gt') # use outfile name
-        self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
-        self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
-        self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
-        self.file.write("<head>\n")
-        self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
-        self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
-        self.file.write("\t<meta name=\"translator\" content=\"X3D exporter v1.55 (2006/01/17)\" />\n")
-        self.file.write("</head>\n")
-        self.file.write("<Scene>\n")
-
-    def writeInline(self):
-        inlines = Blender.Scene.Get()
-        allinlines = len(inlines)
-        if scene != inlines[0]:
-            return
-        else:
-            for i in xrange(allinlines):
-                nameinline=inlines[i].name
-                if (nameinline not in self.namesStandard) and (i > 0):
-                    self.file.write("<Inline DEF=\"%s\" " % (self.cleanStr(nameinline)))
-                    nameinline = nameinline+".x3d"
-                    self.file.write("url=\"%s\" />" % nameinline)
-                    self.file.write("\n\n")
-
-    def writeScript(self):
-        textEditor = Blender.Text.Get() 
-        alltext = len(textEditor)
-        for i in xrange(alltext):
-            nametext = textEditor[i].getName()
-            nlines = textEditor[i].getNLines()
-            if (self.proto == 1):
-                if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None):
-                    nalllines = len(textEditor[i].asLines())
-                    alllines = textEditor[i].asLines()
-                    for j in xrange(nalllines):
-                        self.writeIndented(alllines[j] + "\n")
-            elif (self.proto == 0):
-                if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None):
-                    nalllines = len(textEditor[i].asLines())
-                    alllines = textEditor[i].asLines()
-                    for j in xrange(nalllines):
-                        self.writeIndented(alllines[j] + "\n")
-        self.writeIndented("\n")
-
-    def writeViewpoint(self, thisObj):
-        context = scene.getRenderingContext()
-        ratio = float(context.imageSizeY())/float(context.imageSizeX())
-        lens = (360* (math.atan(ratio *16 / thisObj.data.getLens()) / math.pi))*(math.pi/180)
-        lens = min(lens, math.pi) 
-        # get the camera location, subtract 90 degress from X to orient like X3D does
-        loc = self.rotatePointForVRML(thisObj.loc)
-        rot = [thisObj.RotX - 1.57, thisObj.RotY, thisObj.RotZ]
-        nRot = self.rotatePointForVRML(rot)
-        # convert to Quaternion and to Angle Axis
-        Q  = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2])
-        Q1 = self.multiplyQuaternions(Q[0], Q[1])
-        Qf = self.multiplyQuaternions(Q1, Q[2])
-        angleAxis = self.quaternionToAngleAxis(Qf)
-        self.file.write("<Viewpoint DEF=\"%s\" " % (self.cleanStr(thisObj.name)))
-        self.file.write("description=\"%s\" " % (thisObj.name))
-        self.file.write("centerOfRotation=\"0 0 0\" ")
-        self.file.write("position=\"%3.2f %3.2f %3.2f\" " % (loc[0], loc[1], loc[2]))
-        self.file.write("orientation=\"%3.2f %3.2f %3.2f %3.2f\" " % (angleAxis[0], angleAxis[1], -angleAxis[2], angleAxis[3]))
-        self.file.write("fieldOfView=\"%.3f\" />\n\n" % (lens))
-
-    def writeFog(self):
-        if world:
-            mtype = world.getMistype()
-            mparam = world.getMist()
-            grd = world.getHor()
-            grd0, grd1, grd2 = grd[0], grd[1], grd[2]
-        else:
-            return
-        if (mtype == 1 or mtype == 2):
-            self.file.write("<Fog fogType=\"%s\" " % self.namesFog[mtype])                                             
-            self.file.write("color=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
-        else:
-            return
-
-    def writeNavigationInfo(self, scene):
-        allObj = []
-        allObj = list(scene.objects)
-        headlight = "true"
-        vislimit = 0.0
-        for thisObj in allObj:
-            objType=thisObj.type
-            if objType == "Camera":
-                vislimit = thisObj.data.clipEnd
-            elif objType == "Lamp":
-                headlight = "false"
-        self.file.write("<NavigationInfo headlight=\"%s\" " % headlight)
-        self.file.write("visibilityLimit=\"%s\" " % (round(vislimit,self.cp)))
-        self.file.write("type=\"EXAMINE\", \"ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
-
-    def writeSpotLight(self, ob, lamp):
-        safeName = self.cleanStr(ob.name)
-        if world:
-            ambi = world.amb
-            ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
-        else:
-            ambi = 0
-            ambientIntensity = 0
-
-        # compute cutoff and beamwidth
-        intensity=min(lamp.energy/1.75,1.0)
-        beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
-        cutOffAngle=beamWidth*1.3
-
-        dx,dy,dz=self.computeDirection(ob)
-        # note -dx seems to equal om[3][0]
-        # note -dz seems to equal om[3][1]
-        # note  dy seems to equal om[3][2]
-
-        location=ob.getLocation('worldspace')
-        radius = lamp.dist*math.cos(beamWidth)
-        self.file.write("<SpotLight DEF=\"%s\" " % safeName)
-        self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
-        self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
-        self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
-        self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
-        self.file.write("beamWidth=\"%s\" " % (round(beamWidth,self.cp)))
-        self.file.write("cutOffAngle=\"%s\" " % (round(cutOffAngle,self.cp)))
-        self.file.write("direction=\"%s %s %s\" " % (round(dx,3),round(dy,3),round(dz,3)))
-        self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
-        
-    def writeDirectionalLight(self, ob, lamp):
-        safeName = self.cleanStr(ob.name)
-        if world:
-            ambi = world.amb
-            ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
-        else:
-            ambi = 0
-            ambientIntensity = 0
-
-        intensity=min(lamp.energy/1.75,1.0) 
-        (dx,dy,dz)=self.computeDirection(ob)
-        self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
-        self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
-        self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
-        self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
-        self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
-
-    def writePointLight(self, ob, lamp):
-        safeName = self.cleanStr(ob.name)
-        if world:
-            ambi = world.amb
-            ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
-        else:
-            ambi = 0
-            ambientIntensity = 0
-        
-        location=ob.getLocation('worldspace')
-        intensity=min(lamp.energy/1.75,1.0) 
-        radius = lamp.dist
-        self.file.write("<PointLight DEF=\"%s\" " % safeName)
-        self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
-        self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
-        self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
-        self.file.write("radius=\"%s\" " % radius )
-        self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
-
-    def writeNode(self, thisObj):
-        obname=str(thisObj.getName())
-        if obname in self.namesStandard:
-            return
-        else:
-            dx,dy,dz = self.computeDirection(thisObj)
-            location = thisObj.getLocation('worldspace')
-            self.writeIndented("<%s\n" % obname,1)
-            self.writeIndented("# direction %s %s %s\n" % (round(dx,3),round(dy,3),round(dz,3)))
-            self.writeIndented("# location %s %s %s\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
-            self.writeIndented("/>\n",-1)
-            self.writeIndented("\n")
-
-    def secureName(self, name):
-        name = name + str(self.nodeID)
-        self.nodeID=self.nodeID+1
-        if len(name) <= 3:
-            newname = "_" + str(self.nodeID)
-            return "%s" % (newname)
-        else:
-            for bad in ['"','#',"'",',','.','[','\\',']','{','}']:
-                name=name.replace(bad,'_')
-            if name in self.namesReserved:
-                newname = name[0:3] + "_" + str(self.nodeID)
-                return "%s" % (newname)
-            elif name[0].isdigit():
-                newname = "_" + name + str(self.nodeID)
-                return "%s" % (newname)
-            else:
-                newname = name
-                return "%s" % (newname)
-
-    def writeIndexedFaceSet(self, ob, normals = 0):
-        imageMap={}   # set of used images
-        sided={}      # 'one':cnt , 'two':cnt
-        vColors={}    # 'multi':1
-        meshName = self.cleanStr(ob.name)
-        mesh=ob.data
-        meshME = self.cleanStr(mesh.name)
-        if len(mesh.faces) == 0: return
-        for face in mesh.faces:
-            if face.mode & Blender.NMesh.FaceModes['HALO'] and self.halonode == 0:
-                self.writeIndented("<Billboard axisOfRotation=\"0 0 0\">\n",1)
-                self.halonode = 1
-            elif face.mode & Blender.NMesh.FaceModes['BILLBOARD'] and self.billnode == 0:
-                self.writeIndented("<Billboard axisOfRotation=\"0 1 0\">\n",1)
-                self.billnode = 1
-            elif face.mode & Blender.NMesh.FaceModes['OBCOL'] and self.matonly == 0:
-                self.matonly = 1
-            elif face.mode & Blender.NMesh.FaceModes['SHAREDCOL'] and self.share == 0:
-                self.share = 1
-            elif face.mode & Blender.NMesh.FaceModes['TILES'] and self.tilenode == 0:
-                self.tilenode = 1
-            elif not face.mode & Blender.NMesh.FaceModes['DYNAMIC'] and self.collnode == 0:
-                self.writeIndented("<Collision enabled=\"false\">\n",1)
-                self.collnode = 1
-
-        nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors)
-        
-        if nIFSCnt > 1:
-            self.writeIndented("<Group DEF=\"%s%s\">\n" % ("G_", meshName),1)
-        
-        if sided.has_key('two') and sided['two'] > 0:
-            bTwoSided=1
-        else:
-            bTwoSided=0
-        
-        location= ob.getLocation('worldspace')
-        self.writeIndented("<Transform DEF=\"%s\" translation=\"%s %s %s\">\n" % (meshName, round(location[0],3), round(location[1],3), round(location[2],3)),1)
-        self.writeIndented("<Shape>\n",1)
-            
-        maters=mesh.materials
-        hasImageTexture=0
-        issmooth=0
-
-        if len(maters) > 0 or mesh.hasFaceUV():
-          self.writeIndented("<Appearance>\n", 1)
-          # right now this script can only handle a single material per mesh.
-          if len(maters) >= 1:
-            mat=maters[0]
-            matFlags = mat.getMode()
-            if not matFlags & Blender.Material.Modes['TEXFACE']:
-              self.writeMaterial(mat, self.cleanStr(maters[0].name,''))
-              if len(maters) > 1:
-                print "Warning: mesh named %s has multiple materials" % meshName
-                print "Warning: only one material per object handled"
-        
-            #-- textures
-            if mesh.hasFaceUV():
-                for face in mesh.faces:
-                    if (hasImageTexture == 0) and (face.image):
-                        self.writeImageTexture(face.image)
-                        hasImageTexture=1  # keep track of face texture
-            if self.tilenode == 1:
-                self.writeIndented("<TextureTransform  scale=\"%s %s\" />\n" % (face.image.xrep, face.image.yrep))
-                self.tilenode = 0
-            self.writeIndented("</Appearance>\n", -1)
-
-        #-- IndexedFaceSet or IndexedLineSet
-
-        # check if object is wireframe only
-        if ob.drawType == Blender.Object.DrawTypes.WIRE:
-            # user selected WIRE=2 on the Drawtype=Wire on (F9) Edit page
-            ifStyle="IndexedLineSet"
-            self.wire = 1
-        else:
-            # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
-            ifStyle="IndexedFaceSet"
-        # look up mesh name, use it if available
-        if self.meshNames.has_key(meshME):
-            self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1)
-            self.meshNames[meshME]+=1
-        else:
-            if int(mesh.users) > 1:
-                self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1)
-                self.meshNames[meshME]=1
-            else:
-                self.writeIndented("<%s " % ifStyle, 1)
-            if ob.drawType != Blender.Object.DrawTypes.WIRE:
-                if bTwoSided == 1:
-                    self.file.write("solid=\"false\" ")
-                else:
-                    self.file.write("solid=\"true\" ")
-
-            for face in mesh.faces:
-                if face.smooth:
-                     issmooth=1
-                     break
-            if issmooth==1 and self.wire == 0:
-                creaseAngle=(mesh.getMaxSmoothAngle())*(math.pi/180.0)
-                self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
-
-            #--- output vertexColors
-            if self.share == 1 and self.matonly == 0:
-                self.writeVertexColors(mesh)
-            if ob.drawType != Blender.Object.DrawTypes.WIRE:
-                #--- output textureCoordinates if UV texture used
-                if mesh.hasFaceUV():
-                    if self.matonly == 1 and self.share == 1:
-                        self.writeFaceColors(mesh)
-                    elif hasImageTexture == 1:
-                        self.writeTextureCoordinates(mesh)
-            #--- output coordinates
-            self.writeCoordinates(ob, mesh, meshName)
-
-            self.writingcoords = 1
-            self.writingtexture = 1
-            self.writingcolor = 1
-            self.writeCoordinates(ob, mesh, meshName)
-       
-            if ob.drawType != Blender.Object.DrawTypes.WIRE:
-                #--- output textureCoordinates if UV texture used
-                if mesh.hasFaceUV():
-                    if hasImageTexture == 1:
-                        self.writeTextureCoordinates(mesh)
-                    elif self.matonly == 1 and self.share == 1:
-                        self.writeFaceColors(mesh)
-            #--- output vertexColors
-            if self.share == 1 and self.matonly == 0:
-                self.writeVertexColors(mesh)
-        self.matonly = 0
-        self.share = 0
-        self.wire = 0
-        self.writingcoords = 0
-        self.writingtexture = 0
-        self.writingcolor = 0
-        #--- output closing braces
-        self.writeIndented("</%s>\n" % ifStyle, -1)
-        self.writeIndented("</Shape>\n", -1)
-        self.writeIndented("</Transform>\n", -1)
-
-        if self.halonode == 1:
-            self.writeIndented("</Billboard>\n", -1)
-            self.halonode = 0
-
-        if self.billnode == 1:
-            self.writeIndented("</Billboard>\n", -1)
-            self.billnode = 0
-
-        if self.collnode == 1:
-            self.writeIndented("</Collision>\n", -1)
-            self.collnode = 0
-
-        if nIFSCnt > 1:
-            self.writeIndented("</Group>\n", -1)
-
-        self.file.write("\n")
-
-    def writeCoordinates(self, ob, mesh, meshName):
-        meshVertexList = mesh.verts
-
-        # create vertex list and pre rotate -90 degrees X for VRML
-        location= ob.getLocation('worldspace')
-        if self.writingcoords == 0:
-            self.file.write('coordIndex="')
-            for face in mesh.faces:
-                for i in xrange(len(face)):
-                    indx=face[i].index
-                    self.file.write("%s " % indx)
-                self.file.write("-1, ")
-            self.file.write("\">\n")
-        else:
-            #-- vertices
-            mesh.transform(ob.matrixWorld)
-            self.writeIndented("<Coordinate DEF=\"%s%s\" \n" % ("coord_",meshName), 1)
-            self.file.write("\t\t\t\tpoint=\"")
-            for v in meshVertexList:
-                self.file.write("%.6f %.6f %.6f, " % tuple(v.co))
-            self.file.write("\" />")
-            self.writeIndented("\n", -1)
-
-    def writeTextureCoordinates(self, mesh):
-        texCoordList=[] 
-        texIndexList=[]
-        j=0
-
-        for face in mesh.faces:
-            for i in xrange(len(face)):
-                texIndexList.append(j)
-                texCoordList.append(face.uv[i])
-                j=j+1
-            texIndexList.append(-1)
-        if self.writingtexture == 0:
-            self.file.write("\n\t\t\ttexCoordIndex=\"")
-            texIndxStr=""
-            for i in xrange(len(texIndexList)):
-                texIndxStr = texIndxStr + "%d, " % texIndexList[i]
-                if texIndexList[i]==-1:
-                    self.file.write(texIndxStr)
-                    texIndxStr=""
-            self.file.write("\"\n\t\t\t")
-        else:
-            self.writeIndented("<TextureCoordinate point=\"", 1)
-            for i in xrange(len(texCoordList)):
-                self.file.write("%s %s, " % (round(texCoordList[i][0],self.tp), round(texCoordList[i][1],self.tp)))
-            self.file.write("\" />")
-            self.writeIndented("\n", -1)
-
-    def writeFaceColors(self, mesh):
-        if self.writingcolor == 0:
-            self.file.write("colorPerVertex=\"false\" ")
-        else:
-            self.writeIndented("<Color color=\"", 1)
-            for face in mesh.faces:
-                if face.col:
-                    c=face.col[0]
-                    if self.verbose > 2:
-                        print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
-                    aColor = self.rgbToFS(c)
-                    self.file.write("%s, " % aColor)
-            self.file.write("\" />")
-            self.writeIndented("\n",-1)
-
-    def writeVertexColors(self, mesh):
-        if self.writingcolor == 0:
-            self.file.write("colorPerVertex=\"false\" ")
-        else:
-            self.writeIndented("<Color color=\"", 1)
-            for i in xrange(len(mesh.verts)):
-                c=self.getVertexColorByIndx(mesh,i)
-                if self.verbose > 2:
-                    print "Debug: vertex[%d].col r=%d g=%d b=%d" % (i, c.r, c.g, c.b)
-
-                aColor = self.rgbToFS(c)
-                self.file.write("%s, " % aColor)
-            self.file.write("\" />")
-            self.writeIndented("\n",-1)
-
-    def writeMaterial(self, mat, matName):
-        # look up material name, use it if available
-        if self.matNames.has_key(matName):
-            self.writeIndented("<Material USE=\"MA_%s\" />\n" % matName)
-            self.matNames[matName]+=1
-            return;
-
-        self.matNames[matName]=1
-
-        ambient = mat.amb/3
-        diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
-        if world:
-            ambi = world.getAmb()
-            ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2
-        else:
-            ambi0, ambi1, ambi2 = 0, 0, 0
-        emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2
-
-        shininess = mat.hard/512.0
-        specR = (mat.specCol[0]+0.001)/(1.25/(mat.getSpec()+0.001))
-        specG = (mat.specCol[1]+0.001)/(1.25/(mat.getSpec()+0.001))
-        specB = (mat.specCol[2]+0.001)/(1.25/(mat.getSpec()+0.001))
-        transp = 1-mat.alpha
-        matFlags = mat.getMode()
-        if matFlags & Blender.Material.Modes['SHADELESS']:
-          ambient = 1
-          shine = 1
-          specR = emitR = diffuseR
-          specG = emitG = diffuseG
-          specB = emitB = diffuseB
-        self.writeIndented("<Material DEF=\"MA_%s\" " % matName, 1)
-        self.file.write("diffuseColor=\"%s %s %s\" " % (round(diffuseR,self.cp), round(diffuseG,self.cp), round(diffuseB,self.cp)))
-        self.file.write("specularColor=\"%s %s %s\" " % (round(specR,self.cp), round(specG,self.cp), round(specB,self.cp)))
-        self.file.write("emissiveColor=\"%s %s %s\" \n" % (round(emisR,self.cp), round(emisG,self.cp), round(emisB,self.cp)))
-        self.writeIndented("ambientIntensity=\"%s\" " % (round(ambient,self.cp)))
-        self.file.write("shininess=\"%s\" " % (round(shininess,self.cp)))
-        self.file.write("transparency=\"%s\" />" % (round(transp,self.cp)))
-        self.writeIndented("\n",-1)
-
-    def writeImageTexture(self, image):
-        name = image.name
-        filename = image.filename.split('/')[-1].split('\\')[-1]
-        if self.texNames.has_key(name):
-            self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
-            self.texNames[name] += 1
-            return
-        else:
-            self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
-            self.file.write("url=\"%s\" />" % name)
-            self.writeIndented("\n",-1)
-            self.texNames[name] = 1
-
-    def writeBackground(self):
-        if world:      worldname = world.name
-        else:          return
-        blending = world.getSkytype()  
-        grd = world.getHor()
-        grd0, grd1, grd2 = grd[0], grd[1], grd[2]
-        sky = world.getZen()
-        sky0, sky1, sky2 = sky[0], sky[1], sky[2]
-        mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
-        mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
-        self.file.write("<Background ")
-        if worldname not in self.namesStandard:
-            self.file.write("DEF=\"%s\" " % self.secureName(worldname))
-        # No Skytype - just Hor color
-        if blending == 0:
-            self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.file.write("skyColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-        # Blend Gradient
-        elif blending == 1:
-            self.file.write("groundColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
-            self.file.write("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-            self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
-        # Blend+Real Gradient Inverse
-        elif blending == 3:
-            self.file.write("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-            self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
-            self.file.write("skyColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
-        # Paper - just Zen Color
-        elif blending == 4:
-            self.file.write("groundColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-            self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-        # Blend+Real+Paper - komplex gradient
-        elif blending == 7:
-            self.writeIndented("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-            self.writeIndented("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.writeIndented("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-            self.writeIndented("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-        # Any Other two colors
-        else:
-            self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
-            self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
-        alltexture = len(worldmat)
-        for i in xrange(alltexture):
-            namemat = worldmat[i].getName()
-            pic = worldmat[i].getImage()       
-            if (namemat == "back") and (pic != None):
-                self.file.write("\n\tbackUrl=\"%s\" " % str(pic.getName()))
-            elif (namemat == "bottom") and (pic != None):
-                self.writeIndented("bottomUrl=\"%s\" " % str(pic.getName()))
-            elif (namemat == "front") and (pic != None):
-                self.writeIndented("frontUrl=\"%s\" " % str(pic.getName()))
-            elif (namemat == "left") and (pic != None):
-                self.writeIndented("leftUrl=\"%s\" " % str(pic.getName()))
-            elif (namemat == "right") and (pic != None):
-                self.writeIndented("rightUrl=\"%s\" " % str(pic.getName()))
-            elif (namemat == "top") and (pic != None):
-                self.writeIndented("topUrl=\"%s\" " % str(pic.getName()))
-        self.writeIndented("/>\n\n")
+       def writeHeader(self):
+               #bfile = sys.expandpath( Blender.Get('filename') ).replace('<', '&lt').replace('>', '&gt')
+               bfile = self.filename.replace('<', '&lt').replace('>', '&gt') # use outfile name
+               self.file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
+               self.file.write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.0//EN\" \"http://www.web3d.org/specifications/x3d-3.0.dtd\">\n")
+               self.file.write("<X3D version=\"3.0\" profile=\"Immersive\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema-instance\" xsd:noNamespaceSchemaLocation=\"http://www.web3d.org/specifications/x3d-3.0.xsd\">\n")
+               self.file.write("<head>\n")
+               self.file.write("\t<meta name=\"filename\" content=\"%s\" />\n" % sys.basename(bfile))
+               self.file.write("\t<meta name=\"generator\" content=\"Blender %s\" />\n" % Blender.Get('version'))
+               self.file.write("\t<meta name=\"translator\" content=\"X3D exporter v1.55 (2006/01/17)\" />\n")
+               self.file.write("</head>\n")
+               self.file.write("<Scene>\n")
+       
+       # This functionality is poorly defined, disabling for now - campbell
+       '''
+       def writeInline(self):
+               inlines = Blender.Scene.Get()
+               allinlines = len(inlines)
+               if scene != inlines[0]:
+                       return
+               else:
+                       for i in xrange(allinlines):
+                               nameinline=inlines[i].name
+                               if (nameinline not in self.namesStandard) and (i > 0):
+                                       self.file.write("<Inline DEF=\"%s\" " % (self.cleanStr(nameinline)))
+                                       nameinline = nameinline+".x3d"
+                                       self.file.write("url=\"%s\" />" % nameinline)
+                                       self.file.write("\n\n")
+       '''
+       
+       def writeScript(self):
+               textEditor = Blender.Text.Get() 
+               alltext = len(textEditor)
+               for i in xrange(alltext):
+                       nametext = textEditor[i].name
+                       nlines = textEditor[i].getNLines()
+                       if (self.proto == 1):
+                               if (nametext == "proto" or nametext == "proto.js" or nametext == "proto.txt") and (nlines != None):
+                                       nalllines = len(textEditor[i].asLines())
+                                       alllines = textEditor[i].asLines()
+                                       for j in xrange(nalllines):
+                                               self.writeIndented(alllines[j] + "\n")
+                       elif (self.proto == 0):
+                               if (nametext == "route" or nametext == "route.js" or nametext == "route.txt") and (nlines != None):
+                                       nalllines = len(textEditor[i].asLines())
+                                       alllines = textEditor[i].asLines()
+                                       for j in xrange(nalllines):
+                                               self.writeIndented(alllines[j] + "\n")
+               self.writeIndented("\n")
+
+       def writeViewpoint(self, ob, scene):
+               context = scene.render
+               ratio = float(context.imageSizeY())/float(context.imageSizeX())
+               lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
+               lens = min(lens, math.pi) 
+               
+               # get the camera location, subtract 90 degress from X to orient like X3D does
+               mat = ob.matrixWorld
+               loc = self.rotatePointForVRML(mat.translationPart())
+               rot = mat.toEuler()
+               rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
+               nRot = self.rotatePointForVRML( rot )
+               # convert to Quaternion and to Angle Axis
+               Q  = self.eulerToQuaternions(nRot[0], nRot[1], nRot[2])
+               Q1 = self.multiplyQuaternions(Q[0], Q[1])
+               Qf = self.multiplyQuaternions(Q1, Q[2])
+               angleAxis = self.quaternionToAngleAxis(Qf)
+               self.file.write("<Viewpoint DEF=\"%s\" " % (self.cleanStr(ob.name)))
+               self.file.write("description=\"%s\" " % (ob.name))
+               self.file.write("centerOfRotation=\"0 0 0\" ")
+               self.file.write("position=\"%3.2f %3.2f %3.2f\" " % (loc[0], loc[1], loc[2]))
+               self.file.write("orientation=\"%3.2f %3.2f %3.2f %3.2f\" " % (angleAxis[0], angleAxis[1], -angleAxis[2], angleAxis[3]))
+               self.file.write("fieldOfView=\"%.3f\" />\n\n" % (lens))
+
+       def writeFog(self, world):
+               if world:
+                       mtype = world.getMistype()
+                       mparam = world.getMist()
+                       grd = world.getHor()
+                       grd0, grd1, grd2 = grd[0], grd[1], grd[2]
+               else:
+                       return
+               if (mtype == 1 or mtype == 2):
+                       self.file.write("<Fog fogType=\"%s\" " % self.namesFog[mtype])                                          
+                       self.file.write("color=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
+               else:
+                       return
+       '''
+       def writeNavigationInfo(self, scene):
+               allObj = []
+               allObj = list(scene.objects)
+               headlight = "true"
+               vislimit = 0.0
+               for ob in allObj:
+                       objType=ob.type
+                       if objType == "Camera":
+                               vislimit = ob.data.clipEnd
+                       elif objType == "Lamp":
+                               headlight = "false"
+               self.file.write("<NavigationInfo headlight=\"%s\" " % headlight)
+               self.file.write("visibilityLimit=\"%s\" " % (round(vislimit,self.cp)))
+               self.file.write("type=\"EXAMINE\", \"ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
+       '''
+       def writeSpotLight(self, ob, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+
+               # compute cutoff and beamwidth
+               intensity=min(lamp.energy/1.75,1.0)
+               beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
+               cutOffAngle=beamWidth*1.3
+
+               dx,dy,dz=self.computeDirection(ob)
+               # note -dx seems to equal om[3][0]
+               # note -dz seems to equal om[3][1]
+               # note  dy seems to equal om[3][2]
+
+               location=(ob.matrixWorld*MATWORLD).translationPart()
+               radius = lamp.dist*math.cos(beamWidth)
+               self.file.write("<SpotLight DEF=\"%s\" " % safeName)
+               self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("beamWidth=\"%s\" " % (round(beamWidth,self.cp)))
+               self.file.write("cutOffAngle=\"%s\" " % (round(cutOffAngle,self.cp)))
+               self.file.write("direction=\"%s %s %s\" " % (round(dx,3),round(dy,3),round(dz,3)))
+               self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+               
+               
+       def writeDirectionalLight(self, ob, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+
+               intensity=min(lamp.energy/1.75,1.0) 
+               (dx,dy,dz)=self.computeDirection(ob)
+               self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
+               self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
+
+       def writePointLight(self, ob, lamp, world):
+               safeName = self.cleanStr(ob.name)
+               if world:
+                       ambi = world.amb
+                       ambientIntensity = ((float(ambi[0] + ambi[1] + ambi[2]))/3)/2.5
+               else:
+                       ambi = 0
+                       ambientIntensity = 0
+               
+               location=(ob.matrixWorld*MATWORLD).translationPart()
+               intensity=min(lamp.energy/1.75,1.0) 
+               radius = lamp.dist
+               self.file.write("<PointLight DEF=\"%s\" " % safeName)
+               self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
+               self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
+               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
+               self.file.write("radius=\"%s\" " % radius )
+               self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+
+       def writeNode(self, ob):
+               obname=str(ob.name)
+               if obname in self.namesStandard:
+                       return
+               else:
+                       dx,dy,dz = self.computeDirection(ob)
+                       location=(ob.matrixWorld*MATWORLD).translationPart()
+                       self.writeIndented("<%s\n" % obname,1)
+                       self.writeIndented("# direction %s %s %s\n" % (round(dx,3),round(dy,3),round(dz,3)))
+                       self.writeIndented("# location %s %s %s\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+                       self.writeIndented("/>\n",-1)
+                       self.writeIndented("\n")
+
+       def secureName(self, name):
+               name = name + str(self.nodeID)
+               self.nodeID=self.nodeID+1
+               if len(name) <= 3:
+                       newname = "_" + str(self.nodeID)
+                       return "%s" % (newname)
+               else:
+                       for bad in ['"','#',"'",',','.','[','\\',']','{','}']:
+                               name=name.replace(bad,'_')
+                       if name in self.namesReserved:
+                               newname = name[0:3] + "_" + str(self.nodeID)
+                               return "%s" % (newname)
+                       elif name[0].isdigit():
+                               newname = "_" + name + str(self.nodeID)
+                               return "%s" % (newname)
+                       else:
+                               newname = name
+                               return "%s" % (newname)
+
+       def writeIndexedFaceSet(self, ob, world, normals = 0):
+               imageMap={}   # set of used images
+               sided={}          # 'one':cnt , 'two':cnt
+               vColors={}      # 'multi':1
+               meshName = self.cleanStr(ob.name)
+               mesh=ob.getData(mesh=1)
+               meshME = self.cleanStr(mesh.name)
+               if len(mesh.faces) == 0: return
+               mode = 0
+               if mesh.faceUV:
+                       for face in mesh.faces:
+                               mode |= face.mode 
+               
+               if mode & Mesh.FaceModes.HALO and self.halonode == 0:
+                       self.writeIndented("<Billboard axisOfRotation=\"0 0 0\">\n",1)
+                       self.halonode = 1
+               elif mode & Mesh.FaceModes.BILLBOARD and self.billnode == 0:
+                       self.writeIndented("<Billboard axisOfRotation=\"0 1 0\">\n",1)
+                       self.billnode = 1
+               elif mode & Mesh.FaceModes.OBCOL and self.matonly == 0:
+                       self.matonly = 1
+               elif mode & Mesh.FaceModes.TILES and self.tilenode == 0:
+                       self.tilenode = 1
+               elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
+                       self.writeIndented("<Collision enabled=\"false\">\n",1)
+                       self.collnode = 1
+
+               nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors)
+               
+               if nIFSCnt > 1:
+                       self.writeIndented("<Group DEF=\"%s%s\">\n" % ("G_", meshName),1)
+               
+               if sided.has_key('two') and sided['two'] > 0:
+                       bTwoSided=1
+               else:
+                       bTwoSided=0
+
+               mtx = ob.matrixWorld * MATWORLD
+               
+               loc= mtx.translationPart()
+               sca= mtx.scalePart()
+               quat = mtx.toQuat()
+               rot= quat.axis
+
+               # self.writeIndented('<Transform rotation="%.6f %.6f %.6f %.6f">\n' % (rot[0], rot[1], rot[2], rot[3]))
+               self.writeIndented('<Transform DEF="%s" translation="%.6f %.6f %.6f" scale="%.6f %.6f %.6f" rotation="%.6f %.6f %.6f %.6f">\n' % \
+                 (meshName, loc[0], loc[1], loc[2], sca[0], sca[1], sca[2], rot[0], rot[1], rot[2], quat.angle*DEG2RAD) )
+
+               self.writeIndented("<Shape>\n",1)
+               maters=mesh.materials
+               hasImageTexture=0
+               issmooth=0
+
+               if len(maters) > 0 or mesh.faceUV:
+                       self.writeIndented("<Appearance>\n", 1)
+                       # right now this script can only handle a single material per mesh.
+                       if len(maters) >= 1:
+                               mat=maters[0]
+                               matFlags = mat.getMode()
+                               if not matFlags & Blender.Material.Modes['TEXFACE']:
+                                       self.writeMaterial(mat, self.cleanStr(maters[0].name,''), world)
+                                       if len(maters) > 1:
+                                               print "Warning: mesh named %s has multiple materials" % meshName
+                                               print "Warning: only one material per object handled"
+                       
+                               #-- textures
+                               if mesh.faceUV:
+                                       for face in mesh.faces:
+                                               if (hasImageTexture == 0) and (face.image):
+                                                       self.writeImageTexture(face.image)
+                                                       hasImageTexture=1  # keep track of face texture
+                               if self.tilenode == 1:
+                                       self.writeIndented("<TextureTransform   scale=\"%s %s\" />\n" % (face.image.xrep, face.image.yrep))
+                                       self.tilenode = 0
+                               self.writeIndented("</Appearance>\n", -1)
+
+               #-- IndexedFaceSet or IndexedLineSet
+
+               # user selected BOUNDS=1, SOLID=3, SHARED=4, or TEXTURE=5
+               ifStyle="IndexedFaceSet"
+               # look up mesh name, use it if available
+               if self.meshNames.has_key(meshME):
+                       self.writeIndented("<%s USE=\"ME_%s\">" % (ifStyle, meshME), 1)
+                       self.meshNames[meshME]+=1
+               else:
+                       if int(mesh.users) > 1:
+                               self.writeIndented("<%s DEF=\"ME_%s\" " % (ifStyle, meshME), 1)
+                               self.meshNames[meshME]=1
+                       else:
+                               self.writeIndented("<%s " % ifStyle, 1)
+                       
+                       if bTwoSided == 1:
+                               self.file.write("solid=\"false\" ")
+                       else:
+                               self.file.write("solid=\"true\" ")
+
+                       for face in mesh.faces:
+                               if face.smooth:
+                                        issmooth=1
+                                        break
+                       if issmooth==1:
+                               creaseAngle=(mesh.degr)*(math.pi/180.0)
+                               self.file.write("creaseAngle=\"%s\" " % (round(creaseAngle,self.cp)))
+
+                       #--- output textureCoordinates if UV texture used
+                       if mesh.faceUV:
+                               if self.matonly == 1 and self.share == 1:
+                                       self.writeFaceColors(mesh)
+                               elif hasImageTexture == 1:
+                                       self.writeTextureCoordinates(mesh)
+                       #--- output coordinates
+                       self.writeCoordinates(ob, mesh, meshName)
+
+                       self.writingcoords = 1
+                       self.writingtexture = 1
+                       self.writingcolor = 1
+                       self.writeCoordinates(ob, mesh, meshName)
+                       
+                       #--- output textureCoordinates if UV texture used
+                       if mesh.faceUV:
+                               if hasImageTexture == 1:
+                                       self.writeTextureCoordinates(mesh)
+                               elif self.matonly == 1 and self.share == 1:
+                                       self.writeFaceColors(mesh)
+                       #--- output vertexColors
+               self.matonly = 0
+               self.share = 0
+               
+               self.writingcoords = 0
+               self.writingtexture = 0
+               self.writingcolor = 0
+               #--- output closing braces
+               self.writeIndented("</%s>\n" % ifStyle, -1)
+               self.writeIndented("</Shape>\n", -1)
+               self.writeIndented("</Transform>\n", -1)
+
+               if self.halonode == 1:
+                       self.writeIndented("</Billboard>\n", -1)
+                       self.halonode = 0
+
+               if self.billnode == 1:
+                       self.writeIndented("</Billboard>\n", -1)
+                       self.billnode = 0
+
+               if self.collnode == 1:
+                       self.writeIndented("</Collision>\n", -1)
+                       self.collnode = 0
+
+               if nIFSCnt > 1:
+                       self.writeIndented("</Group>\n", -1)
+
+               self.file.write("\n")
+
+       def writeCoordinates(self, ob, mesh, meshName):
+               # create vertex list and pre rotate -90 degrees X for VRML
+               
+               if self.writingcoords == 0:
+                       self.file.write('coordIndex="')
+                       for face in mesh.faces:
+                               fv = face.v
+                               if len(face)==4:
+                                       self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
+                               else:
+                                       self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+                       self.file.write("\">\n")
+               else:
+                       #-- vertices
+                       # mesh.transform(ob.matrixWorld)
+                       self.writeIndented("<Coordinate DEF=\"%s%s\" \n" % ("coord_",meshName), 1)
+                       self.file.write("\t\t\t\tpoint=\"")
+                       for v in mesh.verts:
+                               self.file.write("%.6f %.6f %.6f, " % tuple(v.co))
+                       self.file.write("\" />")
+                       self.writeIndented("\n", -1)
+
+       def writeTextureCoordinates(self, mesh):
+               texCoordList=[] 
+               texIndexList=[]
+               j=0
+
+               for face in mesh.faces:
+                       for uv in face.uv:
+                               texIndexList.append(j)
+                               texCoordList.append(uv)
+                               j=j+1
+                       texIndexList.append(-1)
+               if self.writingtexture == 0:
+                       self.file.write("\n\t\t\ttexCoordIndex=\"")
+                       texIndxStr=""
+                       for i in xrange(len(texIndexList)):
+                               texIndxStr = texIndxStr + "%d, " % texIndexList[i]
+                               if texIndexList[i]==-1:
+                                       self.file.write(texIndxStr)
+                                       texIndxStr=""
+                       self.file.write("\"\n\t\t\t")
+               else:
+                       self.writeIndented("<TextureCoordinate point=\"", 1)
+                       for i in xrange(len(texCoordList)):
+                               self.file.write("%s %s, " % (round(texCoordList[i][0],self.tp), round(texCoordList[i][1],self.tp)))
+                       self.file.write("\" />")
+                       self.writeIndented("\n", -1)
+
+       def writeFaceColors(self, mesh):
+               if self.writingcolor == 0:
+                       self.file.write("colorPerVertex=\"false\" ")
+               else:
+                       self.writeIndented("<Color color=\"", 1)
+                       for face in mesh.faces:
+                               if face.col:
+                                       c=face.col[0]
+                                       if self.verbose > 2:
+                                               print "Debug: face.col r=%d g=%d b=%d" % (c.r, c.g, c.b)
+                                       aColor = self.rgbToFS(c)
+                                       self.file.write("%s, " % aColor)
+                       self.file.write("\" />")
+                       self.writeIndented("\n",-1)
+       
+       def writeMaterial(self, mat, matName, world):
+               # look up material name, use it if available
+               if self.matNames.has_key(matName):
+                       self.writeIndented("<Material USE=\"MA_%s\" />\n" % matName)
+                       self.matNames[matName]+=1
+                       return;
+
+               self.matNames[matName]=1
+
+               ambient = mat.amb/3
+               diffuseR, diffuseG, diffuseB = mat.rgbCol[0], mat.rgbCol[1],mat.rgbCol[2]
+               if world:
+                       ambi = world.getAmb()
+                       ambi0, ambi1, ambi2 = (ambi[0]*mat.amb)*2, (ambi[1]*mat.amb)*2, (ambi[2]*mat.amb)*2
+               else:
+                       ambi0, ambi1, ambi2 = 0, 0, 0
+               emisR, emisG, emisB = (diffuseR*mat.emit+ambi0)/2, (diffuseG*mat.emit+ambi1)/2, (diffuseB*mat.emit+ambi2)/2
+
+               shininess = mat.hard/512.0
+               specR = (mat.specCol[0]+0.001)/(1.25/(mat.spec+0.001))
+               specG = (mat.specCol[1]+0.001)/(1.25/(mat.spec+0.001))
+               specB = (mat.specCol[2]+0.001)/(1.25/(mat.spec+0.001))
+               transp = 1-mat.alpha
+               matFlags = mat.getMode()
+               if matFlags & Blender.Material.Modes['SHADELESS']:
+                 ambient = 1
+                 shine = 1
+                 specR = emitR = diffuseR
+                 specG = emitG = diffuseG
+                 specB = emitB = diffuseB
+               self.writeIndented("<Material DEF=\"MA_%s\" " % matName, 1)
+               self.file.write("diffuseColor=\"%s %s %s\" " % (round(diffuseR,self.cp), round(diffuseG,self.cp), round(diffuseB,self.cp)))
+               self.file.write("specularColor=\"%s %s %s\" " % (round(specR,self.cp), round(specG,self.cp), round(specB,self.cp)))
+               self.file.write("emissiveColor=\"%s %s %s\" \n" % (round(emisR,self.cp), round(emisG,self.cp), round(emisB,self.cp)))
+               self.writeIndented("ambientIntensity=\"%s\" " % (round(ambient,self.cp)))
+               self.file.write("shininess=\"%s\" " % (round(shininess,self.cp)))
+               self.file.write("transparency=\"%s\" />" % (round(transp,self.cp)))
+               self.writeIndented("\n",-1)
+
+       def writeImageTexture(self, image):
+               name = image.name
+               filename = image.filename.split('/')[-1].split('\\')[-1]
+               if self.texNames.has_key(name):
+                       self.writeIndented("<ImageTexture USE=\"%s\" />\n" % self.cleanStr(name))
+                       self.texNames[name] += 1
+                       return
+               else:
+                       self.writeIndented("<ImageTexture DEF=\"%s\" " % self.cleanStr(name), 1)
+                       self.file.write("url=\"%s\" />" % name)
+                       self.writeIndented("\n",-1)
+                       self.texNames[name] = 1
+
+       def writeBackground(self, world, alltextures):
+               if world:       worldname = world.name
+               else:           return
+               blending = world.getSkytype()   
+               grd = world.getHor()
+               grd0, grd1, grd2 = grd[0], grd[1], grd[2]
+               sky = world.getZen()
+               sky0, sky1, sky2 = sky[0], sky[1], sky[2]
+               mix0, mix1, mix2 = grd[0]+sky[0], grd[1]+sky[1], grd[2]+sky[2]
+               mix0, mix1, mix2 = mix0/2, mix1/2, mix2/2
+               self.file.write("<Background ")
+               if worldname not in self.namesStandard:
+                       self.file.write("DEF=\"%s\" " % self.secureName(worldname))
+               # No Skytype - just Hor color
+               if blending == 0:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+               # Blend Gradient
+               elif blending == 1:
+                       self.file.write("groundColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+               # Blend+Real Gradient Inverse
+               elif blending == 3:
+                       self.file.write("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s, " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(mix0,self.cp), round(mix1,self.cp), round(mix2,self.cp)))
+               # Paper - just Zen Color
+               elif blending == 4:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+               # Blend+Real+Paper - komplex gradient
+               elif blending == 7:
+                       self.writeIndented("groundColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.writeIndented("%s %s %s\" groundAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.writeIndented("skyColor=\"%s %s %s, " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+                       self.writeIndented("%s %s %s\" skyAngle=\"1.57, 1.57\" " %(round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+               # Any Other two colors
+               else:
+                       self.file.write("groundColor=\"%s %s %s\" " % (round(grd0,self.cp), round(grd1,self.cp), round(grd2,self.cp)))
+                       self.file.write("skyColor=\"%s %s %s\" " % (round(sky0,self.cp), round(sky1,self.cp), round(sky2,self.cp)))
+               alltexture = len(alltextures)
+               for i in xrange(alltexture):
+                       namemat = alltextures[i].name
+                       pic = alltextures[i].getImage()
+                       if (namemat == "back") and (pic != None):
+                               self.file.write("\n\tbackUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "bottom") and (pic != None):
+                               self.writeIndented("bottomUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "front") and (pic != None):
+                               self.writeIndented("frontUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "left") and (pic != None):
+                               self.writeIndented("leftUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "right") and (pic != None):
+                               self.writeIndented("rightUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+                       elif (namemat == "top") and (pic != None):
+                               self.writeIndented("topUrl=\"%s\" " % pic.filename.split('/')[-1].split('\\')[-1])
+               self.writeIndented("/>\n\n")
 
 ##########################################################
 # export routine
 ##########################################################
 
-    def export(self, scene, world, worldmat):
-        print "Info: starting X3D export to " + self.filename + "..."
-        self.writeHeader()
-        self.writeScript()
-        self.writeNavigationInfo(scene)
-        self.writeBackground()
-        self.writeFog()
-        self.proto = 0
-        allObj = []
-        if ARG == 'selected':
-            allObj = list(scene.objects.context)
-        else:
-            allObj = list(scene.objects)
-            self.writeInline()
-        for thisObj in allObj:
-            try:
-                objType=thisObj.type
-                objName=thisObj.name
-                self.matonly = 0
-                if objType == "Camera":
-                    self.writeViewpoint(thisObj)
-                elif objType == "Mesh":
-                    self.writeIndexedFaceSet(thisObj, normals = 0)
-                elif objType == "Lamp":
-                    lmpName= thisObj.data
-                    lmpType=lmpName.getType()
-                    if lmpType == Lamp.Types.Lamp:
-                        self.writePointLight(thisObj, lmpName)
-                    elif lmpType == Lamp.Types.Spot:
-                        self.writeSpotLight(thisObj, lmpName)
-                    elif lmpType == Lamp.Types.Sun:
-                        self.writeDirectionalLight(thisObj, lmpName)
-                    else:
-                        self.writeDirectionalLight(thisObj, lmpName)
-                elif objType == "Empty" and objName != "Empty":
-                    self.writeNode(thisObj)
-                else:
-                    #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType())
-                    print ""
-            except AttributeError:
-                print "Error: Unable to get type info for %s" % thisObj.getName()
-        if ARG != 'selected':
-            self.writeScript()
-        self.file.write("\n</Scene>\n</X3D>")
-        self.cleanup()
-        
+       def export(self, scene, world, alltextures):
+               print "Info: starting X3D export to " + self.filename + "..."
+               self.writeHeader()
+               self.writeScript()
+               # self.writeNavigationInfo(scene) # This seems to position me in some strange area I cant see the model (with BS Contact) - Campbell
+               self.writeBackground(world, alltextures)
+               self.writeFog(world)
+               self.proto = 0
+               
+               for ob in scene.objects.context:
+                       objType=ob.type
+                       objName=ob.name
+                       self.matonly = 0
+                       if objType == "Camera":
+                               self.writeViewpoint(ob, scene)
+                       elif objType == "Mesh":
+                               self.writeIndexedFaceSet(ob, world, normals = 0)
+                       elif objType == "Lamp":
+                               data= ob.data
+                               datatype=data.type
+                               if datatype == Lamp.Types.Lamp:
+                                       self.writePointLight(ob, data, world)
+                               elif datatype == Lamp.Types.Spot:
+                                       self.writeSpotLight(ob, data, world)
+                               elif datatype == Lamp.Types.Sun:
+                                       self.writeDirectionalLight(ob, data, world)
+                               else:
+                                       self.writeDirectionalLight(ob, data, world)
+                       elif objType == "Empty" and objName != "Empty":
+                               self.writeNode(ob)
+                       else:
+                               #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
+                               print ""
+               
+               if ARG != 'selected':
+                       self.writeScript()
+               self.file.write("\n</Scene>\n</X3D>")
+               self.cleanup()
+               
 ##########################################################
 # Utility methods
 ##########################################################
 
-    def cleanup(self):
-        self.file.close()
-        self.texNames={}
-        self.matNames={}
-        self.indentLevel=0
-        print "Info: finished X3D export to %s\n" % self.filename
-
-    def cleanStr(self, name, prefix='rsvd_'):
-        """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
-
-        newName=name[:]
-        if len(newName) == 0:
-            self.nNodeID+=1
-            return "%s%d" % (prefix, self.nNodeID)
-        
-        if newName in self.namesReserved:
-            newName='%s%s' % (prefix,newName)
-        
-        if newName[0].isdigit():
-            newName='%s%s' % ('_',newName)
-
-        for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']:
-            newName=newName.replace(bad,'_')
-        return newName
-
-    def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors):
-        """
-        countIFFSetsNeeded() - should look at a blender mesh to determine
-        how many VRML IndexFaceSets or IndexLineSets are needed.  A
-        new mesh created under the following conditions:
-        
-         o - split by UV Textures / one per mesh
-         o - split by face, one sided and two sided
-         o - split by smooth and flat faces
-         o - split when faces only have 2 vertices * needs to be an IndexLineSet
-        """
-        
-        imageNameMap={}
-        faceMap={}
-        nFaceIndx=0
-        
-        for face in mesh.faces:
-            sidename='';
-            if (face.mode & NMesh.FaceModes.TWOSIDE) == NMesh.FaceModes.TWOSIDE:
-                sidename='two'
-            else:
-                sidename='one'
-            
-            if sided.has_key(sidename):
-                sided[sidename]+=1
-            else:
-                sided[sidename]=1
-
-            if face.image:
-                faceName="%s_%s" % (face.image.name, sidename);
-
-                try:
-                    imageMap[faceName].append(face)
-                except:
-                    imageMap[faceName]=[face.image.name,sidename,face]
-
-        if self.verbose > 2:
-            for faceName in imageMap.iterkeys():
-                ifs=imageMap[faceName]
-                print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
-                      (faceName, ifs[0], ifs[1], len(ifs)-2)
-
-        return len(imageMap)
-    
-    def faceToString(self,face):
-
-        print "Debug: face.flag=0x%x (bitflags)" % face.flag
-        if face.sel:
-            print "Debug: face.sel=true"
-
-        print "Debug: face.mode=0x%x (bitflags)" % face.mode
-        if (face.mode & NMesh.FaceModes.TWOSIDE) == NMesh.FaceModes.TWOSIDE:
-            print "Debug: face.mode twosided"
-
-        print "Debug: face.transp=0x%x (enum)" % face.transp
-        if face.transp == NMesh.FaceTranspModes.SOLID:
-            print "Debug: face.transp.SOLID"
-
-        if face.image:
-            print "Debug: face.image=%s" % face.image.name
-        print "Debug: face.materialIndex=%d" % face.materialIndex 
-
-    def getVertexColorByIndx(self, mesh, indx):
-        c = None
-        for face in mesh.faces:
-            j=0
-            for vertex in face.v:
-                if vertex.index == indx:
-                    c=face.col[j]
-                    break
-                j=j+1
-            if c: break
-        return c
-
-    def meshToString(self,mesh):
-        print "Debug: mesh.hasVertexUV=%d" % mesh.hasVertexUV()
-        print "Debug: mesh.hasFaceUV=%d" % mesh.hasFaceUV()
-        print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()
-        print "Debug: mesh.verts=%d" % len(mesh.verts)
-        print "Debug: mesh.faces=%d" % len(mesh.faces)
-        print "Debug: mesh.materials=%d" % len(mesh.materials)
-
-    def rgbToFS(self, c):
-        s="%s %s %s" % (
-            round(c.r/255.0,self.cp),
-            round(c.g/255.0,self.cp),
-            round(c.b/255.0,self.cp))
-        return s
-
-    def computeDirection(self, ob):
-        x,y,z=(0,-1.0,0) # point down
-        ax,ay,az = (ob.RotX,ob.RotZ,ob.RotY)
-
-        # rot X
-        x1=x
-        y1=y*math.cos(ax)-z*math.sin(ax)
-        z1=y*math.sin(ax)+z*math.cos(ax)
-
-        # rot Y
-        x2=x1*math.cos(ay)+z1*math.sin(ay)
-        y2=y1
-        z2=z1*math.cos(ay)-x1*math.sin(ay)
-
-        # rot Z
-        x3=x2*math.cos(az)-y2*math.sin(az)
-        y3=x2*math.sin(az)+y2*math.cos(az)
-        z3=z2
-
-        return [x3,y3,z3]
-        
-
-    # swap Y and Z to handle axis difference between Blender and VRML
-    #------------------------------------------------------------------------
-    def rotatePointForVRML(self, v):
-        x = v[0]
-        y = v[2]
-        z = -v[1]
-        
-        vrmlPoint=[x, y, z]
-        return vrmlPoint
-
-    # For writing well formed VRML code
-    #------------------------------------------------------------------------
-    def writeIndented(self, s, inc=0):
-        if inc < 1:
-            self.indentLevel = self.indentLevel + inc
-
-        spaces=""
-        for x in xrange(self.indentLevel):
-            spaces = spaces + "\t"
-        self.file.write(spaces + s)
-
-        if inc > 0:
-            self.indentLevel = self.indentLevel + inc
-
-    # Converts a Euler to three new Quaternions
-    # Angles of Euler are passed in as radians
-    #------------------------------------------------------------------------
-    def eulerToQuaternions(self, x, y, z):
-        Qx = [math.cos(x/2), math.sin(x/2), 0, 0]
-        Qy = [math.cos(y/2), 0, math.sin(y/2), 0]
-        Qz = [math.cos(z/2), 0, 0, math.sin(z/2)]
-        
-        quaternionVec=[Qx,Qy,Qz]
-        return quaternionVec
-    
-    # Multiply two Quaternions together to get a new Quaternion
-    #------------------------------------------------------------------------
-    def multiplyQuaternions(self, Q1, Q2):
-        result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])),
-                  ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])),
-                  ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])),
-                  ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))]
-        
-        return result
-    
-    # Convert a Quaternion to an Angle Axis (ax, ay, az, angle)
-    # angle is in radians
-    #------------------------------------------------------------------------
-    def quaternionToAngleAxis(self, Qf):
-        scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2)
-        ax = Qf[1]
-        ay = Qf[2]
-        az = Qf[3]
-
-        if scale > .0001:
-            ax/=scale
-            ay/=scale
-            az/=scale
-        
-        angle = 2 * math.acos(Qf[0])
-        
-        result = [ax, ay, az, angle]
-        return result
+       def cleanup(self):
+               self.file.close()
+               self.texNames={}
+               self.matNames={}
+               self.indentLevel=0
+               print "Info: finished X3D export to %s\n" % self.filename
+
+       def cleanStr(self, name, prefix='rsvd_'):
+               """cleanStr(name,prefix) - try to create a valid VRML DEF name from object name"""
+
+               newName=name[:]
+               if len(newName) == 0:
+                       self.nNodeID+=1
+                       return "%s%d" % (prefix, self.nNodeID)
+               
+               if newName in self.namesReserved:
+                       newName='%s%s' % (prefix,newName)
+               
+               if newName[0].isdigit():
+                       newName='%s%s' % ('_',newName)
+
+               for bad in [' ','"','#',"'",',','.','[','\\',']','{','}']:
+                       newName=newName.replace(bad,'_')
+               return newName
+
+       def countIFSSetsNeeded(self, mesh, imageMap, sided, vColors):
+               """
+               countIFFSetsNeeded() - should look at a blender mesh to determine
+               how many VRML IndexFaceSets or IndexLineSets are needed.  A
+               new mesh created under the following conditions:
+               
+                o - split by UV Textures / one per mesh
+                o - split by face, one sided and two sided
+                o - split by smooth and flat faces
+                o - split when faces only have 2 vertices * needs to be an IndexLineSet
+               """
+               
+               imageNameMap={}
+               faceMap={}
+               nFaceIndx=0
+               
+               if mesh.faceUV:
+                       for face in mesh.faces:
+                               sidename='';
+                               if  face.mode & Mesh.FaceModes.TWOSIDE:
+                                       sidename='two'
+                               else:
+                                       sidename='one'
+                               
+                               if sided.has_key(sidename):
+                                       sided[sidename]+=1
+                               else:
+                                       sided[sidename]=1
+                               
+                               image = face.image
+                               if image:
+                                       faceName="%s_%s" % (face.image.name, sidename);
+                                       try:
+                                               imageMap[faceName].append(face)
+                                       except:
+                                               imageMap[faceName]=[face.image.name,sidename,face]
+
+                       if self.verbose > 2:
+                               for faceName in imageMap.iterkeys():
+                                       ifs=imageMap[faceName]
+                                       print "Debug: faceName=%s image=%s, solid=%s facecnt=%d" % \
+                                                 (faceName, ifs[0], ifs[1], len(ifs)-2)
+
+               return len(imageMap)
+       
+       def faceToString(self,face):
+
+               print "Debug: face.flag=0x%x (bitflags)" % face.flag
+               if face.sel:
+                       print "Debug: face.sel=true"
+
+               print "Debug: face.mode=0x%x (bitflags)" % face.mode
+               if face.mode & Mesh.FaceModes.TWOSIDE:
+                       print "Debug: face.mode twosided"
+
+               print "Debug: face.transp=0x%x (enum)" % face.transp
+               if face.transp == Mesh.FaceTranspModes.SOLID:
+                       print "Debug: face.transp.SOLID"
+
+               if face.image:
+                       print "Debug: face.image=%s" % face.image.name
+               print "Debug: face.materialIndex=%d" % face.materialIndex 
+
+       def getVertexColorByIndx(self, mesh, indx):
+               c = None
+               for face in mesh.faces:
+                       j=0
+                       for vertex in face.v:
+                               if vertex.index == indx:
+                                       c=face.col[j]
+                                       break
+                               j=j+1
+                       if c: break
+               return c
+
+       def meshToString(self,mesh):
+               print "Debug: mesh.hasVertexUV=%d" % mesh.vertexColors
+               print "Debug: mesh.faceUV=%d" % mesh.faceUV
+               print "Debug: mesh.hasVertexColours=%d" % mesh.hasVertexColours()
+               print "Debug: mesh.verts=%d" % len(mesh.verts)
+               print "Debug: mesh.faces=%d" % len(mesh.faces)
+               print "Debug: mesh.materials=%d" % len(mesh.materials)
+
+       def rgbToFS(self, c):
+               s="%s %s %s" % (
+                       round(c.r/255.0,self.cp),
+                       round(c.g/255.0,self.cp),
+                       round(c.b/255.0,self.cp))
+               return s
+
+       def computeDirection(self, ob):
+               x,y,z=(0,-1.0,0) # point down
+               
+               ax,ay,az = (ob.matrixWorld*MATWORLD).toEuler()
+               
+               ax *= DEG2RAD
+               ay *= DEG2RAD
+               az *= DEG2RAD
+               # rot X
+               x1=x
+               y1=y*math.cos(ax)-z*math.sin(ax)
+               z1=y*math.sin(ax)+z*math.cos(ax)
+
+               # rot Y
+               x2=x1*math.cos(ay)+z1*math.sin(ay)
+               y2=y1
+               z2=z1*math.cos(ay)-x1*math.sin(ay)
+
+               # rot Z
+               x3=x2*math.cos(az)-y2*math.sin(az)
+               y3=x2*math.sin(az)+y2*math.cos(az)
+               z3=z2
+
+               return [x3,y3,z3]
+               
+
+       # swap Y and Z to handle axis difference between Blender and VRML
+       #------------------------------------------------------------------------
+       def rotatePointForVRML(self, v):
+               x = v[0]
+               y = v[2]
+               z = -v[1]
+               
+               vrmlPoint=[x, y, z]
+               return vrmlPoint
+
+       # For writing well formed VRML code
+       #------------------------------------------------------------------------
+       def writeIndented(self, s, inc=0):
+               if inc < 1:
+                       self.indentLevel = self.indentLevel + inc
+
+               spaces=""
+               for x in xrange(self.indentLevel):
+                       spaces = spaces + "\t"
+               self.file.write(spaces + s)
+
+               if inc > 0:
+                       self.indentLevel = self.indentLevel + inc
+
+       # Converts a Euler to three new Quaternions
+       # Angles of Euler are passed in as radians
+       #------------------------------------------------------------------------
+       def eulerToQuaternions(self, x, y, z):
+               Qx = [math.cos(x/2), math.sin(x/2), 0, 0]
+               Qy = [math.cos(y/2), 0, math.sin(y/2), 0]
+               Qz = [math.cos(z/2), 0, 0, math.sin(z/2)]
+               
+               quaternionVec=[Qx,Qy,Qz]
+               return quaternionVec
+       
+       # Multiply two Quaternions together to get a new Quaternion
+       #------------------------------------------------------------------------
+       def multiplyQuaternions(self, Q1, Q2):
+               result = [((Q1[0] * Q2[0]) - (Q1[1] * Q2[1]) - (Q1[2] * Q2[2]) - (Q1[3] * Q2[3])),
+                                 ((Q1[0] * Q2[1]) + (Q1[1] * Q2[0]) + (Q1[2] * Q2[3]) - (Q1[3] * Q2[2])),
+                                 ((Q1[0] * Q2[2]) + (Q1[2] * Q2[0]) + (Q1[3] * Q2[1]) - (Q1[1] * Q2[3])),
+                                 ((Q1[0] * Q2[3]) + (Q1[3] * Q2[0]) + (Q1[1] * Q2[2]) - (Q1[2] * Q2[1]))]
+               
+               return result
+       
+       # Convert a Quaternion to an Angle Axis (ax, ay, az, angle)
+       # angle is in radians
+       #------------------------------------------------------------------------
+       def quaternionToAngleAxis(self, Qf):
+               scale = math.pow(Qf[1],2) + math.pow(Qf[2],2) + math.pow(Qf[3],2)
+               ax = Qf[1]
+               ay = Qf[2]
+               az = Qf[3]
+
+               if scale > .0001:
+                       ax/=scale
+                       ay/=scale
+                       az/=scale
+               
+               angle = 2 * math.acos(Qf[0])
+               
+               result = [ax, ay, az, angle]
+               return result
 
 ##########################################################
 # Callbacks, needed before Main
 ##########################################################
 
 def select_file(filename):
-  if not filename.endswith(extension):
-    filename += extension
-  if _safeOverwrite and sys.exists(filename):
-    result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
-    if(result != 1):
-      return
-
-  wrlexport=VRML2Export(filename)
-  wrlexport.export(scene, world, worldmat)
-
-def createWRLPath():
-  filename = Blender.Get('filename')
-  print filename
-  
-  if filename.find('.') != -1:
-    filename = filename.split('.')[0]
-    filename += extension
-    print filename
-
-  return filename
+       if not filename.endswith(extension):
+               filename += extension
+       #if _safeOverwrite and sys.exists(filename):
+       #       result = Draw.PupMenu("File Already Exists, Overwrite?%t|Yes%x1|No%x0")
+       #if(result != 1):
+       #       return
+       
+       scene = Blender.Scene.GetCurrent()
+       world = scene.world
+       alltextures = Blender.Texture.Get()
+
+       wrlexport=VRML2Export(filename)
+       wrlexport.export(scene, world, alltextures)
+
 
 #########################################################
 # main routine
 #########################################################
 
-try:
-    ARG = __script__['arg'] # user selected argument
-except:
-    print "older version"
-
-if Blender.Get('version') < 235:
-  print "Warning: X3D export failed, wrong blender version!"
-  print " You aren't running blender version 2.35 or greater"
-  print " download a newer version from http://blender3d.org/"
-else:
-  if ARG == 'comp':
-    from gzip import *
-    extension=".x3dz"
-  else:
-    extension=".x3d"
-  Blender.Window.FileSelector(select_file,"Export X3D",createWRLPath())
-
+if __name__ == '__main__':
+       Blender.Window.FileSelector(select_file,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
+       # select_file('/shared/bed1.x3d')
index 76581e4f34f499d8c978b2cbab7bc8e1ebbc7de6..b3b68a9b3ff21c5c9bb04be75433909578957ecb 100644 (file)
@@ -33,7 +33,8 @@
 #ifndef BKE_NODE_H
 #define BKE_NODE_H
 
-
+/* not very important, but the stack solver likes to know a maximum */
+#define MAX_SOCKET     64
 
 struct ID;
 struct bNodeTree;
index f31c5a0d6728dcc8f7e2e466257b1308a0a33c09..654cf0991ccde0697cc6d16a1e48a2dbb15ea049 100644 (file)
@@ -3304,7 +3304,9 @@ void loadFluidsimMesh(Object *srcob, int useRenderParams)
        } else { // 3
                strcat(targetDir,"fluidsurface_final_####");
        }
-       BLI_convertstringcode(targetDir, G.sce, curFrame); // fixed #frame-no 
+       BLI_convertstringcode(targetDir, G.sce);
+       BLI_convertstringframe(targetDir, curFrame); // fixed #frame-no 
+       
        strcpy(targetFile,targetDir);
        strcat(targetFile, ".bobj.gz");
 
index 88ae02cd4185c69ea9d67d073e6e353cdb1e17f1..f60e39769a2a52403b40bcbbe09591c2cc7c9a90 100644 (file)
@@ -1104,9 +1104,9 @@ static void vectomat (float *vec, float *target_up, short axis, short upflag, sh
        /* identity matrix - don't do anything if the two axes are the same */
        else {
                m[0][0]= m[1][1]= m[2][2]= 1.0;
-               m[0][1]= m[0][2]= m[0][3]= 0.0;
-               m[1][0]= m[1][2]= m[1][3]= 0.0;
-               m[2][0]= m[2][1]= m[2][3]= 0.0;
+               m[0][1]= m[0][2]= 0.0;
+               m[1][0]= m[1][2]= 0.0;
+               m[2][0]= m[2][1]= 0.0;
        }
 }
 
index 8a982b15df7c6a80682dc08946b786a07802a1d2..ff0b2e6db0a4c6df216fb28d1c22907694feb7d0 100644 (file)
@@ -351,7 +351,8 @@ Image *BKE_add_image_file(const char *name)
        }
        
        BLI_strncpy(str, name, sizeof(str));
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(str, G.sce);
+       BLI_convertstringframe(str, G.scene->r.cfra); /* TODO - should this realy be here? */
        
        /* exists? */
        file= open(str, O_BINARY|O_RDONLY);
@@ -362,7 +363,8 @@ Image *BKE_add_image_file(const char *name)
        for(ima= G.main->image.first; ima; ima= ima->id.next) {
                if(ima->source!=IMA_SRC_VIEWER && ima->source!=IMA_SRC_GENERATED) {
                        BLI_strncpy(strtest, ima->name, sizeof(ima->name));
-                       BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
+                       BLI_convertstringcode(strtest, G.sce);
+                       BLI_convertstringframe(strtest, G.scene->r.cfra); /* TODO - should this be here? */
                        
                        if( strcmp(strtest, str)==0 ) {
                                if(ima->anim==NULL || ima->id.us==0) {
@@ -1243,7 +1245,8 @@ void BKE_makepicstring(char *string, char *base, int frame, int imtype)
        if (strchr(string, '#')==NULL)
                strcat(string, "####"); /* 4 numbers */
        
-       BLI_convertstringcode(string, G.sce, frame);
+       BLI_convertstringcode(string, G.sce);
+       BLI_convertstringframe(string, frame);
 
        if(G.scene->r.scemode & R_EXTENSION) 
                BKE_add_image_extension(string, imtype);
@@ -1479,9 +1482,11 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
        BLI_strncpy(name, ima->name, sizeof(name));
        
        if(ima->id.lib)
-               BLI_convertstringcode(name, ima->id.lib->filename, frame);
+               BLI_convertstringcode(name, ima->id.lib->filename);
        else
-               BLI_convertstringcode(name, G.sce, frame);
+               BLI_convertstringcode(name, G.sce);
+       
+       BLI_convertstringframe(name, frame); /* TODO - should this be here? */
        
        /* read ibuf */
        ibuf = IMB_loadiffname(name, IB_rect|IB_multilayer);
@@ -1582,9 +1587,9 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
                
                BLI_strncpy(str, ima->name, FILE_MAX);
                if(ima->id.lib)
-                       BLI_convertstringcode(str, ima->id.lib->filename, 0);
+                       BLI_convertstringcode(str, ima->id.lib->filename);
                else
-                       BLI_convertstringcode(str, G.sce, 0);
+                       BLI_convertstringcode(str, G.sce);
                
                ima->anim = openanim(str, IB_cmap | IB_rect);
                
@@ -1636,9 +1641,11 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
                /* get the right string */
                BLI_strncpy(str, ima->name, sizeof(str));
                if(ima->id.lib)
-                       BLI_convertstringcode(str, ima->id.lib->filename, cfra);
+                       BLI_convertstringcode(str, ima->id.lib->filename);
                else
-                       BLI_convertstringcode(str, G.sce, cfra);
+                       BLI_convertstringcode(str, G.sce);
+               
+               BLI_convertstringframe(str, cfra);
                
                /* read ibuf */
                ibuf = IMB_loadiffname(str, IB_rect|IB_multilayer|IB_imginfo);
index 8740a3d1ed4adf86b1a4e1da40fc75cc720a8ba6..cc3f3f211a49b6630047803f5e620a74f2fc0dca 100644 (file)
@@ -974,7 +974,7 @@ static void image_fix_relative_path(Image *ima)
 {
        if(ima->id.lib==NULL) return;
        if(strncmp(ima->name, "//", 2)==0) {
-               BLI_convertstringcode(ima->name, ima->id.lib->filename, 0);
+               BLI_convertstringcode(ima->name, ima->id.lib->filename);
                BLI_makestringcode(G.sce, ima->name);
        }
 }
index 14e70075e32ccb8b26e57920eaa26252cb2693f2..16916381c95b74c364d2b7e4bc46be29264d706a 100644 (file)
@@ -1214,8 +1214,8 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
                p->y = neg.y;
                p->z = neg.z;
                while (1) {
-                       p->x = 0.5f*(pos.x + neg.x);
                        if (i++ == RES) return;
+                       p->x = 0.5f*(pos.x + neg.x);
                        if ((function(p->x,p->y,p->z)) > 0.0)   pos.x = p->x; else neg.x = p->x; 
                }
        }
@@ -1224,8 +1224,8 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
                p->x = neg.x;
                p->z = neg.z;
                while (1) {
-                       p->y = 0.5f*(pos.y + neg.y);
                        if (i++ == RES) return;
+                       p->y = 0.5f*(pos.y + neg.y);
                        if ((function(p->x,p->y,p->z)) > 0.0)   pos.y = p->y; else neg.y = p->y;
                }
        }
@@ -1234,8 +1234,8 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2,
                p->x = neg.x;
                p->y = neg.y;
                while (1) {
-                       p->z = 0.5f*(pos.z + neg.z);
                        if (i++ == RES) return;
+                       p->z = 0.5f*(pos.z + neg.z);
                        if ((function(p->x,p->y,p->z)) > 0.0)   pos.z = p->z; else neg.z = p->z;
                }
        }
@@ -1300,6 +1300,8 @@ void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
        int index[3]={1,0,-1};
        float f =0.0f;
        float in_v, out_v;
+       MB_POINT workp;
+       float tmp_v, workp_v, max_len, len, dx, dy, dz, nx, ny, nz, MAXN;
 
        ml = mainb[a];
 
@@ -1360,23 +1362,49 @@ void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
 
                                        out_v = mbproc->function(out.x, out.y, out.z);
 
-                                       /* find "first point" on Implicit Surface of MetaElemnt ml */
-                                       converge(&in, &out, in_v, out_v, mbproc->function, &mbproc->start, mb, 0);
-       
-                                       /* indexes of CUBE, which includes "first point" */
-                                       c_i= (int)floor(mbproc->start.x/mbproc->size );
-                                       c_j= (int)floor(mbproc->start.y/mbproc->size );
-                                       c_k= (int)floor(mbproc->start.z/mbproc->size );
-               
-                                       mbproc->start.x= mbproc->start.y= mbproc->start.z= 0.0;
+                                       /* find "first points" on Implicit Surface of MetaElemnt ml */
+                                       //converge(&in, &out, in_v, out_v, mbproc->function, &mbproc->start, mb, 0);
+                                       workp = in;
+                                       workp_v = in_v;
+                                       max_len = sqrt((out.x-in.x)*(out.x-in.x) + (out.y-in.y)*(out.y-in.y) + (out.z-in.z)*(out.z-in.z));
 
-                                       /* add CUBE (with indexes c_i, c_j, c_k) to the stack,
-                                        * this cube includes found point of Implicit Surface */
-                                       if (ml->flag & MB_NEGATIVE)
-                                               add_cube(mbproc, c_i, c_j, c_k, 2);
-                                       else
-                                               add_cube(mbproc, c_i, c_j, c_k, 1);
+                                       nx = abs((out.x - in.x)/mbproc->size);
+                                       ny = abs((out.y - in.y)/mbproc->size);
+                                       nz = abs((out.z - in.z)/mbproc->size);
+                                       
+                                       MAXN = MAX3(nx,ny,nz);
+
+                                       dx = (out.x - in.x)/MAXN;
+                                       dy = (out.y - in.y)/MAXN;
+                                       dz = (out.z - in.z)/MAXN;
+
+                                       len = 0.0;
+                                       while(len<=max_len) {
+                                               workp.x += dx;
+                                               workp.y += dy;
+                                               workp.z += dz;
+                                               /* compute value of implicite function */
+                                               tmp_v = mbproc->function(workp.x, workp.y, workp.z);
+                                               /* add cube to the stack, when value of implicite function crosses zero value */
+                                               if((tmp_v<0.0 && workp_v>=0.0)||(tmp_v>0.0 && workp_v<=0.0)) {
+
+                                                       /* indexes of CUBE, which includes "first point" */
+                                                       c_i= (int)floor(workp.x/mbproc->size);
+                                                       c_j= (int)floor(workp.y/mbproc->size);
+                                                       c_k= (int)floor(workp.z/mbproc->size);
+
+                                                       /* add CUBE (with indexes c_i, c_j, c_k) to the stack,
+                                                        * this cube includes found point of Implicit Surface */
+                                                       if (ml->flag & MB_NEGATIVE)
+                                                               add_cube(mbproc, c_i, c_j, c_k, 2);
+                                                       else
+                                                               add_cube(mbproc, c_i, c_j, c_k, 1);
+                                               }
+                                               len = sqrt((workp.x-in.x)*(workp.x-in.x) + (workp.y-in.y)*(workp.y-in.y) + (workp.z-in.z)*(workp.z-in.z));
+                                               workp_v = tmp_v;
+                                       }
                                                
+                                       mbproc->start.x= mbproc->start.y= mbproc->start.z= 0.0;
                                        
                                }
                        }
index 6c3775bcbaacd64cdbe281d2fde26f55174f1d94..28c3e1c64e6f5b91a39ced6e2cce28cc6c88e1bd 100644 (file)
@@ -68,9 +68,6 @@
 
 #include "SHD_node.h"
 
-/* not very important, but the stack solver likes to know a maximum */
-#define MAX_SOCKET     64
-
 static ListBase empty_list = {NULL, NULL};
 ListBase node_all_composit = {NULL, NULL};
 ListBase node_all_shaders = {NULL, NULL};
index 109f8bd91136f4a47d93fd61b6e361177dff912f..f6a65bd72a5d20f103ecb16fae641549b57da6d2 100644 (file)
@@ -185,7 +185,7 @@ PackedFile * newPackedFile(char * filename)
        // convert relative filenames to absolute filenames
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        // open the file
        // and create a PackedFile structure
@@ -286,7 +286,7 @@ int writePackedFile(char * filename, PackedFile *pf, int guimode)
        if (guimode) waitcursor(1);
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        if (BLI_exists(name)) {
                for (number = 1; number <= 999; number++) {
@@ -351,7 +351,7 @@ int checkPackedFile(char * filename, PackedFile * pf)
        char name[FILE_MAXDIR + FILE_MAXFILE];
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        if (stat(name, &st)) {
                ret_val = PF_NOFILE;
index 069dac60412e7f5de2bff031bb1c1453f7dc3051..9dd21cdda4ea6b9d2f28e3766ad6faebb8d84f29 100644 (file)
@@ -4565,7 +4565,8 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
                // ok, start loading
                strcpy(filename, ob->fluidsimSettings->surfdataPath);
                strcat(filename, suffix);
-               BLI_convertstringcode(filename, G.sce, curFrame); // fixed #frame-no 
+               BLI_convertstringcode(filename, G.sce);
+               BLI_convertstringframe(filename, curFrame); // fixed #frame-no 
                strcat(filename, suffix2);
 
                gzf = gzopen(filename, "rb");
index 3d73ba1e93f7ec59e8507926aaa62b9355df109f..7b727528b3da4dfe2741cf5e2314d0f40042083d 100644 (file)
@@ -186,7 +186,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
                
                sprintf(filename, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
                BLI_add_slash(filename);
-               BLI_convertstringcode(filename, blendfilename, 0);
+               BLI_convertstringcode(filename, blendfilename);
                return strlen(filename);
        }
        
index 3b14cb8adace105bc477310c3966b73298a6c054..2c5b49246fba523e0998c956b2ac8673f95e186f 100644 (file)
@@ -109,13 +109,13 @@ PackedFile* sound_find_packedfile(bSound *sound)
        
        // convert sound->name to abolute filename
        strcpy(soundname, sound->name);
-       BLI_convertstringcode(soundname, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(soundname, G.sce);
        
        search = G.main->sound.first;
        while (search) {
                if (search->sample && search->sample->packedfile) {
                        strcpy(searchname, search->sample->name);
-                       BLI_convertstringcode(searchname, G.sce, G.scene->r.cfra);
+                       BLI_convertstringcode(searchname, G.sce);
                        
                        if (BLI_streq(searchname, soundname)) {
                                pf = search->sample->packedfile;
@@ -125,7 +125,7 @@ PackedFile* sound_find_packedfile(bSound *sound)
                
                if (search->newpackedfile) {
                        strcpy(searchname, search->name);
-                       BLI_convertstringcode(searchname, G.sce, G.scene->r.cfra);
+                       BLI_convertstringcode(searchname, G.sce);
                        if (BLI_streq(searchname, soundname)) {
                                pf = search->newpackedfile;
                                break;
index b6552be93a9859ea4f901e5eba0e73b9a0cf4e5b..872f81ead632a3b7139ceac9602753baf53e1f47 100644 (file)
@@ -218,7 +218,7 @@ int reopen_text(Text *text)
        if (!text || !text->name) return 0;
        
        BLI_strncpy(str, text->name, FILE_MAXDIR+FILE_MAXFILE);
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(str, G.sce);
        BLI_split_dirfile_basic(str, NULL, sfile);
        
        fp= fopen(str, "r");
@@ -316,7 +316,7 @@ Text *add_text(char *file)
 
        BLI_strncpy(str, file, FILE_MAXDIR+FILE_MAXFILE);
        if (G.scene) /* can be NULL (bg mode) */
-               BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(str, G.sce);
        BLI_split_dirfile_basic(str, NULL, sfile);
        
        fp= fopen(str, "r");
@@ -2037,6 +2037,7 @@ void txt_delete_char (Text *text)
 
        if (txt_has_sel(text)) { /* deleting a selection */
          txt_delete_sel(text);
+         return;
        }
        else if (text->curc== text->curl->len) { /* Appending two lines */
                if (text->curl->next) {
@@ -2071,6 +2072,7 @@ void txt_backspace_char (Text *text)
        
        if (txt_has_sel(text)) { /* deleting a selection */
          txt_delete_sel(text);
+         return;
        }
        else if (text->curc==0) { /* Appending two lines */
            if (text->curl->prev) {
index 3d85fe32193c7560d4330bea1f6c01c73f676c4c..44004eeee803d924fe605de4e20d66c8772eb623 100644 (file)
@@ -120,7 +120,7 @@ void makeavistring (RenderData *rd, char *string)
        if (string==0) return;
 
        strcpy(string, rd->pic);
-       BLI_convertstringcode(string, G.sce, rd->cfra);
+       BLI_convertstringcode(string, G.sce);
 
        BLI_make_existing_file(string);
 
index 493620a8dce3bf96ab48a27a13d1d7b2b03bc0dc..e79e36a14987e7d4ec52b9360fb9078417be8bec 100644 (file)
@@ -695,7 +695,8 @@ void makeffmpegstring(char* string) {
        if (!string || !exts) return;
 
        strcpy(string, G.scene->r.pic);
-       BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(string, G.sce);
+       BLI_convertstringframe(string, G.scene->r.cfra);
 
        BLI_make_existing_file(string);
 
index 33567d92c992d6c127de981479e9478776bd57c0..e24ccad12fb28f6cc376fd06c7b8882493ccf4c5 100644 (file)
@@ -150,7 +150,8 @@ void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds
         * @a framenum The framenumber to replace the frame code with.
         * @retval Returns true if the path was relative (started with "//").
         */
-int BLI_convertstringcode(char *path, const char *basepath, int framenum);
+int BLI_convertstringcode(char *path, const char *basepath);
+int BLI_convertstringframe(char *path, int frame);
 
 void BLI_makestringcode(const char *relfile, char *file);
 
index 66eb63c8dfdecef971f64e870fe9a7fdb364f3a8..79d3e4877128397682c270ab00569a6d2b898a5a 100644 (file)
@@ -130,9 +130,9 @@ void BLI_bpathIterator_getPathExpanded( struct BPathIterator *bpi, char *path_ex
        libpath = BLI_bpathIterator_getLib(bpi);
        
        if (libpath) { /* check the files location relative to its library path */
-               BLI_convertstringcode(path_expanded, libpath, G.scene->r.cfra);
+               BLI_convertstringcode(path_expanded, libpath);
        } else { /* local data, use the blend files path */
-               BLI_convertstringcode(path_expanded, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(path_expanded, G.sce);
        }
 }
 char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
index cdac1ba706142e12f54ca2264327c86c5ace5aa9..c85849b5ed4be35af35c35c406011801e8ef005f 100644 (file)
@@ -877,7 +877,7 @@ void BLI_cleanup_file(const char *relabase, char *dir)
        short a;
        char *start, *eind;
        if (relabase) {
-               BLI_convertstringcode(dir, relabase, 0);
+               BLI_convertstringcode(dir, relabase);
        }
 #ifdef WIN32
        if(dir[0]=='.') {       /* happens for example in FILE_MAIN */
@@ -1037,10 +1037,78 @@ void BLI_makestringcode(const char *relfile, char *file)
        }
 }
 
-int BLI_convertstringcode(char *path, const char *basepath, int framenum)
+
+int BLI_convertstringframe(char *path, int frame)
+{
+       int ch_sta, ch_end, i;
+       /* Insert current frame: file### -> file001 */
+       ch_sta = ch_end = 0;
+       for (i = 0; path[i] != '\0'; i++) {
+               if (path[i] == '\\' || path[i] == '/') {
+                       ch_end = 0; /* this is a directory name, dont use any hashes we found */
+               } else if (path[i] == '#') {
+                       ch_sta = i;
+                       ch_end = ch_sta+1;
+                       while (path[ch_end] == '#') {
+                               ch_end++;
+                       }
+                       i = ch_end-1; /* keep searching */
+                       
+                       /* dont break, there may be a slash after this that invalidates the previous #'s */
+               }
+       }
+       if (ch_end) { /* warning, ch_end is the last # +1 */
+               /* Add the frame number? */
+               short numlen, hashlen;
+               char tmp[FILE_MAX];
+               
+               char format[16]; /* 6 is realistically the maxframe (300000), so 8 should be enough, but 16 to be safe. */
+               if (((ch_end-1)-ch_sta) >= 16) {
+                       ch_end = ch_sta+15; /* disallow values longer then 'format' can hold */
+               }
+               
+               strcpy(tmp, path);
+               
+               numlen = 1 + (int)log10((double)frame); /* this is the number of chars in the number */
+               hashlen = ch_end - ch_sta;
+               
+               sprintf(format, "%d", frame);
+               
+               if (numlen==hashlen) { /* simple case */
+                       memcpy(tmp+ch_sta, format, numlen);
+               } else if (numlen < hashlen) {
+                       memcpy(tmp+ch_sta + (hashlen-numlen), format, numlen); /*dont copy the string terminator */
+                       memset(tmp+ch_sta, '0', hashlen-numlen);
+               } else {
+                       /* number is longer then number of #'s */
+                       if (tmp[ch_end] == '\0') { /* hashes are last, no need to move any string*/
+                               /* bad juju - not testing string length here :/ */
+                               memcpy(tmp+ch_sta, format, numlen+1); /* add 1 to get the string terminator \0 */
+                       } else {
+                               /* we need to move the end characters, reuse i */
+                               int j;
+                               
+                               i = strlen(tmp); /* +1 to copy the string terminator */
+                               j = i + (numlen-hashlen); /* from/to */
+                               
+                               while (i >= ch_end) {
+                                       tmp[j] = tmp[i]; 
+                                       i--;
+                                       j--;
+                               }
+                               memcpy(tmp + ch_sta, format, numlen);
+                       }
+               }       
+               strcpy(path, tmp);
+               return 1;
+       }
+       return 0;
+}
+
+
+int BLI_convertstringcode(char *path, const char *basepath)
 {
        int wasrelative;
-       int ch_sta, ch_end;
        char tmp[FILE_MAX];
        char base[FILE_MAX];
        char vol[3] = {'\0', '\0', '\0'};
@@ -1098,54 +1166,8 @@ int BLI_convertstringcode(char *path, const char *basepath, int framenum)
                MEM_freeN(filepart);
        }
        
-       
-       /* Insert current frame: file### -> file001 */
-       ch_end = 0;
-       for (ch_sta = 0; tmp[ch_sta] != '\0'; ch_sta++) {
-               if (tmp[ch_sta] == '#') {
-                       ch_end = ch_sta+1;
-                       while (tmp[ch_end] == '#') {
-                               ch_end++;
-                       }                       
-                       break;
-               }
-       }
-       if (ch_end) { /* warning, ch_end is the last # +1 */
-               /* Add the frame number? */
-               short numlen, hashlen;
-               char format[16]; /* 6 is realistically the maxframe (300000), so 8 should be enough, but 16 to be safe. */
-               
-               numlen = 1 + (int)log10((double)framenum); /* this is the number of chars in the number */
-               hashlen = ch_end - ch_sta;
-               
-               sprintf(format, "%d", framenum);
-               
-               if (numlen==hashlen) { /* simple case */
-                       memcpy(tmp+ch_sta, format, numlen);
-               } else if (numlen < hashlen) {
-                       memcpy(tmp+ch_sta + (hashlen-numlen), format, numlen); /*dont copy the string terminator */
-                       memset(tmp+ch_sta, '0', hashlen-numlen);
-               } else {
-                       /* number is longer then number of #'s */
-                       if (tmp[ch_end] == '\0') { /* hashes are last, no need to move any string*/
-                               /* bad juju - not testing string length here :/ */
-                               memcpy(tmp+ch_sta, format, numlen+1); /* add 1 to get the string terminator \0 */
-                       } else {
-                               /* we need to move the end characters */
-                               int i = strlen(tmp); /* +1 to copy the string terminator */
-                               int j = i + (numlen-hashlen); /* from/to */
-                               while (i >= ch_end) {
-                                       tmp[j] = tmp[i]; 
-                                       i--;
-                                       j--;
-                               }
-                               memcpy(tmp + ch_sta, format, numlen);
-                       }
-               }       
-       }
-       /* done with file### stuff */
-       
        strcpy(path, tmp);
+       
 #ifdef WIN32
        /* skip first two chars, which in case of
           absolute path will be drive:/blabla and
index 7eb6220066e2014bd5247c546ede93717edbf572..87c859de839145294d0943de8e0d630a07f46538 100644 (file)
@@ -213,6 +213,12 @@ void dna_freestructDNA(struct SDNA *sdna)
        MEM_freeN(sdna);
 }
 
+static int ispointer(char *name)
+{
+       /* check if pointer or function pointer */
+       return (name[0]=='*' || (name[0]=='(' && name[1]=='*'));
+}
+
 static int elementsize(struct SDNA *sdna, short type, short name)
 /* call with numbers from struct-array */
 {
@@ -224,7 +230,7 @@ static int elementsize(struct SDNA *sdna, short type, short name)
        
        namelen= strlen(cp);
        /* is it a pointer or function pointer? */
-       if(cp[0]=='*' || cp[1]=='*') {
+       if(ispointer(cp)) {
                /* has the naam an extra length? (array) */
                mul= 1;
                if( cp[namelen-1]==']') mul= arraysize(cp, namelen);
@@ -508,7 +514,7 @@ static void recurs_test_compflags(struct SDNA *sdna, char *compflags, int struct
                        for(b=0; b<elems; b++, sp+=2) {
                                if(sp[0]==typenr) {
                                        cp= sdna->names[ sp[1] ];
-                                       if(cp[0]!= '*') {
+                                       if(!ispointer(cp)) {
                                                compflags[a]= 2;
                                                recurs_test_compflags(sdna, compflags, a);
                                        }
@@ -579,7 +585,7 @@ char *dna_get_structDNA_compareflags(struct SDNA *sdna, struct SDNA *newsdna)
                                                 if(strcmp(str1, str2)!=0) break;
                                                 
                                                 /* same type and same name, now pointersize */
-                                                if(str1[0]=='*') {
+                                                if(ispointer(str1)) {
                                                         if(sdna->pointerlen!=newsdna->pointerlen) break;
                                                 }
                                                 
@@ -834,7 +840,7 @@ static void reconstruct_elem(struct SDNA *newsdna, struct SDNA *oldsdna, char *t
                
                if( strcmp(name, oname)==0 ) {  /* name equal */
                        
-                       if( name[0]=='*') {             /* pointer afhandelen */
+                       if(ispointer(name)) {   /* pointer of functionpointer afhandelen */
                                cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, name, curdata, olddata);
                        }
                        else if( strcmp(type, otype)==0 ) {     /* type equal */
@@ -851,11 +857,11 @@ static void reconstruct_elem(struct SDNA *newsdna, struct SDNA *oldsdna, char *t
                                cursize= arraysize(name, strlen(name));
                                oldsize= arraysize(oname, strlen(oname));
 
-                               if( name[0]=='*') {             /* handle pointer */
+                               if(ispointer(name)) {           /* handle pointer or functionpointer */
                                        if(cursize>oldsize) cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, oname, curdata, olddata);
                                        else cast_pointer(newsdna->pointerlen, oldsdna->pointerlen, name, curdata, olddata);
                                }
-                               else if(name[0]=='*' || strcmp(type, otype)==0 ) {      /* type equal */
+                               else if(strcmp(type, otype)==0 ) {      /* type equal */
                                        mul= len/oldsize;
                                        mul*= MIN2(cursize, oldsize);
                                        memcpy(curdata, olddata, mul);
@@ -909,7 +915,7 @@ static void reconstruct_struct(struct SDNA *newsdna, struct SDNA *oldsdna, char
                elen= elementsize(newsdna, spc[0], spc[1]);
 
                /* test: is type a struct? */
-               if(spc[0]>=firststructtypenr  &&  name[0]!='*') {
+               if(spc[0]>=firststructtypenr  &&  !ispointer(name)) {
                
                        /* where does the old struct data start (and is there an old one?) */
                        cpo= find_elem(oldsdna, type, name, spo, data, &sppo);
@@ -976,7 +982,7 @@ void dna_switch_endian_struct(struct SDNA *oldsdna, int oldSDNAnr, char *data)
                elen= elementsize(oldsdna, spc[0], spc[1]);
 
                /* test: is type a struct? */
-               if(spc[0]>=firststructtypenr  &&  name[0]!='*') {
+               if(spc[0]>=firststructtypenr  &&  !ispointer(name)) {
                        /* where does the old data start (is there one?) */
                        cpo= find_elem(oldsdna, type, name, spo, data, 0);
                        if(cpo) {
@@ -993,7 +999,7 @@ void dna_switch_endian_struct(struct SDNA *oldsdna, int oldSDNAnr, char *data)
                }
                else {
                        
-                       if( name[0]=='*' ) {
+                       if(ispointer(name)) {
                                if(oldsdna->pointerlen==8) {
                                        
                                        mul= arraysize(name, strlen(name));
index aa3fe6a9279ab901f434540a27c225ed8580bdde..6f9c0ae194fc4a1ca7c5a37854d9236ea829dacc 100644 (file)
@@ -82,7 +82,6 @@ void winqdelete(struct ScrArea *sa);
 void winqclear(struct ScrArea *sa);
 void addqueue(short win, unsigned short event, short val);
 void addafterqueue(short win, unsigned short event, short val);
-void add_readfile_event(char *filename);
 short ext_qtest(void);
 unsigned short extern_qread(short *val);
 unsigned short extern_qread_ext(short *val, char *ascii);
index 8556d47e4abc6eb56b3c3ff0690a91cb999e7d24..242965a820c49ceee5ec74efcfed44e74b115122 100644 (file)
@@ -367,7 +367,7 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
 #define B_SEQ_BUT_TRANSFORM     1695
 #define B_SEQ_BUT_RELOAD_FILE   1696
 #define B_SEQ_BUT_REBUILD_PROXY 1697
-
+#define B_SEQ_SEL_PROXY_DIR     1698
 /* *********************** */
 #define B_ARMATUREBUTS         1800
 #define        B_POSE                  1701
index 37bbb68ba030fa7b0b00ea6fc4e87ec0b321a45a..78f780c43b11c624d0bcb4f79a3b8992982f7e49 100644 (file)
@@ -160,11 +160,11 @@ static void node_dynamic_free_storage_cb(bNode *node)
 }
 
 /* Disable pynode when its script fails */
-/*static void node_dynamic_disable(bNode *node)
+static void node_dynamic_disable(bNode *node)
 {
        node->custom1 = 0;
        node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
-}*/
+}
 
 /* Disable all pynodes using the given text (script) id */
 static void node_dynamic_disable_all_by_id(ID *id)
@@ -401,7 +401,11 @@ static int node_dynamic_parse(struct bNode *node)
        MEM_freeN(buf);
 
        if (!pyresult) {
+               if (BTST(node->custom1, NODE_DYNAMIC_LOADED)) {
+                       node_dynamic_disable(node);
+               } else {
                node_dynamic_disable_all_by_id(node->id);
+               }
                node_dynamic_pyerror_print(node);
                PyGILState_Release(gilstate);
                return -1;
index 86bcd51e91434f0d2fcbbf66d8e1cbb70a899b83..ffdb593767a84016df681129532c1e5c993e272f 100644 (file)
@@ -444,7 +444,7 @@ void BPY_rebuild_syspath( void )
                }
 
                BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
-               BLI_convertstringcode(dirpath, G.sce, 0);
+               BLI_convertstringcode(dirpath, G.sce);
                syspath_append(dirpath);        /* append to module search path */
 
                BLI_make_file_string("/", modpath, dirpath, "bpymodules");
@@ -1019,7 +1019,7 @@ int BPY_menu_do_python( short menutype, int event )
 
                /* dirs in Blender can be "//", which has a special meaning */
                BLI_strncpy(upythondir, U.pythondir, FILE_MAX);
-               BLI_convertstringcode(upythondir, G.sce, 0); /* if so, this expands it */
+               BLI_convertstringcode(upythondir, G.sce); /* if so, this expands it */
                BLI_make_file_string( "/", filestr, upythondir, pym->filename );
        }
        else { /* script is in default scripts dir */
index ce1b964b689496a2d85f040d2ca3d79b3c3a8091..82da9edbee6f5f293a6787e6882d5b57b0d04f36 100644 (file)
@@ -492,7 +492,7 @@ static int bpymenu_CreateFromFile( void )
        fscanf( fp, "# User defined scripts dir: %[^\n]\n", w1 );
 
                BLI_strncpy(upythondir, U.pythondir, FILE_MAX);
-               BLI_convertstringcode(upythondir, G.sce, 0);
+               BLI_convertstringcode(upythondir, G.sce);
 
                if( strcmp( w1, upythondir ) != 0 )
                        return -1;
@@ -604,7 +604,7 @@ static void bpymenu_WriteDataFile( void )
                char upythondir[FILE_MAX];
 
                BLI_strncpy(upythondir, U.pythondir, FILE_MAX);
-               BLI_convertstringcode(upythondir, G.sce, 0);
+               BLI_convertstringcode(upythondir, G.sce);
                fprintf( fp, "# User defined scripts dir: %s\n", upythondir );
        }
 
@@ -1003,7 +1003,7 @@ int BPyMenu_Init( int usedir )
        }
        else {
                BLI_strncpy(upythondir, upydir, FILE_MAX);
-               BLI_convertstringcode(upythondir, G.sce, 0);
+               BLI_convertstringcode(upythondir, G.sce);
        }
 
        sdir = bpy_gethome(1);
@@ -1096,7 +1096,7 @@ the user defined Python scripts dir.\n", dirname );
                }
                if( stat_dir2 == 0 ) {
                        BLI_strncpy(dirname, U.pythondir, FILE_MAX);
-                       BLI_convertstringcode(dirname, G.sce, 0);
+                       BLI_convertstringcode(dirname, G.sce);
                        i = bpymenu_ParseDir( dirname, NULL, 1 );
                        if (i == -1 && DEBUG)
                                fprintf(stderr, "User defined scripts dir does not seem valid.\n\n");
index fe5ae25ccb130d18057865845a0d102b0dca30b6..daba0c36fdf4fe3ceaceb6241d091864854e7a25 100644 (file)
@@ -371,7 +371,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char upydir[FILE_MAX];
 
                        BLI_strncpy(upydir, U.pythondir, FILE_MAX);
-                       BLI_convertstringcode(upydir, G.sce, 0);
+                       BLI_convertstringcode(upydir, G.sce);
 
                        if (BLI_exists(upydir)) {
                                char udatadir[FILE_MAXDIR];
@@ -397,7 +397,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char upydir[FILE_MAX];
 
                        BLI_strncpy(upydir, U.pythondir, FILE_MAX);
-                       BLI_convertstringcode(upydir, G.sce, 0);
+                       BLI_convertstringcode(upydir, G.sce);
 
                        if( BLI_exists( upydir ) )
                                ret = PyString_FromString( upydir );
@@ -410,7 +410,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char yfexportdir[FILE_MAX];
 
                        BLI_strncpy(yfexportdir, U.yfexportdir, FILE_MAX);
-                       BLI_convertstringcode(yfexportdir, G.sce, 0);
+                       BLI_convertstringcode(yfexportdir, G.sce);
 
                        if( BLI_exists( yfexportdir ) )
                                ret = PyString_FromString( yfexportdir );
@@ -423,7 +423,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char fontdir[FILE_MAX];
 
                        BLI_strncpy(fontdir, U.fontdir, FILE_MAX);
-                       BLI_convertstringcode(fontdir, G.sce, 0);
+                       BLI_convertstringcode(fontdir, G.sce);
 
                        if( BLI_exists( fontdir ) )
                                ret = PyString_FromString( fontdir );
@@ -436,7 +436,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char textudir[FILE_MAX];
 
                        BLI_strncpy(textudir, U.textudir, FILE_MAX);
-                       BLI_convertstringcode(textudir, G.sce, 0);
+                       BLI_convertstringcode(textudir, G.sce);
 
                        if( BLI_exists( textudir ) )
                                ret = PyString_FromString( textudir );
@@ -449,7 +449,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char plugtexdir[FILE_MAX];
 
                        BLI_strncpy(plugtexdir, U.plugtexdir, FILE_MAX);
-                       BLI_convertstringcode(plugtexdir, G.sce, 0);
+                       BLI_convertstringcode(plugtexdir, G.sce);
 
                        if( BLI_exists( plugtexdir ) )
                                ret = PyString_FromString( plugtexdir );
@@ -462,7 +462,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char plugseqdir[FILE_MAX];
 
                        BLI_strncpy(plugseqdir, U.plugseqdir, FILE_MAX);
-                       BLI_convertstringcode(plugseqdir, G.sce, 0);
+                       BLI_convertstringcode(plugseqdir, G.sce);
 
                        if( BLI_exists( plugseqdir ) )
                                ret = PyString_FromString( plugseqdir );
@@ -475,7 +475,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char renderdir[FILE_MAX];
 
                        BLI_strncpy(renderdir, U.renderdir, FILE_MAX);
-                       BLI_convertstringcode(renderdir, G.sce, 0);
+                       BLI_convertstringcode(renderdir, G.sce);
 
                        if( BLI_exists( renderdir ) )
                                ret = PyString_FromString( renderdir );
@@ -488,7 +488,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char sounddir[FILE_MAX];
 
                        BLI_strncpy(sounddir, U.sounddir, FILE_MAX);
-                       BLI_convertstringcode(sounddir, G.sce, 0);
+                       BLI_convertstringcode(sounddir, G.sce);
 
                        if( BLI_exists( sounddir ) )
                                ret = PyString_FromString( sounddir );
@@ -501,7 +501,7 @@ static PyObject *Blender_Get( PyObject * self, PyObject * value )
                        char tempdir[FILE_MAX];
 
                        BLI_strncpy(tempdir, U.tempdir, FILE_MAX);
-                       BLI_convertstringcode(tempdir, G.sce, 0);
+                       BLI_convertstringcode(tempdir, G.sce);
 
                        if( BLI_exists( tempdir ) )
                                ret = PyString_FromString( tempdir );
@@ -776,7 +776,7 @@ static PyObject *Blender_ShowHelp(PyObject *self, PyObject *script)
                        char upydir[FILE_MAX];
 
                        BLI_strncpy(upydir, U.pythondir, FILE_MAX);
-                       BLI_convertstringcode(upydir, G.sce, 0);
+                       BLI_convertstringcode(upydir, G.sce);
                        BLI_make_file_string("/", hspath, upydir, "help_browser.py");
 
                        if (!BLI_exists(hspath))
index 667db8a1dfd9e2813940018b433c590a3682816a..799735c2062fc31aebe2b57bd4d4f8f0140df1d0 100644 (file)
@@ -166,7 +166,7 @@ static PyObject *M_Library_Open( PyObject * self, PyObject * value )
        
        /* copy the name to make it absolute so BLO_blendhandle_from_file doesn't complain */
        BLI_strncpy(fname1, fname, sizeof(fname1)); 
-       BLI_convertstringcode(fname1, G.sce, 0); /* make absolute */
+       BLI_convertstringcode(fname1, G.sce); /* make absolute */
        
        /* G.sce = last file loaded, save for UI and restore after opening file */
        BLI_strncpy(filename, G.sce, sizeof(filename));
@@ -483,7 +483,7 @@ static BlendHandle *open_library( char *filename, char *longFilename )
 
        /* get complete file name if necessary */
        BLI_strncpy( longFilename, filename, FILE_MAX ); 
-       BLI_convertstringcode( longFilename, G.sce, 0 );
+       BLI_convertstringcode( longFilename, G.sce );
 
        /* throw exceptions for wrong file type, cyclic reference */
        if( !BLO_has_bfile_extension(longFilename) ) {
@@ -515,11 +515,12 @@ static BlendHandle *open_library( char *filename, char *longFilename )
  */
 
 static PyObject *CreatePyObject_LibData( int idtype, int kind,
-               void *name, void *iter, char *filename )
+               void *name, void *iter, char *filename, int rel )
 {
        BPy_LibraryData *seq = PyObject_NEW( BPy_LibraryData, &LibraryData_Type);
        seq->iter = iter;               /* the name list (for iterators) */
        seq->type = idtype;             /* the Blender ID type */
+       seq->rel =  rel;                /* relative or absolute library */
        seq->kind = kind;               /* used by Blender Objects */
        seq->name = name;               /* object name, iterator name list, or NULL */
                                                        /* save the library name */
@@ -560,7 +561,8 @@ static PyObject *lib_link_or_append( BPy_LibraryData *self, PyObject * value,
                /* otherwise, create a pseudo object ready for appending or linking */
 
                return CreatePyObject_LibData( ID_OB, mode, 
-                               BLI_strdupn( name, strlen( name ) ), NULL, self->filename );
+                               BLI_strdupn( name, strlen( name ) ), NULL, self->filename,
+                               self->rel );
        }
 }
 
@@ -586,6 +588,9 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
        if( !openlib )
                return NULL;
 
+       /* fix any /foo/../foo/ */
+       BLI_cleanup_file(NULL, longFilename); 
+
        /* find all datablocks for the specified type */
        names = BLO_blendhandle_get_datablock_names ( openlib, self->type ); 
 
@@ -616,15 +621,15 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
        }
 
        /* import from the libary */
-       BLO_script_library_append( &openlib, longFilename, name, self->type, mode,
-                       scene );
+       BLO_script_library_append( &openlib, longFilename, name, self->type, 
+                       mode | self->rel, scene );
 
        /*
         * locate the library.  If this is an append, make the data local.  If it
         * is link, we need the library for later
         */
        for( lib = G.main->library.first; lib; lib = lib->id.next )
-               if( strcmp( longFilename, lib->name ) == 0 ) {
+               if( strcmp( longFilename, lib->filename ) == 0) {
                        if( mode != FILE_LINK ) {
                                all_local( lib, 1 );
                                /* important we unset, otherwise these object wont
@@ -717,7 +722,7 @@ static PyObject *LibraryData_getIter( BPy_LibraryData * self )
 
        /* build an iterator object for the name list */
        return CreatePyObject_LibData( self->type, OTHER, names,
-                       names, self->filename );
+                       names, self->filename, self->rel );
 }
 
 /* Return next name. */
@@ -942,7 +947,7 @@ PyTypeObject LibraryData_Type = {
 static PyObject *LibraryData_CreatePyObject( BPy_Library *self, void *mode )
 {
        return CreatePyObject_LibData( GET_INT_FROM_POINTER(mode), OTHER, NULL, NULL,
-                       self->filename );
+                       self->filename, self->rel);
 }
 
 /************************************************************
@@ -972,6 +977,39 @@ static int Library_setFilename( BPy_Library * self, PyObject * args )
        return 0;
 }
 
+/*
+ * Return the library's name.  The format depends on whether the library is 
+ * accessed as relative or absolute.
+ */
+
+static PyObject *Library_getName( BPy_Library * self )
+{
+       Library *lib;
+       BlendHandle *openlib;
+       char longFilename[FILE_MAX];
+
+       /* try to open the library */
+       openlib = open_library( self->filename, longFilename );
+       if( openlib ) {
+               BLO_blendhandle_close( openlib );
+               /* remove any /../ or /./ junk */
+               BLI_cleanup_file(NULL, longFilename); 
+
+               /* search the loaded libraries for a match */
+               for( lib = G.main->library.first; lib; lib = lib->id.next )
+                       if( strcmp( longFilename, lib->filename ) == 0) {
+                               return PyString_FromString( lib->name );
+                       }
+
+               /* library not found in memory */
+               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                               "library not loaded" );
+       }
+       /* could not load library */
+       return EXPP_ReturnPyObjError( PyExc_IOError, "library not found" );
+}
+
+
 /************************************************************************
  * Python Library_type attributes get/set structure
  ************************************************************************/
@@ -981,6 +1019,10 @@ static PyGetSetDef Library_getseters[] = {
         (getter)Library_getFilename, (setter)Library_setFilename,
         "library filename",
         NULL},
+       {"name",
+        (getter)Library_getName, (setter)NULL,
+        "library name (as used by Blender)",
+        NULL},
        {"objects",
         (getter)LibraryData_CreatePyObject, (setter)NULL,
         "objects from the library",
@@ -1066,20 +1108,27 @@ static PyGetSetDef Library_getseters[] = {
  * actually accessed later. 
  */
 
-static PyObject *M_Library_Load(PyObject *self, PyObject * value)
+static PyObject *M_Library_Load(PyObject *self, PyObject * args)
 {
-       char *filename = PyString_AsString(value);
+       char *filename = NULL;
+       PyObject *relative = NULL;
        BPy_Library *lib;
 
-       if( !filename )
+       if( !PyArg_ParseTuple( args, "s|O", &filename, &relative ) )
                return EXPP_ReturnPyObjError( PyExc_TypeError,
-                       "expected a string" );
+                       "expected strings and optional bool as arguments." );
 
        /* try to create a new object */
        lib = (BPy_Library *)PyObject_NEW( BPy_Library, &Library_Type );
        if( !lib )
                return NULL;
 
+       /* save relative flag value */
+       if( relative && PyObject_IsTrue(relative) )
+               lib->rel = FILE_STRINGCODE;
+       else
+               lib->rel = 0;
+
        /* assign the library filename for future use, then return */
        BLI_strncpy( lib->filename, filename, sizeof(lib->filename) );
 
@@ -1087,7 +1136,7 @@ static PyObject *M_Library_Load(PyObject *self, PyObject * value)
 }
 
 static struct PyMethodDef M_Library_methods[] = {
-       {"load", (PyCFunction)M_Library_Load, METH_O,
+       {"load", (PyCFunction)M_Library_Load, METH_VARARGS,
        "(string) - declare a .blend file for use as a library"},
        {NULL, NULL, 0, NULL}
 };
index 326040edb3545b08aa41834d4efad198ebaf8c56..b75e61d55ff87d4307137f873c4bbdf47c3ab6dc 100644 (file)
@@ -42,6 +42,7 @@
 typedef struct {
        PyObject_HEAD 
        char filename[FILE_MAXDIR + FILE_MAXFILE];
+       int rel;
 } BPy_Library;
 
 typedef struct {
@@ -50,6 +51,7 @@ typedef struct {
        int type;
        char filename[FILE_MAXDIR + FILE_MAXFILE];
        char *name;
+       int rel;
        enum {
                OBJECT_IS_LINK,
                OBJECT_IS_APPEND,
index 80b45bb22970ff744172e64572815f55f464826c..24df6de66ccf62f6f34f9256ae4375795a007e5b 100644 (file)
@@ -361,6 +361,15 @@ static int pysockets_to_blendersockets(PyObject *tuple, bNodeSocketType **socks,
 
        len = PyTuple_Size(tuple);
 
+       if (len >= MAX_SOCKET) {
+               char error_msg[70];
+               PyOS_snprintf(error_msg, sizeof(error_msg),
+                       "limit exceeded: each node can't have more than %d i/o sockets", MAX_SOCKET - 1);
+               PyErr_SetString(PyExc_AttributeError, error_msg);
+               len = 0;
+               retval = -1;
+       }
+
        nsocks = MEM_callocN(sizeof(bNodeSocketType)*(len+1), "bNodeSocketType in Node.c");
 
        for (pos = 0, a = 0; pos< len; pos++, a++) {
@@ -437,6 +446,7 @@ static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closur
 {
        bNode *node = NULL;
        PyObject *tuple = NULL;
+       int ret = 0;
 
        node = self->node;
 
@@ -453,7 +463,7 @@ static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closur
                        if (args) {
                                if(PySequence_Check(args)) {
                                        tuple = PySequence_Tuple(args);
-                                       pysockets_to_blendersockets(tuple,
+                                       ret = pysockets_to_blendersockets(tuple,
                                                        &(node->typeinfo->inputs), node->custom1, 1);
                                        Py_DECREF(self->input);
                                        self->input = tuple;
@@ -466,7 +476,7 @@ static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closur
                        if (args) {
                                if(PyList_Check(args)) {
                                        tuple = PySequence_Tuple(args);
-                                       pysockets_to_blendersockets(tuple,
+                                       ret = pysockets_to_blendersockets(tuple,
                                                        &(node->typeinfo->outputs), node->custom1, 0);
                                        Py_DECREF(self->output);
                                        self->output = tuple;
@@ -479,6 +489,11 @@ static int Map_socketdef(BPy_NodeSocketLists *self, PyObject *args, void *closur
                        fprintf(stderr,"DEBUG pynodes: got no list in Map_socketdef\n");
                        break;
        }
+
+       if (ret == -1) {
+               node->custom1 = BSET(node->custom1, NODE_DYNAMIC_ERROR);
+       }
+
        return 0;
 }
 
index 337f8b6bb14650c015228d5435cce4520a21a13d..9de4e344e8cc8daa0e964ed37bb35d881d99d2af 100644 (file)
@@ -391,7 +391,8 @@ static PyObject *M_sys_expandpath( PyObject * self, PyObject * value )
                        "expected string argument" );
        
        BLI_strncpy(expanded, path, FILE_MAXDIR + FILE_MAXFILE);
-       BLI_convertstringcode(expanded, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(expanded, G.sce);
+       BLI_convertstringframe(expanded, G.scene->r.cfra);
 
        return PyString_FromString(expanded);
 }
index 7b6f4950c76b6af60f53a708b1fcc74c68d582db..47bd7fdb763efafd334438c4eea7bfe24f2efff2 100644 (file)
@@ -26,13 +26,15 @@ Example::
        me.materials[0] = mat                             # assign linked material to mesh
 """
 
-def load(filename):
+def load(filename,relative=False):
   """
   Select an existing .blend file for use as a library.  Unlike the 
   Library module, multiple libraries can be defined at the same time.  
   
   @type filename: string
   @param filename: The filename of a Blender file. Filenames starting with "//" will be loaded relative to the blend file's location.
+  @type relative: boolean
+  @param relative: Convert relative paths to absolute paths (default).  Setting this parameter to True will leave paths relative.
   @rtype: Library
   @return: return a L{Library} object.
   """
@@ -46,8 +48,10 @@ class Libraries:
        It provides access to scenes, objects, meshes, curves, metaballs,
        materials, textures, images, lattices, lamps, cameras, ipos, worlds,
        fonts, texts, sounds, groups, armatures, and actions.
-       @ivar filename: The path to the library
+       @ivar filename: The filename of the library, as supplied by user.
        @type filename: string
+       @ivar name: The path to the library, as used by Blender.  If the filename supplied by the user is relative, but the relative option to L{library.load()<load>} is False, the name will be the absolute path.
+       @type name: string
        @ivar scenes: library L{scene<Scene.Scene>} data
        @type scenes: L{LibData}
        @ivar objects: library L{object<Object.Object>} data
index 7cae5f6144fea55d0d3d99795ba2582ce8e31303..db5ad669255bf43b6fcd90a8407625bb4fb329f9 100644 (file)
@@ -598,8 +598,7 @@ PyObject *RenderData_Play( BPy_RenderData * self )
        if( self->renderContext->imtype == R_QUICKTIME ) {
 
                strcpy( file, self->renderContext->pic );
-               BLI_convertstringcode( file, (char *) self->scene,
-                                      self->renderContext->cfra );
+               BLI_convertstringcode( file, G.sce );
                BLI_make_existing_file( file );
                if( BLI_strcasecmp( file + strlen( file ) - 4, ".mov" ) ) {
                        sprintf( txt, "%04d_%04d.mov",
@@ -612,8 +611,8 @@ PyObject *RenderData_Play( BPy_RenderData * self )
        {
 
                strcpy( file, self->renderContext->pic );
-               BLI_convertstringcode( file, G.sce,
-                                      self->renderContext->cfra );
+               BLI_convertstringcode( file, G.sce );
+               
                BLI_make_existing_file( file );
                if( BLI_strcasecmp( file + strlen( file ) - 4, ".avi" ) ) {
                        sprintf( txt, "%04d_%04d.avi",
index a49a9a2fdc81a81e927853705ca76fbfc3a6cca7..736bb4dd5843db20f723e68b0299414d5e2ad174 100644 (file)
@@ -428,7 +428,7 @@ void makeqtstring (char *string) {
        if (string==0) return;
 
        strcpy(string, G.scene->r.pic);
-       BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(string, G.sce);
 
        BLI_make_existing_file(string);
 
index 09c850b6252fc3cce7e74e92f27c5bcae5fce5c1..93282e641d352c776ec20145d02bd0cda0d65689 100644 (file)
@@ -1835,7 +1835,8 @@ static void load_backbuffer(Render *re)
                char name[256];
                
                strcpy(name, re->r.backbuf);
-               BLI_convertstringcode(name, G.sce, re->r.cfra);
+               BLI_convertstringcode(name, G.sce);
+               BLI_convertstringframe(name, re->r.cfra);
                
                if(re->backbuf) {
                        re->backbuf->id.us--;
index d007ffad020ab84127adf3cfd1c84738135ce0e3..47a2c6d613de4972c3333f0534b8fe92a54f24cd 100644 (file)
@@ -4606,16 +4606,21 @@ void do_vgroupbuts(unsigned short event)
        switch(event) {
                case B_NEWVGROUP:
                        add_defgroup (ob);
+                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                        scrarea_queue_winredraw(curarea);
                        allqueue(REDRAWOOPS, 0);
+                       
                        break;
                case B_DELVGROUP:
-                       if ((G.obedit) && (G.obedit == ob))
+                       if ((G.obedit) && (G.obedit == ob)) {
                                del_defgroup (ob);
-                       else
+                       } else {
                                del_defgroup_in_object_mode (ob);
+                               DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+                       }
                        allqueue (REDRAWVIEW3D, 1);
                        allqueue(REDRAWOOPS, 0);
+                       allqueue(REDRAWBUTSEDIT, 1);
                        BIF_undo_push("Delete vertex group");
                        break;
                case B_ASSIGNVGROUP:
@@ -4637,6 +4642,7 @@ void do_vgroupbuts(unsigned short event)
                        break;
                case B_DESELVGROUP:
                        sel_verts_defgroup(0);
+                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                        allqueue (REDRAWVIEW3D, 1);
                        allqueue(REDRAWOOPS, 0);
                        countall();
index d58a283b6d185144e3a167ec3d3fc30ed82503ea..37becdc89122f4f005d9345fd3278d573773fa39 100644 (file)
@@ -3130,9 +3130,13 @@ void do_effects_panels(unsigned short event)
                                }
                        }
                        else {
-                               psys->flag |= PSYS_EDITED;
-                               if(G.f & G_PARTICLEEDIT)
-                                       PE_create_particle_edit(ob, psys);
+                               if(psys_check_enabled(ob, psys)) {
+                                       psys->flag |= PSYS_EDITED;
+                                       if(G.f & G_PARTICLEEDIT)
+                                               PE_create_particle_edit(ob, psys);
+                               }
+                               else
+                                       error("Particle system not enabled, skipping set editable");
                        }
                }
        case B_FIELD_DEP:
index 5fd23af591e6b09c6d5c52db16d093aa2542eade..b295cdd84810b3a6ed41da7c452ed14441072197 100644 (file)
@@ -1175,9 +1175,14 @@ static void seq_panel_proxy()
        }
 
        if (last_seq->flag & SEQ_USE_PROXY_CUSTOM_DIR) {
+               uiDefIconBut(block, BUT, B_SEQ_SEL_PROXY_DIR, 
+                            ICON_FILESEL, 10, 120, 20, 20, 0, 0, 0, 0, 0, 
+                            "Select the directory/name for "
+                            "the proxy storage");
+
                uiDefBut(block, TEX, 
                         B_SEQ_BUT_RELOAD, "Dir: ", 
-                        10,120,240,19, last_seq->strip->proxy->dir, 
+                        30,120,220,20, last_seq->strip->proxy->dir, 
                         0.0, 160.0, 100, 0, "");
        }
 
@@ -1264,10 +1269,20 @@ void sequencer_panels()
        }
 }
 
+static void sel_proxy_dir(char *name)
+{
+       Sequence *last_seq = get_last_seq();
+       strcpy(last_seq->strip->proxy->dir, name);
+
+       allqueue(REDRAWBUTSSCENE, 0);
+
+       BIF_undo_push("Change proxy directory");
+}
 
 void do_sequencer_panels(unsigned short event)
 {
        Sequence *last_seq = get_last_seq();
+       ScrArea * sa;
 
        switch(event) {
        case B_SEQ_BUT_PLUGIN:
@@ -1280,6 +1295,13 @@ void do_sequencer_panels(unsigned short event)
        case B_SEQ_BUT_REBUILD_PROXY:
                seq_proxy_rebuild(last_seq);
                break;
+       case B_SEQ_SEL_PROXY_DIR:
+               sa= closest_bigger_area();
+               areawinset(sa->win);
+               activate_fileselect(FILE_SPECIAL, "SELECT PROXY DIR", 
+                                   last_seq->strip->proxy->dir, 
+                                   sel_proxy_dir);
+               break;
        case B_SEQ_BUT_RELOAD:
        case B_SEQ_BUT_RELOAD_ALL:
                update_seq_ipo_rect(last_seq);
index 5e420ade20432aa993f3a8e253ed3868fb54075c..b46679898b4e167d5b8f5711e127faead570a754 100644 (file)
@@ -238,7 +238,7 @@ static void save_env(char *name)
        char str[FILE_MAX];
        
        strcpy(str, name);
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(str, G.sce);
        tex= G.buts->lockpoin;
        
        if(tex && GS(tex->id.name)==ID_TE) {
@@ -2338,9 +2338,9 @@ static void world_panel_preview(World *wrld)
        uiBlockBeginAlign(block);
        uiDefButBitS(block, TOG, WO_SKYBLEND, B_WORLDPRV,"Blend", 220,175,100,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with natural progression from horizon to zenith");
        uiDefButBitS(block, TOG,WO_SKYPAPER, B_WORLDPRV,"Paper", 220,150,100,25, &wrld->skytype, 0, 0, 0, 0, "Flattens blend or texture coordinates");
-       if (wrld->skytype & WO_SKYBLEND) {
+       /*if (wrld->skytype & WO_SKYBLEND) {*/ /* In some (rare?) cases its possible to use this, leave this out for now */
                uiDefButBitS(block, TOG, WO_SKYREAL, B_WORLDPRV,"Real", 220,125,100,25, &wrld->skytype, 0, 0, 0, 0, "Renders background with a real horizon");
-       }
+       /*}*/
        uiBlockEndAlign(block);
 
 }
index ac2b92d08159ce5d8c0734c9a14c47be4ab7921b..6d1cd244b842f8e8feef8016cb12612dde17d9ec 100644 (file)
@@ -533,7 +533,7 @@ void draw_uvs_sima(void)
                
        
        if (G.sima->flag & SI_DRAW_STRETCH) {
-               float col[3];
+               float col[4];
                float aspx, aspy;
                float tface_uv[4][2];
                
index 808320bb9dea0df6a95b8972a7d4df1ae4ae62f4..aec0e112b32e9dc3360a7cad4524e73b9a644ae7 100644 (file)
@@ -3474,6 +3474,8 @@ static void draw_particle_edit(Object *ob, ParticleSystem *psys)
                PE_hide_keys_time(psys,CFRA);
                psys_cache_paths(ob,psys,CFRA,0);
        }
+       if(psys->pathcache==0)
+               return;
 
        if(pset->flag & PE_SHOW_CHILD && psys->part->draw_as == PART_DRAW_PATH) {
                if(psys->childcache==0)
index d97701e8c1e2729b425184abbb3fab1a2424dda3..b01b7bc151ceb6fba901749e0396ceea40336984 100644 (file)
@@ -3394,8 +3394,12 @@ static double swaptime;
 static int curmode;
 
 /* used for fps display */
+#define REDRAW_FRAME_AVERAGE 8
 static double redrawtime;
 static double lredrawtime;
+static float redrawtimes_fps[REDRAW_FRAME_AVERAGE];
+static short redrawtime_index;
+
 
 int update_time(void)
 {
@@ -3418,13 +3422,33 @@ static void draw_viewport_fps(ScrArea *sa)
 {
        float fps;
        char printable[16];
-
+       int i, tot;
        
        if (lredrawtime == redrawtime)
                return;
        
        printable[0] = '\0';
-       fps = (float)(1.0/(lredrawtime-redrawtime));
+       
+#if 0
+       /* this is too simple, better do an average */
+       fps = (float)(1.0/(lredrawtime-redrawtime))
+#else
+       redrawtimes_fps[redrawtime_index] = (float)(1.0/(lredrawtime-redrawtime));
+       
+       for (i=0, tot=0, fps=0.0f ; i < REDRAW_FRAME_AVERAGE ; i++) {
+               if (redrawtimes_fps[i]) {
+                       fps += redrawtimes_fps[i];
+                       tot++;
+               }
+       }
+       if (tot) {
+               redrawtime_index++;
+               if (redrawtime_index >= REDRAW_FRAME_AVERAGE)
+                       redrawtime_index = 0;
+               
+               fps = fps / tot;
+       }
+#endif
        
        /* is this more then half a frame behind? */
        if (fps+0.5 < FPS) {
@@ -3549,6 +3573,12 @@ void inner_play_anim_loop(int init, int mode)
                cached = cached_dynamics(PSFRA,PEFRA);
                
                redrawtime = 1.0/FPS;
+               
+               redrawtime_index = REDRAW_FRAME_AVERAGE;
+               while(redrawtime_index--) {
+                       redrawtimes_fps[redrawtime_index] = 0.0;
+               }
+               redrawtime_index = 0;
                lredrawtime = 0.0;
                return;
        }
index d9bc55fa8bff35ff352c501b3527873eca87f65b..34dcab09c2aaaa52d931b30a03a5cdab0fc8d597 100644 (file)
@@ -4316,8 +4316,10 @@ Nurb *addNurbprim(int type, int stype, int newname)
                        makeknots(nu, 1, nu->flagu>>1);
 
                        BLI_addtail(&editNurb, nu); /* temporal for spin */
-                       if(newname) spin_nurb(0, 2);
-                       else spin_nurb(0, 0);
+                       if(newname && (U.flag & USER_ADD_VIEWALIGNED) == 0)
+                               spin_nurb(0, 2);
+                       else
+                               spin_nurb(0, 0);
 
                        makeknots(nu, 2, nu->flagv>>1);
 
@@ -4344,8 +4346,10 @@ Nurb *addNurbprim(int type, int stype, int newname)
                        nu->resolv= 32;
                        nu->flag= CU_SMOOTH;
                        BLI_addtail(&editNurb, nu); /* temporal for extrude and translate */
-                       if(newname) spin_nurb(0, 2);
-                       else spin_nurb(0, 0);
+                       if(newname && (U.flag & USER_ADD_VIEWALIGNED) == 0)
+                               spin_nurb(0, 2);
+                       else
+                               spin_nurb(0, 0);
 
                        BLI_remlink(&editNurb, nu);
 
index 6d6a53fc59eab6c082a7d737813001f1ebea1a69..a072898327f5550a94b3dd552561846433c8db2a 100644 (file)
@@ -217,19 +217,25 @@ void duplicate_defgroup ( Object *ob )
        dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
        if (!dg)
                return;
-
-       BLI_snprintf (name, 32, "%s_copy", dg->name);
-       while (get_named_vertexgroup (ob, name)) {
-               if ((strlen (name) + 6) > 32) {
-                       error ("Error: the name for the new group is > 32 characters");
-                       return;
+       
+       if (strstr(dg->name, "_copy")) {
+               BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
+       } else {
+               BLI_snprintf (name, 32, "%s_copy", dg->name);
+               while (get_named_vertexgroup (ob, name)) {
+                       if ((strlen (name) + 6) > 32) {
+                               error ("Error: the name for the new group is > 32 characters");
+                               return;
+                       }
+                       strcpy (s, name);
+                       BLI_snprintf (name, 32, "%s_copy", s);
                }
-               strcpy (s, name);
-               BLI_snprintf (name, 32, "%s_copy", s);
-       }
+       }               
 
        cdg = copy_defgroup (dg);
        strcpy (cdg->name, name);
+       unique_vertexgroup_name(cdg, ob);
+       
        BLI_addtail (&ob->defbase, cdg);
 
        idg = (ob->actdef-1);
index 2ee583788e5a15dd79154f4c50c2c5aaa3eb2cde..67e10d771e0210d6aaf1834706795cd3376ce66d 100644 (file)
@@ -166,8 +166,7 @@ static void activate_imageselect_(int type, char *title, char *file, short *menu
 
        name[2]= 0;
        BLI_strncpy(name, file, sizeof(name));
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
-       
+       BLI_convertstringcode(name, G.sce);
        
        simasel= curarea->spacedata.first;
 
index d72bdc6fc802ac5b3be7f51ad8b242b892848293..a8b2ff761e50a52d90e5cd5ff6a160ce3bd54cc9 100644 (file)
@@ -3793,6 +3793,12 @@ void clean_ipo_curve(IpoCurve *icu)
                MEM_freeN(old_bezts);
 }
 
+
+/* temp struct used for smooth_ipo */
+typedef struct tSmooth_Bezt {
+       float *h1, *h2, *h3;    /* bezt->vec[0,1,2][1] */
+} tSmooth_Bezt;
+
 void smooth_ipo(void)
 {
        EditIpo *ei;
@@ -3804,7 +3810,6 @@ void smooth_ipo(void)
        ei= G.sipo->editipo;
        for(b=0; b<G.sipo->totipo; b++, ei++) {
                if (ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt)) {
-               
                        ok= 0;
                        if(G.sipo->showkey) ok= 1;
                        else if(totipo_vert && (ei->flag & IPO_EDIT)) ok= 2;
@@ -3813,52 +3818,94 @@ void smooth_ipo(void)
                        if(ok) {
                                IpoCurve *icu= ei->icu;
                                BezTriple *bezt;
-                               float meanValSum = 0.0f, meanVal;
-                               float valDiff;
-                               int i, totSel = 0;
+                               int i, x, totSel = 0;
                                
                                /* check if enough points */
                                if (icu->totvert >= 3) {
-                                       /* first loop through - obtain average value */
+                                       /* first loop through - count how many verts are selected, and fix up handles */
                                        bezt= icu->bezt;
-                                       for (i=1; i < icu->totvert; i++, bezt++) {                                              
+                                       for (i=0; i < icu->totvert; i++, bezt++) {                                              
                                                if (BEZSELECTED(bezt)) {                                                        
                                                        /* line point's handles up with point's vertical position */
                                                        bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
-                                                       if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN;
-                                                       if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN;
+                                                       if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN;
+                                                       if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN;
                                                        
                                                        /* add value to total */
-                                                       meanValSum += bezt->vec[1][1];
                                                        totSel++;
                                                }
                                        }
                                        
-                                       /* calculate mean value */
-                                       meanVal= meanValSum / totSel;
-                                       
-                                       /* second loop through - update point positions */
-                                       bezt= icu->bezt;
-                                       for (i=0; i < icu->totvert; i++, bezt++) {                                              
-                                               if (BEZSELECTED(bezt)) {
-                                                       /* 1. calculate difference between the points 
-                                                        * 2. move point half-way along that distance 
-                                                        */
-                                                       if (bezt->vec[1][1] > meanVal) {
-                                                               /* bezt val above mean */
-                                                               valDiff= bezt->vec[1][1] - meanVal;
-                                                               bezt->vec[1][1]= meanVal + (valDiff / 2);
+                                       /* if any points were selected, allocate tSmooth_Bezt points to work on */
+                                       if (totSel >= 3) {
+                                               tSmooth_Bezt *tarray, *tsb;
+                                               
+                                               /* allocate memory in one go */
+                                               tsb= tarray= MEM_callocN(totSel*sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
+                                               
+                                               /* populate tarray with data of selected points */
+                                               bezt= icu->bezt;
+                                               for (i=0, x=0; (i < icu->totvert) && (x < totSel); i++, bezt++) {
+                                                       if (BEZSELECTED(bezt)) {
+                                                               /* tsb simply needs pointer to vec, and index */
+                                                               tsb->h1 = &bezt->vec[0][1];
+                                                               tsb->h2 = &bezt->vec[1][1];
+                                                               tsb->h3 = &bezt->vec[2][1];
+                                                               
+                                                               /* advance to the next tsb to populate */
+                                                               if (x < totSel- 1) 
+                                                                       tsb++;
+                                                               else
+                                                                       break;
                                                        }
-                                                       else {
-                                                               /* bezt val below mean */
-                                                               valDiff= meanVal - bezt->vec[1][1];
-                                                               bezt->vec[1][1] = bezt->vec[1][1] + (valDiff / 2);                                                              
+                                               }
+                                               
+                                               /* calculate the new smoothed ipo's with weighted averages:
+                                                *      - this is done with two passes
+                                                *      - uses 5 points for each operation (which stores in the relevant handles)
+                                                *      -       previous: w/a ratio = 3:5:2:1:1
+                                                *      -       next: w/a ratio = 1:1:2:5:3
+                                                */
+                                               
+                                               /* round 1: calculate previous and next */ 
+                                               tsb= tarray;
+                                               for (i=0; i < totSel; i++, tsb++) {
+                                                       /* don't touch end points (otherwise, curves slowly explode) */
+                                                       if (ELEM(i, 0, (totSel-1)) == 0) {
+                                                               tSmooth_Bezt *tP1 = tsb - 1;
+                                                               tSmooth_Bezt *tP2 = (i-2 > 0) ? (tsb - 2) : (NULL);
+                                                               tSmooth_Bezt *tN1 = tsb + 1;
+                                                               tSmooth_Bezt *tN2 = (i+2 < totSel) ? (tsb + 2) : (NULL);
+                                                               
+                                                               float p1 = *tP1->h2;
+                                                               float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
+                                                               float c1 = *tsb->h2;
+                                                               float n1 = *tN1->h2;
+                                                               float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
+                                                               
+                                                               /* calculate previous and next */
+                                                               *tsb->h1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12;
+                                                               *tsb->h3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12;
                                                        }
                                                }
+                                               
+                                               /* round 2: calculate new values and reset handles */
+                                               tsb= tarray;
+                                               for (i=0; i < totSel; i++, tsb++) {
+                                                       /* calculate new position by averaging handles */
+                                                       *tsb->h2 = (*tsb->h1 + *tsb->h3) / 2;
+                                                       
+                                                       /* reset handles now */
+                                                       *tsb->h1 = *tsb->h2;
+                                                       *tsb->h3 = *tsb->h2;
+                                               }
+                                               
+                                               /* free memory required for tarray */
+                                               MEM_freeN(tarray);
                                        }
                                }
-                       
-                               /* recalc handles */
+                               
+                               /* recalculate handles */
                                calchandles_ipocurve(icu);
                        }
                }
index 512a29edbc24207643da7d49b76ff2a6c59782b4..cdc38ab1d2c689e036179df2ad2383b425de4193 100644 (file)
@@ -555,6 +555,20 @@ static int return_editcurve_indexar(int *tot, int **indexar, float *cent)
        return totvert;
 }
 
+/* use this when the loc/size/rot of the parent has changed but the children should stay in the same place
+ * apply-size-rot or object center for eg */
+static void ignore_parent_tx( Object *ob ) {
+       Object *ob_child;
+       /* a change was made, adjust the children to compensate */
+       for (ob_child=G.main->object.first; ob_child; ob_child=ob_child->id.next) {
+               if (ob_child->parent == ob) {
+                       apply_obmat(ob_child);
+                       what_does_parent(ob_child);
+                       Mat4Invert(ob_child->parentinv, workob.obmat);
+               }
+       }
+}
+
 static void select_editcurve_hook(HookModifierData *hmd)
 {
        extern ListBase editNurb;
@@ -1936,6 +1950,9 @@ void docenter(int centermode)
                                                        base->object->loc[1]+= centn[1];
                                                        base->object->loc[2]+= centn[2];
                                                        
+                                                       where_is_object(base->object);
+                                                       ignore_parent_tx(base->object);
+                                                       
                                                        /* other users? */
                                                        ob= G.main->object.first;
                                                        while(ob) {
@@ -1954,6 +1971,9 @@ void docenter(int centermode)
                                                                                ob->loc[1]+= centn[1];
                                                                                ob->loc[2]+= centn[2];
                                                                                
+                                                                               where_is_object(ob);
+                                                                               ignore_parent_tx(ob);
+                                                                               
                                                                                if(tme && (tme->flag & ME_ISDONE)==0) {
                                                                                        mvert= tme->mvert;
                                                                                        for(a=0; a<tme->totvert; a++, mvert++) {
@@ -2033,6 +2053,9 @@ void docenter(int centermode)
                                                        base->object->loc[0]+= cent[0];
                                                        base->object->loc[1]+= cent[1];
                                                        base->object->loc[2]+= cent[2];
+                                                       
+                                                       where_is_object(base->object);
+                                                       ignore_parent_tx(base->object);
                                                }
                                                
                                                tot_change++;
@@ -2080,6 +2103,10 @@ void docenter(int centermode)
                                                 */
                                                docenter_armature(base->object, centermode);
                                                tot_change++;
+                                               
+                                               where_is_object(base->object);
+                                               ignore_parent_tx(base->object);
+                                               
                                                if(G.obedit) 
                                                        break;
                                        }
@@ -3869,7 +3896,7 @@ void make_links(short event)
 void apply_objects_locrot( void )
 {
        Base *base, *basact;
-       Object *ob, *ob_child;
+       Object *ob;
        bArmature *arm;
        Mesh *me;
        Curve *cu;
@@ -4018,14 +4045,7 @@ void apply_objects_locrot( void )
                                continue;
                        }
                        
-                       /* a change was made, adjust the children to compensate */
-                       for (ob_child=G.main->object.first; ob_child; ob_child=ob_child->id.next) {
-                               if (ob_child->parent == ob) {
-                                       apply_obmat(ob_child);
-                                       what_does_parent(ob_child);
-                                       Mat4Invert(ob_child->parentinv, workob.obmat);
-                               }
-                       }
+                       ignore_parent_tx(ob);
                }
        }
        if (change) {
index 2df92af5bcab0591b9b219df4ca4dcf27e12bc41..1cd8733a7ea05248797aee7f833e0618382e4e0d 100644 (file)
@@ -890,12 +890,6 @@ int afterqtest(short win, unsigned short evt)
 
 
 static char ext_load_str[256]= {0, 0};
-void add_readfile_event(char *filename)
-{      
-       mainqenter(LOAD_FILE, 1);
-       strcpy(ext_load_str, filename);
-       BLI_convertstringcode(ext_load_str, G.sce, G.scene->r.cfra);
-}
 
 static short ext_reshape= 0, ext_redraw=0, ext_inputchange=0, ext_mousemove=0, ext_undopush=0;
 
@@ -1396,7 +1390,7 @@ void screenmain(void)
                else if (event==QKEY) {
                        /* Temp place to print mem debugging info ctrl+alt+shift + qkey */
                        if ( G.qual == (LR_SHIFTKEY | LR_ALTKEY | LR_CTRLKEY) ) {
-                               MEM_printmemlist_pydict();
+                               MEM_printmemlist_stats();
                        }
                        
                        else if((G.obedit && G.obedit->type==OB_FONT && g_activearea->spacetype==SPACE_VIEW3D)||g_activearea->spacetype==SPACE_TEXT||g_activearea->spacetype==SPACE_SCRIPT);
index c0efbf8b40b2b7ae1003055d2ac5fcee71d290ca..f5cf29528f37f6994636cbf5d4f5f52ffdbd9989 100644 (file)
@@ -2288,7 +2288,9 @@ static void save_image_doit(char *name)
        if (ibuf) {
                BLI_strncpy(str, name, sizeof(str));
 
-               BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(str, G.sce);
+               BLI_convertstringframe(str, G.scene->r.cfra);
+               
                
                if(G.scene->r.scemode & R_EXTENSION)  {
                        BKE_add_image_extension(str, G.sima->imtypenr);
@@ -2499,7 +2501,7 @@ void save_image_sequence_sima(void)
                                char name[FILE_MAX];
                                BLI_strncpy(name, ibuf->name, sizeof(name));
                                
-                               BLI_convertstringcode(name, G.sce, 0);
+                               BLI_convertstringcode(name, G.sce);
 
                                if(0 == IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat)) {
                                        error("Could not write image", name);
index 3ea9a0fb0562a63fcde035cdd0c5dfb5602f47ef..1cb7ec276cb4529dc1bb1ef747f666d58bca7e3a 100644 (file)
@@ -713,7 +713,7 @@ bSound *sound_new_sound(char *name)
        if (!G.scene->audio.mixrate) G.scene->audio.mixrate = 44100;
        /* convert the name to absolute path */
        strcpy(str, name);
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(str, G.sce);
 
        /* check if the sample on disk can be opened */
        file = open(str, O_BINARY|O_RDONLY);
@@ -825,7 +825,7 @@ bSample *sound_new_sample(bSound *sound)
                /* TODO: increase sound->name, sample->name and strip->name to FILE_MAX, to avoid
                   cutting off sample name here - elubie */
                BLI_strncpy(samplename, sound->name, FILE_MAX);         
-               BLI_convertstringcode(samplename, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(samplename, G.sce);
                BLI_strncpy(sample->name, samplename, FILE_MAXDIR);
 
                /* connect the pf to the sample */
@@ -849,13 +849,13 @@ bSample *sound_find_sample(bSound *sound)
        
        // convert sound->name to abolute filename
        strcpy(name, sound->name);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        /* search through the list of loaded samples */
        sample = samples->first;
        while (sample) {
                strcpy(samplename, sample->name);
-               BLI_convertstringcode(samplename, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(samplename, G.sce);
                
                if (strcmp(name, samplename) == 0)      {
                        break;
index c297edda9054d3a361541293eaab3db54f17cc3e..19372dcbee621fa25217b3d00ab939811b041d2d 100644 (file)
@@ -1172,7 +1172,7 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
 
        name[2]= 0;
        BLI_strncpy(name, file, sizeof(name));
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        sfile= curarea->spacedata.first;
 
index b51f5bba4d6d053bc9dc7e6f2ab215234cead23d..a7361a9ffca35b76c07b5902de74063a30413f21 100644 (file)
@@ -622,7 +622,7 @@ void fluidsimBake(struct Object *ob)
        // prepare names...
        strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
        strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR);
-       BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no 
+       BLI_convertstringcode(targetDir, G.sce); // fixed #frame-no 
 
        strcpy(targetFile, targetDir);
        strcat(targetFile, suffixConfig);
@@ -674,7 +674,7 @@ void fluidsimBake(struct Object *ob)
                if(selection<1) return; // 0 from menu, or -1 aborted
                strcpy(targetDir, newSurfdataPath);
                strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
-               BLI_convertstringcode(targetDir, G.sce, 0); // fixed #frame-no 
+               BLI_convertstringcode(targetDir, G.sce); // fixed #frame-no 
        }
        
        // --------------------------------------------------------------------------------------------
index 90a9ae9e406d9cfb6668a50dbc4841ee449bda80..7179f2fae5767ab8c9a5ae2aa357f1ee86bcb233 100644 (file)
@@ -927,6 +927,42 @@ void window_open_ndof(Window* win)
        }
        
        ndofLib = PIL_dynlib_open(plug_path);
+       
+       /* On systems where blender is installed in /usr/bin/blender, ~/.blender/plugins/ is a better place to look */
+       if (ndofLib==NULL) {
+               
+               if (plug_path) {
+                       MEM_freeN(plug_path);
+               }
+               
+               inst_path = BLI_gethome();
+               if (inst_path) {
+                       size_t len = strlen(inst_path) + strlen(plug_dir) + strlen(PATH_SEP)*2
+                                        + strlen(plug_name) + 1;
+                       
+                       if (!strstr(inst_path, ".blender")) {
+                               len += strlen(".blender") + strlen(PATH_SEP);
+                       }
+                       
+                       plug_path = MEM_mallocN(len, "ndofpluginpath");
+                       if (plug_path) {
+                               strncpy(plug_path, inst_path, len);
+                               strcat(plug_path, PATH_SEP);
+                               if (!strstr(inst_path, ".blender")) {
+                                       strcat(plug_path, ".blender");
+                                       strcat(plug_path, PATH_SEP);
+                               }
+                               strcat(plug_path, plug_dir);
+                               strcat(plug_path, PATH_SEP);
+                               strcat(plug_path, plug_name);
+                       }
+               }
+               
+               ndofLib = PIL_dynlib_open(plug_path);
+       }
+       
+       
+       
 #if 0
        fprintf(stderr, "plugin path=%s; ndofLib=%p\n", plug_path, (void*)ndofLib);
 #endif
index 2ed5107da295515d2e0fe327bca76e0a831e2bc7..9c7046c51115a5c35563975b4a60072856f2900f 100644 (file)
@@ -95,7 +95,10 @@ enum {
        ACTMENU_VIEW_NOHIDE,
        ACTMENU_VIEW_TRANSDELDUPS,
        ACTMENU_VIEW_HORIZOPTIMISE,
-       ACTMENU_VIEW_GCOLORS
+       ACTMENU_VIEW_GCOLORS,
+       ACTMENU_VIEW_PREVRANGESET,
+       ACTMENU_VIEW_PREVRANGECLEAR,
+       ACTMENU_VIEW_PREVRANGEAUTO
 };
 
 enum {
@@ -350,6 +353,15 @@ static void do_action_viewmenu(void *arg, int event)
                case ACTMENU_VIEW_GCOLORS: /* Draw grouped-action channels using its group's color */
                        G.saction->flag ^= SACTION_NODRAWGCOLORS;
                        break;
+               case ACTMENU_VIEW_PREVRANGESET: /* Set preview range */
+                       anim_previewrange_set();
+                       break;
+               case ACTMENU_VIEW_PREVRANGECLEAR: /* Clear preview range */
+                       anim_previewrange_clear();
+                       break;
+               case ACTMENU_VIEW_PREVRANGEAUTO: /* Auto preview-range length */
+                       action_previewrange_set(G.saction->action);
+                       break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -447,11 +459,30 @@ static uiBlock *action_viewmenu(void *arg_unused)
                                         "Play Back Animation|Alt A", 0, yco-=20, 
                                         menuwidth, 19, NULL, 0.0, 0.0, 1, 
                                         ACTMENU_VIEW_PLAY3D, "");
+       //uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+       //                               "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
+       //                               menuwidth, 19, NULL, 0.0, 0.0, 1, 
+       //                               ACTMENU_VIEW_PLAYALL, "");
+       
+       uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
+                        menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+               
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
-                                        "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
+                                        "Set Preview Range|Ctrl P", 0, yco-=20, 
                                         menuwidth, 19, NULL, 0.0, 0.0, 1, 
-                                        ACTMENU_VIEW_PLAYALL, "");
-
+                                        ACTMENU_VIEW_PREVRANGESET, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+                                        "Clear Preview Range|Alt P", 0, yco-=20,
+                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 
+                                        ACTMENU_VIEW_PREVRANGECLEAR, "");
+               
+       if (G.saction->action) {
+               uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+                                        "Preview Range from Action Length|Ctrl Alt P", 0, yco-=20, 
+                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 
+                                        ACTMENU_VIEW_PREVRANGEAUTO, "");
+       }
+               
        uiDefBut(block, SEPR, 0, "", 0, yco-=6, 
                         menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
index 54a3790574bf187d02af4ca28536fc0508b589fb..81d94725a904cdeb89b05a053df72cf8d069f604 100644 (file)
@@ -745,6 +745,12 @@ static void do_ipo_viewmenu(void *arg, int event)
        case 12:        
                G.sipo->flag ^= SIPO_LOCK_VIEW;
                break;
+       case 13: /* Set Preview Range */
+               anim_previewrange_set();
+               break;
+       case 14: /* Clear Preview Range */
+               anim_previewrange_clear();
+               break;
        }
 }
 
@@ -775,10 +781,17 @@ static uiBlock *ipo_viewmenu(void *arg_unused)
        
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation|Alt A", 0, yco-=20, 
                                         menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation in 3D View|Alt Shift A", 0, yco-=20,
-                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+       //uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Animation in 3D View|Alt Shift A", 0, yco-=20,
+       //                               menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
 
        uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Preview Range|Ctrl P", 0, yco-=20, 
+                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Preview Range|Alt P", 0, yco-=20,
+                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
+       
+       uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
 
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center on Current Frame|Shift C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
index 41e7bc3236589201354fb6a9e7574d129f91399f..ef4b79c0537fa6757aee33caf8de00fd76393943 100644 (file)
@@ -122,6 +122,12 @@ static void do_nla_viewmenu(void *arg, int event)
        case 7: /* Show timing in Frames or Seconds */
                G.snla->flag ^= SNLA_DRAWTIME;
                break;
+       case 8: /* Set Preview Range */
+               anim_previewrange_set();
+               break;
+       case 9: /* Clear Preview Range */
+               anim_previewrange_clear();
+               break;
        }
 }
 
@@ -154,7 +160,12 @@ static uiBlock *nla_viewmenu(void *arg_unused)
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation|Alt A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       //uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       
+       uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Preview Range|Ctrl P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Preview Range|Alt P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
        
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
index fdb5fea658ce32bc66d6f5b60b5bdaf0bd98e5b3..83a3c12bae79688014ebc09a47685d1cfad2db73 100644 (file)
@@ -1839,7 +1839,7 @@ static void ui_draw_but_CHARTAB(uiBut *but)
                        int err;
 
                        strcpy(tmpStr, G.selfont->name);
-                       BLI_convertstringcode(tmpStr, G.sce, 0);
+                       BLI_convertstringcode(tmpStr, G.sce);
                        err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
                }
        }
index a887a6f1751f92c1402d2ee9fb6599b3a279b174..683b06aafc41d3ab90bf951279bea4445678cb31 100644 (file)
@@ -3539,7 +3539,7 @@ static void namebutton_cb(void *tep, void *oldnamep)
                        if (te->idcode == ID_LI) {
                                char expanded[FILE_MAXDIR + FILE_MAXFILE];
                                BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE);
-                               BLI_convertstringcode(expanded, G.sce, G.scene->r.cfra);
+                               BLI_convertstringcode(expanded, G.sce);
                                if (!BLI_exists(expanded)) {
                                        error("This path does not exist, correct this before saving");
                                }
index b5240a942418e8a39a156fe8ea7f18d2fd5cc2e4..e793c224fcb6c61486f03168defadd7a0e795676 100644 (file)
@@ -69,7 +69,8 @@ void write_screendump(char *name)
        if(dumprect) {
 
                strcpy(G.ima, name);
-               BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(name, G.sce);
+               BLI_convertstringframe(name, G.scene->r.cfra); /* TODO - is this ever used? */
                
                /* BKE_add_image_extension() checks for if extension was already set */
                if(G.scene->r.scemode & R_EXTENSION) 
index 3e7840192742192b9bc95d5a5e75792f46a87fe8..7c27f32c242b1b94be8acef8abcc90dde3ae7ba0 100644 (file)
@@ -106,7 +106,7 @@ void makewavstring (char *string)
        if (string==0) return;
 
        strcpy(string, G.scene->r.pic);
-       BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(string, G.sce);
 
        BLI_make_existing_file(string);
 
@@ -394,8 +394,7 @@ static void audio_fill_seq(Sequence * seq, void * mixdown,
                                        strncat(name, 
                                                seq->strip->stripdata->name, 
                                                FILE_MAXFILE-1);
-                                       BLI_convertstringcode(name, G.sce, 
-                                                             G.scene->r.cfra);
+                                       BLI_convertstringcode(name, G.sce);
                                
                                        seq->hdaudio= sound_open_hdaudio(name);
                                }
index 22bedab6beebc9fe3b8d5083aa66c1b8c6294383..b4d3a6c3ce24ddb0a052799ac2368c8e2705cb6a 100644 (file)
@@ -429,7 +429,9 @@ void reload_sequence_new_file(Sequence * seq)
                strncpy(str, seq->strip->dir, FILE_MAXDIR-1);
                strncat(str, seq->strip->stripdata->name, FILE_MAXFILE-1);
 
-               BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+               BLI_convertstringcode(str, G.sce);
+               BLI_convertstringframe(str, G.scene->r.cfra); /* TODO - is this needed? */
+               
        }
 
        if (seq->type == SEQ_IMAGE) {
@@ -1068,7 +1070,9 @@ static int seq_proxy_get_fname(Sequence * seq, int cfra, char * name)
                         G.scene->r.size);
        }
 
-       BLI_convertstringcode(name, G.sce, frameno);
+       BLI_convertstringcode(name, G.sce);
+       BLI_convertstringframe(name, frameno);
+       
 
        strcat(name, ".jpg");
 
@@ -1269,8 +1273,8 @@ static void make_cb_table_byte(float lift, float gain, float gamma,
 
        for (y = 0; y < 256; y++) {
                float v = 1.0 * y / 255;
-               v += lift; 
                v *= gain;
+               v += lift; 
                v = pow(v, gamma);
                v *= mul;
                if ( v > 1.0) {
@@ -1290,8 +1294,8 @@ static void make_cb_table_float(float lift, float gain, float gamma,
 
        for (y = 0; y < 256; y++) {
                float v = (float) y * 1.0 / 255.0;
-               v += lift;
                v *= gain;
+               v += lift;
                v = pow(v, gamma);
                v *= mul;
                table[y] = v;
@@ -1367,7 +1371,7 @@ static void color_balance_float_float(Sequence * seq, TStripElem* se,
        while (p < e) {
                int c;
                for (c = 0; c < 3; c++) {
-                       p[c] = pow((p[c] + cb.lift[c]) * cb.gain[c], 
+                       p[c] = pow(p[c] * cb.gain[c] + cb.lift[c], 
                                   cb.gamma[c]) * mul;
                }
                p += 4;
@@ -1705,8 +1709,9 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                        StripElem * s_elem = give_stripelem(seq, cfra);
                        
                        strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
-                       strncat(name, s_elem->name, FILE_MAXFILE);
-                       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+                       strncat(name, s_elem->name, FILE_MAXFILE-1);
+                       BLI_convertstringcode(name, G.sce);
+                       BLI_convertstringframe(name, G.scene->r.cfra);
                        if (!build_proxy_run) {
                                se->ibuf = seq_proxy_fetch(seq, cfra);
                        }
@@ -1735,7 +1740,8 @@ static void do_build_seq_ibuf(Sequence * seq, TStripElem *se, int cfra,
                                if(seq->anim==0) {
                                        strncpy(name, seq->strip->dir, FILE_MAXDIR-1);
                                        strncat(name, seq->strip->stripdata->name, FILE_MAXFILE-1);
-                                       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+                                       BLI_convertstringcode(name, G.sce);
+                                       BLI_convertstringframe(name, G.scene->r.cfra);
                                
                                        seq->anim = openanim(name, IB_rect);
                                }
index 72fb442fda0c444974f416d5457a5607e38fdc9c..41e539c3d1ad85cb16cc060d03eb06763e0acef2 100644 (file)
@@ -1005,6 +1005,8 @@ void BIF_undo_push(char *str)
                        undo_push_armature(str);
        }
        else if(G.f & G_PARTICLEEDIT) {
+               if (U.undosteps == 0) return;
+
                PE_undo_push(str);
        }
        else {
index 8498917b54e0c4b27827c170c845ab22fd39a3b5..163a116371d4da8bffc7218bc81740bce3e2b2dd 100644 (file)
@@ -974,8 +974,10 @@ void viewmove(int mode)
                                /* these limits are in toets.c too */
                                if(G.vd->dist<0.001*G.vd->grid) G.vd->dist= 0.001*G.vd->grid;
                                if(G.vd->dist>10.0*G.vd->far) G.vd->dist=10.0*G.vd->far;
+                               
+                               if(G.vd->persp==V3D_ORTHO || G.vd->persp==V3D_CAMOB) preview3d_event= 0;
                        }
-                       if(G.vd->persp==V3D_ORTHO || G.vd->persp==V3D_CAMOB) preview3d_event= 0;
+                       
                        
                        
                        mvalo[0]= mval[0];
index d7e40dabd4367bb5abaf94941e9cbc2e21c22f5d..1ef32fc33e87f67774e9466243a586c94318714a 100644 (file)
@@ -99,7 +99,8 @@ static void save_rendered_image_cb_real(char *name, int confirm)
                        BKE_add_image_extension(name, G.scene->r.imtype);
 
        strcpy(str, name);
-       BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(str, G.sce);
+       BLI_convertstringframe(str, G.scene->r.cfra); /* TODO - is this even used? */
 
        if (confirm)
                overwrite = saveover(str);
index 83c3b64eabd99ffc45fcc2d7ad84bf2641beee3f..dea7fbd9ddb88ec57d32ecc2837adf3dc170533d 100644 (file)
@@ -97,7 +97,7 @@ static void make_movie_name(char *string)
        if (string==0) return;
 
        strcpy(string, G.scene->r.pic);
-       BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(string, G.sce);
        len= strlen(string);
 
        BLI_make_existing_file(string);
index ac7d2703eb84a15751c36064fcfc3e96c88bcf25..f8bbdad5f652306a690d0b694336f5636c7aea91 100644 (file)
@@ -126,7 +126,7 @@ static void adjustPath(string &path)
        // if relative, expand to full path
        char cpath[MAXPATHLEN];
        strcpy(cpath, path.c_str());
-       BLI_convertstringcode(cpath, G.sce, 0);
+       BLI_convertstringcode(cpath, G.sce);
        path = cpath;
 #ifdef WIN32
        // add drive char if not there
index 361939df9c48ef11cbb8e31485c4eda222936d1c..6ae4a31bf505a12587a5f0c2b60301b3d9718bbe 100644 (file)
@@ -278,7 +278,7 @@ static void adjustPath(string &path)
        // if relative, expand to full path
        char cpath[MAXPATHLEN];
        strcpy(cpath, path.c_str());
-       BLI_convertstringcode(cpath, G.sce, 0);
+       BLI_convertstringcode(cpath, G.sce);
        path = cpath;
 #ifdef WIN32
        // add drive char if not there
index 200c04bbfd313953beb865d9874eacdcea57619a..fa8409b123e56973a4e0b4ddc805556f303cbc22 100644 (file)
@@ -264,7 +264,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                        if (exitstring != "")
                                strcpy(basedpath, exitstring.Ptr());
 
-                       BLI_convertstringcode(basedpath, pathname, 0);
+                       BLI_convertstringcode(basedpath, pathname);
                        bfd = load_game_data(basedpath);
                        
                        // if it wasn't loaded, try it forced relative
@@ -275,7 +275,7 @@ extern "C" void StartKetsjiShell(struct ScrArea *area,
                                strcpy(temppath, "//");
                                strcat(temppath, basedpath);
                                
-                               BLI_convertstringcode(temppath, pathname, 0);
+                               BLI_convertstringcode(temppath, pathname);
                                bfd = load_game_data(temppath);
                        }
                        
index 6b0df44cb1696fa07f3d72c322c51bc4cc9bc7ef..a656c5e5523c0f00dfd46902c6fd7b604cc0488d 100644 (file)
@@ -91,6 +91,10 @@ int  KX_BlenderRenderTools::ProcessLighting(int layer)
        {
                if (m_clientobject)
                {
+                       if (layer == RAS_LIGHT_OBJECT_LAYER)
+                       {
+                               layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
+                       }
                        if (applyLights(layer))
                        {
                                EnableOpenGLLights();
index 3e83ed20840984e22a6f04ac3bf6b8c6c4ac16e5..08e9e36c0483f5411a16da8d046ed11ffb103de7 100644 (file)
@@ -1680,8 +1680,11 @@ static KX_GameObject *gameobject_from_blenderobject(
                break;
        }
        }
-       if (gameobj)
+       if (gameobj) 
+       {
                gameobj->SetPhysicsEnvironment(kxscene->GetPhysicsEnvironment());
+               gameobj->SetLayer(ob->lay);
+       }
        return gameobj;
 }
 
index a575415ab0588f6dbdda669e83b3aad2707f8201..6b594e2e70ba1ec416fc7fdbb537b6a6727a2b3c 100644 (file)
@@ -351,7 +351,7 @@ void BL_ConvertActuators(char* maggiename,
                                                        else
                                                        {
                                                                /* but we need to convert the samplename into absolute pathname first */
-                                                               BLI_convertstringcode(soundact->sound->name, maggiename, 0);
+                                                               BLI_convertstringcode(soundact->sound->name, maggiename);
                                                                samplename = soundact->sound->name;
                                                                
                                                                /* and now we can load it */
index f8fc256b3718abf60f5a9cad371ebde57ebd8e79..f13b1bcf4c991a0b801324ea7f54d6c87a100999 100644 (file)
@@ -163,6 +163,25 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
                        {
                                m_val=(active)?1:0;
                                result = true;
+                       } else
+                       {
+                               if (active)
+                               {
+                                       if (m_val == 0)
+                                       {
+                                               //see comment below
+                                               //m_val = 1;
+                                               //result = true;
+                                               ;
+                                       }
+                               } else
+                               {
+                                       if (m_val == 1)
+                                       {
+                                               m_val = 0;
+                                               result = true;
+                                       }
+                               }
                        }
                }
 
@@ -178,6 +197,13 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
 
                if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
                {
+                       if (m_val == 1)
+                       {
+                               // this situation may occur after a scene suspend: the keyboard release 
+                               // event was not captured, produce now the event off
+                               m_val = 0;
+                               result = true;
+                       }
                } else
                {
                        if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
@@ -190,6 +216,23 @@ bool SCA_KeyboardSensor::Evaluate(CValue* eventval)
                                {
                                        m_val = 0;
                                        result = true;
+                               } else 
+                               {
+                                       if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
+                                       {
+                                               if (m_val == 0)
+                                               {
+                                                       //hmm, this abnormal situation may occur in the following cases:
+                                                       //- the key was pressed while the scene was suspended
+                                                       //- this is a new scene and the key is active from the start
+                                                       //In the second case, it's dangerous to activate the sensor
+                                                       //(think of a key to go to next scene)
+                                                       //What we really need is a edge/level flag in the key sensor
+                                                       //m_val = 1;
+                                                       //result = true;
+                                                       ;
+                                               }
+                                       }
                                }
                        }
                }
index a91cf3e043930a7c57a5c62fecded762034f5dd6..8810b7470ed152974c75148b1b163ab6145d3d6e 100644 (file)
@@ -158,6 +158,25 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
                                {
                                        m_val = 0;
                                        result = true;
+                               } else
+                               {
+                                       if (event.m_status == SCA_InputEvent::KX_ACTIVE)
+                                       {
+                                               if (m_val == 0)
+                                               {
+                                                       //dangerous
+                                                       //m_val = 1;
+                                                       //result = true;
+                                                       ;
+                                               }
+                                       } else
+                                       {
+                                               if (m_val == 1)
+                                               {
+                                                       m_val = 0;
+                                                       result = true;
+                                               }
+                                       }
                                }
                        }
                        break;
@@ -183,6 +202,13 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
                                {
                                        m_val = 0;
                                        result = true;
+                               } else
+                               {
+                                       if (m_val == 1)
+                                       {
+                                               m_val = 0;
+                                               result = true;
+                                       }
                                }
                        }
                        break;
index a5b8d8aacdfc19d6e7006ec26565be00b99f9c7f..edda7657ef950dd3c8fb6b3ba094e5042e049caa 100644 (file)
@@ -137,6 +137,10 @@ int GPC_RenderTools::ProcessLighting(int layer)
        {
                if (m_clientobject)
                {       
+                       if (layer == RAS_LIGHT_OBJECT_LAYER)
+                       {
+                               layer = static_cast<KX_GameObject*>(m_clientobject)->GetLayer();
+                       }
                        if (applyLights(layer))
                        {
                                EnableOpenGLLights();
index 1496f7c6ad3ec141bbc15935c3962ea891bdba47..8817bc98886e17acc76abeecb6a48312110b6061 100644 (file)
@@ -579,7 +579,7 @@ int main(int argc, char** argv)
                                                // base the actuator filename with respect
                                                // to the original file working directory
                                                strcpy(basedpath, exitstring.Ptr());
-                                               BLI_convertstringcode(basedpath, pathname, 0);
+                                               BLI_convertstringcode(basedpath, pathname);
                                                
                                                bfd = load_game_data(basedpath);
                                        }
index cfdcba8a5d67d90b95c16c83c4455fc25fd0e7fc..447275881065e85d73f18b40837fbfaacd327494 100644 (file)
@@ -84,6 +84,7 @@ KX_BlenderMaterial::KX_BlenderMaterial(
        mScene(scene),
        mUserDefBlend(0),
        mModified(0),
+       mConstructed(false),
        mPass(0)
 
 {
@@ -119,7 +120,9 @@ KX_BlenderMaterial::KX_BlenderMaterial(
 KX_BlenderMaterial::~KX_BlenderMaterial()
 {
        // cleanup work
-       OnExit();
+       if (mConstructed)
+               // clean only if material was actually used
+               OnExit();
 }
 
 
@@ -138,6 +141,10 @@ unsigned int* KX_BlenderMaterial::GetMCol(void) const
 
 void KX_BlenderMaterial::OnConstruction()
 {
+       if (mConstructed)
+               // when material are reused between objects
+               return;
+
        // for each unique material...
        int i;
        for(i=0; i<mMaterial->num_enabled; i++) {
@@ -148,19 +155,20 @@ void KX_BlenderMaterial::OnConstruction()
                        }
                        if(!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) )
                                spit("unable to initialize image("<<i<<") in "<< 
-                                               mMaterial->matname<< ", image will not be available");
+                                                mMaterial->matname<< ", image will not be available");
                } 
        
                else {
                        if( mMaterial->img[i] ) {
                                if( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 ))
                                        spit("unable to initialize image("<<i<<") in "<< 
-                                                mMaterial->matname<< ", image will not be available");
+                                               mMaterial->matname<< ", image will not be available");
                        }
                }
        }
        mBlendFunc[0] =0;
        mBlendFunc[1] =0;
+       mConstructed = true;
 }
 
 void KX_BlenderMaterial::OnExit()
index 2b1264154d0c5b7a094fc30d0b731784ea98ef67..b9d4819952011bbbb2f5730b627e1f525186417f 100644 (file)
@@ -93,6 +93,7 @@ private:
        bool                    mUserDefBlend;
        unsigned int    mBlendFunc[2];
        bool                    mModified;
+       bool                    mConstructed;                   // if false, don't clean on exit
 
        void ActivatGLMaterials( RAS_IRasterizer* rasty )const;
        void ActivateTexGen( RAS_IRasterizer *ras ) const;
index 4a61c37be065639662617d126ca0ae070d8dff5b..e0cd5a3bc9e458431de5624a0a5c0e6bc465873d 100644 (file)
@@ -1123,7 +1123,7 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
        ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
        ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
-
+       ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
        KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
        //remember that we created a shape so that we can delete it when the scene is removed (bullet will not delete it) 
        kxscene->AddShape(bm);
@@ -1147,6 +1147,7 @@ void      KX_ConvertBulletObject( class   KX_GameObject* gameobj,
        //{
        //      rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
        //}
+       
        if (objprop->m_dyna && !objprop->m_angular_rigidbody)
        {
                /*
@@ -1161,8 +1162,10 @@ void     KX_ConvertBulletObject( class   KX_GameObject* gameobj,
                */
 
                //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
-               physicscontroller->GetRigidBody()->setAngularFactor(0.f);
-
+       
+               //Now done directly in ci.m_bRigid so that it propagates to replica
+               //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
+               ;
        }
 
        bool isActor = objprop->m_isactor;
index cf621e04f999ac1392dae9aca2c6a2969e4ebb5e..4c6ba448ebf8661bb9b469b4cc8d3892d71aaa1d 100644 (file)
@@ -74,6 +74,7 @@ KX_GameObject::KX_GameObject(
 ) : 
        SCA_IObject(T),
        m_bDyna(false),
+       m_layer(0),
        m_bSuspendDynamics(false),
        m_bUseObjectColor(false),
        m_bVisible(true),
@@ -228,7 +229,7 @@ void KX_GameObject::SetParent(KX_Scene *scene, KX_GameObject* obj)
 
                NodeSetLocalScale(scale1);
                NodeSetLocalPosition(MT_Point3(newpos[0],newpos[1],newpos[2]));
-               NodeSetLocalOrientation(NodeGetWorldOrientation()*invori);
+               NodeSetLocalOrientation(invori*NodeGetWorldOrientation());
                NodeUpdateGS(0.f,true);
                // object will now be a child, it must be removed from the parent list
                CListValue* rootlist = scene->GetRootParentList();
@@ -479,6 +480,22 @@ KX_GameObject::SetVisible(
        m_bVisible = v;
 }
 
+void
+KX_GameObject::SetLayer(
+       int l
+       )
+{
+       m_layer = l;
+}
+
+int
+KX_GameObject::GetLayer(
+       void
+       )
+{
+       return m_layer;
+}
+
 // used by Python, and the actuatorshould _not_ be misused by the
 // scene!
 void 
index 87775e812167b2e346673b83f74776687d12d6bb..da0cd69e129d05c41353cba54457b627b159c5d5 100644 (file)
@@ -70,6 +70,7 @@ protected:
        KX_ClientObjectInfo*                            m_pClient_info;
        STR_String                                                      m_name;
        STR_String                                                      m_text;
+       int                                                                     m_layer;
        std::vector<RAS_MeshObject*>            m_meshes;
        
        bool                                                            m_bSuspendDynamics;
@@ -571,6 +572,22 @@ public:
                bool b
        );
 
+       /**
+        * Change the layer of the object (when it is added in another layer
+        * than the original layer)
+        */
+               void
+       SetLayer(
+               int l
+       );
+
+       /**
+        * Get the object layer
+        */
+               int
+       GetLayer(
+               void
+       );
                
        /**
         * @section Logic bubbling methods.
index 54003284e03d8b0a68b77944b3a710736b7f9070..e4054e07475b97d6b55af7d5acd662e55be248c4 100644 (file)
@@ -650,6 +650,8 @@ SCA_IObject* KX_Scene::AddReplicaObject(class CValue* originalobject,
        for (git = m_logicHierarchicalGameObjects.begin();!(git==m_logicHierarchicalGameObjects.end());++git)
        {
                (*git)->Relink(&m_map_gameobject_to_replica);
+               // add the object in the layer of the parent
+               (*git)->SetLayer(parentobj->GetLayer());
        }
 
        // now replicate logic
index d99b75482b9eb9a6bdc58f5bc2eff7749ae82cc9..e444c4c73be1c18e28a1d855c38fcab640432b0b 100644