Skip to content

Commit b1b9adc

Browse files
committed
Closes #595! However, in working on this bug it was discovered that the regions feature is quite possibly broken, and that we don't have test coverage for it! Also discovered is that Aircraft export types have been previously unable to work with regions. Bug reports made.
1 parent d04dabf commit b1b9adc

13 files changed

Lines changed: 393 additions & 111 deletions

io_xplane2blender/xplane_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# The current data model version, incrementing every time xplane_constants, xplane_props, or xplane_updater
2020
# changes. Builds earlier than 3.4.0-beta.5 have and a version of 0.
2121
# When merging, take the higher data model version of the two branches and add one
22-
CURRENT_DATA_MODEL_VERSION = 94
22+
CURRENT_DATA_MODEL_VERSION = 95
2323

2424
# The build number, hardcoded by the build script when there is one, otherwise it is xplane_constants.BUILD_NUMBER_NONE
2525
CURRENT_BUILD_NUMBER = xplane_constants.BUILD_NUMBER_NONE

io_xplane2blender/xplane_constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,7 @@ def _get_all_manipulators():
247247
LOGGER_LEVEL_SUCCESS,
248248
LOGGER_LEVEL_WARN,
249249
)
250+
251+
PANEL_COCKPIT = "cockpit"
252+
PANEL_COCKPIT_LIT_ONLY = "cockpit_lit_only"
253+
PANEL_COCKPIT_REGION = "cockpit_region"

