I made few little scripts to work with .sim checkpoint files. Before, I just deleted them manually. Now I have few hotkeys. The toolset is intended for long sims with keyframed behavior. Now I work on an animation for a dancer performance, which is ~ 7200 frames. I plan to update the scripts asap ... to reset multiple related DOPs (pops driven by pyro etc.) with one hotkey press.
The script contains os.remove(file_path), so check it before use.
- reset the sim, hotkey: F5
delete all the .sim cache files in the playrange
but don't delete the first one, I want to built on it
sim_cache_reset ()
sim_cache_delete_playrange ()
- trim the playback range start to the playhead's precedent .sim file
hotkey: /
playrange_to_precedent ()
- add or remove one .sim spacing in playrange
hotkeys: . ,
playrange_extend_spacing (direction)
import os
import hou
import math
import bisect
import toolutils
#####################
### resim ###
#####################
# return the current dopnet node
def sim_dopnet () :
dopnet = hou.currentDopNet()
if dopnet == None :
cache_on = 0
cache_name = None
cache_substeps = 1
cache_start = 1
cache_spacing = 1
else :
cache_on = dopnet.parm("explicitcache").eval()
cache_name = dopnet.parm("explicitcachename").rawValue()
cache_substeps = dopnet.parm("substep").eval()
cache_start = dopnet.parm("startframe").eval()
cache_spacing = dopnet.parm("explicitcachecheckpointspacing").eval()
return [dopnet, cache_on, cache_name, cache_substeps, cache_start, cache_spacing]
# list of all $SF that may be cached with current dopnet settings
# and list of appropriate $F frames
def sim_cache_framelists() :
dopnet, cache_on, cache_name, cache_substeps, cache_start, cache_spacing = sim_dopnet()
framerange_end = hou.playbar.frameRange()[1]
candidate_sf = 0
candidate_f = cache_start
list_sf = [candidate_sf]
list_f = [candidate_f]
while candidate_f <= framerange_end :
candidate_sf += cache_spacing
candidate_f = math.floor((candidate_sf-1) / cache_substeps) + cache_start
list_sf.append(candidate_sf)
list_f.append (candidate_f)
return list_sf, list_f
# find the given frame's precedent cached $F
def sim_cache_precedent_index ( frame ) :
list_sf, list_f = sim_cache_framelists()
precedent_index = bisect.bisect_right(list_f,frame)
precedent_index = max (precedent_index - 1, 0)
return precedent_index
# delete the .sim cache files in the playrange
# but don't delete the first one, we want to built on it
def sim_cache_delete_playrange () :
dopnet, cache_on, cache_name, cache_substeps, cache_start, cache_spacing = sim_dopnet()
hou.cd(dopnet.path()) # to expandString() correctly
list_sf, list_f = sim_cache_framelists()
index = 1 + sim_cache_precedent_index( hou.playbar.playbackRange()[0] )
candidate_frames = list_sf[index:]
# try to delete the files, if they exist
for frame in candidate_frames :
file_path = cache_name.replace("$SF",str(frame))
file_path = hou.expandString(file_path)
file_path = file_path.replace("*","_")
if file_path.endswith(".sim") :
try :
os.remove(file_path)
except :
frame_was_not_cached = 1
# hotkey: F5
# reset the sim
def sim_cache_reset () :
dopnet, cache_on, cache_name, cache_substeps, cache_start, cache_spacing = sim_dopnet()
if cache_on:
# delete .sim files
message = "Delete .sim files in playback range? \n\n" + str(dopnet.path())
if hou.ui.displayMessage(message, buttons=("OK", "Cancel")) == 0:
sim_cache_delete_playrange()
if dopnet:
dopnet.parm("resimulate").pressButton()
hou.setFrame(hou.playbar.playbackRange()[0])
# hotkey: /
# trim the playback start to the playhead's precedent cached .sim file
def playrange_to_precedent () :
list_sf, list_f = sim_cache_framelists()
index = sim_cache_precedent_index( hou.intFrame() )
frame_start = list_f[index]
frame_end = hou.playbar.playbackRange()[1]
hou.playbar.setPlaybackRange( frame_start, frame_end )
# hotkeys: . ,
# add or remove one cached spacing in playrange
def playrange_extend_spacing (direction) :
list_sf, list_f = sim_cache_framelists()
index = sim_cache_precedent_index( hou.playbar.playbackRange()[0] )
index = max (index + direction, 0)
frame_start = list_f[index]
frame_end = hou.playbar.playbackRange()[1]
hou.playbar.setPlaybackRange( frame_start, frame_end )
#####################
### resim end ###
#####################