Merge 16964:17122
authorMartin Poirier <theeth@yahoo.com>
Mon, 20 Oct 2008 00:27:33 +0000 (00:27 +0000)
committerMartin Poirier <theeth@yahoo.com>
Mon, 20 Oct 2008 00:27:33 +0000 (00:27 +0000)
166 files changed:
SConstruct
config/darwin-config.py
config/linux2-config.py
config/linuxcross-config.py
config/openbsd3-config.py
config/sunos5-config.py
config/win32-mingw-config.py
config/win32-vc-config.py
extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
extern/bullet2/src/BulletSoftBody/btSoftBody.h
extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
intern/SoundSystem/SND_Utils.h
intern/SoundSystem/fmod/SND_FmodDevice.cpp
intern/SoundSystem/intern/SND_Scene.cpp
intern/SoundSystem/intern/SND_SoundObject.cpp
intern/SoundSystem/intern/SND_Utils.cpp
intern/elbeem/intern/elbeem.cpp
intern/ghost/intern/GHOST_WindowWin32.cpp
release/VERSION
release/datafiles/splash.jpg
release/scripts/bvh_import.py
release/scripts/c3d_import.py
release/scripts/config.py
release/scripts/export_fbx.py
release/scripts/export_obj.py
release/scripts/help_browser.py
release/scripts/hotkeys.py
release/scripts/import_obj.py
release/scripts/import_web3d.py [new file with mode: 0755]
release/scripts/render_save_layers.py
release/scripts/scripttemplate_gamelogic_basic.py
release/scripts/vrml97_export.py
release/text/Python-license.txt
release/windows/installer/00.sconsblender.nsi
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/bullet.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/idprop.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenlib/intern/dynlib.c
source/blender/blenlib/intern/fileops.c
source/blender/blenloader/intern/readfile.c
source/blender/gpu/GPU_extensions.h
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/gpu/intern/gpu_material.c
source/blender/imbuf/intern/cineon/cineon_dpx.c
source/blender/imbuf/intern/cineon/cineonlib.c
source/blender/imbuf/intern/cineon/dpxlib.c
source/blender/imbuf/intern/dynlibtiff.c
source/blender/include/BDR_gpencil.h
source/blender/include/BIF_drawgpencil.h
source/blender/include/BIF_keyframing.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/python/BPY_menus.c
source/blender/python/SConscript
source/blender/python/api2_2x/Armature.c
source/blender/python/api2_2x/Ipocurve.c
source/blender/python/api2_2x/Material.c
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/Particle.c
source/blender/python/api2_2x/Window.c
source/blender/python/api2_2x/doc/BGL.py
source/blender/python/api2_2x/doc/Ipo.py
source/blender/python/api2_2x/doc/IpoCurve.py
source/blender/python/api2_2x/doc/Material.py
source/blender/python/api2_2x/doc/Noise.py
source/blender/python/api2_2x/doc/Object.py
source/blender/python/api2_2x/doc/Particle.py
source/blender/python/api2_2x/doc/Render.py
source/blender/python/api2_2x/doc/Renderlayer.py [new file with mode: 0644]
source/blender/python/api2_2x/doc/SConscript [new file with mode: 0644]
source/blender/python/api2_2x/doc/Text.py
source/blender/python/api2_2x/doc/Texture.py
source/blender/python/api2_2x/doc/epy_docgen.sh
source/blender/python/api2_2x/sceneRender.c
source/blender/render/intern/include/sss.h
source/blender/render/intern/include/zbuf.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/sss.c
source/blender/render/intern/source/zbuf.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_logic.c
source/blender/src/buttons_object.c
source/blender/src/buttons_shading.c
source/blender/src/drawaction.c
source/blender/src/drawgpencil.c
source/blender/src/drawimage.c
source/blender/src/drawnode.c
source/blender/src/drawobject.c
source/blender/src/drawseq.c
source/blender/src/editaction.c
source/blender/src/editaction_gpencil.c
source/blender/src/editconstraint.c
source/blender/src/editmesh.c
source/blender/src/editnode.c
source/blender/src/fluidsim.c
source/blender/src/ghostwinlay.c
source/blender/src/gpencil.c
source/blender/src/hddaudio.c
source/blender/src/header_view3d.c
source/blender/src/imagepaint.c
source/blender/src/keyframing.c
source/blender/src/outliner.c
source/blender/src/playanim.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/splash.jpg.c
source/blender/src/transform_conversions.c
source/blender/src/view.c
source/blender/yafray/intern/export_Plugin.cpp
source/creator/CMakeLists.txt
source/creator/SConscript
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
source/gameengine/Converter/KX_ConvertSensors.cpp
source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
source/gameengine/GameLogic/Joystick/SCA_Joystick.h
source/gameengine/GameLogic/Joystick/SCA_JoystickEvents.cpp
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_JoystickManager.cpp
source/gameengine/GameLogic/SCA_JoystickSensor.cpp
source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_NearSensor.cpp
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_PythonInit.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_TouchSensor.cpp
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Ketsji/KX_VehicleWrapper.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp
source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.cpp
source/gameengine/Physics/Sumo/SumoPhysicsEnvironment.h
source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
source/gameengine/PyDoc/GameLogic.py
source/gameengine/PyDoc/KX_ActuatorSensor.py
source/gameengine/PyDoc/KX_ConstraintActuator.py
source/gameengine/PyDoc/KX_IpoActuator.py
source/gameengine/PyDoc/Rasterizer.py
source/gameengine/PyDoc/SCA_JoystickSensor.py [new file with mode: 0644]
source/gameengine/PyDoc/epy_docgen.sh
tools/Blender.py
tools/btools.py

index 0a959cc5b7bb4de8314376b55f0a148baf58c182..f15aa8bfa2241d65e442d44cf5be4b2b3a65c835 100644 (file)
@@ -277,15 +277,15 @@ if 'blenderlite' in B.targets:
     env['WITH_BF_BINRELOC'] = False
     env['BF_BUILDINFO'] = False
     env['BF_NO_ELBEEM'] = True
-    
-
 
 # lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
 #B.root_build_dir = B.arguments.get('BF_BUILDDIR', '..'+os.sep+'build'+os.sep+platform+os.sep)
 B.root_build_dir = env['BF_BUILDDIR']
-env['BUILDDIR'] = B.root_build_dir
+B.doc_build_dir = env['BF_DOCDIR']
 if not B.root_build_dir[-1]==os.sep:
     B.root_build_dir += os.sep
+if not B.doc_build_dir[-1]==os.sep:
+    B.doc_build_dir += os.sep
     
 # We do a shortcut for clean when no quicklist is given: just delete
 # builddir without reading in SConscripts
@@ -294,8 +294,18 @@ if 'clean' in B.targets:
     do_clean = True
 
 if not quickie and do_clean:
+    if os.path.exists(B.doc_build_dir):
+        print B.bc.HEADER+'Cleaning doc dir...'+B.bc.ENDC
+        dirs = os.listdir(B.doc_build_dir)
+        for entry in dirs:
+            if os.path.isdir(B.doc_build_dir + entry) == 1:
+                print "clean dir %s"%(B.doc_build_dir+entry)
+                shutil.rmtree(B.doc_build_dir+entry)
+            else: # remove file
+                print "remove file %s"%(B.doc_build_dir+entry)
+                os.remove(B.root_build_dir+entry)
     if os.path.exists(B.root_build_dir):
-        print B.bc.HEADER+'Cleaning...'+B.bc.ENDC
+        print B.bc.HEADER+'Cleaning build dir...'+B.bc.ENDC
         dirs = os.listdir(B.root_build_dir)
         for entry in dirs:
             if os.path.isdir(B.root_build_dir + entry) == 1:
@@ -321,6 +331,8 @@ if not os.path.isdir ( B.root_build_dir):
     os.makedirs ( B.root_build_dir + 'extern' )
     os.makedirs ( B.root_build_dir + 'lib' )
     os.makedirs ( B.root_build_dir + 'bin' )
+if not os.path.isdir(B.doc_build_dir):
+    os.makedirs ( B.doc_build_dir )
 
 Help(opts.GenerateHelpText(env))
 
@@ -363,7 +375,8 @@ dobj = B.buildinfo(env, "dynamic") + B.resources
 thestatlibs, thelibincs = B.setup_staticlibs(env)
 thesyslibs = B.setup_syslibs(env)
 