io_xplane2blender/xplane_props.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,11 +1004,13 @@ class XPlaneLayer(bpy.types.PropertyGroup):
10041004
or they'll reload the file and the problem will be (hopefully solved)
10051005
"""
10061006
def update_cockpit_regions(self, context)->None:
1007+
# Avoids the need for operators to increase and decrease the size of self.cockpit_region
10071008
while len(self.cockpit_region) < xplane_constants.MAX_COCKPIT_REGIONS:
10081009
self.cockpit_region.add()
10091010
return None
10101011

10111012
def update_lods(self, context):
1013+
# Avoids the need for operators to increase and decrease the size of self.lods
10121014
#MAX_LODS also counts "None", so we have to subtract by 1
10131015
while len(self.lod) < xplane_constants.MAX_LODS - 1:
10141016
self.lod.add()
@@ -1021,10 +1023,15 @@ def update_lods(self, context):
10211023
default = False
10221024
)
10231025

1024-
cockpit_lit_only: bpy.props.BoolProperty(
1025-
name="Emissive Panel Texture Only",
1026-
description="Only emissive panel texture will be dynamic. Great for computer displays",
1027-
default = False
1026+
cockpit_panel_mode: bpy.props.EnumProperty(
1027+
name="Panel Texture Mode",
1028+
description="Panel Texture Mode, affects all Materials using Panel",
1029+
items=[
1030+
(PANEL_COCKPIT, "Default", "Full Panel Texture: Albedo, Lit, and Normal"),
1031+
(PANEL_COCKPIT_LIT_ONLY, "Emissive Panel Texture Only", "Only emissive panel texture will be dynamic. Great for computer displays"),
1032+
(PANEL_COCKPIT_REGION, "Regions", "Uses regions of panel texture")
1033+
],
1034+
default=PANEL_COCKPIT,
10281035
)
10291036

10301037
expanded: bpy.props.BoolProperty(
@@ -1163,6 +1170,8 @@ def update_lods(self, context):
11631170
default = ""
11641171
)
11651172

1173+
# BAD NAME ALERT!
1174+
# regions (plural) is the enum, region (singular) is the collection
11661175
cockpit_regions: bpy.props.EnumProperty(
11671176
name = "Cockpit Regions",
11681177
description = "Number of Cockpit regions to use",
@@ -1183,6 +1192,8 @@ def update_lods(self, context):
11831192
description = "Cockpit Region"
11841193
)
11851194

1195+
# BAD NAME ALERT!
1196+
# lods (plural) is the enum, lod (singular) is the collection
11861197
lods: bpy.props.EnumProperty(
11871198
name = "Levels of Detail",
11881199
description = "Levels of detail",

io_xplane2blender/xplane_types/xplane_header.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ def __init__(self, xplaneFile: "XPlaneFile", obj_version: int) -> None:
8787
self.attributes.add(XPlaneAttribute("COCKPIT_REGION", None))
8888
self.attributes.add(XPlaneAttribute("DEBUG", None))
8989
self.attributes.add(XPlaneAttribute("GLOBAL_cockpit_lit", None))
90-
self.attributes.add(XPlaneAttribute("ATTR_cockpit_lit_only", None))
9190
self.attributes.add(XPlaneAttribute("GLOBAL_tint", None))
9291
self.attributes.add(XPlaneAttribute("REQUIRE_WET", None))
9392
self.attributes.add(XPlaneAttribute("REQUIRE_DRY", None))
@@ -324,7 +323,7 @@ def _init(self):
324323
)
325324

326325
# set cockpit regions
327-
if isCockpit:
326+
if isAircraft or isCockpit:
328327
num_regions = int(self.xplaneFile.options.cockpit_regions)
329328

330329
if num_regions > 0:
@@ -481,15 +480,9 @@ def _init(self):
481480
mat.attributes["ATTR_no_shadow"].setValue(None)
482481

483482
# cockpit_lit
484-
if isCockpit:
483+
if isAircraft or isCockpit:
485484
if self.xplaneFile.options.cockpit_lit or xplane_version >= 1100:
486485
self.attributes["GLOBAL_cockpit_lit"].setValue(True)
487-
if (
488-
self.xplaneFile.options.cockpit_lit_only
489-
and xplane_version >= 1110
490-
and self.xplaneFile.options.cockpit_regions == "0"
491-
):
492-
self.attributes["ATTR_cockpit_lit_only"].setValue(True)
493486

494487
if len(self.export_path_dirs):
495488
self.attributes["EXPORT"].value = [

io_xplane2blender/xplane_types/xplane_material.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ def __init__(self, xplaneObject: xplane_object.XPlaneObject):
8383

8484
self.cockpitAttributes = XPlaneAttributes()
8585
self.cockpitAttributes.add(XPlaneAttribute("ATTR_cockpit", None, 2000))
86-
self.cockpitAttributes.add(XPlaneAttribute("ATTR_no_cockpit", True, 2000))
86+
self.cockpitAttributes.add(XPlaneAttribute("ATTR_cockpit_lit_only", None, 2000))
8787
self.cockpitAttributes.add(XPlaneAttribute("ATTR_cockpit_region", None, 2000))
88+
self.cockpitAttributes.add(XPlaneAttribute("ATTR_no_cockpit", True, 2000))
8889

8990
self.conditions = []
9091

@@ -206,13 +207,29 @@ def collectCustomAttributes(self, mat: bpy.types.Material) -> None:
206207

207208
def collectCockpitAttributes(self, mat: bpy.types.Material) -> None:
208209
if mat.xplane.panel:
209-
self.cockpitAttributes["ATTR_cockpit"].setValue(True)
210-
self.cockpitAttributes["ATTR_no_cockpit"].setValue(None)
210+
xplaneFile = self.xplaneObject.xplaneBone.xplaneFile
211+
xplane_version = int(bpy.context.scene.xplane.version)
212+
cockpit_panel_mode = xplaneFile.options.cockpit_panel_mode
211213
cockpit_region = int(mat.xplane.cockpit_region)
212-
if cockpit_region > 0:
213-
self.cockpitAttributes["ATTR_cockpit_region"].setValue(
214-
cockpit_region - 1
215-
)
214+
215+
self.cockpitAttributes["ATTR_no_cockpit"].setValue(None)
216+
if xplane_version >= 1110:
217+
if cockpit_panel_mode == PANEL_COCKPIT:
218+
self.cockpitAttributes["ATTR_cockpit"].setValue(True)
219+
elif cockpit_panel_mode == PANEL_COCKPIT_LIT_ONLY:
220+
self.cockpitAttributes["ATTR_cockpit_lit_only"].setValue(True)
221+
elif cockpit_panel_mode == PANEL_COCKPIT_REGION and cockpit_region:
222+
self.cockpitAttributes["ATTR_cockpit_region"].setValue(
223+
cockpit_region - 1
224+
)
225+
elif xplane_version < 1110:
226+
# TODO: I believe this is wrong!
227+
# This prints out ATTR_cockpit then region no matter
228+
self.cockpitAttributes["ATTR_cockpit"].setValue(True)
229+
if cockpit_region:
230+
self.cockpitAttributes["ATTR_cockpit_region"].setValue(
231+
cockpit_region - 1
232+
)
216233

217234
def collectLightLevelAttributes(self, mat: bpy.types.Material) -> None:
218235
if mat.xplane.lightLevel:

io_xplane2blender/xplane_ui.py

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,6 @@ def layer_layout(
406406

407407
global_mat_box = layout.box()
408408
global_mat_box.label(text="Global Material Options")
409-
if version >= 1110:
410-
if (
411-
layer_props.export_type == EXPORT_TYPE_COCKPIT
412-
and layer_props.cockpit_regions == "0"
413-
):
414-
global_mat_box.row().prop(layer_props, "cockpit_lit_only")
415409
if version >= 1100:
416410
global_mat_box.row().prop(layer_props, "blend_glass")
417411
global_mat_box.row().prop(layer_props, "normal_metalness")
@@ -428,42 +422,42 @@ def layer_layout(
428422
row.prop(layer_props, "tint_emissive", text="Emissive", slider=True)
429423

430424
# cockpit regions
431-
if layer_props.export_type == EXPORT_TYPE_COCKPIT:
425+
if layer_props.export_type in {EXPORT_TYPE_AIRCRAFT, EXPORT_TYPE_COCKPIT}:
432426
cockpit_box = layout.box()
433-
cockpit_box.label(text="Cockpits")
434-
cockpit_box.prop(layer_props, "cockpit_regions", text="Regions")
435-
num_regions = int(layer_props.cockpit_regions)
436-
437-
if num_regions > 0:
438-
for i in range(0, num_regions):
439-
# get cockpit region or create it if not present
440-
if len(layer_props.cockpit_region) > i:
441-
cockpit_region = layer_props.cockpit_region[i]
442-
443-
if cockpit_region.expanded:
444-
expandIcon = "TRIA_DOWN"
445-
else:
446-
expandIcon = "TRIA_RIGHT"
447-
448-
region_box = cockpit_box.box()
449-
region_box.prop(
450-
cockpit_region,
451-
"expanded",
452-
text="Cockpit region %i" % (i + 1),
453-
expand=True,
454-
emboss=False,
455-
icon=expandIcon,
456-
)
427+
cockpit_box.label(text="Cockpit Panel Options")
428+
if version >= 1110:
429+
cockpit_box.row().prop(layer_props, "cockpit_panel_mode")
430+
431+
if layer_props.cockpit_panel_mode == PANEL_COCKPIT:
432+
pass
433+
elif (
434+
version >= 1110 and layer_props.cockpit_panel_mode == PANEL_COCKPIT_LIT_ONLY
435+
):
436+
pass
437+
elif layer_props.cockpit_panel_mode == PANEL_COCKPIT_REGION or version < 1110:
438+
cockpit_box.prop(layer_props, "cockpit_regions", text="Regions")
439+
for i, cockpit_region in enumerate(
440+
layer_props.cockpit_region[: int(layer_props.cockpit_regions)]
441+
):
442+
region_box = cockpit_box.box()
443+
region_box.prop(
444+
cockpit_region,
445+
"expanded",
446+
text="Cockpit region %i" % (i + 1),
447+
expand=True,
448+
emboss=False,
449+
icon=("TRIA_DOWN" if cockpit_region.expanded else "TRIA_RIGHT"),
450+
)
457451

458-
if cockpit_region.expanded:
459-
region_box.prop(cockpit_region, "left")
460-
region_box.prop(cockpit_region, "top")
461-
region_split = region_box.split(factor=0.5)
462-
region_split.prop(cockpit_region, "width")
463-
region_split.label(text="= %d" % (2 ** cockpit_region.width))
464-
region_split = region_box.split(factor=0.5)
465-
region_split.prop(cockpit_region, "height")
466-
region_split.label(text="= %d" % (2 ** cockpit_region.height))
452+
if cockpit_region.expanded:
453+
region_box.prop(cockpit_region, "left")
454+
region_box.prop(cockpit_region, "top")
455+
region_split = region_box.split(factor=0.5)
456+
region_split.prop(cockpit_region, "width")
457+
region_split.label(text="= %d" % (2 ** cockpit_region.width))
458+
region_split = region_box.split(factor=0.5)
459+
region_split.prop(cockpit_region, "height")
460+
region_split.label(text="= %d" % (2 ** cockpit_region.height))
467461

468462
# v1010
469463
if version < 1100:
-2.58 KB
Binary file not shown.

tests/features/cockpit_lit_only.test.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,33 @@ class TestCockpitLitOnly(XPlaneTestCase):
1616
def test_Scene_1100(self) -> None:
1717
bpy.context.window.scene = bpy.data.scenes["Scene_1100"]
1818

19-
out = self.exportExportableRoot("05_cockpit_lit_only_no_export_wrong_version")
20-
self.assertNotIn("ATTR_cockpit_lit_only", out)
19+
filename = "test_05_cockpit_lit_only_no_export_wrong_version"
20+
self.assertExportableRootExportEqualsFixture(
21+
filename[5:],
22+
os.path.join(__dirname__, "fixtures", f"{filename}.obj"),
23+
{"ATTR_cockpit_lit_only"},
24+
filename,
25+
)
2126

2227
def test_Scene_1110(self) -> None:
2328
bpy.context.window.scene = bpy.data.scenes["Scene_1110"]
2429

25-
out = self.exportExportableRoot("01_cockpit_lit_only_exported")
26-
self.assertIn("ATTR_cockpit_lit_only", out)
27-
for root in [
28-
c
29-
for c in bpy.context.scene.collection.children
30-
if not c.name.startswith("01")
30+
out = self.exportExportableRoot("test_02_cockpit_lit_only_wrong_type_error"[5:])
31+
# Scenery cannot have panel
32+
self.assertLoggerErrors(1)
33+
34+
for filename in [
35+
"test_01_cockpit_lit_only_exported",
36+
"test_03_cockpit_lit_only_no_export_regions",
37+
"test_04_cockpit_lit_no_export_panel_mode_default",
3138
]:
32-
with self.subTest(f"Exporting {root.name}", root=root):
33-
out = self.exportExportableRoot(root)
34-
self.assertNotIn("ATTR_cockpit_lit_only", out)
39+
with self.subTest(f"Testing fixture {filename}", filename=filename):
40+
self.assertExportableRootExportEqualsFixture(
41+
filename[5:],
42+
os.path.join(__dirname__, "fixtures", f"{filename}.obj"),
43+
{"ATTR_cockpit_lit_only"},
44+
filename,
45+
)
3546

3647
def test_Scene_default_version(self) -> None:
3748
bpy.context.window.scene = bpy.data.scenes["Scene_default_version"]
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
I
2+
800
3+
OBJ
4+
5+
GLOBAL_cockpit_lit
6+
POINT_COUNTS 36 0 0 36
7+
8+
VT -1 1 1 0 1 -0 0.625 0.25 # 0
9+
VT -1 1 -1 0 1 -0 0.625 0 # 1
10+
VT 1 1 -1 0 1 -0 0.375 0 # 2
11+
VT 1 1 1 0 1 0 0.375 0.25 # 3
12+
VT -1 1 1 0 1 0 0.625 0.25 # 4
13+
VT 1 1 -1 0 1 0 0.375 0 # 5
14+
VT -1 1 1 0 0 1 0.625 0.5 # 6
15+
VT 1 1 1 0 0 1 0.625 0.25 # 7
16+
VT 1 -1 1 0 0 1 0.375 0.25 # 8
17+
VT -1 -1 1 0 0 1 0.375 0.5 # 9
18+
VT -1 1 1 0 0 1 0.625 0.5 # 10
19+
VT 1 -1 1 0 0 1 0.375 0.25 # 11
20+
VT -1 1 -1 -1 -0 0 0.625 0.75 # 12
21+
VT -1 1 1 -1 -0 0 0.625 0.5 # 13
22+
VT -1 -1 1 -1 -0 0 0.375 0.5 # 14
23+
VT -1 -1 -1 -1 0 0 0.375 0.75 # 15
24+
VT -1 1 -1 -1 0 0 0.625 0.75 # 16
25+
VT -1 -1 1 -1 0 0 0.375 0.5 # 17
26+
VT 1 -1 1 0 -1 -0 0.625 1 # 18
27+
VT 1 -1 -1 0 -1 -0 0.625 0.75 # 19
28+
VT -1 -1 -1 0 -1 -0 0.375 0.75 # 20
29+
VT -1 -1 1 0 -1 -0 0.375 1 # 21
30+
VT 1 -1 1 0 -1 -0 0.625 1 # 22
31+
VT -1 -1 -1 0 -1 -0 0.375 0.75 # 23
32+
VT 1 1 1 1 0 0 0.375 0.75 # 24
33+
VT 1 1 -1 1 0 0 0.375 0.5 # 25
34+
VT 1 -1 -1 1 0 0 0.125 0.5 # 26
35+
VT 1 -1 1 1 0 0 0.125 0.75 # 27
36+
VT 1 1 1 1 0 0 0.375 0.75 # 28
37+
VT 1 -1 -1 1 0 0 0.125 0.5 # 29
38+
VT 1 1 -1 0 0 -1 0.875 0.75 # 30
39+
VT -1 1 -1 0 0 -1 0.875 0.5 # 31
40+
VT -1 -1 -1 0 0 -1 0.625 0.5 # 32
41+
VT 1 -1 -1 0 -0 -1 0.625 0.75 # 33
42+
VT 1 1 -1 0 -0 -1 0.875 0.75 # 34
43+
VT -1 -1 -1 0 -0 -1 0.625 0.5 # 35
44+
45+
IDX10 0 1 2 3 4 5 6 7 8 9
46+
IDX10 10 11 12 13 14 15 16 17 18 19
47+
IDX10 20 21 22 23 24 25 26 27 28 29
48+
IDX 30
49+
IDX 31
50+
IDX 32
51+
IDX 33
52+
IDX 34
53+
IDX 35
54+
55+
# 0 ROOT
56+
# 1 Mesh: Cube
57+
# MESH: Cube weight: 2
58+
# MATERIAL: MaterialPartOfPanel
59+
ATTR_cockpit_lit_only
60+
TRIS 0 36
61+
62+
# Build with Blender 2.80 (sub 75) (build b'f6cb5f54494e'). Exported with XPlane2Blender 4.1.0-dev.0+94.NO_BUILD_NUMBR

0 commit comments

Comments
 (0)