NLA SoC: Merge from 2.5 - 21179 to 21209
authorJoshua Leung <aligorith@gmail.com>
Sun, 28 Jun 2009 03:26:10 +0000 (03:26 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 28 Jun 2009 03:26:10 +0000 (03:26 +0000)
44 files changed:
CMake/macros.cmake
CMakeLists.txt
release/ui/buttons_object_constraint.py
release/ui/buttons_particle.py
release/ui/buttons_physic_cloth.py
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/view2d.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/object/object_edit.c
source/blender/editors/physics/ed_pointcache.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_buttons/buttons_header.c
source/blender/editors/space_buttons/buttons_intern.h
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_buttons/space_buttons.c
source/blender/editors/space_view3d/view3d_toolbar.c
source/blender/editors/transform/transform_conversions.c
source/blender/makesdna/DNA_object_force.h
source/blender/makesrna/intern/rna_cloth.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_force.c
source/blender/makesrna/intern/rna_particle.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/CMakeLists.txt
source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp
source/gameengine/BlenderRoutines/SConscript
source/gameengine/Ketsji/KX_KetsjiEngine.cpp

index bc8892e4b999c653df0340e6b5254180ad0be047..44fc2903875fca1023fd542bb3e98064b5117f69 100644 (file)
@@ -61,7 +61,7 @@ MACRO(SETUP_LIBLINKS
   SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ")
   #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS})
 
-  TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS})
+  TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIBRARY} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${SDL_LIB} ${LLIBS})
 
   # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
 
index 9c7ee34cc147e4b841c2c040119a979580ad211d..99f1c10027b0bc883ffb031f9adb1065b800b768 100644 (file)
@@ -89,7 +89,7 @@ INCLUDE(CMake/macros.cmake)
 
 IF(UNIX)
   IF(WITH_OPENAL)
-    INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake)
+    FIND_PACKAGE(OpenAL)
     IF(OPENAL_FOUND)
       SET(WITH_OPENAL ON)
       SET(OPENAL_LIB ${OPENAL_LIBRARY})
@@ -102,22 +102,12 @@ IF(UNIX)
   FIND_LIBRARY(INTL_LIBRARY
     NAMES intl
     PATHS
-    /usr/local/lib
-    /usr/lib
     /sw/lib
-    /opt/local/lib
-    /opt/csw/lib
-    /opt/lib
   )
   FIND_LIBRARY(ICONV_LIBRARY
     NAMES iconv
     PATHS
-    /usr/local/lib
-    /usr/lib
     /sw/lib
-    /opt/local/lib
-    /opt/csw/lib
-    /opt/lib
   )
   IF(INTL_LIBRARY AND ICONV_LIBRARY)
     SET(GETTEXT_LIB ${INTL_LIBRARY} ${ICONV_LIBRARY})
@@ -136,14 +126,14 @@ IF(UNIX)
   )
   SET(FREETYPE_LIB freetype)
 
-  INCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake)
+  FIND_PACKAGE(PythonLibs)
   SET(PYTHON_INC "${PYTHON_INCLUDE_PATH}" CACHE STRING "")
   SET(PYTHON_LIB "${PYTHON_LIBRARIES}" CACHE STRING "")
-  INCLUDE(${CMAKE_ROOT}/Modules/FindPythonInterp.cmake)
+  FIND_PACKAGE(PythonInterp)
   SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
   SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
 
-  INCLUDE(${CMAKE_ROOT}/Modules/FindSDL.cmake)
+  FIND_PACKAGE(SDL)
   SET(SDL_INC ${SDL_INCLUDE_DIR})
   SET(SDL_LIB ${SDL_LIBRARY})
 
@@ -164,11 +154,11 @@ IF(UNIX)
   SET(FFMPEG_LIB avformat avcodec avutil avdevice swscale)
   SET(FFMPEG_LIBPATH ${FFMPEG}/lib)
 
-  SET(JPEG_LIB jpeg)
+  FIND_PACKAGE(JPEG REQUIRED)
 
-  SET(PNG_LIB png)
+  FIND_PACKAGE(PNG REQUIRED)
 
-  SET(ZLIB_LIB z)
+  FIND_PACKAGE(ZLIB REQUIRED)
 
   SET(LLIBS "-lXi -lutil -lc -lm -lpthread -lstdc++ -lX11 -ldl")
 
@@ -186,12 +176,13 @@ IF(UNIX)
   # Better warnings
   SET(C_WARNINGS "-Wall -Wno-char-subscripts -Wpointer-arith -Wcast-align -Wnested-externs -Wdeclaration-after-statement")
 
-  INCLUDE_DIRECTORIES(/usr/include /usr/local/include)
+  INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
 ENDIF(UNIX)
 
 IF(WIN32)
 
-  INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
+  # this file is included anyway when building under Windows with cl.exe
+  #  INCLUDE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake)
   
   SET(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/windows)
 
@@ -219,15 +210,15 @@ IF(WIN32)
   ENDIF(CMAKE_CL_64)
 
   IF(CMAKE_CL_64)
-       SET(PNG_LIB libpng)
+       SET(PNG_LIBRARIES libpng)
   ELSE(CMAKE_CL_64)
-       SET(PNG_LIB libpng_st)
+    SET(PNG_LIBRARIES libpng_st)
   ENDIF(CMAKE_CL_64)
-  SET(JPEG_LIB libjpeg)
+  SET(JPEG_LIBRARY libjpeg)
 
   SET(ZLIB ${LIBDIR}/zlib)
   SET(ZLIB_INC ${ZLIB}/include)
-  SET(ZLIB_LIB libz)
+  SET(ZLIB_LIBRARIES zlib)
   SET(ZLIB_LIBPATH ${ZLIB}/lib)
   
   SET(PTHREADS ${LIBDIR}/pthreads)
@@ -335,7 +326,7 @@ IF(APPLE)
   ENDIF(CMAKE_OSX_ARCHITECTURES MATCHES i386)
 
   IF(WITH_OPENAL)
-    INCLUDE(${CMAKE_ROOT}/Modules/FindOpenAL.cmake)
+    FIND_PACKAGE(OpenAL)
     IF(OPENAL_FOUND)
       SET(WITH_OPENAL ON)
       SET(OPENAL_LIB ${OPENAL_LIBRARY})
@@ -362,12 +353,12 @@ IF(APPLE)
   SET(GETTEXT_LIB intl iconv)
   SET(GETTEXT_LIBPATH ${GETTEXT}/lib)
 
-  SET(PNG_LIB png)
-  SET(JPEG_LIB jpeg)
+  SET(PNG_LIBRARIES png)
+  SET(JPEG_LIBRARY jpeg)
 
   SET(ZLIB /usr)
   SET(ZLIB_INC "${ZLIB}/include")
-  SET(ZLIB_LIB z)
+  SET(ZLIB_LIBRARIES z)
 
   SET(FREETYPE ${LIBDIR}/freetype)
   SET(FREETYPE_INC ${FREETYPE}/include ${FREETYPE}/include/freetype2)
@@ -438,7 +429,7 @@ ENDIF(WITH_WEBPLUGIN)
 
 #-----------------------------------------------------------------------------
 # Configure OpenGL.
-INCLUDE(${CMAKE_ROOT}/Modules/FindOpenGL.cmake)
+FIND_PACKAGE(OpenGL)
 INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
 #-----------------------------------------------------------------------------
 # Extra compile flags
index 3048bdaa39978903c749dcbb3b37fb963ccb793a..f2b0b986ab9d46ce5704d537a1f82cb9b9581964 100644 (file)
@@ -529,20 +529,20 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel):
 class BONE_PT_constraints(ConstraintButtonsPanel):
        __idname__ = "BONE_PT_constraints"
        __label__ = "Bone Constraints"
-       __context__ = "constraint"
+       __context__ = "bone"
 
        def poll(self, context):
                ob = context.object
-               return (ob and ob.type == "ARMATURE")
+               return (ob and ob.type == "ARMATURE" and context.bone)
                
        def draw(self, context):
                ob = context.object
-               pchan = ob.pose.pose_channels[0] # XXX
+               pchan = ob.pose.pose_channels[context.bone.name]
                layout = self.layout
 
-               #row = layout.row()
-               #row.item_menu_enumO("BONE_OT_constraint_add", "type")
-               #row.itemL();
+               row = layout.row()
+               row.item_menu_enumO("OBJECT_OT_constraint_add", "type")
+               row.itemL();
 
                for con in pchan.constraints:
                        self.draw_constraint(con)
index f82324db9d8e14341f74004292dd9d7643fa142c..e51df6ef7fd1777d4b992c83ea62e9a8d8b7c931 100644 (file)
@@ -7,6 +7,7 @@ def particle_panel_enabled(psys):
 def particle_panel_poll(context):
        psys = context.particle_system
        if psys==None:  return False
+       if psys.settings==None:  return False
        return psys.settings.type in ('EMITTER', 'REACTOR', 'HAIR')
 
 class ParticleButtonsPanel(bpy.types.Panel):
@@ -29,42 +30,51 @@ class PARTICLE_PT_particles(ParticleButtonsPanel):
                ob = context.object
                psys = context.particle_system
 
-               split = layout.split(percentage=0.65)
+               if ob:
+                       row = layout.row()
 
-               if psys:
-                       split.template_ID(psys, "settings")
+                       row.template_list(ob, "particle_systems", "active_particle_system_index")
+
+                       col = row.column(align=True)
+                       col.itemO("OBJECT_OT_particle_system_slot_add", icon="ICON_ZOOMIN", text="")
+                       col.itemO("OBJECT_OT_particle_system_slot_remove", icon="ICON_ZOOMOUT", text="")
 
                if psys:
+                       split = layout.split(percentage=0.65)
+                       
+                       split.template_ID(psys, "settings", new="PARTICLE_OT_new")
+                       
                        #row = layout.row()
                        #row.itemL(text="Viewport")
                        #row.itemL(text="Render")
                        
                        part = psys.settings
-                       ptype = psys.settings.type
                        
-                       if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
-                               layout.itemL(text="No settings for fluid particles")
-                               return
+                       if part:
+                               ptype = psys.settings.type
+                               if ptype not in ('EMITTER', 'REACTOR', 'HAIR'):
+                                       layout.itemL(text="No settings for fluid particles")
+                                       return
+                                       
+                               split = layout.split(percentage=0.65)
                                
-                       split = layout.split(percentage=0.65)
-                       
-                       split.enabled = particle_panel_enabled(psys)
-                       split.itemR(part, "type")
-                       split.itemR(psys, "seed")
-                       
-                       split = layout.split(percentage=0.65)
-                       if part.type=='HAIR':
-                               if psys.editable==True:
-                                       split.itemO("PARTICLE_OT_editable_set", text="Free Edit")
-                               else:
-                                       split.itemO("PARTICLE_OT_editable_set", text="Make Editable")
-                               row = split.row()
-                               row.enabled = particle_panel_enabled(psys)
-                               row.itemR(part, "hair_step")
-                       elif part.type=='REACTOR':
                                split.enabled = particle_panel_enabled(psys)
-                               split.itemR(psys, "reactor_target_object")
-                               split.itemR(psys, "reactor_target_particle_system", text="Particle System")
+                               split.itemR(part, "type")
+                               split.itemR(psys, "seed")
+                               
+                               split = layout.split(percentage=0.65)
+                               if part.type=='HAIR':
+                                       if psys.editable==True:
+                                               split.itemO("PARTICLE_OT_editable_set", text="Free Edit")
+                                       else:
+                                               split.itemO("PARTICLE_OT_editable_set", text="Make Editable")
+                                       row = split.row()
+                                       row.enabled = particle_panel_enabled(psys)
+                                       row.itemR(part, "hair_step")
+                               elif part.type=='REACTOR':
+                                       split.enabled = particle_panel_enabled(psys)
+                                       split.itemR(psys, "reactor_target_object")
+                                       split.itemR(psys, "reactor_target_particle_system", text="Particle System")
                
 class PARTICLE_PT_emission(ParticleButtonsPanel):
        __idname__= "PARTICLE_PT_emission"
@@ -120,6 +130,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
        def poll(self, context):
                psys = context.particle_system
                if psys==None:  return False
+               if psys.settings==None:  return False
                return psys.settings.type in ('EMITTER', 'REACTOR')
 
        def draw(self, context):
@@ -130,11 +141,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
                cache = psys.point_cache
                
                row = layout.row()
-               row.itemR(cache, "name", text="")
-               if cache.outdated:
-                       row.itemL(text="Cache is outdated.")
-               else:
-                       row.itemL(text="")
+               row.itemR(cache, "name")
                
                row = layout.row()
                
@@ -142,18 +149,29 @@ class PARTICLE_PT_cache(ParticleButtonsPanel):
                        row.itemO("PTCACHE_OT_free_bake_particle_system", text="Free Bake")
                else:
                        row.item_booleanO("PTCACHE_OT_cache_particle_system", "bake", True, text="Bake")
-                       
+               
+               subrow = row.row()
+               subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys)
+               subrow.itemO("PTCACHE_OT_cache_particle_system", text="Calculate to Current Frame")
+               
                row = layout.row()
                row.enabled = particle_panel_enabled(psys)
                row.itemO("PTCACHE_OT_bake_from_particles_cache", text="Current Cache to Bake")
-               if cache.autocache == 0:
-                       row.itemO("PTCACHE_OT_cache_particle_system", text="Cache to Current Frame")
+               row.itemR(cache, "step");
        
                row = layout.row()
                row.enabled = particle_panel_enabled(psys)
-               #row.itemR(cache, "autocache")
+               row.itemR(cache, "quick_cache")
                row.itemR(cache, "disk_cache")
-               row.itemL(text=cache.info)
+               
+               layout.itemL(text=cache.info)
+               
+               layout.itemS()
+               
+               row = layout.row()
+               row.item_booleanO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+               row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+               layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
                
                # for particles these are figured out automatically
                #row.itemR(cache, "start_frame")
@@ -280,7 +298,10 @@ class PARTICLE_PT_render(ParticleButtonsPanel):
        __label__ = "Render"
        
        def poll(self, context):
-               return (context.particle_system != None)
+               psys = context.particle_system
+               if psys==None: return False
+               if psys.settings==None: return False
+               return True;
                
        def draw(self, context):
                layout = self.layout
@@ -414,7 +435,10 @@ class PARTICLE_PT_draw(ParticleButtonsPanel):
        __default_closed__ = True
        
        def poll(self, context):
-               return (context.particle_system != None)
+               psys = context.particle_system
+               if psys==None: return False
+               if psys.settings==None: return False
+               return True;
        
        def draw(self, context):
                layout = self.layout