-env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist + thestatlibs, [], thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
+if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
+    env.BlenderProg(B.root_build_dir, "blender", dobj + mainlist + thestatlibs, [], thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
 if env['WITH_BF_PLAYER']:
     playerlist = B.create_blender_liblist(env, 'player')
     env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist + thestatlibs, [], thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
@@ -534,6 +547,10 @@ nsisaction = env.Action(btools.NSIS_Installer, btools.NSIS_print)
 nsiscmd = env.Command('nsisinstaller', None, nsisaction)
 nsisalias = env.Alias('nsis', nsiscmd)
 
+if 'blender' in B.targets:
+       blenderexe= env.Alias('blender', B.program_list)
+       Depends(blenderexe,installtarget)
+
 if env['WITH_BF_PLAYER']:
     blenderplayer = env.Alias('blenderplayer', B.program_list)
     Depends(blenderplayer,installtarget)
@@ -560,5 +577,6 @@ if not env['WITHOUT_BF_INSTALL']:
 # TODO: build stubs and link into blenderplayer
 
 #------------ EPYDOC
-# TODO: run epydoc
+if env['WITH_BF_BPYDOC']:
+    SConscript(['source/blender/python/api2_2x/doc/SConscript'])
 
index 0eb275dcaf4c9efe0718b19241795d00795090e6..cc6c6ef76aff736bd0fba5e629838884add3d14f 100644 (file)
@@ -268,3 +268,4 @@ BF_DEBUG_FLAGS = '-g'
 
 BF_BUILDDIR='../build/darwin'
 BF_INSTALLDIR='../install/darwin'
+BF_DOCDIR='../install/doc'
index 2b7bf074f83eb14a29a6e26207bc814886a4e1f5..74853de70b65718ae784f3c462005179523ec342 100644 (file)
@@ -205,6 +205,7 @@ BF_DEBUG_FLAGS = '-g'
 
 BF_BUILDDIR = '../build/linux2'
 BF_INSTALLDIR='../install/linux2'
+BF_DOCDIR='../install/doc'
 
 
 #Link against pthread
index 9d58512151b6ff0e9c222cb51bf6b13c943b5f5b..13f477d21f3eb43aa8948e76d16a07471f910827 100644 (file)
@@ -148,3 +148,4 @@ BF_DEBUG_FLAGS= ''
 
 BF_BUILDDIR = '../build/linuxcross'
 BF_INSTALLDIR='../install/linuxcross'
+BF_DOCDIR='../install/doc'
index 5ef3d90f168afcfbde0be7115a0cfb3f983d9869..1cd93008561e69d3987af45be0ad1f2c6e3aff22 100644 (file)
@@ -163,3 +163,4 @@ BF_DEBUG_FLAGS = '-g'
 
 BF_BUILDDIR='../build/openbsd3'
 BF_INSTALLDIR='../install/openbsd3'
+BF_DOCDIR='../install/doc'
index bfb1513ca3f545066a25ba15722ffb8cd4c59530..a5ba33e44cd7a7608e8adf4c57c4a902fad56862 100644 (file)
@@ -177,6 +177,7 @@ BF_DEBUG_FLAGS = ''
 
 BF_BUILDDIR = '../build/sunos5'
 BF_INSTALLDIR='../install/sunos5'
+BF_DOCDIR='../install/doc'
 
 
 PLATFORM_LINKFLAGS = ['']
index 4ff93bf7078a294e8f4cb215dc0e16b2bf4f0542..65b7beb79adb7d27d831b4f718a577e6f5167b92 100644 (file)
@@ -167,3 +167,4 @@ BF_PROFILE = 'false'
 
 BF_BUILDDIR = '..\\build\\win32-mingw'
 BF_INSTALLDIR='..\\install\\win32-mingw'
+BF_DOCDIR = '..\\install\\doc'
\ No newline at end of file
index 1b7737ed004510376e6014d7ea4fc2f27124644a..14fd8b3aac75ba739c17e2333e267cb19a855167 100644 (file)
@@ -187,3 +187,4 @@ PLATFORM_LINKFLAGS = '''
 
 BF_BUILDDIR = '..\\build\\win32-vc'
 BF_INSTALLDIR='..\\install\\win32-vc'
+BF_DOCDIR='..\\install\\doc'
index 2911d52e5ea470e42919ce4fae34fd561550a2e5..41e336c9d17cc1e02db28baf95b8b8925a962a34 100644 (file)
@@ -1015,7 +1015,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio
                btAssert(pt);
                pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
                pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
-               pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+               pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
 
                //do a callback here?
 
index 329a1d9cde3671b7d12400dee453b6d233719ce2..745694e2f70f202e127ef279f26046e20367b67b 100644 (file)
@@ -423,6 +423,13 @@ btVector3 btDiscreteDynamicsWorld::getGravity () const
 
 void   btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
 {
+       //remove all constraints too
+       while (body->getNumConstraintRefs())
+       {
+               btTypedConstraint* constraint = body->getConstraintRef(0);
+               removeConstraint(constraint);
+       }
+
        removeCollisionObject(body);
 }
 
index 1604167b6efa7e674ab9d8c4ab1d51f7736fa7bc..1ec668c9c78dca09461b673b592857abd1a37cb0 100644 (file)
@@ -306,8 +306,16 @@ void                       btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
 }
 
 //
-void                   btSoftBody::appendAnchor(int node,btRigidBody* body)
+void                   btSoftBody::appendAnchor(int node,btRigidBody* body,bool disableCollisionWithBody=false)
 {
+       if (disableCollisionWithBody)
+       {
+               if (m_collisionDisabledObjects.findLinearSearch(body)==m_collisionDisabledObjects.size())
+               {
+                       m_collisionDisabledObjects.push_back(body);
+               }
+       }
+
        Anchor  a;
        a.m_node                        =       &m_nodes[node];
        a.m_body                        =       body;
index 79d272765e01c04ddd9ca245585b1540e3baf20c..743462d259a48a7d1c9bc2203016692ce420616e 100644 (file)
@@ -49,6 +49,8 @@ struct        btSoftBodyWorldInfo
 class  btSoftBody : public btCollisionObject
 {
 public:
+       btAlignedObjectArray<class btCollisionObject*> m_collisionDisabledObjects;
+
        //
        // Enumerations
        //
@@ -667,7 +669,7 @@ public:
                                                                        Material* mat=0);
        /* Append anchor                                                                                                                */ 
        void                            appendAnchor(   int node,
-                                                                               btRigidBody* body);
+                                                                               btRigidBody* body,bool disableCollision);
        /* Append linear joint                                                                                                  */ 
        void                            appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
        void                            appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
index e79dd214e6200e911f6856237198bad16a79dc57..53ac27825834dbe256f249ba665c997c714ca649 100644 (file)
@@ -62,6 +62,7 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
                collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
                if (collisionAlgorithmMaxElementSize > curElemSize)
                {
+                       m_collisionAlgorithmPool->~btPoolAllocator();
                        btAlignedFree(m_collisionAlgorithmPool);
                        void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
                        m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
index 835a03b8e3c79610bb9715095c72017354297982..e5feb5ef749d4ad6b15aabb9203ebfc0469cc86f 100644 (file)
@@ -59,7 +59,10 @@ void btSoftRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,b
        btSoftBody* softBody =  m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0;
        btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1;
        
-       softBody->defaultCollisionHandler(rigidCollisionObject);
+       if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObject)==softBody->m_collisionDisabledObjects.size())
+       {
+               softBody->defaultCollisionHandler(rigidCollisionObject);
+       }
 
 
 }
index c54aa434eec292381c02a8c8dcbd1d556aeeeb61..26cf1bda11cc19dab04986825563f95803393676 100644 (file)
@@ -97,8 +97,8 @@ extern unsigned int SND_GetSampleFormat(void* sample);
 extern unsigned int SND_GetNumberOfChannels(void* sample);
 extern unsigned int SND_GetSampleRate(void* sample);
 extern unsigned int SND_GetBitRate(void* sample);
-extern unsigned int SND_GetNumberOfSamples(void* sample);
-extern unsigned int SND_GetHeaderSize(void* sample);
+extern unsigned int SND_GetNumberOfSamples(void* sample, int sample_length);
+extern unsigned int SND_GetHeaderSize(void* sample, int sample_length);
 extern unsigned int SND_GetExtraChunk(void* sample);
 
 extern void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot);
index cc252954fea70e47fd210cd46700fcb5def9eb00..3ba0802a5b046fd80d5fc2b9c16ae035d61083fa 100644 (file)
@@ -162,7 +162,7 @@ SND_WaveSlot* SND_FmodDevice::LoadSample(const STR_String& name,
                                                int numberofchannels = SND_GetNumberOfChannels(memlocation);
                                                int samplerate = SND_GetSampleRate(memlocation);
                                                int bitrate = SND_GetBitRate(memlocation);
-                                               int numberofsamples = SND_GetNumberOfSamples(memlocation);
+                                               int numberofsamples = SND_GetNumberOfSamples(memlocation, size);
                                                
                                                waveslot->SetFileSize(size);
                                                waveslot->SetData(memlocation);
index bbf971ddc871dccb514f1c508e69f3275b603821..9d050a81161f8b3a8f022694dc94bb8786322112 100644 (file)
@@ -388,11 +388,18 @@ void SND_Scene::UpdateActiveObects()
 #endif
 #ifdef USE_OPENAL
                        // ok, properties Set. now see if it must play
-                       if (pObject->GetPlaystate() == SND_MUST_PLAY)
-                       {
+                       switch (pObject->GetPlaystate()){
+                       case SND_MUST_PLAY:
                                m_audiodevice->PlayObject(id);
                                pObject->SetPlaystate(SND_PLAYING);
-                               //break;
+                               break;
+                       case SND_MUST_STOP:
+                               RemoveActiveObject(pObject);
+                               break;
+                       case SND_MUST_PAUSE:
+                               m_audiodevice->PauseObject(id);
+                               pObject->SetPlaystate(SND_PAUSED);
+                               break;
                        }
 #endif
 
index e514a186e5e219f322e2e923f679d78eef68b6b7..7a244b5090dbf90189a91fcbd61a620441aa45e5 100644 (file)
@@ -91,21 +91,24 @@ SND_SoundObject::~SND_SoundObject()
 
 void SND_SoundObject::StartSound()
 {
-       m_playstate = SND_MUST_PLAY;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_PLAY;
 }
 
 
 
 void SND_SoundObject::StopSound()
 {
-       m_playstate = SND_MUST_STOP;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_STOP;
 }
 
 
 
 void SND_SoundObject::PauseSound()
 {
-       m_playstate = SND_MUST_PAUSE;
+       if (m_id >= 0)
+               m_playstate = SND_MUST_PAUSE;
 }
 
 
index 754c8b029a1a6c182d2d34b15d58389a09979a5e..78115807970c08c7c53aef3d3c36dc316bdf3a15 100644 (file)
@@ -285,26 +285,32 @@ unsigned int SND_GetBitRate(void* sample)
 
 
 /* gets the length of the actual sample data (without the header) */
-unsigned int SND_GetNumberOfSamples(void* sample)
+unsigned int SND_GetNumberOfSamples(void* sample, int sample_length)
 {
-       unsigned int chunklength, length = 0, offset = 16;
-       char data[4];
-       
+       unsigned int chunklength, length = 0, offset;
+       unsigned short block_align;
        if (CheckSample(sample))
        {
-               memcpy(&chunklength, ((char*)sample) + offset, 4);
+               memcpy(&chunklength, ((char*)sample) + 16, 4);
+               memcpy(&block_align, ((char*)sample) + 32, 2); /* always 2 or 4 it seems */
+               
                /* This was endian unsafe. See top of the file for the define. */
-               if (SND_fEndian == SND_endianBig) SWITCH_INT(chunklength);
-
-               offset = offset + chunklength + 4;
-               memcpy(data, ((char*)sample) + offset, 4);
+               if (SND_fEndian == SND_endianBig)
+               {
+                       SWITCH_INT(chunklength);
+                       SWITCH_SHORT(block_align);
+               }
+                               
+               offset = 16 + chunklength + 4;
 
                /* This seems very unsafe, what if data is never found (f.i. corrupt file)... */
                // lets find "data"
-               while (memcmp(data, "data", 4))
+               while (memcmp(((char*)sample) + offset, "data", 4))
                {
-                       offset += 4;
-                       memcpy(data, ((char*)sample) + offset, 4);
+                       offset += block_align;
+                       
+                       if (offset+block_align > sample_length) /* save us from crashing */
+                               return 0;
                }
                offset += 4;
                memcpy(&length, ((char*)sample) + offset, 4);
@@ -319,34 +325,38 @@ unsigned int SND_GetNumberOfSamples(void* sample)
 
 
 /* gets the size of the entire header (file - sampledata) */
-unsigned int SND_GetHeaderSize(void* sample)
+unsigned int SND_GetHeaderSize(void* sample, int sample_length)
 {
        unsigned int chunklength, headersize = 0, offset = 16;
-       char data[4];
-       
+       unsigned short block_align;
        if (CheckSample(sample))
        {
                memcpy(&chunklength, ((char*)sample) + offset, 4);
+               memcpy(&block_align, ((char*)sample) + 32, 2); /* always 2 or 4 it seems */
+               
                /* This was endian unsafe. See top of the file for the define. */
-               if (SND_fEndian == SND_endianBig) SWITCH_INT(chunklength);
+               if (SND_fEndian == SND_endianBig)
+               {
+                       SWITCH_INT(chunklength);
+                       SWITCH_SHORT(block_align);
+               }
                offset = offset + chunklength + 4;
-               memcpy(data, ((char*)sample) + offset, 4);
 
                // lets find "data"
-               while (memcmp(data, "data", 4))
+               while (memcmp(((char*)sample) + offset, "data", 4))
                {
-                       offset += 4;
-                       memcpy(data, ((char*)sample) + offset, 4);
+                       offset += block_align;
+                       
+                       if (offset+block_align > sample_length) /* save us from crashing */
+                               return 0;
                }
                headersize = offset + 8;
        }
 
-
        return headersize;
 }
 
 
-
 unsigned int SND_GetExtraChunk(void* sample)
 {
        unsigned int extrachunk = 0, chunklength, offset = 16;
@@ -382,58 +392,60 @@ void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot)
        if (CheckSample(sample))
        {
                memcpy(&fileheader, sample, sizeof(WavFileHeader));
-               fileheader.size = SND_GetHeaderSize(sample);
-               sample += sizeof(WavFileHeader);
-               fileheader.size = ((fileheader.size+1) & ~1) - 4;
+               fileheader.size = SND_GetHeaderSize(sample, waveslot->GetFileSize());
+               if (fileheader.size) { /* this may fail for corrupt files */
+                       sample += sizeof(WavFileHeader);
+                       fileheader.size = ((fileheader.size+1) & ~1) - 4;
 
-               while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
-               {
-                       sample += sizeof(WavChunkHeader);
-                       if (!memcmp(chunkheader.id, "fmt ", 4))
+                       while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
                        {
-                               memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
-                               waveslot->SetSampleFormat(fmtheader.format);
-
-                               if (fmtheader.format == 0x0001)
+                               sample += sizeof(WavChunkHeader);
+                               if (!memcmp(chunkheader.id, "fmt ", 4))
                                {
-                                       waveslot->SetNumberOfChannels(fmtheader.numberofchannels);
-                                       waveslot->SetBitRate(fmtheader.bitrate);
-                                       waveslot->SetSampleRate(fmtheader.samplerate);
-                                       sample += chunkheader.size;
-                               } 
-                               else
-                               {
-                                       memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader));
-                                       sample += chunkheader.size;
-                               }
-                       }
-                       else if (!memcmp(chunkheader.id, "data", 4))
-                       {
-                               if (fmtheader.format == 0x0001)
-                               {
-                                       waveslot->SetNumberOfSamples(chunkheader.size);
-                                       sample += chunkheader.size;
+                                       memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
+                                       waveslot->SetSampleFormat(fmtheader.format);
+
+                                       if (fmtheader.format == 0x0001)
+                                       {
+                                               waveslot->SetNumberOfChannels(fmtheader.numberofchannels);
+                                               waveslot->SetBitRate(fmtheader.bitrate);
+                                               waveslot->SetSampleRate(fmtheader.samplerate);
+                                               sample += chunkheader.size;
+                                       } 
+                                       else
+                                       {
+                                               memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader));
+                                               sample += chunkheader.size;
+                                       }
                                }
-                               else if (fmtheader.format == 0x0011)
+                               else if (!memcmp(chunkheader.id, "data", 4))
                                {
-                                       //IMA ADPCM
+                                       if (fmtheader.format == 0x0001)
+                                       {
+                                               waveslot->SetNumberOfSamples(chunkheader.size);
+                                               sample += chunkheader.size;
+                                       }
+                                       else if (fmtheader.format == 0x0011)
+                                       {
+                                               //IMA ADPCM
+                                       }
+                                       else if (fmtheader.format == 0x0055)
+                                       {
+                                               //MP3 WAVE
+                                       }
                                }
-                               else if (fmtheader.format == 0x0055)
+                               else if (!memcmp(chunkheader.id, "smpl", 4))
                                {
-                                       //MP3 WAVE
+                                       memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
+                                       //loop = sampleheader.loops;
+                                       sample += chunkheader.size;
                                }
-                       }
-                       else if (!memcmp(chunkheader.id, "smpl", 4))
-                       {
-                               memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
-                               //loop = sampleheader.loops;
-                               sample += chunkheader.size;
-                       }
-                       else
-                               sample += chunkheader.size;
+                               else
+                                       sample += chunkheader.size;
 
-                       sample += chunkheader.size & 1;
-                       fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
+                               sample += chunkheader.size & 1;
+                               fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
+                       }
                }
        }
 }
index f7923322d5b4e3e008197cfb14056ea7e3abc99f..179e103e326774915f4f304651f8d5c9078eb8b6 100644 (file)
@@ -204,6 +204,7 @@ int elbeemAddMesh(elbeemMesh *mesh) {
        
        ntlGeometryObjModel *obj = new ntlGeometryObjModel( );
        gpWorld->getRenderGlobals()->getSimScene()->addGeoClass( obj );
+       gpWorld->getRenderGlobals()->getRenderScene()->addGeoClass(obj);
        obj->initModel(
                        mesh->numVertices, mesh->vertices, mesh->numTriangles, mesh->triangles,
                        mesh->channelSizeVertices, mesh->channelVertices );
index c30b915c019b4068661fa82fa86b02f6d58a1284..6a06f4d715a65863b38c6556eede99c16ed874fa 100644 (file)
@@ -434,16 +434,6 @@ GHOST_TSuccess GHOST_WindowWin32::setOrder(GHOST_TWindowOrder order)
 
 GHOST_TSuccess GHOST_WindowWin32::swapBuffers()
 {
-       // adding a glFinish() here is to prevent Geforce in 'full scene antialias' mode
-       // from antialising the Blender window. Officially a swapbuffers does a glFinish
-       // itself, so this feels really like a hack... but it won't harm. (ton)
-       // 
-       // disabled this because it is a performance killer for the game engine, glFinish
-       // forces synchronization with the graphics card and calling it is strongly
-       // discouraged for good performance. (brecht)
-       //
-       // glFinish();
-
        return ::SwapBuffers(m_hDC) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
 }
 
index 5d8213c95e7315cd60de7ebf6c1df9697be3b052..1c593e17dae63eac99ea3a8b58b1cce422c994c5 100644 (file)
@@ -1 +1 @@
-2.47
+2.48
index 684a12c3cbb11786236b5951c7b8b6c86c0edddf..f80a35becbc02eb2dc561c733e340ecc61f68606 100644 (file)
Binary files a/release/datafiles/splash.jpg and b/release/datafiles/splash.jpg differ
index 2093ac109f73fca7791f7af0d3e3786d2e5c48ff..5cdd8a712316da1b1b088de37afa05d0a05f29a6 100644 (file)
@@ -231,7 +231,7 @@ def read_bvh(file_path, GLOBAL_SCALE=1.0):
        
        bvh_nodes_list= bvh_nodes.values()
        
-       while lineIdx < len(file_lines) -1:
+       while lineIdx < len(file_lines):
                line= file_lines[lineIdx]
                for bvh_node in bvh_nodes_list:
                        #for bvh_node in bvh_nodes_serial:
@@ -726,7 +726,7 @@ def load_bvh_ui(file, PREF_UI= True):
        Blender.Window.WaitCursor(1)
        # Get the BVH data and act on it.
        t1= Blender.sys.time()
-       print '\tpassing bvh...',
+       print '\tparsing bvh...',
        bvh_nodes= read_bvh(file, IMPORT_SCALE)
        print '%.4f' % (Blender.sys.time()-t1)
        t1= Blender.sys.time()
index ca4f8cd79e90e12e21cf0611a03db5ae11e4696e..bfe691c394c6c5d691c9676f8590f75493037b93 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# -*- coding: latin-1 -*-
 """
 Name: 'Motion Capture  (.c3d)...'
 Blender: 246
index 4251bad86544e9ea9918d3a0321f107c9a305081..cbf8e272b9151194f1642396518a7df607361416 100644 (file)
@@ -246,6 +246,10 @@ information about how to fix this.
                        fields = fields[2].split()
                        if len(fields) > 1:
                                fname = fields[1].split(sep)[-1]
+                               i = 1
+                               while not fname.endswith('.py'):
+                                       i += 1
+                                       fname = "%s %s" % (fname, fields[i])
                                ALL_SCRIPTS[fname] = (menuname, group_len - 1)
        return True
 
index 2d8859aa8fbfb84ea16e886b15d290de43a81d24..696d3d1561a1816b1e2c54622629dc0c95685cae 100644 (file)
@@ -2887,7 +2887,7 @@ def fbx_ui():
 def write_ui():
        
        # globals
-       GLOBALS['EVENT'] = 2
+       GLOBALS['EVENT'] = EVENT_REDRAW
        #GLOBALS['MOUSE'] = Window.GetMouseCoords()
        GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
        GLOBALS['FILENAME'] = ''
@@ -2929,13 +2929,6 @@ def write_ui():
        GLOBALS['_YROT90'] =                                    Draw.Create(False)
        GLOBALS['_ZROT90'] =                                    Draw.Create(False)
        
-       # horrible ugly hack so tooltips draw, dosnt always work even
-       # Fixed in Draw.UIBlock for 2.45rc2, but keep this until 2.45 is released
-       Window.SetKeyQualifiers(0)
-       while Window.GetMouseButtons(): Blender.sys.sleep(10)
-       for i in xrange(100): Window.QHandle(i)
-       # END HORRID HACK
-       
        # best not do move the cursor
        # Window.SetMouseCoords(*[i/2 for i in Window.GetScreenSize()])
        
index 6ea890879ddb8bda9ab756157378b7a4b8e0b3ba..f99a949fbae3c32910806a8ea13f15dc5b1df8bc 100644 (file)
@@ -2,14 +2,14 @@
 
 """
 Name: 'Wavefront (.obj)...'
-Blender: 243
+Blender: 248
 Group: 'Export'
 Tooltip: 'Save a Wavefront OBJ File'
 """
 
 __author__ = "Campbell Barton, Jiri Hnidek"
-__url__ = ['www.blender.org', 'blenderartists.org']
-__version__ = "1.1"
+__url__ = ['http://wiki.blender.org/index.php/Scripts/Manual/Export/wavefront_obj', 'www.blender.org', 'blenderartists.org']
+__version__ = "1.2"
 
 __bpydoc__ = """\
 This script is an exporter to OBJ file format.
@@ -535,23 +535,31 @@ def write_ui(filename):
        if not BPyMessages.Warning_SaveOver(filename):
                return
        
-       EXPORT_APPLY_MODIFIERS = Draw.Create(1)
+       global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\
+               EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\
+               EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\
+               EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\
+               EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER
+       
+       EXPORT_APPLY_MODIFIERS = Draw.Create(0)
        EXPORT_ROTX90 = Draw.Create(1)
        EXPORT_TRI = Draw.Create(0)
        EXPORT_EDGES = Draw.Create(1)
        EXPORT_NORMALS = Draw.Create(0)
-       EXPORT_NORMALS_HQ = Draw.Create(1)
+       EXPORT_NORMALS_HQ = Draw.Create(0)
        EXPORT_UV = Draw.Create(1)
        EXPORT_MTL = Draw.Create(1)
        EXPORT_SEL_ONLY = Draw.Create(1)
        EXPORT_ALL_SCENES = Draw.Create(0)
        EXPORT_ANIMATION = Draw.Create(0)
        EXPORT_COPY_IMAGES = Draw.Create(0)
-       EXPORT_BLEN_OBS = Draw.Create(1)
+       EXPORT_BLEN_OBS = Draw.Create(0)
        EXPORT_GROUP_BY_OB = Draw.Create(0)
        EXPORT_GROUP_BY_MAT = Draw.Create(0)
        EXPORT_KEEP_VERT_ORDER = Draw.Create(1)
        
+       # Old UI
+       '''
        # removed too many options are bad!
        
        # Get USER Options
@@ -580,12 +588,124 @@ def write_ui(filename):
        
        if not Draw.PupBlock('Export...', pup_block):
                return
+       '''
+       
+       # BEGIN ALTERNATIVE UI *******************
+       if True: 
+               
+               EVENT_NONE = 0
+               EVENT_EXIT = 1
+               EVENT_REDRAW = 2
+               EVENT_EXPORT = 3
+               
+               GLOBALS = {}
+               GLOBALS['EVENT'] = EVENT_REDRAW
+               #GLOBALS['MOUSE'] = Window.GetMouseCoords()
+               GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
+               
+               def obj_ui_set_event(e,v):
+                       GLOBALS['EVENT'] = e
+               
+               def do_split(e,v):
+                       global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER
+                       if EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val:
+                               EXPORT_KEEP_VERT_ORDER.val = 0
+                       else:
+                               EXPORT_KEEP_VERT_ORDER.val = 1
+                       
+               def do_vertorder(e,v):
+                       global EXPORT_BLEN_OBS, EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_APPLY_MODIFIERS, KEEP_VERT_ORDER
+                       if EXPORT_KEEP_VERT_ORDER.val:
+                               EXPORT_BLEN_OBS.val = EXPORT_GROUP_BY_OB.val = EXPORT_GROUP_BY_MAT.val = EXPORT_APPLY_MODIFIERS.val = 0
+                       else:
+                               if not (EXPORT_BLEN_OBS.val or EXPORT_GROUP_BY_OB.val or EXPORT_GROUP_BY_MAT.val or EXPORT_APPLY_MODIFIERS.val):
+                                       EXPORT_KEEP_VERT_ORDER.val = 1
+                       
+               def do_help(e,v):
+                       url = __url__[0]
+                       print 'Trying to open web browser with documentation at this address...'
+                       print '\t' + url
+                       
+                       try:
+                               import webbrowser
+                               webbrowser.open(url)
+                       except:
+                               print '...could not open a browser window.'
+               
+               def obj_ui():
+                       ui_x, ui_y = GLOBALS['MOUSE']
+                       
+                       # Center based on overall pup size
+                       ui_x -= 165
+                       ui_y -= 110
+                       
+                       global EXPORT_APPLY_MODIFIERS, EXPORT_ROTX90, EXPORT_TRI, EXPORT_EDGES,\
+                               EXPORT_NORMALS, EXPORT_NORMALS_HQ, EXPORT_UV,\
+                               EXPORT_MTL, EXPORT_SEL_ONLY, EXPORT_ALL_SCENES,\
+                               EXPORT_ANIMATION, EXPORT_COPY_IMAGES, EXPORT_BLEN_OBS,\
+                               EXPORT_GROUP_BY_OB, EXPORT_GROUP_BY_MAT, EXPORT_KEEP_VERT_ORDER
+
+                       Draw.Label('Context...', ui_x+9, ui_y+209, 220, 20)
+                       Draw.BeginAlign()
+                       EXPORT_SEL_ONLY = Draw.Toggle('Selection Only', EVENT_NONE, ui_x+9, ui_y+189, 110, 20, EXPORT_SEL_ONLY.val, 'Only export objects in visible selection. Else export whole scene.')
+                       EXPORT_ALL_SCENES = Draw.Toggle('All Scenes', EVENT_NONE, ui_x+119, ui_y+189, 110, 20, EXPORT_ALL_SCENES.val, 'Each scene as a separate OBJ file.')
+                       EXPORT_ANIMATION = Draw.Toggle('Animation', EVENT_NONE, ui_x+229, ui_y+189, 110, 20, EXPORT_ANIMATION.val, 'Each frame as a numbered OBJ file.')
+                       Draw.EndAlign()
+                       
+                       
+                       Draw.Label('Output Options...', ui_x+9, ui_y+159, 220, 20)
+                       Draw.BeginAlign()
+                       EXPORT_APPLY_MODIFIERS = Draw.Toggle('Apply Modifiers', EVENT_REDRAW, ui_x+9, ui_y+140, 110, 20, EXPORT_APPLY_MODIFIERS.val, 'Use transformed mesh data from each object. May break vert order for morph targets.', do_split)
+                       EXPORT_ROTX90 = Draw.Toggle('Rotate X90', EVENT_NONE, ui_x+119, ui_y+140, 110, 20, EXPORT_ROTX90.val, 'Rotate on export so Blenders UP is translated into OBJs UP')
+                       EXPORT_COPY_IMAGES = Draw.Toggle('Copy Images', EVENT_NONE, ui_x+229, ui_y+140, 110, 20, EXPORT_COPY_IMAGES.val, 'Copy image files to the export directory, never overwrite.')
+                       Draw.EndAlign()
+                       
+                       
+                       Draw.Label('Export...', ui_x+9, ui_y+109, 220, 20)
+                       Draw.BeginAlign()
+                       EXPORT_EDGES = Draw.Toggle('Edges', EVENT_NONE, ui_x+9, ui_y+90, 50, 20, EXPORT_EDGES.val, 'Edges not connected to faces.')
+                       EXPORT_TRI = Draw.Toggle('Triangulate', EVENT_NONE, ui_x+59, ui_y+90, 70, 20, EXPORT_TRI.val, 'Triangulate quads.')
+                       Draw.EndAlign()
+                       Draw.BeginAlign()
+                       EXPORT_MTL = Draw.Toggle('Materials', EVENT_NONE, ui_x+139, ui_y+90, 70, 20, EXPORT_MTL.val, 'Write a separate MTL file with the OBJ.')
+                       EXPORT_UV = Draw.Toggle('UVs', EVENT_NONE, ui_x+209, ui_y+90, 31, 20, EXPORT_UV.val, 'Export texface UV coords.')
+                       Draw.EndAlign()
+                       Draw.BeginAlign()
+                       EXPORT_NORMALS = Draw.Toggle('Normals', EVENT_NONE, ui_x+250, ui_y+90, 59, 20, EXPORT_NORMALS.val, 'Export vertex normal data (Ignored on import).')
+                       EXPORT_NORMALS_HQ = Draw.Toggle('HQ', EVENT_NONE, ui_x+309, ui_y+90, 31, 20, EXPORT_NORMALS_HQ.val, 'Calculate high quality normals for rendering.')
+                       Draw.EndAlign()
+                       
+                       
+                       Draw.Label('Blender Objects as OBJ:', ui_x+9, ui_y+59, 220, 20)
+                       Draw.BeginAlign()
+                       EXPORT_BLEN_OBS = Draw.Toggle('Objects', EVENT_REDRAW, ui_x+9, ui_y+40, 60, 20, EXPORT_BLEN_OBS.val, 'Export blender objects as "OBJ objects".', do_split)
+                       EXPORT_GROUP_BY_OB = Draw.Toggle('Groups', EVENT_REDRAW, ui_x+69, ui_y+39, 60, 20, EXPORT_GROUP_BY_OB.val, 'Export blender objects as "OBJ Groups".', do_split)
+                       EXPORT_GROUP_BY_MAT = Draw.Toggle('Material Groups', EVENT_REDRAW, ui_x+129, ui_y+39, 100, 20, EXPORT_GROUP_BY_MAT.val, 'Group by materials.', do_split)
+                       Draw.EndAlign()
+                       
+                       EXPORT_KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+239, ui_y+39, 100, 20, EXPORT_KEEP_VERT_ORDER.val, 'Keep vert and face order, disables some other options. Use for morph targets.', do_vertorder)
+                       
+                       Draw.BeginAlign()
+                       Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 20, 'Load the wiki page for this script', do_help)
+                       Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 20, '', obj_ui_set_event)
+                       Draw.PushButton('Export', EVENT_EXPORT, ui_x+229, ui_y+9, 110, 20, 'Export with these settings', obj_ui_set_event)
+                       Draw.EndAlign()
+
+               
+               # hack so the toggle buttons redraw. this is not nice at all
+               while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_EXPORT):
+                       Draw.UIBlock(obj_ui)
+               
+               if GLOBALS['EVENT'] != EVENT_EXPORT:
+                       return
+               
+       # END ALTERNATIVE UI *********************
+       
        
        if EXPORT_KEEP_VERT_ORDER.val:
                EXPORT_BLEN_OBS.val = False
                EXPORT_GROUP_BY_OB.val = False
                EXPORT_GROUP_BY_MAT.val = False
-               EXPORT_GROUP_BY_MAT.val = False
                EXPORT_APPLY_MODIFIERS.val = False
        
        Window.EditMode(0)
index 696dfd3ca2b48f5395224c4e1e7d93ce76fbb630..b27e266f368aa5c9ccd0d7e5614360fc83d2f179 100644 (file)
@@ -448,11 +448,19 @@ def parse_help_info(script):
 
 def parse_script_line(l):
 
+       tip = 'No tooltip'
        try:
                pieces = l.split("'")
                name = pieces[1].replace('...','')
-               version, fname, userdir = pieces[2].strip().split()
-               tip = pieces[3]
+               data = pieces[2].strip().split()
+               version = data[0]
+               userdir = data[-1]
+               fname = data[1]
+               i = 1
+               while not fname.endswith('.py'):
+                       i += 1
+                       fname = '%s %s' % (fname, data[i])
+               if len(pieces) > 3: tip = pieces[3]
        except:
                return None
 
index d9c7101c98216c8ffeec354d6944d80c8974bbe9..187cba964bcb2a8f6dcb637be396d43b0e08a5b7 100644 (file)
@@ -128,13 +128,13 @@ hotkeys={
 ['RMB hold down', 'Popup menu'],
 ['Alt-RMB', 'Object Mode :Select but in a displayed list of objects located under the mouse cursor'],
 ['Alt-RMB', 'Edit Mode: Select EDGES LOOP '],
-['Alt+Ctrl-RMB', 'Edit Mode: Select FACES LOOP'],      
-['Alt+Ctrl-RMB', 'UV Image Editor: Select face'],
+['Alt-Ctrl-RMB', 'Edit Mode: Select FACES LOOP'],      
+['Alt-Ctrl-RMB', 'UV Image Editor: Select face'],
 ['Shift-RMB', 'Add/subtract to/from selection'],
 ['Wheel', 'Zoom view'],
 ['Transformations:', ''],
 ['Drag+Ctrl', 'Step adjustment'],
-['Drag+Ctrl+Shift', 'Small step adjustment (Transform Widget : first select the axe or axes with LBM alone)'],
+['Drag+Ctrl-Shift', 'Small step adjustment (Transform Widget : first select the axe or axes with LBM alone)'],
 ['Drag+Shift', 'Fine adjustment (Transform Widget : first select the axe or axes with LBM alone)'],
 ['LMB', 'Confirm transformation'],
 ['MMB', 'Toggle optional transform feature'],
@@ -232,7 +232,7 @@ hotkeys={
 ['Home', 'OutLiner Windows, Show hierarchy'],
 ['PgUp', 'Edit Mode and Proportionnal Editing Tools, increase influence'],
 ['PgUp', 'Strip Editor, Move Down'],
-['PgUn', 'TimeLine: Jump to next marker'],
+['PgUp', 'TimeLine: Jump to next marker'],
 ['PgUp', 'IPO: Select next keyframe'],
 ['Ctrl-PgUp', 'IPO: Select and jump to next keyframe'],
 ['Ctrl-PgUn', 'TimeLine: Jump to next key'],   
@@ -250,7 +250,6 @@ hotkeys={
 ['Alt-Up', 'Blender in Fullscreen mode'],
 ['Ctrl-Left', 'Previous screen'],
 ['Ctrl-Right', 'Next screen'],
-['Ctrl-Alt-C', 'Object Mode : Add  Constraint'],
 ['Ctrl-Down', 'Maximize window toggle'],
 ['Ctrl-Up', 'Maximize window toggle'],
 ['Shift-Arrow', 'Toggle first frame/ last frame'],
@@ -271,6 +270,7 @@ hotkeys={
 ['Ctrl-ALT-A', '3D-View: Armature Edit mode, align selected bones to active bone'],
 ['Shift-A', 'Sequencer: Add menu'],
 ['Shift-A', '3D-View: Add menu'],
+['Shift-A', 'Sculpt Mode: Keep the brush center anchored to the initial location'],
 ['Shift-ALT-A', 'Play animation in all windows'],
 ['Shift-CTRL-A', 'Apply lattice / Make dupliverts real'],
 ['Shift-CTRL-A', 'Apply Deform '],
@@ -280,13 +280,13 @@ hotkeys={
 "B":[ 
 ['B', 'Border select'],
 ['BB', 'Circle select'],
-['Alt+B', 'Object Mode: Select visible view section in 3D space'],
+['Alt-B', 'Object Mode: Select visible view section in 3D space'],
 ['Shift-B', 'Set render border (in active camera view)'],
-['Ctrl-Alt+B', 'Object Mode: in 3D view, Bake (on an image in the uv editor window) the selected Meshes'], #243
-['Ctrl-Alt+B', 'Object Mode: in 3D view, Bake Full render of selected Meshes'],         #243
-['Ctrl-Alt+B', 'Object Mode: in 3D view, Bake Ambient Occlusion of selected Meshes'],  #243    
-['Ctrl-Alt+B', 'Object Mode: in 3D view, Bake Normals of the selected Meshes'],         #243
-['Ctrl-Alt+B', 'Object Mode: in 3D view, Bake Texture Only of selected Meshes'],       #243
+['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake (on an image in the uv editor window) the selected Meshes'], #243
+['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Full render of selected Meshes'],         #243
+['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Ambient Occlusion of selected Meshes'],  #243    
+['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Normals of the selected Meshes'],         #243
+['Ctrl-Alt-B', 'Object Mode: in 3D view, Bake Texture Only of selected Meshes'],       #243
 ['.', '...']
 ],
 
@@ -300,11 +300,12 @@ hotkeys={
 ['C', 'NODE window : Show cyclic referencies'], #243                           
 ['Alt-C', 'Object Mode: Convert menu'],
 ['Alt-C', 'Text Editor: Copy '],
+['Ctrl-Alt-C', 'Object Mode : Add  Constraint'],
 ['Ctrl-Shift-C', 'Text Editor: Copy selection to clipboard'],
 ['Ctrl-C', 'Copy menu (Copy properties of active to selected objects)'],
 ['Ctrl-C', 'UV Image Editor: Stick UVs to mesh vertex'],
 ['Ctrl-C','ARMATURE : posemode, Copy pose attributes'],
-['Ctrl+Alt-C',' ARMATURE : posemode, add constraint to new empty object.'],
+['Ctrl-Alt-C',' ARMATURE : posemode, add constraint to new empty object.'],
 ['Shift-C', 'Center and zoom view on selected objects'],
 ['Shift-C', 'UV Image Editor: Stick local UVs to mesh vertex'],
 ['.', '...']
@@ -494,8 +495,8 @@ hotkeys={
 "P":[ 
 ['P', 'Object Mode: Start realtime engine'],
 ['P', 'Edit mode: Seperate vertices to new object'],
-['shift-P', 'Edit mode: Push-Pull'],
-['shift-P', 'Object mode: Add a preview window in the D window'],
+['Shift-P', 'Edit mode: Push-Pull'],
+['Shift-P', 'Object mode: Add a preview window in the D window'],
 ['P', 'UV Image Editor:  Pin selected vertices. Pinned vertices will stay in place on the UV editor when executing an LSCM unwrap.'],
 ['Alt-P', 'Clear parent relationship'],
 ['Alt-P', 'UV Image Editor: Unpin UVs'],
@@ -553,6 +554,7 @@ hotkeys={
 ['Alt-Shift-S,','Text editor : Select the line '],
 ['Ctrl-Alt-G', 'MANIPULATOR (transform widget): set in Size Mode'],
 ['Shift-S', 'Cursor/Grid snap menu'],
+['Shift-S', 'Sculpt Mode: Smooth Stroke.'],
 ['Shift-S+1', 'VIDEO SEQUENCE editor : jump to the current frame '],
 ['.', '...']
 ],
@@ -568,7 +570,7 @@ hotkeys={
 ['Alt-T', 'Clear tracking of object'],
 ['Ctrl-T', 'Make selected object track active object'],
 ['Ctrl-T', 'Edit Mode: Convert to triangles'],
-['Ctrl-ALT-T', 'Benchmark'],
+['Ctrl-Alt-T', 'Benchmark'],
 ['.', '...']
 ],
 
@@ -606,9 +608,18 @@ hotkeys={
 "W":[ 
 ['W', 'Edit Mode: Specials menu'],
 ['W', 'Edit Mode: Specials menu, ARMATURE 1 Subdivide'],
-['W', 'Edit Mode: Specials menu, ARMATURE 2 Flip Left-Right Name'],
+['W', 'Edit Mode: Specials menu, ARMATURE 2 Subdivide Multi'],
+['W', 'Edit Mode: Specials menu, ARMATURE 3 Switch Direction'],
+['W', 'Edit Mode: Specials menu, ARMATURE 4 Flip Left-Right Name'],
+['W', 'Edit Mode: Specials menu, ARMATURE 5 AutoName Left-Right'],
+['W', 'Edit Mode: Specials menu, ARMATURE 6 AutoName Front-Back'],
+['W', 'Edit Mode: Specials menu, ARMATURE 7 AutoName Top-Bottom'],
 ['W', 'Edit Mode: Specials menu, CURVE 1 Subdivide'],
 ['W', 'Edit Mode: Specials menu, CURVE 2 Swich Direction'],
+['W', 'Edit Mode: Specials menu, CURVE 3 Set Goal Weight'],
+['W', 'Edit Mode: Specials menu, CURVE 4 Set Radius'],
+['W', 'Edit Mode: Specials menu, CURVE 5 Smooth'],
+['W', 'Edit Mode: Specials menu, CURVE 6 Smooth Radius'],
 ['W', 'Edit Mode: Specials menu, MESH 1 Subdivide'],
 ['W', 'Edit Mode: Specials menu, MESH 2 Subdivide Multi'],
 ['W', 'Edit Mode: Specials menu, MESH 3 Subdivide Multi Fractal'],
@@ -636,7 +647,6 @@ hotkeys={
 ['WY', 'UV Image Editor: Weld/Align Y axis'],
 ['Ctrl-W', 'Save current file'] ,
 ['Shift-W', 'Warp/bend selected vertices around cursor'],
-['alt-W', 'Export in videoscape format'],
 ['.', '...']
  ],
 
index 6ddfb867a36186232dc28194027c92c87534562f..b7bdd54fe6de1dfa3d78e8f1c6e90514b5cfba12 100644 (file)
@@ -2,14 +2,14 @@
  
 """
 Name: 'Wavefront (.obj)...'
-Blender: 242
+Blender: 248
 Group: 'Import'
 Tooltip: 'Load a Wavefront OBJ File, Shift: batch import all dir.'
 """
 
 __author__= "Campbell Barton", "Jiri Hnidek"
-__url__= ["blender.org", "blenderartists.org"]
-__version__= "2.0"
+__url__= ['http://wiki.blender.org/index.php/Scripts/Manual/Import/wavefront_obj', 'blender.org', 'blenderartists.org']
+__version__= "2.1"
 
 __bpydoc__= """\
 This script imports a Wavefront OBJ files to Blender.
@@ -756,19 +756,22 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
        if BPyMessages.Error_NoFile(filepath):
                return
        
+       global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, KEEP_VERT_ORDER
        
        CREATE_SMOOTH_GROUPS= Draw.Create(0)
        CREATE_FGONS= Draw.Create(1)
        CREATE_EDGES= Draw.Create(1)
-       SPLIT_OBJECTS= Draw.Create(1)
-       SPLIT_GROUPS= Draw.Create(1)
-       SPLIT_MATERIALS= Draw.Create(1)
-       KEEP_VERT_ORDER= Draw.Create(1)
+       SPLIT_OBJECTS= Draw.Create(0)
+       SPLIT_GROUPS= Draw.Create(0)
+       SPLIT_MATERIALS= Draw.Create(0)
        CLAMP_SIZE= Draw.Create(10.0)
        IMAGE_SEARCH= Draw.Create(1)
+       KEEP_VERT_ORDER= Draw.Create(1)
        
        
        # Get USER Options
+       # Note, Works but not pretty, instead use a more complicated GUI
+       '''
        pup_block= [\
        'Import...',\
        ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\
@@ -791,6 +794,102 @@ def load_obj_ui(filepath, BATCH_LOAD= False):
                SPLIT_OBJECTS.val = False
                SPLIT_GROUPS.val = False
                SPLIT_MATERIALS.val = False
+       '''
+       
+       
+       
+       # BEGIN ALTERNATIVE UI *******************
+       if True: 
+               
+               EVENT_NONE = 0
+               EVENT_EXIT = 1
+               EVENT_REDRAW = 2
+               EVENT_IMPORT = 3
+               
+               GLOBALS = {}
+               GLOBALS['EVENT'] = EVENT_REDRAW
+               #GLOBALS['MOUSE'] = Window.GetMouseCoords()
+               GLOBALS['MOUSE'] = [i/2 for i in Window.GetScreenSize()]
+               
+               def obj_ui_set_event(e,v):
+                       GLOBALS['EVENT'] = e
+               
+               def do_split(e,v):
+                       global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER
+                       if SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val:
+                               KEEP_VERT_ORDER.val = 0
+                       else:
+                               KEEP_VERT_ORDER.val = 1
+                       
+               def do_vertorder(e,v):
+                       global SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, KEEP_VERT_ORDER
+                       if KEEP_VERT_ORDER.val:
+                               SPLIT_OBJECTS.val = SPLIT_GROUPS.val = SPLIT_MATERIALS.val = 0
+                       else:
+                               if not (SPLIT_OBJECTS.val or SPLIT_GROUPS.val or SPLIT_MATERIALS.val):
+                                       KEEP_VERT_ORDER.val = 1
+                       
+               def do_help(e,v):
+                       url = __url__[0]
+                       print 'Trying to open web browser with documentation at this address...'
+                       print '\t' + url
+                       
+                       try:
+                               import webbrowser
+                               webbrowser.open(url)
+                       except:
+                               print '...could not open a browser window.'
+               
+               def obj_ui():
+                       ui_x, ui_y = GLOBALS['MOUSE']
+                       
+                       # Center based on overall pup size
+                       ui_x -= 165
+                       ui_y -= 90
+                       
+                       global CREATE_SMOOTH_GROUPS, CREATE_FGONS, CREATE_EDGES, SPLIT_OBJECTS, SPLIT_GROUPS, SPLIT_MATERIALS, CLAMP_SIZE, IMAGE_SEARCH, KEEP_VERT_ORDER
+                       
+                       Draw.Label('Import...', ui_x+9, ui_y+159, 220, 21)
+                       Draw.BeginAlign()
+                       CREATE_SMOOTH_GROUPS = Draw.Toggle('Smooth Groups', EVENT_NONE, ui_x+9, ui_y+139, 110, 20, CREATE_SMOOTH_GROUPS.val, 'Surround smooth groups by sharp edges')
+                       CREATE_FGONS = Draw.Toggle('NGons as FGons', EVENT_NONE, ui_x+119, ui_y+139, 110, 20, CREATE_FGONS.val, 'Import faces with more then 4 verts as fgons')
+                       CREATE_EDGES = Draw.Toggle('Lines as Edges', EVENT_NONE, ui_x+229, ui_y+139, 110, 20, CREATE_EDGES.val, 'Import lines and faces with 2 verts as edges')
+                       Draw.EndAlign()
+                       
+                       Draw.Label('Separate objects by OBJ...', ui_x+9, ui_y+110, 220, 20)
+                       Draw.BeginAlign()
+                       SPLIT_OBJECTS = Draw.Toggle('Object', EVENT_REDRAW, ui_x+9, ui_y+89, 70, 21, SPLIT_OBJECTS.val, 'Import OBJ Objects into Blender Objects', do_split)
+                       SPLIT_GROUPS = Draw.Toggle('Group', EVENT_REDRAW, ui_x+79, ui_y+89, 70, 21, SPLIT_GROUPS.val, 'Import OBJ Groups into Blender Objects', do_split)
+                       SPLIT_MATERIALS = Draw.Toggle('Material', EVENT_REDRAW, ui_x+149, ui_y+89, 70, 21, SPLIT_MATERIALS.val, 'Import each material into a seperate mesh (Avoids > 16 per mesh error)', do_split)
+                       Draw.EndAlign()
+                       
+                       # Only used for user feedback
+                       KEEP_VERT_ORDER = Draw.Toggle('Keep Vert Order', EVENT_REDRAW, ui_x+229, ui_y+89, 110, 21, KEEP_VERT_ORDER.val, 'Keep vert and face order, disables split options, enable for morph targets', do_vertorder)
+                       
+                       Draw.Label('Options...', ui_x+9, ui_y+60, 211, 20)
+                       CLAMP_SIZE = Draw.Number('Clamp Scale: ', EVENT_NONE, ui_x+9, ui_y+39, 211, 21, CLAMP_SIZE.val, 0.0, 1000.0, 'Clamp the size to this maximum (Zero to Disable)')
+                       IMAGE_SEARCH = Draw.Toggle('Image Search', EVENT_NONE, ui_x+229, ui_y+39, 110, 21, IMAGE_SEARCH.val, 'Search subdirs for any assosiated images (Warning, may be slow)')
+                       Draw.BeginAlign()
+                       Draw.PushButton('Online Help', EVENT_REDRAW, ui_x+9, ui_y+9, 110, 21, 'Load the wiki page for this script', do_help)
+                       Draw.PushButton('Cancel', EVENT_EXIT, ui_x+119, ui_y+9, 110, 21, '', obj_ui_set_event)
+                       Draw.PushButton('Import', EVENT_IMPORT, ui_x+229, ui_y+9, 110, 21, 'Import with these settings', obj_ui_set_event)
+                       Draw.EndAlign()
+                       
+               
+               # hack so the toggle buttons redraw. this is not nice at all
+               while GLOBALS['EVENT'] not in (EVENT_EXIT, EVENT_IMPORT):
+                       Draw.UIBlock(obj_ui)
+               
+               if GLOBALS['EVENT'] != EVENT_IMPORT:
+                       return
+               
+       # END ALTERNATIVE UI *********************
+       
+       
+       
+       
+       
+       
        
        Window.WaitCursor(1)
        
diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py
new file mode 100755 (executable)
index 0000000..e934d06
--- /dev/null
@@ -0,0 +1,1938 @@
+#!BPY
+"""
+Name: 'X3D & VRML97 (.x3d / wrl)...'
+Blender: 248
+Group: 'Import'
+Tooltip: 'Load an X3D or VRML97 file'
+"""
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# (C) Copyright 2008 Paravizion
+# Written by Campbell Barton aka Ideasman42
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+__author__ = "Campbell Barton"
+__url__ = ['www.blender.org', 'blenderartists.org', 'http://wiki.blender.org/index.php/Scripts/Manual/Import/X3D_VRML97']
+__version__ = "0.1"
+
+__bpydoc__ = """\
+This script is an importer for the X3D and VRML97 file formats.
+"""
+
+# This should work without a blender at all
+try:
+       from Blender.sys import exists
+except:
+       from os.path import exists
+
+def baseName(path):
+       return path.split('/')[-1].split('\\')[-1]
+
+def dirName(path):
+       return path[:-len(baseName(path))]
+
+# notes
+# transform are relative 
+# order dosnt matter for loc/size/rot
+# right handed rotation
+# angles are in radians
+# rotation first defines axis then ammount in deg
+
+
+
+# =============================== VRML Spesific
+
+
+def vrmlFormat(data):
+       '''
+       Keep this as a valid vrml file, but format in a way we can pradict.
+       '''
+       # Strip all commends - # not in strings - warning multiline strings are ignored.
+       def strip_comment(l):
+               #l = ' '.join(l.split())
+               l = l.strip()
+               
+               if l.startswith('#'):
+                       return ''
+               
+               i = l.find('#')
+               
+               if i==-1:
+                       return l
+               
+               # Most cases accounted for! if we have a comment at the end of the line do this...
+               j = l.find('"')
+               
+               if j == -1: # simple no strings
+                       return l[:i].strip()
+               
+               q = False
+               for i,c in enumerate(l):
+                       if c == '"':
+                               q = not q # invert
+                       
+                       elif c == '#':
+                               if q==False:
+                                       return l[:i-1]
+               
+               return l
+       
+       data = '\n'.join([strip_comment(l) for l in data.split('\n') ]) # remove all whitespace
+       
+               
+       # Bad, dont take strings into account
+       '''
+       data = data.replace('#', '\n#')
+       data = '\n'.join([ll for l in data.split('\n') for ll in (l.strip(),) if not ll.startswith('#')]) # remove all whitespace
+       '''
+       data = data.replace('{', '\n{\n')
+       data = data.replace('}', '\n}\n')
+       data = data.replace('[', '\n[\n')
+       data = data.replace(']', '\n]\n')
+       data = data.replace(',', ' , ') # make sure comma's seperate
+       
+       # More annoying obscure cases where USE or DEF are placed on a newline
+       # data = data.replace('\nDEF ', ' DEF ')
+       # data = data.replace('\nUSE ', ' USE ')
+       
+       data = '\n'.join([' '.join(l.split()) for l in data.split('\n')]) # remove all whitespace
+       
+       # Better to parse the file accounting for multiline arrays
+       '''
+       data = data.replace(',\n', ' , ') # remove line endings with commas
+       data = data.replace(']', '\n]\n') # very very annoying - but some comma's are at the end of the list, must run this again.
+       '''
+       
+       return [l for l in data.split('\n') if l]
+
+NODE_NORMAL = 1 # {}
+NODE_ARRAY = 2 # []
+NODE_REFERENCE = 3 # USE foobar
+
+lines = []
+
+def getNodePreText(i, words):
+       # print lines[i]
+       use_node = False
+       while len(words) < 5:
+               
+               if i>=len(lines):
+                       break
+               elif lines[i]=='{':
+                       # words.append(lines[i]) # no need
+                       # print "OK"
+                       return NODE_NORMAL, i+1
+               elif lines[i].count('"') % 2 != 0: # odd number of quotes? - part of a string.
+                       # print 'ISSTRING'
+                       break
+               else:
+                       new_words = lines[i].split()
+                       if 'USE' in new_words:
+                               use_node = True
+                       
+                       words.extend(new_words)
+                       i += 1
+               
+               # Check for USE node - no {
+               # USE #id - should always be on the same line.
+               if use_node:
+                       # print 'LINE', i, words[:words.index('USE')+2]
+                       words[:] = words[:words.index('USE')+2]
+                       if lines[i] == '{' and lines[i+1] == '}':
+                               # USE sometimes has {} after it anyway
+                               i+=2 
+                       return NODE_REFERENCE, i
+               
+       # print "error value!!!", words
+       return 0, -1
+
+def is_nodeline(i, words):
+       
+       if not lines[i][0].isalpha():
+               return 0, 0
+       
+       # Simple "var [" type
+       if lines[i+1] == '[':
+               if lines[i].count('"') % 2 == 0:
+                       words[:] = lines[i].split()
+                       return NODE_ARRAY, i+2
+       
+       node_type, new_i = getNodePreText(i, words)
+       
+       if not node_type:
+               return 0, 0
+       
+       # Ok, we have a { after some values
+       # Check the values are not fields
+       for i, val in enumerate(words):
+               if i != 0 and words[i-1] in ('DEF', 'USE'):
+                       # ignore anything after DEF, it is a ID and can contain any chars.
+                       pass
+               elif val[0].isalpha() and val not in ('TRUE', 'FALSE'):
+                       pass
+               else:
+                       # There is a number in one of the values, therefor we are not a node.
+                       return 0, 0
+       
+       #if node_type==NODE_REFERENCE:
+       #       print words, "REF_!!!!!!!"
+       return node_type, new_i
+
+def is_numline(i):
+       '''
+       Does this line start with a number?
+       '''
+       l = lines[i]
+       line_end = len(l)-1
+       line_end_new = l.find(' ') # comma's always have a space before them
+       
+       if line_end_new != -1:
+               line_end = line_end_new
+       
+       try:
+               float(l[:line_end]) # works for a float or int
+               return True
+       except:
+               return False
+
+class vrmlNode(object):
+       __slots__ = 'id', 'fields', 'node_type', 'parent', 'children', 'parent', 'array_data', 'reference', 'lineno', 'filename', 'blendObject', 'DEF_NAMESPACE', 'FIELD_NAMESPACE', 'x3dNode'
+       def __init__(self, parent, node_type, lineno):
+               self.id = None
+               self.node_type = node_type
+               self.parent = parent
+               self.blendObject = None
+               self.x3dNode = None # for x3d import only
+               if parent:
+                       parent.children.append(self)
+               
+               self.lineno = lineno
+               
+               # This is only set from the root nodes.
+               # Having a filename also denotes a root node
+               self.filename = None
+               
+               # Store in the root node because each inline file needs its own root node and its own namespace
+               self.DEF_NAMESPACE = None 
+               self.FIELD_NAMESPACE = None
+               
+               self.reference = None
+               
+               if node_type==NODE_REFERENCE:
+                       # For references, only the parent and ID are needed
+                       # the reference its self is assigned on parsing
+                       return 
+               
+               self.fields = [] # fields have no order, in some cases rool level values are not unique so dont use a dict
+               self.children = []
+               self.array_data = [] # use for arrays of data - should only be for NODE_ARRAY types
+               
+       
+       # Only available from the root node
+       def getFieldDict(self):
+               if self.FIELD_NAMESPACE != None:
+                       return self.FIELD_NAMESPACE
+               else:
+                       return self.parent.getFieldDict()
+       
+       def getDefDict(self):
+               if self.DEF_NAMESPACE != None:
+                       return self.DEF_NAMESPACE
+               else:
+                       return self.parent.getDefDict()
+       
+       def setRoot(self, filename):
+               self.filename = filename
+               self.FIELD_NAMESPACE =  {}
+               self.DEF_NAMESPACE=             {}
+               
+       def getFilename(self):
+               if self.filename:
+                       return self.filename
+               elif self.parent:
+                       return self.parent.getFilename()
+               else:
+                       return None
+       
+       def getRealNode(self):
+               if self.reference:
+                       return self.reference
+               else:
+                       return self
+       
+       def getSpec(self):
+               self_real = self.getRealNode()
+               try:
+                       return self_real.id[-1] # its possible this node has no spec
+               except:
+                       return None
+       
+       def getDefName(self):
+               self_real = self.getRealNode()
+               
+               if 'DEF' in self_real.id:
+                       # print self_real.id
+                       return self_real.id[ list(self_real.id).index('DEF')+1 ]
+               else:
+                       return None
+               
+       
+       def getChildrenBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
+               self_real = self.getRealNode()
+               # using getSpec functions allows us to use the spec of USE children that dont have their spec in their ID
+               if type(node_spec) == str:
+                       return [child for child in self_real.children if child.getSpec()==node_spec]
+               else:
+                       # Check inside a list of optional types
+                       return [child for child in self_real.children if child.getSpec() in node_spec]
+       
+       def getChildBySpec(self, node_spec): # spec could be Transform, Shape, Appearance
+               # Use in cases where there is only ever 1 child of this type
+               ls = self.getChildrenBySpec(node_spec)
+               if ls: return ls[0]
+               else: return None
+       
+       def getChildrenByName(self, node_name): # type could be geometry, children, appearance
+               self_real = self.getRealNode()
+               return [child for child in self_real.children if child.id if child.id[0]==node_name]
+       
+       def getChildByName(self, node_name):
+               self_real = self.getRealNode()
+               for child in self_real.children:
+                       if child.id and child.id[0]==node_name: # and child.id[-1]==node_spec:
+                               return child
+       
+       def getSerialized(self, results, ancestry):
+               '''     Return this node and all its children in a flat list '''
+               ancestry = ancestry[:] # always use a copy
+               
+               # self_real = self.getRealNode()
+               
+               results.append((self, tuple(ancestry)))
+               ancestry.append(self)
+               for child in self.getRealNode().children:
+                       if child not in ancestry:
+                               child.getSerialized(results, ancestry)
+               
+               return results
+               
+       def searchNodeTypeID(self, node_spec, results):
+               self_real = self.getRealNode()
+               # print self.lineno, self.id
+               if self_real.id and self_real.id[-1]==node_spec: # use last element, could also be only element
+                       results.append(self_real)
+               for child in self_real.children:
+                       child.searchNodeTypeID(node_spec, results)
+               return results
+       
+       def getFieldName(self, field):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               for f in self_real.fields:
+                       # print f
+                       if f and f[0] == field:
+                               # print '\tfound field', f
+                               
+                               return f[1:]
+               # print '\tfield not found', field
+               return None
+       
+       def getFieldAsInt(self, field, default):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               f = self_real.getFieldName(field)
+               if f==None:     return default
+               if ',' in f: f = f[:f.index(',')] # strip after the comma
+               
+               if len(f) != 1:
+                       print '\t"%s" wrong length for int conversion for field "%s"' % (f, field)
+                       return default
+               
+               try:
+                       return int(f[0])
+               except:
+                       print '\tvalue "%s" could not be used as an int for field "%s"' % (f[0], field)
+                       return default
+       
+       def getFieldAsFloat(self, field, default):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               f = self_real.getFieldName(field)
+               if f==None:     return default
+               if ',' in f: f = f[:f.index(',')] # strip after the comma
+               
+               if len(f) != 1:
+                       print '\t"%s" wrong length for float conversion for field "%s"' % (f, field)
+                       return default
+               
+               try:
+                       return float(f[0])
+               except:
+                       print '\tvalue "%s" could not be used as a float for field "%s"' % (f[0], field)
+                       return default
+       
+       def getFieldAsFloatTuple(self, field, default):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               f = self_real.getFieldName(field)
+               if f==None:     return default
+               # if ',' in f: f = f[:f.index(',')] # strip after the comma
+               
+               if len(f) < 1:
+                       print '"%s" wrong length for float tuple conversion for field "%s"' % (f, field)
+                       return default
+               
+               ret = []
+               for v in f:
+                       if v != ',':
+                               try:            ret.append(float(v))
+                               except:         break # quit of first non float, perhaps its a new field name on the same line? - if so we are going to ignore it :/ TODO
+               # print ret
+               
+               if ret:
+                       return ret
+               if not ret:
+                       print '\tvalue "%s" could not be used as a float tuple for field "%s"' % (f, field)
+                       return default
+       
+       def getFieldAsBool(self, field, default):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               f = self_real.getFieldName(field)
+               if f==None:     return default
+               if ',' in f: f = f[:f.index(',')] # strip after the comma
+               
+               if len(f) != 1:
+                       print '\t"%s" wrong length for bool conversion for field "%s"' % (f, field)
+                       return default
+               
+               if f[0].upper()=='"TRUE"' or f[0].upper()=='TRUE':
+                       return True
+               elif f[0].upper()=='"FALSE"' or f[0].upper()=='FALSE':
+                       return False
+               else:
+                       print '\t"%s" could not be used as a bool for field "%s"' % (f[1], field)
+                       return default
+       
+       def getFieldAsString(self, field, default=None):
+               self_real = self.getRealNode() # incase we're an instance
+               
+               f = self_real.getFieldName(field)
+               if f==None:     return default
+               if len(f) < 1:
+                       print '\t"%s" wrong length for string conversion for field "%s"' % (f, field)
+                       return default
+               
+               if len(f) > 1:
+                       # String may contain spaces
+                       st = ' '.join(f)
+               else:
+                       st = f[0]
+               
+               # X3D HACK 
+               if self.x3dNode: 
+                       return st
+                       
+               if st[0]=='"' and st[-1]=='"':
+                       return st[1:-1]
+               else:
+                       print '\tvalue "%s" could not be used as a string for field "%s"' % (f[0], field)
+                       return default
+       
+       def getFieldAsArray(self, field, group):
+               '''
+               For this parser arrays are children
+               '''
+               self_real = self.getRealNode() # incase we're an instance
+               
+               child_array = None
+               for child in self_real.children:
+                       if child.id and len(child.id) == 1 and child.id[0] == field:
+                               child_array = child
+                               break
+               
+               if child_array==None:
+                       # For x3d, should work ok with vrml too
+                       # for x3d arrays are fields, vrml they are nodes, annoying but not tooo bad.
+                       data_split = self.getFieldName(field)
+                       if not data_split:
+                               return []
+                       array_data = ' '.join(data_split)
+                       if array_data == None:
+                               return []
+                       
+                       array_data = array_data.replace(',', ' ')
+                       data_split = array_data.split()
+                       try:
+                               array_data = [int(val) for val in data_split]
+                       except:
+                               try:
+                                       array_data = [float(val) for val in data_split]
+                               except:
+                                       print '\tWarning, could not parse array data from field'
+                                       array_data = []
+               else:
+                       
+                       # Normal vrml
+                       array_data = child_array.array_data
+               
+               if group==-1 or len(array_data)==0:
+                       return array_data
+               
+               # We want a flat list
+               flat = True
+               for item in array_data:
+                       if type(item) == list:
+                               flat = False
+                               break
+               
+               # make a flat array
+               if flat:
+                       flat_array = array_data # we are alredy flat.
+               else:
+                       flat_array = []
+                       
+                       def extend_flat(ls):
+                               for item in ls:
+                                       if type(item)==list:    extend_flat(item)
+                                       else:                                   flat_array.append(item)
+                       
+                       extend_flat(array_data)
+               
+               
+               # We requested a flat array
+               if group == 0:
+                       return flat_array
+                       
+                       
+               
+               new_array = []
+               sub_array = []
+               
+               for item in flat_array:
+                       sub_array.append(item)
+                       if len(sub_array)==group:
+                               new_array.append(sub_array)
+                               sub_array = []
+               
+               if sub_array:
+                       print '\twarning, array was not aligned to requested grouping', group, 'remaining value', sub_array
+               
+               return new_array
+       
+       def getLevel(self):
+               # Ignore self_real
+               level = 0
+               p = self.parent
+               while p:
+                       level +=1
+                       p = p.parent
+                       if not p: break
+                       
+               return level
+       
+       def __repr__(self):
+               level = self.getLevel()
+               ind = '  ' * level
+               
+               if self.node_type==NODE_REFERENCE:
+                       brackets = ''
+               elif self.node_type==NODE_NORMAL:
+                       brackets = '{}'
+               else:
+                       brackets = '[]'
+               
+               if brackets:
+                       text = ind + brackets[0] + '\n'
+               else:
+                       text = ''
+               
+               text += ind + 'ID: ' + str(self.id) + ' ' + str(level) + ('lineno %d\n' % self.lineno)
+               
+               if self.node_type==NODE_REFERENCE:
+                       return text
+               
+               for item in self.fields:
+                       text += ind + str(item) +'\n'
+               
+               #text += ind + 'ARRAY: ' + str(len(self.array_data)) + ' ' + str(self.array_data) + '\n'
+               text += ind + 'ARRAY: ' + str(len(self.array_data)) + '[...] \n'
+               
+               text += ind + 'CHILDREN: ' + str(len(self.children)) + '\n'
+               for child in self.children:
+                       text += str(child)
+               
+               text += '\n' + ind + brackets[1]
+               
+               return text
+       
+       def parse(self, i):
+               new_i = self.__parse(i)
+               
+               # print self.id, self.getFilename()
+               
+               # If we were an inline then try load the file
+               if self.node_type == NODE_NORMAL and self.getSpec() == 'Inline':
+                       url = self.getFieldAsString('url', None)
+                       
+                       if url != None:
+                               if not exists(url):
+                                       url = dirName(self.getFilename()) + baseName(url)
+                               if not exists(url):
+                                       print '\tWarning: Inline URL could not be found:', url
+                               else:
+                                       if url==self.getFilename(): 
+                                               print '\tWarning: cant Inline yourself recursively:', url
+                                       else:
+                                               
+                                               try:
+                                                       f = open(url, 'rU')
+                                               except:
+                                                       print '\tWarning: cant open the file:', url
+                                                       f = None
+                                               
+                                               if f:
+                                                       # Tricky - inline another VRML
+                                                       print '\tLoading Inline:"%s"...' % url
+                                                       
+                                                       # Watch it! - backup lines
+                                                       lines_old = lines[:]
+                                                       
+                                                       
+                                                       lines[:] = vrmlFormat( f.read() )
+                                                       f.close()
+                                                       
+                                                       lines.insert(0, '{')
+                                                       lines.insert(0, 'root_node____')
+                                                       lines.append('}')
+                                                       
+                                                       child = vrmlNode(self, NODE_NORMAL, -1)
+                                                       child.setRoot(url) # initialized dicts
+                                                       child.parse(0)
+                                                       
+                                                       # Watch it! - restore lines
+                                                       lines[:] = lines_old
+                                       
+               
+               return new_i
+       
+       def __parse(self, i):
+               # print 'parsing at', i,
+               # print i, self.id, self.lineno
+               l = lines[i]
+               
+               if l=='[':
+                       # An anonymous list
+                       self.id = None
+                       i+=1
+               else:
+                       words = []
+                       node_type, new_i = is_nodeline(i, words)
+                       if not node_type: # fail for parsing new node.
+                               raise "error"
+                       
+                       if self.node_type==NODE_REFERENCE:
+                               # Only assign the reference and quit
+                               key = words[words.index('USE')+1]
+                               self.id = (words[0],)
+                               
+                               self.reference = self.getDefDict()[key]
+                               return new_i
+                       
+                       self.id = tuple(words)
+                       
+                       # fill in DEF/USE
+                       key = self.getDefName()
+                       
+                       if key != None:
+                               self.getDefDict()[ key ] = self
+                       
+                       i = new_i
+               
+               # print self.id
+               ok = True
+               while ok:
+                       l = lines[i]
+                       # print '\t', i, l
+                       if l=='':
+                               i+=1
+                               continue 
+                       
+                       if l=='}':
+                               if self.node_type != NODE_NORMAL:
+                                       print 'wrong node ending, expected an } ' + str(i)
+                                       raise ""
+                               ### print "returning", i
+                               return i+1
+                       if l==']':
+                               if self.node_type != NODE_ARRAY:
+                                       print 'wrong node ending, expected a ] ' + str(i)
+                                       raise ""
+                               ### print "returning", i
+                               return i+1
+                               
+                       node_type, new_i = is_nodeline(i, [])
+                       if node_type: # check text\n{
+                               ### print '\t\tgroup', i
+                               child = vrmlNode(self, node_type, i)
+                               i = child.parse(i)
+                               # print child.id, 'YYY'
+                               
+                       elif l=='[': # some files have these anonymous lists
+                               child = vrmlNode(self, NODE_ARRAY, i)
+                               i = child.parse(i)
+                               
+                       elif is_numline(i):
+                               l_split = l.split(',')
+                               
+                               values = None
+                               # See if each item is a float?
+                               
+                               for num_type in (int, float):
+                                       try:
+                                               values = [num_type(v) for v in l_split ]
+                                               break
+                                       except:
+                                               pass
+                                       
+                                       
+                                       try:
+                                               values = [[num_type(v) for v in segment.split()] for segment in l_split ]
+                                               break
+                                       except:
+                                               pass
+                               
+                               if values == None: # dont parse
+                                       values = l_split
+                               
+                               # This should not extend over multiple lines however it is possible
+                               self.array_data.extend( values )
+                               i+=1
+                       else:
+                               words = l.split()
+                               if len(words) > 2 and words[1] == 'USE':
+                                       vrmlNode(self, NODE_REFERENCE, i)
+                               else:
+                                       
+                                       # print "FIELD", i, l
+                                       # 
+                                       #words = l.split()
+                                       ### print '\t\ttag', i
+                                       # this is a tag/
+                                       # print words, i, l
+                                       value = l
+                                       # print i
+                                       # javastrips can exist as values.
+                                       quote_count = l.count('"')
+                                       if quote_count % 2: # odd number?
+                                               # print 'MULTILINE'
+                                               while 1:
+                                                       i+=1
+                                                       l = lines[i]
+                                                       quote_count = l.count('"')
+                                                       if quote_count % 2: # odd number?
+                                                               value += '\n'+ l[:l.rfind('"')]
+                                                               break # assume
+                                                       else:
+                                                               value += '\n'+ l
+                                       
+                                       value_all = value.split()
+                                       
+                                       def iskey(k):
+                                               if k[0] != '"' and k[0].isalpha() and k.upper() not in ('TRUE', 'FALSE'):
+                                                       return True
+                                               return False
+                                       
+                                       def split_fields(value):
+                                               '''
+                                               key 0.0 otherkey 1,2,3 opt1 opt1 0.0
+                                                       -> [key 0.0], [otherkey 1,2,3], [opt1 opt1 0.0]
+                                               '''
+                                               field_list = []
+                                               field_context = []
+                                               
+                                               for j in xrange(len(value)):
+                                                       if iskey(value[j]):
+                                                               if field_context:
+                                                                       # this IS a key but the previous value was not a key, ot it was a defined field.
+                                                                       if (not iskey(field_context[-1])) or ((len(field_context)==3 and field_context[1]=='IS')):
+                                                                               field_list.append(field_context)
+                                                                               field_context = [value[j]]
+                                                                       else:
+                                                                               # The last item was not a value, multiple keys are needed in some cases.
+                                                                               field_context.append(value[j])
+                                                               else:
+                                                                       # Is empty, just add this on
+                                                                       field_context.append(value[j])
+                                                       else:
+                                                               # Add a value to the list
+                                                               field_context.append(value[j])
+                                               
+                                               if field_context:
+                                                       field_list.append(field_context)
+                                               
+                                               return field_list
+                                       
+                                       
+                                       for value in split_fields(value_all):
+                                               # Split 
+                                               
+                                               if value[0]=='field':
+                                                       # field SFFloat creaseAngle 4
+                                                       self.getFieldDict()[value[2]] = value[3:] # skip the first 3 values
+                                               else:
+                                                       # Get referenced field
+                                                       if len(value) >= 3 and value[1]=='IS':
+                                                               try:
+                                                                       value = [ value[0] ] + self.getFieldDict()[ value[2] ]
+                                                               except:
+                                                                       print '\tWarning, field could not be found:', value, 'TODO add support for exposedField'
+                                                                       print '\t', self.getFieldDict()
+                                                                       self.fields.append(value)
+                                                       else:
+                                                               self.fields.append(value)
+                               i+=1
+
+def gzipOpen(path):
+       try: import gzip
+       except: gzip = None
+       
+       data = None
+       if gzip:
+               try: data = gzip.open(path, 'r').read()
+               except: pass
+       else:
+               print '\tNote, gzip module could not be imported, compressed files will fail to load'
+       
+       if data==None:
+               try:    data = open(path, 'rU').read()
+               except: pass
+       
+       return data
+
+def vrml_parse(path):
+       '''
+       Sets up the root node and returns it so load_web3d() can deal with the blender side of things.
+       Return root (vrmlNode, '') or (None, 'Error String')
+       '''
+       data = gzipOpen(path)
+       
+       if data==None:
+               return None, 'Failed to open file: ' + path
+       
+       # Stripped above
+       lines[:] = vrmlFormat( data )
+       
+       lines.insert(0, '{')
+       lines.insert(0, 'dymmy_node')
+       lines.append('}')
+       
+       # Use for testing our parsed output, so we can check on line numbers.
+       
+       ## ff = open('m:\\test.txt', 'w')
+       ## ff.writelines([l+'\n' for l in lines])
+       
+       
+       # Now evaluate it
+       node_type, new_i = is_nodeline(0, [])
+       if not node_type:
+               return None, 'Error: VRML file has no starting Node'
+       
+       # Trick to make sure we get all root nodes.
+       lines.insert(0, '{')
+       lines.insert(0, 'root_node____') # important the name starts with an ascii char
+       lines.append('}')
+       
+       root = vrmlNode(None, NODE_NORMAL, -1)
+       root.setRoot(path) # we need to set the root so we have a namespace and know the path incase of inlineing
+       
+       # Parse recursively
+       root.parse(0)
+       
+       # print root
+       return root, ''
+
+# ====================== END VRML 
+
+
+
+# ====================== X3d Support
+
+# Sane as vrml but replace the parser
+class x3dNode(vrmlNode):
+       def __init__(self, parent, node_type, x3dNode):
+               vrmlNode.__init__(self, parent, node_type, -1)
+               self.x3dNode = x3dNode
+               
+       def parse(self):
+               # print self.x3dNode.tagName
+               
+               define = self.x3dNode.getAttributeNode('DEF')
+               if define:
+                       self.getDefDict()[define.value] = self
+               else:
+                       use = self.x3dNode.getAttributeNode('USE')
+                       if use:
+                               try:
+                                       self.reference = self.getDefDict()[use.value]
+                                       self.node_type = NODE_REFERENCE
+                               except:
+                                       print '\tWarning: reference', use.value, 'not found'
+                                       self.parent.children.remove(self)
+                               
+                               return
+               
+               for x3dChildNode in self.x3dNode.childNodes:
+                       if x3dChildNode.nodeType in (x3dChildNode.TEXT_NODE, x3dChildNode.COMMENT_NODE, x3dChildNode.CDATA_SECTION_NODE):
+                               continue
+                       
+                       node_type = NODE_NORMAL
+                       # print x3dChildNode, dir(x3dChildNode)
+                       if x3dChildNode.getAttributeNode('USE'):
+                               node_type = NODE_REFERENCE
+                       
+                       child = x3dNode(self, node_type, x3dChildNode)
+                       child.parse()
+               
+               # TODO - x3d Inline
+               
+       def getSpec(self):
+               return self.x3dNode.tagName # should match vrml spec
+       
+       def getDefName(self):
+               data = self.x3dNode.getAttributeNode('DEF')
+               if data: data.value
+               return None
+       
+       # Other funcs operate from vrml, but this means we can wrap XML fields, still use nice utility funcs
+       # getFieldAsArray getFieldAsBool etc
+       def getFieldName(self, field):
+               self_real = self.getRealNode() # incase we're an instance
+               field_xml = self.x3dNode.getAttributeNode(field)
+               if field_xml:
+                       value = field_xml.value
+                       
+                       # We may want to edit. for x3d spesific stuff
+                       # Sucks a bit to return the field name in the list but vrml excepts this :/
+                       return value.split()
+               else:
+                       return None
+
+def x3d_parse(path):
+       '''
+       Sets up the root node and returns it so load_web3d() can deal with the blender side of things.
+       Return root (x3dNode, '') or (None, 'Error String')
+       '''
+       
+       try:
+               import xml.dom.minidom
+       except:
+               return None, 'Error, import XML parsing module (xml.dom.minidom) failed, install python'
+       
+       '''
+       try:    doc = xml.dom.minidom.parse(path)
+       except: return None, 'Could not parse this X3D file, XML error'
+       '''
+       
+       # Could add a try/except here, but a console error is more useful.
+       data = gzipOpen(path)
+       
+       if data==None:
+               return None, 'Failed to open file: ' + path
+       
+       doc = xml.dom.minidom.parseString(data)
+       
+       
+       try:
+               x3dnode = doc.getElementsByTagName('X3D')[0]
+       except:
+               return None, 'Not a valid x3d document, cannot import'
+       
+       root = x3dNode(None, NODE_NORMAL, x3dnode)
+       root.setRoot(path) # so images and Inline's we load have a relative path
+       root.parse()
+       
+       return root, ''
+
+
+
+## f = open('/_Cylinder.wrl', 'r')
+# f = open('/fe/wrl/Vrml/EGS/TOUCHSN.WRL', 'r')
+# vrml_parse('/fe/wrl/Vrml/EGS/TOUCHSN.WRL')
+#vrml_parse('/fe/wrl/Vrml/EGS/SCRIPT.WRL')
+'''
+
+import os
+files = os.popen('find /fe/wrl -iname "*.wrl"').readlines()
+files.sort()
+tot = len(files)
+for i, f in enumerate(files):
+       #if i < 801:
+       #       continue
+       
+       f = f.strip()
+       print f, i, tot
+       vrml_parse(f)
+'''
+
+# NO BLENDER CODE ABOVE THIS LINE.
+# -----------------------------------------------------------------------------------
+import bpy
+import BPyImage
+import Blender
+from Blender import Texture, Material, Mathutils, Mesh, Types, Window
+from Blender.Mathutils import TranslationMatrix
+from Blender.Mathutils import RotationMatrix
+from Blender.Mathutils import Vector
+from Blender.Mathutils import Matrix
+
+RAD_TO_DEG = 57.29578
+
+GLOBALS = {'CIRCLE_DETAIL':16}
+
+def translateRotation(rot):
+       '''     axis, angle     '''
+       return RotationMatrix(rot[3]*RAD_TO_DEG, 4, 'r', Vector(rot[:3]))
+
+def translateScale(sca):
+       mat = Matrix() # 4x4 default
+       mat[0][0] = sca[0]
+       mat[1][1] = sca[1]
+       mat[2][2] = sca[2]
+       return mat
+
+def translateTransform(node):
+       cent =          node.getFieldAsFloatTuple('center', None) # (0.0, 0.0, 0.0)
+       rot =           node.getFieldAsFloatTuple('rotation', None) # (0.0, 0.0, 1.0, 0.0)
+       sca =           node.getFieldAsFloatTuple('scale', None) # (1.0, 1.0, 1.0)
+       scaori =        node.getFieldAsFloatTuple('scaleOrientation', None) # (0.0, 0.0, 1.0, 0.0)
+       tx =            node.getFieldAsFloatTuple('translation', None) # (0.0, 0.0, 0.0)
+       
+       if cent:
+               cent_mat = TranslationMatrix(Vector(cent)).resize4x4()
+               cent_imat = cent_mat.copy().invert()
+       else:
+               cent_mat = cent_imat = None
+       
+       if rot:         rot_mat = translateRotation(rot)
+       else:           rot_mat = None
+       
+       if sca:         sca_mat = translateScale(sca)
+       else:           sca_mat = None
+       
+       if scaori:
+               scaori_mat = translateRotation(scaori)
+               scaori_imat = scaori_mat.copy().invert()
+       else:
+               scaori_mat = scaori_imat = None
+       
+       if tx:          tx_mat = TranslationMatrix(Vector(tx)).resize4x4()
+       else:           tx_mat = None
+       
+       new_mat = Matrix()
+       
+       mats = [tx_mat, cent_mat, rot_mat, scaori_mat, sca_mat, scaori_imat, cent_imat]
+       for mtx in mats:
+               if mtx:
+                       new_mat = mtx * new_mat
+       
+       return new_mat
+
+def translateTexTransform(node):
+       cent =          node.getFieldAsFloatTuple('center', None) # (0.0, 0.0)
+       rot =           node.getFieldAsFloat('rotation', None) # 0.0
+       sca =           node.getFieldAsFloatTuple('scale', None) # (1.0, 1.0)
+       tx =            node.getFieldAsFloatTuple('translation', None) # (0.0, 0.0)
+       
+       
+       if cent:
+               # cent is at a corner by default
+               cent_mat = TranslationMatrix(Vector(cent).resize3D()).resize4x4()
+               cent_imat = cent_mat.copy().invert()
+       else:
+               cent_mat = cent_imat = None
+       
+       if rot:         rot_mat = RotationMatrix(rot*RAD_TO_DEG, 4, 'z') # translateRotation(rot)
+       else:           rot_mat = None
+       
+       if sca:         sca_mat = translateScale((sca[0], sca[1], 0.0))
+       else:           sca_mat = None
+       
+       if tx:          tx_mat = TranslationMatrix(Vector(tx).resize3D()).resize4x4()
+       else:           tx_mat = None
+       
+       new_mat = Matrix()
+       
+       # as specified in VRML97 docs
+       mats = [cent_imat, sca_mat, rot_mat, cent_mat, tx_mat]
+
+       for mtx in mats:
+               if mtx:
+                       new_mat = mtx * new_mat
+       
+       return new_mat
+
+
+def getFinalMatrix(node, mtx, ancestry):
+       
+       transform_nodes = [node_tx for node_tx in ancestry if node_tx.getSpec() == 'Transform']
+       if node.getSpec()=='Transform':
+               transform_nodes.append(node)
+       transform_nodes.reverse()
+       
+       if mtx==None:
+               mtx = Matrix()
+       
+       for node_tx in transform_nodes:
+               mat = translateTransform(node_tx)
+               mtx = mtx * mat
+       
+       return mtx
+
+def importMesh_IndexedFaceSet(geom, bpyima):
+       # print geom.lineno, geom.id, vrmlNode.DEF_NAMESPACE.keys()
+       
+       ccw =                           geom.getFieldAsBool('ccw', True)
+       ifs_colorPerVertex =    geom.getFieldAsBool('colorPerVertex', True) # per vertex or per face
+       ifs_normalPerVertex =   geom.getFieldAsBool('normalPerVertex', True)
+       
+       # This is odd how point is inside Coordinate
+       
+       # VRML not x3d
+       #coord = geom.getChildByName('coord') # 'Coordinate'
+       
+       coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml
+       
+       if coord:       ifs_points = coord.getFieldAsArray('point', 3)
+       else:           coord = []
+       
+       if not coord:
+               print '\tWarnint: IndexedFaceSet has no points'
+               return None, ccw
+       
+       ifs_faces = geom.getFieldAsArray('coordIndex', 0)
+       
+       coords_tex = None
+       if ifs_faces: # In rare cases this causes problems - no faces but UVs???
+               
+               # WORKS - VRML ONLY
+               # coords_tex = geom.getChildByName('texCoord')
+               coords_tex = geom.getChildBySpec('TextureCoordinate')
+               
+               if coords_tex:
+                       ifs_texpoints = coords_tex.getFieldAsArray('point', 2)
+                       ifs_texfaces = geom.getFieldAsArray('texCoordIndex', 0)
+                       
+                       if not ifs_texpoints:
+                               # IF we have no coords, then dont bother
+                               coords_tex = None
+               
+               
+       # WORKS - VRML ONLY
+       # vcolor = geom.getChildByName('color')
+       vcolor = geom.getChildBySpec('Color')
+       vcolor_spot = None # spot color when we dont have an array of colors
+       if vcolor:
+               # float to char
+               ifs_vcol = [[int(c*256) for c in col] for col in vcolor.getFieldAsArray('color', 3)]
+               ifs_color_index = geom.getFieldAsArray('colorIndex', 0)
+               
+               if not ifs_vcol:
+                       vcolor_spot = [int(c*256) for c in vcolor.getFieldAsFloatTuple('color', [])]
+       
+       # Convert faces into somthing blender can use
+       edges = []
+       
+       # All lists are aligned!
+       faces = []
+       faces_uv = [] # if ifs_texfaces is empty then the faces_uv will match faces exactly.
+       faces_orig_index = [] # for ngons, we need to know our original index
+       
+       if coords_tex and ifs_texfaces:
+               do_uvmap = True
+       else:
+               do_uvmap = False
+       
+       # current_face = [0] # pointer anyone
+       
+       def add_face(face, fuvs, orig_index):
+               l = len(face)
+               if l==3 or l==4:
+                       faces.append(face)
+                       # faces_orig_index.append(current_face[0])
+                       if do_uvmap:
+                               faces_uv.append(fuvs)
+                               
+                       faces_orig_index.append(orig_index)
+               elif l==2:                      edges.append(face)
+               elif l>4:
+                       for i in xrange(2, len(face)):
+                               faces.append([face[0], face[i-1], face[i]])
+                               if do_uvmap:
+                                       faces_uv.append([fuvs[0], fuvs[i-1], fuvs[i]])
+                               faces_orig_index.append(orig_index)
+               else:
+                       # faces with 1 verts? pfft!
+                       # still will affect index ordering
+                       pass
+       
+       face = []
+       fuvs = []
+       orig_index = 0
+       for i, fi in enumerate(ifs_faces):
+               # ifs_texfaces and ifs_faces should be aligned
+               if fi != -1:
+                       # face.append(int(fi)) # in rare cases this is a float
+                       # EEKADOODLE!!!
+                       # Annoyance where faces that have a zero index vert get rotated. This will then mess up UVs and VColors
+                       face.append(int(fi)+1) # in rare cases this is a float, +1 because of stupid EEKADOODLE :/
+                       
+                       if do_uvmap:
+                               if i >= len(ifs_texfaces):
+                                       print '\tWarning: UV Texface index out of range'
+                                       fuvs.append(ifs_texfaces[0])
+                               else:
+                                       fuvs.append(ifs_texfaces[i])
+               else:
+                       add_face(face, fuvs, orig_index)
+                       face = []
+                       if do_uvmap:
+                               fuvs = []
+                       orig_index += 1
+       
+       add_face(face, fuvs, orig_index)
+       del add_face # dont need this func anymore
+       
+       bpymesh = bpy.data.meshes.new()
+       
+       bpymesh.verts.extend([(0,0,0)]) # EEKADOODLE
+       bpymesh.verts.extend(ifs_points)
+       
+       # print len(ifs_points), faces, edges, ngons
+       
+       try:
+               bpymesh.faces.extend(faces, smooth=True, ignoreDups=True)
+       except KeyError:
+               print "one or more vert indicies out of range. corrupt file?"
+               #for f in faces:
+               #       bpymesh.faces.extend(faces, smooth=True)
+       
+       bpymesh.calcNormals()
+       
+       if len(bpymesh.faces) != len(faces):
+               print '\tWarning: adding faces did not work! file is invalid, not adding UVs or vcolors'
+               return bpymesh, ccw
+       
+       # Apply UVs if we have them
+       if not do_uvmap:
+               faces_uv = faces # fallback, we didnt need a uvmap in the first place, fallback to the face/vert mapping.
+       if coords_tex:
+               #print ifs_texpoints
+               # print geom
+               bpymesh.faceUV = True
+               for i,f in enumerate(bpymesh.faces):
+                       f.image = bpyima
+                       fuv = faces_uv[i] # uv indicies
+                       for j,uv in enumerate(f.uv):
+                               # print fuv, j, len(ifs_texpoints)
+                               try:
+                                       uv[:] = ifs_texpoints[fuv[j]]
+                               except:
+                                       print '\tWarning: UV Index out of range'
+                                       uv[:] = ifs_texpoints[0]
+       
+       elif bpyima and len(bpymesh.faces):
+               # Oh Bugger! - we cant really use blenders ORCO for for texture space since texspace dosnt rotate.
+               # we have to create VRML's coords as UVs instead.
+               
+               # VRML docs
+               '''
+               If the texCoord field is NULL, a default texture coordinate mapping is calculated using the local
+               coordinate system bounding box of the shape. The longest dimension of the bounding box defines the S coordinates,
+               and the next longest defines the T coordinates. If two or all three dimensions of the bounding box are equal,
+               ties shall be broken by choosing the X, Y, or Z dimension in that order of preference.
+               The value of the S coordinate ranges from 0 to 1, from one end of the bounding box to the other.
+               The T coordinate ranges between 0 and the ratio of the second greatest dimension of the bounding box to the greatest dimension.
+               '''
+               
+               # Note, S,T == U,V
+               # U gets longest, V gets second longest
+               xmin, ymin, zmin = ifs_points[0]
+               xmax, ymax, zmax = ifs_points[0]
+               for co in ifs_points:
+                       x,y,z = co
+                       if x < xmin: xmin = x
+                       if y < ymin: ymin = y
+                       if z < zmin: zmin = z
+                       
+                       if x > xmax: xmax = x
+                       if y > ymax: ymax = y
+                       if z > zmax: zmax = z
+                       
+               xlen = xmax - xmin
+               ylen = ymax - ymin
+               zlen = zmax - zmin
+               
+               depth_min = xmin, ymin, zmin
+               depth_list = [xlen, ylen, zlen]
+               depth_sort = depth_list[:]
+               depth_sort.sort()
+               
+               depth_idx = [depth_list.index(val) for val in depth_sort]
+               
+               axis_u = depth_idx[-1]
+               axis_v = depth_idx[-2] # second longest
+               
+               # Hack, swap these !!! TODO - Why swap??? - it seems to work correctly but should not.
+               # axis_u,axis_v = axis_v,axis_u
+               
+               min_u = depth_min[axis_u]
+               min_v = depth_min[axis_v]
+               depth_u = depth_list[axis_u]
+               depth_v = depth_list[axis_v]
+               
+               depth_list[axis_u]
+               
+               if axis_u == axis_v:
+                       # This should be safe because when 2 axies have the same length, the lower index will be used.
+                       axis_v += 1
+               
+               bpymesh.faceUV = True
+               
+               # HACK !!! - seems to be compatible with Cosmo though.
+               depth_v = depth_u = max(depth_v, depth_u)
+               
+               for f in bpymesh.faces:
+                       f.image = bpyima
+                       fuv = f.uv
+                       
+                       for i,v in enumerate(f):
+                               co = v.co
+                               fuv[i][:] = (co[axis_u]-min_u) / depth_u, (co[axis_v]-min_v) / depth_v
+       
+       # Add vcote 
+       if vcolor:
+               # print ifs_vcol
+               bpymesh.vertexColors = True
+               
+               for f in bpymesh.faces:
+                       fcol = f.col
+                       if ifs_colorPerVertex:
+                               fv = f.verts
+                               for i,c in enumerate(fcol):
+                                       color_index = fv[i].index # color index is vert index
+                                       if ifs_color_index: color_index = ifs_color_index[color_index]
+                                       
+                                       if len(ifs_vcol) < color_index:
+                                               c.r, c.g, c.b = ifs_vcol[color_index]
+                                       else:
+                                               print '\tWarning: per face color index out of range'
+                       else:
+                               if vcolor_spot: # use 1 color, when ifs_vcol is []
+                                       for c in fcol:
+                                               c.r, c.g, c.b = vcolor_spot
+                               else:
+                                       color_index = faces_orig_index[f.index] # color index is face index
+                                       #print color_index, ifs_color_index
+                                       if ifs_color_index:
+                                               if color_index <= len(ifs_color_index):
+                                                       print '\tWarning: per face color index out of range'
+                                                       color_index = 0
+                                               else:
+                                                       color_index = ifs_color_index[color_index]
+                                               
+                                       
+                                       col = ifs_vcol[color_index]
+                                       for i,c in enumerate(fcol):
+                                               c.r, c.g, c.b = col
+       
+       bpymesh.verts.delete([0,]) # EEKADOODLE
+       
+       return bpymesh, ccw
+
+def importMesh_IndexedLineSet(geom):
+       # VRML not x3d
+       #coord = geom.getChildByName('coord') # 'Coordinate'
+       coord = geom.getChildBySpec('Coordinate') # works for x3d and vrml
+       if coord:       points = coord.getFieldAsArray('point', 3)
+       else:           points = []
+       
+       if not points:
+               print '\tWarning: IndexedLineSet had no points'
+               return None
+       
+       ils_lines = geom.getFieldAsArray('coordIndex', 0)
+       
+       lines = []
+       line = []
+       
+       for il in ils_lines:
+               if il==-1:
+                       lines.append(line)
+                       line = []
+               else:
+                       line.append(int(il))
+       lines.append(line)
+       
+       # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color
+       
+       bpycurve = bpy.data.curves.new('IndexedCurve', 'Curve')
+       bpycurve.setFlag(1)
+       
+       w=t=1
+       
+       curve_index = 0
+       
+       for line in lines:
+               if not line:
+                       continue
+               co = points[line[0]]
+               bpycurve.appendNurb([co[0], co[1], co[2], w, t])
+               bpycurve[curve_index].type= 0 # Poly Line
+               
+               for il in line[1:]:
+                       co = points[il]
+                       bpycurve.appendPoint(curve_index, [co[0], co[1], co[2], w])
+               
+               
+               curve_index += 1
+       
+       return bpycurve
+
+
+def importMesh_PointSet(geom):
+       # VRML not x3d
+       #coord = geom.getChildByName('coord') # 'Coordinate'
+       coord = geom.getChildBySpec('Coordinate')  # works for x3d and vrml
+       if coord:       points = coord.getFieldAsArray('point', 3)
+       else:           points = []
+       
+       # vcolor = geom.getChildByName('color') # blender dosnt have per vertex color
+       
+       bpymesh = bpy.data.meshes.new()
+       bpymesh.verts.extend(points)
+       bpymesh.calcNormals() # will just be dummy normals
+       return bpymesh
+
+GLOBALS['CIRCLE_DETAIL'] = 12
+
+MATRIX_Z_TO_Y = RotationMatrix(90, 4, 'x')
+
+def importMesh_Sphere(geom):
+       # bpymesh = bpy.data.meshes.new()
+       diameter = geom.getFieldAsFloat('radius', 0.5) * 2 # * 2 for the diameter
+       bpymesh = Mesh.Primitives.UVsphere(GLOBALS['CIRCLE_DETAIL'], GLOBALS['CIRCLE_DETAIL'], diameter)  
+       bpymesh.transform(MATRIX_Z_TO_Y)
+       return bpymesh
+
+def importMesh_Cylinder(geom):
+       # bpymesh = bpy.data.meshes.new()
+       diameter = geom.getFieldAsFloat('radius', 1.0) * 2 # * 2 for the diameter
+       height = geom.getFieldAsFloat('height', 2)
+       bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height) 
+       bpymesh.transform(MATRIX_Z_TO_Y)
+       
+       # Warning - Rely in the order Blender adds verts
+       # not nice design but wont change soon.
+       
+       bottom = geom.getFieldAsBool('bottom', True)
+       side = geom.getFieldAsBool('side', True)
+       top = geom.getFieldAsBool('top', True)
+       
+       if not top: # last vert is top center of tri fan.
+               bpymesh.verts.delete([(GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL'])+1])
+       
+       if not bottom: # second last vert is bottom of triangle fan
+               bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+GLOBALS['CIRCLE_DETAIL']])
+       
+       if not side:
+               # remove all quads
+               bpymesh.faces.delete(1, [f for f in bpymesh.faces if len(f)==4])
+       
+       return bpymesh
+
+def importMesh_Cone(geom):
+       # bpymesh = bpy.data.meshes.new()
+       diameter = geom.getFieldAsFloat('bottomRadius', 1.0) * 2 # * 2 for the diameter
+       height = geom.getFieldAsFloat('height', 2)
+       bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height) 
+       bpymesh.transform(MATRIX_Z_TO_Y)
+       
+       # Warning - Rely in the order Blender adds verts
+       # not nice design but wont change soon.
+       
+       bottom = geom.getFieldAsBool('bottom', True)
+       side = geom.getFieldAsBool('side', True)
+       
+       if not bottom: # last vert is on the bottom
+               bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']+1])
+       if not side: # second last vert is on the pointy bit of the cone
+               bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']])
+       
+       return bpymesh
+
+def importMesh_Box(geom):
+       # bpymesh = bpy.data.meshes.new()
+       
+       size = geom.getFieldAsFloatTuple('size', (2.0, 2.0, 2.0))
+       bpymesh = Mesh.Primitives.Cube(1.0) 
+
+       # Scale the box to the size set
+       scale_mat = Matrix([size[0],0,0], [0, size[1], 0], [0, 0, size[2]])
+       bpymesh.transform(scale_mat.resize4x4())
+       
+       return bpymesh
+
+def importShape(node, ancestry):
+       vrmlname = node.getDefName()
+       if not vrmlname: vrmlname = 'Shape'
+       
+       # works 100% in vrml, but not x3d
+       #appr = node.getChildByName('appearance') # , 'Appearance'
+       #geom = node.getChildByName('geometry') # , 'IndexedFaceSet'
+       
+       # Works in vrml and x3d
+       appr = node.getChildBySpec('Appearance')
+       geom = node.getChildBySpec(['IndexedFaceSet', 'IndexedLineSet', 'PointSet', 'Sphere', 'Box', 'Cylinder', 'Cone'])
+       
+       # For now only import IndexedFaceSet's
+       if geom:
+               bpymat = None
+               bpyima = None
+               texmtx = None
+               if appr:
+                       
+                       #mat = appr.getChildByName('material') # 'Material'
+                       #ima = appr.getChildByName('texture') # , 'ImageTexture'
+                       #if ima and ima.getSpec() != 'ImageTexture':
+                       #       print '\tWarning: texture type "%s" is not supported' % ima.getSpec() 
+                       #       ima = None
+                       # textx = appr.getChildByName('textureTransform')
+                       
+                       mat = appr.getChildBySpec('Material')
+                       ima = appr.getChildBySpec('ImageTexture')
+                       
+                       textx = appr.getChildBySpec('TextureTransform')
+                       
+                       if textx:
+                               texmtx = translateTexTransform(textx)
+                       
+
+                       
+                       # print mat, ima
+                       if mat or ima:
+                               
+                               if not mat:
+                                       mat = ima # This is a bit dumb, but just means we use default values for all
+                               
+                               # all values between 0.0 and 1.0, defaults from VRML docs
+                               bpymat = bpy.data.materials.new()
+                               bpymat.amb =            mat.getFieldAsFloat('ambientIntensity', 0.2)
+                               bpymat.rgbCol =         mat.getFieldAsFloatTuple('diffuseColor', [0.8, 0.8, 0.8])
+                               
+                               # NOTE - blender dosnt support emmisive color
+                               # Store in mirror color and approximate with emit.
+                               emit =                          mat.getFieldAsFloatTuple('emissiveColor', [0.0, 0.0, 0.0])
+                               bpymat.mirCol =         emit
+                               bpymat.emit =           (emit[0]+emit[1]+emit[2])/3.0
+                               
+                               bpymat.hard =           int(1+(510*mat.getFieldAsFloat('shininess', 0.2))) # 0-1 -> 1-511
+                               bpymat.specCol =        mat.getFieldAsFloatTuple('specularColor', [0.0, 0.0, 0.0])
+                               bpymat.alpha =          1.0 - mat.getFieldAsFloat('transparency', 0.0)
+                               if bpymat.alpha < 0.999:
+                                       bpymat.mode |= Material.Modes.ZTRANSP
+                       
+                       
+                       if ima:
+                               # print ima
+                               ima_url =                       ima.getFieldAsString('url')
+                               if ima_url==None:
+                                       print "\twarning, image with no URL, this is odd"
+                               else:
+                                       bpyima= BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER= False, RECURSIVE= False)
+                                       if bpyima:
+                                               texture= bpy.data.textures.new()
+                                               texture.setType('Image')
+                                               texture.image = bpyima
+                                               
+                                               # Adds textures for materials (rendering)
+                                               try:    depth = bpyima.depth
+                                               except: depth = -1
+                                               
+                                               if depth == 32:
+                                                       # Image has alpha
+                                                       bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL | Texture.MapTo.ALPHA)
+                                                       texture.setImageFlags('MipMap', 'InterPol', 'UseAlpha')
+                                                       bpymat.mode |= Material.Modes.ZTRANSP
+                                                       bpymat.alpha = 0.0
+                                               else:
+                                                       bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
+                                                       
+                                               ima_repS =                      ima.getFieldAsBool('repeatS', True)
+                                               ima_repT =                      ima.getFieldAsBool('repeatT', True)
+                                               
+                                               texture.repeat =        max(1, ima_repS * 512), max(1, ima_repT * 512)
+                                               
+                                               if not ima_repS: bpyima.clampX = True
+                                               if not ima_repT: bpyima.clampY = True
+               
+               bpydata = None
+               geom_spec = geom.getSpec()
+               ccw = True
+               if geom_spec == 'IndexedFaceSet':
+                       bpydata, ccw = importMesh_IndexedFaceSet(geom, bpyima)
+               elif geom_spec == 'IndexedLineSet':
+                       bpydata = importMesh_IndexedLineSet(geom)
+               elif geom_spec == 'PointSet':
+                       bpydata = importMesh_PointSet(geom)
+               elif geom_spec == 'Sphere':
+                       bpydata = importMesh_Sphere(geom)
+               elif geom_spec == 'Box':
+                       bpydata = importMesh_Box(geom)
+               elif geom_spec == 'Cylinder':
+                       bpydata = importMesh_Cylinder(geom)
+               elif geom_spec == 'Cone':
+                       bpydata = importMesh_Cone(geom)
+               else:
+                       print '\tWarning: unsupported type "%s"' % geom_spec
+                       return
+               
+               if bpydata:
+                       vrmlname = vrmlname + geom_spec
+                       
+                       bpydata.name = vrmlname
+                       
+                       bpyob  = node.blendObject = bpy.data.scenes.active.objects.new(bpydata)
+                       
+                       if type(bpydata) == Types.MeshType:
+                               is_solid =                      geom.getFieldAsBool('solid', True)
+                               creaseAngle =           geom.getFieldAsFloat('creaseAngle', None)
+                               
+                               if creaseAngle != None:
+                                       bpydata.maxSmoothAngle = 1+int(min(79, creaseAngle * RAD_TO_DEG))
+                                       bpydata.mode |= Mesh.Modes.AUTOSMOOTH
+                               
+                               # Only ever 1 material per shape
+                               if bpymat:      bpydata.materials = [bpymat]
+                               
+                               if bpydata.faceUV and texmtx:
+                                       # Apply texture transform?
+                                       uv_copy = Vector()
+                                       for f in bpydata.faces:
+                                               for uv in f.uv:
+                                                       uv_copy.x = uv.x
+                                                       uv_copy.y = uv.y
+                                                       
+                                                       uv.x, uv.y = (uv_copy * texmtx)[0:2]
+                               # Done transforming the texture
+                               
+                               
+                               # Must be here and not in IndexedFaceSet because it needs an object for the flip func. Messy :/
+                               if not ccw: bpydata.flipNormals()
+                               
+                               
+                       # else could be a curve for example
+                       
+                       
+                       
+                       # Can transform data or object, better the object so we can instance the data
+                       #bpymesh.transform(getFinalMatrix(node))
+                       bpyob.setMatrix( getFinalMatrix(node, None, ancestry) )
+
+
+def importLamp_PointLight(node):
+       vrmlname = node.getDefName()
+       if not vrmlname: vrmlname = 'PointLight'
+       
+       # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0) # TODO
+       # attenuation = node.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0)) # TODO
+       color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0))
+       intensity = node.getFieldAsFloat('intensity', 1.0) # max is documented to be 1.0 but some files have higher.
+       location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0))
+       # is_on = node.getFieldAsBool('on', True) # TODO
+       radius = node.getFieldAsFloat('radius', 100.0)
+       
+       bpylamp = bpy.data.lamps.new()
+       bpylamp.setType('Lamp')
+       bpylamp.energy = intensity
+       bpylamp.dist = radius
+       bpylamp.col = color
+       
+       mtx = TranslationMatrix(Vector(location))
+       
+       return bpylamp, mtx
+
+def importLamp_DirectionalLight(node):
+       vrmlname = node.getDefName()
+       if not vrmlname: vrmlname = 'DirectLight'
+       
+       # ambientIntensity = node.getFieldAsFloat('ambientIntensity', 0.0) # TODO
+       color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0))
+       direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0))
+       intensity = node.getFieldAsFloat('intensity', 1.0) # max is documented to be 1.0 but some files have higher.
+       # is_on = node.getFieldAsBool('on', True) # TODO
+       
+       bpylamp = bpy.data.lamps.new(vrmlname)
+       bpylamp.setType('Sun')
+       bpylamp.energy = intensity
+       bpylamp.col = color
+       
+       # lamps have their direction as -z, yup
+       mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4()
+       
+       return bpylamp, mtx
+
+# looks like default values for beamWidth and cutOffAngle were swapped in VRML docs.
+
+def importLamp_SpotLight(node):
+       vrmlname = node.getDefName()
+       if not vrmlname: vrmlname = 'SpotLight'
+       
+       # ambientIntensity = geom.getFieldAsFloat('ambientIntensity', 0.0) # TODO
+       # attenuation = geom.getFieldAsFloatTuple('attenuation', (1.0, 0.0, 0.0)) # TODO
+       beamWidth = node.getFieldAsFloat('beamWidth', 1.570796) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
+       color = node.getFieldAsFloatTuple('color', (1.0, 1.0, 1.0))
+       cutOffAngle = node.getFieldAsFloat('cutOffAngle', 0.785398) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
+       direction = node.getFieldAsFloatTuple('direction', (0.0, 0.0, -1.0))
+       intensity = node.getFieldAsFloat('intensity', 1.0) # max is documented to be 1.0 but some files have higher.
+       location = node.getFieldAsFloatTuple('location', (0.0, 0.0, 0.0))
+       # is_on = node.getFieldAsBool('on', True) # TODO
+       radius = node.getFieldAsFloat('radius', 100.0)
+       
+       bpylamp = bpy.data.lamps.new(vrmlname)
+       bpylamp.setType('Spot')
+       bpylamp.energy = intensity
+       bpylamp.dist = radius
+       bpylamp.col = color
+       bpylamp.spotSize = cutOffAngle
+       if beamWidth > cutOffAngle:
+               bpylamp.spotBlend = 0.0
+       else:
+               if cutOffAngle==0.0: #@#$%^&*(!!! - this should never happen
+                       bpylamp.spotBlend = 0.5
+               else:
+                       bpylamp.spotBlend = beamWidth / cutOffAngle
+       
+       # Convert 
+       
+       # lamps have their direction as -z, y==up
+       mtx = TranslationMatrix(Vector(location)) * Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4()
+       
+       return bpylamp, mtx
+
+
+def importLamp(node, spec, ancestry):
+       if spec=='PointLight':
+               bpylamp,mtx = importLamp_PointLight(node)
+       elif spec=='DirectionalLight':
+               bpylamp,mtx = importLamp_DirectionalLight(node)
+       elif spec=='SpotLight':
+               bpylamp,mtx = importLamp_SpotLight(node)
+       else:
+               print "Error, not a lamp"
+               raise ""
+       
+       bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpylamp)
+       bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) )
+
+
+def importViewpoint(node, ancestry):
+       name = node.getDefName()
+       if not name: name = 'Viewpoint'
+       
+       fieldOfView = node.getFieldAsFloat('fieldOfView', 0.785398) * RAD_TO_DEG # max is documented to be 1.0 but some files have higher.
+       # jump = node.getFieldAsBool('jump', True)
+       orientation = node.getFieldAsFloatTuple('orientation', (0.0, 0.0, 1.0, 0.0))
+       position = node.getFieldAsFloatTuple('position', (0.0, 0.0, 10.0))
+       description = node.getFieldAsString('description', '')
+       
+       bpycam = bpy.data.cameras.new(name)
+       
+       bpycam.angle = fieldOfView
+       
+       mtx = TranslationMatrix(Vector(position)) * translateRotation(orientation) * MATRIX_Z_TO_Y
+       
+       
+       bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpycam)
+       bpyob.setMatrix( getFinalMatrix(node, mtx, ancestry) )
+
+
+def importTransform(node, ancestry):
+       name = node.getDefName()
+       if not name: name = 'Transform'
+       
+       bpyob = node.blendObject = bpy.data.scenes.active.objects.new('Empty', name) # , name)
+       bpyob.setMatrix( getFinalMatrix(node, None, ancestry) )
+
+
+def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16):
+       
+       # Used when adding blender primitives
+       GLOBALS['CIRCLE_DETAIL'] = PREF_CIRCLE_DIV
+       
+       #root_node = vrml_parse('/_Cylinder.wrl')
+       if path.lower().endswith('.x3d'):
+               root_node, msg = x3d_parse(path)
+       else:
+               root_node, msg = vrml_parse(path)
+       
+       if not root_node:
+               if Blender.mode == 'background':
+                       print msg
+               else:
+                       Blender.Draw.PupMenu(msg)
+               return
+       
+       
+       # fill with tuples - (node, [parents-parent, parent])
+       all_nodes = root_node.getSerialized([], [])
+       
+       for node, ancestry in all_nodes:
+               #if 'castle.wrl' not in node.getFilename():
+               #       continue
+               
+               spec = node.getSpec()
+               if spec=='Shape':
+                       importShape(node, ancestry)
+               elif spec in ('PointLight', 'DirectionalLight', 'SpotLight'):
+                       importLamp(node, spec, ancestry)
+               elif spec=='Viewpoint':
+                       importViewpoint(node, ancestry)
+               elif spec=='Transform':
+                       # Only use transform nodes when we are not importing a flat object hierarchy
+                       if PREF_FLAT==False:
+                               importTransform(node, ancestry)
+       
+       # Add in hierarchy
+       if PREF_FLAT==False:
+               child_dict = {}
+               for node, ancestry in all_nodes:
+                       if node.blendObject:
+                               blendObject = None
+                               
+                               # Get the last parent
+                               i = len(ancestry)
+                               while i:
+                                       i-=1
+                                       blendObject = ancestry[i].blendObject
+                                       if blendObject:
+                                               break
+                               
+                               if blendObject:
+                                       # Parent Slow, - 1 liner but works
+                                       # blendObject.makeParent([node.blendObject], 0, 1)
+                                       
+                                       # Parent FAST
+                                       try:    child_dict[blendObject].append(node.blendObject)
+                                       except: child_dict[blendObject] = [node.blendObject]
+               
+               # Parent FAST
+               for parent, children in child_dict.iteritems():
+                       parent.makeParent(children, 0, 1)
+               
+               # update deps
+               bpy.data.scenes.active.update(1)
+               del child_dict
+
+
+def load_ui(path):
+       Draw = Blender.Draw
+       PREF_HIERARCHY= Draw.Create(0)
+       PREF_CIRCLE_DIV= Draw.Create(16)
+       
+       # Get USER Options
+       pup_block= [\
+       'Import...',\
+       ('Hierarchy', PREF_HIERARCHY, 'Import transform nodes as empties to create a parent/child hierarchy'),\
+       ('Circle Div:', PREF_CIRCLE_DIV, 3, 128, 'Number of divisions to use for circular primitives')
+       ]
+       
+       if not Draw.PupBlock('Import X3D/VRML...', pup_block):
+               return
+       
+       Window.WaitCursor(1)
+       
+       load_web3d(path,\
+         (not PREF_HIERARCHY.val),\
+         PREF_CIRCLE_DIV.val,\
+       )
+       
+       Window.WaitCursor(0)
+       
+
+if __name__ == '__main__':
+       Window.FileSelector(load_ui, 'Import X3D/VRML97')
+       
+       
+# Testing stuff
+
+# load_web3d('/test.x3d')
+# load_web3d('/_Cylinder.x3d')
+
+# Testing below
+# load_web3d('m:\\root\\Desktop\\_Cylinder.wrl')
+# load_web3d('/_Cylinder.wrl')
+# load_web3d('/fe/wrl/Vrml/EGS/BCKGD.WRL')
+
+# load_web3d('/fe/wrl/Vrml/EGS/GRNDPLNE.WRL')
+# load_web3d('/fe/wrl/Vrml/EGS/INDEXFST.WRL')
+# load_web3d('/fe/wrl/panel1c.wrl')
+# load_web3d('/test.wrl')
+# load_web3d('/fe/wrl/dulcimer.wrl')
+# load_web3d('/fe/wrl/rccad/Ju-52.wrl') # Face index out of range
+# load_web3d('/fe/wrl/16lat.wrl') # spotlight
+# load_web3d('/fe/wrl/Vrml/EGS/FOG.WRL') # spotlight
+# load_web3d('/fe/wrl/Vrml/EGS/LOD.WRL') # vcolor per face
+
+# load_web3d('/fe/wrl/new/daybreak_final.wrl') # no faces in mesh, face duplicate error
+# load_web3d('/fe/wrl/new/earth.wrl')
+# load_web3d('/fe/wrl/new/hendrix.ei.dtu.dk/vrml/talairach/fourd/TalaDruryRight.wrl') # define/use fields
+# load_web3d('/fe/wrl/new/imac.wrl') # extrusion and define/use fields, face index is a float somehow
+# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/mcastle.wrl') 
+# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/tower.wrl') 
+# load_web3d('/fe/wrl/new/www.igs.net/~mascott/vrml/vrml2/temple.wrl') 
+# load_web3d('/fe/wrl/brain.wrl')  # field define test 'a IS b'
+# load_web3d('/fe/wrl/new/coaster.wrl')  # fields that are confusing to read.
+
+# X3D 
+
+# load_web3d('/fe/x3d/www.web3d.org/x3d/content/examples/Basic/StudentProjects/PlayRoom.x3d') # invalid UVs
+
+'''
+import os
+# files = os.popen('find /fe/wrl -iname "*.wrl"').readlines()
+# files = os.popen('find /fe/x3d -iname "*.x3d"').readlines()
+files = os.popen('find   /fe/x3d/X3dExamplesSavage   -iname "*.x3d"').readlines()
+
+files.sort()
+tot = len(files)
+for i, f in enumerate(files):
+       if i < 12803 or i > 1000000:
+               continue
+       #if i != 12686:
+       #       continue
+       
+       f = f.strip()
+       print f, i, tot
+       sce = bpy.data.scenes.new(f.split('/')[-1])
+       bpy.data.scenes.active = sce
+       # Window.
+       load_web3d(f, PREF_FLAT=True)
+'''
\ No newline at end of file
index ad1265be50c017756bfc29da3e8099670d0346c5..c91fcce794808292227d6209330cd7dd8d9e506b 100644 (file)
@@ -45,7 +45,7 @@ from Blender import Scene
 sce = Scene.GetCurrent()
 rend = sce.render
 
-# default filename: theme's name + '_theme.py' in user's scripts dir:
+# default filename: filename + scenename + '_renderlayer.py' in user's scripts dir:
 default_fname = Blender.Get("scriptsdir")
 if not default_fname:
        default_fname = Blender.Get("uscriptsdir")
@@ -81,10 +81,10 @@ Remember to also set author, version and possibly url(s) above.  You can also
 define an __email__ tag, check some bundled script's source for examples.
 \"\"\"
 
-# This script was automatically generated by the save_theme.py bpython script.
+# This script was automatically generated by the render_save_layers.py bpython script.
 # By default, these generated scripts are released as Public Domain, but you
 # are free to change the license of the scripts you generate with
-# save_theme.py before releasing them.
+# render_save_layers.py before releasing them.
 
 import Blender
 from Blender import Scene
index dfd52a9f749318194d8811a554ae7e4494bb7e6b..1584659d3176f13130ff84dcc673f34181568f58 100644 (file)
@@ -27,7 +27,7 @@ def main():
 main()
 '''
 
-new_text = bpy.data.texts.new('gamelogic_example.py')
+new_text = bpy.data.texts.new('gamelogic_simple.py')
 new_text.write(script_data)
 bpy.data.texts.active = new_text
 Window.RedrawAll()
index db21cabe14fc6e6ae9cb11544ac172678300ce97..bd1a35f7c3ba768b5fa794a7fbaae23d562d1dba 100644 (file)
@@ -639,7 +639,7 @@ class VRML2Export:
                # Check if any faces the material or image
                for face in me.faces:
                        if (matnum == -1):
-                               if (f.image == image):
+                               if (face.image == image):
                                        return True
                        elif (image == None):
                                if (face.mat == matnum):
index 1487c1e9eb3fa13799a4127acb93adf2b4ff1511..b3e8fb53db0f606c54716d797d758dd50eaaa1fa 100644 (file)
@@ -1,37 +1,37 @@
-PSF LICENSE AGREEMENT FOR PYTHON 2.3
-------------------------------------
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
 
 1. This LICENSE AGREEMENT is between the Python Software Foundation
 ("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using Python 2.3 software in source or binary form and its
-associated documentation.
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
 
 2. Subject to the terms and conditions of this License Agreement, PSF
 hereby grants Licensee a nonexclusive, royalty-free, world-wide
 license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 2.3
+prepare derivative works, distribute, and otherwise use Python
 alone or in any derivative version, provided, however, that PSF's
 License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
-retained in Python 2.3 alone or in any derivative version prepared by
-Licensee.
+2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
+Reserved" are retained in Python alone or in any derivative version 
+prepared by Licensee.
 
 3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 2.3 or any part thereof, and wants to make
+or incorporates Python or any part thereof, and wants to make
 the derivative work available to others as provided herein, then
 Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 2.3.
+the changes made to Python.
 
-4. PSF is making Python 2.3 available to Licensee on an "AS IS"
+4. PSF is making Python available to Licensee on an "AS IS"
 basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
 IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
 DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
 INFRINGE ANY THIRD PARTY RIGHTS.
 
 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
 OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
 
 6. This License Agreement will automatically terminate upon a material
@@ -43,6 +43,7 @@ Licensee.  This License Agreement does not grant permission to use PSF
 trademarks or trade name in a trademark sense to endorse or promote
 products or services of Licensee, or any third party.
 
-8. By copying, installing or otherwise using Python 2.3, Licensee
+8. By copying, installing or otherwise using Python, Licensee
 agrees to be bound by the terms and conditions of this License
 Agreement.
+
index c96b188fb0287ce6426dcc71551d7bc1f38520a9..1cb159050fed5c42702f2b8486d2e758714b01b6 100644 (file)
@@ -182,12 +182,11 @@ Function MigrateUserSettings
   ${EndIf}  
 FunctionEnd
 
-!define DLL_VER "8.00.50727.42"
-!define DLL_VER2 "7.10.3052.4"
+!define DLL_VER "9.00.21022.8"
 
-Function LocateCallback_80
-       MoreInfo::GetProductVersion "$R9"
-       Pop $0
+Function LocateCallback_90
+    MoreInfo::GetProductVersion "$R9"
+    Pop $0
 
         ${VersionCompare} "$0" "${DLL_VER}" $R1
 
@@ -196,7 +195,7 @@ Function LocateCallback_80
         StrCmp $R1 1 0 old
       old:
         StrCmp $R1 2 0 end
-       ; Found DLL is older
+    ; Found DLL is older
         Call DownloadDLL
 
      end:
@@ -206,35 +205,14 @@ Function LocateCallback_80
 
 FunctionEnd
 
-Function LocateCallback_71
-       MoreInfo::GetProductVersion "$R9"
-       Pop $0
-
-        ${VersionCompare} "$0" "${DLL_VER2}" $R1
-
-        StrCmp $R1 0 0 new
-      new:
-        StrCmp $R1 1 0 old
-      old:
-        StrCmp $R1 2 0 end
-       ; Found DLL is older
-        Call PythonInstall
-
-     end:
-       StrCpy "$0" StopLocate
-       StrCpy $DLL_found "true"
-       Push "$0"
-
-FunctionEnd
-
 Function DownloadDLL
-    MessageBox MB_OK "You will need to download the Microsoft Visual C++ 2005 Redistributable Package in order to run Blender. Pressing OK will take you to the download page, please follow the instructions on the page that appears."
-    StrCpy $0 "http://www.microsoft.com/downloads/details.aspx?familyid=32BC1BEE-A3F9-4C13-9C99-220B62A191EE&displaylang=en"
+    MessageBox MB_OK "You will need to download the Microsoft Visual C++ 2008 Redistributable Package in order to run Blender. Pressing OK will take you to the download page, please follow the instructions on the page that appears."
+    StrCpy $0 "http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&DisplayLang=en"
     Call openLinkNewWindow
 FunctionEnd
 
 Function PythonInstall
-    MessageBox MB_OK "You will need to install python 2.5 in order to run blender. Pressing OK will take you to the python.org website."
+    MessageBox MB_OK "You will need to install python 2.5.2 in order to run blender. Pressing OK will take you to the python.org website."
     StrCpy $0 "http://www.python.org"
     Call openLinkNewWindow
 FunctionEnd
@@ -359,19 +337,19 @@ Section "Blender-VERSION (required)" SecCopyUI
   WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Blender" "UninstallString" '"$INSTDIR\uninstall.exe"'
   WriteUninstaller "uninstall.exe"
 
+  IfSilent 0 +2
+    Goto silentdone
   ; Check for msvcr80.dll - give notice to download if not found
   MessageBox MB_OK "The installer will now check your system for the required system dlls."
   StrCpy $1 $WINDIR
   StrCpy $DLL_found "false"
-  ${Locate} "$1" "/L=F /M=MSVCR80.DLL /S=0B" "LocateCallback_80"
+  ${Locate} "$1" "/L=F /M=MSVCR90.DLL /S=0B" "LocateCallback_90"
   StrCmp $DLL_found "false" 0 +2
     Call DownloadDLL
-  StrCpy $1 $WINDIR
-  StrCpy $DLL_found "false"
-  ${Locate} "$1" "/L=F /M=MSVCR71.DLL /S=0B" "LocateCallback_71"
-  StrCmp $DLL_found "false" 0 +2
+  ReadRegStr $0 HKLM SOFTWARE\Python\PythonCore\2.5\InstallPath ""
+  StrCmp $0 "" 0 +2
     Call PythonInstall
-  
+silentdone:
 SectionEnd
 
 Section "Add Start Menu shortcuts" Section2
@@ -424,7 +402,7 @@ Section "Uninstall"
   Delete "$DESKTOP\Blender.lnk"
   ; remove directories used.
   RMDir /r $BLENDERHOME\.blender\locale
-  MessageBox MB_YESNO "Erase .blender\scripts folder? (ALL contents will be erased!)" IDNO Next
+  MessageBox MB_YESNO "Erase .blender\scripts folder? (ALL contents will be erased!)" /SD IDYES IDNO Next
   RMDir /r $BLENDERHOME\.blender\scripts
   RMDir /r $BLENDERHOME\.blender\scripts\bpymodules
   RMDir /r $BLENDERHOME\.blender\scripts\bpydata
index 421b4300c8a6e2c20e4baff3d90a32b8222a5501..1806fa18ea9d32dc0a01f74bd46dd36815d5c9e6 100644 (file)
@@ -40,8 +40,8 @@ extern "C" {
 struct ListBase;
 struct MemFile;
 
-#define BLENDER_VERSION                        247
-#define BLENDER_SUBVERSION             10
+#define BLENDER_VERSION                        248
+#define BLENDER_SUBVERSION             0
 
 #define BLENDER_MINVERSION             245
 #define BLENDER_MINSUBVERSION  15
index eeec4d0bd4e8ce5570e93270d81c1041cd8931be..b389f8c0536aa912e8fb0195138e478c2213925b 100644 (file)
@@ -78,6 +78,7 @@ BulletSoftBody *bsbNew(void)
 
        bsb->kSHR                       =       1.0f;
        bsb->kAHR                       =       0.7f;
+       
        bsb->collisionflags = 0;
        //bsb->collisionflags = OB_BSB_COL_CL_RS + OB_BSB_COL_CL_SS;
        bsb->numclusteriterations = 64;
index b8f5b467c11ca3e972342920b8ce77f1cd6dd589..775f1dee241be01f004eaf36475697bd71e07d21 100644 (file)
@@ -1313,16 +1313,18 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                
                coll_ob = base->object;
                
+               if(coll_ob == self)
+                               continue;
+               
                if(coll_ob->pd && coll_ob->pd->deflect)
                {
                        collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
                }
+               else
+                       collmd = NULL;
                
                if ( collmd )
-               {
-                       if(coll_ob == self)
-                               continue;
-                       
+               {       
                        if(numobj >= maxobj)
                        {
                                // realloc
@@ -1351,16 +1353,18 @@ CollisionModifierData **get_collisionobjects(Object *self, int *numcollobj)
                                        coll_ob = go->ob;
                                        collmd = NULL;
                                        
+                                       if(coll_ob == self)
+                                               continue;
+                                       
                                        if(coll_ob->pd && coll_ob->pd->deflect)
                                        {
                                                collmd = ( CollisionModifierData * ) modifiers_findByType ( coll_ob, eModifierType_Collision );
                                        }
+                                       else
+                                               collmd = NULL;
 
                                        if ( !collmd )
                                                continue;
-
-                                       if(coll_ob == self)
-                                               continue;
                                        
                                        if( !collmd->bvhtree)
                                                continue;
index f83f66daa852579693ef0eae8844205bddf619f2..79ecbf09f55f446b43a6e08ef81b46c9757e100b 100644 (file)
@@ -352,7 +352,10 @@ IDProperty *IDP_GetProperties(ID *id, int create_if_needed)
                if (create_if_needed) {
                        id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty");
                        id->properties->type = IDP_GROUP;
-                       strcpy(id->name, "top_level_group");
+                       /* dont overwite the data's name and type
+                        * some functions might need this if they
+                        * dont have a real ID, should be named elsewhere - Campbell */
+                       /* strcpy(id->name, "top_level_group");*/
                }
                return id->properties;
        }
index 185705150571cda9e438bf98c0827cf306356d42..d5166fc7a838d49075edf8c501eb3407f5e3ff55 100644 (file)
@@ -1571,7 +1571,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f
                        ibuf->channels= rpass->channels;
                        
                        image_initialize_after_load(ima, ibuf);
-                       image_assign_ibuf(ima, ibuf, iuser->multi_index, frame);
+                       image_assign_ibuf(ima, ibuf, iuser?iuser->multi_index:0, frame);
                        
                }
                // else printf("pass not found\n");
index dd6c7ddacd20cb0cdb0afbd229bc366b7aca547b..755a41ec4b284f602045b1924cee6e6ca375a958 100644 (file)
@@ -284,10 +284,10 @@ void set_four_ipo(float d, float *data, int type)
                }
                else if(type==KEY_BSPLINE) {
 
-                       data[0]= -0.1666f*d3    +0.5f*d2        -0.5f*d +0.16666f;
-                       data[1]= 0.5f*d3                -d2                             +0.6666f;
-                       data[2]= -0.5f*d3               +0.5f*d2        +0.5f*d +0.1666f;
-                       data[3]= 0.1666f*d3                     ;
+                       data[0]= -0.16666666f*d3        +0.5f*d2        -0.5f*d +0.16666666f;
+                       data[1]= 0.5f*d3                -d2                             +0.6666666f;
+                       data[2]= -0.5f*d3               +0.5f*d2        +0.5f*d +0.16666666f;
+                       data[3]= 0.16666666f*d3                 ;
                }
        }
 }
@@ -313,10 +313,10 @@ void set_afgeleide_four_ipo(float d, float *data, int type)
                }
                else if(type==KEY_BSPLINE) {
 
-                       data[0]= -0.1666f*3.0f*d2       +d      -0.5f;
+                       data[0]= -0.16666666f*3.0f*d2   +d      -0.5f;
                        data[1]= 1.5f*d2                -2.0f*d;
                        data[2]= -1.5f*d2               +d      +0.5f;
-                       data[3]= 0.1666f*3.0f*d2                        ;
+                       data[3]= 0.16666666f*3.0f*d2                    ;
                }
        }
 }
