Compare commits
4
Commits
709dd0ea4f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f08d44188 | ||
|
|
f069a8091b | ||
|
|
5eb623d6af | ||
|
|
c92094cc26 |
@@ -0,0 +1,4 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*.qxw~
|
||||||
|
.DS_Store
|
||||||
@@ -1,2 +1,49 @@
|
|||||||
# qlcplus
|
# qlcplus
|
||||||
|
|
||||||
|
QLC+ show files, fixture definitions, and generators for the XCHC stage
|
||||||
|
(8× beamZ BCC145 parcans + 2× Small Eye 7 movers).
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
fixtures/ Fixture definitions (.qxf) — install into QLC+ if needed
|
||||||
|
shows/ Workspaces to open in QLC+
|
||||||
|
xchc.qxw Main show (patterns + movers, unified VC)
|
||||||
|
simple.qxw Manual board: M1/M2 pads, shared + individual RGBW
|
||||||
|
small_eye.qxw Movers-only figure-of-8 show
|
||||||
|
archive/ Older scratch workspaces
|
||||||
|
scripts/ Generators / patchers for the shows
|
||||||
|
stage/ Stage map (SVG, JSON, canvas)
|
||||||
|
tests/ Art-Net / fixture helpers used by scripts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Open in QLC+
|
||||||
|
|
||||||
|
- Full show: `shows/xchc.qxw`
|
||||||
|
- Simple RGBW + positions: `shows/simple.qxw`
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Rebuild simple manual board
|
||||||
|
python3 scripts/make_simple_vc.py
|
||||||
|
|
||||||
|
# Rewrite can/mover patterns from stage layout
|
||||||
|
python3 scripts/integrate_u_patterns.py
|
||||||
|
|
||||||
|
# Unify Patterns + Movers into one Show frame
|
||||||
|
python3 scripts/unify_vc.py
|
||||||
|
|
||||||
|
# Figure-of-8 (live Art-Net or write/merge workspace)
|
||||||
|
python3 scripts/figure8_small_eye.py --write-qxw shows/small_eye.qxw
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fixtures / DMX
|
||||||
|
|
||||||
|
| Fixture | Mode | Addresses |
|
||||||
|
|---------|------|-----------|
|
||||||
|
| Small Eye 7 #1–#2 | 43ch | 1–43, 45–87 |
|
||||||
|
| BCC145 #1–#8 | 8ch | 87–150 (starts 87, 95, …) |
|
||||||
|
|
||||||
|
Copy `.qxf` files from `fixtures/` into QLC+’s fixture library if the
|
||||||
|
manufacturer/model is missing.
|
||||||
|
|||||||
@@ -0,0 +1,443 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE FixtureDefinition>
|
||||||
|
<FixtureDefinition xmlns="http://www.qlcplus.org/FixtureDefinition">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Manufacturer>Small Eye 7</Manufacturer>
|
||||||
|
<Model>Mover</Model>
|
||||||
|
<Type>Moving Head</Type>
|
||||||
|
<Channel Name="Pan" Preset="PositionPan"/>
|
||||||
|
<Channel Name="Pan Fine" Preset="PositionPanFine"/>
|
||||||
|
<Channel Name="Tilt" Preset="PositionTilt"/>
|
||||||
|
<Channel Name="Tilt Fine" Preset="PositionTiltFine"/>
|
||||||
|
<Channel Name="Pan/Tilt Speed" Preset="SpeedPanTiltFastSlow"/>
|
||||||
|
<Channel Name="Zoom" Preset="BeamZoomSmallBig"/>
|
||||||
|
<Channel Name="Focus" Preset="BeamFocusNearFar"/>
|
||||||
|
<Channel Name="Center Brightness" Preset="IntensityMasterDimmer"/>
|
||||||
|
<Channel Name="Center Strobe">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="3" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="4" Max="200" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
|
||||||
|
<Capability Min="201" Max="215" Preset="StrobeRandom">Random strobe low</Capability>
|
||||||
|
<Capability Min="216" Max="234" Preset="StrobeRandom">Random strobe mid</Capability>
|
||||||
|
<Capability Min="235" Max="255" Preset="StrobeRandom">Random strobe high</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Lens Rotate">
|
||||||
|
<Group Byte="0">Prism</Group>
|
||||||
|
<Capability Min="0" Max="127">Index 0–60° (no spin)</Capability>
|
||||||
|
<Capability Min="128" Max="188" Preset="RotationCounterClockwiseFastToSlow">Spin CCW fast to slow</Capability>
|
||||||
|
<Capability Min="189" Max="193">Stop</Capability>
|
||||||
|
<Capability Min="194" Max="255" Preset="RotationClockwiseSlowToFast">Spin CW slow to fast</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Lens Rotate 35">
|
||||||
|
<Group Byte="0">Prism</Group>
|
||||||
|
<Capability Min="0" Max="127">Index 0–60°</Capability>
|
||||||
|
<Capability Min="128" Max="191" Preset="RotationClockwise">Rotate CW infinite</Capability>
|
||||||
|
<Capability Min="192" Max="255" Preset="RotationCounterClockwise">Rotate CCW infinite</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Dimmer" Preset="IntensityMasterDimmer"/>
|
||||||
|
<Channel Name="Dimmer Fine" Preset="IntensityMasterDimmerFine"/>
|
||||||
|
<Channel Name="Strobe">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="3" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="4" Max="200" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
|
||||||
|
<Capability Min="201" Max="215" Preset="StrobeRandom">Random strobe low</Capability>
|
||||||
|
<Capability Min="216" Max="234" Preset="StrobeRandom">Random strobe mid</Capability>
|
||||||
|
<Capability Min="235" Max="255" Preset="StrobeRandom">Random strobe high</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Strobe 35">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
|
||||||
|
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
|
||||||
|
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
|
||||||
|
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
|
||||||
|
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Red" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Red Fine" Preset="IntensityRedFine"/>
|
||||||
|
<Channel Name="Green" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Green Fine" Preset="IntensityGreenFine"/>
|
||||||
|
<Channel Name="Blue" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="Blue Fine" Preset="IntensityBlueFine"/>
|
||||||
|
<Channel Name="White" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="White Fine" Preset="IntensityWhiteFine"/>
|
||||||
|
<Channel Name="Colour Temperature">
|
||||||
|
<Group Byte="0">Colour</Group>
|
||||||
|
<Capability Min="0" Max="255">Linear CTO / colour temperature</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Colour Macro">
|
||||||
|
<Group Byte="0">Colour</Group>
|
||||||
|
<Capability Min="0" Max="9">No function</Capability>
|
||||||
|
<Capability Min="10" Max="255">Built-in colour macros</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Static Effect">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="9">No function</Capability>
|
||||||
|
<Capability Min="10" Max="255">Static pixel effect select</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Dynamic Effect">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="9">No function</Capability>
|
||||||
|
<Capability Min="10" Max="255">Dynamic pixel effect select</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Dynamic Effect Speed">
|
||||||
|
<Group Byte="0">Speed</Group>
|
||||||
|
<Capability Min="0" Max="127">Forward fast to slow</Capability>
|
||||||
|
<Capability Min="128" Max="255">Reverse slow to fast</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Background Red" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Background Green" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Background Blue" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="Background White" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Reset">
|
||||||
|
<Group Byte="0">Maintenance</Group>
|
||||||
|
<Capability Min="0" Max="199">No function</Capability>
|
||||||
|
<Capability Min="200" Max="205" Preset="ResetMotors">Reset all (hold ~5 s)</Capability>
|
||||||
|
<Capability Min="206" Max="255">No function</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Function">
|
||||||
|
<Group Byte="0">Maintenance</Group>
|
||||||
|
<Capability Min="0" Max="255">Reserved</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Pattern Select">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="255">Pattern / gobo select</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Pattern Speed">
|
||||||
|
<Group Byte="0">Speed</Group>
|
||||||
|
<Capability Min="0" Max="255">Pattern effect speed</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Pattern Fade">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="255">Pattern fade</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Pattern Red" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Pattern Green" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Pattern Blue" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="Pattern White" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Pattern Dimmer" Preset="IntensityDimmer"/>
|
||||||
|
<Channel Name="Background Dimmer" Preset="IntensityDimmer"/>
|
||||||
|
<Channel Name="Pattern Transition">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="255">Pattern transition</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Pattern Angle">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="255">Pattern angle / translation</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Foreground Strobe">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
|
||||||
|
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
|
||||||
|
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
|
||||||
|
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
|
||||||
|
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Background Strobe">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="3" Preset="ShutterClose">Closed</Capability>
|
||||||
|
<Capability Min="4" Max="103" Preset="StrobeSlowToFast">Sync strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="104" Max="107" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="108" Max="207" Preset="StrobeSlowToFast">Pulse strobe 1–25 Hz</Capability>
|
||||||
|
<Capability Min="208" Max="212" Preset="ShutterOpen">Open</Capability>
|
||||||
|
<Capability Min="213" Max="225" Preset="StrobeRandom">Random strobe low</Capability>
|
||||||
|
<Capability Min="226" Max="238" Preset="StrobeRandom">Random strobe mid</Capability>
|
||||||
|
<Capability Min="239" Max="251" Preset="StrobeRandom">Random strobe high</Capability>
|
||||||
|
<Capability Min="252" Max="255" Preset="ShutterOpen">Open</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Background Select">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="255">Background pattern select</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Red 1" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 1" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 1" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 1" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 2" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 2" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 2" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 2" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 3" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 3" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 3" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 3" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 4" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 4" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 4" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 4" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 5" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 5" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 5" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 5" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 6" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 6" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 6" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 6" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Red 7" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green 7" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue 7" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White 7" Preset="IntensityWhite"/>
|
||||||
|
<Mode Name="43 Channel">
|
||||||
|
<Channel Number="0">Pan</Channel>
|
||||||
|
<Channel Number="1">Pan Fine</Channel>
|
||||||
|
<Channel Number="2">Tilt</Channel>
|
||||||
|
<Channel Number="3">Tilt Fine</Channel>
|
||||||
|
<Channel Number="4">Pan/Tilt Speed</Channel>
|
||||||
|
<Channel Number="5">Zoom</Channel>
|
||||||
|
<Channel Number="6">Lens Rotate</Channel>
|
||||||
|
<Channel Number="7">Focus</Channel>
|
||||||
|
<Channel Number="8">Center Brightness</Channel>
|
||||||
|
<Channel Number="9">Center Strobe</Channel>
|
||||||
|
<Channel Number="10">Red 1</Channel>
|
||||||
|
<Channel Number="11">Green 1</Channel>
|
||||||
|
<Channel Number="12">Blue 1</Channel>
|
||||||
|
<Channel Number="13">White 1</Channel>
|
||||||
|
<Channel Number="14">Red 2</Channel>
|
||||||
|
<Channel Number="15">Green 2</Channel>
|
||||||
|
<Channel Number="16">Blue 2</Channel>
|
||||||
|
<Channel Number="17">White 2</Channel>
|
||||||
|
<Channel Number="18">Red 3</Channel>
|
||||||
|
<Channel Number="19">Green 3</Channel>
|
||||||
|
<Channel Number="20">Blue 3</Channel>
|
||||||
|
<Channel Number="21">White 3</Channel>
|
||||||
|
<Channel Number="22">Red 4</Channel>
|
||||||
|
<Channel Number="23">Green 4</Channel>
|
||||||
|
<Channel Number="24">Blue 4</Channel>
|
||||||
|
<Channel Number="25">White 4</Channel>
|
||||||
|
<Channel Number="26">Red 5</Channel>
|
||||||
|
<Channel Number="27">Green 5</Channel>
|
||||||
|
<Channel Number="28">Blue 5</Channel>
|
||||||
|
<Channel Number="29">White 5</Channel>
|
||||||
|
<Channel Number="30">Red 6</Channel>
|
||||||
|
<Channel Number="31">Green 6</Channel>
|
||||||
|
<Channel Number="32">Blue 6</Channel>
|
||||||
|
<Channel Number="33">White 6</Channel>
|
||||||
|
<Channel Number="34">Red 7</Channel>
|
||||||
|
<Channel Number="35">Green 7</Channel>
|
||||||
|
<Channel Number="36">Blue 7</Channel>
|
||||||
|
<Channel Number="37">White 7</Channel>
|
||||||
|
<Channel Number="38">Colour Temperature</Channel>
|
||||||
|
<Channel Number="39">Colour Macro</Channel>
|
||||||
|
<Channel Number="40">Static Effect</Channel>
|
||||||
|
<Channel Number="41">Dynamic Effect</Channel>
|
||||||
|
<Channel Number="42">Reset</Channel>
|
||||||
|
<Head>
|
||||||
|
<Channel>10</Channel>
|
||||||
|
<Channel>11</Channel>
|
||||||
|
<Channel>12</Channel>
|
||||||
|
<Channel>13</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>14</Channel>
|
||||||
|
<Channel>15</Channel>
|
||||||
|
<Channel>16</Channel>
|
||||||
|
<Channel>17</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>18</Channel>
|
||||||
|
<Channel>19</Channel>
|
||||||
|
<Channel>20</Channel>
|
||||||
|
<Channel>21</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>22</Channel>
|
||||||
|
<Channel>23</Channel>
|
||||||
|
<Channel>24</Channel>
|
||||||
|
<Channel>25</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>26</Channel>
|
||||||
|
<Channel>27</Channel>
|
||||||
|
<Channel>28</Channel>
|
||||||
|
<Channel>29</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>30</Channel>
|
||||||
|
<Channel>31</Channel>
|
||||||
|
<Channel>32</Channel>
|
||||||
|
<Channel>33</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>34</Channel>
|
||||||
|
<Channel>35</Channel>
|
||||||
|
<Channel>36</Channel>
|
||||||
|
<Channel>37</Channel>
|
||||||
|
</Head>
|
||||||
|
</Mode>
|
||||||
|
<Mode Name="23 Channel">
|
||||||
|
<Channel Number="0">Pan</Channel>
|
||||||
|
<Channel Number="1">Pan Fine</Channel>
|
||||||
|
<Channel Number="2">Tilt</Channel>
|
||||||
|
<Channel Number="3">Tilt Fine</Channel>
|
||||||
|
<Channel Number="4">Pan/Tilt Speed</Channel>
|
||||||
|
<Channel Number="5">Zoom</Channel>
|
||||||
|
<Channel Number="6">Lens Rotate</Channel>
|
||||||
|
<Channel Number="7">Focus</Channel>
|
||||||
|
<Channel Number="8">Center Brightness</Channel>
|
||||||
|
<Channel Number="9">Center Strobe</Channel>
|
||||||
|
<Channel Number="10">Red</Channel>
|
||||||
|
<Channel Number="11">Green</Channel>
|
||||||
|
<Channel Number="12">Blue</Channel>
|
||||||
|
<Channel Number="13">White</Channel>
|
||||||
|
<Channel Number="14">Colour Macro</Channel>
|
||||||
|
<Channel Number="15">Static Effect</Channel>
|
||||||
|
<Channel Number="16">Dynamic Effect</Channel>
|
||||||
|
<Channel Number="17">Dynamic Effect Speed</Channel>
|
||||||
|
<Channel Number="18">Background Red</Channel>
|
||||||
|
<Channel Number="19">Background Green</Channel>
|
||||||
|
<Channel Number="20">Background Blue</Channel>
|
||||||
|
<Channel Number="21">Background White</Channel>
|
||||||
|
<Channel Number="22">Reset</Channel>
|
||||||
|
</Mode>
|
||||||
|
<Mode Name="35 Channel">
|
||||||
|
<Channel Number="0">Red</Channel>
|
||||||
|
<Channel Number="1">Red Fine</Channel>
|
||||||
|
<Channel Number="2">Green</Channel>
|
||||||
|
<Channel Number="3">Green Fine</Channel>
|
||||||
|
<Channel Number="4">Blue</Channel>
|
||||||
|
<Channel Number="5">Blue Fine</Channel>
|
||||||
|
<Channel Number="6">White</Channel>
|
||||||
|
<Channel Number="7">White Fine</Channel>
|
||||||
|
<Channel Number="8">Colour Temperature</Channel>
|
||||||
|
<Channel Number="9">Colour Macro</Channel>
|
||||||
|
<Channel Number="10">Strobe 35</Channel>
|
||||||
|
<Channel Number="11">Dimmer</Channel>
|
||||||
|
<Channel Number="12">Dimmer Fine</Channel>
|
||||||
|
<Channel Number="13">Pan</Channel>
|
||||||
|
<Channel Number="14">Pan Fine</Channel>
|
||||||
|
<Channel Number="15">Tilt</Channel>
|
||||||
|
<Channel Number="16">Tilt Fine</Channel>
|
||||||
|
<Channel Number="17">Function</Channel>
|
||||||
|
<Channel Number="18">Reset</Channel>
|
||||||
|
<Channel Number="19">Zoom</Channel>
|
||||||
|
<Channel Number="20">Lens Rotate 35</Channel>
|
||||||
|
<Channel Number="21">Pattern Select</Channel>
|
||||||
|
<Channel Number="22">Pattern Speed</Channel>
|
||||||
|
<Channel Number="23">Pattern Fade</Channel>
|
||||||
|
<Channel Number="24">Pattern Red</Channel>
|
||||||
|
<Channel Number="25">Pattern Green</Channel>
|
||||||
|
<Channel Number="26">Pattern Blue</Channel>
|
||||||
|
<Channel Number="27">Pattern White</Channel>
|
||||||
|
<Channel Number="28">Pattern Dimmer</Channel>
|
||||||
|
<Channel Number="29">Background Dimmer</Channel>
|
||||||
|
<Channel Number="30">Pattern Transition</Channel>
|
||||||
|
<Channel Number="31">Pattern Angle</Channel>
|
||||||
|
<Channel Number="32">Foreground Strobe</Channel>
|
||||||
|
<Channel Number="33">Background Strobe</Channel>
|
||||||
|
<Channel Number="34">Background Select</Channel>
|
||||||
|
</Mode>
|
||||||
|
<Mode Name="51 Channel">
|
||||||
|
<Channel Number="0">Pan</Channel>
|
||||||
|
<Channel Number="1">Pan Fine</Channel>
|
||||||
|
<Channel Number="2">Tilt</Channel>
|
||||||
|
<Channel Number="3">Tilt Fine</Channel>
|
||||||
|
<Channel Number="4">Pan/Tilt Speed</Channel>
|
||||||
|
<Channel Number="5">Zoom</Channel>
|
||||||
|
<Channel Number="6">Lens Rotate</Channel>
|
||||||
|
<Channel Number="7">Focus</Channel>
|
||||||
|
<Channel Number="8">Center Brightness</Channel>
|
||||||
|
<Channel Number="9">Center Strobe</Channel>
|
||||||
|
<Channel Number="10">Red</Channel>
|
||||||
|
<Channel Number="11">Green</Channel>
|
||||||
|
<Channel Number="12">Blue</Channel>
|
||||||
|
<Channel Number="13">White</Channel>
|
||||||
|
<Channel Number="14">Colour Macro</Channel>
|
||||||
|
<Channel Number="15">Static Effect</Channel>
|
||||||
|
<Channel Number="16">Dynamic Effect</Channel>
|
||||||
|
<Channel Number="17">Dynamic Effect Speed</Channel>
|
||||||
|
<Channel Number="18">Background Red</Channel>
|
||||||
|
<Channel Number="19">Background Green</Channel>
|
||||||
|
<Channel Number="20">Background Blue</Channel>
|
||||||
|
<Channel Number="21">Background White</Channel>
|
||||||
|
<Channel Number="22">Reset</Channel>
|
||||||
|
<Channel Number="23">Red 1</Channel>
|
||||||
|
<Channel Number="24">Green 1</Channel>
|
||||||
|
<Channel Number="25">Blue 1</Channel>
|
||||||
|
<Channel Number="26">White 1</Channel>
|
||||||
|
<Channel Number="27">Red 2</Channel>
|
||||||
|
<Channel Number="28">Green 2</Channel>
|
||||||
|
<Channel Number="29">Blue 2</Channel>
|
||||||
|
<Channel Number="30">White 2</Channel>
|
||||||
|
<Channel Number="31">Red 3</Channel>
|
||||||
|
<Channel Number="32">Green 3</Channel>
|
||||||
|
<Channel Number="33">Blue 3</Channel>
|
||||||
|
<Channel Number="34">White 3</Channel>
|
||||||
|
<Channel Number="35">Red 4</Channel>
|
||||||
|
<Channel Number="36">Green 4</Channel>
|
||||||
|
<Channel Number="37">Blue 4</Channel>
|
||||||
|
<Channel Number="38">White 4</Channel>
|
||||||
|
<Channel Number="39">Red 5</Channel>
|
||||||
|
<Channel Number="40">Green 5</Channel>
|
||||||
|
<Channel Number="41">Blue 5</Channel>
|
||||||
|
<Channel Number="42">White 5</Channel>
|
||||||
|
<Channel Number="43">Red 6</Channel>
|
||||||
|
<Channel Number="44">Green 6</Channel>
|
||||||
|
<Channel Number="45">Blue 6</Channel>
|
||||||
|
<Channel Number="46">White 6</Channel>
|
||||||
|
<Channel Number="47">Red 7</Channel>
|
||||||
|
<Channel Number="48">Green 7</Channel>
|
||||||
|
<Channel Number="49">Blue 7</Channel>
|
||||||
|
<Channel Number="50">White 7</Channel>
|
||||||
|
<Head>
|
||||||
|
<Channel>23</Channel>
|
||||||
|
<Channel>24</Channel>
|
||||||
|
<Channel>25</Channel>
|
||||||
|
<Channel>26</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>27</Channel>
|
||||||
|
<Channel>28</Channel>
|
||||||
|
<Channel>29</Channel>
|
||||||
|
<Channel>30</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>31</Channel>
|
||||||
|
<Channel>32</Channel>
|
||||||
|
<Channel>33</Channel>
|
||||||
|
<Channel>34</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>35</Channel>
|
||||||
|
<Channel>36</Channel>
|
||||||
|
<Channel>37</Channel>
|
||||||
|
<Channel>38</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>39</Channel>
|
||||||
|
<Channel>40</Channel>
|
||||||
|
<Channel>41</Channel>
|
||||||
|
<Channel>42</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>43</Channel>
|
||||||
|
<Channel>44</Channel>
|
||||||
|
<Channel>45</Channel>
|
||||||
|
<Channel>46</Channel>
|
||||||
|
</Head>
|
||||||
|
<Head>
|
||||||
|
<Channel>47</Channel>
|
||||||
|
<Channel>48</Channel>
|
||||||
|
<Channel>49</Channel>
|
||||||
|
<Channel>50</Channel>
|
||||||
|
</Head>
|
||||||
|
</Mode>
|
||||||
|
<Physical>
|
||||||
|
<Bulb Type="LED" Lumens="0" ColourTemperature="0"/>
|
||||||
|
<Dimensions Weight="5.6" Width="242" Height="313" Depth="184"/>
|
||||||
|
<Lens Name="Other" DegreesMin="5" DegreesMax="45"/>
|
||||||
|
<Focus Type="Head" PanMax="540" TiltMax="270"/>
|
||||||
|
<Layout Width="7" Height="1"/>
|
||||||
|
<Technical PowerConsumption="300" DmxConnector="3-pin"/>
|
||||||
|
</Physical>
|
||||||
|
</FixtureDefinition>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE FixtureDefinition>
|
||||||
|
<FixtureDefinition xmlns="http://www.qlcplus.org/FixtureDefinition">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Type>Color Changer</Type>
|
||||||
|
<Channel Name="Dimmer" Default="255" Preset="IntensityMasterDimmer"/>
|
||||||
|
<Channel Name="Red" Preset="IntensityRed"/>
|
||||||
|
<Channel Name="Green" Preset="IntensityGreen"/>
|
||||||
|
<Channel Name="Blue" Preset="IntensityBlue"/>
|
||||||
|
<Channel Name="White" Preset="IntensityWhite"/>
|
||||||
|
<Channel Name="Strobe">
|
||||||
|
<Group Byte="0">Shutter</Group>
|
||||||
|
<Capability Min="0" Max="7" Preset="ShutterOpen">No function</Capability>
|
||||||
|
<Capability Min="8" Max="255" Preset="StrobeSlowToFast">Strobe slow to fast</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Macro">
|
||||||
|
<Group Byte="0">Effect</Group>
|
||||||
|
<Capability Min="0" Max="50">RGBW mix</Capability>
|
||||||
|
<Capability Min="51" Max="100">Fixed colour</Capability>
|
||||||
|
<Capability Min="101" Max="150">Colour jump</Capability>
|
||||||
|
<Capability Min="151" Max="200">Colour pulse</Capability>
|
||||||
|
<Capability Min="201" Max="250">Colour gradient</Capability>
|
||||||
|
<Capability Min="251" Max="253">Sound 1</Capability>
|
||||||
|
<Capability Min="254" Max="255">Sound 2</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Channel Name="Speed">
|
||||||
|
<Group Byte="0">Speed</Group>
|
||||||
|
<Capability Min="0" Max="255">Macro speed from slow to fast</Capability>
|
||||||
|
</Channel>
|
||||||
|
<Mode Name="4 Channel">
|
||||||
|
<Channel Number="0">Red</Channel>
|
||||||
|
<Channel Number="1">Green</Channel>
|
||||||
|
<Channel Number="2">Blue</Channel>
|
||||||
|
<Channel Number="3">White</Channel>
|
||||||
|
</Mode>
|
||||||
|
<Mode Name="8 Channel">
|
||||||
|
<Channel Number="0">Dimmer</Channel>
|
||||||
|
<Channel Number="1">Strobe</Channel>
|
||||||
|
<Channel Number="2">Red</Channel>
|
||||||
|
<Channel Number="3">Green</Channel>
|
||||||
|
<Channel Number="4">Blue</Channel>
|
||||||
|
<Channel Number="5">White</Channel>
|
||||||
|
<Channel Number="6">Macro</Channel>
|
||||||
|
<Channel Number="7">Speed</Channel>
|
||||||
|
</Mode>
|
||||||
|
<Physical>
|
||||||
|
<Bulb Type="LED" Lumens="0" ColourTemperature="0"/>
|
||||||
|
<Dimensions Weight="1.15" Width="232" Height="225" Depth="110"/>
|
||||||
|
<Lens Name="Other" DegreesMin="25" DegreesMax="25"/>
|
||||||
|
<Focus Type="Fixed" PanMax="0" TiltMax="0"/>
|
||||||
|
<Technical PowerConsumption="56" DmxConnector="3-pin"/>
|
||||||
|
</Physical>
|
||||||
|
</FixtureDefinition>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,366 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Rewrite xchc pattern scenes so the U of cans + centre movers act as one.
|
||||||
|
|
||||||
|
Building 7 m wide. Coordinates in metres:
|
||||||
|
X = 0 at centre line, +X to the right
|
||||||
|
Y = 0 at the row of 4, +Y toward audience (in front of the 4)
|
||||||
|
|
||||||
|
Audience
|
||||||
|
1 8 ← wall-mounted sides @ 2.4 m in front of the 4
|
||||||
|
2 M1 M2 7 ← wall-mounted sides @ 1.2 m; movers @ 1.1 m, ±0.3 m
|
||||||
|
3 — 4 — 5 — 6 ← row of 4 at ±0.6 m and ±1.8 m from centre
|
||||||
|
|
||||||
|
Building 7 m → side walls at ±3.5 m. #1,#2 left wall; #7,#8 right wall.
|
||||||
|
#1 front left. Movers 1.1 m in front of the row of 4, 0.3 m off centre.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
CANS = list(range(8))
|
||||||
|
MOVERS = (8, 9)
|
||||||
|
|
||||||
|
WALL = 3.5 # building half-width
|
||||||
|
|
||||||
|
# Fixture ID → (x_m, y_m) — Y=0 = row of 4; +Y toward audience
|
||||||
|
LAYOUT_M = {
|
||||||
|
0: (-WALL, 2.4), # #1 front left — left wall
|
||||||
|
1: (-WALL, 1.2), # #2 — left wall
|
||||||
|
2: (-1.8, 0.0), # #3 row of 4
|
||||||
|
3: (-0.6, 0.0), # #4 row of 4
|
||||||
|
4: (0.6, 0.0), # #5 row of 4
|
||||||
|
5: (1.8, 0.0), # #6 row of 4
|
||||||
|
6: (WALL, 1.2), # #7 — right wall
|
||||||
|
7: (WALL, 2.4), # #8 front right — right wall
|
||||||
|
8: (-0.3, 1.1), # Small Eye #1 — 0.3 m off centre, 1.1 m in front of row of 4
|
||||||
|
9: (0.3, 1.1), # Small Eye #2 — 0.3 m off centre, 1.1 m in front of row of 4
|
||||||
|
}
|
||||||
|
|
||||||
|
# Walk U: #1 → #2 → along row of 4 L→R → #7 → #8
|
||||||
|
U_WALK = [0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
|
LEFT_SIDE = {0, 1}
|
||||||
|
RIGHT_SIDE = {6, 7}
|
||||||
|
ROW4 = {2, 3, 4, 5}
|
||||||
|
RINGS = [
|
||||||
|
{8, 9},
|
||||||
|
{8, 9, 3, 4}, # movers + centre of row of 4
|
||||||
|
{8, 9, *ROW4},
|
||||||
|
{8, 9, *CANS},
|
||||||
|
]
|
||||||
|
LEFT = LEFT_SIDE | {2, 3, 8}
|
||||||
|
RIGHT = RIGHT_SIDE | {4, 5, 9}
|
||||||
|
|
||||||
|
GRID_W = 7.0
|
||||||
|
GRID_H = 3.2
|
||||||
|
X_ORIGIN = -3.5
|
||||||
|
|
||||||
|
|
||||||
|
def m_to_grid(x_m: float, y_m: float) -> tuple[float, float]:
|
||||||
|
gx = round(x_m - X_ORIGIN, 2)
|
||||||
|
# Row of 4 (y=0) toward top; audience / front sides toward bottom
|
||||||
|
gy = round(y_m, 2)
|
||||||
|
return gx, gy
|
||||||
|
|
||||||
|
|
||||||
|
COLORS = {
|
||||||
|
"Red": (255, 0, 0),
|
||||||
|
"Orange": (255, 127, 0),
|
||||||
|
"Yellow": (255, 255, 0),
|
||||||
|
"Green": (0, 255, 0),
|
||||||
|
"Cyan": (0, 255, 255),
|
||||||
|
"Blue": (0, 0, 255),
|
||||||
|
"Violet": (127, 0, 255),
|
||||||
|
"Magenta": (255, 0, 255),
|
||||||
|
"White": (255, 255, 255),
|
||||||
|
}
|
||||||
|
|
||||||
|
RAINBOW = [
|
||||||
|
(255, 0, 0),
|
||||||
|
(255, 127, 0),
|
||||||
|
(255, 255, 0),
|
||||||
|
(0, 255, 0),
|
||||||
|
(0, 255, 255),
|
||||||
|
(0, 0, 255),
|
||||||
|
(127, 0, 255),
|
||||||
|
(255, 0, 255),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def can_channels(r: int, g: int, b: int, *, white: int = 0, on: bool = True) -> str:
|
||||||
|
if not on:
|
||||||
|
return "0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0"
|
||||||
|
if white:
|
||||||
|
return f"1,0,2,0,3,0,4,0,5,{white},6,0,7,0"
|
||||||
|
return f"1,0,2,{r},3,{g},4,{b},5,0,6,0,7,0"
|
||||||
|
|
||||||
|
|
||||||
|
def mover_channels(r: int, g: int, b: int, *, on: bool = True, dim: int = 255) -> str:
|
||||||
|
if not on or (r == g == b == 0):
|
||||||
|
dim = 0
|
||||||
|
r = g = b = 0
|
||||||
|
parts = [
|
||||||
|
0, 128, 2, 80, 4, 0, 5, 0, 6, 191, 7, 70, 8, dim, 9, 0,
|
||||||
|
10, r, 11, g, 12, b, 13, 0,
|
||||||
|
]
|
||||||
|
for pixel in range(1, 7):
|
||||||
|
base = 10 + pixel * 4
|
||||||
|
parts.extend([base, 0, base + 1, 0, base + 2, 0, base + 3, 0])
|
||||||
|
return ",".join(str(x) for x in parts)
|
||||||
|
|
||||||
|
|
||||||
|
def fixture_vals(
|
||||||
|
lit: dict[int, tuple[int, int, int] | None], *, white_ids: set[int] | None = None
|
||||||
|
) -> str:
|
||||||
|
white_ids = white_ids or set()
|
||||||
|
lines = []
|
||||||
|
for fid in list(CANS) + list(MOVERS):
|
||||||
|
rgb = lit.get(fid)
|
||||||
|
if rgb is None:
|
||||||
|
ch = (
|
||||||
|
mover_channels(0, 0, 0, on=False)
|
||||||
|
if fid in MOVERS
|
||||||
|
else can_channels(0, 0, 0, on=False)
|
||||||
|
)
|
||||||
|
lines.append(f' <FixtureVal ID="{fid}">{ch}</FixtureVal>')
|
||||||
|
continue
|
||||||
|
r, g, b = rgb
|
||||||
|
if fid in MOVERS:
|
||||||
|
ch = mover_channels(r, g, b)
|
||||||
|
elif fid in white_ids:
|
||||||
|
ch = can_channels(0, 0, 0, white=255)
|
||||||
|
else:
|
||||||
|
ch = can_channels(r, g, b)
|
||||||
|
lines.append(f' <FixtureVal ID="{fid}">{ch}</FixtureVal>')
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def scene(
|
||||||
|
fid: int,
|
||||||
|
name: str,
|
||||||
|
lit: dict,
|
||||||
|
*,
|
||||||
|
white_ids: set[int] | None = None,
|
||||||
|
fade: int = 0,
|
||||||
|
) -> str:
|
||||||
|
return f""" <Function ID="{fid}" Type="Scene" Name="{name}">
|
||||||
|
<Speed FadeIn="{fade}" FadeOut="0" Duration="{fade}" />
|
||||||
|
{fixture_vals(lit, white_ids=white_ids)}
|
||||||
|
</Function>"""
|
||||||
|
|
||||||
|
|
||||||
|
def replace_function(text: str, function_id: int, new_xml: str) -> str:
|
||||||
|
pattern = re.compile(
|
||||||
|
rf' <Function ID="{function_id}"[\s\S]*?</Function>\n',
|
||||||
|
re.MULTILINE,
|
||||||
|
)
|
||||||
|
if not pattern.search(text):
|
||||||
|
raise SystemExit(f"Function ID {function_id} not found")
|
||||||
|
return pattern.sub(new_xml.rstrip() + "\n", text, count=1)
|
||||||
|
|
||||||
|
|
||||||
|
def all_color(rgb: tuple[int, int, int]) -> dict:
|
||||||
|
lit = {i: rgb for i in CANS}
|
||||||
|
lit[8] = rgb
|
||||||
|
lit[9] = rgb
|
||||||
|
return lit
|
||||||
|
|
||||||
|
|
||||||
|
def monitor_xml() -> str:
|
||||||
|
items = []
|
||||||
|
for fid, (xm, ym) in LAYOUT_M.items():
|
||||||
|
gx, gy = m_to_grid(xm, ym)
|
||||||
|
items.append(f' <FxItem ID="{fid}" XPos="{gx}" YPos="{gy}" />')
|
||||||
|
return f""" <Monitor DisplayMode="1" ShowLabels="1">
|
||||||
|
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
|
||||||
|
<ChannelStyle>0</ChannelStyle>
|
||||||
|
<ValueStyle>0</ValueStyle>
|
||||||
|
<Grid Width="{GRID_W}" Height="{GRID_H}" Depth="5" Units="0" />
|
||||||
|
{chr(10).join(items)}
|
||||||
|
</Monitor>"""
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path = Path(__file__).resolve().parents[1] / "shows" / "xchc.qxw"
|
||||||
|
text = path.read_text()
|
||||||
|
|
||||||
|
for i, (name, rgb) in enumerate(COLORS.items()):
|
||||||
|
white_ids = set(CANS) if name == "White" else None
|
||||||
|
text = replace_function(text, i, scene(i, name, all_color(rgb), white_ids=white_ids))
|
||||||
|
|
||||||
|
for step in range(8):
|
||||||
|
lit = {}
|
||||||
|
for ci, can in enumerate(U_WALK):
|
||||||
|
lit[can] = RAINBOW[(ci + step) % 8]
|
||||||
|
lit[8] = RAINBOW[(3 + step) % 8]
|
||||||
|
lit[9] = RAINBOW[(4 + step) % 8]
|
||||||
|
text = replace_function(text, 10 + step, scene(10 + step, f"Rainbow {step + 1}", lit))
|
||||||
|
|
||||||
|
blue, red = (0, 0, 255), (255, 0, 0)
|
||||||
|
odd_blue, odd_red = {}, {}
|
||||||
|
for i in CANS:
|
||||||
|
if i % 2 == 0:
|
||||||
|
odd_blue[i], odd_red[i] = blue, red
|
||||||
|
else:
|
||||||
|
odd_blue[i], odd_red[i] = red, blue
|
||||||
|
odd_blue[8], odd_blue[9] = blue, red
|
||||||
|
odd_red[8], odd_red[9] = red, blue
|
||||||
|
text = replace_function(text, 20, scene(20, "Odd Blue Even Red", odd_blue))
|
||||||
|
text = replace_function(text, 21, scene(21, "Odd Red Even Blue", odd_red))
|
||||||
|
|
||||||
|
off = {i: None for i in list(CANS) + list(MOVERS)}
|
||||||
|
text = replace_function(text, 23, scene(23, "Test Off", off))
|
||||||
|
text = replace_function(text, 72, scene(72, "Soft Blackout", off, fade=4000))
|
||||||
|
|
||||||
|
for i, can in enumerate(U_WALK):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
lit[can] = (255, 255, 255)
|
||||||
|
text = replace_function(
|
||||||
|
text, 33 + i, scene(33 + i, f"Scanner {i + 1}", lit, white_ids={can})
|
||||||
|
)
|
||||||
|
for mid, name, ids in ((99, "Scanner Movers", {8, 9}), (100, "Scanner Off", set())):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
for m in ids:
|
||||||
|
lit[m] = (255, 255, 255)
|
||||||
|
block = scene(mid, name, lit)
|
||||||
|
if f'Function ID="{mid}"' in text:
|
||||||
|
text = replace_function(text, mid, block)
|
||||||
|
else:
|
||||||
|
text = text.replace(
|
||||||
|
' <Function ID="41" Type="Chaser" Name="Scanner">',
|
||||||
|
block + '\n <Function ID="41" Type="Chaser" Name="Scanner">',
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
scanner_steps = "\n".join(
|
||||||
|
f' <Step Number="{i}" FadeIn="0" Hold="400" FadeOut="0">{sid}</Step>'
|
||||||
|
for i, sid in enumerate([*range(33, 41), 99, 100])
|
||||||
|
)
|
||||||
|
text = replace_function(
|
||||||
|
text,
|
||||||
|
41,
|
||||||
|
f""" <Function ID="41" Type="Chaser" Name="Scanner">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="400" />
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>Loop</RunOrder>
|
||||||
|
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
|
||||||
|
{scanner_steps}
|
||||||
|
</Function>""",
|
||||||
|
)
|
||||||
|
|
||||||
|
for n in range(1, 9):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
for can in U_WALK[:n]:
|
||||||
|
lit[can] = (255, 255, 255)
|
||||||
|
if n >= 3:
|
||||||
|
lit[8] = lit[9] = (255, 255, 255)
|
||||||
|
white = {c for c in U_WALK[:n]}
|
||||||
|
text = replace_function(
|
||||||
|
text, 41 + n, scene(41 + n, f"Fill {n}", lit, white_ids=white)
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, ring in enumerate(RINGS):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
white = {f for f in ring if f in CANS}
|
||||||
|
for fid in ring:
|
||||||
|
lit[fid] = (255, 255, 255)
|
||||||
|
text = replace_function(
|
||||||
|
text, 51 + i, scene(51 + i, f"Center {i + 1}", lit, white_ids=white)
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, (ids, name) in enumerate(
|
||||||
|
[
|
||||||
|
({0, 7}, "Pairs 1"),
|
||||||
|
({1, 6}, "Pairs 2"),
|
||||||
|
({2, 5}, "Pairs 3"),
|
||||||
|
({3, 4, 8, 9}, "Pairs 4"),
|
||||||
|
]
|
||||||
|
):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
white = {f for f in ids if f in CANS}
|
||||||
|
for fid in ids:
|
||||||
|
lit[fid] = (255, 255, 255)
|
||||||
|
text = replace_function(text, 56 + i, scene(56 + i, name, lit, white_ids=white))
|
||||||
|
|
||||||
|
lbrr = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
lrbr = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
for fid in LEFT:
|
||||||
|
lbrr[fid], lrbr[fid] = (0, 0, 255), (255, 0, 0)
|
||||||
|
for fid in RIGHT:
|
||||||
|
lbrr[fid], lrbr[fid] = (255, 0, 0), (0, 0, 255)
|
||||||
|
text = replace_function(text, 61, scene(61, "Left Blue Right Red", lbrr))
|
||||||
|
text = replace_function(text, 62, scene(62, "Left Red Right Blue", lrbr))
|
||||||
|
|
||||||
|
for step in range(3):
|
||||||
|
lit = {fid: None for fid in list(CANS) + list(MOVERS)}
|
||||||
|
white = set()
|
||||||
|
for can in CANS:
|
||||||
|
if can % 3 == step:
|
||||||
|
lit[can] = (255, 255, 255)
|
||||||
|
white.add(can)
|
||||||
|
if step == 0:
|
||||||
|
lit[8] = (255, 255, 255)
|
||||||
|
elif step == 1:
|
||||||
|
lit[9] = (255, 255, 255)
|
||||||
|
else:
|
||||||
|
lit[8] = lit[9] = (255, 200, 140)
|
||||||
|
text = replace_function(
|
||||||
|
text, 64 + step, scene(64 + step, f"Theater {step + 1}", lit, white_ids=white)
|
||||||
|
)
|
||||||
|
|
||||||
|
collapse_steps = "\n".join(
|
||||||
|
f' <Step Number="{i}" FadeIn="200" Hold="300" FadeOut="0">{sid}</Step>'
|
||||||
|
for i, sid in enumerate([54, 53, 52, 51, 23])
|
||||||
|
)
|
||||||
|
text = replace_function(
|
||||||
|
text,
|
||||||
|
68,
|
||||||
|
f""" <Function ID="68" Type="Chaser" Name="Collapse In">
|
||||||
|
<Speed FadeIn="200" FadeOut="0" Duration="500" />
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>SingleShot</RunOrder>
|
||||||
|
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
|
||||||
|
{collapse_steps}
|
||||||
|
</Function>""",
|
||||||
|
)
|
||||||
|
|
||||||
|
chase_steps = "\n".join(
|
||||||
|
f' <Step Number="{i}" FadeIn="0" Hold="300" FadeOut="0">{sid}</Step>'
|
||||||
|
for i, sid in enumerate([*range(33, 41), 99, 23])
|
||||||
|
)
|
||||||
|
text = replace_function(
|
||||||
|
text,
|
||||||
|
69,
|
||||||
|
f""" <Function ID="69" Type="Chaser" Name="Chase Out">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="400" />
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>SingleShot</RunOrder>
|
||||||
|
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common" />
|
||||||
|
{chase_steps}
|
||||||
|
</Function>""",
|
||||||
|
)
|
||||||
|
|
||||||
|
text = replace_function(
|
||||||
|
text, 70, scene(70, "Home Soft", all_color((255, 180, 80)), fade=2500)
|
||||||
|
)
|
||||||
|
|
||||||
|
text = re.sub(
|
||||||
|
r' <Monitor DisplayMode="1" ShowLabels="1">[\s\S]*?</Monitor>',
|
||||||
|
lambda _m: monitor_xml(),
|
||||||
|
text,
|
||||||
|
count=1,
|
||||||
|
)
|
||||||
|
text = text.replace("<Name>BCC145 Line</Name>", "<Name>BCC145 U</Name>", 1)
|
||||||
|
|
||||||
|
path.write_text(text)
|
||||||
|
print("Updated", path)
|
||||||
|
print("Y=0 row of 4; +Y toward audience (in front of the 4)")
|
||||||
|
for fid in sorted(LAYOUT_M):
|
||||||
|
x, y = LAYOUT_M[fid]
|
||||||
|
label = f"Can #{fid + 1}" if fid < 8 else f"Mover #{fid - 7}"
|
||||||
|
print(f" {label:10} x={x:+.1f} y={y:.1f}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,837 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate shows/cabaret.qxw — grouped can RGB + per-mover position and RGB."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
OUT = ROOT / "shows" / "cabaret.qxw"
|
||||||
|
|
||||||
|
M1, M2 = 8, 9
|
||||||
|
|
||||||
|
# Can groups: 1-2 | 3-4-5-6 | 7-8
|
||||||
|
GROUP_L = [0, 1]
|
||||||
|
GROUP_C = [2, 3, 4, 5]
|
||||||
|
GROUP_R = [6, 7]
|
||||||
|
|
||||||
|
# Can 8ch: Dim=0, R=2, G=3, B=4
|
||||||
|
# Mover 43ch: Pan/Tilt Speed=4, Focus=7, Center Bright=8; RGB heads 1–7
|
||||||
|
MOVER_SPEED = 4
|
||||||
|
MOVER_FOCUS = 7
|
||||||
|
MOVER_DIM = 8
|
||||||
|
MOVER_R = [10, 14, 18, 22, 26, 30, 34]
|
||||||
|
MOVER_G = [11, 15, 19, 23, 27, 31, 35]
|
||||||
|
MOVER_B = [12, 16, 20, 24, 28, 32, 36]
|
||||||
|
FOCUS_DEFAULT = 70
|
||||||
|
CANS = list(range(8))
|
||||||
|
|
||||||
|
PALETTE: dict[str, tuple[int, int, int]] = {
|
||||||
|
"Amber": (255, 90, 0),
|
||||||
|
"Pink": (255, 50, 160),
|
||||||
|
"HotBlue": (round(0.30 * 255), 0, 255), # 30% red, 100% blue
|
||||||
|
"Red": (255, 0, 0),
|
||||||
|
"Green": (0, 255, 0),
|
||||||
|
"Blue": (0, 0, 255),
|
||||||
|
"Orange": (255, 127, 0),
|
||||||
|
"Yellow": (255, 255, 0),
|
||||||
|
"Purple": (127, 0, 255),
|
||||||
|
}
|
||||||
|
|
||||||
|
CAN_ODD = [0, 2, 4, 6] # #1,3,5,7
|
||||||
|
CAN_EVEN = [1, 3, 5, 7] # #2,4,6,8
|
||||||
|
MOVER_SOLIDS = [
|
||||||
|
"Amber",
|
||||||
|
"Pink",
|
||||||
|
"Red",
|
||||||
|
"Green",
|
||||||
|
"Blue",
|
||||||
|
"Orange",
|
||||||
|
"Yellow",
|
||||||
|
"Purple",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Pad display values. M2 (left) is hung 180°, so its pad pan is reversed:
|
||||||
|
# DMX pan = 255 - pad pan. M1 pad pan is DMX pan.
|
||||||
|
PAD_PAN = {M2: 181, M1: 80}
|
||||||
|
PAD_TILT = {M2: 145, M1: 161}
|
||||||
|
POSITION_FADE_MS = 2000
|
||||||
|
# name, M1 (pan, tilt), M2 (pan, tilt), button colour
|
||||||
|
# Same DMX pan = split (180° hang). Cross left was mirrored (108) = 180° out.
|
||||||
|
# Now = live pad aim (M2 pad 181/145 → DMX 74/145, M1 pad 80/161).
|
||||||
|
POSITIONS: list[tuple[str, tuple[int, int], tuple[int, int], str]] = [
|
||||||
|
("Now", (80, 161), (74, 145), "4278236360"),
|
||||||
|
("Here", (179, 0), (179, 0), "4282664004"),
|
||||||
|
("Down", (179, 36), (179, 36), "4284900966"),
|
||||||
|
("Mid", (164, 18), (144, 18), "4286611584"),
|
||||||
|
("Cross", (140, 26), (140, 26), "4281545523"),
|
||||||
|
("Out", (200, 22), (200, 22), "4279900698"),
|
||||||
|
]
|
||||||
|
POSITION_FUNC0 = 100
|
||||||
|
PADS_FUNC = POSITION_FUNC0 + len(POSITIONS)
|
||||||
|
PADS_BG = "4282800750" # #465A6E pad grey-blue
|
||||||
|
FIGURE8_FLOOR_FUNC = 110
|
||||||
|
FIGURE8_WALL_FUNC = 111
|
||||||
|
FIGURE8_MS = 12000
|
||||||
|
FIGURE8_FLOOR_BG = "4282664004"
|
||||||
|
FIGURE8_WALL_BG = "4286611584"
|
||||||
|
LOOK_PAIRS: list[tuple[str, str | None]] = [
|
||||||
|
("Amber", None),
|
||||||
|
("Pink", "Amber"),
|
||||||
|
("Pink", "HotBlue"),
|
||||||
|
("Red", "Green"),
|
||||||
|
("Blue", "Green"),
|
||||||
|
("Blue", "Red"),
|
||||||
|
("Orange", "Blue"),
|
||||||
|
("Yellow", "Purple"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def color_label(name: str) -> str:
|
||||||
|
return "Blue" if name == "HotBlue" else name
|
||||||
|
|
||||||
|
|
||||||
|
def qlc_color(r: int, g: int, b: int) -> str:
|
||||||
|
return str((0xFF << 24) | (r << 16) | (g << 8) | b)
|
||||||
|
|
||||||
|
|
||||||
|
def mix_color(
|
||||||
|
a: tuple[int, int, int], b: tuple[int, int, int]
|
||||||
|
) -> tuple[int, int, int]:
|
||||||
|
return ((a[0] + b[0]) // 2, (a[1] + b[1]) // 2, (a[2] + b[2]) // 2)
|
||||||
|
|
||||||
|
RGB = [
|
||||||
|
("R", 2, MOVER_R, "4294901760", "Red"),
|
||||||
|
("G", 3, MOVER_G, "4278255360", "Green"),
|
||||||
|
("B", 4, MOVER_B, "4278190335", "Blue"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def appearance(
|
||||||
|
fg: str = "Default",
|
||||||
|
bg: str = "Default",
|
||||||
|
frame: str = "Sunken",
|
||||||
|
) -> str:
|
||||||
|
return f""" <Appearance>
|
||||||
|
<FrameStyle>{frame}</FrameStyle>
|
||||||
|
<ForegroundColor>{fg}</ForegroundColor>
|
||||||
|
<BackgroundColor>{bg}</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>"""
|
||||||
|
|
||||||
|
|
||||||
|
def slider(
|
||||||
|
wid: int,
|
||||||
|
caption: str,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
w: int,
|
||||||
|
h: int,
|
||||||
|
channels: list[tuple[int, int]],
|
||||||
|
*,
|
||||||
|
value: int = 0,
|
||||||
|
fg: str = "Default",
|
||||||
|
cng: str = "None",
|
||||||
|
inverted: bool = False,
|
||||||
|
) -> str:
|
||||||
|
ch_xml = "\n".join(
|
||||||
|
f' <Channel Fixture="{fid}">{ch}</Channel>' for fid, ch in channels
|
||||||
|
)
|
||||||
|
inv = "true" if inverted else "false"
|
||||||
|
return f""" <Slider Caption="{caption}" ID="{wid}" WidgetStyle="Slider" InvertedAppearance="{inv}">
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
{appearance(fg=fg)}
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="{cng}" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="{value}">
|
||||||
|
{ch_xml}
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>"""
|
||||||
|
|
||||||
|
|
||||||
|
def xypad(
|
||||||
|
wid: int,
|
||||||
|
caption: str,
|
||||||
|
fid: int,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
w: int,
|
||||||
|
h: int,
|
||||||
|
*,
|
||||||
|
reverse_pan: bool = False,
|
||||||
|
reverse_tilt: bool = False,
|
||||||
|
pan: int = 128,
|
||||||
|
tilt: int = 128,
|
||||||
|
) -> str:
|
||||||
|
pan_rev = "True" if reverse_pan else "False"
|
||||||
|
tilt_rev = "True" if reverse_tilt else "False"
|
||||||
|
return f""" <XYPad Caption="{caption}" ID="{wid}" InvertedAppearance="0">
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
{appearance()}
|
||||||
|
<Fixture ID="{fid}" Head="0">
|
||||||
|
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="{pan_rev}"/>
|
||||||
|
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="{tilt_rev}"/>
|
||||||
|
</Fixture>
|
||||||
|
<Window hMin="0" hMax="255" vMin="0" vMax="255"/>
|
||||||
|
<Pan Position="{pan}"/>
|
||||||
|
<Tilt Position="{tilt}"/>
|
||||||
|
</XYPad>"""
|
||||||
|
|
||||||
|
|
||||||
|
def label_frame(wid: int, caption: str, x: int, y: int, w: int, h: int) -> str:
|
||||||
|
return f""" <Frame Caption="{caption}" ID="{wid}">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
<AllowChildren>True</AllowChildren>
|
||||||
|
<AllowResize>True</AllowResize>
|
||||||
|
<ShowHeader>True</ShowHeader>
|
||||||
|
<ShowEnableButton>False</ShowEnableButton>
|
||||||
|
<ShowIntensityButton>False</ShowIntensityButton>
|
||||||
|
<Mixing>False</Mixing>
|
||||||
|
</Frame>"""
|
||||||
|
|
||||||
|
|
||||||
|
def button(
|
||||||
|
wid: int,
|
||||||
|
caption: str,
|
||||||
|
func_id: int,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
w: int,
|
||||||
|
h: int,
|
||||||
|
bg: str,
|
||||||
|
fg: str = "4294967295",
|
||||||
|
*,
|
||||||
|
indent: str = " ",
|
||||||
|
) -> str:
|
||||||
|
inner = indent + " "
|
||||||
|
return f"""{indent}<Button Caption="{caption}" ID="{wid}" Icon="">
|
||||||
|
{inner}<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
{inner}<Appearance>
|
||||||
|
{inner} <FrameStyle>None</FrameStyle>
|
||||||
|
{inner} <ForegroundColor>{fg}</ForegroundColor>
|
||||||
|
{inner} <BackgroundColor>{bg}</BackgroundColor>
|
||||||
|
{inner} <BackgroundImage>None</BackgroundImage>
|
||||||
|
{inner} <Font>Default</Font>
|
||||||
|
{inner}</Appearance>
|
||||||
|
{inner}<Function ID="{func_id}"/>
|
||||||
|
{inner}<Action>Toggle</Action>
|
||||||
|
{inner}<Intensity Adjust="False">100</Intensity>
|
||||||
|
{indent}</Button>"""
|
||||||
|
|
||||||
|
|
||||||
|
def solo_frame(wid: int, caption: str, x: int, y: int, w: int, h: int, children: str) -> str:
|
||||||
|
return f""" <SoloFrame Caption="{caption}" ID="{wid}">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
<AllowChildren>True</AllowChildren>
|
||||||
|
<AllowResize>True</AllowResize>
|
||||||
|
<ShowHeader>True</ShowHeader>
|
||||||
|
<ShowEnableButton>False</ShowEnableButton>
|
||||||
|
<Mixing>False</Mixing>
|
||||||
|
{children}
|
||||||
|
</SoloFrame>"""
|
||||||
|
|
||||||
|
|
||||||
|
def can_fixture_val(fid: int, r: int, g: int, b: int) -> str:
|
||||||
|
# Dimmer is owned by the Can Bright slider (HTP).
|
||||||
|
return (
|
||||||
|
f' <FixtureVal ID="{fid}">'
|
||||||
|
f"1,0,2,{r},3,{g},4,{b},5,0,6,0,7,0"
|
||||||
|
f"</FixtureVal>"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def mover_fixture_val(fid: int, r: int, g: int, b: int) -> str:
|
||||||
|
# Dimmer is owned by the Mover Bright slider (HTP).
|
||||||
|
parts: list[int] = []
|
||||||
|
for i in range(7):
|
||||||
|
base = 10 + i * 4
|
||||||
|
parts.extend([base, r, base + 1, g, base + 2, b, base + 3, 0])
|
||||||
|
return f' <FixtureVal ID="{fid}">{",".join(str(x) for x in parts)}</FixtureVal>'
|
||||||
|
|
||||||
|
|
||||||
|
def look_scene_xml(
|
||||||
|
func_id: int,
|
||||||
|
name: str,
|
||||||
|
can_colors: dict[int, tuple[int, int, int]] | None = None,
|
||||||
|
mover_colors: dict[int, tuple[int, int, int]] | None = None,
|
||||||
|
) -> str:
|
||||||
|
vals: list[str] = []
|
||||||
|
if can_colors:
|
||||||
|
vals += [can_fixture_val(fid, *rgb) for fid, rgb in can_colors.items()]
|
||||||
|
if mover_colors:
|
||||||
|
vals += [mover_fixture_val(fid, *rgb) for fid, rgb in mover_colors.items()]
|
||||||
|
return f""" <Function ID="{func_id}" Type="Scene" Name="{name}">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
{chr(10).join(vals)}
|
||||||
|
</Function>"""
|
||||||
|
|
||||||
|
|
||||||
|
def look_caption(kind: str, left_n: str, right_n: str | None) -> str:
|
||||||
|
ll, rl = color_label(left_n), color_label(right_n or left_n)
|
||||||
|
if right_n is None:
|
||||||
|
return ll
|
||||||
|
if kind == "cans":
|
||||||
|
return f"1-4 {ll} 5-8 {rl}"
|
||||||
|
return f"Odd {ll} Even {rl}"
|
||||||
|
|
||||||
|
|
||||||
|
def look_values(
|
||||||
|
kind: str, left: tuple[int, int, int], right: tuple[int, int, int]
|
||||||
|
) -> tuple[dict[int, tuple[int, int, int]] | None, dict[int, tuple[int, int, int]] | None]:
|
||||||
|
if kind == "cans":
|
||||||
|
return {**{i: left for i in range(4)}, **{i: right for i in range(4, 8)}}, None
|
||||||
|
if kind == "cans_oe":
|
||||||
|
return {**{i: left for i in CAN_ODD}, **{i: right for i in CAN_EVEN}}, None
|
||||||
|
raise ValueError(kind)
|
||||||
|
|
||||||
|
|
||||||
|
def build_looks() -> tuple[str, dict[str, list[tuple[str, int, str]]]]:
|
||||||
|
specs: dict[str, list[tuple[str, int, str]]] = {
|
||||||
|
"cans": [],
|
||||||
|
"movers": [],
|
||||||
|
"cans_oe": [],
|
||||||
|
}
|
||||||
|
scenes: list[str] = []
|
||||||
|
func_id = 0
|
||||||
|
for kind in ("cans", "cans_oe"):
|
||||||
|
for left_n, right_n in LOOK_PAIRS:
|
||||||
|
if kind == "cans_oe" and right_n is None:
|
||||||
|
continue
|
||||||
|
left = PALETTE[left_n]
|
||||||
|
right = PALETTE[right_n] if right_n else left
|
||||||
|
cans, movers = look_values(kind, left, right)
|
||||||
|
if right_n is None:
|
||||||
|
cans = {fid: left for fid in CANS}
|
||||||
|
movers = None
|
||||||
|
ll, rl = color_label(left_n), color_label(right_n or left_n)
|
||||||
|
name = f"{kind} {ll}" if right_n is None else f"{kind} {ll} {rl}"
|
||||||
|
scenes.append(look_scene_xml(func_id, name, cans, movers))
|
||||||
|
bg = qlc_color(*left) if right_n is None else qlc_color(*mix_color(left, right))
|
||||||
|
specs[kind].append((look_caption(kind, left_n, right_n), func_id, bg))
|
||||||
|
func_id += 1
|
||||||
|
for color_n in MOVER_SOLIDS:
|
||||||
|
rgb = PALETTE[color_n]
|
||||||
|
label = color_label(color_n)
|
||||||
|
scenes.append(
|
||||||
|
look_scene_xml(
|
||||||
|
func_id,
|
||||||
|
f"movers {label}",
|
||||||
|
mover_colors={M1: rgb, M2: rgb},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
specs["movers"].append((label, func_id, qlc_color(*rgb)))
|
||||||
|
func_id += 1
|
||||||
|
return "\n".join(scenes), specs
|
||||||
|
|
||||||
|
|
||||||
|
def look_scenes_xml() -> str:
|
||||||
|
xml, _ = build_looks()
|
||||||
|
return xml
|
||||||
|
|
||||||
|
|
||||||
|
def position_scene_xml() -> str:
|
||||||
|
blocks = [
|
||||||
|
f""" <Function ID="{PADS_FUNC}" Type="Scene" Name="Mover Pads">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
</Function>"""
|
||||||
|
]
|
||||||
|
for i, (name, m1, m2, _bg) in enumerate(POSITIONS):
|
||||||
|
poses = {M1: m1, M2: m2}
|
||||||
|
vals = []
|
||||||
|
for fid in (M1, M2):
|
||||||
|
pan, tilt = poses[fid]
|
||||||
|
vals.append(
|
||||||
|
f' <FixtureVal ID="{fid}">0,{pan},1,0,2,{tilt},3,0</FixtureVal>'
|
||||||
|
)
|
||||||
|
blocks.append(
|
||||||
|
f""" <Function ID="{POSITION_FUNC0 + i}" Type="Scene" Name="Mover {name}">
|
||||||
|
<Speed FadeIn="{POSITION_FADE_MS}" FadeOut="0" Duration="{POSITION_FADE_MS}"/>
|
||||||
|
{chr(10).join(vals)}
|
||||||
|
</Function>"""
|
||||||
|
)
|
||||||
|
return "\n".join(blocks)
|
||||||
|
|
||||||
|
|
||||||
|
def position_button_specs() -> list[tuple[str, int, str]]:
|
||||||
|
return (
|
||||||
|
[("Pads", PADS_FUNC, PADS_BG)]
|
||||||
|
+ [
|
||||||
|
(name, POSITION_FUNC0 + i, bg)
|
||||||
|
for i, (name, _m1, _m2, bg) in enumerate(POSITIONS)
|
||||||
|
]
|
||||||
|
+ [
|
||||||
|
("Floor 8", FIGURE8_FLOOR_FUNC, FIGURE8_FLOOR_BG),
|
||||||
|
("Wall 8", FIGURE8_WALL_FUNC, FIGURE8_WALL_BG),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def figure8_floor_center() -> tuple[int, int]:
|
||||||
|
"""Now is the live floor aim; average both heads so the 8 stays on the ground."""
|
||||||
|
now = next((m1, m2) for name, m1, m2, _bg in POSITIONS if name == "Now")
|
||||||
|
pans = [now[0][0], now[1][0]]
|
||||||
|
tilts = [now[0][1], now[1][1]]
|
||||||
|
return (pans[0] + pans[1]) // 2, (tilts[0] + tilts[1]) // 2
|
||||||
|
|
||||||
|
|
||||||
|
def figure8_wall_bounds() -> tuple[int, int, int, int]:
|
||||||
|
"""Pan/tilt centre and amplitude covering Here–Out (the wall looks)."""
|
||||||
|
pans: list[int] = []
|
||||||
|
tilts: list[int] = []
|
||||||
|
for name, m1, m2, _bg in POSITIONS:
|
||||||
|
if name == "Now":
|
||||||
|
continue
|
||||||
|
for pan, tilt in (m1, m2):
|
||||||
|
pans.append(pan)
|
||||||
|
tilts.append(tilt)
|
||||||
|
p0, p1 = min(pans), max(pans)
|
||||||
|
t0, t1 = min(tilts), max(tilts)
|
||||||
|
return (p0 + p1) // 2, (t0 + t1) // 2, (p1 - p0) // 2, (t1 - t0) // 2
|
||||||
|
|
||||||
|
|
||||||
|
def figure8_efx_block(
|
||||||
|
func_id: int,
|
||||||
|
name: str,
|
||||||
|
width: int,
|
||||||
|
height: int,
|
||||||
|
rotation: int,
|
||||||
|
pan_c: int,
|
||||||
|
tilt_c: int,
|
||||||
|
) -> str:
|
||||||
|
fixtures = "\n".join(
|
||||||
|
f""" <Fixture>
|
||||||
|
<ID>{fid}</ID>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<Intensity>255</Intensity>
|
||||||
|
</Fixture>"""
|
||||||
|
for fid in (M1, M2)
|
||||||
|
)
|
||||||
|
return f""" <Function ID="{func_id}" Type="EFX" Name="{name}">
|
||||||
|
{fixtures}
|
||||||
|
<PropagationMode>Parallel</PropagationMode>
|
||||||
|
<Speed Duration="{FIGURE8_MS}" FadeOut="0" FadeIn="0"/>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>Loop</RunOrder>
|
||||||
|
<Algorithm>Eight</Algorithm>
|
||||||
|
<Width>{width}</Width>
|
||||||
|
<Height>{height}</Height>
|
||||||
|
<Rotation>{rotation}</Rotation>
|
||||||
|
<Axis Name="X">
|
||||||
|
<Offset>{pan_c}</Offset>
|
||||||
|
<Frequency>1</Frequency>
|
||||||
|
<Phase>0</Phase>
|
||||||
|
</Axis>
|
||||||
|
<Axis Name="Y">
|
||||||
|
<Offset>{tilt_c}</Offset>
|
||||||
|
<Frequency>1</Frequency>
|
||||||
|
<Phase>0</Phase>
|
||||||
|
</Axis>
|
||||||
|
</Function>"""
|
||||||
|
|
||||||
|
|
||||||
|
def figure8_efx_xml() -> str:
|
||||||
|
floor_pan, floor_tilt = figure8_floor_center()
|
||||||
|
wall_pan, wall_tilt, wall_pan_amp, wall_tilt_amp = figure8_wall_bounds()
|
||||||
|
# Floor 8: around Now, tilt stays on the ground. Rotation 90 = upright 8.
|
||||||
|
# Wall 8: Here–Out box (tilt 0–36). Rotation 0 = 8 across the wall.
|
||||||
|
return "\n".join(
|
||||||
|
[
|
||||||
|
figure8_efx_block(
|
||||||
|
FIGURE8_FLOOR_FUNC,
|
||||||
|
"Figure of 8 Floor",
|
||||||
|
16,
|
||||||
|
18,
|
||||||
|
90,
|
||||||
|
floor_pan,
|
||||||
|
floor_tilt,
|
||||||
|
),
|
||||||
|
figure8_efx_block(
|
||||||
|
FIGURE8_WALL_FUNC,
|
||||||
|
"Figure of 8 Walls",
|
||||||
|
wall_pan_amp,
|
||||||
|
wall_tilt_amp,
|
||||||
|
0,
|
||||||
|
wall_pan,
|
||||||
|
wall_tilt,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def fixture_xml() -> str:
|
||||||
|
parts = []
|
||||||
|
for i in range(8):
|
||||||
|
parts.append(
|
||||||
|
f""" <Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>{i}</ID>
|
||||||
|
<Name>BCC145 #{i + 1}</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>{87 + i * 8}</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>"""
|
||||||
|
)
|
||||||
|
for i, addr in enumerate((0, 44)):
|
||||||
|
parts.append(
|
||||||
|
f""" <Fixture>
|
||||||
|
<Manufacturer>Small Eye 7</Manufacturer>
|
||||||
|
<Model>Mover</Model>
|
||||||
|
<Mode>43 Channel</Mode>
|
||||||
|
<ID>{8 + i}</ID>
|
||||||
|
<Name>Small Eye 7 #{i + 1}</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>{addr}</Address>
|
||||||
|
<Channels>43</Channels>
|
||||||
|
</Fixture>"""
|
||||||
|
)
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def fixture_groups_xml() -> str:
|
||||||
|
def heads(fids: list[int]) -> str:
|
||||||
|
return "\n".join(
|
||||||
|
f' <Head X="{i}" Y="0" Fixture="{fid}">0</Head>'
|
||||||
|
for i, fid in enumerate(fids)
|
||||||
|
)
|
||||||
|
|
||||||
|
return f""" <FixtureGroup ID="0">
|
||||||
|
<Name>Cans 1-2</Name>
|
||||||
|
<Size X="2" Y="1"/>
|
||||||
|
{heads(GROUP_L)}
|
||||||
|
</FixtureGroup>
|
||||||
|
<FixtureGroup ID="1">
|
||||||
|
<Name>Cans 3-6</Name>
|
||||||
|
<Size X="4" Y="1"/>
|
||||||
|
{heads(GROUP_C)}
|
||||||
|
</FixtureGroup>
|
||||||
|
<FixtureGroup ID="2">
|
||||||
|
<Name>Cans 7-8</Name>
|
||||||
|
<Size X="2" Y="1"/>
|
||||||
|
{heads(GROUP_R)}
|
||||||
|
</FixtureGroup>
|
||||||
|
<FixtureGroup ID="3">
|
||||||
|
<Name>Small Eye Movers</Name>
|
||||||
|
<Size X="2" Y="1"/>
|
||||||
|
<Head X="0" Y="0" Fixture="8">0</Head>
|
||||||
|
<Head X="1" Y="0" Fixture="9">0</Head>
|
||||||
|
</FixtureGroup>"""
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
pad_w, pad_h = 240, 240
|
||||||
|
sl_w, sl_h = 44, 240
|
||||||
|
gap = 8
|
||||||
|
block_gap = 28
|
||||||
|
|
||||||
|
widgets: list[str] = []
|
||||||
|
wid = 0
|
||||||
|
max_x = 0
|
||||||
|
max_y = 0
|
||||||
|
|
||||||
|
def place_slider(
|
||||||
|
caption, x, y, w, h, channels, value=0, fg="Default", cng="None", inverted=False
|
||||||
|
):
|
||||||
|
nonlocal wid, max_x, max_y
|
||||||
|
widgets.append(
|
||||||
|
slider(
|
||||||
|
wid,
|
||||||
|
caption,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
channels,
|
||||||
|
value=value,
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
inverted=inverted,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
wid += 1
|
||||||
|
max_x = max(max_x, x + w)
|
||||||
|
max_y = max(max_y, y + h)
|
||||||
|
|
||||||
|
def place_rgb_block(prefix: str, x: int, y: int, dim_chs, rgb_chs_for):
|
||||||
|
"""Dim + R G B. rgb_chs_for(name, can_ch, mover_chs) -> channel list."""
|
||||||
|
place_slider(
|
||||||
|
f"{prefix} Dim", x, y, sl_w, sl_h, dim_chs, 0, "4294967295"
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
for name, can_ch, mover_chs, fg, cng in RGB:
|
||||||
|
place_slider(
|
||||||
|
f"{prefix} {name}",
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
rgb_chs_for(name, can_ch, mover_chs),
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
return x
|
||||||
|
|
||||||
|
def place_mover(prefix: str, fid: int, x: int, y: int, *, reverse_pan: bool = False) -> int:
|
||||||
|
nonlocal wid, max_y
|
||||||
|
widgets.append(
|
||||||
|
xypad(
|
||||||
|
wid,
|
||||||
|
f"{prefix} Position",
|
||||||
|
fid,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
pad_w,
|
||||||
|
pad_h,
|
||||||
|
reverse_pan=reverse_pan,
|
||||||
|
pan=PAD_PAN[fid],
|
||||||
|
tilt=PAD_TILT[fid],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
wid += 1
|
||||||
|
max_y = max(max_y, y + pad_h)
|
||||||
|
return x + pad_w + gap
|
||||||
|
|
||||||
|
def place_looks(
|
||||||
|
title: str,
|
||||||
|
looks: list[tuple[str, int, str]],
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
*,
|
||||||
|
cols: int = 2,
|
||||||
|
btn_w: int = 156,
|
||||||
|
) -> int:
|
||||||
|
nonlocal wid, max_x, max_y
|
||||||
|
header_h = 28
|
||||||
|
pad = 4
|
||||||
|
gap_x, gap_y = 6, 6
|
||||||
|
n = len(looks)
|
||||||
|
cols = max(1, min(cols, n))
|
||||||
|
rows = max(1, (n + cols - 1) // cols)
|
||||||
|
frame_w = pad * 2 + cols * btn_w + (cols - 1) * gap_x
|
||||||
|
frame_h = header_h + sl_h
|
||||||
|
inner_h = sl_h - pad
|
||||||
|
btn_h = (inner_h - gap_y * (rows - 1)) // rows
|
||||||
|
look_btns = []
|
||||||
|
frame_id = wid
|
||||||
|
wid += 1
|
||||||
|
for i, (caption, func_id, bg) in enumerate(looks):
|
||||||
|
col, row = i % cols, i // cols
|
||||||
|
look_btns.append(
|
||||||
|
button(
|
||||||
|
wid,
|
||||||
|
caption,
|
||||||
|
func_id,
|
||||||
|
pad + col * (btn_w + gap_x),
|
||||||
|
header_h + pad + row * (btn_h + gap_y),
|
||||||
|
btn_w,
|
||||||
|
btn_h,
|
||||||
|
bg,
|
||||||
|
indent=" ",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
wid += 1
|
||||||
|
widgets.append(
|
||||||
|
solo_frame(
|
||||||
|
frame_id,
|
||||||
|
title,
|
||||||
|
x,
|
||||||
|
y - header_h,
|
||||||
|
frame_w,
|
||||||
|
frame_h,
|
||||||
|
"\n".join(look_btns),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
max_x = max(max_x, x + frame_w)
|
||||||
|
max_y = max(max_y, y - header_h + frame_h)
|
||||||
|
return x + frame_w
|
||||||
|
|
||||||
|
_, look_specs = build_looks()
|
||||||
|
|
||||||
|
y0 = 28
|
||||||
|
x = 10
|
||||||
|
# M2 on the left, M1 on the right. Left unit is hung opposite, so pan is reversed.
|
||||||
|
x = place_mover("M2", M2, x, y0, reverse_pan=True)
|
||||||
|
x += block_gap
|
||||||
|
x = place_mover("M1", M1, x, y0)
|
||||||
|
x += block_gap
|
||||||
|
place_slider(
|
||||||
|
"M Bright",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(M1, MOVER_DIM), (M2, MOVER_DIM)],
|
||||||
|
255,
|
||||||
|
"4294967295",
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
place_slider(
|
||||||
|
"M Focus",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(M1, MOVER_FOCUS), (M2, MOVER_FOCUS)],
|
||||||
|
FOCUS_DEFAULT,
|
||||||
|
"4294902015",
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
place_slider(
|
||||||
|
"Speed",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(M1, MOVER_SPEED), (M2, MOVER_SPEED)],
|
||||||
|
0,
|
||||||
|
"4294967295",
|
||||||
|
inverted=True,
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
for name, _can_ch, mover_chs, fg, cng in RGB:
|
||||||
|
place_slider(
|
||||||
|
f"M {name}",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(fid, c) for fid in (M1, M2) for c in mover_chs],
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
x += block_gap - 2
|
||||||
|
x = place_looks(
|
||||||
|
"Position",
|
||||||
|
position_button_specs(),
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
cols=2,
|
||||||
|
btn_w=72,
|
||||||
|
)
|
||||||
|
x += block_gap
|
||||||
|
x = place_looks("Movers", look_specs["movers"], x, y0)
|
||||||
|
|
||||||
|
y1 = y0 + pad_h + 40
|
||||||
|
x = 10
|
||||||
|
groups = [
|
||||||
|
("1-2", GROUP_L),
|
||||||
|
("3-6", GROUP_C),
|
||||||
|
("7-8", GROUP_R),
|
||||||
|
]
|
||||||
|
for label, fids in groups:
|
||||||
|
block_w = 4 * sl_w + 3 * 2
|
||||||
|
widgets.append(label_frame(wid, f"Cans {label}", x, y1 - 28, block_w, 24))
|
||||||
|
wid += 1
|
||||||
|
x = place_rgb_block(
|
||||||
|
label,
|
||||||
|
x,
|
||||||
|
y1,
|
||||||
|
[(f, 0) for f in fids],
|
||||||
|
lambda _n, can_ch, _m, fids=fids: [(f, can_ch) for f in fids],
|
||||||
|
)
|
||||||
|
x += block_gap
|
||||||
|
|
||||||
|
place_slider(
|
||||||
|
"C Bright",
|
||||||
|
x,
|
||||||
|
y1,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(f, 0) for f in CANS],
|
||||||
|
255,
|
||||||
|
"4294967295",
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
place_slider(
|
||||||
|
"C Color",
|
||||||
|
x,
|
||||||
|
y1,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(f, ch) for f in CANS for ch in (2, 3, 4)],
|
||||||
|
0,
|
||||||
|
"4294967295",
|
||||||
|
"RGB",
|
||||||
|
)
|
||||||
|
x += sl_w + block_gap
|
||||||
|
x = place_looks("Cans", look_specs["cans"], x, y1)
|
||||||
|
x += block_gap
|
||||||
|
place_looks("Cans Odd/Even", look_specs["cans_oe"], x, y1)
|
||||||
|
|
||||||
|
total_w = max_x + 16
|
||||||
|
total_h = max_y + 16
|
||||||
|
|
||||||
|
qxw = f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Workspace>
|
||||||
|
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Engine>
|
||||||
|
<InputOutputMap>
|
||||||
|
<Universe Name="Universe 1" ID="0">
|
||||||
|
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
|
||||||
|
<PluginParameters outputIP="192.168.1.228" outputUni="0"/>
|
||||||
|
</Output>
|
||||||
|
</Universe>
|
||||||
|
<Universe Name="Universe 2" ID="1"/>
|
||||||
|
<Universe Name="Universe 3" ID="2"/>
|
||||||
|
<Universe Name="Universe 4" ID="3"/>
|
||||||
|
</InputOutputMap>
|
||||||
|
{fixture_xml()}
|
||||||
|
{fixture_groups_xml()}
|
||||||
|
{look_scenes_xml()}
|
||||||
|
{position_scene_xml()}
|
||||||
|
{figure8_efx_xml()}
|
||||||
|
</Engine>
|
||||||
|
<VirtualConsole>
|
||||||
|
<Frame Caption="">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
{"\n".join(widgets)}
|
||||||
|
</Frame>
|
||||||
|
<Properties>
|
||||||
|
<Size Width="{total_w}" Height="{total_h}"/>
|
||||||
|
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
|
||||||
|
</Properties>
|
||||||
|
</VirtualConsole>
|
||||||
|
<SimpleDesk>
|
||||||
|
<Engine/>
|
||||||
|
</SimpleDesk>
|
||||||
|
</Workspace>
|
||||||
|
"""
|
||||||
|
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
OUT.write_text(qxw)
|
||||||
|
print(f"Wrote {OUT} ({total_w}x{total_h}, {wid} widgets)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate shows/simple.qxw — per-mover position + shared and individual RGBW."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
OUT = ROOT / "shows" / "simple.qxw"
|
||||||
|
|
||||||
|
# Fixture IDs match shows/xchc.qxw
|
||||||
|
CANS = list(range(8)) # BCC145 #1–#8
|
||||||
|
M1, M2 = 8, 9
|
||||||
|
MOVERS = [M1, M2]
|
||||||
|
|
||||||
|
# Can 8ch: Dim=0, R=2, G=3, B=4, W=5
|
||||||
|
# Mover 43ch: Center Bright=8; RGBW heads 1–7
|
||||||
|
MOVER_R = [10, 14, 18, 22, 26, 30, 34]
|
||||||
|
MOVER_G = [11, 15, 19, 23, 27, 31, 35]
|
||||||
|
MOVER_B = [12, 16, 20, 24, 28, 32, 36]
|
||||||
|
MOVER_W = [13, 17, 21, 25, 29, 33, 37]
|
||||||
|
|
||||||
|
COLORS = [
|
||||||
|
("R", 2, MOVER_R, "4294901760", "Red"),
|
||||||
|
("G", 3, MOVER_G, "4278255360", "Green"),
|
||||||
|
("B", 4, MOVER_B, "4278190335", "Blue"),
|
||||||
|
("W", 5, MOVER_W, "4294967295", "None"),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def appearance(
|
||||||
|
fg: str = "Default",
|
||||||
|
bg: str = "Default",
|
||||||
|
frame: str = "Sunken",
|
||||||
|
) -> str:
|
||||||
|
return f""" <Appearance>
|
||||||
|
<FrameStyle>{frame}</FrameStyle>
|
||||||
|
<ForegroundColor>{fg}</ForegroundColor>
|
||||||
|
<BackgroundColor>{bg}</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>"""
|
||||||
|
|
||||||
|
|
||||||
|
def slider(
|
||||||
|
wid: int,
|
||||||
|
caption: str,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
w: int,
|
||||||
|
h: int,
|
||||||
|
channels: list[tuple[int, int]],
|
||||||
|
*,
|
||||||
|
value: int = 0,
|
||||||
|
fg: str = "Default",
|
||||||
|
cng: str = "None",
|
||||||
|
) -> str:
|
||||||
|
ch_xml = "\n".join(
|
||||||
|
f' <Channel Fixture="{fid}">{ch}</Channel>' for fid, ch in channels
|
||||||
|
)
|
||||||
|
return f""" <Slider Caption="{caption}" ID="{wid}" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
{appearance(fg=fg)}
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="{cng}" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="{value}">
|
||||||
|
{ch_xml}
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>"""
|
||||||
|
|
||||||
|
|
||||||
|
def xypad(wid: int, caption: str, fid: int, x: int, y: int, w: int, h: int) -> str:
|
||||||
|
return f""" <XYPad Caption="{caption}" ID="{wid}" InvertedAppearance="0">
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
{appearance()}
|
||||||
|
<Fixture ID="{fid}" Head="0">
|
||||||
|
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
</Fixture>
|
||||||
|
<Window hMin="0" hMax="255" vMin="0" vMax="255"/>
|
||||||
|
<Pan Position="128"/>
|
||||||
|
<Tilt Position="128"/>
|
||||||
|
</XYPad>"""
|
||||||
|
|
||||||
|
|
||||||
|
def label_frame(caption: str, x: int, y: int, w: int, h: int) -> str:
|
||||||
|
return f""" <Frame Caption="{caption}">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
<AllowChildren>True</AllowChildren>
|
||||||
|
<AllowResize>True</AllowResize>
|
||||||
|
<ShowHeader>True</ShowHeader>
|
||||||
|
<ShowEnableButton>False</ShowEnableButton>
|
||||||
|
<ShowIntensityButton>False</ShowIntensityButton>
|
||||||
|
<Mixing>False</Mixing>
|
||||||
|
</Frame>"""
|
||||||
|
|
||||||
|
|
||||||
|
def fixture_xml() -> str:
|
||||||
|
parts = []
|
||||||
|
for i in range(8):
|
||||||
|
parts.append(
|
||||||
|
f""" <Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>{i}</ID>
|
||||||
|
<Name>BCC145 #{i + 1}</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>{87 + i * 8}</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>"""
|
||||||
|
)
|
||||||
|
for i, addr in enumerate((0, 44)):
|
||||||
|
parts.append(
|
||||||
|
f""" <Fixture>
|
||||||
|
<Manufacturer>Small Eye 7</Manufacturer>
|
||||||
|
<Model>Mover</Model>
|
||||||
|
<Mode>43 Channel</Mode>
|
||||||
|
<ID>{8 + i}</ID>
|
||||||
|
<Name>Small Eye 7 #{i + 1}</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>{addr}</Address>
|
||||||
|
<Channels>43</Channels>
|
||||||
|
</Fixture>"""
|
||||||
|
)
|
||||||
|
return "\n".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
pad_w, pad_h = 240, 240
|
||||||
|
sl_w, sl_h = 44, 240
|
||||||
|
ind_w, ind_h = 36, 160
|
||||||
|
gap = 8
|
||||||
|
|
||||||
|
widgets: list[str] = []
|
||||||
|
wid = 0
|
||||||
|
max_x = 0
|
||||||
|
max_y = 0
|
||||||
|
|
||||||
|
def place_slider(caption, x, y, w, h, channels, value=0, fg="Default", cng="None"):
|
||||||
|
nonlocal wid, max_x, max_y
|
||||||
|
widgets.append(
|
||||||
|
slider(wid, caption, x, y, w, h, channels, value=value, fg=fg, cng=cng)
|
||||||
|
)
|
||||||
|
wid += 1
|
||||||
|
max_x = max(max_x, x + w)
|
||||||
|
max_y = max(max_y, y + h)
|
||||||
|
|
||||||
|
y0 = 28
|
||||||
|
x = 10
|
||||||
|
widgets.append(xypad(wid, "M1 Position", M1, x, y0, pad_w, pad_h))
|
||||||
|
wid += 1
|
||||||
|
x += pad_w + gap
|
||||||
|
widgets.append(xypad(wid, "M2 Position", M2, x, y0, pad_w, pad_h))
|
||||||
|
wid += 1
|
||||||
|
x += pad_w + gap + 12
|
||||||
|
max_x = max(max_x, x)
|
||||||
|
max_y = max(max_y, y0 + pad_h)
|
||||||
|
|
||||||
|
place_slider("C Dim", x, y0, sl_w, sl_h, [(f, 0) for f in CANS], 255, "4294967295")
|
||||||
|
x += sl_w + 2
|
||||||
|
for name, can_ch, _mover_chs, fg, cng in COLORS:
|
||||||
|
place_slider(
|
||||||
|
f"C {name}",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(f, can_ch) for f in CANS],
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
|
||||||
|
x += 14
|
||||||
|
|
||||||
|
place_slider("M Dim", x, y0, sl_w, sl_h, [(f, 8) for f in MOVERS], 255, "4294967295")
|
||||||
|
x += sl_w + 2
|
||||||
|
for name, _can_ch, mover_chs, fg, cng in COLORS:
|
||||||
|
place_slider(
|
||||||
|
f"M {name}",
|
||||||
|
x,
|
||||||
|
y0,
|
||||||
|
sl_w,
|
||||||
|
sl_h,
|
||||||
|
[(f, c) for f in MOVERS for c in mover_chs],
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
x += sl_w + 2
|
||||||
|
|
||||||
|
y1 = y0 + pad_h + 36
|
||||||
|
x = 10
|
||||||
|
widgets.append(label_frame("Cans individual RGBW", x, y1 - 28, 200, 24))
|
||||||
|
|
||||||
|
for i, fid in enumerate(CANS):
|
||||||
|
col_x = x + i * (4 * (ind_w + 2) + 10)
|
||||||
|
for j, (name, can_ch, _m, fg, cng) in enumerate(COLORS):
|
||||||
|
place_slider(
|
||||||
|
f"{i + 1}{name}",
|
||||||
|
col_x + j * (ind_w + 2),
|
||||||
|
y1,
|
||||||
|
ind_w,
|
||||||
|
ind_h,
|
||||||
|
[(fid, can_ch)],
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
|
||||||
|
mx = x + 8 * (4 * (ind_w + 2) + 10) + 16
|
||||||
|
widgets.append(label_frame("Movers individual RGBW", mx, y1 - 28, 220, 24))
|
||||||
|
for mi, (fid, label) in enumerate(((M1, "M1"), (M2, "M2"))):
|
||||||
|
col_x = mx + mi * (4 * (ind_w + 2) + 14)
|
||||||
|
for j, (name, _can_ch, mover_chs, fg, cng) in enumerate(COLORS):
|
||||||
|
place_slider(
|
||||||
|
f"{label}{name}",
|
||||||
|
col_x + j * (ind_w + 2),
|
||||||
|
y1,
|
||||||
|
ind_w,
|
||||||
|
ind_h,
|
||||||
|
[(fid, c) for c in mover_chs],
|
||||||
|
fg=fg,
|
||||||
|
cng=cng,
|
||||||
|
)
|
||||||
|
|
||||||
|
total_w = max_x + 16
|
||||||
|
total_h = max_y + 16
|
||||||
|
|
||||||
|
qxw = f"""<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Workspace>
|
||||||
|
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Engine>
|
||||||
|
<InputOutputMap>
|
||||||
|
<Universe Name="Universe 1" ID="0">
|
||||||
|
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
|
||||||
|
<PluginParameters outputIP="192.168.1.228" outputUni="0"/>
|
||||||
|
</Output>
|
||||||
|
</Universe>
|
||||||
|
<Universe Name="Universe 2" ID="1"/>
|
||||||
|
<Universe Name="Universe 3" ID="2"/>
|
||||||
|
<Universe Name="Universe 4" ID="3"/>
|
||||||
|
</InputOutputMap>
|
||||||
|
{fixture_xml()}
|
||||||
|
<FixtureGroup ID="0">
|
||||||
|
<Name>BCC145 U</Name>
|
||||||
|
<Size X="8" Y="1"/>
|
||||||
|
<Head X="0" Y="0" Fixture="0">0</Head>
|
||||||
|
<Head X="1" Y="0" Fixture="1">0</Head>
|
||||||
|
<Head X="2" Y="0" Fixture="2">0</Head>
|
||||||
|
<Head X="3" Y="0" Fixture="3">0</Head>
|
||||||
|
<Head X="4" Y="0" Fixture="4">0</Head>
|
||||||
|
<Head X="5" Y="0" Fixture="5">0</Head>
|
||||||
|
<Head X="6" Y="0" Fixture="6">0</Head>
|
||||||
|
<Head X="7" Y="0" Fixture="7">0</Head>
|
||||||
|
</FixtureGroup>
|
||||||
|
<FixtureGroup ID="1">
|
||||||
|
<Name>Small Eye Movers</Name>
|
||||||
|
<Size X="2" Y="1"/>
|
||||||
|
<Head X="0" Y="0" Fixture="8">0</Head>
|
||||||
|
<Head X="1" Y="0" Fixture="9">0</Head>
|
||||||
|
</FixtureGroup>
|
||||||
|
</Engine>
|
||||||
|
<VirtualConsole>
|
||||||
|
<Frame Caption="">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
{"\n".join(widgets)}
|
||||||
|
</Frame>
|
||||||
|
<Properties>
|
||||||
|
<Size Width="{total_w}" Height="{total_h}"/>
|
||||||
|
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
|
||||||
|
</Properties>
|
||||||
|
</VirtualConsole>
|
||||||
|
<SimpleDesk>
|
||||||
|
<Engine/>
|
||||||
|
</SimpleDesk>
|
||||||
|
</Workspace>
|
||||||
|
"""
|
||||||
|
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
OUT.write_text(qxw)
|
||||||
|
print(f"Wrote {OUT} ({total_w}x{total_h}, {wid} widgets)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Merge Patterns + Movers into one SoloFrame and one Speed dial in xchc.qxw."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def btn(
|
||||||
|
widget_id: int,
|
||||||
|
caption: str,
|
||||||
|
func_id: int,
|
||||||
|
x: int,
|
||||||
|
y: int,
|
||||||
|
w: int,
|
||||||
|
h: int,
|
||||||
|
bg: str,
|
||||||
|
fg: str = "4294967295",
|
||||||
|
) -> str:
|
||||||
|
return f""" <Button Caption="{caption}" ID="{widget_id}" Icon="">
|
||||||
|
<WindowState Visible="True" X="{x}" Y="{y}" Width="{w}" Height="{h}"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>{fg}</ForegroundColor>
|
||||||
|
<BackgroundColor>{bg}</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<Function ID="{func_id}"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
</Button>"""
|
||||||
|
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
path = ROOT / "shows" / "xchc.qxw"
|
||||||
|
text = path.read_text()
|
||||||
|
|
||||||
|
# Combined looks: can colour chase + figure-of-8 movement
|
||||||
|
combos = [
|
||||||
|
(101, "Colour + F8", 9, 77),
|
||||||
|
(102, "Rainbow + F8", 18, 77),
|
||||||
|
(103, "OddEven + F8", 22, 77),
|
||||||
|
(104, "Center + F8", 55, 77),
|
||||||
|
(105, "Theater + F8", 67, 77),
|
||||||
|
]
|
||||||
|
combo_xml = []
|
||||||
|
for fid, name, a, b in combos:
|
||||||
|
block = f""" <Function ID="{fid}" Type="Collection" Name="{name}">
|
||||||
|
<Step Number="0">{a}</Step>
|
||||||
|
<Step Number="1">{b}</Step>
|
||||||
|
</Function>
|
||||||
|
"""
|
||||||
|
if f'Function ID="{fid}"' in text:
|
||||||
|
text = re.sub(
|
||||||
|
rf' <Function ID="{fid}"[\s\S]*?</Function>\n',
|
||||||
|
block,
|
||||||
|
text,
|
||||||
|
count=1,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
combo_xml.append(block.rstrip())
|
||||||
|
if combo_xml:
|
||||||
|
text = text.replace(
|
||||||
|
' <Monitor DisplayMode="1"',
|
||||||
|
"\n".join(combo_xml) + "\n <Monitor DisplayMode=\"1\"",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Build unified Show SoloFrame
|
||||||
|
# Row 0: colour / spatial patterns (cans+movers already in scenes)
|
||||||
|
# Row 1: combined flight looks
|
||||||
|
# Row 2: mover-only + exits
|
||||||
|
w, h = 150, 56
|
||||||
|
gap_x, gap_y = 8, 8
|
||||||
|
x0, y0 = 10, 28
|
||||||
|
|
||||||
|
def cell(col, row):
|
||||||
|
return x0 + col * (w + gap_x), y0 + row * (h + gap_y)
|
||||||
|
|
||||||
|
buttons = []
|
||||||
|
# Row 0 — parcans + movers colour/spatial
|
||||||
|
row0 = [
|
||||||
|
(0, "Colour", 9, "4282664004"),
|
||||||
|
(28, "Rainbow", 18, "4280427042"),
|
||||||
|
(37, "Odd Even", 22, "4284752486"),
|
||||||
|
(47, "Scanner", 41, "4292033564"),
|
||||||
|
(48, "Fill", 50, "4278218076"),
|
||||||
|
(49, "Center Out", 55, "4280817043"),
|
||||||
|
]
|
||||||
|
for i, (wid, cap, fid, bg) in enumerate(row0):
|
||||||
|
x, y = cell(i, 0)
|
||||||
|
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
|
||||||
|
|
||||||
|
row1 = [
|
||||||
|
(50, "Pairs", 60, "4294946560", "4278190080"),
|
||||||
|
(51, "Left Right", 63, "4279648704", "4294967295"),
|
||||||
|
(52, "Theater", 67, "4285143962", "4294967295"),
|
||||||
|
(200, "Colour+F8", 101, "4282664004", "4294967295"),
|
||||||
|
(201, "Rainbow+F8", 102, "4280427042", "4294967295"),
|
||||||
|
(202, "Center+F8", 104, "4280817043", "4294967295"),
|
||||||
|
]
|
||||||
|
for i, (wid, cap, fid, bg, fg) in enumerate(row1):
|
||||||
|
x, y = cell(i, 1)
|
||||||
|
buttons.append(btn(wid, cap, fid, x, y, w, h, bg, fg))
|
||||||
|
|
||||||
|
row2 = [
|
||||||
|
(100, "Figure of 8", 77, "4282664004"),
|
||||||
|
(203, "OddEven+F8", 103, "4284752486"),
|
||||||
|
(204, "Theater+F8", 105, "4285143962"),
|
||||||
|
(53, "Collapse In", 68, "4281545523"),
|
||||||
|
(54, "Chase Out", 69, "4284900966"),
|
||||||
|
(55, "Home Fade", 71, "4286611584"),
|
||||||
|
]
|
||||||
|
for i, (wid, cap, fid, bg) in enumerate(row2):
|
||||||
|
x, y = cell(i, 2)
|
||||||
|
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
|
||||||
|
|
||||||
|
# Home Fade for whole stage uses can Home Fade 71; keep mover Home Fade via MIB/Soft BO
|
||||||
|
row3 = [
|
||||||
|
(101, "Ring Collapse", 85, "4281545523"),
|
||||||
|
(114, "Ring Chase", 94, "4284900966"),
|
||||||
|
(116, "Move in Black", 98, "4279900698"),
|
||||||
|
(56, "Soft Blackout", 72, "4278190080"),
|
||||||
|
(38, "Red Test", 32, "4286578688"),
|
||||||
|
]
|
||||||
|
for i, (wid, cap, fid, bg) in enumerate(row3):
|
||||||
|
x, y = cell(i, 3)
|
||||||
|
buttons.append(btn(wid, cap, fid, x, y, w, h, bg))
|
||||||
|
|
||||||
|
frame_w = x0 + 6 * (w + gap_x) + 10
|
||||||
|
frame_h = y0 + 4 * (h + gap_y) + 16
|
||||||
|
show_frame = f""" <SoloFrame Caption="Show">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<WindowState Visible="True" X="10" Y="10" Width="{frame_w}" Height="{frame_h}"/>
|
||||||
|
<AllowChildren>True</AllowChildren>
|
||||||
|
<AllowResize>True</AllowResize>
|
||||||
|
<ShowHeader>True</ShowHeader>
|
||||||
|
<Mixing>False</Mixing>
|
||||||
|
{chr(10).join(buttons)}
|
||||||
|
</SoloFrame>"""
|
||||||
|
|
||||||
|
# Replace Patterns SoloFrame
|
||||||
|
text = re.sub(
|
||||||
|
r' <SoloFrame Caption="Patterns">[\s\S]*?</SoloFrame>',
|
||||||
|
show_frame,
|
||||||
|
text,
|
||||||
|
count=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove Movers SoloFrame (buttons now in Show)
|
||||||
|
text = re.sub(
|
||||||
|
r' <SoloFrame Caption="Movers">[\s\S]*?</SoloFrame>\n',
|
||||||
|
"",
|
||||||
|
text,
|
||||||
|
count=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Merge mover speed targets into main Speed dial; drop Mover Speed dial
|
||||||
|
text = re.sub(
|
||||||
|
r' <SpeedDial Caption="Mover Speed" ID="102">[\s\S]*?</SpeedDial>\n',
|
||||||
|
"",
|
||||||
|
text,
|
||||||
|
count=1,
|
||||||
|
)
|
||||||
|
speed_extra = """ <Function FadeIn="6" FadeOut="0" Duration="6">74</Function>
|
||||||
|
<Function FadeIn="0" FadeOut="0" Duration="6">76</Function>
|
||||||
|
<Function FadeIn="6" FadeOut="0" Duration="6">101</Function>
|
||||||
|
<Function FadeIn="6" FadeOut="0" Duration="6">102</Function>
|
||||||
|
<Function FadeIn="6" FadeOut="0" Duration="6">103</Function>
|
||||||
|
<Function FadeIn="6" FadeOut="0" Duration="6">104</Function>
|
||||||
|
<Function FadeIn="0" FadeOut="0" Duration="6">105</Function>
|
||||||
|
"""
|
||||||
|
if 'Function FadeIn="6" FadeOut="0" Duration="6">74</Function>' not in text:
|
||||||
|
text = text.replace(
|
||||||
|
' <Function FadeIn="0" FadeOut="0" Duration="6">69</Function>\n </SpeedDial>',
|
||||||
|
' <Function FadeIn="0" FadeOut="0" Duration="6">69</Function>\n'
|
||||||
|
+ speed_extra
|
||||||
|
+ " </SpeedDial>",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make Speed dial visible next to Show
|
||||||
|
text = text.replace(
|
||||||
|
'<SpeedDial Caption="Speed" ID="3">\n <WindowState Visible="False" X="720" Y="20" Width="90" Height="250"/>',
|
||||||
|
f'<SpeedDial Caption="Speed" ID="3">\n <WindowState Visible="True" X="{frame_w + 20}" Y="10" Width="100" Height="{frame_h}"/>',
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# All Dim also drives mover dimmers
|
||||||
|
if "<Channel Fixture=\"8\">8</Channel>" not in text.split('Caption="All Dim"', 1)[1][:800]:
|
||||||
|
text = text.replace(
|
||||||
|
""" <Level LowLimit="0" HighLimit="255" Value="174">
|
||||||
|
<Channel Fixture="0">0</Channel>
|
||||||
|
<Channel Fixture="1">0</Channel>
|
||||||
|
<Channel Fixture="2">0</Channel>
|
||||||
|
<Channel Fixture="3">0</Channel>
|
||||||
|
<Channel Fixture="4">0</Channel>
|
||||||
|
<Channel Fixture="5">0</Channel>
|
||||||
|
<Channel Fixture="6">0</Channel>
|
||||||
|
<Channel Fixture="7">0</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="1 R\"""",
|
||||||
|
""" <Level LowLimit="0" HighLimit="255" Value="174">
|
||||||
|
<Channel Fixture="0">0</Channel>
|
||||||
|
<Channel Fixture="1">0</Channel>
|
||||||
|
<Channel Fixture="2">0</Channel>
|
||||||
|
<Channel Fixture="3">0</Channel>
|
||||||
|
<Channel Fixture="4">0</Channel>
|
||||||
|
<Channel Fixture="5">0</Channel>
|
||||||
|
<Channel Fixture="6">0</Channel>
|
||||||
|
<Channel Fixture="7">0</Channel>
|
||||||
|
<Channel Fixture="8">8</Channel>
|
||||||
|
<Channel Fixture="9">8</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="1 R\"""",
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Relabel / place XY pad under Show
|
||||||
|
text = text.replace(
|
||||||
|
'Caption="Mover Position"',
|
||||||
|
'Caption="Position"',
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
text = text.replace(
|
||||||
|
'<XYPad Caption="Position" ID="103" InvertedAppearance="0">\n <WindowState Visible="True" X="720" Y="180" Width="320" Height="320"/>',
|
||||||
|
f'<XYPad Caption="Position" ID="103" InvertedAppearance="0">\n <WindowState Visible="True" X="10" Y="{frame_h + 20}" Width="320" Height="300"/>',
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Shift mover sliders under Show, right of XY pad
|
||||||
|
slider_y = frame_h + 20
|
||||||
|
old_xs = [1050 + i * 46 for i in range(10)]
|
||||||
|
new_xs = [340 + i * 46 for i in range(10)]
|
||||||
|
for ox, nx in zip(old_xs, new_xs):
|
||||||
|
text = text.replace(
|
||||||
|
f'Visible="True" X="{ox}" Y="180" Width="44" Height="320"',
|
||||||
|
f'Visible="True" X="{nx}" Y="{slider_y}" Width="44" Height="300"',
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
|
||||||
|
path.write_text(text)
|
||||||
|
print(f"Unified Show controls in {path}")
|
||||||
|
print(f" SoloFrame {frame_w}x{frame_h} with pattern + F8 combos + exits")
|
||||||
|
print(" One Speed dial; Position pad + mover sliders below")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Workspace>
|
||||||
|
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Engine>
|
||||||
|
<InputOutputMap>
|
||||||
|
<Universe Name="Universe 1" ID="0">
|
||||||
|
<Output Plugin="E1.31" UID="10.1.1.222" Line="1">
|
||||||
|
<PluginParameters UniverseChannels="8" multicast="0" ucastIP="10.1.1.159" universe="1"/>
|
||||||
|
</Output>
|
||||||
|
</Universe>
|
||||||
|
<Universe Name="Universe 2" ID="1"/>
|
||||||
|
<Universe Name="Universe 3" ID="2"/>
|
||||||
|
<Universe Name="Universe 4" ID="3"/>
|
||||||
|
</InputOutputMap>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>0</ID>
|
||||||
|
<Name>BCC145</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>0</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<ChannelsGroup ID="0" Name="Red" Value="0">0,2</ChannelsGroup>
|
||||||
|
<ChannelsGroup ID="1" Name="Green" Value="0">0,3</ChannelsGroup>
|
||||||
|
<ChannelsGroup ID="2" Name="Blue" Value="0">0,4</ChannelsGroup>
|
||||||
|
<ChannelsGroup ID="3" Name="White" Value="0">0,5</ChannelsGroup>
|
||||||
|
<ChannelsGroup ID="4" Name="Dimmer" Value="0">0,0</ChannelsGroup>
|
||||||
|
<!-- 8ch: 0 dimmer, 1 strobe, 2 R, 3 G, 4 B, 5 W, 6 macro (0=RGBW mix), 7 speed -->
|
||||||
|
<Function Type="Scene" Name="Red" ID="0" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,255,3,0,4,0,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Orange" ID="1" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,255,3,127,4,0,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Yellow" ID="2" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,255,3,255,4,0,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Green" ID="3" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,0,3,255,4,0,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Cyan" ID="4" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,0,3,255,4,255,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Blue" ID="5" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,255,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Violet" ID="6" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,127,3,0,4,255,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Magenta" ID="7" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,255,3,0,4,255,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="White" ID="8" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,0,5,255,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Blackout" ID="9" Path="Colors">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Scene" Name="Built-in Gradient" ID="10">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">0,255,1,0,2,0,3,0,4,0,5,0,6,225,7,80</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function Type="Chaser" Name="Color Transition" ID="11">
|
||||||
|
<Speed FadeIn="3000" FadeOut="0" Duration="4000"/>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>Loop</RunOrder>
|
||||||
|
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common"/>
|
||||||
|
<Step Number="0" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">0</Step>
|
||||||
|
<Step Number="1" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">1</Step>
|
||||||
|
<Step Number="2" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">2</Step>
|
||||||
|
<Step Number="3" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">3</Step>
|
||||||
|
<Step Number="4" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">4</Step>
|
||||||
|
<Step Number="5" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">5</Step>
|
||||||
|
<Step Number="6" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">6</Step>
|
||||||
|
<Step Number="7" FadeIn="3000" Hold="1000" FadeOut="0" Duration="4000">7</Step>
|
||||||
|
</Function>
|
||||||
|
</Engine>
|
||||||
|
<VirtualConsole>
|
||||||
|
<Frame Caption="">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<Button Icon="" Caption="Color Transition">
|
||||||
|
<Function ID="11"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="20" Y="20" Width="180" Height="70" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4282664004</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Built-in Gradient">
|
||||||
|
<Function ID="10"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="210" Y="20" Width="180" Height="70" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4280427042</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Blackout">
|
||||||
|
<Function ID="9"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="400" Y="20" Width="120" Height="70" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4278190080</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Red">
|
||||||
|
<Function ID="0"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="20" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4294901760</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Orange">
|
||||||
|
<Function ID="1"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="110" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4278190080</ForegroundColor>
|
||||||
|
<BackgroundColor>4294944000</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Yellow">
|
||||||
|
<Function ID="2"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="200" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4278190080</ForegroundColor>
|
||||||
|
<BackgroundColor>4294967040</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Green">
|
||||||
|
<Function ID="3"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="290" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4278190080</ForegroundColor>
|
||||||
|
<BackgroundColor>4278255360</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Cyan">
|
||||||
|
<Function ID="4"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="380" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4278190080</ForegroundColor>
|
||||||
|
<BackgroundColor>4278255615</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Blue">
|
||||||
|
<Function ID="5"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="470" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4278190335</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Violet">
|
||||||
|
<Function ID="6"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="560" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4286578687</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="Magenta">
|
||||||
|
<Function ID="7"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="650" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4294902015</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button Icon="" Caption="White">
|
||||||
|
<Function ID="8"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="740" Y="110" Width="80" Height="50" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4278190080</ForegroundColor>
|
||||||
|
<BackgroundColor>4294967295</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
</Frame>
|
||||||
|
<Properties>
|
||||||
|
<Size Width="1920" Height="1080"/>
|
||||||
|
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
|
||||||
|
</Properties>
|
||||||
|
</VirtualConsole>
|
||||||
|
<SimpleDesk>
|
||||||
|
<Engine/>
|
||||||
|
</SimpleDesk>
|
||||||
|
</Workspace>
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Workspace>
|
||||||
|
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="SimpleDesk">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Engine>
|
||||||
|
<InputOutputMap>
|
||||||
|
<Universe Name="Universe 1" ID="0">
|
||||||
|
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
|
||||||
|
<PluginParameters outputIP="192.168.1.228"/>
|
||||||
|
</Output>
|
||||||
|
</Universe>
|
||||||
|
<Universe Name="Universe 2" ID="1"/>
|
||||||
|
<Universe Name="Universe 3" ID="2"/>
|
||||||
|
<Universe Name="Universe 4" ID="3"/>
|
||||||
|
</InputOutputMap>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>0</ID>
|
||||||
|
<Name>BCC145 #1</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>71</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>1</ID>
|
||||||
|
<Name>BCC145 #2</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>79</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>2</ID>
|
||||||
|
<Name>BCC145 #3</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>87</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>3</ID>
|
||||||
|
<Name>BCC145 #4</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>95</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>4</ID>
|
||||||
|
<Name>BCC145 #5</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>103</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>5</ID>
|
||||||
|
<Name>BCC145 #6</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>111</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>beamZ</Manufacturer>
|
||||||
|
<Model>BCC145</Model>
|
||||||
|
<Mode>8 Channel</Mode>
|
||||||
|
<ID>6</ID>
|
||||||
|
<Name>BCC145 #7</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>119</Address>
|
||||||
|
<Channels>8</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Monitor DisplayMode="1" ShowLabels="0">
|
||||||
|
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
|
||||||
|
<ChannelStyle>0</ChannelStyle>
|
||||||
|
<ValueStyle>0</ValueStyle>
|
||||||
|
<Grid Width="5" Height="3" Depth="5" Units="0"/>
|
||||||
|
</Monitor>
|
||||||
|
</Engine>
|
||||||
|
<VirtualConsole>
|
||||||
|
<Frame Caption="">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Frame>
|
||||||
|
<Properties>
|
||||||
|
<Size Width="1920" Height="1080"/>
|
||||||
|
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
|
||||||
|
</Properties>
|
||||||
|
</VirtualConsole>
|
||||||
|
<SimpleDesk>
|
||||||
|
<Engine/>
|
||||||
|
</SimpleDesk>
|
||||||
|
</Workspace>
|
||||||
+1473
File diff suppressed because it is too large
Load Diff
+1259
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,487 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Workspace>
|
||||||
|
<Workspace xmlns="http://www.qlcplus.org/Workspace" CurrentWindow="VirtualConsole">
|
||||||
|
<Creator>
|
||||||
|
<Name>Q Light Controller Plus</Name>
|
||||||
|
<Version>4.12.7</Version>
|
||||||
|
<Author>Jimmy</Author>
|
||||||
|
</Creator>
|
||||||
|
<Engine>
|
||||||
|
<InputOutputMap>
|
||||||
|
<Universe Name="Universe 1" ID="0">
|
||||||
|
<Output Plugin="ArtNet" UID="192.168.1.92" Line="7">
|
||||||
|
<PluginParameters outputIP="192.168.1.228" outputUni="0"/>
|
||||||
|
</Output>
|
||||||
|
</Universe>
|
||||||
|
<Universe Name="Universe 2" ID="1"/>
|
||||||
|
<Universe Name="Universe 3" ID="2"/>
|
||||||
|
<Universe Name="Universe 4" ID="3"/>
|
||||||
|
</InputOutputMap>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>Small Eye 7</Manufacturer>
|
||||||
|
<Model>Mover</Model>
|
||||||
|
<Mode>43 Channel</Mode>
|
||||||
|
<ID>0</ID>
|
||||||
|
<Name>Small Eye 7 #1</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>0</Address>
|
||||||
|
<Channels>43</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<Manufacturer>Small Eye 7</Manufacturer>
|
||||||
|
<Model>Mover</Model>
|
||||||
|
<Mode>43 Channel</Mode>
|
||||||
|
<ID>1</ID>
|
||||||
|
<Name>Small Eye 7 #2</Name>
|
||||||
|
<Universe>0</Universe>
|
||||||
|
<Address>44</Address>
|
||||||
|
<Channels>43</Channels>
|
||||||
|
</Fixture>
|
||||||
|
<Function ID="0" Type="Scene" Name="Figure of 8 Look">
|
||||||
|
<Speed FadeIn="0" FadeOut="0" Duration="0"/>
|
||||||
|
<FixtureVal ID="0">4,0,5,0,6,230,7,70,8,255,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0</FixtureVal>
|
||||||
|
<FixtureVal ID="1">4,0,5,0,6,230,7,70,8,255,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function ID="1" Type="Sequence" Name="Figure of 8 Colour Focus" BoundScene="0">
|
||||||
|
<Speed FadeIn="188" FadeOut="0" Duration="188"/>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>Loop</RunOrder>
|
||||||
|
<SpeedModes FadeIn="Common" FadeOut="Common" Duration="Common"/>
|
||||||
|
<Step Number="0" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,14,60,18,60,22,60,26,60,30,60,34,60:1:5,0,6,230,7,70,8,255,10,255,14,60,18,60,22,60,26,60,30,60,34,60</Step>
|
||||||
|
<Step Number="1" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,24,14,60,15,6,18,60,19,6,22,60,23,6,26,60,27,6,30,60,31,6,34,60,35,6:1:5,0,6,230,7,70,8,255,10,255,11,24,14,60,15,6,18,60,19,6,22,60,23,6,26,60,27,6,30,60,31,6,34,60,35,6</Step>
|
||||||
|
<Step Number="2" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,48,14,60,15,11,18,60,19,11,22,60,23,11,26,60,27,11,30,60,31,11,34,60,35,11:1:5,0,6,230,7,70,8,255,10,255,11,48,14,60,15,11,18,60,19,11,22,60,23,11,26,60,27,11,30,60,31,11,34,60,35,11</Step>
|
||||||
|
<Step Number="3" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,72,14,60,15,17,18,60,19,17,22,60,23,17,26,60,27,17,30,60,31,17,34,60,35,17:1:5,0,6,230,7,70,8,255,10,255,11,72,14,60,15,17,18,60,19,17,22,60,23,17,26,60,27,17,30,60,31,17,34,60,35,17</Step>
|
||||||
|
<Step Number="4" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,96,14,60,15,23,18,60,19,23,22,60,23,23,26,60,27,23,30,60,31,23,34,60,35,23:1:5,0,6,230,7,70,8,255,10,255,11,96,14,60,15,23,18,60,19,23,22,60,23,23,26,60,27,23,30,60,31,23,34,60,35,23</Step>
|
||||||
|
<Step Number="5" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,120,14,60,15,28,18,60,19,28,22,60,23,28,26,60,27,28,30,60,31,28,34,60,35,28:1:5,0,6,230,7,70,8,255,10,255,11,120,14,60,15,28,18,60,19,28,22,60,23,28,26,60,27,28,30,60,31,28,34,60,35,28</Step>
|
||||||
|
<Step Number="6" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,143,14,60,15,34,18,60,19,34,22,60,23,34,26,60,27,34,30,60,31,34,34,60,35,34:1:5,0,6,230,7,70,8,255,10,255,11,143,14,60,15,34,18,60,19,34,22,60,23,34,26,60,27,34,30,60,31,34,34,60,35,34</Step>
|
||||||
|
<Step Number="7" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,167,14,60,15,39,18,60,19,39,22,60,23,39,26,60,27,39,30,60,31,39,34,60,35,39:1:5,0,6,230,7,70,8,255,10,255,11,167,14,60,15,39,18,60,19,39,22,60,23,39,26,60,27,39,30,60,31,39,34,60,35,39</Step>
|
||||||
|
<Step Number="8" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,191,14,60,15,45,18,60,19,45,22,60,23,45,26,60,27,45,30,60,31,45,34,60,35,45:1:5,0,6,230,7,70,8,255,10,255,11,191,14,60,15,45,18,60,19,45,22,60,23,45,26,60,27,45,30,60,31,45,34,60,35,45</Step>
|
||||||
|
<Step Number="9" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,215,14,60,15,51,18,60,19,51,22,60,23,51,26,60,27,51,30,60,31,51,34,60,35,51:1:5,0,6,230,7,70,8,255,10,255,11,215,14,60,15,51,18,60,19,51,22,60,23,51,26,60,27,51,30,60,31,51,34,60,35,51</Step>
|
||||||
|
<Step Number="10" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,11,239,14,60,15,56,18,60,19,56,22,60,23,56,26,60,27,56,30,60,31,56,34,60,35,56:1:5,0,6,230,7,70,8,255,10,255,11,239,14,60,15,56,18,60,19,56,22,60,23,56,26,60,27,56,30,60,31,56,34,60,35,56</Step>
|
||||||
|
<Step Number="11" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,247,11,255,14,58,15,60,18,58,19,60,22,58,23,60,26,58,27,60,30,58,31,60,34,58,35,60:1:5,0,6,230,7,70,8,255,10,247,11,255,14,58,15,60,18,58,19,60,22,58,23,60,26,58,27,60,30,58,31,60,34,58,35,60</Step>
|
||||||
|
<Step Number="12" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,223,11,255,14,52,15,60,18,52,19,60,22,52,23,60,26,52,27,60,30,52,31,60,34,52,35,60:1:5,0,6,230,7,70,8,255,10,223,11,255,14,52,15,60,18,52,19,60,22,52,23,60,26,52,27,60,30,52,31,60,34,52,35,60</Step>
|
||||||
|
<Step Number="13" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,199,11,255,14,47,15,60,18,47,19,60,22,47,23,60,26,47,27,60,30,47,31,60,34,47,35,60:1:5,0,6,230,7,70,8,255,10,199,11,255,14,47,15,60,18,47,19,60,22,47,23,60,26,47,27,60,30,47,31,60,34,47,35,60</Step>
|
||||||
|
<Step Number="14" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,175,11,255,14,41,15,60,18,41,19,60,22,41,23,60,26,41,27,60,30,41,31,60,34,41,35,60:1:5,0,6,230,7,70,8,255,10,175,11,255,14,41,15,60,18,41,19,60,22,41,23,60,26,41,27,60,30,41,31,60,34,41,35,60</Step>
|
||||||
|
<Step Number="15" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,151,11,255,14,36,15,60,18,36,19,60,22,36,23,60,26,36,27,60,30,36,31,60,34,36,35,60:1:5,0,6,230,7,70,8,255,10,151,11,255,14,36,15,60,18,36,19,60,22,36,23,60,26,36,27,60,30,36,31,60,34,36,35,60</Step>
|
||||||
|
<Step Number="16" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,128,11,255,14,30,15,60,18,30,19,60,22,30,23,60,26,30,27,60,30,30,31,60,34,30,35,60:1:5,0,6,230,7,70,8,255,10,128,11,255,14,30,15,60,18,30,19,60,22,30,23,60,26,30,27,60,30,30,31,60,34,30,35,60</Step>
|
||||||
|
<Step Number="17" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,104,11,255,14,24,15,60,18,24,19,60,22,24,23,60,26,24,27,60,30,24,31,60,34,24,35,60:1:5,0,6,230,7,70,8,255,10,104,11,255,14,24,15,60,18,24,19,60,22,24,23,60,26,24,27,60,30,24,31,60,34,24,35,60</Step>
|
||||||
|
<Step Number="18" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,80,11,255,14,19,15,60,18,19,19,60,22,19,23,60,26,19,27,60,30,19,31,60,34,19,35,60:1:5,0,6,230,7,70,8,255,10,80,11,255,14,19,15,60,18,19,19,60,22,19,23,60,26,19,27,60,30,19,31,60,34,19,35,60</Step>
|
||||||
|
<Step Number="19" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,56,11,255,14,13,15,60,18,13,19,60,22,13,23,60,26,13,27,60,30,13,31,60,34,13,35,60:1:5,0,6,230,7,70,8,255,10,56,11,255,14,13,15,60,18,13,19,60,22,13,23,60,26,13,27,60,30,13,31,60,34,13,35,60</Step>
|
||||||
|
<Step Number="20" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,32,11,255,14,8,15,60,18,8,19,60,22,8,23,60,26,8,27,60,30,8,31,60,34,8,35,60:1:5,0,6,230,7,70,8,255,10,32,11,255,14,8,15,60,18,8,19,60,22,8,23,60,26,8,27,60,30,8,31,60,34,8,35,60</Step>
|
||||||
|
<Step Number="21" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,8,11,255,14,2,15,60,18,2,19,60,22,2,23,60,26,2,27,60,30,2,31,60,34,2,35,60:1:5,0,6,230,7,70,8,255,10,8,11,255,14,2,15,60,18,2,19,60,22,2,23,60,26,2,27,60,30,2,31,60,34,2,35,60</Step>
|
||||||
|
<Step Number="22" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,16,15,60,16,4,19,60,20,4,23,60,24,4,27,60,28,4,31,60,32,4,35,60,36,4:1:5,0,6,230,7,70,8,255,11,255,12,16,15,60,16,4,19,60,20,4,23,60,24,4,27,60,28,4,31,60,32,4,35,60,36,4</Step>
|
||||||
|
<Step Number="23" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,40,15,60,16,9,19,60,20,9,23,60,24,9,27,60,28,9,31,60,32,9,35,60,36,9:1:5,0,6,230,7,70,8,255,11,255,12,40,15,60,16,9,19,60,20,9,23,60,24,9,27,60,28,9,31,60,32,9,35,60,36,9</Step>
|
||||||
|
<Step Number="24" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,64,15,60,16,15,19,60,20,15,23,60,24,15,27,60,28,15,31,60,32,15,35,60,36,15:1:5,0,6,230,7,70,8,255,11,255,12,64,15,60,16,15,19,60,20,15,23,60,24,15,27,60,28,15,31,60,32,15,35,60,36,15</Step>
|
||||||
|
<Step Number="25" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,88,15,60,16,21,19,60,20,21,23,60,24,21,27,60,28,21,31,60,32,21,35,60,36,21:1:5,0,6,230,7,70,8,255,11,255,12,88,15,60,16,21,19,60,20,21,23,60,24,21,27,60,28,21,31,60,32,21,35,60,36,21</Step>
|
||||||
|
<Step Number="26" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,112,15,60,16,26,19,60,20,26,23,60,24,26,27,60,28,26,31,60,32,26,35,60,36,26:1:5,0,6,230,7,70,8,255,11,255,12,112,15,60,16,26,19,60,20,26,23,60,24,26,27,60,28,26,31,60,32,26,35,60,36,26</Step>
|
||||||
|
<Step Number="27" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,135,15,60,16,32,19,60,20,32,23,60,24,32,27,60,28,32,31,60,32,32,35,60,36,32:1:5,0,6,230,7,70,8,255,11,255,12,135,15,60,16,32,19,60,20,32,23,60,24,32,27,60,28,32,31,60,32,32,35,60,36,32</Step>
|
||||||
|
<Step Number="28" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,159,15,60,16,37,19,60,20,37,23,60,24,37,27,60,28,37,31,60,32,37,35,60,36,37:1:5,0,6,230,7,70,8,255,11,255,12,159,15,60,16,37,19,60,20,37,23,60,24,37,27,60,28,37,31,60,32,37,35,60,36,37</Step>
|
||||||
|
<Step Number="29" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,183,15,60,16,43,19,60,20,43,23,60,24,43,27,60,28,43,31,60,32,43,35,60,36,43:1:5,0,6,230,7,70,8,255,11,255,12,183,15,60,16,43,19,60,20,43,23,60,24,43,27,60,28,43,31,60,32,43,35,60,36,43</Step>
|
||||||
|
<Step Number="30" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,207,15,60,16,49,19,60,20,49,23,60,24,49,27,60,28,49,31,60,32,49,35,60,36,49:1:5,0,6,230,7,70,8,255,11,255,12,207,15,60,16,49,19,60,20,49,23,60,24,49,27,60,28,49,31,60,32,49,35,60,36,49</Step>
|
||||||
|
<Step Number="31" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,231,15,60,16,54,19,60,20,54,23,60,24,54,27,60,28,54,31,60,32,54,35,60,36,54:1:5,0,6,230,7,70,8,255,11,255,12,231,15,60,16,54,19,60,20,54,23,60,24,54,27,60,28,54,31,60,32,54,35,60,36,54</Step>
|
||||||
|
<Step Number="32" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,255,12,255,15,60,16,60,19,60,20,60,23,60,24,60,27,60,28,60,31,60,32,60,35,60,36,60:1:5,0,6,230,7,70,8,255,11,255,12,255,15,60,16,60,19,60,20,60,23,60,24,60,27,60,28,60,31,60,32,60,35,60,36,60</Step>
|
||||||
|
<Step Number="33" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,231,12,255,15,54,16,60,19,54,20,60,23,54,24,60,27,54,28,60,31,54,32,60,35,54,36,60:1:5,0,6,230,7,70,8,255,11,231,12,255,15,54,16,60,19,54,20,60,23,54,24,60,27,54,28,60,31,54,32,60,35,54,36,60</Step>
|
||||||
|
<Step Number="34" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,207,12,255,15,49,16,60,19,49,20,60,23,49,24,60,27,49,28,60,31,49,32,60,35,49,36,60:1:5,0,6,230,7,70,8,255,11,207,12,255,15,49,16,60,19,49,20,60,23,49,24,60,27,49,28,60,31,49,32,60,35,49,36,60</Step>
|
||||||
|
<Step Number="35" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,183,12,255,15,43,16,60,19,43,20,60,23,43,24,60,27,43,28,60,31,43,32,60,35,43,36,60:1:5,0,6,230,7,70,8,255,11,183,12,255,15,43,16,60,19,43,20,60,23,43,24,60,27,43,28,60,31,43,32,60,35,43,36,60</Step>
|
||||||
|
<Step Number="36" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,159,12,255,15,37,16,60,19,37,20,60,23,37,24,60,27,37,28,60,31,37,32,60,35,37,36,60:1:5,0,6,230,7,70,8,255,11,159,12,255,15,37,16,60,19,37,20,60,23,37,24,60,27,37,28,60,31,37,32,60,35,37,36,60</Step>
|
||||||
|
<Step Number="37" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,135,12,255,15,32,16,60,19,32,20,60,23,32,24,60,27,32,28,60,31,32,32,60,35,32,36,60:1:5,0,6,230,7,70,8,255,11,135,12,255,15,32,16,60,19,32,20,60,23,32,24,60,27,32,28,60,31,32,32,60,35,32,36,60</Step>
|
||||||
|
<Step Number="38" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,112,12,255,15,26,16,60,19,26,20,60,23,26,24,60,27,26,28,60,31,26,32,60,35,26,36,60:1:5,0,6,230,7,70,8,255,11,112,12,255,15,26,16,60,19,26,20,60,23,26,24,60,27,26,28,60,31,26,32,60,35,26,36,60</Step>
|
||||||
|
<Step Number="39" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,88,12,255,15,21,16,60,19,21,20,60,23,21,24,60,27,21,28,60,31,21,32,60,35,21,36,60:1:5,0,6,230,7,70,8,255,11,88,12,255,15,21,16,60,19,21,20,60,23,21,24,60,27,21,28,60,31,21,32,60,35,21,36,60</Step>
|
||||||
|
<Step Number="40" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,64,12,255,15,15,16,60,19,15,20,60,23,15,24,60,27,15,28,60,31,15,32,60,35,15,36,60:1:5,0,6,230,7,70,8,255,11,64,12,255,15,15,16,60,19,15,20,60,23,15,24,60,27,15,28,60,31,15,32,60,35,15,36,60</Step>
|
||||||
|
<Step Number="41" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,40,12,255,15,9,16,60,19,9,20,60,23,9,24,60,27,9,28,60,31,9,32,60,35,9,36,60:1:5,0,6,230,7,70,8,255,11,40,12,255,15,9,16,60,19,9,20,60,23,9,24,60,27,9,28,60,31,9,32,60,35,9,36,60</Step>
|
||||||
|
<Step Number="42" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,11,16,12,255,15,4,16,60,19,4,20,60,23,4,24,60,27,4,28,60,31,4,32,60,35,4,36,60:1:5,0,6,230,7,70,8,255,11,16,12,255,15,4,16,60,19,4,20,60,23,4,24,60,27,4,28,60,31,4,32,60,35,4,36,60</Step>
|
||||||
|
<Step Number="43" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,8,12,255,14,2,16,60,18,2,20,60,22,2,24,60,26,2,28,60,30,2,32,60,34,2,36,60:1:5,0,6,230,7,70,8,255,10,8,12,255,14,2,16,60,18,2,20,60,22,2,24,60,26,2,28,60,30,2,32,60,34,2,36,60</Step>
|
||||||
|
<Step Number="44" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,32,12,255,14,8,16,60,18,8,20,60,22,8,24,60,26,8,28,60,30,8,32,60,34,8,36,60:1:5,0,6,230,7,70,8,255,10,32,12,255,14,8,16,60,18,8,20,60,22,8,24,60,26,8,28,60,30,8,32,60,34,8,36,60</Step>
|
||||||
|
<Step Number="45" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,56,12,255,14,13,16,60,18,13,20,60,22,13,24,60,26,13,28,60,30,13,32,60,34,13,36,60:1:5,0,6,230,7,70,8,255,10,56,12,255,14,13,16,60,18,13,20,60,22,13,24,60,26,13,28,60,30,13,32,60,34,13,36,60</Step>
|
||||||
|
<Step Number="46" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,80,12,255,14,19,16,60,18,19,20,60,22,19,24,60,26,19,28,60,30,19,32,60,34,19,36,60:1:5,0,6,230,7,70,8,255,10,80,12,255,14,19,16,60,18,19,20,60,22,19,24,60,26,19,28,60,30,19,32,60,34,19,36,60</Step>
|
||||||
|
<Step Number="47" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,104,12,255,14,24,16,60,18,24,20,60,22,24,24,60,26,24,28,60,30,24,32,60,34,24,36,60:1:5,0,6,230,7,70,8,255,10,104,12,255,14,24,16,60,18,24,20,60,22,24,24,60,26,24,28,60,30,24,32,60,34,24,36,60</Step>
|
||||||
|
<Step Number="48" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,128,12,255,14,30,16,60,18,30,20,60,22,30,24,60,26,30,28,60,30,30,32,60,34,30,36,60:1:5,0,6,230,7,70,8,255,10,128,12,255,14,30,16,60,18,30,20,60,22,30,24,60,26,30,28,60,30,30,32,60,34,30,36,60</Step>
|
||||||
|
<Step Number="49" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,151,12,255,14,36,16,60,18,36,20,60,22,36,24,60,26,36,28,60,30,36,32,60,34,36,36,60:1:5,0,6,230,7,70,8,255,10,151,12,255,14,36,16,60,18,36,20,60,22,36,24,60,26,36,28,60,30,36,32,60,34,36,36,60</Step>
|
||||||
|
<Step Number="50" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,175,12,255,14,41,16,60,18,41,20,60,22,41,24,60,26,41,28,60,30,41,32,60,34,41,36,60:1:5,0,6,230,7,70,8,255,10,175,12,255,14,41,16,60,18,41,20,60,22,41,24,60,26,41,28,60,30,41,32,60,34,41,36,60</Step>
|
||||||
|
<Step Number="51" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,199,12,255,14,47,16,60,18,47,20,60,22,47,24,60,26,47,28,60,30,47,32,60,34,47,36,60:1:5,0,6,230,7,70,8,255,10,199,12,255,14,47,16,60,18,47,20,60,22,47,24,60,26,47,28,60,30,47,32,60,34,47,36,60</Step>
|
||||||
|
<Step Number="52" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,223,12,255,14,52,16,60,18,52,20,60,22,52,24,60,26,52,28,60,30,52,32,60,34,52,36,60:1:5,0,6,230,7,70,8,255,10,223,12,255,14,52,16,60,18,52,20,60,22,52,24,60,26,52,28,60,30,52,32,60,34,52,36,60</Step>
|
||||||
|
<Step Number="53" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,247,12,255,14,58,16,60,18,58,20,60,22,58,24,60,26,58,28,60,30,58,32,60,34,58,36,60:1:5,0,6,230,7,70,8,255,10,247,12,255,14,58,16,60,18,58,20,60,22,58,24,60,26,58,28,60,30,58,32,60,34,58,36,60</Step>
|
||||||
|
<Step Number="54" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,239,14,60,16,56,18,60,20,56,22,60,24,56,26,60,28,56,30,60,32,56,34,60,36,56:1:5,0,6,230,7,70,8,255,10,255,12,239,14,60,16,56,18,60,20,56,22,60,24,56,26,60,28,56,30,60,32,56,34,60,36,56</Step>
|
||||||
|
<Step Number="55" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,215,14,60,16,51,18,60,20,51,22,60,24,51,26,60,28,51,30,60,32,51,34,60,36,51:1:5,0,6,230,7,70,8,255,10,255,12,215,14,60,16,51,18,60,20,51,22,60,24,51,26,60,28,51,30,60,32,51,34,60,36,51</Step>
|
||||||
|
<Step Number="56" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,191,14,60,16,45,18,60,20,45,22,60,24,45,26,60,28,45,30,60,32,45,34,60,36,45:1:5,0,6,230,7,70,8,255,10,255,12,191,14,60,16,45,18,60,20,45,22,60,24,45,26,60,28,45,30,60,32,45,34,60,36,45</Step>
|
||||||
|
<Step Number="57" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,167,14,60,16,39,18,60,20,39,22,60,24,39,26,60,28,39,30,60,32,39,34,60,36,39:1:5,0,6,230,7,70,8,255,10,255,12,167,14,60,16,39,18,60,20,39,22,60,24,39,26,60,28,39,30,60,32,39,34,60,36,39</Step>
|
||||||
|
<Step Number="58" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,143,14,60,16,34,18,60,20,34,22,60,24,34,26,60,28,34,30,60,32,34,34,60,36,34:1:5,0,6,230,7,70,8,255,10,255,12,143,14,60,16,34,18,60,20,34,22,60,24,34,26,60,28,34,30,60,32,34,34,60,36,34</Step>
|
||||||
|
<Step Number="59" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,120,14,60,16,28,18,60,20,28,22,60,24,28,26,60,28,28,30,60,32,28,34,60,36,28:1:5,0,6,230,7,70,8,255,10,255,12,120,14,60,16,28,18,60,20,28,22,60,24,28,26,60,28,28,30,60,32,28,34,60,36,28</Step>
|
||||||
|
<Step Number="60" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,96,14,60,16,23,18,60,20,23,22,60,24,23,26,60,28,23,30,60,32,23,34,60,36,23:1:5,0,6,230,7,70,8,255,10,255,12,96,14,60,16,23,18,60,20,23,22,60,24,23,26,60,28,23,30,60,32,23,34,60,36,23</Step>
|
||||||
|
<Step Number="61" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,72,14,60,16,17,18,60,20,17,22,60,24,17,26,60,28,17,30,60,32,17,34,60,36,17:1:5,0,6,230,7,70,8,255,10,255,12,72,14,60,16,17,18,60,20,17,22,60,24,17,26,60,28,17,30,60,32,17,34,60,36,17</Step>
|
||||||
|
<Step Number="62" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,48,14,60,16,11,18,60,20,11,22,60,24,11,26,60,28,11,30,60,32,11,34,60,36,11:1:5,0,6,230,7,70,8,255,10,255,12,48,14,60,16,11,18,60,20,11,22,60,24,11,26,60,28,11,30,60,32,11,34,60,36,11</Step>
|
||||||
|
<Step Number="63" FadeIn="188" Hold="0" FadeOut="0" Values="68">0:5,0,6,230,7,70,8,255,10,255,12,24,14,60,16,6,18,60,20,6,22,60,24,6,26,60,28,6,30,60,32,6,34,60,36,6:1:5,0,6,230,7,70,8,255,10,255,12,24,14,60,16,6,18,60,20,6,22,60,24,6,26,60,28,6,30,60,32,6,34,60,36,6</Step>
|
||||||
|
</Function>
|
||||||
|
<Function ID="2" Type="Scene" Name="Blackout">
|
||||||
|
<Speed FadeIn="4000" FadeOut="0" Duration="4000"/>
|
||||||
|
<FixtureVal ID="0">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0</FixtureVal>
|
||||||
|
<FixtureVal ID="1">0,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0</FixtureVal>
|
||||||
|
</Function>
|
||||||
|
<Function ID="3" Type="EFX" Name="Figure of 8">
|
||||||
|
<Fixture>
|
||||||
|
<ID>0</ID>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<Intensity>255</Intensity>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture>
|
||||||
|
<ID>1</ID>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<Intensity>255</Intensity>
|
||||||
|
</Fixture>
|
||||||
|
<PropagationMode>Parallel</PropagationMode>
|
||||||
|
<Speed Duration="12000" FadeOut="0" FadeIn="0"/>
|
||||||
|
<Direction>Forward</Direction>
|
||||||
|
<RunOrder>Loop</RunOrder>
|
||||||
|
<Algorithm>Eight</Algorithm>
|
||||||
|
<Width>28</Width>
|
||||||
|
<Height>22</Height>
|
||||||
|
<Rotation>0</Rotation>
|
||||||
|
<Axis Name="X">
|
||||||
|
<Offset>128</Offset>
|
||||||
|
<Frequency>1</Frequency>
|
||||||
|
<Phase>0</Phase>
|
||||||
|
</Axis>
|
||||||
|
<Axis Name="Y">
|
||||||
|
<Offset>80</Offset>
|
||||||
|
<Frequency>1</Frequency>
|
||||||
|
<Phase>0</Phase>
|
||||||
|
</Axis>
|
||||||
|
</Function>
|
||||||
|
<Function ID="4" Type="Collection" Name="Figure of 8">
|
||||||
|
<Step Number="0">0</Step>
|
||||||
|
<Step Number="1">1</Step>
|
||||||
|
<Step Number="2">3</Step>
|
||||||
|
</Function>
|
||||||
|
<Monitor DisplayMode="1" ShowLabels="1">
|
||||||
|
<Font>Arial,12,-1,5,50,0,0,0,0,0</Font>
|
||||||
|
<ChannelStyle>0</ChannelStyle>
|
||||||
|
<ValueStyle>0</ValueStyle>
|
||||||
|
<Grid Width="5" Height="3" Depth="5" Units="0"/>
|
||||||
|
<FxItem ID="0" XPos="1.5" YPos="0.5"/>
|
||||||
|
<FxItem ID="1" XPos="3.5" YPos="0.5"/>
|
||||||
|
</Monitor>
|
||||||
|
</Engine>
|
||||||
|
<VirtualConsole>
|
||||||
|
<Frame Caption="">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SoloFrame Caption="Cues">
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<WindowState Visible="True" X="20" Y="20" Width="400" Height="90"/>
|
||||||
|
<AllowChildren>True</AllowChildren>
|
||||||
|
<AllowResize>True</AllowResize>
|
||||||
|
<ShowHeader>False</ShowHeader>
|
||||||
|
<Mixing>False</Mixing>
|
||||||
|
<Button ID="0" Icon="" Caption="Figure of 8">
|
||||||
|
<Function ID="4"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="10" Y="10" Width="220" Height="70" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4282664004</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
<Button ID="1" Icon="" Caption="Blackout">
|
||||||
|
<Function ID="2"/>
|
||||||
|
<Action>Toggle</Action>
|
||||||
|
<Intensity Adjust="False">100</Intensity>
|
||||||
|
<WindowState X="240" Y="10" Width="140" Height="70" Visible="True"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>None</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>4278190080</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
</Button>
|
||||||
|
</SoloFrame>
|
||||||
|
<SpeedDial Caption="Speed" ID="2">
|
||||||
|
<WindowState Visible="True" X="1000" Y="120" Width="100" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<Visibility>108</Visibility>
|
||||||
|
<AbsoluteValue Minimum="50" Maximum="20000"/>
|
||||||
|
<Time>12000</Time>
|
||||||
|
<Function FadeIn="6" FadeOut="0" Duration="6">1</Function>
|
||||||
|
<Function FadeIn="0" FadeOut="0" Duration="6">3</Function>
|
||||||
|
</SpeedDial>
|
||||||
|
<XYPad Caption="Position" ID="3" InvertedAppearance="0">
|
||||||
|
<WindowState Visible="True" X="20" Y="120" Width="390" Height="390"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>Default</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<Fixture ID="0" Head="0">
|
||||||
|
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
</Fixture>
|
||||||
|
<Fixture ID="1" Head="0">
|
||||||
|
<Axis ID="X" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
<Axis ID="Y" LowLimit="0" HighLimit="1" Reverse="False"/>
|
||||||
|
</Fixture>
|
||||||
|
<Window hMin="100" hMax="156" vMin="58" vMax="102"/>
|
||||||
|
<Pan Position="128"/>
|
||||||
|
<Tilt Position="80"/>
|
||||||
|
<Preset ID="0">
|
||||||
|
<Type>EFX</Type>
|
||||||
|
<Name>Figure of 8</Name>
|
||||||
|
<FuncID>3</FuncID>
|
||||||
|
</Preset>
|
||||||
|
</XYPad>
|
||||||
|
<Slider Caption="Pan" ID="4" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="430" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4294944000</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">0</Channel>
|
||||||
|
<Channel Fixture="1">0</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Tilt" ID="5" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="480" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4278255615</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">2</Channel>
|
||||||
|
<Channel Fixture="1">2</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Zoom" ID="6" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="530" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4294967040</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">5</Channel>
|
||||||
|
<Channel Fixture="1">5</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Focus" ID="7" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="580" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4294902015</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="70">
|
||||||
|
<Channel Fixture="0">7</Channel>
|
||||||
|
<Channel Fixture="1">7</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Dim" ID="8" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="630" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4294967295</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="255">
|
||||||
|
<Channel Fixture="0">8</Channel>
|
||||||
|
<Channel Fixture="1">8</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="R" ID="9" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="680" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4294901760</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Red" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">10</Channel>
|
||||||
|
<Channel Fixture="1">10</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="G" ID="10" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="730" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4278255360</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Green" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">11</Channel>
|
||||||
|
<Channel Fixture="1">11</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="B" ID="11" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="780" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4278190335</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="Blue" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="0">
|
||||||
|
<Channel Fixture="0">12</Channel>
|
||||||
|
<Channel Fixture="1">12</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Outer" ID="12" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="830" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4288256409</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="60">
|
||||||
|
<Channel Fixture="0">14</Channel>
|
||||||
|
<Channel Fixture="0">15</Channel>
|
||||||
|
<Channel Fixture="0">16</Channel>
|
||||||
|
<Channel Fixture="0">18</Channel>
|
||||||
|
<Channel Fixture="0">19</Channel>
|
||||||
|
<Channel Fixture="0">20</Channel>
|
||||||
|
<Channel Fixture="0">22</Channel>
|
||||||
|
<Channel Fixture="0">23</Channel>
|
||||||
|
<Channel Fixture="0">24</Channel>
|
||||||
|
<Channel Fixture="0">26</Channel>
|
||||||
|
<Channel Fixture="0">27</Channel>
|
||||||
|
<Channel Fixture="0">28</Channel>
|
||||||
|
<Channel Fixture="0">30</Channel>
|
||||||
|
<Channel Fixture="0">31</Channel>
|
||||||
|
<Channel Fixture="0">32</Channel>
|
||||||
|
<Channel Fixture="0">34</Channel>
|
||||||
|
<Channel Fixture="0">35</Channel>
|
||||||
|
<Channel Fixture="0">36</Channel>
|
||||||
|
<Channel Fixture="1">14</Channel>
|
||||||
|
<Channel Fixture="1">15</Channel>
|
||||||
|
<Channel Fixture="1">16</Channel>
|
||||||
|
<Channel Fixture="1">18</Channel>
|
||||||
|
<Channel Fixture="1">19</Channel>
|
||||||
|
<Channel Fixture="1">20</Channel>
|
||||||
|
<Channel Fixture="1">22</Channel>
|
||||||
|
<Channel Fixture="1">23</Channel>
|
||||||
|
<Channel Fixture="1">24</Channel>
|
||||||
|
<Channel Fixture="1">26</Channel>
|
||||||
|
<Channel Fixture="1">27</Channel>
|
||||||
|
<Channel Fixture="1">28</Channel>
|
||||||
|
<Channel Fixture="1">30</Channel>
|
||||||
|
<Channel Fixture="1">31</Channel>
|
||||||
|
<Channel Fixture="1">32</Channel>
|
||||||
|
<Channel Fixture="1">34</Channel>
|
||||||
|
<Channel Fixture="1">35</Channel>
|
||||||
|
<Channel Fixture="1">36</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
<Slider Caption="Rotate" ID="13" WidgetStyle="Slider" InvertedAppearance="false">
|
||||||
|
<WindowState Visible="True" X="880" Y="120" Width="50" Height="380"/>
|
||||||
|
<Appearance>
|
||||||
|
<FrameStyle>Sunken</FrameStyle>
|
||||||
|
<ForegroundColor>4291611852</ForegroundColor>
|
||||||
|
<BackgroundColor>Default</BackgroundColor>
|
||||||
|
<BackgroundImage>None</BackgroundImage>
|
||||||
|
<Font>Default</Font>
|
||||||
|
</Appearance>
|
||||||
|
<SliderMode ValueDisplayStyle="Exact" ClickAndGoType="None" Monitor="true">Level</SliderMode>
|
||||||
|
<Reset/>
|
||||||
|
<Level LowLimit="0" HighLimit="255" Value="230">
|
||||||
|
<Channel Fixture="0">6</Channel>
|
||||||
|
<Channel Fixture="1">6</Channel>
|
||||||
|
</Level>
|
||||||
|
<Playback>
|
||||||
|
<Function>4294967295</Function>
|
||||||
|
</Playback>
|
||||||
|
</Slider>
|
||||||
|
</Frame>
|
||||||
|
<Properties>
|
||||||
|
<Size Width="1920" Height="1080"/>
|
||||||
|
<GrandMaster ChannelMode="Intensity" ValueMode="Reduce" SliderMode="Normal"/>
|
||||||
|
</Properties>
|
||||||
|
</VirtualConsole>
|
||||||
|
<SimpleDesk>
|
||||||
|
<Engine/>
|
||||||
|
</SimpleDesk>
|
||||||
|
</Workspace>
|
||||||
+2584
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,279 @@
|
|||||||
|
import {
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
CardHeader,
|
||||||
|
H1,
|
||||||
|
H2,
|
||||||
|
Stack,
|
||||||
|
Table,
|
||||||
|
Text,
|
||||||
|
useHostTheme,
|
||||||
|
} from "cursor/canvas";
|
||||||
|
|
||||||
|
/** Y=0 = row of 4; +Y toward audience. Side cans on walls at ±3.5 m. */
|
||||||
|
const WALL = 3.5;
|
||||||
|
const FIXTURES: {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
kind: "can" | "mover";
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}[] = [
|
||||||
|
{ key: "c3", label: "#3", kind: "can", x: -1.8, y: 0.0 },
|
||||||
|
{ key: "c4", label: "#4", kind: "can", x: -0.6, y: 0.0 },
|
||||||
|
{ key: "c5", label: "#5", kind: "can", x: 0.6, y: 0.0 },
|
||||||
|
{ key: "c6", label: "#6", kind: "can", x: 1.8, y: 0.0 },
|
||||||
|
{ key: "c2", label: "#2", kind: "can", x: -WALL, y: 1.2 },
|
||||||
|
{ key: "c7", label: "#7", kind: "can", x: WALL, y: 1.2 },
|
||||||
|
{ key: "m1", label: "M1", kind: "mover", x: -0.3, y: 1.1 },
|
||||||
|
{ key: "m2", label: "M2", kind: "mover", x: 0.3, y: 1.1 },
|
||||||
|
{ key: "c1", label: "#1", kind: "can", x: -WALL, y: 2.4 },
|
||||||
|
{ key: "c8", label: "#8", kind: "can", x: WALL, y: 2.4 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const BUILDING_W = 7;
|
||||||
|
const DEPTH = 2.4;
|
||||||
|
|
||||||
|
export default function StageMap() {
|
||||||
|
const theme = useHostTheme();
|
||||||
|
|
||||||
|
const pad = 0.55;
|
||||||
|
const x0 = -BUILDING_W / 2 - pad;
|
||||||
|
const x1 = BUILDING_W / 2 + pad;
|
||||||
|
const y0 = -0.45;
|
||||||
|
const y1 = DEPTH + 0.55;
|
||||||
|
const vbW = x1 - x0;
|
||||||
|
const vbH = y1 - y0;
|
||||||
|
const px = 88;
|
||||||
|
const svgW = vbW * px;
|
||||||
|
const svgH = vbH * px;
|
||||||
|
|
||||||
|
const sx = (x: number) => ((x - x0) / vbW) * svgW;
|
||||||
|
const sy = (y: number) => ((y1 - y) / vbH) * svgH;
|
||||||
|
|
||||||
|
const dim = theme.text.tertiary;
|
||||||
|
const ink = theme.text.primary;
|
||||||
|
const accent = theme.accent.primary;
|
||||||
|
const canFill = theme.fill.tertiary;
|
||||||
|
const stroke = theme.stroke.primary;
|
||||||
|
const onAccent = theme.text.onAccent;
|
||||||
|
|
||||||
|
function DimH(
|
||||||
|
xA: number,
|
||||||
|
xB: number,
|
||||||
|
y: number,
|
||||||
|
label: string,
|
||||||
|
side: "above" | "below" = "above",
|
||||||
|
) {
|
||||||
|
const ya = sy(y);
|
||||||
|
const x1p = sx(Math.min(xA, xB));
|
||||||
|
const x2p = sx(Math.max(xA, xB));
|
||||||
|
const mid = (x1p + x2p) / 2;
|
||||||
|
const ty = side === "above" ? ya - 8 : ya + 14;
|
||||||
|
return (
|
||||||
|
<g stroke={dim} fill={dim} strokeWidth={1}>
|
||||||
|
<line x1={x1p} y1={ya} x2={x2p} y2={ya} />
|
||||||
|
<line x1={x1p} y1={ya - 4} x2={x1p} y2={ya + 4} />
|
||||||
|
<line x1={x2p} y1={ya - 4} x2={x2p} y2={ya + 4} />
|
||||||
|
<text x={mid} y={ty} textAnchor="middle" fontSize={11} fill={dim} stroke="none">
|
||||||
|
{label}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function DimV(
|
||||||
|
yA: number,
|
||||||
|
yB: number,
|
||||||
|
x: number,
|
||||||
|
label: string,
|
||||||
|
side: "left" | "right" = "right",
|
||||||
|
) {
|
||||||
|
const xa = sx(x);
|
||||||
|
const y1p = sy(Math.max(yA, yB));
|
||||||
|
const y2p = sy(Math.min(yA, yB));
|
||||||
|
const mid = (y1p + y2p) / 2;
|
||||||
|
const tx = side === "right" ? xa + 8 : xa - 8;
|
||||||
|
return (
|
||||||
|
<g stroke={dim} fill={dim} strokeWidth={1}>
|
||||||
|
<line x1={xa} y1={y1p} x2={xa} y2={y2p} />
|
||||||
|
<line x1={xa - 4} y1={y1p} x2={xa + 4} y2={y1p} />
|
||||||
|
<line x1={xa - 4} y1={y2p} x2={xa + 4} y2={y2p} />
|
||||||
|
<text
|
||||||
|
x={tx}
|
||||||
|
y={mid + 4}
|
||||||
|
textAnchor={side === "right" ? "start" : "end"}
|
||||||
|
fontSize={11}
|
||||||
|
fill={dim}
|
||||||
|
stroke="none"
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Stack gap={20} style={{ padding: 20, maxWidth: 960 }}>
|
||||||
|
<Stack gap={6}>
|
||||||
|
<H1>Stage map</H1>
|
||||||
|
<Text tone="secondary">
|
||||||
|
Building {BUILDING_W} m wide · walls at ±{WALL} m · Y = 0 at row of 4 ·
|
||||||
|
+Y toward audience
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader>Plan (audience at bottom)</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<svg
|
||||||
|
width="100%"
|
||||||
|
viewBox={`0 0 ${svgW} ${svgH}`}
|
||||||
|
style={{ display: "block", maxWidth: svgW, background: theme.bg.editor }}
|
||||||
|
>
|
||||||
|
<rect
|
||||||
|
x={sx(-BUILDING_W / 2)}
|
||||||
|
y={sy(DEPTH)}
|
||||||
|
width={BUILDING_W * px}
|
||||||
|
height={DEPTH * px}
|
||||||
|
fill="none"
|
||||||
|
stroke={stroke}
|
||||||
|
strokeWidth={2}
|
||||||
|
/>
|
||||||
|
{/* Wall labels */}
|
||||||
|
<text
|
||||||
|
x={sx(-WALL) + 4}
|
||||||
|
y={sy(1.8)}
|
||||||
|
fontSize={10}
|
||||||
|
fill={dim}
|
||||||
|
stroke="none"
|
||||||
|
transform={`rotate(-90 ${sx(-WALL) + 4} ${sy(1.8)})`}
|
||||||
|
>
|
||||||
|
3.5 m from centre
|
||||||
|
</text>
|
||||||
|
<text
|
||||||
|
x={sx(WALL) - 4}
|
||||||
|
y={sy(1.8)}
|
||||||
|
fontSize={10}
|
||||||
|
fill={dim}
|
||||||
|
stroke="none"
|
||||||
|
textAnchor="end"
|
||||||
|
transform={`rotate(90 ${sx(WALL) - 4} ${sy(1.8)})`}
|
||||||
|
>
|
||||||
|
3.5 m from centre
|
||||||
|
</text>
|
||||||
|
{DimH(0, -WALL, 1.8, "3.5 m", "above")}
|
||||||
|
{DimH(0, WALL, 1.8, "3.5 m", "below")}
|
||||||
|
<line
|
||||||
|
x1={sx(0)}
|
||||||
|
y1={sy(-0.15)}
|
||||||
|
x2={sx(0)}
|
||||||
|
y2={sy(DEPTH + 0.2)}
|
||||||
|
stroke={dim}
|
||||||
|
strokeWidth={1}
|
||||||
|
strokeDasharray="3 5"
|
||||||
|
/>
|
||||||
|
<text x={sx(0) + 6} y={sy(-0.05)} fontSize={10} fill={dim} stroke="none">
|
||||||
|
centre
|
||||||
|
</text>
|
||||||
|
<text
|
||||||
|
x={sx(0)}
|
||||||
|
y={sy(DEPTH + 0.38)}
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize={12}
|
||||||
|
fill={ink}
|
||||||
|
fontWeight={600}
|
||||||
|
stroke="none"
|
||||||
|
>
|
||||||
|
AUDIENCE
|
||||||
|
</text>
|
||||||
|
<text
|
||||||
|
x={sx(0)}
|
||||||
|
y={sy(-0.28)}
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize={11}
|
||||||
|
fill={dim}
|
||||||
|
stroke="none"
|
||||||
|
>
|
||||||
|
row of 4
|
||||||
|
</text>
|
||||||
|
|
||||||
|
{DimH(-3.5, 3.5, DEPTH + 0.32, "7.0 m building", "below")}
|
||||||
|
{DimH(0, 0.6, 0, "0.6", "above")}
|
||||||
|
{DimH(0, 1.8, 0, "1.8", "above")}
|
||||||
|
{DimH(0, -0.6, 0, "0.6", "below")}
|
||||||
|
{DimH(0, -1.8, 0, "1.8", "below")}
|
||||||
|
{DimH(0, 0.3, 1.1, "0.3", "above")}
|
||||||
|
{DimV(0, 1.1, 2.4, "1.1 m movers")}
|
||||||
|
{DimV(0, 1.2, 2.4, "1.2 m")}
|
||||||
|
{DimV(0, 2.4, -2.4, "2.4 m", "left")}
|
||||||
|
|
||||||
|
{FIXTURES.map((f) => {
|
||||||
|
const cx = sx(f.x);
|
||||||
|
const cy = sy(f.y);
|
||||||
|
const r = f.kind === "mover" ? 14 : 12;
|
||||||
|
return (
|
||||||
|
<g key={f.key}>
|
||||||
|
{f.kind === "mover" ? (
|
||||||
|
<rect
|
||||||
|
x={cx - r}
|
||||||
|
y={cy - r}
|
||||||
|
width={r * 2}
|
||||||
|
height={r * 2}
|
||||||
|
rx={3}
|
||||||
|
fill={accent}
|
||||||
|
stroke={stroke}
|
||||||
|
strokeWidth={1}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<circle
|
||||||
|
cx={cx}
|
||||||
|
cy={cy}
|
||||||
|
r={r}
|
||||||
|
fill={canFill}
|
||||||
|
stroke={stroke}
|
||||||
|
strokeWidth={1.5}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<text
|
||||||
|
x={cx}
|
||||||
|
y={cy + 4}
|
||||||
|
textAnchor="middle"
|
||||||
|
fontSize={11}
|
||||||
|
fontWeight={600}
|
||||||
|
fill={f.kind === "mover" ? onAccent : ink}
|
||||||
|
stroke="none"
|
||||||
|
>
|
||||||
|
{f.label}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</svg>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Stack gap={12}>
|
||||||
|
<H2>Coordinates</H2>
|
||||||
|
<Table
|
||||||
|
headers={["Fixture", "Type", "X (m)", "Y (m)", "Notes"]}
|
||||||
|
rows={[
|
||||||
|
["#3", "Can", "−1.8", "0.0", "Row of 4"],
|
||||||
|
["#4", "Can", "−0.6", "0.0", "Row of 4"],
|
||||||
|
["#5", "Can", "+0.6", "0.0", "Row of 4"],
|
||||||
|
["#6", "Can", "+1.8", "0.0", "Row of 4"],
|
||||||
|
["#2", "Can", "−3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
|
||||||
|
["#7", "Can", "+3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
|
||||||
|
["M1", "Mover", "−0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
|
||||||
|
["M2", "Mover", "+0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
|
||||||
|
["#1", "Can", "−3.5", "2.4", "Side · 3.5 m from centre · front left · 2.4 m in front"],
|
||||||
|
["#8", "Can", "+3.5", "2.4", "Side · 3.5 m from centre · front right · 2.4 m in front"],
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Text tone="secondary" size="small">
|
||||||
|
Source: integrate_u_patterns.py LAYOUT_M
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"units": "metres",
|
||||||
|
"building_width": 7.0,
|
||||||
|
"origin": "Y=0 at row of 4; +Y toward audience; X=0 centre",
|
||||||
|
"fixtures": {
|
||||||
|
"#1": {
|
||||||
|
"x": -3.5,
|
||||||
|
"y": 2.4,
|
||||||
|
"label": "#1",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#2": {
|
||||||
|
"x": -3.5,
|
||||||
|
"y": 1.2,
|
||||||
|
"label": "#2",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#3": {
|
||||||
|
"x": -1.8,
|
||||||
|
"y": 0.0,
|
||||||
|
"label": "#3",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#4": {
|
||||||
|
"x": -0.6,
|
||||||
|
"y": 0.0,
|
||||||
|
"label": "#4",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#5": {
|
||||||
|
"x": 0.6,
|
||||||
|
"y": 0.0,
|
||||||
|
"label": "#5",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#6": {
|
||||||
|
"x": 1.8,
|
||||||
|
"y": 0.0,
|
||||||
|
"label": "#6",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#7": {
|
||||||
|
"x": 3.5,
|
||||||
|
"y": 1.2,
|
||||||
|
"label": "#7",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"#8": {
|
||||||
|
"x": 3.5,
|
||||||
|
"y": 2.4,
|
||||||
|
"label": "#8",
|
||||||
|
"kind": "can"
|
||||||
|
},
|
||||||
|
"M1": {
|
||||||
|
"x": -0.3,
|
||||||
|
"y": 1.1,
|
||||||
|
"label": "M1",
|
||||||
|
"kind": "mover"
|
||||||
|
},
|
||||||
|
"M2": {
|
||||||
|
"x": 0.3,
|
||||||
|
"y": 1.1,
|
||||||
|
"label": "M2",
|
||||||
|
"kind": "mover"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="840" height="350" viewBox="0 0 840.0 350.0">
|
||||||
|
<title>XCHC stage map — 7 m building</title>
|
||||||
|
<desc>Y=0 row of 4; +Y toward audience. Sides on walls ±3.5 m. Movers ±0.3 m, 1.1 m in front of row of 4.</desc>
|
||||||
|
<rect width="100%" height="100%" fill="#1a1a1a"/>
|
||||||
|
<rect x="70.0" y="60.0" width="700.0" height="240.0" fill="none" stroke="#888" stroke-width="2"/>
|
||||||
|
<line x1="420.0" y1="320.0" x2="420.0" y2="35.0" stroke="#555" stroke-dasharray="4 6"/>
|
||||||
|
<text x="426.0" y="305.0" fill="#888" font-size="12" font-family="system-ui,sans-serif">centre</text>
|
||||||
|
<text x="420.0" y="20.0" text-anchor="middle" fill="#eee" font-size="14" font-weight="600" font-family="system-ui,sans-serif">AUDIENCE</text>
|
||||||
|
<text x="420.0" y="332.0" text-anchor="middle" fill="#888" font-size="12" font-family="system-ui,sans-serif">row of 4</text>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="70.0" y1="25.0" x2="770.0" y2="25.0"/>
|
||||||
|
<line x1="70.0" y1="21.0" x2="70.0" y2="29.0"/>
|
||||||
|
<line x1="770.0" y1="21.0" x2="770.0" y2="29.0"/>
|
||||||
|
<text x="420.0" y="39.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">7.0 m building</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="420.0" y1="300.0" x2="480.0" y2="300.0"/>
|
||||||
|
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||||
|
<line x1="480.0" y1="296.0" x2="480.0" y2="304.0"/>
|
||||||
|
<text x="450.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="420.0" y1="300.0" x2="600.0" y2="300.0"/>
|
||||||
|
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||||
|
<line x1="600.0" y1="296.0" x2="600.0" y2="304.0"/>
|
||||||
|
<text x="510.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="360.0" y1="300.0" x2="420.0" y2="300.0"/>
|
||||||
|
<line x1="360.0" y1="296.0" x2="360.0" y2="304.0"/>
|
||||||
|
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||||
|
<text x="390.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="240.0" y1="300.0" x2="420.0" y2="300.0"/>
|
||||||
|
<line x1="240.0" y1="296.0" x2="240.0" y2="304.0"/>
|
||||||
|
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||||
|
<text x="330.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="420.0" y1="190.0" x2="450.0" y2="190.0"/>
|
||||||
|
<line x1="420.0" y1="186.0" x2="420.0" y2="194.0"/>
|
||||||
|
<line x1="450.0" y1="186.0" x2="450.0" y2="194.0"/>
|
||||||
|
<text x="435.0" y="182.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.3 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="70.0" y1="120.0" x2="420.0" y2="120.0"/>
|
||||||
|
<line x1="70.0" y1="116.0" x2="70.0" y2="124.0"/>
|
||||||
|
<line x1="420.0" y1="116.0" x2="420.0" y2="124.0"/>
|
||||||
|
<text x="245.0" y="112.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="420.0" y1="100.0" x2="770.0" y2="100.0"/>
|
||||||
|
<line x1="420.0" y1="96.0" x2="420.0" y2="104.0"/>
|
||||||
|
<line x1="770.0" y1="96.0" x2="770.0" y2="104.0"/>
|
||||||
|
<text x="595.0" y="114.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="640.0" y1="190.0" x2="640.0" y2="300.0"/>
|
||||||
|
<line x1="636.0" y1="190.0" x2="644.0" y2="190.0"/>
|
||||||
|
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
|
||||||
|
<text x="648.0" y="249.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.1 m movers</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="640.0" y1="180.0" x2="640.0" y2="300.0"/>
|
||||||
|
<line x1="636.0" y1="180.0" x2="644.0" y2="180.0"/>
|
||||||
|
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
|
||||||
|
<text x="648.0" y="244.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.2 m</text>
|
||||||
|
</g>
|
||||||
|
<g stroke="#888" fill="#888" stroke-width="1">
|
||||||
|
<line x1="200.0" y1="60.0" x2="200.0" y2="300.0"/>
|
||||||
|
<line x1="196.0" y1="60.0" x2="204.0" y2="60.0"/>
|
||||||
|
<line x1="196.0" y1="300.0" x2="204.0" y2="300.0"/>
|
||||||
|
<text x="192.0" y="184.0" text-anchor="end" font-size="11" stroke="none" font-family="system-ui,sans-serif">2.4 m</text>
|
||||||
|
</g>
|
||||||
|
<circle cx="70.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="70.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#1</text>
|
||||||
|
<circle cx="70.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="70.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#2</text>
|
||||||
|
<circle cx="240.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="240.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#3</text>
|
||||||
|
<circle cx="360.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="360.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#4</text>
|
||||||
|
<circle cx="480.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="480.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#5</text>
|
||||||
|
<circle cx="600.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="600.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#6</text>
|
||||||
|
<circle cx="770.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="770.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#7</text>
|
||||||
|
<circle cx="770.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||||
|
<text x="770.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#8</text>
|
||||||
|
<rect x="376.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
|
||||||
|
<text x="390.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M1</text>
|
||||||
|
<rect x="436.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
|
||||||
|
<text x="450.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M2</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 6.9 KiB |
Executable
+294
@@ -0,0 +1,294 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Art-Net tester for Small Eye 7 Mover channels 5 / 6 / 7.
|
||||||
|
|
||||||
|
Pan/tilt (1–4) already look right. This script lights the centre LED, then
|
||||||
|
isolates:
|
||||||
|
|
||||||
|
CH5 pan/tilt speed — head should move fast at 0, crawl at 255
|
||||||
|
CH6 zoom — beam should grow/shrink
|
||||||
|
CH7 lens rotate — front glass spins only in 128–188 or 194–255,
|
||||||
|
and often only when zoom is fully in (narrow)
|
||||||
|
|
||||||
|
Quit with Ctrl+C (sends blackout). Stop QLC+ output first so the two
|
||||||
|
sources do not fight.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
python3 test_small_eye.py --ip 192.168.1.228 --address 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
ARTNET_PORT = 6454
|
||||||
|
HEADER = b"Art-Net\x00"
|
||||||
|
OP_DMX = 0x5000
|
||||||
|
PROT_VER = 14
|
||||||
|
|
||||||
|
# 1-based fixture channels (43ch pixel mode)
|
||||||
|
CH_PAN = 1
|
||||||
|
CH_TILT = 3
|
||||||
|
CH_SPEED = 5
|
||||||
|
CH_ZOOM = 6
|
||||||
|
CH_ROTATE = 7
|
||||||
|
CH_FOCUS = 8
|
||||||
|
CH_DIMMER = 9
|
||||||
|
CH_STROBE = 10
|
||||||
|
CH_RED = 11
|
||||||
|
CH_GREEN = 12
|
||||||
|
CH_BLUE = 13
|
||||||
|
CH_WHITE = 14
|
||||||
|
FIXTURE_CHANNELS = 43
|
||||||
|
|
||||||
|
|
||||||
|
def build_artdmx(channels: bytes, universe: int = 0, sequence: int = 1) -> bytes:
|
||||||
|
data = bytearray(channels)
|
||||||
|
n = len(data)
|
||||||
|
if n < 2:
|
||||||
|
data.extend(b"\x00" * (2 - n))
|
||||||
|
n = 2
|
||||||
|
if n & 1:
|
||||||
|
data.append(0)
|
||||||
|
n += 1
|
||||||
|
if n > 512:
|
||||||
|
data = data[:512]
|
||||||
|
n = 512
|
||||||
|
pkt = bytearray(18 + n)
|
||||||
|
pkt[0:8] = HEADER
|
||||||
|
pkt[8:10] = bytes((OP_DMX & 0xFF, OP_DMX >> 8))
|
||||||
|
pkt[10] = 0
|
||||||
|
pkt[11] = PROT_VER
|
||||||
|
pkt[12] = sequence & 0xFF
|
||||||
|
pkt[13] = 0
|
||||||
|
pkt[14] = universe & 0xFF
|
||||||
|
pkt[15] = 0
|
||||||
|
pkt[16] = (n >> 8) & 0xFF
|
||||||
|
pkt[17] = n & 0xFF
|
||||||
|
pkt[18 : 18 + n] = data
|
||||||
|
return bytes(pkt)
|
||||||
|
|
||||||
|
|
||||||
|
class ArtNetSender:
|
||||||
|
def __init__(self, dest: str, universe: int = 0, hz: float = 40.0):
|
||||||
|
self.dest = dest
|
||||||
|
self.universe = universe
|
||||||
|
self.period = 1.0 / hz
|
||||||
|
self.frame = bytearray(512)
|
||||||
|
self.sequence = 1
|
||||||
|
self._lock = threading.Lock()
|
||||||
|
self._running = True
|
||||||
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||||
|
self._thread = threading.Thread(target=self._loop, daemon=True)
|
||||||
|
self._thread.start()
|
||||||
|
|
||||||
|
def _loop(self):
|
||||||
|
while self._running:
|
||||||
|
with self._lock:
|
||||||
|
pkt = build_artdmx(self.frame, self.universe, self.sequence)
|
||||||
|
self.sequence = 1 if self.sequence >= 255 else self.sequence + 1
|
||||||
|
try:
|
||||||
|
self.sock.sendto(pkt, (self.dest, ARTNET_PORT))
|
||||||
|
except OSError as exc:
|
||||||
|
print(f"Art-Net send failed: {exc}", file=sys.stderr)
|
||||||
|
time.sleep(self.period)
|
||||||
|
|
||||||
|
def set_slot(self, dmx_addr: int, value: int):
|
||||||
|
"""dmx_addr is 1-based DMX."""
|
||||||
|
with self._lock:
|
||||||
|
self.frame[dmx_addr - 1] = max(0, min(255, int(value)))
|
||||||
|
|
||||||
|
def blackout(self):
|
||||||
|
with self._lock:
|
||||||
|
self.frame[:] = b"\x00" * 512
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.blackout()
|
||||||
|
time.sleep(self.period * 3)
|
||||||
|
self._running = False
|
||||||
|
self._thread.join(timeout=1.0)
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
|
||||||
|
class SmallEye:
|
||||||
|
def __init__(self, sender: ArtNetSender, address: int):
|
||||||
|
self.artnet = sender
|
||||||
|
self.address = address
|
||||||
|
|
||||||
|
def set(self, channel: int, value: int):
|
||||||
|
self.artnet.set_slot(self.address + channel - 1, value)
|
||||||
|
|
||||||
|
def park_light(self, pan=128, tilt=80, dimmer=255, white=255, rgb=40):
|
||||||
|
"""Still, visible beam. Strobe open, pixels off except centre RGBW."""
|
||||||
|
for ch in range(1, FIXTURE_CHANNELS + 1):
|
||||||
|
self.set(ch, 0)
|
||||||
|
self.set(CH_PAN, pan)
|
||||||
|
self.set(CH_TILT, tilt)
|
||||||
|
self.set(CH_SPEED, 0)
|
||||||
|
self.set(CH_ZOOM, 0)
|
||||||
|
self.set(CH_ROTATE, 0)
|
||||||
|
self.set(CH_FOCUS, 128)
|
||||||
|
self.set(CH_DIMMER, dimmer)
|
||||||
|
self.set(CH_STROBE, 0)
|
||||||
|
self.set(CH_RED, rgb)
|
||||||
|
self.set(CH_GREEN, rgb)
|
||||||
|
self.set(CH_BLUE, rgb)
|
||||||
|
self.set(CH_WHITE, white)
|
||||||
|
|
||||||
|
|
||||||
|
def say(msg: str):
|
||||||
|
print(f"\n=== {msg} ===", flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
def hold(seconds: float, label: str = ""):
|
||||||
|
if label:
|
||||||
|
print(f" {label}", flush=True)
|
||||||
|
end = time.monotonic() + seconds
|
||||||
|
while time.monotonic() < end:
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
|
||||||
|
def sweep(fixture: SmallEye, channel: int, start: int, stop: int, seconds: float):
|
||||||
|
steps = max(1, int(seconds * 40))
|
||||||
|
for i in range(steps + 1):
|
||||||
|
value = int(start + (stop - start) * i / steps)
|
||||||
|
fixture.set(channel, value)
|
||||||
|
time.sleep(seconds / steps)
|
||||||
|
|
||||||
|
|
||||||
|
def wait_enter(enabled: bool, prompt: str):
|
||||||
|
if enabled:
|
||||||
|
input(f" {prompt} [Enter] ")
|
||||||
|
|
||||||
|
|
||||||
|
def test_speed(fixture: SmallEye, hold_s: float, pause: bool):
|
||||||
|
say("CH5 pan/tilt SPEED")
|
||||||
|
print("Watch the HEAD (yoke), not the lens.")
|
||||||
|
print("CH5=0 should be fast, CH5=255 should crawl.")
|
||||||
|
fixture.park_light()
|
||||||
|
wait_enter(pause, "Ready to wiggle pan")
|
||||||
|
for speed in (0, 80, 160, 255):
|
||||||
|
fixture.set(CH_SPEED, speed)
|
||||||
|
print(f" CH5 = {speed:3d} sweeping pan 40 → 220")
|
||||||
|
sweep(fixture, CH_PAN, 40, 220, hold_s)
|
||||||
|
sweep(fixture, CH_PAN, 220, 40, hold_s)
|
||||||
|
fixture.set(CH_PAN, 128)
|
||||||
|
fixture.set(CH_SPEED, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_zoom(fixture: SmallEye, hold_s: float, pause: bool):
|
||||||
|
say("CH6 ZOOM")
|
||||||
|
print("Watch the SPOT size on the wall. Should grow then shrink.")
|
||||||
|
fixture.park_light()
|
||||||
|
fixture.set(CH_ROTATE, 0)
|
||||||
|
wait_enter(pause, "Ready for zoom sweep")
|
||||||
|
print(" CH6 0 → 255")
|
||||||
|
sweep(fixture, CH_ZOOM, 0, 255, hold_s * 2)
|
||||||
|
hold(1.5, "CH6 = 255 (hold)")
|
||||||
|
print(" CH6 255 → 0")
|
||||||
|
sweep(fixture, CH_ZOOM, 255, 0, hold_s * 2)
|
||||||
|
hold(1.5, "CH6 = 0 (hold, narrow)")
|
||||||
|
|
||||||
|
|
||||||
|
def test_rotate(fixture: SmallEye, hold_s: float, pause: bool):
|
||||||
|
say("CH7 LENS ROTATE")
|
||||||
|
print("Watch the FRONT GLASS. Index 0–127 does not spin.")
|
||||||
|
print("Spin is 128–188 (CCW) and 194–255 (CW). 189–193 is stop.")
|
||||||
|
print("If nothing moves, zoom is probably too wide — trying both extremes.")
|
||||||
|
fixture.park_light()
|
||||||
|
wait_enter(pause, "Ready for rotate")
|
||||||
|
|
||||||
|
points = [
|
||||||
|
(0, "index 0°"),
|
||||||
|
(64, "index mid"),
|
||||||
|
(127, "index 60°"),
|
||||||
|
(160, "SPIN CCW"),
|
||||||
|
(191, "stop band"),
|
||||||
|
(220, "SPIN CW"),
|
||||||
|
(255, "SPIN CW fast"),
|
||||||
|
(0, "back to index 0"),
|
||||||
|
]
|
||||||
|
for zoom in (0, 255):
|
||||||
|
fixture.set(CH_ZOOM, zoom)
|
||||||
|
fixture.set(CH_ROTATE, 0)
|
||||||
|
print(f"\n zoom CH6 = {zoom}")
|
||||||
|
hold(1.0)
|
||||||
|
for value, label in points:
|
||||||
|
fixture.set(CH_ROTATE, value)
|
||||||
|
hold(hold_s, f"CH7 = {value:3d} {label}")
|
||||||
|
fixture.set(CH_ROTATE, 0)
|
||||||
|
fixture.set(CH_ZOOM, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_hunt(fixture: SmallEye, hold_s: float, pause: bool):
|
||||||
|
say("HUNT: put spin values on CH5, then CH6, then CH7")
|
||||||
|
print("Whichever channel actually spins the glass is lens rotate.")
|
||||||
|
fixture.park_light()
|
||||||
|
wait_enter(pause, "Ready to hunt rotate")
|
||||||
|
for candidate in (CH_SPEED, CH_ZOOM, CH_ROTATE):
|
||||||
|
fixture.park_light()
|
||||||
|
# Narrow zoom on the other two optics channels
|
||||||
|
if candidate != CH_ZOOM:
|
||||||
|
fixture.set(CH_ZOOM, 0)
|
||||||
|
print(f"\n putting spin (160, then 220) on CH{candidate}")
|
||||||
|
fixture.set(candidate, 160)
|
||||||
|
hold(hold_s, f"CH{candidate} = 160 CCW")
|
||||||
|
fixture.set(candidate, 220)
|
||||||
|
hold(hold_s, f"CH{candidate} = 220 CW")
|
||||||
|
fixture.set(candidate, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
p.add_argument("--ip", default="192.168.1.228", help="Art-Net destination (QLC uses 192.168.1.228)")
|
||||||
|
p.add_argument("--universe", type=int, default=0, help="Art-Net universe (default 0)")
|
||||||
|
p.add_argument("--address", type=int, default=1, help="Fixture DMX start address, 1-based")
|
||||||
|
p.add_argument("--hold", type=float, default=3.0, help="Seconds to hold each rotate/speed step")
|
||||||
|
p.add_argument("--pause", action="store_true", help="Wait for Enter before each test")
|
||||||
|
p.add_argument(
|
||||||
|
"--only",
|
||||||
|
choices=("speed", "zoom", "rotate", "hunt", "all"),
|
||||||
|
default="all",
|
||||||
|
help="Run one test (default all)",
|
||||||
|
)
|
||||||
|
return p.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
if not 1 <= args.address <= 512:
|
||||||
|
sys.exit("address must be 1–512")
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"Art-Net → {args.ip} universe {args.universe} "
|
||||||
|
f"fixture start {args.address} (43ch)"
|
||||||
|
)
|
||||||
|
print("Stop QLC+ Art-Net output first.")
|
||||||
|
|
||||||
|
sender = ArtNetSender(args.ip, universe=args.universe)
|
||||||
|
fixture = SmallEye(sender, args.address)
|
||||||
|
try:
|
||||||
|
fixture.park_light()
|
||||||
|
hold(2.0, "centre LED on, head still")
|
||||||
|
tests = {
|
||||||
|
"speed": lambda: test_speed(fixture, args.hold, args.pause),
|
||||||
|
"zoom": lambda: test_zoom(fixture, args.hold, args.pause),
|
||||||
|
"rotate": lambda: test_rotate(fixture, args.hold, args.pause),
|
||||||
|
"hunt": lambda: test_hunt(fixture, args.hold, args.pause),
|
||||||
|
}
|
||||||
|
order = ("speed", "zoom", "rotate", "hunt") if args.only == "all" else (args.only,)
|
||||||
|
for name in order:
|
||||||
|
tests[name]()
|
||||||
|
say("done — blackout")
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nstopped")
|
||||||
|
finally:
|
||||||
|
sender.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user