index bd65392ad63426d5d2350b74d84b73bf95f66d6e..a06c644322ad8f26e52072b356d29009108da80d 100644 (file)
@@ -43,7 +43,54 @@ class Physic_PT_cloth(PhysicButtonsPanel):
                        col.itemR(cloth, "goal_spring", text="Stiffness")
                        col.itemR(cloth, "goal_friction", text="Friction")
                """
+
+class PHYSICS_PT_cloth_cache(PhysicButtonsPanel):
+       __idname__= "PHYSICS_PT_cloth_cache"
+       __label__ = "Cache"
+       __default_closed__ = True
+
+       def draw(self, context):
+               layout = self.layout
+
+               cache = context.cloth.point_cache
+               
+               row = layout.row()
+               row.itemR(cache, "name")
+               
+               row = layout.row()
+               row.itemR(cache, "start_frame")
+               row.itemR(cache, "end_frame")
+               
+               row = layout.row()
+               
+               if cache.baked == True:
+                       row.itemO("PTCACHE_OT_free_bake_cloth", text="Free Bake")
+               else:
+                       row.item_booleanO("PTCACHE_OT_cache_cloth", "bake", True, text="Bake")
+               
+               subrow = row.row()
+               subrow.enabled = cache.frames_skipped or cache.outdated
+               subrow.itemO("PTCACHE_OT_cache_cloth", text="Calculate to Current Frame")
+                       
+               row = layout.row()
+               #row.enabled = particle_panel_enabled(psys)
+               row.itemO("PTCACHE_OT_bake_from_cloth_cache", text="Current Cache to Bake")
+               row.itemR(cache, "step");
        
+               row = layout.row()
+               #row.enabled = particle_panel_enabled(psys)
+               row.itemR(cache, "quick_cache")
+               row.itemR(cache, "disk_cache")
+               
+               layout.itemL(text=cache.info)
+               
+               layout.itemS()
+               
+               row = layout.row()
+               row.itemO("PTCACHE_OT_bake_all", "bake", True, text="Bake All Dynamics")
+               row.itemO("PTCACHE_OT_free_bake_all", text="Free All Bakes")
+               layout.itemO("PTCACHE_OT_bake_all", text="Update All Dynamics to current frame")
+               
 class Physic_PT_cloth_collision(PhysicButtonsPanel):
        __idname__ = "Physic_PT_clothcollision"
        __label__ = "Cloth Collision"
@@ -102,5 +149,6 @@ class Physic_PT_cloth_stiffness(PhysicButtonsPanel):
                sub.itemR(cloth, "bending_stiffness_max", text="Max")
                
 bpy.types.register(Physic_PT_cloth)
+bpy.types.register(PHYSICS_PT_cloth_cache)
 bpy.types.register(Physic_PT_cloth_collision)
 bpy.types.register(Physic_PT_cloth_stiffness)
index e09be838f0617d9e3eff28873202cd94f73218cc..4270c677338e5dd837a95aa4dd7e94b5a7204550 100644 (file)
@@ -46,6 +46,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
+#include "DNA_scene_types.h"
 
 #include "BKE_collision.h"
 
@@ -245,8 +246,8 @@ void bvhtree_update_from_cloth ( ClothModifierData *clmd, int moving );
 void bvhselftree_update_from_cloth ( ClothModifierData *clmd, int moving );
 
 // needed for editmesh.c
-void cloth_write_cache ( Object *ob, ClothModifierData *clmd, float framenr );
-int cloth_read_cache ( Object *ob, ClothModifierData *clmd, float framenr );
+void cloth_write_cache( Object *ob, ClothModifierData *clmd, int framenr );
+int cloth_read_cache( Scene *scene, Object *ob, ClothModifierData *clmd, float framenr, int *old_framenr );
 
 // needed for button_object.c
 void cloth_clear_cache ( Object *ob, ClothModifierData *clmd, float framenr );
index 0ecd71fc4a311676763835b67ef6b70ab01a12a7..4d9916b955767830761239ea6823ab690326f7c7 100644 (file)
@@ -217,6 +217,7 @@ char *psys_menu_string(struct Object *ob, int for_sb);
 
 struct ParticleSystem *psys_get_current(struct Object *ob);
 short psys_get_current_num(struct Object *ob);
+void psys_set_current_num(Object *ob, int index);
 struct Object *psys_find_object(struct Scene *scene, struct ParticleSystem *psys);
 //struct ParticleSystem *psys_get(struct Object *ob, int index);
 struct ParticleData *psys_get_selected_particle(struct ParticleSystem *psys, int *index);
@@ -250,9 +251,10 @@ void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int tim
 void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
 struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys);
 
+void object_add_particle_system_slot(struct Scene *scene, struct Object *ob);
+void object_remove_particle_system_slot(struct Scene *scene, struct Object *ob);
 struct ParticleSettings *psys_new_settings(char *name, struct Main *main);
 struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part);
-int psys_count_autocache(struct Scene *scene, struct ParticleSettings *part);
 void psys_flush_particle_settings(struct Scene *scene, struct ParticleSettings *part, int recalc);
 void make_local_particlesettings(struct ParticleSettings *part);
 
index b79357edf36953b8842145db8661d21db849f901..3f1c45d28ecc932353c7e06f4da88785aadf617f 100644 (file)
@@ -93,7 +93,7 @@ typedef struct PTCacheWriter {
        int cfra;
        int totelem;
 
-       float *(*elem_ptr)(int index, void *calldata);
+       void (*set_elem)(int index, void *calldata, float *data);
        void *calldata;
 } PTCacheWriter;
 
@@ -103,12 +103,10 @@ typedef struct PTCacheReader {
        float cfra;
        int totelem;
 
-       void (*set_elem)(int index, void *calldata, float *data);
-       void (*interpolate_elem)(int index, void *calldata, float frs_sec, float cfra, int cfra1, int cfra2, float *data1, float *data2);
+       void (*set_elem)(int elem_index, void *calldata, float *data);
+       void (*interpolate_elem)(int index, void *calldata, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2);
        void *calldata;
 
-       int allow_interpolate;
-       int allow_old;
        int *old_frame;
 } PTCacheReader;
 
@@ -116,6 +114,7 @@ typedef struct PTCacheBaker {
        struct Scene *scene;
        int bake;
        int render;
+       int quick_step;
        struct PTCacheID *pid;
        int (*break_test)(void *data);
        void *break_data;
@@ -146,6 +145,8 @@ void         BKE_ptcache_file_close(PTCacheFile *pf);
 int          BKE_ptcache_file_read_floats(PTCacheFile *pf, float *f, int tot);
 int          BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot);
 
+void BKE_ptcache_update_info(PTCacheID *pid);
+
 /* General cache reading/writing */
 int                     BKE_ptcache_read_cache(PTCacheReader *reader);
 int                     BKE_ptcache_write_cache(PTCacheWriter *writer);
@@ -160,7 +161,7 @@ void BKE_ptcache_free(struct PointCache *cache);
 struct PointCache *BKE_ptcache_copy(struct PointCache *cache);
 
 /* Baking */
-void BKE_ptcache_autocache_all(struct Scene *scene);
+void BKE_ptcache_quick_cache_all(struct Scene *scene);
 void BKE_ptcache_make_cache(struct PTCacheBaker* baker);
 void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid);
 
index e98d7bb01a48e205e4aff03b1a4ff15c27dd128f..08caea565aa72859e5ada99d725e7f08c85d8513 100644 (file)
@@ -33,6 +33,7 @@
 #include "DNA_mesh_types.h"
 #include "DNA_object_force.h"
 #include "DNA_scene_types.h"
+#include "DNA_particle_types.h"
 
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
@@ -42,6 +43,7 @@
 #include "BKE_object.h"
 #include "BKE_modifier.h"
 #include "BKE_utildefines.h"
+#include "BKE_particle.h"
 
 #include "BKE_pointcache.h"
 
@@ -339,78 +341,99 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving)
 }
 
 int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
+static void cloth_write_state(int index, Cloth *cloth, float *data)
+{
+       ClothVertex *vert = cloth->verts + index;
 
-int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
+       memcpy(data, vert->x, 3 * sizeof(float));
+       memcpy(data + 3, vert->xconst, 3 * sizeof(float));
+       memcpy(data + 6, vert->v, 3 * sizeof(float));
+}
+static void cloth_read_state(int index, Cloth *cloth, float *data)
 {
-       PTCacheID pid;
-       PTCacheFile *pf;
-       Cloth *cloth = clmd->clothObject;
-       unsigned int a, ret = 1;
+       ClothVertex *vert = cloth->verts + index;
        
-       if(!cloth)
-               return 0;
-       
-       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-       pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr);
-       if(pf) {
-               for(a = 0; a < cloth->numverts; a++) {
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) {
-                               ret = 0;
-                               break;
-                       }
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) {
-                               ret = 0;
-                               break;
-                       }
-                       if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) {
-                               ret = 0;
-                               break;
-                       }
-               }
-               
-               BKE_ptcache_file_close(pf);
-       }
-       else
-               ret = 0;
-       
-       return ret;
+       memcpy(vert->x, data, 3 * sizeof(float));
+       memcpy(vert->xconst, data + 3, 3 * sizeof(float));
+       memcpy(vert->v, data + 6, 3 * sizeof(float));
 }
+static void cloth_cache_interpolate(int index, Cloth *cloth, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
+{
+       ClothVertex *vert = cloth->verts + index;
+       ParticleKey keys[4];
+       float dfra;
 
-void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+       if(cfra1 == cfra2) {
+               cloth_read_state(index, cloth, data1);
+               return;
+       }
+
+       memcpy(keys[1].co, data1, 3 * sizeof(float));
+       memcpy(keys[1].vel, data1 + 6, 3 * sizeof(float));
+
+       memcpy(keys[2].co, data2, 3 * sizeof(float));
+       memcpy(keys[2].vel, data2 + 6, 3 * sizeof(float));
+
+       dfra = cfra2 - cfra1;
+
+       VecMulf(keys[1].vel, dfra);
+       VecMulf(keys[2].vel, dfra);
+
+       psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1);
+
+       VecMulf(keys->vel, 1.0f / dfra);
+
+       memcpy(vert->x, keys->co, 3 * sizeof(float));
+       memcpy(vert->v, keys->vel, 3 * sizeof(float));
+
+       /* not sure what to do with this - jahka */
+       memcpy(vert->xconst, data1 + 3, 3 * sizeof(float));
+}
+void cloth_write_cache(Object *ob, ClothModifierData *clmd, int cfra)
 {
+       PTCacheWriter writer;
        PTCacheID pid;
-       
+
        BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 
-       // don't do anything as long as we're in editmode!
-       if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
-               return;
-       
-       BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
+       writer.calldata = clmd->clothObject;
+       writer.cfra = cfra;
+       writer.set_elem = cloth_write_state;
+       writer.pid = &pid;
+       writer.totelem = clmd->clothObject->numverts;
+
+       BKE_ptcache_write_cache(&writer);
 }
 
-void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
+int cloth_read_cache(Scene *scene, Object *ob, ClothModifierData *clmd, float cfra, int *old_framenr)
 {
-       Cloth *cloth = clmd->clothObject;
+       PTCacheReader reader;
        PTCacheID pid;
-       PTCacheFile *pf;
-       unsigned int a;
        
-       if(!cloth)
-               return;
+       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+       reader.calldata = clmd->clothObject;
+       reader.cfra = cfra;
+       reader.interpolate_elem = cloth_cache_interpolate;
+       reader.old_frame = old_framenr;
+       reader.pid = &pid;
+       reader.scene = scene;
+       reader.set_elem = cloth_read_state;
+       reader.totelem = clmd->clothObject->numverts;
+
+       return BKE_ptcache_read_cache(&reader);
+}
+void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
+{
+       PTCacheID pid;
        
        BKE_ptcache_id_from_cloth(&pid, ob, clmd);
-       pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr);
-       if(!pf)
+
+       // don't do anything as long as we're in editmode!
+       if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
                return;
        
-       for(a = 0; a < cloth->numverts; a++) {
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3);
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3);
-               BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3);
-       }
-       
-       BKE_ptcache_file_close(pf);
+       BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr);
 }
 
 static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
@@ -486,6 +509,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
        PTCacheID pid;
        float timescale;
        int framedelta, framenr, startframe, endframe;
+       int cache_result, old_framenr;
 
        clmd->scene= scene;     /* nice to pass on later :) */
        framenr= (int)scene->r.cfra;
@@ -499,6 +523,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
        if(!result) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return dm;
        }
        
@@ -510,6 +535,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
                if(result->getNumVerts(result) != clmd->clothObject->numverts) {
                        cache->flag &= ~PTCACHE_SIMULATION_VALID;
                        cache->simframe= 0;
+                       cache->last_exact= 0;
                        return result;
                }
        }
@@ -521,6 +547,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
        if(BKE_ptcache_get_continue_physics()) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
 
                /* do simulation */
                if(!do_init_cloth(ob, clmd, result, framenr))
@@ -536,6 +563,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
        if(framenr < startframe) {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return result;
        }
        else if(framenr > endframe) {
@@ -552,7 +580,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
                return result;
 
        /* try to read from cache */
-       if(cloth_read_cache(ob, clmd, framenr)) {
+       cache_result = cloth_read_cache(scene, ob, clmd, framenr, &old_framenr);
+
+       if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) {
                cache->flag |= PTCACHE_SIMULATION_VALID;
                cache->simframe= framenr;
 
@@ -561,25 +591,40 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
 
                return result;
        }
+       else if(cache_result==PTCACHE_READ_OLD) {
+               BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+
+               implicit_set_positions(clmd);
+
+               cache->flag |= PTCACHE_SIMULATION_VALID;
+               cache->simframe= old_framenr;
+       }
        else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
                /* if baked and nothing in cache, do nothing */
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
                cache->simframe= 0;
+               cache->last_exact= 0;
                return result;
        }
 
        if(framenr == startframe) {
+               if(cache->flag & PTCACHE_REDO_NEEDED) {
+                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+                       do_init_cloth(ob, clmd, result, framenr);
+               }
                cache->flag |= PTCACHE_SIMULATION_VALID;
                cache->simframe= framenr;
 
                /* don't write cache on first frame, but on second frame write
                 * cache for frame 1 and 2 */
        }
-       else if(framedelta == 1) {
+       else {
                /* if on second frame, write cache for first frame */
-               if(framenr == startframe+1)
+               if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
                        cloth_write_cache(ob, clmd, startframe);
 
+               clmd->sim_parms->timescale *= framenr - cache->simframe;
+
                /* do simulation */
                cache->flag |= PTCACHE_SIMULATION_VALID;
                cache->simframe= framenr;
@@ -587,16 +632,13 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Scene *scene, Object *ob,
                if(!do_step_cloth(ob, clmd, result, framenr)) {
                        cache->flag &= ~PTCACHE_SIMULATION_VALID;
                        cache->simframe= 0;
+                       cache->last_exact= 0;
                }
                else
                        cloth_write_cache(ob, clmd, framenr);
 
                cloth_to_object (ob, clmd, result);
        }
-       else {
-               cache->flag &= ~PTCACHE_SIMULATION_VALID;
-               cache->simframe= 0;
-       }
 
        return result;
 }
index b57b8b7a6da1878d0d371007dd8898f790e94d9b..a36b825293e2793398940139394a324cb22d74fa 100644 (file)
@@ -559,7 +559,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
 
                        dag_add_relation(dag, node, node, DAG_RL_OB_DATA, "Particle-Object Relation");
 
-                       if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+                       if(!psys_check_enabled(ob, psys))
                                continue;
 
                        if(part->phystype==PART_PHYS_KEYED && psys->keyed_ob &&
index 40c98c1d9cc6052cf2ad11bcb6ca2e5b3e4c7633..fc5213d5532faca3508f0f3cf08281317d0c8c44 100644 (file)
@@ -1600,6 +1600,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                
                if(clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
                {
+                       float temp = clmd->sim_parms->stepsPerFrame;
+                       /* not too nice hack, but collisions need this correction -jahka */
+                       clmd->sim_parms->stepsPerFrame /= clmd->sim_parms->timescale;
+
                        // collisions 
                        // itstart();
                        
@@ -1614,7 +1618,7 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                        
                        // call collision function
                        // TODO: check if "step" or "step+dt" is correct - dg
-                       result = cloth_bvh_objcollision(ob, clmd, step, dt);
+                       result = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale);
                        
                        // correct velocity again, just to be sure we had to change it due to adaptive collisions
                        for(i = 0; i < numverts; i++)
@@ -1637,6 +1641,9 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                                }
                        }
                        
+                       /* restore original stepsPerFrame */
+                       clmd->sim_parms->stepsPerFrame = temp;
+                       
                        // X = Xnew;
                        cp_lfvector(id->X, id->Xnew, numverts);
                        
@@ -1654,7 +1661,6 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                                
                                simulate_implicit_euler(id->Vnew, id->X, id->V, id->F, id->dFdV, id->dFdX, dt / 2.0f, id->A, id->B, id->dV, id->S, id->z, id->olddV, id->P, id->Pinv, id->M, id->bigI);
                        }
-                       
                }
                else
                {
index 1a6f57e75c421f457e953fe2aad38c1b0de1a2aa..80a9f173d6ac119b23c9d0918fc9e670f5d41e90 100644 (file)
@@ -6295,6 +6295,9 @@ CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData
        MTex *mtex;
        int i;
 
+       if(!psmd->psys->part)
+               return 0;
+
        ma= give_current_material(ob, psmd->psys->part->omat);
        if(ma) {
                for(i=0; i<MAX_MTEX; i++) {
index 5b3720cd6b01879c5bc78b4d863d0954cec870da..2474053298d81a1148b2715dbf6af847842b923d 100644 (file)
@@ -222,6 +222,20 @@ short psys_get_current_num(Object *ob)
        
        return i;
 }
+void psys_set_current_num(Object *ob, int index)
+{
+       ParticleSystem *psys;
+       short i;
+
+       if(ob==0) return;
+
+       for(psys=ob->particlesystem.first, i=0; psys; psys=psys->next, i++) {
+               if(i == index - 1)
+                       psys->flag |= PSYS_CURRENT;
+               else
+                       psys->flag &= ~PSYS_CURRENT;
+       }
+}
 Object *psys_find_object(Scene *scene, ParticleSystem *psys)
 {
        Base *base = scene->base.first;
@@ -236,31 +250,6 @@ Object *psys_find_object(Scene *scene, ParticleSystem *psys)
 
        return NULL;
 }
-int psys_count_autocache(Scene *scene, ParticleSettings *part)
-{
-       Base *base = scene->base.first;
-       ParticleSystem *psys;
-       PTCacheID pid;
-       int autocache_count= 0;
-
-       for(base = scene->base.first; base; base = base->next) {
-               for(psys = base->object->particlesystem.first; psys; psys=psys->next) {
-                       if(part && psys->part != part)
-                               continue;
-
-                       BKE_ptcache_id_from_particles(&pid, base->object, psys);
-
-                       if((psys->pointcache->flag & PTCACHE_BAKED)
-                               || (psys->pointcache->flag & PTCACHE_AUTOCACHE)==0)
-                               continue;
-
-                       if((psys->pointcache->flag & PTCACHE_OUTDATED)
-                               || BKE_ptcache_id_exist(&pid, CFRA)==0)
-                               autocache_count++;
-               }
-       }
-       return autocache_count;
-}
 /* change object's active particle system */
 void psys_change_act(void *ob_v, void *act_v)
 {
@@ -332,7 +321,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
        ParticleSystemModifierData *psmd;
        Mesh *me;
 
-       if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE)
+       if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part)
                return 0;
 
        if(ob->type == OB_MESH) {
@@ -2940,6 +2929,61 @@ void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleDa
 /************************************************/
 /*                     ParticleSettings handling                       */
 /************************************************/
+void object_add_particle_system_slot(Scene *scene, Object *ob)
+{
+       ParticleSystem *psys;
+       ModifierData *md;
+       ParticleSystemModifierData *psmd;
+
+       if(!ob || ob->type != OB_MESH)
+               return;
+
+       psys = ob->particlesystem.first;
+       for(; psys; psys=psys->next)
+               psys->flag &= ~PSYS_CURRENT;
+
+       psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+       psys->pointcache = BKE_ptcache_add();
+       BLI_addtail(&ob->particlesystem, psys);
+
+       psys->part = psys_new_settings("PSys", NULL);
+
+       md= modifier_new(eModifierType_ParticleSystem);
+       sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+       psmd= (ParticleSystemModifierData*) md;
+       psmd->psys=psys;
+       BLI_addtail(&ob->modifiers, md);
+
+       psys->totpart=0;
+       psys->flag = PSYS_ENABLED|PSYS_CURRENT;
+       psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0);
+
+       DAG_scene_sort(scene);
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+void object_remove_particle_system_slot(Scene *scene, Object *ob)
+{
+       ParticleSystem *psys = psys_get_current(ob);
+       ParticleSystemModifierData *psmd;
+
+       if(!psys)
+               return;
+
+       /* clear modifier */
+       psmd= psys_get_modifier(ob, psys);
+       BLI_remlink(&ob->modifiers, psmd);
+       modifier_free((ModifierData *)psmd);
+
+       /* clear particle system */
+       BLI_remlink(&ob->particlesystem, psys);
+       psys_free(ob,psys);
+
+       if(ob->particlesystem.first)
+               ((ParticleSystem *) ob->particlesystem.first)->flag |= PSYS_CURRENT;
+
+       DAG_scene_sort(scene);
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
 static void default_particle_settings(ParticleSettings *part)
 {
        int i;
@@ -3026,6 +3070,9 @@ ParticleSettings *psys_new_settings(char *name, Main *main)
 {
        ParticleSettings *part;
 
+       if(main==NULL)
+               main = G.main;
+
        part= alloc_libblock(&main->particle, ID_PA, name);
        
        default_particle_settings(part);
@@ -3740,6 +3787,8 @@ int psys_get_particle_state(struct Scene *scene, Object *ob, ParticleSystem *psy
                        if((pa->alive==PARS_UNBORN && (part->flag & PART_UNBORN)==0)
                                || (pa->alive==PARS_DEAD && (part->flag & PART_DIED)==0))
                                return 0;
+
+               state->time = MIN2(state->time, pa->dietime);
        }
 
        if(psys->flag & PSYS_KEYED){
index 97b1956bba913ffe1107f3357f9bf0ef30485fea..591b6ca9be535cb9d931b3e6d36e4354b9a995c6 100644 (file)
@@ -2205,11 +2205,9 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
        *sfra = MAX2(1, (int)part->sta);
        *efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra);
 }
-static float *particle_state_ptr(int index, void *psys_ptr)
+static void particle_write_state(int index, ParticleSystem *psys, float *data)
 {
-       ParticleSystem *psys= psys_ptr;
-
-       return (float *)(&(psys->particles+index)->state);
+       memcpy(data, (float *)(&(psys->particles+index)->state), sizeof(ParticleKey));
 }
 static void particle_read_state(int index, void *psys_ptr, float *data)
 {
@@ -2222,24 +2220,35 @@ static void particle_read_state(int index, void *psys_ptr, float *data)
 
        copy_particle_key(&pa->state, key, 1);
 }
-static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec, float cfra, int cfra1, int cfra2, float *data1, float *data2)
+static void particle_cache_interpolate(int index, void *psys_ptr, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2)
 {
        ParticleSystem *psys= psys_ptr;
        ParticleData *pa = psys->particles + index;
        ParticleKey keys[4];
-       float dfra;
+       float dfra, cfra1f = (float)cfra1, cfra2f(float);
+
+       cfra = MIN2(cfra, pa->dietime);
+       cfra1 = MIN2(cfra1, pa->dietime);
+       cfra2 = MIN2(cfra2, pa->dietime);
 
        keys[1] = *((ParticleKey*)data1);
        keys[2] = *((ParticleKey*)data2);
 
-       dfra = keys[2].time - keys[1].time;
+       if(cfra1 == cfra2) {
+               copy_particle_key(&pa->state, &keys[1], 1);
+               return;
+       }
+
+       dfra = cfra2 - cfra1;
 
        VecMulf(keys[1].vel, dfra / frs_sec);
        VecMulf(keys[2].vel, dfra / frs_sec);
 
-       psys_interpolate_particle(-1, keys, (keys[1].time - cfra) / dfra, &pa->state, 1);
+       psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1);
 
        VecMulf(pa->state.vel, frs_sec / dfra);
+
+       pa->state.time = cfra;
 }
 static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
 {
@@ -2250,22 +2259,20 @@ static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
 
        writer.calldata = psys;
        writer.cfra = cfra;
-       writer.elem_ptr = particle_state_ptr;
+       writer.set_elem = particle_write_state;
        writer.pid = &pid;
        writer.totelem = psys->totpart;
 
        BKE_ptcache_write_cache(&writer);
 }
 
-static int get_particles_from_cache(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int allow_interpolate, int allow_old, int *old_frame)
+static int get_particles_from_cache(Scene *scene, Object *ob, ParticleSystem *psys, float cfra, int *old_frame)
 {
        PTCacheReader reader;
        PTCacheID pid;
        
        BKE_ptcache_id_from_particles(&pid, ob, psys);
 
-       reader.allow_interpolate = allow_interpolate;
-       reader.allow_old = allow_old;
        reader.calldata = psys;
        reader.cfra = cfra;
        reader.interpolate_elem = particle_cache_interpolate;
@@ -2402,6 +2409,8 @@ static void add_to_effectors(ListBase *lb, Scene *scene, Object *ob, Object *obs
                Object *tob;
 
                for(i=0; epsys; epsys=epsys->next,i++){
+                       if(!psys_check_enabled(ob, epsys))
+                               continue;
                        type=0;
                        if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
                                epart=epsys->part;
@@ -4366,7 +4375,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
                        pa->alive = PARS_UNBORN;
                else if(dietime <= cfra){
                        if(dietime > psys->cfra){
-                               state.time = pa->dietime;
+                               state.time = dietime;
                                psys_get_particle_state(scene, ob,psys,p,&state,1);
                                push_reaction(ob,psys,p,PART_EVENT_DEATH,&state);
                        }
@@ -4668,9 +4677,9 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
 
        /* try to read from the cache */
        if(usecache) {
-               int result = get_particles_from_cache(scene, ob, psys, (float)framenr, 0, 1, &old_framenr);
+               int result = get_particles_from_cache(scene, ob, psys, (float)framenr, &old_framenr);
 
-               if(result == PTCACHE_READ_EXACT) {
+               if(result == PTCACHE_READ_EXACT || result == PTCACHE_READ_INTERPOLATED) {
                        //if(part->phystype==PART_PHYS_KEYED && psys->flag&PSYS_FIRST_KEYED) {
                        //      psys_count_keyed_targets(ob,psys);
                        //      set_keyed_keys(scene, ob, psys);
@@ -4687,15 +4696,12 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
                        cache->simframe= framenr;
                        cache->flag |= PTCACHE_SIMULATION_VALID;
 
-                       if(cache->flag & PTCACHE_OUTDATED)
-                               BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
+                       if(result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
+                               write_particles_to_cache(ob, psys, cfra);
 
                        return;
                }
-               else if((cache->flag & PTCACHE_AUTOCACHE)==0 && result==PTCACHE_READ_OLD) {
-                       /* clear cache after current frame */
-                       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE);
-
+               else if(result==PTCACHE_READ_OLD) {
                        /* set old cfra */
                        psys->cfra = (float)old_framenr;
 
@@ -4715,15 +4721,6 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
                        psys->recalc = 0;
                        return;
                }
-
-               if(framenr != startframe && framedelta != 1 && cache->flag & PTCACHE_AUTOCACHE) {
-                       //psys_reset(psys, PSYS_RESET_CACHE_MISS);
-                       /* make sure cache is recalculated */
-                       BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_FRAME, (int)cfra);
-                       psys->cfra = cfra;
-                       psys->recalc = 0;
-                       return;
-               }
        }
        else {
                cache->flag &= ~PTCACHE_SIMULATION_VALID;
index b514ac026fb783a03130330615598daad0a40772..64473d071517350885f1a5155be2175b818c181d 100644 (file)
@@ -303,7 +303,7 @@ static int ptcache_pid_elemsize(PTCacheID *pid)
        else if(pid->type==PTCACHE_TYPE_PARTICLES)
                return sizeof(ParticleKey);
        else if(pid->type==PTCACHE_TYPE_CLOTH)
-               return 0; // TODO
+               return 9 * sizeof(float);
 
        return 0;
 }
@@ -321,10 +321,11 @@ static int ptcache_pid_totelem(PTCacheID *pid)
        return 0;
 }
 
-void ptcache_update_info(PTCacheID *pid)
+void BKE_ptcache_update_info(PTCacheID *pid)
 {
        PointCache *cache = pid->cache;
        int totframes = 0;
+       char mem_info[64];
 
        if(cache->flag & PTCACHE_DISK_CACHE) {
                int cfra = cache->startframe;
@@ -334,7 +335,7 @@ void ptcache_update_info(PTCacheID *pid)
                                totframes++;
                }
 
-               sprintf(cache->info, "%i frames on disk.", totframes);
+               sprintf(mem_info, "%i frames on disk", totframes);
        }
        else {
                PTCacheMem *pm = cache->mem_cache.first;                
@@ -351,11 +352,20 @@ void ptcache_update_info(PTCacheID *pid)
 
                mb = (bytes > 1024.0f * 1024.0f);
 
-               sprintf(cache->info, "%i frames in memory (%.1f %s).",
+               sprintf(mem_info, "%i frames in memory (%.1f %s)",
                        totframes,
                        bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
                        mb ? "Mb" : "kb");
        }
+
+       if(cache->flag & PTCACHE_OUTDATED) {
+               sprintf(cache->info, "%s, cache is outdated!", mem_info);
+       }
+       else if(cache->flag & PTCACHE_FRAMES_SKIPPED) {
+               sprintf(cache->info, "%s, not exact since frame %i.", mem_info, cache->last_exact);
+       }
+       else
+               sprintf(cache->info, "%s.", mem_info);
 }
 /* reads cache from disk or memory */
 /* possible to get old or interpolated result */
@@ -370,10 +380,13 @@ int BKE_ptcache_read_cache(PTCacheReader *reader)
        int elemsize = ptcache_pid_elemsize(pid);
        int i, incr = elemsize / sizeof(float);
        float frs_sec = reader->scene->r.frs_sec;
+       int cfra1=0, cfra2;
+       int ret = 0;
 
        if(totelem == 0)
                return 0;
 
+
        /* first check if we have the actual frame cached */
        if(cfra == (float)cfrai) {
                if(pid->cache->flag & PTCACHE_DISK_CACHE) {
@@ -419,130 +432,147 @@ int BKE_ptcache_read_cache(PTCacheReader *reader)
                        MEM_freeN(data);
                }
 
-               return PTCACHE_READ_EXACT;
+               ret = PTCACHE_READ_EXACT;
        }
-       /* no exact cache frame found so try to find cached frames around cfra */
-       if(reader->allow_interpolate || reader->allow_old) {
-               int cfra1, cfra2;
 
-               if(pid->cache->flag & PTCACHE_DISK_CACHE) {
-                       pf=NULL;
-                       while(cfrai > pid->cache->startframe && !pf) {
-                               cfrai--;
-                               pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
-                               cfra1 = cfrai;
-                       }
+       if(ret)
+               ;
+       /* no exact cache frame found so try to find cached frames around cfra */
+       else if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+               pf=NULL;
+               while(cfrai > pid->cache->startframe && !pf) {
+                       cfrai--;
+                       pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+                       cfra1 = cfrai;
+               }
 
+               if(reader->old_frame)
                        *(reader->old_frame) = cfrai;
 
-                       cfrai = (int)cfra;
-                       while(cfrai < pid->cache->endframe && !pf2) {
-                               cfrai++;
-                               pf2= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
-                               cfra2 = cfrai;
-                       }
+               cfrai = (int)cfra;
+               while(cfrai < pid->cache->endframe && !pf2) {
+                       cfrai++;
+                       pf2= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cfrai);
+                       cfra2 = cfrai;
                }
-               else if(pid->cache->mem_cache.first){
-                       pm = pid->cache->mem_cache.first;
+       }
+       else if(pid->cache->mem_cache.first){
+               pm = pid->cache->mem_cache.first;
 
-                       while(pm->next && pm->next->frame < cfra)
-                               pm= pm->next;
+               while(pm->next && pm->next->frame < cfra)
+                       pm= pm->next;
 
-                       if(pm) {
+               if(pm) {
+                       if(reader->old_frame)
                                *(reader->old_frame) = pm->frame;
-                               cfra1 = pm->frame;
-                       }
+                       cfra1 = pm->frame;
+               }
 
-                       pm2 = pid->cache->mem_cache.last;
+               pm2 = pid->cache->mem_cache.last;
 
-                       while(pm2->prev && pm2->frame > cfra)
+               if(pm2 && pm2->frame < cfra)
+                       pm2 = NULL;
+               else {
+                       while(pm2->prev && pm2->prev->frame > cfra)
                                pm2= pm2->prev;
 
                        if(pm2)
                                cfra2 = pm2->frame;
                }
+       }
 
-               if(reader->allow_interpolate && ((pf && pf2) || (pm && pm2))) {
-                       /* interpolate from nearest frames */
-                       float *data1, *data2;
+       if(ret)
+               ;
+       else if((pf && pf2) || (pm && pm2)) {
+               /* interpolate from nearest frames if cache isn't outdated */
+               float *data1, *data2;
 
-                       if(pm) {
-                               data1 = pm->data;
-                               data2 = pm2->data;
-                       }
-                       else {
-                               data1 = MEM_callocN(elemsize, "pointcache read data1");
-                               data2 = MEM_callocN(elemsize, "pointcache read data2");
-                       }
+               if(pm) {
+                       data1 = pm->data;
+                       data2 = pm2->data;
+               }
+               else {
+                       data1 = MEM_callocN(elemsize, "pointcache read data1");
+                       data2 = MEM_callocN(elemsize, "pointcache read data2");
+               }
 
-                       for(i=0; i<totelem; i++) {
-                               if(pf && pf2) {
-                                       if(!BKE_ptcache_file_read_floats(pf, data1, incr)) {
-                                               BKE_ptcache_file_close(pf);
-                                               BKE_ptcache_file_close(pf2);
-                                               MEM_freeN(data1);
-                                               MEM_freeN(data2);
-                                               return 0;
-                                       }
-                                       if(!BKE_ptcache_file_read_floats(pf2, data2, incr)) {
-                                               BKE_ptcache_file_close(pf);
-                                               BKE_ptcache_file_close(pf2);
-                                               MEM_freeN(data1);
-                                               MEM_freeN(data2);
-                                               return 0;
-                                       }
-                                       reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, cfra1, cfra2, data1, data2);
+               for(i=0; i<totelem; i++) {
+                       if(pf && pf2) {
+                               if(!BKE_ptcache_file_read_floats(pf, data1, incr)) {
+                                       BKE_ptcache_file_close(pf);
+                                       BKE_ptcache_file_close(pf2);
+                                       MEM_freeN(data1);
+                                       MEM_freeN(data2);
+                                       return 0;
                                }
-                               else {
-                                       reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, cfra1, cfra2, data1, data2);
-                                       data1 += incr;
-                                       data2 += incr;
+                               if(!BKE_ptcache_file_read_floats(pf2, data2, incr)) {
+                                       BKE_ptcache_file_close(pf);
+                                       BKE_ptcache_file_close(pf2);
+                                       MEM_freeN(data1);
+                                       MEM_freeN(data2);
+                                       return 0;
                                }
+                               reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
                        }
+                       else {
+                               reader->interpolate_elem(i, reader->calldata, frs_sec, cfra, (float)cfra1, (float)cfra2, data1, data2);
+                               data1 += incr;
+                               data2 += incr;
+                       }
+               }
 
-                       if(pf) {
+               if(pf) {
+                       BKE_ptcache_file_close(pf);
+                       BKE_ptcache_file_close(pf2);
+                       MEM_freeN(data1);
+                       MEM_freeN(data2);
+               }
+
+               ret = PTCACHE_READ_INTERPOLATED;
+       }
+       else if(pf || pm) {
+               /* use last valid cache frame */
+               float *data;
+
+               /* don't read cache if allready simulated past cached frame */
+               if(cfra1 && cfra1 <= pid->cache->simframe) {
+                       if(pf)
                                BKE_ptcache_file_close(pf);
+                       if(pf2)
                                BKE_ptcache_file_close(pf2);
-                               MEM_freeN(data1);
-                               MEM_freeN(data2);
-                       }
 
-                       return PTCACHE_READ_INTERPOLATED;
+                       return 0;
                }
-               else if(reader->allow_old && (pf || pm)) {
-                       /* use last valid cache frame */
-                       float *data;
 
-                       if(pm)
-                               data = pm->data;
-                       else
-                               data = MEM_callocN(elemsize, "pointcache read data");
-
-                       for(i=0; i<totelem; i++) {
-                               if(pf) {
-                                       if(!BKE_ptcache_file_read_floats(pf, data, incr)) {
-                                               BKE_ptcache_file_close(pf);
-                                               if(pf2)
-                                                       BKE_ptcache_file_close(pf2);
-                                               return 0;
-                                       }
-                                       reader->set_elem(i, reader->calldata, data);
-                               }
-                               else {
-                                       reader->set_elem(i, reader->calldata, data);
-                                       data += incr;
-                               }
-                       }
+               if(pm)
+                       data = pm->data;
+               else
+                       data = MEM_callocN(elemsize, "pointcache read data");
 
+               for(i=0; i<totelem; i++) {
                        if(pf) {
-                               BKE_ptcache_file_close(pf);
-                               MEM_freeN(data);
+                               if(!BKE_ptcache_file_read_floats(pf, data, incr)) {
+                                       BKE_ptcache_file_close(pf);
+                                       if(pf2)
+                                               BKE_ptcache_file_close(pf2);
+                                       return 0;
+                               }
+                               reader->set_elem(i, reader->calldata, data);
                        }
-                       if(pf2)
-                               BKE_ptcache_file_close(pf2);
+                       else {
+                               reader->set_elem(i, reader->calldata, data);
+                               data += incr;
+                       }
+               }
 
-                       return PTCACHE_READ_OLD;
+               if(pf) {
+                       BKE_ptcache_file_close(pf);
+                       MEM_freeN(data);
                }
+               if(pf2)
+                       BKE_ptcache_file_close(pf2);
+
+               ret = PTCACHE_READ_OLD;
        }
 
        if(pf)
@@ -550,7 +580,20 @@ int BKE_ptcache_read_cache(PTCacheReader *reader)
        if(pf2)
                BKE_ptcache_file_close(pf2);
 
-       return 0;
+       if((pid->cache->flag & PTCACHE_QUICK_CACHE)==0) {
+               /* clear invalid cache frames so that better stuff can be simulated */
+               if(pid->cache->flag & PTCACHE_OUTDATED) {
+                       BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfra);
+               }
+               else if(pid->cache->flag & PTCACHE_FRAMES_SKIPPED) {
+                       if(cfra <= pid->cache->last_exact)
+                               pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+
+                       BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfra,pid->cache->last_exact));
+               }
+       }
+
+       return ret;
 }
 /* writes cache to disk or memory */
 int BKE_ptcache_write_cache(PTCacheWriter *writer)
@@ -559,57 +602,118 @@ int BKE_ptcache_write_cache(PTCacheWriter *writer)
        PTCacheFile *pf= NULL;
        int elemsize = ptcache_pid_elemsize(writer->pid);
        int i, incr = elemsize / sizeof(float);
+       int add = 0, overwrite = 0, ocfra;
+       float temp[14];
 
        if(writer->totelem == 0 || writer->cfra <= 0)
                return 0;
 
        if(cache->flag & PTCACHE_DISK_CACHE) {
-               pf = BKE_ptcache_file_open(writer->pid, PTCACHE_FILE_WRITE, writer->cfra);
-               if(!pf)
-                       return 0;
+               /* allways start from scratch on the first frame */
+               if(writer->cfra == cache->startframe) {
+                       BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+                       cache->flag &= ~PTCACHE_REDO_NEEDED;
+                       add = 1;
+               }
+               else {
+                       int cfra = cache->endframe;
+                       /* find last cached frame */
+                       while(cfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, cfra))
+                               cfra--;
+
+                       /* find second last cached frame */
+                       ocfra = cfra-1;
+                       while(ocfra > cache->startframe && !BKE_ptcache_id_exist(writer->pid, ocfra))
+                               ocfra--;
+
+                       if(writer->cfra > cfra) {
+                               if(ocfra >= cache->startframe && cfra - ocfra < cache->step)
+                                       overwrite = 1;
+                               else
+                                       add = 1;
+                       }
+               }
 
-               for(i=0; i<writer->totelem; i++)
-                       BKE_ptcache_file_write_floats(pf, writer->elem_ptr(i, writer->calldata), incr);
+               if(add || overwrite) {
+                       if(overwrite)
+                               BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_FRAME, ocfra);
+
+                       pf = BKE_ptcache_file_open(writer->pid, PTCACHE_FILE_WRITE, writer->cfra);
+                       if(!pf)
+                               return 0;
+
+                       for(i=0; i<writer->totelem; i++) {
+                               writer->set_elem(i, writer->calldata, &temp);
+                               BKE_ptcache_file_write_floats(pf, &temp, incr);
+                       }
+               }
        }
        else {
-               PTCacheMem *pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+               PTCacheMem *pm;
                PTCacheMem *pm2;
                float *pmdata;
 
-               pm->data = MEM_callocN(elemsize * writer->totelem, "Pointcache mem data");
-               pmdata = pm->data;
+               pm2 = cache->mem_cache.first;
+               
+               /* allways start from scratch on the first frame */
+               if(writer->cfra == cache->startframe) {
+                       BKE_ptcache_id_clear(writer->pid, PTCACHE_CLEAR_ALL, writer->cfra);
+                       cache->flag &= ~PTCACHE_REDO_NEEDED;
+                       add = 1;
+               }
+               else {
+                       pm2 = cache->mem_cache.last;
+
+                       if(pm2 && writer->cfra > pm2->frame) {
+                               if(pm2 && pm2->prev && pm2->frame - pm2->prev->frame < cache->step)
+                                       overwrite = 1;
+                               else
+                                       add = 1;
+                       }
+               }
 
-               for(i=0; i<writer->totelem; i++, pmdata+=incr)
-                       memcpy(pmdata, writer->elem_ptr(i, writer->calldata), elemsize);
+               if(overwrite) {
+                       pm = cache->mem_cache.last;
+                       pmdata = pm->data;
 
-               pm->frame = writer->cfra;
-               pm->totpoint = writer->totelem;
+                       for(i=0; i<writer->totelem; i++, pmdata+=incr) {
+                               writer->set_elem(i, writer->calldata, &temp);
+                               memcpy(pmdata, &temp, elemsize);
+                       }
 
-               /* find add location */
-               pm2 = cache->mem_cache.first;
-               if(!pm2)
-                       BLI_addtail(&cache->mem_cache, pm);
-               else if(pm2->frame == writer->cfra) {
-                       /* overwrite same frame */
-                       MEM_freeN(pm2->data);
-                       pm2->data = pm->data;
-                       MEM_freeN(pm);
+                       pm->frame = writer->cfra;
                }
-               else {
-                       while(pm2->next && pm2->next->frame < writer->cfra)
-                               pm2 = pm2->next;
+               else if(add) {
+                       pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
+                       pm->data = MEM_callocN(elemsize * writer->totelem, "Pointcache mem data");
+                       pmdata = pm->data;
+
+                       for(i=0; i<writer->totelem; i++, pmdata+=incr) {
+                               writer->set_elem(i, writer->calldata, &temp);
+                               memcpy(pmdata, &temp, elemsize);
+                       }
+
+                       pm->frame = writer->cfra;
+                       pm->totpoint = writer->totelem;
 
-                       BLI_insertlinkafter(&cache->mem_cache, pm2, pm);
+                       BLI_addtail(&cache->mem_cache, pm);
                }
        }
 
-       if(writer->cfra - cache->last_exact == 1)
-               cache->last_exact = writer->cfra;
+       if(add || overwrite) {
+               if(writer->cfra - cache->last_exact == 1
+                       || writer->cfra == cache->startframe) {
+                       cache->last_exact = writer->cfra;
+                       cache->flag &= ~PTCACHE_FRAMES_SKIPPED;
+               }
+               else
+                       cache->flag |= PTCACHE_FRAMES_SKIPPED;
+       }
        
        if(pf)
                BKE_ptcache_file_close(pf);
 
-       ptcache_update_info(writer->pid);
+       BKE_ptcache_update_info(writer->pid);
 
        return 1;
 }
@@ -730,7 +834,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
                break;
        }
 
-       ptcache_update_info(pid);
+       BKE_ptcache_update_info(pid);
 }
 
 int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
@@ -762,6 +866,9 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
        PointCache *cache;
        float offset, time, nexttime;
 
+       /* TODO: this has to be sorter out once bsystem_time gets redone, */
+       /*       now caches can handle interpolating etc. too - jahka */
+
        /* time handling for point cache:
         * - simulation time is scaled by result of bsystem_time
         * - for offsetting time only time offset is taken into account, since
@@ -798,7 +905,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
 int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
 {
        PointCache *cache;
-       int reset, clear, current, after;
+       int reset, clear, after;
 
        if(!pid->cache)
                return 0;
@@ -806,23 +913,17 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
        cache= pid->cache;
        reset= 0;
        clear= 0;
-       current= 0;
        after= 0;
 
        if(mode == PTCACHE_RESET_DEPSGRAPH) {
                if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
-                       if(cache->flag & PTCACHE_AUTOCACHE) {
-                               reset= 1;
+                       if(cache->flag & PTCACHE_QUICK_CACHE)
                                clear= 1;
-                       }
-                       else {
-                               current= 1;
-                               after= 1;
-                               cache->flag |= PTCACHE_OUTDATED;
-                       }
+
+                       after= 1;
                }
-               else
-                       cache->flag |= PTCACHE_OUTDATED;
+
+               cache->flag |= PTCACHE_OUTDATED;
        }
        else if(mode == PTCACHE_RESET_BAKED) {
                if(!BKE_ptcache_get_continue_physics()) {
@@ -839,17 +940,9 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
                        if(!(cache->flag & PTCACHE_BAKED))
                                clear= 1;
        }
-       else if(mode == PTCACHE_RESET_FREE) {
-               if(!(cache->flag & PTCACHE_BAKED) && !BKE_ptcache_get_continue_physics()) {
-                       if((cache->flag & PTCACHE_AUTOCACHE)==0) {
-                               current= 1;
-                               after= 1;
-                       }
-               }
-       }
 
        if(reset) {
-               cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_SIMULATION_VALID);
+               cache->flag &= ~(PTCACHE_REDO_NEEDED|PTCACHE_SIMULATION_VALID);
                cache->simframe= 0;
                cache->last_exact= 0;
 
@@ -862,12 +955,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
        }
        if(clear)
                BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
-       if(after)
+       else if(after)
                BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, CFRA);
-       if(current)
-               BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_FRAME, CFRA);
 
-       return (reset || clear || current || after);
+       return (reset || clear || after);
 }
 
 int BKE_ptcache_object_reset(Scene *scene, Object *ob, int mode)
@@ -987,6 +1078,7 @@ PointCache *BKE_ptcache_add()
        cache= MEM_callocN(sizeof(PointCache), "PointCache");
        cache->startframe= 1;
        cache->endframe= 250;
+       cache->step= 10;
 
        return cache;
 }
@@ -1019,7 +1111,39 @@ PointCache *BKE_ptcache_copy(PointCache *cache)
 
 
 /* Baking */
-void BKE_ptcache_autocache_all(Scene *scene)
+static int count_quick_cache(Scene *scene, int *quick_step)
+{
+       Base *base = scene->base.first;
+       PTCacheID *pid;
+       ListBase pidlist;
+       int autocache_count= 0;
+
+       for(base = scene->base.first; base; base = base->next) {
+               if(base->object) {
+                       BKE_ptcache_ids_from_object(&pidlist, base->object);
+
+                       for(pid=pidlist.first; pid; pid=pid->next) {
+                               if((pid->cache->flag & PTCACHE_BAKED)
+                                       || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
+                                       continue;
+
+                               if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
+                                       if(!autocache_count)
+                                               *quick_step = pid->cache->step;
+                                       else
+                                               *quick_step = MIN2(*quick_step, pid->cache->step);
+
+                                       autocache_count++;
+                               }
+                       }
+
+                       BLI_freelistN(&pidlist);
+               }
+       }
+
+       return autocache_count;
+}
+void BKE_ptcache_quick_cache_all(Scene *scene)
 {
        PTCacheBaker baker;
 
@@ -1032,7 +1156,7 @@ void BKE_ptcache_autocache_all(Scene *scene)
        baker.render=0;
        baker.scene=scene;
 
-       if(psys_count_autocache(scene, NULL))
+       if(count_quick_cache(scene, &baker.quick_step))
                BKE_ptcache_make_cache(&baker);
 }
 
@@ -1050,11 +1174,10 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
        int endframe = CFRA;
        int bake = baker->bake;
        int render = baker->render;
+       int step = baker->quick_step;
 
        G.afbreek = 0;
 
-       //printf("Caching physics...");
-
        /* set caches to baking mode and figure out start frame */
        if(pid) {
                /* cache/bake a single object */
@@ -1063,7 +1186,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
                        if(pid->type==PTCACHE_TYPE_PARTICLES)
                                psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
 
-                       if(bake || cache->flag & PTCACHE_OUTDATED)
+                       if(bake || cache->flag & PTCACHE_REDO_NEEDED)
                                BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
 
                        startframe = MAX2(cache->last_exact, cache->startframe);
@@ -1072,8 +1195,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
                                endframe = cache->endframe;
                                cache->flag |= PTCACHE_BAKING;
                        }
-                       else
+                       else {
                                endframe = MIN2(endframe, cache->endframe);
+                       }
 
                        cache->flag &= ~PTCACHE_BAKED;
                }
@@ -1088,31 +1212,30 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
                                if(pid->type==PTCACHE_TYPE_PARTICLES)
                                        psys_get_pointcache_start_end(scene, pid->data, &cache->startframe, &cache->endframe);
 
-                               if(cache->flag & PTCACHE_OUTDATED)
+                               if((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0)
+                                       && ((cache->flag & PTCACHE_QUICK_CACHE)==0 || render || bake))
                                        BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
 
                                startframe = MIN2(startframe, cache->startframe);
 
-                               if(bake) {
-                                       endframe = MAX2(endframe, cache->endframe);
+                               if(bake || render) {
                                        cache->flag |= PTCACHE_BAKING;
+
+                                       if(bake)
+                                               endframe = MAX2(endframe, cache->endframe);
                                }
-                               else if(render)
-                                       cache->flag |= PTCACHE_BAKING;
 
                                cache->flag &= ~PTCACHE_BAKED;
 
                        }
                }
-
                BLI_freelistN(&pidlist);
        }
 
        CFRA= startframe;
        scene->r.framelen = 1.0;
-       scene_update_for_newframe(scene, scene->lay);
 
-       for(; CFRA <= endframe; CFRA++) {
+       for(; CFRA <= endframe; CFRA+=step) {
                float prog;
 
                if(bake)
@@ -1133,7 +1256,8 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
 
        /* clear baking flag */
        if(pid) {
-               cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
+               cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+               cache->flag |= PTCACHE_SIMULATION_VALID;
                if(bake)
                        cache->flag |= PTCACHE_BAKED;
        }
@@ -1141,17 +1265,26 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker)
                BKE_ptcache_ids_from_object(&pidlist, base->object);
 
                for(pid=pidlist.first; pid; pid=pid->next) {
-                       cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
+                       cache = pid->cache;
+
+                       if(step > 1)
+                               cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED);
+                       else
+                               cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED);
+
+                       cache->flag |= PTCACHE_SIMULATION_VALID;
+
                        if(bake)
                                cache->flag |= PTCACHE_BAKED;
                }
+               BLI_freelistN(&pidlist);
        }
-       
-       //printf("done!\n");
 
        scene->r.framelen = frameleno;
        CFRA = cfrao;
        scene_update_for_newframe(scene, scene->lay);
+
+       /* TODO: call redraw all windows somehow */
 }
 
 void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
@@ -1161,6 +1294,7 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
        int totelem=0;
        int float_count=0;
        int tot;
+       int last_exact = cache->last_exact;
 
        if (!G.relbase_valid){
                cache->flag &= ~PTCACHE_DISK_CACHE;
@@ -1230,6 +1364,7 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
                                }
 
                                pm->frame = cfra;
+                               pm->totpoint = totelem;
 
                                BLI_addtail(&pid->cache->mem_cache, pm);
 
@@ -1241,4 +1376,8 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) {
                BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
                cache->flag &= ~PTCACHE_DISK_CACHE;
        }
+       
+       cache->last_exact = last_exact;
+
+       BKE_ptcache_update_info(pid);
 }
index b9cbb863022e3514bc16f975250f06719ce8b678..6df907fe132ac4161174f97961badd82342e763b 100644 (file)
@@ -9076,6 +9076,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                Tex *tx;
                ParticleSettings *part;
                Object *ob;
+               PTCacheID *pid;
+               ListBase pidlist;
                
                for(screen= main->screen.first; screen; screen= screen->id.next) {
                        do_versions_windowmanager_2_50(screen);
@@ -9136,14 +9138,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
                /* set old pointcaches to have disk cache flag */
                for(ob = main->object.first; ob; ob= ob->id.next) {
-                       ParticleSystem *psys = ob->particlesystem.first;
 
-                       for(; psys; psys=psys->next) {
-                               if(psys->pointcache)
-                                       psys->pointcache->flag |= PTCACHE_DISK_CACHE;
-                       }
+                       BKE_ptcache_ids_from_object(&pidlist, ob);
+
+                       for(pid=pidlist.first; pid; pid=pid->next)
+                               pid->cache->flag |= PTCACHE_DISK_CACHE;
 
-                       /* TODO: softbody & cloth caches */
+                       BLI_freelistN(&pidlist);
                }
        }
 
index e6ca289e610248ae7e39e2b9154f40450a5d07ea..80d1d78257b6123128f6205d088567e86cfaf965 100644 (file)
@@ -552,6 +552,7 @@ static void write_userdef(WriteData *wd)
 
 /* TODO: replace *cache with *cachelist once it's coded */
 #define PTCACHE_WRITE_PSYS     0
+#define PTCACHE_WRITE_CLOTH    1
 static void write_pointcaches(WriteData *wd, PointCache *cache, int type)
 {
        writestruct(wd, DATA, "PointCache", 1, cache);
@@ -563,6 +564,8 @@ static void write_pointcaches(WriteData *wd, PointCache *cache, int type)
                        writestruct(wd, DATA, "PTCacheMem", 1, pm);
                        if(type==PTCACHE_WRITE_PSYS)
                                writestruct(wd, DATA, "ParticleKey", pm->totpoint, pm->data);
+                       else if(type==PTCACHE_WRITE_CLOTH)
+                               writedata(wd, DATA, 9 * sizeof(float) * pm->totpoint, pm->data);
                }
        }
 }
@@ -1058,7 +1061,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase, int write_undo)
                        
                        writestruct(wd, DATA, "ClothSimSettings", 1, clmd->sim_parms);
                        writestruct(wd, DATA, "ClothCollSettings", 1, clmd->coll_parms);
-                       writestruct(wd, DATA, "PointCache", 1, clmd->point_cache);
+                       write_pointcaches(wd, clmd->point_cache, PTCACHE_WRITE_CLOTH);
                } 
                else if(md->type==eModifierType_Fluidsim) {
                        FluidsimModifierData *fluidmd = (FluidsimModifierData*) md;
index 3a61237e1cb126f0c99d1da91e2e7fd03c5d3a14..a9866d8898e4021ec34c9fee85081440ca0005e5 100644 (file)
@@ -2077,13 +2077,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
                rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2);
        }
 
-       if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU)) {
-               but->flag |= UI_TEXT_LEFT;
-       }
-       
-       if(but->type==BUT_TOGDUAL) {
+       if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU))
+               but->flag |= (UI_TEXT_LEFT|UI_ICON_LEFT);
+       else if(but->type==BUT_TOGDUAL)
                but->flag |= UI_ICON_LEFT;
-       }
 
        but->flag |= (block->flag & UI_BUT_ALIGN);
 
index 06dc5d1e606a74861b78ee005146a4d67a2768d7..eaf78ae89ef01f7c3433bdcc5299a255594a10aa 100644 (file)
@@ -1288,6 +1288,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
 
 /**************** window level modal panel interaction **************/
 
+/* note, this is modal handler and should not swallow events for animation */
 static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
 {
        Panel *panel= userdata;
@@ -1303,8 +1304,6 @@ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
                        panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
                else
                        panel_activate_state(C, panel, PANEL_STATE_EXIT);
-
-               return WM_UI_HANDLER_BREAK;
        }
        else if(event->type == MOUSEMOVE) {
                if(data->state == PANEL_STATE_WAIT_UNTAB)
index 735cfe742c60af279c27915ec545cbe7d82b9087..ddf31c0db6688c38cc166c017a19796bd4ccffb6 100644 (file)
@@ -1028,7 +1028,7 @@ static struct uiWidgetColors wcol_menu_back= {
        {0, 0, 0, 255},
        {25, 25, 25, 230},
        {45, 45, 45, 230},
-       {255, 255, 255, 255},
+       {100, 100, 100, 255},
        
        {255, 255, 255, 255},
        {255, 255, 255, 255},
index aa1cc5790efbb2188d622c31b25167c0c7580c82..c32c8c817fb8188203a56974b5e94042fc1943ae 100644 (file)
@@ -333,6 +333,12 @@ void UI_view2d_curRect_validate(View2D *v2d)
        if (v2d->keepzoom & V2D_LOCKZOOM_Y)
                height= winy;
                
+       /* values used to divide, so make it safe */
+       if(width<1) width= 1;
+       if(height<1) height= 1;
+       if(winx<1) winx= 1;
+       if(winy<1) winy= 1;
+       
        /* keepzoom (V2D_KEEPZOOM set), indicates that zoom level on each axis must not exceed limits 
         * NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
         */
index 8483aee52f48b9f0942724f851fac8b04d1bbf3b..12138ee13d2c0233cb5bf7827c4bc73557249012 100644 (file)
@@ -1295,9 +1295,9 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
        /* center */
        curs= give_cursor(scene, v3d);
        VECCOPY(primmat[3], curs);
+       VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
        Mat3Inv(imat, mat);
        Mat3MulVecfl(imat, primmat[3]);
-       VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
        
        if(v3d) return v3d->grid;
        return 1.0f;
index 8102b1bfb9ca3ed934af41b694b9f70490085ba3..c436ccdb328473c6a1f328d9b6ca80dd0b2b220d 100644 (file)
@@ -388,7 +388,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_mesh_add(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Mesh";
+       ot->name= "Add Mesh";
        ot->description = "Add a mesh object to the scene.";
        ot->idname= "OBJECT_OT_mesh_add";
        
@@ -462,7 +462,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event)
 void OBJECT_OT_curve_add(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Curve";
+       ot->name= "Add Curve";
        ot->description = "Add a curve object to the scene.";
        ot->idname= "OBJECT_OT_curve_add";
        
@@ -520,7 +520,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_surface_add(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Surface";
+       ot->name= "Add Surface";
        ot->description = "Add a surface object to the scene.";
        ot->idname= "OBJECT_OT_surface_add";
        
@@ -557,7 +557,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_text_add(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Text";
+       ot->name= "Add Text";
        ot->description = "Add a text object to the scene";
        ot->idname= "OBJECT_OT_text_add";
        
@@ -602,7 +602,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
 void OBJECT_OT_armature_add(wmOperatorType *ot)
 {      
        /* identifiers */
-       ot->name= "Armature";
+       ot->name= "Add Armature";
        ot->description = "Add an armature object to the scene.";
        ot->idname= "OBJECT_OT_armature_add";
        
index 3374e05883cf8f99fc3f5412d27afcfc97ec482b..893c59a521ded680d240a22b705c195786124ea8 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "DNA_scene_types.h"
 #include "DNA_object_force.h"
+#include "DNA_modifier_types.h"
 
 #include "BKE_context.h"
 #include "BKE_particle.h"
@@ -39,7 +40,7 @@
 #include "BKE_utildefines.h" 
 #include "BKE_pointcache.h"
 #include "BKE_global.h"
-#include "BKE_multires.h"
+#include "BKE_modifier.h"
 
 #include "BLI_blenlib.h"
 
@@ -81,6 +82,7 @@ static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
        baker.pid = NULL;
        baker.bake = RNA_boolean_get(op->ptr, "bake");
        baker.render = 0;
+       baker.quick_step = 1;
        baker.break_test = cache_break_test;
        baker.break_data = NULL;
        baker.progressbar = (void (*)(void *, int))WM_timecursor;
@@ -104,12 +106,11 @@ static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
 
                for(pid=pidlist.first; pid; pid=pid->next) {
                        pid->cache->flag &= ~PTCACHE_BAKED;
-                       BKE_ptcache_id_reset(scene, pid, PTCACHE_RESET_OUTDATED);
                }
+               
+               BLI_freelistN(&pidlist);
        }
 
-       BLI_freelistN(&pidlist);
-
        WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
 
        return OPERATOR_FINISHED;
@@ -127,6 +128,8 @@ void PTCACHE_OT_bake_all(wmOperatorType *ot)
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
 }
 void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
 {
@@ -142,6 +145,112 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/**************************** cloth **********************************/
+static int ptcache_bake_cloth_poll(bContext *C)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+       if(!scene || !ob || ob->id.lib || !clmd)
+               return 0;
+       
+       return 1;
+}
+
+static int ptcache_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       PTCacheID pid;
+       PTCacheBaker baker;
+
+       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+       baker.scene = scene;
+       baker.pid = &pid;
+       baker.bake = RNA_boolean_get(op->ptr, "bake");
+       baker.render = 0;
+       baker.quick_step = 1;
+       baker.break_test = cache_break_test;
+       baker.break_data = NULL;
+       baker.progressbar = WM_timecursor;
+       baker.progresscontext = CTX_wm_window(C);
+
+       BKE_ptcache_make_cache(&baker);
+
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+       return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_active_object(C);
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       PTCacheID pid;
+
+       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+       pid.cache->flag &= ~PTCACHE_BAKED;
+
+       WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+       return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_cloth(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake Cloth";
+       ot->idname= "PTCACHE_OT_cache_cloth";
+       
+       /* api callbacks */
+       ot->exec= ptcache_bake_cloth_exec;
+       ot->poll= ptcache_bake_cloth_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_cloth(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Free Cloth Bake";
+       ot->idname= "PTCACHE_OT_free_bake_cloth";
+       
+       /* api callbacks */
+       ot->exec= ptcache_free_bake_cloth_exec;
+       ot->poll= ptcache_bake_cloth_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_cloth_cache_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_active_object(C);
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       PTCacheID pid;
+
+       BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+       pid.cache->flag |= PTCACHE_BAKED;
+
+       return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_cloth_cache(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake From Cache";
+       ot->idname= "PTCACHE_OT_bake_from_cloth_cache";
+       
+       /* api callbacks */
+       ot->exec= ptcache_bake_from_cloth_cache_exec;
+       ot->poll= ptcache_bake_cloth_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /**************************** particles **********************************/
 static int ptcache_bake_particle_system_poll(bContext *C)
 {
@@ -168,6 +277,7 @@ static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
        baker.pid = &pid;
        baker.bake = RNA_boolean_get(op->ptr, "bake");
        baker.render = 0;
+       baker.quick_step = 1;
        baker.break_test = cache_break_test;
        baker.break_data = NULL;
        baker.progressbar = (void (*)(void *, int))WM_timecursor;
@@ -188,7 +298,6 @@ static int ptcache_free_bake_particle_system_exec(bContext *C, wmOperator *op)
 
        BKE_ptcache_id_from_particles(&pid, ob, psys);
        psys->pointcache->flag &= ~PTCACHE_BAKED;
-       BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
 
        WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
 
@@ -256,6 +365,9 @@ void ED_operatortypes_pointcache(void)
        WM_operatortype_append(PTCACHE_OT_cache_particle_system);
        WM_operatortype_append(PTCACHE_OT_free_bake_particle_system);
        WM_operatortype_append(PTCACHE_OT_bake_from_particles_cache);
+       WM_operatortype_append(PTCACHE_OT_cache_cloth);
+       WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
+       WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
 }
 
 //void ED_keymap_pointcache(wmWindowManager *wm)
index f40880b901f1c407e40598af57cfe9b14af1f15d..8f0b52ef3a19159ae9a70b6f0ad2452f26dd824a 100644 (file)
@@ -738,37 +738,6 @@ static void sculpt_add_damaged_rect(SculptSession *ss)
        }
 }
 
-/* Clears the depth buffer in each modified area. */
-#if 0
-static void sculpt_clear_damaged_areas(SculptSession *ss)
-{
-       RectNode *rn= NULL;
-
-       for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
-               rcti clp = rn->r;
-               rcti *win = NULL; /*XXX: &curarea->winrct; */
-               
-               clp.xmin += win->xmin;
-               clp.xmax += win->xmin;
-               clp.ymin += win->ymin;
-               clp.ymax += win->ymin;
-               
-               if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
-                  clp.ymin < win->ymax && clp.ymax > win->ymin) {
-                       if(clp.xmin < win->xmin) clp.xmin = win->xmin;
-                       if(clp.ymin < win->ymin) clp.ymin = win->ymin;
-                       if(clp.xmax > win->xmax) clp.xmax = win->xmax;
-                       if(clp.ymax > win->ymax) clp.ymax = win->ymax;
-
-                       glScissor(clp.xmin + 1, clp.ymin + 1,
-                                 clp.xmax - clp.xmin - 2,
-                                 clp.ymax - clp.ymin - 2);
-               }
-               
-               glClear(GL_DEPTH_BUFFER_BIT);
-       }
-}
-#endif
 static void do_brush_action(Sculpt *sd, StrokeCache *cache)
 {
        SculptSession *ss = sd->session;
@@ -987,25 +956,6 @@ static void sculpt_update_tex(Sculpt *sd)
        }
 }
 
-void sculptmode_selectbrush_menu(void)
-{
-       /* XXX: I guess menus belong elsewhere too?
-
-       Sculpt *sd= sculpt_data();
-       int val;
-       
-       pupmenu_set_active(sd->brush_type);
-       
-       val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
-
-       if(val>0) {
-               sd->brush_type= val;
-
-               allqueue(REDRAWVIEW3D, 1);
-               allqueue(REDRAWBUTSEDIT, 1);
-       }*/
-}
-
 static void sculptmode_update_all_projverts(SculptSession *ss)
 {
        unsigned i;
@@ -1084,89 +1034,6 @@ static void sculpt_update_mesh_elements(bContext *C)
        }
 }
 
-/* XXX: lots of drawing code (partial redraw), has to go elsewhere */
-#if 0
-void sculptmode_draw_wires(SculptSession *ss, int only_damaged)
-{
-       Mesh *me = get_mesh(OBACT);
-       int i;
-
-       bglPolygonOffset(1.0);
-       glDepthMask(0);
-       BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
-
-       for(i=0; i<me->totedge; i++) {
-               MEdge *med= &me->medge[i];
-
-               if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
-                  (med->flag & ME_EDGEDRAW)) {
-                       glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
-               }
-       }
-
-       glDepthMask(1);
-       bglPolygonOffset(0.0);
-}
-
-void sculptmode_draw_mesh(int only_damaged) 
-{
-       int i, j, dt, drawCurrentMat = 1, matnr= -1;
-       SculptSession *ss = sculpt_session();
-
-       sculpt_update_mesh_elements(ss, OBACT);
-
-       persp(PERSP_VIEW);
-       mymultmatrix(OBACT->obmat);
-       glEnable(GL_DEPTH_TEST);
-       glEnable(GL_LIGHTING);
-       /* XXX: GPU_set_object_materials(G.scene, OBACT, 0, NULL); */
-       glEnable(GL_CULL_FACE);
-
-       glShadeModel(GL_SMOOTH);
-
-       glVertexPointer(3, GL_FLOAT, sizeof(MVert), &cache->mvert[0].co);
-       glNormalPointer(GL_SHORT, sizeof(MVert), &cache->mvert[0].no);
-
-       dt= MIN2(G.vd->drawtype, OBACT->dt);
-       if(dt==OB_WIRE)
-               glColorMask(0,0,0,0);
-
-       for(i=0; i<ss->totface; ++i) {
-               MFace *f= &ss->mface[i];
-               char inside= 0;
-               int new_matnr= f->mat_nr + 1;
-               
-               if(new_matnr != matnr)
-                       drawCurrentMat= GPU_enable_material(matnr = new_matnr, NULL);
-               
-               /* If only_damaged!=0, only draw faces that are partially
-                  inside the area(s) modified by the brush */
-               if(only_damaged) {
-                       for(j=0; j<(f->v4?4:3); ++j) {
-                               if(ss->projverts[*((&f->v1)+j)].inside) {
-                                       inside= 1;
-                                       break;
-                               }
-                       }
-               }
-               else
-                       inside= 1;
-                       
-               if(inside && drawCurrentMat)
-                       glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
-       }
-
-       glDisable(GL_CULL_FACE);
-       glDisable(GL_LIGHTING);
-       glColorMask(1,1,1,1);
-
-       if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
-               sculptmode_draw_wires(ss, only_damaged);
-
-       glDisable(GL_DEPTH_TEST);
-}
-#endif
-
 static int sculpt_mode_poll(bContext *C)
 {
        return G.f & G_SCULPTMODE;
@@ -1476,9 +1343,6 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
        Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
 
        view3d_operator_needs_opengl(C);
-       sculpt_brush_stroke_init_properties(C, op, event, sd->session);
-
-       sculptmode_update_all_projverts(sd->session);
 
        /* TODO: Shouldn't really have to do this at the start of every
           stroke, but sculpt would need some sort of notification when
@@ -1547,34 +1411,53 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
 {
        PointerRNA itemptr;
        Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+       ARegion *ar = CTX_wm_region(C);
        float center[3];
        int mouse[2] = {event->x, event->y};
+       float cur_depth;
 
        sculpt_update_mesh_elements(C);
 
-       unproject(sd->session->cache->mats, center, event->x, event->y,
-                 read_cached_depth(&sd->session->cache->vc, event->x, event->y));
+       if(!sd->session->cache) {
+               ViewContext vc;
+               view3d_set_viewcontext(C, &vc);
+               cur_depth = read_cached_depth(&vc, event->x, event->y);
 
-       /* Add to stroke */
-       RNA_collection_add(op->ptr, "stroke", &itemptr);
-       RNA_float_set_array(&itemptr, "location", center);
-       RNA_int_set_array(&itemptr, "mouse", mouse);
-       RNA_boolean_set(&itemptr, "flip", event->shift);
-       sculpt_update_cache_variants(sd, &itemptr);
+               /* Don't start the stroke until a valid depth is found */
+               if(cur_depth < 1.0 - FLT_EPSILON) {
+                       sculpt_brush_stroke_init_properties(C, op, event, sd->session);
+                       sculptmode_update_all_projverts(sd->session);
+               }
 
-       sculpt_restore_mesh(sd);
-       do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
+               ED_region_tag_redraw(ar);
+       }
 
-       sculpt_flush_update(C);
-       sculpt_post_stroke_free(sd->session);
+       if(sd->session->cache) {
+               cur_depth = read_cached_depth(&sd->session->cache->vc, event->x, event->y);
+               unproject(sd->session->cache->mats, center, event->x, event->y, cur_depth);
 
-       /* Finished */
-       if(event->type == LEFTMOUSE && event->val == 0) {
-               request_depth_update(sd->session->cache->vc.rv3d);
+               /* Add to stroke */
+               RNA_collection_add(op->ptr, "stroke", &itemptr);
+               RNA_float_set_array(&itemptr, "location", center);
+               RNA_int_set_array(&itemptr, "mouse", mouse);
+               RNA_boolean_set(&itemptr, "flip", event->shift);
+               sculpt_update_cache_variants(sd, &itemptr);
 
-               sculpt_cache_free(sd->session->cache);
+               sculpt_restore_mesh(sd);
+               do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
 
-               sculpt_undo_push(C, sd);
+               sculpt_flush_update(C);
+               sculpt_post_stroke_free(sd->session);
+       }
+
+       /* Finished */
+       if(event->type == LEFTMOUSE && event->val == 0) {
+               if(sd->session->cache) {
+                       request_depth_update(sd->session->cache->vc.rv3d);
+                       sculpt_cache_free(sd->session->cache);
+                       sd->session->cache = NULL;
+                       sculpt_undo_push(C, sd);
+               }
 
                return OPERATOR_FINISHED;
        }
@@ -1718,454 +1601,3 @@ void ED_operatortypes_sculpt()
        WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
        WM_operatortype_append(SCULPT_OT_brush_curve_preset);
 }
-
-void sculpt(Sculpt *sd)
-{
-#if 0
-       SculptSession *ss= sd->session;
-       Object *ob= NULL; /*XXX */
-       Mesh *me;
-       MultiresModifierData *mmd = NULL;
-       /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
-       short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
-       short modifier_calculations= 0;
-       BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
-       short spacing= 32000;
-       int scissor_box[4];
-       float offsetRot;
-       int smooth_stroke = 0, i;
-       int anchored, rake = 0 /* XXX: rake = ? */;
-
-       /* XXX: checking that sculpting is allowed
-       if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
-               return;
-       if(!(ob->lay & G.vd->lay))
-               error("Active object is not in this layer");
-       if(ob_get_keyblock(ob)) {
-               if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
-                       error("Cannot sculpt on unlocked shape key");
-                       return;
-               }
-       }*/
-       
-       anchored = sd->brush->flag & BRUSH_ANCHORED;
-       smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored;
-
-       if(smooth_stroke)
-               sculpt_stroke_new(256);
-
-       ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-       ss->damaged_verts.first = ss->damaged_verts.last = NULL;
-       ss->vertexcosnos = NULL;
-
-       mmd = sculpt_multires_active(ob);
-
-       /* Check that vertex users are up-to-date */
-       if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != cache->totvert) {
-               sculpt_vertexusers_free(ss);
-               calc_vertex_users(ss);
-               if(ss->projverts)
-                       MEM_freeN(ss->projverts);
-               ss->projverts = NULL;
-               active_ob= ob;
-       }
-               
-       glEnableClientState(GL_VERTEX_ARRAY);
-       glEnableClientState(GL_NORMAL_ARRAY);
-
-       /*XXX:
-       persp(PERSP_VIEW);
-       getmouseco_areawin(mvalo);*/
-
-       /* Init texture
-          FIXME: Shouldn't be doing this every time! */
-       if(sd->tex_mode!=SCULPTREPT_3D)
-               sculptmode_update_tex(sd);
-
-       /*XXX: getmouseco_areawin(mouse); */
-       mvalo[0]= mouse[0];
-       mvalo[1]= mouse[1];
-       lastSigMouse[0]=mouse[0];
-       lastSigMouse[1]=mouse[1];
-       mousebut = 0; /* XXX: L_MOUSE; */
-
-       /* If modifier_calculations is true, then extra time must be spent
-          updating the mesh. This takes a *lot* longer, so it's worth
-          skipping if the modifier stack is empty. */
-       modifier_calculations= sculpt_modifiers_active(ob);
-
-       if(modifier_calculations)
-               ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */
-       sculptmode_update_all_projverts(ss);
-
-       /* Capture original copy */
-       if(sd->flags & SCULPT_DRAW_FAST)
-               glAccum(GL_LOAD, 1);
-
-       /* Get original scissor box */
-       glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
-       
-       /* For raking, get the original angle*/
-       offsetRot=sculpt_tex_angle(sd);
-
-       me = get_mesh(ob);
-
-       while (/*XXX:get_mbut() & mousebut*/0) {
-               /* XXX: getmouseco_areawin(mouse); */
-               /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
-               if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
-                       /*Nasty looking, but just orig + new angle really*/
-                       set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
-                       lastSigMouse[0]=mouse[0];
-                       lastSigMouse[1]=mouse[1];
-               }
-               
-               if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
-                  sd->brush->flag & BRUSH_AIRBRUSH) {
-                       a->firsttime = firsttime;
-                       firsttime= 0;
-
-                       if(smooth_stroke)
-                               sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]);
-
-                       spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
-
-                       if(modifier_calculations && !ss->vertexcosnos)
-                               ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /*XXX scene = ? */
-
-                       if(sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
-                               if(anchored) {
-                                       /* Restore the mesh before continuing with anchored stroke */
-                                       /*if(a->mesh_store) {
-                                               for(i = 0; i < cache->totvert; ++i) {
-                                                       VecCopyf(cache->mvert[i].co, &a->mesh_store[i].x);
-                                                       cache->mvert[i].no[0] = a->orig_norms[i][0];
-                                                       cache->mvert[i].no[1] = a->orig_norms[i][1];
-                                                       cache->mvert[i].no[2] = a->orig_norms[i][2];
-                                               }
-                                               }*/
-                                       
-                                       //do_symmetrical_brush_actions(sd, a, mouse, NULL);
-                               }
-                               else {
-                                       if(smooth_stroke) {
-                                               sculpt_stroke_apply(sd, ss->stroke);
-                                       }
-                                       else if(sd->spacing==0 || spacing>sd->spacing) {
-                                               //do_symmetrical_brush_actions(sd, a, mouse, NULL);
-                                               spacing= 0;
-                                       }
-                               }
-                       }
-                       else {
-                               //do_symmetrical_brush_actions(sd, a, mouse, mvalo);
-                               //unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth);
-                       }
-
-                       if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) {
-                               /* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ }
-
-                       if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) {
-                               calc_damaged_verts(ss, a);
-                               /*XXX: scrarea_do_windraw(curarea);
-                               screen_swapbuffers(); */
-                       } else { /* Optimized drawing */
-                               calc_damaged_verts(ss, a);
-
-                               /* Draw the stored image to the screen */
-                               glAccum(GL_RETURN, 1);
-
-                               sculpt_clear_damaged_areas(ss);
-                               
-                               /* Draw all the polygons that are inside the modified area(s) */
-                               glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
-                               /* XXX: sculptmode_draw_mesh(1); */
-                               glAccum(GL_LOAD, 1);
-
-                               projverts_clear_inside(ss);
-
-                               /* XXX: persp(PERSP_WIN); */
-                               glDisable(GL_DEPTH_TEST);
-                               
-                               /* Draw cursor */
-                               if(sd->flags & SCULPT_TOOL_DRAW)
-                                       fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size);
-                               /* XXX: if(smooth_stroke)
-                                  sculpt_stroke_draw();
-                               
-                               myswapbuffers(); */
-                       }
-
-                       BLI_freelistN(&ss->damaged_rects);
-                       ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-       
-                       mvalo[0]= mouse[0];
-                       mvalo[1]= mouse[1];
-
-                       if(ss->vertexcosnos) {
-                               MEM_freeN(ss->vertexcosnos);
-                               ss->vertexcosnos= NULL;
-                       }
-
-               }
-               else { /*XXX:BIF_wait_for_statechange();*/ }
-       }
-
-       /* Set the rotation of the brush back to what it was before any rake */
-       set_tex_angle(sd, offsetRot);
-       
-       if(smooth_stroke) {
-               sculpt_stroke_apply_all(sd, ss->stroke);
-               calc_damaged_verts(ss, a);
-               BLI_freelistN(&ss->damaged_rects);
-       }
-
-       //if(a->layer_disps) MEM_freeN(a->layer_disps);
-       //if(a->mesh_store) MEM_freeN(a->mesh_store);
-       //if(a->orig_norms) MEM_freeN(a->orig_norms);
-       for(i=0; i<8; ++i)
-               BLI_freelistN(&a->grab_active_verts[i]);
-       MEM_freeN(a);
-       sculpt_stroke_free(ss->stroke);
-       ss->stroke = NULL;
-
-       if(mmd) {
-               if(mmd->undo_verts && mmd->undo_verts != cache->mvert)
-                       MEM_freeN(mmd->undo_verts);
-               
-               mmd->undo_verts = cache->mvert;
-               mmd->undo_verts_tot = cache->totvert;
-       }
-
-       //sculpt_undo_push(sd);
-
-       /* XXX: if(G.vd->depths) G.vd->depths->damaged= 1;
-          allqueue(REDRAWVIEW3D, 0); */
-#endif
-}
-
-/* Partial Mesh Visibility */
-
-/* XXX: Partial vis. always was a mess, have to figure something out */
-#if 0
-/* mode: 0=hide outside selection, 1=hide inside selection */
-static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
-{
-       Mesh *me= get_mesh(ob);
-       float hidebox[6][3];
-       vec3f plane_normals[4];
-       float plane_ds[4];
-       unsigned i, j;
-       unsigned ndx_show, ndx_hide;
-       MVert *nve;
-       unsigned face_cnt_show= 0, face_ndx_show= 0;
-       unsigned edge_cnt_show= 0, edge_ndx_show= 0;
-       unsigned *old_map= NULL;
-       const unsigned SHOW= 0, HIDE=1;
-
-       /* Convert hide box from 2D to 3D */
-       unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
-       unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
-       unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
-       unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
-       unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
-       unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
-       
-       /* Calculate normals for each side of hide box */
-       CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
-       CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
-       CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
-       CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
-       
-       /* Calculate D for each side of hide box */
-       for(i= 0; i<4; ++i)
-               plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
-                       hidebox[i][2]*plane_normals[i].z;
-       
-       /* Add partial visibility to mesh */
-       if(!me->pv) {
-               me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
-       } else {
-               old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
-               for(i=0; i<me->pv->totvert; ++i) {
-                       old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
-               }
-               mesh_pmv_revert(ob, me);
-       }
-       
-       /* Kill sculpt data */
-       active_ob= NULL;
-       
-       /* Initalize map with which verts are to be hidden */
-       me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
-       me->pv->totvert= me->totvert;
-       me->totvert= 0;
-       for(i=0; i<me->pv->totvert; ++i) {
-               me->pv->vert_map[i]= mode ? HIDE:SHOW;
-               for(j=0; j<4; ++j) {
-                       if(me->mvert[i].co[0] * plane_normals[j].x +
-                          me->mvert[i].co[1] * plane_normals[j].y +
-                          me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
-                               me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
-                               break;
-                       }
-               }
-               if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
-               if(!me->pv->vert_map[i]) ++me->totvert;
-
-       }
-       if(old_map) MEM_freeN(old_map);
-
-       /* Find out how many faces to show */
-       for(i=0; i<me->totface; ++i) {
-               if(!me->pv->vert_map[me->mface[i].v1] &&
-                  !me->pv->vert_map[me->mface[i].v2] &&
-                  !me->pv->vert_map[me->mface[i].v3]) {
-                       if(me->mface[i].v4) {
-                               if(!me->pv->vert_map[me->mface[i].v4])
-                                       ++face_cnt_show;
-                       }
-                       else ++face_cnt_show;
-               }
-       }
-       /* Find out how many edges to show */
-       for(i=0; i<me->totedge; ++i) {
-               if(!me->pv->vert_map[me->medge[i].v1] &&
-                  !me->pv->vert_map[me->medge[i].v2])
-                       ++edge_cnt_show;
-       }
-
-       /* Create new vert array and reset each vert's map with map[old]=new index */
-       nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
-       ndx_show= 0; ndx_hide= me->totvert;
-       for(i=0; i<me->pv->totvert; ++i) {
-               if(me->pv->vert_map[i]) {
-                       me->pv->vert_map[i]= ndx_hide;
-                       nve[me->pv->vert_map[i]]= me->mvert[i];
-                       ++ndx_hide;
-               } else {
-                       me->pv->vert_map[i]= ndx_show;
-                       nve[me->pv->vert_map[i]]= me->mvert[i];
-                       ++ndx_show;
-               }
-       }
-       CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
-       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
-
-       /* Create new face array */
-       me->pv->old_faces= me->mface;
-       me->pv->totface= me->totface;
-       me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
-       for(i=0; i<me->totface; ++i) {
-               MFace *pr_f= &me->pv->old_faces[i];
-               char show= 0;
-
-               if(me->pv->vert_map[pr_f->v1] < me->totvert &&
-                  me->pv->vert_map[pr_f->v2] < me->totvert &&
-                  me->pv->vert_map[pr_f->v3] < me->totvert) {
-                       if(pr_f->v4) {
-                               if(me->pv->vert_map[pr_f->v4] < me->totvert)
-                                       show= 1;
-                       }
-                       else show= 1;
-               }
-
-               if(show) {
-                       MFace *cr_f= &me->mface[face_ndx_show];
-                       *cr_f= *pr_f;
-                       cr_f->v1= me->pv->vert_map[pr_f->v1];
-                       cr_f->v2= me->pv->vert_map[pr_f->v2];
-                       cr_f->v3= me->pv->vert_map[pr_f->v3];
-                       cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
-                       test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
-                       ++face_ndx_show;
-               }
-       }
-       me->totface= face_cnt_show;
-       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-       /* Create new edge array */
-       me->pv->old_edges= me->medge;
-       me->pv->totedge= me->totedge;
-       me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
-       me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
-       for(i=0; i<me->totedge; ++i) {
-               if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
-                  me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
-                       MEdge *cr_e= &me->medge[edge_ndx_show];
-                       me->pv->edge_map[i]= edge_ndx_show;
-                       *cr_e= me->pv->old_edges[i];
-                       cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
-                       cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
-                       ++edge_ndx_show;
-               }
-               else me->pv->edge_map[i]= -1;
-       }
-       me->totedge= edge_cnt_show;
-       CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
-
-       /* XXX: DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); */
-}
-
-static rcti sculptmode_pmv_box()
-{
-       /*XXX:  short down[2], mouse[2];
-       rcti ret;
-
-       getmouseco_areawin(down);
-
-       while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
-               getmouseco_areawin(mouse);
-
-               scrarea_do_windraw(curarea);
-
-               persp(PERSP_WIN);
-               glLineWidth(2);
-               setlinestyle(2);
-               sdrawXORline(down[0],down[1],mouse[0],down[1]);
-               sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
-               sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
-               sdrawXORline(down[0],mouse[1],down[0],down[1]);
-               setlinestyle(0);
-               glLineWidth(1);
-               persp(PERSP_VIEW);
-
-               screen_swapbuffers();
-               backdrawview3d(0);
-       }
-
-       ret.xmin= down[0]<mouse[0]?down[0]:mouse[0];
-       ret.ymin= down[1]<mouse[1]?down[1]:mouse[1];
-       ret.xmax= down[0]>mouse[0]?down[0]:mouse[0];
-       ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
-       return ret;*/
-}
-
-void sculptmode_pmv(int mode)
-{
-       Object *ob= NULL; /*XXX: OBACT; */
-       rcti hb_2d;
-       
-       if(ob_get_key(ob)) {
-               error("Cannot hide mesh with shape keys enabled");
-               return;
-       }
-       
-       hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
-       
-       sculptmode_correct_state();
-
-       waitcursor(1);
-
-       if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
-               init_sculptmatrices();
-
-               sculptmode_do_pmv(ob,&hb_2d,mode);
-       }
-       else mesh_pmv_off(ob, get_mesh(ob));
-
-       /*XXX: scrarea_do_windraw(curarea); */
-
-       waitcursor(0);
-}
-#endif
index 79284ada4836cdf51e1281c8115020b441b4db43..7c622f172a2be23ab1957ed58aafa65e6c43afc1 100644 (file)
@@ -173,10 +173,10 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
                uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     ICON_OBJECT_DATA,       xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object");
        if(sbuts->pathflag & (1<<BCONTEXT_CONSTRAINT))
                uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     ICON_CONSTRAINT,        xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint");
-       if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER))
-               uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     ICON_MODIFIER,  xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
        if(sbuts->pathflag & (1<<BCONTEXT_DATA))
                uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     sbuts->dataicon,        xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data");
+       if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER))
+               uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     ICON_MODIFIER,  xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
        if(sbuts->pathflag & (1<<BCONTEXT_BONE))
                uiDefIconButS(block, ROW, B_CONTEXT_SWITCH,     ICON_BONE_DATA, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone");
        if(sbuts->pathflag & (1<<BCONTEXT_MATERIAL))
index b213e4288be407dd67245f205f469412ab7e0f2c..13ea778fb007ff59fad8a5a3fda68859e45f7044 100644 (file)
@@ -71,5 +71,10 @@ void MATERIAL_OT_new(struct wmOperatorType *ot);
 void TEXTURE_OT_new(struct wmOperatorType *ot);
 void WORLD_OT_new(struct wmOperatorType *ot);
 
+void OBJECT_OT_particle_system_slot_add(struct wmOperatorType *ot);
+void OBJECT_OT_particle_system_slot_remove(struct wmOperatorType *ot);
+
+void PARTICLE_OT_new(struct wmOperatorType *ot);
+
 #endif /* ED_BUTTONS_INTERN_H */
 
index 6755a2be1b7fea4b419984917ec2972eec68380b..6ca92674c6edaef3ee191f5c441ceeae60fdff45 100644 (file)
@@ -42,6 +42,7 @@
 #include "BKE_font.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
+#include "BKE_particle.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
 #include "BKE_world.h"
@@ -407,3 +408,109 @@ void WORLD_OT_new(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+
+
+/********************** particle system slot operators *********************/
+
+static int particle_system_slot_add_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Scene *scene = CTX_data_scene(C);
+
+       if(!scene || !ob)
+               return OPERATOR_CANCELLED;
+
+       object_add_particle_system_slot(scene, ob);
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_slot_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Add Particle System Slot";
+       ot->idname= "OBJECT_OT_particle_system_slot_add";
+       
+       /* api callbacks */
+       ot->exec= particle_system_slot_add_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int particle_system_slot_remove_exec(bContext *C, wmOperator *op)
+{
+       Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+       Scene *scene = CTX_data_scene(C);
+
+       if(!scene || !ob)
+               return OPERATOR_CANCELLED;
+
+       object_remove_particle_system_slot(scene, ob);
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_slot_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Remove Particle System Slot";
+       ot->idname= "OBJECT_OT_particle_system_slot_remove";
+       
+       /* api callbacks */
+       ot->exec= particle_system_slot_remove_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new particle settings operator *********************/
+
+static int new_particle_settings_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       ParticleSettings *part= CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings).data;
+       Object *ob;
+       PointerRNA ptr;
+
+       /* add or copy particle setting */
+       if(part)
+               part= psys_copy_settings(part);
+       else
+               part= psys_new_settings("PSys", NULL);
+
+       /* attempt to assign to material slot */
+       ptr= CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+
+       if(ptr.data) {
+               ParticleSystem *psys = (ParticleSystem*)ptr.data;
+               ob= ptr.id.data;
+
+               if(psys->part)
+                       psys->part->id.us--;
+
+               psys->part = part;
+
+               DAG_scene_sort(scene);
+               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+               WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+       }
+       
+       return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "New Particle Settings";
+       ot->idname= "PARTICLE_OT_new";
+       
+       /* api callbacks */
+       ot->exec= new_particle_settings_exec;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
index 483a1dc61002c60f7fb1385865513847a4041b12..7954d5254cc0a37c6d248e921bd64058b2824df7 100644 (file)
@@ -219,6 +219,11 @@ void buttons_operatortypes(void)
        WM_operatortype_append(MATERIAL_OT_new);
        WM_operatortype_append(TEXTURE_OT_new);
        WM_operatortype_append(WORLD_OT_new);
+
+       WM_operatortype_append(OBJECT_OT_particle_system_slot_add);
+       WM_operatortype_append(OBJECT_OT_particle_system_slot_remove);
+
+       WM_operatortype_append(PARTICLE_OT_new);
 }
 
 void buttons_keymap(struct wmWindowManager *wm)
index 88af60ac0f489e864d56074efc76edfc96a48851..34a935103a7c7bfd9d5f041532e21726727a0d61 100644 (file)
@@ -148,8 +148,82 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
        uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
 }
 
+/* ******************* */
+
+typedef struct CustomTool {
+       struct CustomTool *next, *prev;
+       char opname[OP_MAX_TYPENAME];
+} CustomTool;
+
+static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
+{
+       wmOperatorType *ot= arg2;
+       
+       if(ot) {
+               CustomTool *ct= MEM_callocN(sizeof(CustomTool), "CustomTool");
+               
+               BLI_addtail(arg_listbase, ct);
+               BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
+       }
+               
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+       wmOperatorType *ot = WM_operatortype_first();
+       
+       for(; ot; ot= ot->next) {
+               
+               if(BLI_strcasestr(ot->name, str)) {
+                       if(ot->poll==NULL || ot->poll((bContext *)C)) {
+                               
+                               if(0==uiSearchItemAdd(items, ot->name, ot, 0))
+                                       break;
+                       }
+               }
+       }
+}
+
+
+/* ID Search browse menu, open */
+static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
+{
+       static char search[OP_MAX_TYPENAME];
+       wmEvent event;
+       wmWindow *win= CTX_wm_window(C);
+       uiBlock *block;
+       uiBut *but;
+       
+       /* clear initial search string, then all items show */
+       search[0]= 0;
+       
+       block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+       uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+       
+       /* fake button, it holds space for search items */
+       uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+       
+       but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+       uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb);
+       
+       uiBoundsBlock(block, 6);
+       uiBlockSetDirection(block, UI_DOWN);    
+       uiEndBlock(C, block);
+       
+       event= *(win->eventstate);      /* XXX huh huh? make api call */
+       event.type= EVT_BUT_OPEN;
+       event.val= KM_PRESS;
+       event.customdata= but;
+       event.customdatafree= FALSE;
+       wm_event_add(win, &event);
+       
+       return block;
+}
+
+
 static void view3d_panel_tools(const bContext *C, Panel *pa)
 {
+       static ListBase tools= {NULL, NULL};
        Object *obedit= CTX_data_edit_object(C);
 //     Object *obact = CTX_data_active_object(C);
        uiLayout *col;
@@ -157,24 +231,20 @@ static void view3d_panel_tools(const bContext *C, Panel *pa)
        if(obedit) {
                if(obedit->type==OB_MESH) {
                        
-                       // void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context)
-                       col= uiLayoutColumn(pa->layout, 1);
-                       uiItemFullO(col, NULL, 0, "MESH_OT_delete", NULL, WM_OP_INVOKE_REGION_WIN);
-                       
-                       col= uiLayoutColumn(pa->layout, 1);
-                       uiItemFullO(col, NULL, 0, "MESH_OT_subdivide", NULL, WM_OP_INVOKE_REGION_WIN);
-                       
-                       col= uiLayoutColumn(pa->layout, 1);
-                       uiItemFullO(col, NULL, 0, "MESH_OT_primitive_monkey_add", NULL, WM_OP_INVOKE_REGION_WIN);
-                       uiItemFullO(col, NULL, 0, "MESH_OT_primitive_uv_sphere_add", NULL, WM_OP_INVOKE_REGION_WIN);
-                       
-                       col= uiLayoutColumn(pa->layout, 1);
-                       uiItemFullO(col, NULL, 0, "MESH_OT_select_all_toggle", NULL, WM_OP_INVOKE_REGION_WIN);
-                       
                        col= uiLayoutColumn(pa->layout, 1);
                        uiItemFullO(col, NULL, 0, "MESH_OT_spin", NULL, WM_OP_INVOKE_REGION_WIN);
                        uiItemFullO(col, NULL, 0, "MESH_OT_screw", NULL, WM_OP_INVOKE_REGION_WIN);
                        
+                       if(tools.first) {
+                               CustomTool *ct;
+                               
+                               for(ct= tools.first; ct; ct= ct->next) {
+                                       col= uiLayoutColumn(pa->layout, 1);
+                                       uiItemFullO(col, NULL, 0, ct->opname, NULL, WM_OP_INVOKE_REGION_WIN);
+                               }
+                       }
+                       col= uiLayoutColumn(pa->layout, 1);
+                       uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &tools, "Add Operator", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add tool");
                }
        }
        else {
index 3bc950d5863909254357356faa6d93bd498a8842..d23f8fdfe40dac2471f6819bf30a5a0c3a4f1499 100644 (file)
@@ -4828,6 +4828,12 @@ void special_aftertrans_update(TransInfo *t)
                                /* pointcache refresh */
                                if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
                                        ob->recalc |= OB_RECALC_DATA;
+
+                               /* Needed for proper updating of "quick cached" dynamics. */
+                               /* Creates troubles for moving animated objects without */
+                               /* autokey though, probably needed is an anim sys override? */
+                               /* Please remove if some other solution is found. -jahka */
+                               DAG_object_flush_update(scene, ob, OB_RECALC_OB);
                                
                                /* Set autokey if necessary */
                                if (!cancelled)
index a8d402fc503e878f6ed5f785487b9b02d41dbb50..88d9894cf7a16208ec749733a8437157b55cd887 100644 (file)
@@ -82,7 +82,8 @@ typedef struct PTCacheMem {
 } PTCacheMem;
 
 typedef struct PointCache {
-       int flag, rt;           /* generic flag */
+       int flag;               /* generic flag */
+       int step;               /* frames between cached frames */
        int simframe;   /* current frame of simulation (only if SIMULATION_VALID) */
        int startframe; /* simulation start frame */
        int endframe;   /* simulation end frame */
@@ -263,7 +264,11 @@ typedef struct SoftBody {
 #define PTCACHE_BAKE_EDIT                      16
 #define PTCACHE_BAKE_EDIT_ACTIVE       32
 #define PTCACHE_DISK_CACHE                     64
-#define PTCACHE_AUTOCACHE                      128
+#define PTCACHE_QUICK_CACHE                    128
+#define PTCACHE_FRAMES_SKIPPED         256
+
+/* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */
+#define PTCACHE_REDO_NEEDED                    258
 
 /* ob->softflag */
 #define OB_SB_ENABLE   1
index 361c1b61303fb5fd7558357a582c016704f4f832..cefd2316fbfa3b87af3e7470a96b5fcc1158fa5d 100644 (file)
 #include "BKE_modifier.h"
 
 #include "DNA_cloth_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "WM_types.h"
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+
+static void rna_cloth_update(bContext *C, PointerRNA *ptr)
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = ptr->id.data;
+
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+}
+
 static void rna_ClothSettings_max_bend_set(struct PointerRNA *ptr, float value)
 {
        ClothSimSettings *settings = (ClothSimSettings*)ptr->data;
@@ -165,42 +180,50 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "mingoal");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "maxgoal");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "defgoal");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "goalspring");
        RNA_def_property_range(prop, 0.0f, 0.999f);
        RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "goalfrict");
        RNA_def_property_range(prop, 0.0f, 50.0f);
        RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        /* mass */
 
        prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 10.0f);
        RNA_def_property_ui_text(prop, "Mass", "Mass of cloth material.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "mass_vertex_group", PROP_STRING, PROP_NONE);
        RNA_def_property_string_funcs(prop, "rna_ClothSettings_mass_vgroup_get", "rna_ClothSettings_mass_vgroup_length", "rna_ClothSettings_mass_vgroup_set");
        RNA_def_property_ui_text(prop, "Mass Vertex Group", "Vertex group for fine control over mass distribution.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_VECTOR);
        RNA_def_property_array(prop, 3);
        RNA_def_property_range(prop, -100.0, 100.0);
        RNA_def_property_float_funcs(prop, "rna_ClothSettings_gravity_get", "rna_ClothSettings_gravity_set", NULL);
        RNA_def_property_ui_text(prop, "Gravity", "Gravity or external force vector.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        /* various */
 
@@ -208,61 +231,73 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "Cvi");
        RNA_def_property_range(prop, 0.0f, 10.0f);
        RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "pin_cloth", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL);
        RNA_def_property_ui_text(prop, "Pin Cloth", "Define forces for vertices to stick to animated position.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "pin_stiffness", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "goalspring");
        RNA_def_property_range(prop, 0.0f, 50.0);
        RNA_def_property_ui_text(prop, "Pin Stiffness", "Pin (vertex target position) spring stiffness.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "quality", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "stepsPerFrame");
        RNA_def_property_range(prop, 4, 80);
        RNA_def_property_ui_text(prop, "Quality", "Quality of the simulation in steps per frame (higher is better quality but slower).");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        /* springs */
 
        prop= RNA_def_property(srna, "stiffness_scaling", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_SCALING);
        RNA_def_property_ui_text(prop, "Stiffness Scaling", "If enabled, stiffness can be scaled along a weight painted vertex group.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "spring_damping", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "Cdis");
        RNA_def_property_range(prop, 0.0f, 50.0f);
        RNA_def_property_ui_text(prop, "Spring Damping", "Damping of cloth velocity (higher = more smooth, less jiggling)");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "structural_stiffness", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "structural");
        RNA_def_property_range(prop, 1.0f, 10000.0f);
        RNA_def_property_ui_text(prop, "Structural Stiffness", "Overall stiffness of structure.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "structural_stiffness_max", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "max_struct");
        RNA_def_property_range(prop, 0.0f, 10000.0f);
        RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_struct_set", NULL);
        RNA_def_property_ui_text(prop, "Structural Stiffness Maximum", "Maximum structural stiffness value.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "structural_stiffness_vertex_group", PROP_STRING, PROP_NONE);
        RNA_def_property_string_funcs(prop, "rna_ClothSettings_struct_vgroup_get", "rna_ClothSettings_struct_vgroup_length", "rna_ClothSettings_struct_vgroup_set");
        RNA_def_property_ui_text(prop, "Structural Stiffness Vertex Group", "Vertex group for fine control over structural stiffness.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "bending_stiffness", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "bending");
        RNA_def_property_range(prop, 0.0f, 10000.0f);
        RNA_def_property_ui_text(prop, "Bending Stiffness", "Wrinkle coefficient (higher = less smaller but more big wrinkles).");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "bending_stiffness_max", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "max_bend");
        RNA_def_property_range(prop, 0.0f, 10000.0f);
        RNA_def_property_float_funcs(prop, NULL, "rna_ClothSettings_max_bend_set", NULL);
        RNA_def_property_ui_text(prop, "Bending Stiffness Maximum", "Maximum bending stiffness value.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "bending_vertex_group", PROP_STRING, PROP_NONE);
        RNA_def_property_string_funcs(prop, "rna_ClothSettings_bend_vgroup_get", "rna_ClothSettings_bend_vgroup_length", "rna_ClothSettings_bend_vgroup_set");
        RNA_def_property_ui_text(prop, "Bending Stiffness Vertex Group", "Vertex group for fine control over bending stiffness.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        /* unused */
 
@@ -323,40 +358,48 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
        prop= RNA_def_property(srna, "enable_collision", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_ENABLED);
        RNA_def_property_ui_text(prop, "Enable Collision", "Enable collisions with other objects.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "min_distance", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "epsilon");
        RNA_def_property_range(prop, 0.001f, 1.0f);
        RNA_def_property_ui_text(prop, "Minimum Distance", "Minimum distance between collision objects before collision response takes in, can be changed for each frame.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 80.0f);
        RNA_def_property_ui_text(prop, "Friction", "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "collision_quality", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "loop_count");
        RNA_def_property_range(prop, 1, 20);
        RNA_def_property_ui_text(prop, "Collision Quality", "How many collision iterations should be done. (higher is better quality but slower)");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        /* self collision */
 
        prop= RNA_def_property(srna, "enable_self_collision", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_COLLSETTINGS_FLAG_SELF);
        RNA_def_property_ui_text(prop, "Enable Self Collision", "Enable self collisions.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "self_min_distance", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "selfepsilon");
        RNA_def_property_range(prop, 0.5f, 1.0f);
        RNA_def_property_ui_text(prop, "Self Minimum Distance", "0.5 means no distance at all, 1.0 is maximum distance");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
        
        prop= RNA_def_property(srna, "self_friction", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, 0.0f, 80.0f);
        RNA_def_property_ui_text(prop, "Self Friction", "Friction/damping with self contact.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 
        prop= RNA_def_property(srna, "self_collision_quality", PROP_INT, PROP_NONE);
        RNA_def_property_int_sdna(prop, NULL, "self_loop_count");
        RNA_def_property_range(prop, 1, 10);
        RNA_def_property_ui_text(prop, "Self Collision Quality", "How many self collision iterations should be done. (higher is better quality but slower), can be changed for each frame.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_GEOM_DATA, "rna_cloth_update");
 }
 
 void RNA_def_cloth(BlenderRNA *brna)
index fd79ac36c57f770ef2ffd78d382690cc8c4785a4..3b54409ffb0f62aeb0700d3bbe6a716321fe3189 100644 (file)
@@ -33,6 +33,7 @@
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
+#include "DNA_object_force.h"
 #include "DNA_object_types.h"
 #include "DNA_property_types.h"
 #include "DNA_scene_types.h"
@@ -240,6 +241,25 @@ static PointerRNA rna_Object_active_material_get(PointerRNA *ptr)
        return rna_pointer_inherit_refine(ptr, &RNA_MaterialSlot, ob->mat+ob->actcol);
 }
 
+static void rna_Object_active_particle_system_index_range(PointerRNA *ptr, int *min, int *max)
+{
+       Object *ob= (Object*)ptr->id.data;
+       *min= 1;
+       *max= BLI_countlist(&ob->particlesystem);
+}
+
+static int rna_Object_active_particle_system_index_get(PointerRNA *ptr)
+{
+       Object *ob= (Object*)ptr->id.data;
+       return psys_get_current_num(ob) + 1;
+}
+
+static void rna_Object_active_particle_system_index_set(struct PointerRNA *ptr, int value)
+{
+       Object *ob= (Object*)ptr->id.data;
+       psys_set_current_num(ob, value);
+}
+
 #if 0
 static void rna_Object_active_material_set(PointerRNA *ptr, PointerRNA value)
 {
@@ -928,6 +948,10 @@ static void rna_def_object(BlenderRNA *brna)
        RNA_def_property_pointer_funcs(prop, "rna_Object_active_particle_system_get", NULL, NULL);
        RNA_def_property_ui_text(prop, "Active Particle System", "Active particle system being displayed");
 
+       prop= RNA_def_property(srna, "active_particle_system_index", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_int_funcs(prop, "rna_Object_active_particle_system_index_get", "rna_Object_active_particle_system_index_set", "rna_Object_active_particle_system_index_range");
+       RNA_def_property_ui_text(prop, "Active Particle System Index", "Index of active particle system slot.");
+
        /* restrict */
 
        prop= RNA_def_property(srna, "restrict_view", PROP_BOOLEAN, PROP_NONE);
index bc3f0733a0ddc341b24df07479726eabb80eb1d6..4d8c728db1218099aa6dc6a821320463c6f6d16d 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
+#include "DNA_scene_types.h"
 
 #include "WM_types.h"
 
 
 #include "BKE_context.h"
 #include "BKE_pointcache.h"
+#include "BKE_depsgraph.h"
 
 #include "BLI_blenlib.h"
 
+static void rna_Cache_change(bContext *C, PointerRNA *ptr)
+{
+       Scene *scene = CTX_data_scene(C);
+       Object *ob = CTX_data_active_object(C);
+       PointCache *cache = (PointCache*)ptr->data;
+       PTCacheID *pid = NULL;
+       ListBase pidlist;
+
+       if(!ob)
+               return;
+
+       cache->flag |= PTCACHE_OUTDATED;
+
+       BKE_ptcache_ids_from_object(&pidlist, ob);
+
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+       for(pid=pidlist.first; pid; pid=pid->next) {
+               if(pid->cache==cache)
+                       break;
+       }
+
+       if(pid)
+               BKE_ptcache_update_info(pid);
+
+       BLI_freelistN(&pidlist);
+}
+
 static void rna_Cache_toggle_disk_cache(bContext *C, PointerRNA *ptr)
 {
        Object *ob = CTX_data_active_object(C);
@@ -113,6 +143,113 @@ static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr)
 
        BLI_freelistN(&pidlist);
 }
+
+static int rna_SoftBodySettings_use_edges_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_EDGES) != 0);
+}
+
+static void rna_SoftBodySettings_use_edges_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_EDGES;
+       else data->softflag &= ~OB_SB_EDGES;
+}
+
+static int rna_SoftBodySettings_use_goal_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_GOAL) != 0);
+}
+
+static void rna_SoftBodySettings_use_goal_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_GOAL;
+       else data->softflag &= ~OB_SB_GOAL;
+}
+
+static int rna_SoftBodySettings_stiff_quads_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_QUADS) != 0);
+}
+
+static void rna_SoftBodySettings_stiff_quads_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_QUADS;
+       else data->softflag &= ~OB_SB_QUADS;
+}
+
+static int rna_SoftBodySettings_self_collision_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_SELF) != 0);
+}
+
+static void rna_SoftBodySettings_self_collision_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_SELF;
+       else data->softflag &= ~OB_SB_SELF;
+}
+
+static int rna_SoftBodySettings_new_aero_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_AERO_ANGLE) != 0);
+}
+
+static void rna_SoftBodySettings_new_aero_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_AERO_ANGLE;
+       else data->softflag &= ~OB_SB_AERO_ANGLE;
+}
+
+static int rna_SoftBodySettings_enabled_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_ENABLE) != 0);
+}
+
+#if 0
+static void rna_SoftBodySettings_enabled_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_ENABLE;
+       else data->softflag &= ~OB_SB_ENABLE;
+}
+#endif
+
+static int rna_SoftBodySettings_face_collision_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_FACECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_face_collision_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_FACECOLL;
+       else data->softflag &= ~OB_SB_FACECOLL;
+}
+
+static int rna_SoftBodySettings_edge_collision_get(PointerRNA *ptr)
+{
+       Object *data= (Object*)(ptr->data);
+       return (((data->softflag) & OB_SB_EDGECOLL) != 0);
+}
+
+static void rna_SoftBodySettings_edge_collision_set(PointerRNA *ptr, int value)
+{
+       Object *data= (Object*)(ptr->data);
+       if(value) data->softflag |= OB_SB_EDGECOLL;
+       else data->softflag &= ~OB_SB_EDGECOLL;
+}
+
 #else
 
 static void rna_def_pointcache(BlenderRNA *brna)
@@ -133,6 +270,12 @@ static void rna_def_pointcache(BlenderRNA *brna)
        RNA_def_property_range(prop, 1, 300000);
        RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops.");
 
+       prop= RNA_def_property(srna, "step", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "step");
+       RNA_def_property_range(prop, 1, 20);
+       RNA_def_property_ui_text(prop, "Cache Step", "Number of frames between cached frames.");
+       RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
+
        /* flags */
        prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED);
@@ -150,21 +293,24 @@ static void rna_def_pointcache(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Cache is outdated", "");
 
+       prop= RNA_def_property(srna, "frames_skipped", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_FRAMES_SKIPPED);
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
        prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "name");
        RNA_def_property_ui_text(prop, "Name", "Cache name");
        RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change");
 
-       prop= RNA_def_property(srna, "autocache", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_AUTOCACHE);
-       RNA_def_property_ui_text(prop, "Auto Cache", "Cache changes automatically");
-       //RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_toggle_autocache");
+       prop= RNA_def_property(srna, "quick_cache", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_QUICK_CACHE);
+       RNA_def_property_ui_text(prop, "Quick Cache", "Update simulation with cache steps");
+       RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change");
 
        prop= RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
        RNA_def_property_string_sdna(prop, NULL, "info");
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Cache Info", "Info on current cache status.");
-
 }
 
 static void rna_def_collision(BlenderRNA *brna)
@@ -268,6 +414,7 @@ static void rna_def_field(BlenderRNA *brna)
        srna= RNA_def_struct(brna, "FieldSettings", NULL);
        RNA_def_struct_sdna(srna, "PartDeflect");
        RNA_def_struct_ui_text(srna, "Field Settings", "Field settings for an object in physics simulation.");
+       RNA_def_struct_ui_icon(srna, ICON_PHYSICS);
        
        /* Enums */
        
@@ -410,10 +557,206 @@ static void rna_def_game_softbody(BlenderRNA *brna)
 static void rna_def_softbody(BlenderRNA *brna)
 {
        StructRNA *srna;
+       PropertyRNA *prop;
+       
+       static EnumPropertyItem collision_type_items[] = {
+               {SBC_MODE_MANUAL, "MANUAL", 0, "Manual", "Manual adjust"},
+               {SBC_MODE_AVG, "AVERAGE", 0, "Average", "Average Spring lenght * Ball Size"},
+               {SBC_MODE_MIN, "MINIMAL", 0, "Minimal", "Minimal Spring lenght * Ball Size"},
+               {SBC_MODE_MAX, "MAXIMAL", 0, "Maximal", "Maximal Spring lenght * Ball Size"},
+               {SBC_MODE_AVGMINMAX, "MINMAX", 0, "AvMinMax", "(Min+Max)/2 * Ball Size"},
+               {0, NULL, 0, NULL, NULL}};
 
        srna= RNA_def_struct(brna, "SoftBodySettings", NULL);
        RNA_def_struct_sdna(srna, "SoftBody");
        RNA_def_struct_ui_text(srna, "Soft Body Settings", "Soft body simulation settings for an object.");
+       
+       /* General Settings */
+       
+       prop= RNA_def_property(srna, "friction", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "mediafrict");
+       RNA_def_property_range(prop, 0.0f, 50.0f);
+       RNA_def_property_ui_text(prop, "Friction", "General media friction for point movements");
+       
+       prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "nodemass");
+       RNA_def_property_range(prop, 0.0f, 50000.0f);
+       RNA_def_property_ui_text(prop, "Mass", "");
+       
+       prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "grav");
+       RNA_def_property_range(prop, -10.0f, 10.0f);
+       RNA_def_property_ui_text(prop, "Gravitation", "Apply gravitation to point movement");
+       
+       prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "physics_speed");
+       RNA_def_property_range(prop, 0.01f, 100.0f);
+       RNA_def_property_ui_text(prop, "Speed", "Tweak timing for physics to control frequency and speed");
+       
+       /* Goal */
+       
+       /*prop= RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "vertgroup");
+       RNA_def_property_ui_text(prop, "Vertex Group", "Use control point weight values");*/
+       
+       prop= RNA_def_property(srna, "goal_min", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "mingoal");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Goal Minimum", "Goal minimum, vertex group weights are scaled to match this range.");
+
+       prop= RNA_def_property(srna, "goal_max", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "maxgoal");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Goal Maximum", "Goal maximum, vertex group weights are scaled to match this range.");
+
+       prop= RNA_def_property(srna, "goal_default", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "defgoal");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Goal Default", "Default Goal (vertex target position) value, when no Vertex Group used.");
+       
+       prop= RNA_def_property(srna, "goal_spring", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "goalspring");
+       RNA_def_property_range(prop, 0.0f, 0.999f);
+       RNA_def_property_ui_text(prop, "Goal Stiffness", "Goal (vertex target position) spring stiffness.");
+       
+       prop= RNA_def_property(srna, "goal_friction", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "goalfrict");
+       RNA_def_property_range(prop, 0.0f, 50.0f);
+       RNA_def_property_ui_text(prop, "Goal Damping", "Goal (vertex target position) friction.");
+       
+       /* Edge Spring Settings */
+       
+       prop= RNA_def_property(srna, "pull", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "inspring");
+       RNA_def_property_range(prop, 0.0f, 0.999f);
+       RNA_def_property_ui_text(prop, "Pull", "Edge spring stiffness when longer than rest length");
+       
+       prop= RNA_def_property(srna, "push", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "inpush");
+       RNA_def_property_range(prop, 0.0f, 0.999f);
+       RNA_def_property_ui_text(prop, "Push", "Edge spring stiffness when shorter than rest length");
+       
+       prop= RNA_def_property(srna, "damp", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "infrict");
+       RNA_def_property_range(prop, 0.0f, 50.0f);
+       RNA_def_property_ui_text(prop, "Damp", "Edge spring friction");
+       
+       prop= RNA_def_property(srna, "spring_lenght", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "springpreload");
+       RNA_def_property_range(prop, 0.0f, 200.0f);
+       RNA_def_property_ui_text(prop, "SL", "Alter spring lenght to shrink/blow up (unit %) 0 to disable");
+       
+       prop= RNA_def_property(srna, "aero", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "aeroedge");
+       RNA_def_property_range(prop, 0.0f, 30000.0f);
+       RNA_def_property_ui_text(prop, "Aero", "Make edges 'sail'");
+       
+       prop= RNA_def_property(srna, "plastic", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "plastic");
+       RNA_def_property_range(prop, 0.0f, 100.0f);
+       RNA_def_property_ui_text(prop, "Plastic", "Permanent deform");
+       
+       prop= RNA_def_property(srna, "bending", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "secondspring");
+       RNA_def_property_range(prop, 0.0f, 10.0f);
+       RNA_def_property_ui_text(prop, "Bending", "Bending Stiffness");
+       
+       prop= RNA_def_property(srna, "shear", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "shearstiff");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Shear", "Shear Stiffness");
+       
+       /* Collision */
+       
+       prop= RNA_def_property(srna, "collision_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "sbc_mode");
+       RNA_def_property_enum_items(prop, collision_type_items);
+       RNA_def_property_ui_text(prop, "Collision Type", "Choose Collision Type");
+       
+       prop= RNA_def_property(srna, "ball_size", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "colball");
+       RNA_def_property_range(prop, -10.0f, 10.0f);
+       RNA_def_property_ui_text(prop, "Ball Size", "Absolute ball size or factor if not manual adjusted");
+       
+       prop= RNA_def_property(srna, "ball_stiff", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "ballstiff");
+       RNA_def_property_range(prop, 0.001f, 100.0f);
+       RNA_def_property_ui_text(prop, "Ball Size", "Ball inflating presure");
+       
+       prop= RNA_def_property(srna, "ball_damp", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "balldamp");
+       RNA_def_property_range(prop, 0.001f, 1.0f);
+       RNA_def_property_ui_text(prop, "Ball Size", "Blending to inelastic collision");
+       
+       /* Solver */
+       
+       prop= RNA_def_property(srna, "error_limit", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "rklimit");
+       RNA_def_property_range(prop, 0.001f, 10.0f);
+       RNA_def_property_ui_text(prop, "Error Limit", "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
+       
+       prop= RNA_def_property(srna, "minstep", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "minloops");
+       RNA_def_property_range(prop, 0, 30000);
+       RNA_def_property_ui_text(prop, "Min Step", "Minimal # solver steps/frame");
+       
+       prop= RNA_def_property(srna, "maxstep", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "maxloops");
+       RNA_def_property_range(prop, 0, 30000);
+       RNA_def_property_ui_text(prop, "Max Step", "Maximal # solver steps/frame");
+       
+       prop= RNA_def_property(srna, "choke", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "choke");
+       RNA_def_property_range(prop, 0, 100);
+       RNA_def_property_ui_text(prop, "Choke", "'Viscosity' inside collision target");
+       
+       prop= RNA_def_property(srna, "fuzzy", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "fuzzyness");
+       RNA_def_property_range(prop, 1, 100);
+       RNA_def_property_ui_text(prop, "Fuzzy", "Fuzzyness while on collision, high values make collsion handling faster but less stable");
+       
+       prop= RNA_def_property(srna, "auto_step", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_OLDERR);
+       RNA_def_property_ui_text(prop, "V", "Use velocities for automagic step sizes");
+       
+       prop= RNA_def_property(srna, "diagnose", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_MONITOR);
+       RNA_def_property_ui_text(prop, "Print Performance to Console", "Turn on SB diagnose console prints");
+       
+       /* Flags */
+       
+       prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_enabled_get", "rna_SoftBodySettings_enabled_set");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Enable", "Sets object to become soft body.");
+       
+       prop= RNA_def_property(srna, "use_goal", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_goal_get", "rna_SoftBodySettings_use_goal_set");
+       RNA_def_property_ui_text(prop, "Use Goal", "Define forces for vertices to stick to animated position.");
+       
+       prop= RNA_def_property(srna, "use_edges", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_use_edges_get", "rna_SoftBodySettings_use_edges_set");
+       RNA_def_property_ui_text(prop, "Use Edges", "Use Edges as springs");
+       
+       prop= RNA_def_property(srna, "stiff_quads", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_stiff_quads_get", "rna_SoftBodySettings_stiff_quads_set");
+       RNA_def_property_ui_text(prop, "Stiff Quads", "Adds diagonal springs on 4-gons.");
+       
+       prop= RNA_def_property(srna, "edge_collision", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_edge_collision_get", "rna_SoftBodySettings_edge_collision_set");
+       RNA_def_property_ui_text(prop, "Edge Collision", "Edges collide too.");
+       
+       prop= RNA_def_property(srna, "face_collision", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_face_collision_get", "rna_SoftBodySettings_face_collision_set");
+       RNA_def_property_ui_text(prop, "Face Collision", "Faces collide too, SLOOOOOW warning.");
+       
+       prop= RNA_def_property(srna, "new_aero", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_new_aero_get", "rna_SoftBodySettings_new_aero_set");
+       RNA_def_property_ui_text(prop, "N", "New aero(uses angle and length).");
+       
+       prop= RNA_def_property(srna, "self_collision", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_funcs(prop, "rna_SoftBodySettings_self_collision_get", "rna_SoftBodySettings_self_collision_set");
+       RNA_def_property_ui_text(prop, "Self Collision", "Enable naive vertex ball self collision.");
 }
 
 void RNA_def_object_force(BlenderRNA *brna)
index ae53c815ed9c84a6758f4439528953ff7c4dc618..d60a215b4985126b41f442b52240aecc37b25655 100644 (file)
@@ -81,13 +81,11 @@ static void rna_Particle_reset(bContext *C, PointerRNA *ptr)
 
                if(ob) {
                        DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-                       //WM_event_add_notifier(C, NC_SCENE|ND_CACHE_PHYSICS, scene);
                }
        }
        else {
                part = ptr->id.data;
                psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET);
-               //WM_event_add_notifier(C, NC_SCENE|ND_CACHE_PHYSICS, scene);
        }
 }
 
@@ -104,13 +102,11 @@ static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
 
                if(ob) {
                        DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-                       //WM_event_add_notifier(C, NC_SCENE|ND_CACHE_PHYSICS, scene);
                }
        }
        else {
                part = ptr->id.data;
                psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_TYPE);
-               //WM_event_add_notifier(C, NC_SCENE|ND_CACHE_PHYSICS, scene);
        }
 }
 
@@ -134,6 +130,27 @@ static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
                psys_flush_particle_settings(scene, part, PSYS_RECALC_CHILD);
        }
 }
+static PointerRNA rna_particle_settings_get(PointerRNA *ptr)
+{
+       Object *ob= (Object*)ptr->id.data;
+       ParticleSettings *part = psys_get_current(ob)->part;
+
+       return rna_pointer_inherit_refine(ptr, &RNA_ParticleSettings, part);
+}
+
+static void rna_particle_settings_set(PointerRNA *ptr, PointerRNA value)
+{
+       Object *ob= (Object*)ptr->id.data;
+       ParticleSystem *psys = psys_get_current(ob);
+
+       if(psys->part)
+               psys->part->id.us--;
+
+       psys->part = (ParticleSettings *)value.data;
+
+       if(psys->part)
+               psys->part->id.us++;
+}
 static void rna_PartSettings_start_set(struct PointerRNA *ptr, float value)
 {
        ParticleSettings *settings = (ParticleSettings*)ptr->data;
@@ -1493,9 +1510,15 @@ static void rna_def_particle_system(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_EDITABLE);
        RNA_def_struct_name_property(srna, prop);
 
+       /* access to particle settings is redirected through functions */
+       /* to allow proper id-buttons functionality */
        prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NEVER_NULL);
-       RNA_def_property_pointer_sdna(prop, NULL, "part");
+       //RNA_def_property_pointer_sdna(prop, NULL, "part");
+       RNA_def_property_struct_type(prop, "ParticleSettings");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_pointer_funcs(prop, "rna_particle_settings_get", "rna_particle_settings_set", NULL);
        RNA_def_property_ui_text(prop, "Settings", "Particle system settings.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "particles", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "particles", "totpart");
index 5eec13ed7fe343aa85acdd8fa3cfcdb44924e9ac..ccc793e4235322cd4dcf75da9eb3738033c47f69 100644 (file)
@@ -2421,6 +2421,7 @@ static void update_physics_cache(Render *re, Scene *scene)
        baker.pid = NULL;
        baker.bake = 0;
        baker.render = 1;
+       baker.quick_step = 1;
        baker.break_test = re->test_break;
        baker.break_data = re->tbh;
        baker.progressbar = NULL;
index ea6a65859e5f9597afd3e79b67c4c18f460039da..286d1216f66269a25a9584c272019a3a63d3e98b 100644 (file)
@@ -49,6 +49,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_utildefines.h"
+#include "BKE_pointcache.h"
 
 #include "ED_fileselect.h"
 #include "ED_screen.h"
@@ -234,6 +235,8 @@ void wm_event_do_notifiers(bContext *C)
                        for(base= scene->base.first; base; base= base->next) {
                                object_handle_update(scene, base->object);
                        }
+
+                       BKE_ptcache_quick_cache_all(scene);
                }               
        }
        CTX_wm_window_set(C, NULL);
index d13d8ec6ccc66a8eb7e91424cb85e34b0cb6c727..861080f30ba82a0aaaf1690ec2459d9a7a729407 100644 (file)
@@ -294,8 +294,6 @@ int WM_read_homefile(bContext *C, wmOperator *op)
        G.relbase_valid = 0;
        if (!from_memory) {
                BLI_make_file_string(G.sce, tstr, home, ".B25.blend");
-               if(!BLI_exists(tstr))
-                       BLI_make_file_string(G.sce, tstr, home, ".B.blend");
        }
        strcpy(scestr, G.sce);  /* temporary store */
        
index 44678cb73eb57efc94a88168a7ef650bb99ed4f6..fb222b419c30c05959ae6e2268d63d419960ca7d 100644 (file)
 
 #include "SYS_System.h"
 
+#include "GPU_extensions.h"
+#include "Value.h"
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
        /***/
 #include "DNA_view3d_types.h"
 #include "DNA_screen_types.h"
 //XXX #include "BIF_scrarea.h"
 
 #include "BKE_main.h"
-//#include "BKE_context.h"
 #include "BLI_blenlib.h"
 #include "BLO_readfile.h"
 #include "DNA_scene_types.h"
        /***/
 
-#include "GPU_extensions.h"
-#include "Value.h"
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
 //XXX #include "BSE_headerbuttons.h"
+#include "BKE_context.h"
 #include "../../blender/windowmanager/WM_types.h"
 #include "../../blender/windowmanager/wm_window.h"
 #include "../../blender/windowmanager/wm_event_system.h"
@@ -118,19 +118,10 @@ static BlendFileData *load_game_data(char *filename)
        return bfd;
 }
 
-
-/* screw it, BKE_context.h is complaining! */
-extern "C" struct wmWindow *CTX_wm_window(const bContext *C);
-extern "C" struct ScrArea *CTX_wm_area(const bContext *C);
-extern "C" struct ARegion *CTX_wm_region(const bContext *C);
-extern "C" struct Scene *CTX_data_scene(const bContext *C);
-extern "C" struct Main *CTX_data_main(const bContext *C);
-
 extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_framing)
 {
        /* context values */
        struct wmWindow *win= CTX_wm_window(C);
-       struct ScrArea *area= CTX_wm_area(C); // curarea
        struct ARegion *ar= CTX_wm_region(C);
        struct Scene *scene= CTX_data_scene(C);
        struct Main* maggie1= CTX_data_main(C);
@@ -159,8 +150,8 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami
 
        do
        {
-               View3D *v3d= (View3D*) area->spacedata.first;
-               RegionView3D *rv3d= (RegionView3D*) ar->regiondata;
+               View3D *v3d= CTX_wm_view3d(C);
+               RegionView3D *rv3d= CTX_wm_region_view3d(C);
 
                // get some preferences
                SYS_SystemHandle syshandle = SYS_GetSystem();
@@ -239,13 +230,12 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami
                        scene->camera= v3d->camera;
                }
 
-       
                // some blender stuff
                MT_CmMatrix4x4 projmat;
                MT_CmMatrix4x4 viewmat;
                float camzoom;
                int i;
-               
+
                for (i = 0; i < 16; i++)
                {
                        float *viewmat_linear= (float*) rv3d->viewmat;
@@ -257,7 +247,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami
                        projmat.setElem(i, projmat_linear[i]);
                }
                
-               if(v3d->persp==V3D_CAMOB) {
+               if(rv3d->persp==V3D_CAMOB) {
                        camzoom = (1.41421 + (rv3d->camzoom / 50.0));
                        camzoom *= camzoom;
                }
@@ -348,10 +338,10 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami
                
                if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
                {
-                       if (v3d->persp != V3D_CAMOB)
+                       if (rv3d->persp != V3D_CAMOB)
                        {
                                ketsjiengine->EnableCameraOverride(startscenename);
-                               ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == V3D_ORTHO));
+                               ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == V3D_ORTHO));
                                ketsjiengine->SetCameraOverrideProjectionMatrix(projmat);
                                ketsjiengine->SetCameraOverrideViewMatrix(viewmat);
                                ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
@@ -587,7 +577,6 @@ extern "C" void StartKetsjiShell(struct bContext *C, int always_use_expand_frami
 }
 
 extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
-                                                                struct ScrArea *area,
                                                                 struct ARegion *ar,
                                                                 char* scenename,
                                                                 struct Main* maggie,
index 3b690a215844122cebe84a6b179e2e7a2d0f9451..2874a0273cceb8f1d6b394933458bcadc89bfd69 100644 (file)
@@ -19,7 +19,8 @@ SET(INC
   ../../../source/blender/windowmanager
   ../../../source/blender 
   ../../../source/blender/include
-  ../../../source/blender/makesdna 
+  ../../../source/blender/makesdna
+  ../../../source/blender/makesrna 
   ../../../source/gameengine/Rasterizer 
   ../../../source/gameengine/GameLogic
   ../../../source/gameengine/Expressions 
index aa83d17a03a36e2d37bd4f97debef92db6fc438d..360794ceb33add7b05e661e5964eeb55b66bee04 100644 (file)
 
 #include "KX_BlenderCanvas.h"
 #include "DNA_screen_types.h"
+#include "stdio.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+
 KX_BlenderCanvas::KX_BlenderCanvas(struct wmWindow *win, ARegion *ar) :
 m_win(win),
 m_ar(ar)
index c2094a158258fd4e50f8e547fe9ce4acfdd33739..fc12f453d8682e7702743dcf8b9c9031cc773dcd 100644 (file)
@@ -11,7 +11,8 @@ incs += ' #intern/ghost/include'
 incs += ' #intern/moto/include #source/gameengine/Ketsji #source/blender/blenlib'
 incs += ' #source/blender/blenkernel #source/blender'
 incs += ' #source/blender/blenfont #source/blender/editors/include'
-incs += ' #source/blender/makesdna #source/gameengine/Rasterizer #source/gameengine/GameLogic'
+incs += ' #source/blender/makesdna #source/blender/makesrna'
+incs += ' #source/gameengine/Rasterizer #source/gameengine/GameLogic'
 incs += ' #source/gameengine/Expressions #source/gameengine/Network'
 incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common'
 incs += ' #source/gameengine/Physics/Bullet'
index 1a417110c08f7307c918e010bb2a8c806133d493..cc0f50d9e7afb767fdc00e145b0bd0631b776dcf 100644 (file)
@@ -396,9 +396,9 @@ void KX_KetsjiEngine::StartEngine(bool clearIpo)
        World* world = m_scenes[0]->GetBlenderScene()->world;
        if (world)
        {
-               m_ticrate = world->ticrate;
-               m_maxLogicFrame = world->maxlogicstep;
-               m_maxPhysicsFrame = world->maxphystep;
+               m_ticrate = world->ticrate ? world->ticrate : DEFAULT_LOGIC_TIC_RATE;
+               m_maxLogicFrame = world->maxlogicstep ? world->maxlogicstep : 5;
+               m_maxPhysicsFrame = world->maxphystep ? world->maxlogicstep : 5;
        }
        else
        {