index c3dddf06e7c0df668276d404ef1f14323dfcb6a8..3d1b342bf732d88f942d0aa50abdac1e1cd9611a 100644 (file)
@@ -407,6 +407,10 @@ void *copy_libblock(void *rt)
        lb= wich_libbase(G.main, GS(id->name));
        idn= alloc_libblock(lb, GS(id->name), id->name+2);
        
+       if(idn==NULL) {
+               printf("ERROR: Illegal ID name for %s (Crashing now)\n", id->name);
+       }
+       
        idn_len= MEM_allocN_len(idn);
        if(idn_len - sizeof(ID) > 0) {
                cp= (char *)id;
index b9a60ca9329ee264c39b7195133d83d1a8093faf..13dc2e834f234de04fa532aec14fec4932adb325 100644 (file)
@@ -7759,6 +7759,8 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
        tsmd->keepDist  = smd->keepDist;
        tsmd->shrinkType= smd->shrinkType;
        tsmd->shrinkOpts= smd->shrinkOpts;
+       tsmd->projAxis = smd->projAxis;
+       tsmd->subsurfLevels = smd->subsurfLevels;
 }
 
 CustomDataMask shrinkwrapModifier_requiredDataMask(ModifierData *md)
index 259a4e0de0409588b4fb1415d0037f365ab59986..4d312632b1a8645880d57fca706d0d02f9fb0d63 100644 (file)
@@ -642,6 +642,10 @@ static void multires_update_vertices(Mesh *me, EditMesh *em)
        MultiApplyData data;
        int i, j;
 
