diff options
44 files changed, 1540 insertions, 1061 deletions
diff --git a/CMake/macros.cmake b/CMake/macros.cmake index bc8892e4b99..44fc2903875 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c7ee34cc14..99f1c10027b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/release/ui/buttons_object_constraint.py b/release/ui/buttons_object_constraint.py index 3048bdaa399..f2b0b986ab9 100644 --- a/release/ui/buttons_object_constraint.py +++ b/release/ui/buttons_object_constraint.py @@ -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) diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index f82324db9d8..e51df6ef7fd 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -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 diff --git a/release/ui/buttons_physic_cloth.py b/release/ui/buttons_physic_cloth.py index bd65392ad63..a06c644322a 100644 --- a/release/ui/buttons_physic_cloth.py +++ b/release/ui/buttons_physic_cloth.py @@ -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) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index e09be838f06..4270c677338 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -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 ); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 0ecd71fc4a3..4d9916b9557 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -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); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index b79357edf36..3f1c45d28ec 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -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); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e98d7bb01a4..08caea565aa 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -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; } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index b57b8b7a6da..a36b825293e 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -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 && diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 40c98c1d9cc..fc5213d5532 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -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 { diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 1a6f57e75c4..80a9f173d6a 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -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++) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5b3720cd6b0..2474053298d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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){ diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 97b1956bba9..591b6ca9be5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -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; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index b514ac026fb..64473d07151 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -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); } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b9cbb863022..6df907fe132 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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); } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e6ca289e610..80d1d78257b 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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; diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 3a61237e1cb..a9866d8898e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -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); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 06dc5d1e606..eaf78ae89ef 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -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) diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 735cfe742c6..ddf31c0db66 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -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}, diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index aa1cc5790ef..c32c8c817fb 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -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 */ diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 8483aee52f4..12138ee13d2 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -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; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 8102b1bfb9c..c436ccdb328 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -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"; diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c index 3374e05883c..893c59a521d 100644 --- a/source/blender/editors/physics/ed_pointcache.c +++ b/source/blender/editors/physics/ed_pointcache.c @@ -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) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index f40880b901f..8f0b52ef3a1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -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 diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c index 79284ada483..7c622f172a2 100644 --- a/source/blender/editors/space_buttons/buttons_header.c +++ b/source/blender/editors/space_buttons/buttons_header.c @@ -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)) diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index b213e4288be..13ea778fb00 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -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 */ diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 6755a2be1b7..6ca92674c6e 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -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; +} diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 483a1dc6100..7954d5254cc 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -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) diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 88af60ac0f4..34a935103a7 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -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 { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3bc950d5863..d23f8fdfe40 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -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) diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index a8d402fc503..88d9894cf7a 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -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 diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c index 361c1b61303..cefd2316fbf 100644 --- a/source/blender/makesrna/intern/rna_cloth.c +++ b/source/blender/makesrna/intern/rna_cloth.c @@ -34,9 +34,24 @@ #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) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index fd79ac36c57..3b54409ffb0 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -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); diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index bc3f0733a0d..4d8c728db12 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -31,6 +31,7 @@ #include "DNA_object_types.h" #include "DNA_object_force.h" +#include "DNA_scene_types.h" #include "WM_types.h" @@ -40,9 +41,38 @@ #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) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index ae53c815ed9..d60a215b498 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -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"); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 5eec13ed7fe..ccc793e4235 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -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; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index ea6a65859e5..286d1216f66 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -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); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index d13d8ec6ccc..861080f30ba 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -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 */ diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 44678cb73eb..fb222b419c3 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -65,6 +65,14 @@ #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" @@ -77,21 +85,13 @@ //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, diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt index 3b690a21584..2874a0273cc 100644 --- a/source/gameengine/BlenderRoutines/CMakeLists.txt +++ b/source/gameengine/BlenderRoutines/CMakeLists.txt @@ -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 diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index aa83d17a03a..360794ceb33 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -28,11 +28,13 @@ #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) diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript index c2094a15825..fc12f453d86 100644 --- a/source/gameengine/BlenderRoutines/SConscript +++ b/source/gameengine/BlenderRoutines/SConscript @@ -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' diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 1a417110c08..cc0f50d9e7a 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -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 { |