By J. Hedberg / CCNY Planetarium
Overview: This notebook will generate a list of datatimes and use them to set the simulation time for OpenSpace. It can then take screenshots at each moment.
Based on earlier work by the OpenSpace team found here: https://github.com/OpenSpace/scripts/tree/master/jupyter-notebooks
#connect to openspace and pause time
from websocket import create_connection
import json
url = "localhost:4682"
ws_endpoint = f"ws://localhost:4682/websocket"
ws = create_connection(ws_endpoint)
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.time.setPause",
"arguments": [True],
"return": False}})
ws.send(message)
import time;
import datetime;
import math;
from datetime import date
#initialize arrays
#this one stores the time objects to send to openspace
snapshotdate = []
#this one stores them as readable dates and times for human inspection
snapshotdateString = []
#the initial starting moment
timestring = "2023-01-01T12:00:00.0"
#needs some cleaninup/formating etc
timestamp = time.mktime(datetime.datetime.strptime(timestring, '%Y-%m-%dT%H:%M:%S.%f').timetuple())
j2000offset = datetime.datetime(2000,1,1,12) - datetime.datetime(1970,1,1)
#for some reason, OpenSpace is 70 seconds off. ¯\_(ºº)_/¯
timestamp -= j2000offset.total_seconds()-70
#set your interval and number of images
interval = 86400 #in seconds
number_of_photos = 365
#this will populate the snapshotdate array with all the moments you want to capture.
#In this example, it's one shot every 24 hours (86400 seconds) starting at Jan 1, Noon, EST
#But, one can imagine all sorts of other time deltas of interest.
for i in range(0,number_of_photos):
snapshotdate.append(timestamp)
snapshotTimeObject = time.gmtime(snapshotdate[i]+j2000offset.total_seconds()-70)
snapshotdateString.append(time.strftime('%d %B %Y %H:%M', snapshotTimeObject))
timestamp += interval
print('Total number of images: ' + str(len(snapshotdate)))
print('First datetime (in seconds since ): '+str(snapshotdate[0]))
print(snapshotdateString[0])
#This will set the time to the first snapshot entry
#i.e. in this example, Noon in NY on Jan 1, 2023
timestamp = snapshotdate[0]
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.time.setTime",
"arguments": [timestamp],
"return": False}})
ws.send(message)
#This will run through the entire array of snapshots
#If you are not saving anything, then the sleep command can be very short, i.e. 10 milliseconds
for i, value in enumerate(snapshotdate):
timestamp = str(value)
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.time.setTime",
"arguments": [timestamp],
"return": False}})
ws.send(message)
time.sleep(0.01)
print (".", end="", flush=True)
#This will run through the entire array of snapshots and save each one in the User Screenshots folder
#The Sleep commands have been increased to allow for breathing.
#If you wanted to load temporal layers for each day, then you might need to increase these to a few seconds each.
for i, value in enumerate(snapshotdate):
timestamp = str(value)
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.time.setTime",
"arguments": [timestamp],
"return": False}})
ws.send(message)
print (".", end="", flush=True)
time.sleep(0.1)
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.takeScreenshot",
"arguments": [],
"return": False}})
ws.send(message)
time.sleep(0.1)
#You can automate other properties programatically too
#This will linearly scale the Field of View as the Year progresses.
fovSetting = []
for i, value in enumerate(snapshotdate):
fovSetting.append(30+40*i/len(snapshotdate))
for i, value in enumerate(snapshotdate):
timestamp = str(value)
message = json.dumps({"topic": 4,
"type": "luascript",
"payload": {"function": "openspace.time.setTime",
"arguments": [timestamp],
"return": False}})
ws.send(message)
print (".", end="", flush=True)
time.sleep(0.1)
message = json.dumps({"topic": 0,
"type": "set",
"payload": {"property": "RenderEngine.HorizFieldOfView",
"value": fovSetting[i],
"return": False}})
ws.send(message)