+       /* XXX added this to prevent crash, but if it works? (ton) */
+       if(me->mr->verts==NULL)
+               return;
+       
        /* Prepare deltas */
        pr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 1");
        cr_deltas= MEM_callocN(sizeof(vec3f)*last_lvl->totvert, "multires deltas 2");
index 4a4278a05f8f4ad6c5a97db5bb26235ba8d2caa5..39226faff1e9275791a431384deacd7e7264e208 100644 (file)
@@ -3101,7 +3101,7 @@ static void deflect_particle(Object *pob, ParticleSystemModifierData *psmd, Part
                                col.md = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
                                col.ob_t = ob;
 
-                               if(col.md->bvhtree)
+                               if(col.md && col.md->bvhtree)
                                        BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
                        }
                }
index e7fa3332f435ac27fcc9209fa88bc405101510e8..858aa6e60bf96582c5379469b431d79d27bd0681 100644 (file)
@@ -78,10 +78,7 @@ char *PIL_dynlib_get_error_as_string(PILdynlib* lib) {
 
        /* if lib is NULL reset the last error code */
        err= GetLastError();
-       if (!lib) {
-               SetLastError(ERROR_SUCCESS);
-               err = ERROR_SUCCESS;
-       }
+       if (!lib) SetLastError(ERROR_SUCCESS);
 
        if (err) {
                static char buf[1024];
@@ -96,7 +93,7 @@ char *PIL_dynlib_get_error_as_string(PILdynlib* lib) {
                        return buf;
        }
        
-       return "unrecognized error";
+       return err;
 }
 
 void PIL_dynlib_close(PILdynlib *lib) {
index 2acbbbe6712c8197c67957c7961cf5640dd718d2..ebd8f4be1cfebdf0a0dc6fbba0ff45c177a71f7c 100644 (file)
@@ -95,12 +95,12 @@ char *BLI_last_slash(const char *string) {
 void BLI_add_slash(char *string) {
        int len = strlen(string);
 #ifdef WIN32
-       if (string[len-1]!='\\') {
+       if (len==0 || string[len-1]!='\\') {
                string[len] = '\\';
                string[len+1] = '\0';
        }
 #else
-       if (string[len-1]!='/') {
+       if (len==0 || string[len-1]!='/') {
                string[len] = '/';
                string[len+1] = '\0';
        }
@@ -303,7 +303,8 @@ void BLI_recurdir_fileops(char *dirname) {
 int BLI_rename(char *from, char *to) {
        if (!BLI_exists(from)) return 0;
 
-       if (BLI_exists(to))
+       /* make sure the filenames are different (case insensitive) before removing */
+       if (BLI_exists(to) && BLI_strcasecmp(from, to))
                if(BLI_delete(to, 0, 0)) return 1;
                
        return rename(from, to);
index 25f9e179ca901cbc1aed8775eedef452cc310b11..c2dcc86ae41dbf90716923b6fe386b7c7dd914ab 100644 (file)
@@ -7767,23 +7767,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
 
        /* sun/sky */
        if(main->versionfile < 246) {
-               Lamp *la;
                Object *ob;
                bActuator *act;
 
-               for(la=main->lamp.first; la; la= la->id.next) {
-                       la->sun_effect_type = 0;
-                       la->horizon_brightness = 1.0;
-                       la->spread = 1.0;
-                       la->sun_brightness = 1.0;
-                       la->sun_size = 1.0;
-                       la->backscattered_light = 1.0;
-                       la->atm_turbidity = 2.0;
-                       la->atm_inscattering_factor = 1.0;
-                       la->atm_extinction_factor = 1.0;
-                       la->atm_distance_factor = 1.0;
-                       la->sun_intensity = 1.0;
-               }
                /* dRot actuator change direction in 2.46 */
                for(ob = main->object.first; ob; ob= ob->id.next) {
                        for(act= ob->actuators.first; act; act= act->next) {
@@ -7938,7 +7924,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                                        bMessageActuator *msgAct = (bMessageActuator *) act->data;
                                        if (strlen(msgAct->toPropName) > 2) {
                                                /* strip first 2 chars, would have only worked if these were OB anyway */
-                                               strncpy(msgAct->toPropName, msgAct->toPropName+2, sizeof(msgAct->toPropName));
+                                               memmove( msgAct->toPropName, msgAct->toPropName+2, sizeof(msgAct->toPropName)-2 );
                                        } else {
                                                msgAct->toPropName[0] = '\0';
                                        }
@@ -7946,6 +7932,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        }
                }
        }
+
+       if (main->versionfile < 248) {
+               Lamp *la;
+
+               for(la=main->lamp.first; la; la= la->id.next) {
+                       if(la->atm_turbidity == 0.0) {
+                               la->sun_effect_type = 0;
+                               la->horizon_brightness = 1.0;
+                               la->spread = 1.0;
+                               la->sun_brightness = 1.0;
+                               la->sun_size = 1.0;
+                               la->backscattered_light = 1.0;
+                               la->atm_turbidity = 2.0;
+                               la->atm_inscattering_factor = 1.0;
+                               la->atm_extinction_factor = 1.0;
+                               la->atm_distance_factor = 1.0;
+                               la->sun_intensity = 1.0;
+                       }
+               }
+       }
        
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
index 3813fe3da8ec8cb25fc5d002230ebb561ef1e5f4..66b1944941927919a4493ebe14ca83b8bb1ef96c 100644 (file)
@@ -51,6 +51,7 @@ typedef struct GPUFrameBuffer GPUFrameBuffer;
 struct GPUShader;
 typedef struct GPUShader GPUShader;
 
+void GPU_extensions_disable(void);
 void GPU_extensions_init(void); /* call this before running any of the functions below */
 void GPU_extensions_exit(void);
 int GPU_extensions_minimum_support(void);
index 85a1a059b75e41b13333306ce42554b0bffb9a69..4025a12a867ba993b08518af1575124d311206c8 100644 (file)
@@ -220,12 +220,24 @@ static int gpu_get_mipmap(void)
        return GTS.domipmap && (!(G.f & G_TEXTUREPAINT));
 }
 
-static GLenum gpu_get_mipmap_filter()
+static GLenum gpu_get_mipmap_filter(int mag)
 {
-       /* linearmipmap is off by default
-        * when mipmapping is off, use unfiltered display */
-       return GTS.linearmipmap? GL_LINEAR_MIPMAP_LINEAR :
-                               (GTS.domipmap ? GL_LINEAR_MIPMAP_NEAREST : GL_NEAREST);
+       /* linearmipmap is off by default *when mipmapping is off,
+        * use unfiltered display */
+       if(mag) {
+               if(GTS.linearmipmap || GTS.domipmap)
+                       return GL_LINEAR;
+               else
+                       return GL_NEAREST;
+       }
+       else {
+               if(GTS.linearmipmap)
+                       return GL_LINEAR_MIPMAP_LINEAR;
+               else if(GTS.domipmap)
+                       return GL_LINEAR_MIPMAP_NEAREST;
+               else
+                       return GL_NEAREST;
+       }
 }
 
 /* Set OpenGL state for an MTFace */
@@ -359,6 +371,8 @@ int GPU_verify_image(Image *ima, int tftile, int tfmode, int compare)
        else
                GTS.tile= tftile;
 
+       GTS.tile = MAX2(0, GTS.tile);
+
        if(ima) {
                GTS.tileXRep = ima->xrep;
                GTS.tileYRep = ima->yrep;
@@ -477,12 +491,12 @@ int GPU_verify_image(Image *ima, int tftile, int tfmode, int compare)
        if (!gpu_get_mipmap()) {
                glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA,  rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter());
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
        }
        else {
                gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, rectw, recth, GL_RGBA, GL_UNSIGNED_BYTE, rect);
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter());
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter());
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
 
                ima->tpageflag |= IMA_MIPMAP_COMPLETE;
        }
@@ -574,8 +588,8 @@ void GPU_paint_set_mipmap(int mipmap)
                        if(ima->bindcode) {
                                if(ima->tpageflag & IMA_MIPMAP_COMPLETE) {
                                        glBindTexture(GL_TEXTURE_2D, ima->bindcode);
-                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter());
-                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter());
+                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
+                                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
                                }
                                else
                                        GPU_free_image(ima);
@@ -588,7 +602,7 @@ void GPU_paint_set_mipmap(int mipmap)
                        if(ima->bindcode) {
                                glBindTexture(GL_TEXTURE_2D, ima->bindcode);
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter());
+                               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
                        }
                }
        }
