Skip to content

Commit 281b99a

Browse files
committed
Add MVR Export. Move object scaling from pymvr to blender
1 parent 68ece06 commit 281b99a

File tree

7 files changed

+708
-109
lines changed

7 files changed

+708
-109
lines changed

blender_manifest.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ license = [
1616

1717
wheels = [
1818
"wheels/pygdtf-1.4.2-py3-none-any.whl",
19-
"wheels/pymvr-1.0.5-py3-none-any.whl",
19+
"wheels/pymvr-1.0.6.dev0-py3-none-any.whl",
2020
"wheels/sacn-1.9.1-py3-none-any.whl",
2121
"wheels/oscpy-0.6.0-py2.py3-none-any.whl",
2222
"wheels/ifaddr-0.2.0-py3-none-any.whl",

dmx.py

Lines changed: 13 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import os
2121
import re
2222
import sys
23+
import tempfile
2324
import time
2425
import traceback
2526
import uuid as py_uuid
@@ -57,7 +58,7 @@
5758
from .logging_setup import DMX_Log
5859
from .material import get_gobo_material, set_light_nodes
5960
from .mdns import DMX_Zeroconf
60-
from .mvr import load_mvr
61+
from .mvr import load_mvr, export_mvr as mvr_export_mvr
6162
from .mvr_objects import DMX_MVR_Class, DMX_MVR_Object
6263
from .mvrx_protocol import DMX_MVR_X_Client, DMX_MVR_X_Server, DMX_MVR_X_WS_Client
6364
from .mvrxchange.mvr_xchange_blender import (
@@ -2226,78 +2227,19 @@ def is_there_universe_zero(self):
22262227
return False
22272228

22282229
def export_mvr(
2229-
self, file_name, export_focus_points=True, selected_fixtures_only=False
2230+
self,
2231+
file_name,
2232+
export_focus_points=True,
2233+
selected_fixtures_only=False,
2234+
export_fixtures_only=False,
22302235
):
2231-
start_time = time.time()
2232-
bpy.context.window_manager.dmx.pause_render = (
2233-
True # this stops the render loop, to prevent slowness and crashes
2236+
return mvr_export_mvr(
2237+
self,
2238+
file_name,
2239+
export_focus_points=export_focus_points,
2240+
selected_fixtures_only=selected_fixtures_only,
2241+
export_fixtures_only=export_fixtures_only,
22342242
)
2235-
dmx = bpy.context.scene.dmx
2236-
# reset 3D cursor to eliminate offset issues
2237-
bpy.context.scene.cursor.location = (0.0, 0.0, 0.0)
2238-
bpy.context.scene.cursor.rotation_euler = (0.0, 0.0, 0.0)
2239-
2240-
folder_path = self.get_addon_path()
2241-
folder_path = os.path.join(folder_path, "assets", "profiles")
2242-
universe_add = self.is_there_universe_zero()
2243-
2244-
try:
2245-
fixtures_list = []
2246-
mvr = pymvr.GeneralSceneDescriptionWriter()
2247-
mvr.serialize_user_data(pymvr.UserData())
2248-
2249-
layers = pymvr.Layers()
2250-
2251-
for dmx_fixture in dmx.fixtures:
2252-
if selected_fixtures_only and not dmx_fixture.is_selected():
2253-
continue
2254-
fixture_layer_name = dmx_fixture.get("layer_name", "DMX")
2255-
fixture_layer_uuid = dmx_fixture.get("layer_uuid", None)
2256-
if fixture_layer_uuid is not None:
2257-
use_layer = next(
2258-
(l for l in layers if l.uuid == fixture_layer_uuid), None
2259-
)
2260-
if not use_layer:
2261-
use_layer = pymvr.Layer(
2262-
name=fixture_layer_name, uuid=fixture_layer_uuid
2263-
)
2264-
new_child_list = pymvr.ChildList()
2265-
use_layer.child_list = new_child_list
2266-
layers.append(use_layer)
2267-
else: # no layer in fixture
2268-
use_layer = next(
2269-
(l for l in layers if l.name == fixture_layer_name), None
2270-
) # we should get "DMX" layer if exists
2271-
if not use_layer: # create new DMX layer
2272-
use_layer = pymvr.Layer(name="DMX", uuid=str(py_uuid.uuid4()))
2273-
new_child_list = pymvr.ChildList()
2274-
use_layer.child_list = new_child_list
2275-
layers.append(use_layer)
2276-
2277-
child_list = use_layer.child_list
2278-
2279-
fixture_object = dmx_fixture.to_mvr_fixture(universe_add=universe_add)
2280-
focus_point = dmx_fixture.focus_to_mvr_focus_point()
2281-
if export_focus_points and focus_point is not None:
2282-
child_list.focus_points.append(focus_point)
2283-
child_list.fixtures.append(fixture_object)
2284-
if fixture_object.gdtf_spec:
2285-
file_path = os.path.join(folder_path, fixture_object.gdtf_spec)
2286-
fixtures_list.append((file_path, fixture_object.gdtf_spec))
2287-
2288-
scene = pymvr.Scene(layers=layers, aux_data=pymvr.AUXData())
2289-
mvr.serialize_scene(scene)
2290-
mvr.files_list = list(set(fixtures_list))
2291-
mvr.write_mvr(file_name)
2292-
file_size = Path(file_name).stat().st_size
2293-
2294-
except Exception as e:
2295-
traceback.print_exception(e)
2296-
return SimpleNamespace(ok=False, error=str(e))
2297-
2298-
bpy.context.window_manager.dmx.pause_render = False # re-enable render loop
2299-
print("INFO", "MVR scene exported in %.4f sec." % (time.time() - start_time))
2300-
return SimpleNamespace(ok=True, file_size=file_size)
23012243

23022244
def ensureUniverseExists(self, universe):
23032245
# Allocate universes to be able to control devices

fixture.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,15 +2732,22 @@ def remove_ies(self):
27322732
if ies is not None:
27332733
light_obj.data.node_tree.nodes.remove(ies)
27342734

2735+
def _matrix_to_mvr_units(self, matrix_world):
2736+
matrix = [list(col) for col in matrix_world.col]
2737+
if len(matrix) >= 4 and len(matrix[3]) >= 3:
2738+
matrix[3][0] *= 1000.0
2739+
matrix[3][1] *= 1000.0
2740+
matrix[3][2] *= 1000.0
2741+
return matrix
2742+
27352743
def to_mvr_fixture(self, universe_add=False):
27362744
matrix = 0
27372745
uuid_focus_point = None
27382746
add_to_universe = 1 if universe_add else 0
27392747

27402748
for obj in self.objects:
27412749
if obj.object.get("geometry_root", False):
2742-
m = obj.object.matrix_world
2743-
matrix = [list(col) for col in m.col]
2750+
matrix = self._matrix_to_mvr_units(obj.object.matrix_world)
27442751
if "Target" in obj.name:
27452752
uuid_focus_point = obj.object.get("uuid", None)
27462753

@@ -2775,8 +2782,7 @@ def focus_to_mvr_focus_point(self):
27752782
if "Target" in obj.name:
27762783
matrix = None
27772784
uuid_ = None
2778-
m = obj.object.matrix_world
2779-
matrix = [list(col) for col in m.col]
2785+
matrix = self._matrix_to_mvr_units(obj.object.matrix_world)
27802786
uuid_ = obj.object.get("uuid", None)
27812787
if matrix is None or uuid_ is None:
27822788
DMX_Log.log.error("Matrix or uuid of a Target not defined")

in_out_mvr.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,15 @@ class DMX_OT_Export_MVR(Operator, ExportHelper):
229229

230230
selected_fixtures_only: BoolProperty(
231231
name=_("Export only selected fixtures"),
232-
description=_("Export only selected fixtures"),
232+
description=_(
233+
"Export only selected fixtures (does not filter non-fixture objects)"
234+
),
235+
default=False,
236+
)
237+
238+
export_fixtures_only: BoolProperty(
239+
name=_("Export fixtures only"),
240+
description=_("Export fixtures only (skip all non-fixture objects)"),
233241
default=False,
234242
)
235243

@@ -249,6 +257,7 @@ def draw(self, context):
249257
box = layout.column().box()
250258
box.prop(self, "export_focus_points")
251259
box.prop(self, "selected_fixtures_only")
260+
box.prop(self, "export_fixtures_only")
252261

253262
def execute(self, context):
254263
dmx = context.scene.dmx
@@ -257,6 +266,7 @@ def execute(self, context):
257266
self.filepath,
258267
export_focus_points=self.export_focus_points,
259268
selected_fixtures_only=self.selected_fixtures_only,
269+
export_fixtures_only=self.export_fixtures_only,
260270
)
261271

262272
if result.ok:

0 commit comments

Comments
 (0)