changeset 2434:9b101d8bd7ea

discover annotated lights in blender; send their color to the graph (temporary stmt)
author drewp@bigasterisk.com
date Tue, 28 May 2024 17:56:16 -0700
parents ffa69645e9dc
children 207fe0670952
files src/light9/blender/light_control/__init__.py src/light9/blender/light_control/send_to_collector.py src/light9/blender/time_sync/time_from_graph.py
diffstat 3 files changed, 80 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/light9/blender/light_control/__init__.py	Tue May 28 15:41:53 2024 -0700
+++ b/src/light9/blender/light_control/__init__.py	Tue May 28 17:56:16 2024 -0700
@@ -2,12 +2,6 @@
 watch blender lights, output to real lights
 """
 
-import time
-from typing import cast
-
-import bpy  # type: ignore
-from bpy.app.handlers import persistent
-
 sender: object = None
 
 
@@ -17,12 +11,6 @@
 
     sender = Sender()
 
-    # @persistent
-    # def fcp(scene):
-    #     cast(Sender, sender).on_frame_change_post(scene)
-
-    # bpy.app.handlers.frame_change_post.append(fcp)
-
 
 def unregister():
     raise NotImplementedError
--- a/src/light9/blender/light_control/send_to_collector.py	Tue May 28 15:41:53 2024 -0700
+++ b/src/light9/blender/light_control/send_to_collector.py	Tue May 28 17:56:16 2024 -0700
@@ -1,7 +1,81 @@
+import asyncio
+import logging
+from dataclasses import dataclass, field
+
+import bpy  # type: ignore
+from light9.blender.time_sync.time_from_graph import clamp
+from light9.effect.effecteval import literalColor
+from rdfdb.patch import Patch
+from rdfdb.syncedgraph.syncedgraph import SyncedGraph
+from rdflib import Literal, URIRef
+
+from light9 import networking
+from light9.blender.asyncio_thread import startLoopInThread
+from light9.namespaces import L9
+from light9.newtypes import DeviceUri
+from light9.showconfig import showUri
+
+log = logging.getLogger('sendcoll')
+
+UPDATE_PERIOD = 1 / 20
+
+
+@dataclass
+class BlenderDev:
+    ctx: URIRef
+    obj: bpy.types.Object
+    uri: DeviceUri
+    color: tuple[float, float, float] = (0, 0, 0)
+
+    def updateColor(self):
+        self.color = self.obj.data.color
+
+    def makePatch(self, graph: SyncedGraph) -> Patch:
+        c = literalColor(*[clamp(x, 0, 1) for x in self.color])
+        return graph.getObjectPatch(self.ctx, self.uri, L9['blenderColor'], c)
+
+
+@dataclass
 class Sender:
+    syncedObjects: dict[str, BlenderDev] = field(default_factory=dict)
 
-    def blenderTime(self) -> float:
-        return -55
+    ctx = URIRef(showUri() + '/blender')
+
+    def __post_init__(self):
+        bpy.app.timers.register(self.findLightsInScene, first_interval=0.1)  # todo: what event to use?
+        startLoopInThread(self.task())
+
+    async def task(self):
+        graph = SyncedGraph(networking.rdfdb.url, "blender_light_control")
+        while True:
+            try:
+                p = Patch(addQuads=[], delQuads=[])
+                for d in self.syncedObjects.values():
+                    p = p.update(d.makePatch(graph))
+                if p:
+                    await graph.patch(p)
+            except Exception:
+                log.error('skip', exc_info=True)
+                await asyncio.sleep(1)
+            await asyncio.sleep(UPDATE_PERIOD)
 
-    def on_frame_change_post(self, scene, *args):
-        print('ofcp',scene,args)
+    def findLightsInScene(self):
+        self.syncedObjects.clear()
+        for obj in bpy.data.objects:
+            if obj.get('l9dev'):
+                uri = DeviceUri(URIRef(obj['l9dev']))
+                self.syncedObjects[obj.name] = BlenderDev(self.ctx, obj, uri)
+                log.info(f'found {self.syncedObjects[obj.name]}')
+
+        self.watchForUpdates()
+
+    def watchForUpdates(self):
+        bpy.app.handlers.depsgraph_update_post.append(self.onColorChanges)
+        bpy.app.handlers.frame_change_post.append(self.onColorChanges)
+
+    def onColorChanges(self, scene, deps):
+        for obj in deps.objects:
+            dev = self.syncedObjects.get(obj.name)
+            if dev is None:
+                continue
+            dev.updateColor()
--- a/src/light9/blender/time_sync/time_from_graph.py	Tue May 28 15:41:53 2024 -0700
+++ b/src/light9/blender/time_sync/time_from_graph.py	Tue May 28 17:56:16 2024 -0700
@@ -50,7 +50,7 @@
             self.wallStartTime = typedValue(float | None, self.graph, asco, L9['wallStartTime'])
             self.pausedSongTime = typedValue(float | None, self.graph, asco, L9['pausedSongTime'])
             self.duration = typedValue(float | None, self.graph, asco, L9['duration']) or 1.0
-            self.playing = typedValue(bool, self.graph, asco, L9['playing'])
+            self.playing = typedValue(bool|None, self.graph, asco, L9['playing']) or False
 
     def currentTime(self) -> float | None:
         if self.wallStartTime is not None:
@@ -92,4 +92,4 @@
             self.setInGraph(t)
 
     def setInGraph(self, t: float):
-        log.warning(f'todo: set graph to {t}')
+        log.warning(f'todo: set graph to {t:.2f}')