index a8dc369460cd656c1d1270116d832c046decb9ff..7654c67419bf29f26591dad685904bce8f94fc0c 100644 (file)
        - arb draw buffers? 2.0 core
 */
 
-struct GPUGlobal {
+static struct GPUGlobal {
        GLint maxtextures;
        GLuint currentfb;
        int minimumsupport;
-} GG = {1, 0, 0};
+       int extdisabled;
+} GG = {1, 0, 0, 0};
+
+void GPU_extensions_disable()
+{
+       GG.extdisabled = 1;
+}
 
 void GPU_extensions_init()
 {
@@ -89,7 +95,7 @@ void GPU_extensions_init()
 
 int GPU_extensions_minimum_support()
 {
-       return GG.minimumsupport;
+       return !GG.extdisabled && GG.minimumsupport;
 }
 
 int GPU_print_error(char *str)
index 6dff5802c31ab6aea21c8b04d7bcbb10fcc73553..46df003cbbc0116cf51fe25a6b5875e6b82b7085 100644 (file)
@@ -693,7 +693,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
                                                shr->spec, &shr->spec);
                                
                                add_user_list(&mat->lamps, lamp);
-                               add_user_list(&lamp->materials, ma);
+                               add_user_list(&lamp->materials, shi->gpumat->ma);
                                return;
                        }
                        
@@ -702,7 +702,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
        }
        else if((G.fileflags & G_FILE_GLSL_NO_SHADOWS) && (lamp->mode & LA_ONLYSHADOW)) {
                add_user_list(&mat->lamps, lamp);
-               add_user_list(&lamp->materials, ma);
+               add_user_list(&lamp->materials, shi->gpumat->ma);
                return;
        }
        else
@@ -755,7 +755,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
        }
 
        add_user_list(&mat->lamps, lamp);
-       add_user_list(&lamp->materials, ma);
+       add_user_list(&lamp->materials, shi->gpumat->ma);
 }
 
 static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
@@ -928,7 +928,7 @@ static void do_material_tex(GPUShadeInput *shi)
                        else if(mtex->texco==TEXCO_OBJECT)
                                texco= texco_object;
                        else if(mtex->texco==TEXCO_NORM)
-                               texco= texco_norm;
+                               texco= orn;
                        else if(mtex->texco==TEXCO_TANGENT)
                                texco= texco_object;
                        else if(mtex->texco==TEXCO_GLOB)
@@ -1362,10 +1362,14 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
 
 static void gpu_lamp_shadow_free(GPULamp *lamp)
 {
-       if(lamp->tex)
+       if(lamp->tex) {
                GPU_texture_free(lamp->tex);
-       if(lamp->fb)
+               lamp->tex= NULL;
+       }
+       if(lamp->fb) {
                GPU_framebuffer_free(lamp->fb);
+               lamp->fb= NULL;
+       }
 }
 
 GPULamp *GPU_lamp_from_blender(Scene *scene, Object *ob, Object *par)
index 2959ed654abe9e1c07f53d367c31b27acd7ffb86..514d6b5522b623d4c07c945e18a944dceb408dc4 100644 (file)
 
 static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
 {
-       params->blackPoint = G.scene->r.cineonblack;
-       params->whitePoint = G.scene->r.cineonwhite;
-       params->gamma = G.scene->r.cineongamma;
-       params->doLogarithm = G.scene->r.subimtype & R_CINEON_LOG;
+       params->blackPoint = G.scene?G.scene->r.cineonblack:95;
+       params->whitePoint = G.scene?G.scene->r.cineonwhite:685;
+       params->gamma = G.scene?G.scene->r.cineongamma:1.7f;
+       params->doLogarithm = G.scene?G.scene->r.subimtype & R_CINEON_LOG:0;
 }
 
 static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
index ecee3c7d6c0a3ddb23cfa835072f13e44ebd5e14..75516bbf3ae8a28bc9fdd2774ccd6049d054357e 100644 (file)
@@ -617,7 +617,7 @@ cineonOpenFromMem(unsigned char *mem, unsigned int size) {
        
        cineon->file = 0;
        cineon->reading = 1;
-       verbose = 1;
+       verbose = 0;
        if (size < sizeof(CineonGenericHeader)) {
                if (verbose) d_printf("Not enough data for header!\n");
                cineonClose(cineon);
index 1710cdde501fc6cd4e2d005b565cc47812734546..8a9adc73cdc1a1e010caa767b1d086ac79e91c2f 100644 (file)
@@ -199,7 +199,7 @@ dumpDpxMainHeader(DpxMainHeader* header) {
 #endif
 }
 
-static int verbose = 1;
+static int verbose = 0;
 void
 dpxSetVerbose(int verbosity) {
        verbose = verbosity;
index b057e3f8bd26ae6d60514c25f09c17280ce44f4f..b9186e482c5c6ac90ac1a4fd4cc2d7f1d49a0c7f 100644 (file)
@@ -106,8 +106,11 @@ void *libtiff_findsymbol(char *name)
        assert(libtiff != NULL);
        symbol = PIL_dynlib_find_symbol(libtiff, name);
        if (symbol == NULL) {
-               printf("libtiff_findsymbol: error %s\n",
-                       PIL_dynlib_get_error_as_string(libtiff));
+               char *err = PIL_dynlib_get_error_as_string(libtiff);
+
+               if (err) printf("libtiff_findsymbol: error %s\n",err);
+               else printf("libtiff_findsymbol: error Unknown.\n");
+
                libtiff = NULL;
                G.have_libtiff = (0);
                return NULL;
index 82263c8cda776a9e6d2d0e32b238c4cf38d9c172..6af156775bea5f34ef9feac0f33b62db740dc006 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: BDR_gpencil.h 14444 2008-04-16 22:40:48Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
index eacafce058d92e5ec064372a839b314c2827fe13..ae2ec192cc789775664d3f18eff9ced53797f69a 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_drawgpencil.h 14444 2008-04-16 22:40:48Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
index 9f85e69b77fcb5bb2e60ae7e778c942b3f12310b..dbbe55123e409a497659a43e4a47c1bc36b1a462 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: BIF_keyframing.h 14444 2008-04-16 22:40:48Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
index ecfb7dc7a90106742de3d2232ba501dcd6c7d225..fe19cf60f12fe44a38882ef46cd7b3846b19645e 100644 (file)
@@ -520,6 +520,7 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG {
 
 /* Rigid-Body Constraint */
 #define CONSTRAINT_DRAW_PIVOT 0x40
+#define CONSTRAINT_DISABLE_LINKED_COLLISION 0x80
 
 /* important: these defines need to match up with PHY_DynamicTypes headerfile */
 #define CONSTRAINT_RB_BALL             1
index cc0c99120572ca33ce3d6539e99d61537e59a82a..70f469b2bb8fc80840ce8055bd5f6cb786fa0f5d 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: DNA_gpencil_types.h 8768 2006-11-07 00:10:37Z aligorith $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
index fdf08c737982da3c4fe2ab7f02878a7376a1d8cc..fbd962f937216606171df38b4d74b57d403279c3 100644 (file)
@@ -327,7 +327,8 @@ extern UserDef U; /* from usiblender.c !!!! */
 /* tw_flag (transform widget) */
 
 /* gp_settings (Grease Pencil Settings) */
-#define GP_PAINT_DOSMOOTH      (1<<0)
+#define GP_PAINT_DOSMOOTH              (1<<0)
+#define GP_PAINT_DOSIMPLIFY            (1<<1)
 
 
 #endif
index 69b50e5c47abb944dfbaf231ffd62fef929798c2..9e7abc446575a870327c8fb681ec65cd2d595cc7 100644 (file)
@@ -479,7 +479,7 @@ static int bpymenu_CreateFromFile( void )
        char line[255], w1[255], w2[255], tooltip[255], *tip;
        char upythondir[FILE_MAX];
        char *homedir = NULL;
-       int parsing, version, is_userdir;
+       int parsing, version, w2_len, is_userdir;
        short group;
        BPyMenu *pymenu = NULL;
 
@@ -554,17 +554,32 @@ will use 'Misc'.\n", w1 );
                        else if( line[0] == '\n' )
                                continue;
                        else if( line[0] == '\'' ) {    /* menu entry */
-                               parsing =
+/*                             parsing =
                                        sscanf( line,
                                                "'%[^']' %d %s %d '%[^']'\n",
                                                w1, &version, w2, &is_userdir,
                                                tooltip );
-
-                               if( parsing <= 0 ) {    /* invalid line, get rid of it */
+*/
+                               /* previously filenames with spaces were not supported;
+                                * this adds support for that w/o breaking the existing
+                                * few, exotic scripts that parse the Bpymenus file */
+                               parsing = sscanf( line,
+                                               "'%[^']' %d %[^'\n] '%[^']'\n",
+                                               w1, &version, w2, tooltip );
+                               if( parsing <= 0 ) { /* invalid line, get rid of it */
                                        fgets( line, 255, fp );
-                               } else if( parsing == 5 )
+                               } else if( parsing == 4 )
                                        tip = tooltip;  /* has tooltip */
 
+                               w2_len = strlen(w2);
+                               if( w2[w2_len-1] == ' ') {
+                                       w2[w2_len-1] = '\0';
+                                       w2_len -= 1;
+                               }
+                               if( w2[w2_len-1] == '1') is_userdir = 1;
+                               else is_userdir = 0;
+                               w2[w2_len-2] = '\0';
+
                                pymenu = bpymenu_AddEntry( group,
                                                           ( short ) version,
                                                           w1, w2, is_userdir,
@@ -693,13 +708,7 @@ void BPyMenu_PrintAllEntries( void )
 }
 
 /* bpymenu_ParseFile:
- * recursively scans folders looking for scripts to register.
- *
- * This function scans the scripts directory looking for .py files with the
- * right header and menu info, using that to fill the bpymenu structs.
- * is_userdir defines if the script is in the default scripts dir or the
- * user defined one (U.pythondir: is_userdir == 1).
- * Speed is important.
+ * parse a given .py file looking for a proper header.
  *
  * The first line of the script must be '#!BPY'.
  * The header registration lines must appear between the first pair of
index 27dd510f944343e0f075ee2ee5b87e7bea7e3c10..1f0cbd2c86d9828bfb88eb4ab0de3d49f5d50b24 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 Import ('env')
 
-sources = Split('BPY_interface.c BPY_menus.c') + env.Glob('api2_2x/*.c')
+sources = env.Glob('*.c') + env.Glob('api2_2x/*.c')
 
 incs = 'api2_2x ../blenkernel ../nodes ../blenlib ../blenloader'
 incs += ' ../render/extern/include ../radiosity/extern/include'
index acf18ac60589164e1b951f289719bd8fec82a738..dab2d49df0c876f93818059dfebe5d4c27669d8b 100644 (file)
@@ -923,7 +923,7 @@ AttributeError:
                sArmatureError, "You are not allowed to change the .Bones attribute");
 }
 
-//------------------------Bone.layerMask (get)
+//------------------------Armature.layerMask (get)
 static PyObject *Armature_getLayerMask(BPy_Armature *self)
 {
        /* do this extra stuff because the short's bits can be negative values */
@@ -931,7 +931,7 @@ static PyObject *Armature_getLayerMask(BPy_Armature *self)
        laymask |= self->armature->layer;
        return PyInt_FromLong((int)laymask);
 }
-//------------------------Bone.layerMask (set)
+//------------------------Armature.layerMask (set)
 static int Armature_setLayerMask(BPy_Armature *self, PyObject *value)
 {
        int laymask;
@@ -1295,6 +1295,26 @@ static PyObject *M_Armature_New(PyObject * self, PyObject * args)
        return (PyObject *)obj;
 }
 
+static PyObject *M_Armature_DataSize(PyObject * self, PyObject *args)
+{
+       int t = 0;
+       int ret = 0;
+       if( !PyArg_ParseTuple(args, "|i", &t))
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                                               "expected nothing or an int as argument" );
+       
+       switch(t) {
+               case 0:
+                       ret = sizeof(struct bArmature);
+                       break;
+               default:
+                       ret = sizeof(struct Bone);
+                       break;
+       }
+       
+       return PyInt_FromLong(ret);
+}
+
 
 //-------------------MODULE METHODS DEFINITION-----------------------------
 
@@ -1304,9 +1324,12 @@ static char M_Armature_Get_doc[] = "(name) - return the armature with the name '
 
 static char M_Armature_New_doc[] = "(name) - return a new armature object.";
 
+static char M_Armature_DataSize_doc[] = "(type) - return sizeof of either Armature (0) or Bone (1).";
+
 struct PyMethodDef M_Armature_methods[] = {
        {"Get", M_Armature_Get, METH_VARARGS, M_Armature_Get_doc},
        {"New", M_Armature_New, METH_VARARGS, M_Armature_New_doc},
+       {"DataSize", M_Armature_DataSize, METH_VARARGS, M_Armature_DataSize_doc},
        {NULL, NULL, 0, NULL}
 };
 //------------------VISIBLE PROTOTYPE IMPLEMENTATION-----------------------
index 4a8cba30e8e6a8b87c53d0cf03f25919f0394ecb..5dfb52f2733c0e61163c50a68d3b9f3469b51beb 100644 (file)
@@ -41,6 +41,7 @@
 #include "MEM_guardedalloc.h"
 #include "DNA_ipo_types.h"
 #include "DNA_key_types.h"
+#include "DNA_scene_types.h"
 #include "BezTriple.h"
 #include "gen_utils.h"
 
@@ -80,6 +81,7 @@ static PyObject *IpoCurve_getExtrapolation( C_IpoCurve * self );
 static PyObject *IpoCurve_newgetExtend( C_IpoCurve * self );
 static int IpoCurve_newsetExtend( C_IpoCurve * self, PyObject * args );
 static PyObject *IpoCurve_getPoints( C_IpoCurve * self );
+static PyObject *IpoCurve_clean( C_IpoCurve * self, PyObject *value );
 static PyObject *IpoCurve_evaluate( C_IpoCurve * self, PyObject * args );
 static PyObject *IpoCurve_getDriver( C_IpoCurve * self );
 static int IpoCurve_setDriver( C_IpoCurve * self, PyObject * args );
@@ -127,6 +129,8 @@ static PyMethodDef C_IpoCurve_methods[] = {
         "() - Returns list of all bezTriples of the curve"},
        {"evaluate", ( PyCFunction ) IpoCurve_evaluate, METH_VARARGS,
         "(float) - Evaluate curve at given time"},
+       {"clean", ( PyCFunction ) IpoCurve_clean, METH_VARARGS,
+        "(float) - Clean BezTriples using the given threshold value"},
        {NULL, NULL, 0, NULL}
 };
 
@@ -770,6 +774,29 @@ static PyObject *IpoCurve_evaluate( C_IpoCurve * self, PyObject * args )
 
 }
 
+/***************************************************************************/
+/* Function:      IpoCurve_clean( thresh )                                */
+/* Description:   Cleans IPO curve with the (optional) threshold.         */
+/***************************************************************************/
+static PyObject *IpoCurve_clean( C_IpoCurve * self, PyObject * args )
+{
+       float thresh, othresh;
+       
+       thresh= othresh= G.scene->toolsettings->clean_thresh;
+       
+       /* expecting float */
+       if( !PyArg_ParseTuple( args, "|f", &thresh ) )
+               return ( EXPP_ReturnPyObjError
+                        ( PyExc_TypeError, "expected float argument" ) );
+       
+       /* set IPO-cleaning threshold based on value provided by user (temporarily) */
+       G.scene->toolsettings->clean_thresh= thresh;
+       clean_ipo_curve( self->ipocurve );
+       G.scene->toolsettings->clean_thresh= othresh;
+
+       Py_RETURN_NONE;
+}
+
 static PyObject *IpoCurve_getDriver( C_IpoCurve * self )
 {
        if( !self->ipocurve->driver )
index ef19fab462a67f1b5eac96a096c7c2a2a5415937..02fdc32c5c93f37c7975a1bcde2d0d64227039ad 100644 (file)
 #define EXPP_MAT_SUBSIZE_MAX                   25.0
 
 #define EXPP_MAT_HARD_MIN                               1
-#define EXPP_MAT_HARD_MAX               255    /* 127 with MODE HALO ON */
+#define EXPP_MAT_HARD_MAX               511    /* 127 with MODE HALO ON */
 #define EXPP_MAT_HALOSEED_MIN           0
 #define EXPP_MAT_HALOSEED_MAX    255
 #define EXPP_MAT_NFLARES_MIN            1
 static PyObject *M_Material_New( PyObject * self, PyObject * args,
                                 PyObject * keywords );
 static PyObject *M_Material_Get( PyObject * self, PyObject * args );
+static PyObject *M_Material_DataSize(PyObject *unused);
 
 /*****************************************************************************/
 /* The following string definitions are used for documentation strings.  In  */
@@ -231,6 +232,8 @@ struct PyMethodDef M_Material_methods[] = {
         M_Material_New_doc},
        {"Get", M_Material_Get, METH_VARARGS, M_Material_Get_doc},
        {"get", M_Material_Get, METH_VARARGS, M_Material_Get_doc},
+       {"DataSize", ( PyCFunction ) M_Material_DataSize, METH_NOARGS,
+               "Get sizeof() of Material"},
        {NULL, NULL, 0, NULL}
 };
 
@@ -335,6 +338,12 @@ static PyObject *M_Material_Get( PyObject * self, PyObject * args )
        }
 }
 
+static PyObject *M_Material_DataSize(PyObject *unused)
+{
+       return PyInt_FromLong(sizeof(Material));
+}
+
+
 static PyObject *Material_ModesDict( void )
 {
        PyObject *Modes = PyConstant_New(  );
index d513a8be4db8ea6e979cba0c4bf76daf1d8299e8..fdecd66f5e257979db16e7271f381d7237ab2254 100644 (file)
@@ -8637,6 +8637,35 @@ static PyObject *M_Mesh_MVert( PyObject * self_unused, PyObject * args )
        return PVert_CreatePyObject( &vert );
 }
 
+static PyObject *M_Mesh_DataSize(PyObject * self, PyObject *args)
+{
+       int t = 0;
+       int ret = 0;
+       if( !PyArg_ParseTuple(args, "|i", &t))
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                                               "expected nothing or an int as argument" );
+       
+       switch(t) {
+               case 0:
+                       ret = sizeof(Mesh);
+                       break;
+               case 1:
+                       ret = sizeof(MVert);
+                       break;
+               case 2:
+                       ret = sizeof(MEdge);
+                       break;
+               case 3:
+                       ret = sizeof(MFace);
+                       break;
+               default:
+                       ret = sizeof(Mesh);
+                       break;
+       }
+       
+       return PyInt_FromLong(ret);
+}
+
 static PyObject *M_Mesh_Modes( PyObject * self_unused, PyObject * args )
 {
        int modes = 0;
@@ -8668,6 +8697,8 @@ static struct PyMethodDef M_Mesh_methods[] = {
                "Create a new MVert"},
        {"Mode", (PyCFunction)M_Mesh_Modes, METH_VARARGS,
                "Get/set edit selection mode(s)"},
+       {"DataSize", (PyCFunction)M_Mesh_DataSize, METH_VARARGS,
+               "Get sizeof() of Mesh (0), MVert (1), MEdge (2) or MFace (3)"},
        {NULL, NULL, 0, NULL},
 };
 
index 4495dc6c65555f3fcd27fe837b634b85fc8f8595..f14ac81fe247cad3415ae7e65ea16d6cbca80296 100644 (file)
@@ -290,6 +290,7 @@ static PyObject *M_Object_New( PyObject * self, PyObject * args );
 PyObject *M_Object_Get( PyObject * self, PyObject * args );
 static PyObject *M_Object_GetSelected( PyObject * self );
 static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args, PyObject *kwd);
+static PyObject *M_Object_DataSize( PyObject * self );
 
 /* HELPER FUNCTION FOR PARENTING */
 static PyObject *internal_makeParent(Object *parent, PyObject *py_child, int partype, int noninverse, int fast, int v1, int v2, int v3, char *bonename);
@@ -299,25 +300,27 @@ static PyObject *internal_makeParent(Object *parent, PyObject *py_child, int par
 /* In Python these will be written to the console when doing a          */
 /* Blender.Object.__doc__                                               */
 /*****************************************************************************/
-char M_Object_doc[] = "The Blender Object module\n\n\
+static char M_Object_doc[] = "The Blender Object module\n\n\
 This module provides access to **Object Data** in Blender.\n";
 
-char M_Object_New_doc[] =
+static char M_Object_New_doc[] =
        "(type) - Add a new object of type 'type' in the current scene";
 
-char M_Object_Get_doc[] =
+static char M_Object_Get_doc[] =
        "(name) - return the object with the name 'name', returns None if not\
        found.\n\
        If 'name' is not specified, it returns a list of all objects in the\n\
        current scene.";
 
-char M_Object_GetSelected_doc[] =
+static char M_Object_GetSelected_doc[] =
        "() - Returns a list of selected Objects in the active layer(s)\n\
 The active object is the first in the list, if visible";
 
-char M_Object_Duplicate_doc[] =
+static char M_Object_Duplicate_doc[] =
        "(linked) - Duplicate all selected, visible objects in the current scene";
 
+static char M_Object_DataSize_doc[] = 
+       "() - return the sizeof(Object)";
 
 /*****************************************************************************/
 /* Python method structure definition for Blender.Object module:        */
@@ -331,6 +334,8 @@ struct PyMethodDef M_Object_methods[] = {
         M_Object_GetSelected_doc},
        {"Duplicate", ( PyCFunction ) M_Object_Duplicate, METH_VARARGS | METH_KEYWORDS,
         M_Object_Duplicate_doc},
+       {"DataSize", ( PyCFunction ) M_Object_DataSize, METH_NOARGS,
+        M_Object_DataSize_doc},
        {NULL, NULL, 0, NULL}
 };
 
@@ -342,9 +347,8 @@ static int setupSB(Object* ob); /*Make sure Softbody Pointer is initialized */
 static int setupPI(Object* ob);
 
 static PyObject *Object_getParticleSys( BPy_Object * self );
-/* fixme Object_newParticleSys( self, default-partsys-name ) */
 static PyObject *Object_addVertexGroupsFromArmature( BPy_Object * self, PyObject * args);
-static PyObject *Object_newParticleSys( BPy_Object * self );
+static PyObject *Object_newParticleSys( BPy_Object * self, PyObject * args );
 static PyObject *Object_buildParts( BPy_Object * self );
 static PyObject *Object_clearIpo( BPy_Object * self );
 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
@@ -478,7 +482,7 @@ static PyMethodDef BPy_Object_methods[] = {
        /* name, method, flags, doc */
        {"getParticleSystems", ( PyCFunction ) Object_getParticleSys, METH_NOARGS,
         "Return a list of particle systems"},
-       {"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_NOARGS,
+       {"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_VARARGS,
         "Create and link a new particle system"},
        {"addVertexGroupsFromArmature" , ( PyCFunction ) Object_addVertexGroupsFromArmature, METH_VARARGS,
         "Add vertex groups from armature using the bone heat method"},
@@ -1038,48 +1042,59 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused,
        Py_RETURN_NONE;
 }
 
+static PyObject *M_Object_DataSize(PyObject * self)
+{
+       return PyInt_FromLong(sizeof(Object));
+}
+
 
 /*****************************************************************************/
 /* Python BPy_Object methods:                                  */
 /*****************************************************************************/
 
 PyObject *Object_getParticleSys( BPy_Object * self ){
-       ParticleSystem *blparticlesys = 0;
+       PyObject *list;
+       ParticleSystem *psys= NULL;
        Object *ob = self->object;
-       PyObject *partsyslist,*current;
-
-       blparticlesys = ob->particlesystem.first;
+       int i= 0;
 
-       partsyslist = PyList_New( 0 );
-
-       if (!blparticlesys)
-               return partsyslist;
-
-/* fixme:  for(;;) */
-       current = ParticleSys_CreatePyObject( blparticlesys, ob );
-       PyList_Append(partsyslist,current);
-       Py_DECREF(current);
+       list = PyList_New( BLI_countlist( &ob->particlesystem ) );
+       if( !list )
+               return EXPP_ReturnPyObjError( PyExc_MemoryError,
+                               "PyList_New() failed" );
 
-       while((blparticlesys = blparticlesys->next)){
-               current = ParticleSys_CreatePyObject( blparticlesys, ob );
-               PyList_Append(partsyslist,current);
-               Py_DECREF(current);
-       }
+       for( psys=ob->particlesystem.first; psys; psys=psys->next )
+               PyList_SET_ITEM( list, i++, ParticleSys_CreatePyObject( psys, ob ) );
 
-       return partsyslist;
+       return list;
 }
 
-PyObject *Object_newParticleSys( BPy_Object * self ){
+PyObject *Object_newParticleSys( BPy_Object * self, PyObject * args ) {
        ParticleSystem *psys = 0;
        ParticleSystem *rpsys = 0;
        ModifierData *md;
        ParticleSystemModifierData *psmd;
        Object *ob = self->object;
-/*     char *name = NULL;  optional name param */
+       char *name = NULL;
        ID *id;
-       int nr;
+       int nr; 
+
+       if( !PyArg_ParseTuple( args, "|s", &name ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected a string or nothing" );
 
-       id = (ID *)psys_new_settings("PSys", G.main);
+       if( name ) {
+               for( id= G.main->particle.first; id; id= id->next ) {
+                       if( !strcmp( name, id->name + 2 ) )
+                               break;
+               }
+               if( !id )
+                       return EXPP_ReturnPyObjError( PyExc_AttributeError,
+                                       "specified particle system not found" );
+               else
+                       id->us++;
+       } else
+               id = (ID *)psys_new_settings("PSys", G.main);
 
        psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
        psys->pointcache = BKE_ptcache_add();
index 893ee077d67e789407628e1e4ac3cdd1c612fa0b..bbdc3942fc7e64a04bd1145673d3d283f9f39470 100644 (file)
@@ -138,7 +138,7 @@ static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args );
 /*****************************************************************************/
 /* Python Effect_Type callback function prototypes:                           */
 /*****************************************************************************/
-static PyObject *ParticleSys_repr( void );
+static PyObject *ParticleSys_repr( BPy_PartSys * self );
 
 /*****************************************************************************/
 /* The following string definitions are used for documentation strings.      */
@@ -415,13 +415,14 @@ PyTypeObject ParticleSys_Type = {
 
 /*****************************************************************************/
 /* Function:    PARTICLESYS_repr                                             */
-/* Description: This is a callback function for the BPy_Effect type. It      */
-/*              builds a meaninful string to represent effcte objects.       */
+/* Description: This is a callback function for the BPy_PartSys type. It     */
+/*              builds a meaningful string to represent effect objects.      */
 /*****************************************************************************/
 
-static PyObject *ParticleSys_repr( void )
+static PyObject *ParticleSys_repr( BPy_PartSys * self )
 {
-       return PyString_FromString( "ParticleSys" );
+       return PyString_FromFormat( "ParticleSys \"%s\"",
+                       self->psys->part->id.name+2 );
 }
 
 /*****************************************************************************/
index a4c7802ff34d47406f3f43e4757c3299332c8279..40f6d52d8daa4b54140542a50560d4ac4ab1805b 100644 (file)
@@ -577,8 +577,6 @@ static PyObject * FileAndImageSelector(PyObject * self, PyObject * args, int typ
                        "\nexpected a callback function (and optionally one or two strings) "
                        "as argument(s)" );
 
-       Py_INCREF(pycallback);
-
 /* trick: we move to a spacescript because then the fileselector will properly
  * unset our SCRIPT_FILESEL flag when the user chooses a file or cancels the
  * selection.  This is necessary because when a user cancels, the
@@ -605,9 +603,18 @@ static PyObject * FileAndImageSelector(PyObject * self, PyObject * args, int typ
                script->lastspace = startspace;
                sc->script = script;
        }
-
+       
+       if (!script) {
+               /* should never happen unless we are executed
+               * from the BGE or somthing really strange like that */
+               return EXPP_ReturnPyObjError( PyExc_AttributeError,
+                       "Could not allocate a screen for an unknown reason." );
+       }
+       
+       Py_INCREF(pycallback);
+       
        script->flags |= SCRIPT_FILESEL;
-
+       
        /* clear any previous callback (nested calls to selector) */
        if (script->py_browsercallback) {
                Py_DECREF((PyObject *)script->py_browsercallback);
index 661042f341b8054380bcdaa7a018639006a5613a..4a10de4a05c5d41e5e4c513fe3644383c4125e8d 100644 (file)
@@ -146,11 +146,11 @@ def glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap):
 
   @type width, height: int
   @param width, height: Specify the pixel width and height of the bitmap image.
-  @type xorig,yorig: float
-  @param xorig,yorig: Specify the location of the origin in the bitmap image. The origin is measured
+  @type xorig, yorig: float
+  @param xorig, yorig: Specify the location of the origin in the bitmap image. The origin is measured
   from the lower left corner of the bitmap, with right and up being the positive axes.
-  @type xmove,ymove: float
-  @param xmove,ymove: Specify the x and y offsets to be added to the current raster position after 
+  @type xmove, ymove: float
+  @param xmove, ymove: Specify the x and y offsets to be added to the current raster position after 
   the bitmap is drawn. 
   @type bitmap: Buffer object I{type GL_BYTE}
   @param bitmap: Specifies the address of the bitmap image. 
@@ -207,8 +207,8 @@ def glClearAccum(red, green, blue, alpha):
   Specify clear values for the accumulation buffer
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearaccum.html}
 
-  @type red,green,blue,alpha: float
-  @param red,green,blue,alpha: Specify the red, green, blue, and alpha values used when the 
+  @type red, green, blue, alpha: float
+  @param red, green, blue, alpha: Specify the red, green, blue, and alpha values used when the 
   accumulation buffer is cleared. The initial values are all 0. 
   """
 
@@ -217,8 +217,8 @@ def glClearColor(red, green, blue, alpha):
   Specify clear values for the color buffers
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/clearcolor.html}
 
-  @type red,green,blue,alpha: float
-  @param red,green,blue,alpha: Specify the red, green, blue, and alpha values used when the 
+  @type red, green, blue, alpha: float
+  @param red, green, blue, alpha: Specify the red, green, blue, and alpha values used when the 
   color buffers are cleared. The initial values are all 0. 
   """
 
@@ -274,8 +274,8 @@ def glColor (red, green, blue, alpha):
   Set a new color.
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/color.html}
 
-  @type red,green,blue,alpha: Depends on function prototype. 
-  @param red,green,blue: Specify new red, green, and blue values for the current color. 
+  @type red, green, blue, alpha: Depends on function prototype. 
+  @param red, green, blue: Specify new red, green, and blue values for the current color. 
   @param alpha: Specifies a new alpha value for the current color. Included only in the 
   four-argument glColor4 commands. (With '4' colors only)
   """
@@ -285,8 +285,8 @@ def glColorMask(red, green, blue, alpha):
   Enable and disable writing of frame buffer color components
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/colormask.html}
 
-  @type red,green,blue,alpha: int (boolean)
-  @param red,green,blue,alpha: Specify whether red, green, blue, and alpha can or cannot be 
+  @type red, green, blue, alpha: int (boolean)
+  @param red, green, blue, alpha: Specify whether red, green, blue, and alpha can or cannot be 
   written into the frame buffer. The initial values are all GL_TRUE, indicating that the 
   color components can be written. 
   """
@@ -308,8 +308,8 @@ def glCopyPixels(x, y, width, height, type):
   Copy pixels in the frame buffer
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/copypixels.html}
 
-  @type x,y: int
-  @param x,y: Specify the window coordinates of the lower left corner of the rectangular 
+  @type x, y: int
+  @param x, y: Specify the window coordinates of the lower left corner of the rectangular 
   region of pixels to be copied. 
   @type width, height: int
   @param width,height: Specify the dimensions of the rectangular region of pixels to be copied. 
@@ -1079,7 +1079,7 @@ def glNormal3 (nx, ny, nz, v):
   @param nx, ny, nz: Specify the x, y, and z coordinates of the new current normal. 
   The initial value of the current normal is the unit vector, (0, 0, 1). 
   @type v: Buffer object. Depends on function prototype. ('v' prototypes)
-  @param v: Specifies a pointer to an array of three elements: the x,y, and z coordinates
+  @param v: Specifies a pointer to an array of three elements: the x, y, and z coordinates
   of the new current normal.
   """
   
@@ -1290,7 +1290,7 @@ def glRasterPos (x,y,z,w):
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/rasterpos.html}
 
   @type x, y, z, w: Depends on function prototype. (z and w for '3' and '4' prototypes only)
-  @param x,y,z,w: Specify the x,y,z, and w object coordinates (if present) for the 
+  @param x, y, z, w: Specify the x,y,z, and w object coordinates (if present) for the 
   raster position.  If function prototype ends in 'v' specifies a pointer to an array of two, 
   three, or four elements, specifying x, y, z, and w coordinates, respectively.
   @note:
@@ -1326,8 +1326,8 @@ def glReadPixels(x, y, width, height, format, type, pixels):
   Read a block of pixels from the frame buffer
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/readpixels.html}
   
-  @type x,y: int
-  @param x,y:Specify the window coordinates of the first pixel that is read 
+  @type x, y: int
+  @param x, y:Specify the window coordinates of the first pixel that is read 
   from the frame buffer. This location is the lower left corner of a rectangular
   block of pixels. 
   @type width, height: int
@@ -1375,8 +1375,8 @@ def glRotate (angle, x, y, z):
 
   @type angle:  Depends on function prototype.
   @param angle:  Specifies the angle of rotation in degrees.
-  @type x,y,z:  Depends on function prototype.
-  @param x,y,z:  Specify the x,y, and z coordinates of a vector respectively.
+  @type x, y, z:  Depends on function prototype.
+  @param x, y, z:  Specify the x, y, and z coordinates of a vector respectively.
   """
 
 def glScale (x,y,z):
@@ -1386,8 +1386,8 @@ def glScale (x,y,z):
   Multiply the current matrix by a general scaling matrix
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/scale.html}
 
-  @type x,y,z: Depends on function prototype.
-  @param x,y,z: Specify scale factors along the x,y, and z axes, respectively.
+  @type x, y, z: Depends on function prototype.
+  @param x, y, z: Specify scale factors along the x, y, and z axes, respectively.
   """
 
 def glScissor(x,y,width,height):
@@ -1395,8 +1395,8 @@ def glScissor(x,y,width,height):
   Define the scissor box
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/scissor.html}
  
-  @type x,y: int
-  @param x,y: Specify the lower left corner of the scissor box. Initially (0, 0). 
+  @type x, y: int
+  @param x, y: Specify the lower left corner of the scissor box. Initially (0, 0). 
   @type width, height: int
   @param width height: Specify the width and height of the scissor box. When a 
   GL context is first attached to a window, width and height are set to the 
@@ -1480,8 +1480,8 @@ def glTexCoord (s,t,r,q,v):
   Set the current texture coordinates
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/texcoord.html}
   
-  @type s,t,r,q: Depends on function prototype. (r and q for '3' and '4' prototypes only)
-  @param s,t,r,q: Specify s, t, r, and q texture coordinates. Not all parameters are 
+  @type s, t, r, q: Depends on function prototype. (r and q for '3' and '4' prototypes only)
+  @param s, t, r, q: Specify s, t, r, and q texture coordinates. Not all parameters are 
   present in all forms of the command. 
   @type v: Buffer object. Depends on function prototype. (for 'v' prototypes only)
   @param v: Specifies a pointer to an array of one, two, three, or four elements, 
@@ -1604,8 +1604,8 @@ def glTranslate (x, y, z):
   Multiply the current matrix by a translation matrix
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/translate.html}
 
-  @type x,y,z: Depends on function prototype.
-  @param x,y,z: Specify the x, y, and z coordinates of a translation vector. 
+  @type x, y, z: Depends on function prototype.
+  @param x, y, z: Specify the x, y, and z coordinates of a translation vector. 
   """
 
 def glVertex (x,y,z,w,v):
@@ -1618,8 +1618,8 @@ def glVertex (x,y,z,w,v):
   Specify a vertex
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/vertex.html}
   
-  @type x,y,z,w: Depends on function prototype (z and w for '3' and '4' prototypes only)
-  @param x,y,z,w: Specify x, y, z, and w coordinates of a vertex. Not all parameters 
+  @type x, y, z, w: Depends on function prototype (z and w for '3' and '4' prototypes only)
+  @param x, y, z, w: Specify x, y, z, and w coordinates of a vertex. Not all parameters 
   are present in all forms of the command. 
   @type v: Buffer object. Depends of function prototype (for 'v' prototypes only)
   @param v: Specifies a pointer to an array of two, three, or four elements. The 
@@ -1632,11 +1632,11 @@ def glViewport(x,y,width,height):
   Set the viewport
   @see: U{www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/viewport.html}
 
-  @type x,y: int
-  @param x,y: Specify the lower left corner of the viewport rectangle, 
+  @type x, y: int
+  @param x, y: Specify the lower left corner of the viewport rectangle, 
   in pixels. The initial value is (0,0). 
-  @type width,height: int
-  @param width,height: Specify the width and height of the viewport. When a GL context 
+  @type width, height: int
+  @param width, height: Specify the width and height of the viewport. When a GL context 
   is first attached to a window, width and height are set to the dimensions of that window. 
   """
 
index d1c72f8cb86cfb06c5751336546463e0011a9426..507592ce8a68800e9094fc0fdf3ec4c0420a6878 100644 (file)
@@ -57,8 +57,8 @@ The valid IpoCurve constants are:
                        TE_DISTA, TE_MGTYPE, TE_MGH, TE_LACU, TE_OCT, TE_MGOFF,
                        TE_MGGAIN, TE_NBASE1, TE_NBASE2, TE_COLR, TE_COLG, TE_COLB,
                        TE_BRIGHT, TE_CONTRAS
-                       9. Pose/Action Ipo: PO_LOCX, PO_LOCY, PO_LOCZ, PO_SIZEX, PO_SIZEY,
-                       PO_SIZEZ, PO_QUATW, PO_QUATX, PO_QUATY, PO_QUATZ
+                       9. Pose/Action Ipo: PO_LOCX, PO_LOCY, PO_LOCZ, PO_SCALEX, PO_SCALEY,
+                       PO_SCALEZ, PO_QUATW, PO_QUATX, PO_QUATY, PO_QUATZ
                        10. Sequence Ipo: SQ_FAC
 
 Shape Key Ipos are handled differently from other Ipos.  The user can rename
index 54d9136ec1e5a640048f1f60595ae68968678c98..850a1825325d7f964e97dd2a15c9ad77244f1524 100644 (file)
@@ -16,7 +16,7 @@ BezTriples.
 Example::
   import Blender
   ipo = Blender.Ipo.Get('ObIpo')  # retrieves an Ipo object
-  ipo.name = 'ipo1'                             # change the Ipo's name
+  ipo.name = 'ipo1'                 # change the Ipo's name
   icu = ipo[Blender.Ipo.OB_LOCX] # request X Location Ipo curve object
   if icu != None and len(icu.bezierPoints) > 0: # if curve exists and has BezTriple points
      val = icu[2.5]              # get the curve's value at time 2.5
@@ -78,27 +78,27 @@ class IpoCurve:
   get the value of the final curve point, read the final point from the
   curve::
 
-               ipo = Blender.Object.Get('Cube').ipo
-               icu = ipo['LocX']
-               endtime,endvalue = icu.bezierPoints[-1].pt
+        ipo = Blender.Object.Get('Cube').ipo
+        icu = ipo['LocX']
+        endtime,endvalue = icu.bezierPoints[-1].pt
   @type extend: int
   """
 
   def __getitem__ (time):
-       """
-       Returns the value of the curve at a particular time.
+    """
+    Returns the value of the curve at a particular time.
     @type time: float
     @param time: time (Vertex X) on the curve
     @rtype: float
     @return: value (Vertex Y) corresponding to the given time
-       """
+    """
 
   def __setitem__ (time):
-       """
-       Sets the value (Vertex Y) of the curve at a particular time.
+    """
+    Sets the value (Vertex Y) of the curve at a particular time.
     @type time: float
     @param time: time (Vertex X) on the curve
-       """
+    """
 
   def setExtrapolation(extendmode):
     """
@@ -216,6 +216,17 @@ class IpoCurve:
     @return: the points of the Ipo curve.
     """
 
+  def clean( thresh=0.0000001 ):
+    """
+    Calls the IPO-curve cleaning function on this IpoCurve. 
+    There is no need to recalculate curve manually.
+    @type thresh: float
+    @param thresh: The threshold to used to determine if two values are identical. 
+    By default, the IPO-editor tool's value is used.
+    @rtype: None
+    @return: None
+    """
+
   def evaluate( time ):
     """
     Compute the value of the Ipo curve at a particular time (B{deprecated}).
index fa6a9f7047a00e5129a941bf5b87d34b61514af7..b37fd660810ea3e088589fdfe43bf5f0428e30da 100644 (file)
@@ -212,7 +212,7 @@ class Material:
        Value is clamped to the range [0.0,100.0].
        @type haloSize:  float
        @ivar hard:  Hardness of the specularity.
-       Value is clamped to the range [1,255].
+       Value is clamped to the range [1,511].
        @type hard:  int
        @ivar ipo:  Material Ipo data.
        Contains the Ipo if one is assigned to the object, None otherwise.  Setting to None clears the current Ipo.
index 5a246031fd062e011f5c34e7e93a9d697d2595bf..122fdd3eda18d437fd7223207bf1e84ea2528c8f 100644 (file)
@@ -128,11 +128,9 @@ def turbulence (xyz, octaves, hard, basis = NoiseTypes['STDPERLIN'],
   @return: the generated turbulence value.
   """
 
-def vTurbulence (xyz, octaves, hard, basis = NoiseTypes['STDPERLIN'],
-    ampscale = 0.5, freqscale = 2.0):
+def vTurbulence (xyz, octaves, hard, basis = NoiseTypes['STDPERLIN'], ampscale = 0.5, freqscale = 2.0):
   """
-  Returns general turbulence vector using the optional specified noise basis
-function.
+  Returns general turbulence vector using the optional specified noise basis function.
   @type xyz: 3-float tuple
   @param xyz: (x,y,z) float values.
   @type octaves: int
index d56a547911ede3fb69ec60bce355ab60213572ff..c5ce7a4d2bfd7961021e3a520c871f9e029aa6c7 100644 (file)
@@ -656,9 +656,13 @@ class Object:
                Return a list of particle systems linked to this object (see Blender.Particle).
                """
                
-       def newParticleSystem():
+       def newParticleSystem(name = None):
                """
-               Link a new particle system (see Blender.Particle).
+               Link a particle system (see Blender.Particle).  If no name is
+               given, a new particle system is created.  If a name is given and a 
+               particle system  with that name exists, it is linked to the object.
+               @type name: string
+               @param name: The name of the requested Particle system (optional).
                """
                
        def addVertexGroupsFromArmature(object):
index 511ad81b45f0ccc5fe51ed305e6ca2f084e25f60..cf662d9147a0ce6518cc32e93bf432253c738818 100644 (file)
@@ -131,8 +131,7 @@ class Particle:
                Get the particles locations.
                A list of tuple is returned in particle mode.
                A list of list of tuple is returned in hair mode.
-               The tuple is a vector of 3 or 4 floats in world space (x,y,z,
-optionally the particle's id).
+               The tuple is a vector of 3 or 4 floats in world space (x,y,z, optionally the particle's id).
                @type all: int
                @param all: if not 0 export all particles (uninitialized (unborn or died)particles exported as None).
                @type id: int
index 5300fdab808aaccf216c289d288181f9a6a645aa..397020fb909655cd8599eb2fac42d6ea094f1a5c 100644 (file)
@@ -1228,3 +1228,17 @@ class RenderData:
     @rtype: int (if prototype is empty)
     @return: Current new map value for the scene.
     """
+    
+  def addRenderLayer():
+    """
+    Add a new render layer to the rendering context, see L{RenderLayer}.
+    @rtype: RenderLayer
+    @return: The newly created renderlayer.
+    """
+
+  def removeRenderLayer(renderlayer):
+    """
+    Remove the specified render layer from the rendering context.
+    @type renderlayer: L{RenderLayer}
+    @param renderlayer: must be a L{RenderLayer}
+    """
diff --git a/source/blender/python/api2_2x/doc/Renderlayer.py b/source/blender/python/api2_2x/doc/Renderlayer.py
new file mode 100644 (file)
index 0000000..60b8ec4
--- /dev/null
@@ -0,0 +1,92 @@
+# Blender.Scene.Render.RenderLayer module and the RenderLayer PyType object
+
+"""
+The Blender.Scene.Render.RenderLayer submodule.
+
+Scene.Render.RenderLayer
+========================
+
+This module provides access to B{Render Layers} in Blender.
+
+Example::
+       import bpy
+       sce = bpy.data.scenes.active
+       render = sce.render
+       layer = render.addRenderLayer()
+       render.removeRenderLayer(layer)
+"""
+
+class RenderLayer:
+       """
+       The RenderLayer object
+       ======================
+       @type name: string
+       @ivar name: Get or set the name for the L{RenderLayer}
+       @type lightGroup: group
+       @ivar lightGroup: group of lights
+       @type enable: bool
+       @ivar enable: enable this render layer
+       @type enableZMask: bool
+       @ivar enableZMask: Only render what's in front of the solid z values
+       @type enableZMaskAll: bool
+       @ivar enableZMaskAll: Fill in Z values for solid faces in invisible layers, for masking
+       @type enableSolid: bool
+       @ivar enableSolid: Render Solid faces in this Layer
+       @type enableZTra: bool
+       @ivar enableZTra: Render Z-Transparent faces in this Layer (On top of Solid and Halos)
+       @type enableHalo: bool
+       @ivar enableHalo: Render Halos in this Layer (on top of Solid)
+       @type enableEdge: bool
+       @ivar enableEdge: Render Edge-enhance in this Layer (only works for Solid faces)
+       @type enableSky: bool
+       @ivar enableSky: Render Sky or backbuffer in this Layer
+       @type enableStrand: bool
+       @ivar enableStrand: Render Strands in this Layer
+       @type layerMask: bool
+       @ivar layerMask: ...
+       @type zLayerMask: bool
+       @ivar zLayerMask: ...
+         
+       @type passCombined: bool
+       @ivar passCombined: Deliver full combined RGBA buffer
+       @type passZ: bool
+       @ivar passZ: Deliver Z values pass
+       @type passSpeed: bool
+       @ivar passSpeed: Deliver Speed Vector pass
+       @type passNormal: bool
+       @ivar passNormal: Deliver Normal pass
+       @type passUV: bool
+       @ivar passUV: Deliver Texture UV pass
+       @type passMist: bool
+       @ivar passMist: Deliver Mist factor pass (0-1)
+       @type passIndex: bool
+       @ivar passIndex: Deliver Object Index pass
+       @type passColor: bool
+       @ivar passColor: Deliver shade-less Color pass
+       @type passDiffuse: bool
+       @ivar passDiffuse: Deliver Diffuse pass
+       @type passSpecular: bool
+       @ivar passSpecular: Deliver Specular pass
+       @type passShadow: bool
+       @ivar passShadow: Deliver Shadow pass
+       @type passAO: bool
+       @ivar passAO: Deliver AO pass
+       @type passReflect: bool
+       @ivar passReflect: Deliver Raytraced Reflection pass
+       @type passRefract: bool
+       @ivar passRefract: Deliver Raytraced Reflection pass
+       @type passRadiosity: bool
+       @ivar passRadiosity: Deliver Radiosity pass
+       
+       
+       @type passSpecularXOR: bool
+       @ivar passSpecularXOR: Deliver Specular pass XOR
+       @type passShadowXOR: bool
+       @ivar passShadowXOR: Deliver Shadow pass XOR
+       @type passAOXOR: bool
+       @ivar passAOXOR: Deliver AO pass XOR
+       @type passRefractXOR: bool
+       @ivar passRefractXOR: Deliver Raytraced Reflection pass XOR
+       @type passRadiosityXOR: bool
+       @ivar passRadiosityXOR: Deliver Radiosity pass XOR
+       """
\ No newline at end of file
diff --git a/source/blender/python/api2_2x/doc/SConscript b/source/blender/python/api2_2x/doc/SConscript
new file mode 100644 (file)
index 0000000..49d2089
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+Import ('env')
+
+
+from optparse import OptionParser
+try:
+    import epydoc
+except ImportError:
+    print "No epydoc install detected, Python API Docs will not be generated "
+if epydoc:
+    from epydoc.docbuilder import build_doc_index
+    from epydoc import cli
+    names = env.Glob("source/blender/python/api2_2x/doc/[A-Z]*.py")
+    docindex = build_doc_index(names)
+    optvalues = cli.OPTION_DEFAULTS
+    optvalues["verbose"] = 1
+    optvalues["target"] = env["BF_DOCDIR"]+"/BPY_API/"
+    optvalues["url"] = "http://www.blender.org"
+    optvalues["top"] = "API_intro"
+    optvalues["name"] = "Blender"
+    optvalues["noprivate"] = 1
+    optvalues["noframes"] = 1
+    optvalues["names"] = names
+    optparser = OptionParser()
+    optparser.set_defaults(**optvalues)
+    (options, args) = optparser.parse_args()
+    cli.write_html(docindex, options)
+
index 022205573aad9eb78f80a1e49a343542f06f31bd..3093b63665858c0749642a6b4dbd67dd1a3f581e 100644 (file)
@@ -143,7 +143,7 @@ class Text:
                Retrieve the contents of this Text buffer as a list of strings between
                the start and end lines specified. If end < 0 all lines from start will
                be included.
-               @type start int
+               @type start: int
                @param start:  Optional index of first line of the span to return
                @type end int
                @param end:  Optional index of the line to which the span is taken or
index b5b82b1a519ea4a60ade774d450ef015ad4ab06c..ad57c303ed2d91246f0e35e777d7e534ebc90a25 100644 (file)
@@ -432,9 +432,9 @@ class Texture:
        def setFlags(f1=None, f2=None, f3=None, f4=None):
                """
                Set this object's flags.
-               @param f1,f2,f3,f4: Flags to be set (omitted flags are cleared). Can be any of 
+               @param f1, f2, f3, f4: Flags to be set (omitted flags are cleared). Can be any of 
                                'FlipBlendXY', 'NegAlpha', 'CheckerOdd', and 'CheckerEven'
-               @type f1,f2,f3,f4: string
+               @type f1, f2, f3, f4: string
                """
 
        def setImage(image):
index 8cbebf82f8dbb16097901a9e70ec6c3daeecaecd..0e5350e41ae7849003d835afea51e4cb0e604749 100644 (file)
@@ -7,5 +7,5 @@
 # set posix locale so regex works properly for [A-Z]*.py
 LC_ALL=POSIX
 
-epydoc -v  -o BPY_API --url "http://www.blender.org" --top API_intro \
+epydoc --debug -v  -o BPY_API --url "http://www.blender.org" --top API_intro \
  --name "Blender" --no-private --no-frames [A-Z]*.py 
index 8e815b95ddf2ac028e91683af2673862df70cc53..4e1051176fd1266501e2a08653e8cd0b2fdd8e1d 100644 (file)
@@ -89,7 +89,8 @@ enum rend_constants {
        EXPP_RENDER_ATTR_BAKEMODE,
        EXPP_RENDER_ATTR_BAKEDIST,
        EXPP_RENDER_ATTR_BAKENORMALSPACE,
-       EXPP_RENDER_ATTR_BAKEBIAS
+       EXPP_RENDER_ATTR_BAKEBIAS,
+       EXPP_RENDER_ATTR_OCRES
 };
 
 #define EXPP_RENDER_ATTR_CFRA                 2
@@ -1995,6 +1996,9 @@ static PyObject *RenderData_getIValueAttr( BPy_RenderData *self, void *type )
        case EXPP_RENDER_ATTR_BAKENORMALSPACE:
                param = self->renderContext->bake_normal_space;
                break;
+       case EXPP_RENDER_ATTR_OCRES:
+               param = self->renderContext->ocres;
+               break;
        default:
                return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                "undefined type constant in RenderData_setIValueAttrClamp" );
@@ -2796,6 +2800,10 @@ static PyGetSetDef BPy_RenderData_getseters[] = {
         (getter)RenderData_getMapNew, (setter)RenderData_setMapNew,
         "New mapping value (in frames)",
         NULL},
+       {"octreeResolution",
+        (getter)RenderData_getIValueAttr, (setter)NULL,
+        "Resolution for octree",
+        (void *)EXPP_RENDER_ATTR_OCRES},
        {"set",
         (getter)RenderData_getSet, (setter)RenderData_setSet,
         "Scene link 'set' value",
@@ -3581,7 +3589,7 @@ static PyGetSetDef BPy_RenderLayer_getseters[] = {
         (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
         "Deliver Raytraced Reflection pass",
         (void *)SCE_PASS_REFRACT},
-       {"passRadiosiy",
+       {"passRadiosity",
         (getter)RenderLayer_getPassBits, (setter)RenderLayer_setPassBits,
         "Deliver Radiosity pass",
         (void *)SCE_PASS_RADIO},
@@ -3603,7 +3611,7 @@ static PyGetSetDef BPy_RenderLayer_getseters[] = {
         (getter)RenderLayer_getPassXorBits, (setter)RenderLayer_setPassXorBits,
         "Deliver Raytraced Reflection pass XOR",
         (void *)SCE_PASS_REFRACT},
-       {"passRadiosiyXOR",
+       {"passRadiosityXOR",
         (getter)RenderLayer_getPassXorBits, (setter)RenderLayer_setPassXorBits,
         "Deliver Radiosity pass XOR",
         (void *)SCE_PASS_RADIO},
index 660fb5442275ea3fea89a1a60aa60b19b41ac5a1..9ffdcaf206a0fb5b6962d204c8f33746901cef38 100644 (file)
@@ -59,7 +59,7 @@ void sss_add_points(Render *re, float (*co)[3], float (*color)[3], float *area,
 void free_sss(struct Render *re);
 
 int sample_sss(struct Render *re, struct Material *mat, float *co, float *col);
-int has_sss_tree(struct Render *re, struct Material *mat);
+int sss_pass_done(struct Render *re, struct Material *mat);
 
 #endif /*SSS_H*/
 
index 346ed653977dc43ba022a566ea1b259f589afb14..b6d0c656f636411d98f7e4fb09a2ae06224bc92d 100644 (file)
@@ -53,7 +53,6 @@ void zbuffer_shadow(struct Render *re, float winmat[][4], struct LampRen *lar, i
 void zbuffer_solid(struct RenderPart *pa, struct RenderLayer *rl, void (*fillfunc)(struct RenderPart*, struct ZSpan*, int, void*), void *data);
 
 unsigned short *zbuffer_transp_shade(struct RenderPart *pa, struct RenderLayer *rl, float *pass, struct ListBase *psmlist);
-void convert_zbuf_to_distbuf(struct RenderPart *pa, struct RenderLayer *rl);
 void zbuffer_sss(RenderPart *pa, unsigned int lay, void *handle, void (*func)(void*, int, int, int, int, int));
 int zbuffer_strands_abuf(struct Render *re, struct RenderPart *pa, struct RenderLayer *rl, struct APixstrand *apixbuf, struct ListBase *apsmbase, struct StrandShadeCache *cache);
 
index 2d229cb33878568cdbbaf1646121e06d4b08d595..ae955a63f98443463b58d321e9053bbfdbd1bfe4 100644 (file)
@@ -1868,7 +1868,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
                        dosimplify= psys_render_simplify_params(psys, cpa, simplify);
 
-                       if(path_nbr) {
+                       if(path_nbr && psys->childcache) {
                                cache = psys->childcache[a-totpart];
                                max_k = (int)cache->steps;
                        }
index aa4e40739da9f222dca2220b5e10fe4422030274..d281ac9e5c85145fb68e325fdddcb582aaef9781 100644 (file)
@@ -640,7