Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ported hubs exporter to 4.x - while keeping backwards compatibility #273

Closed
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ Makefile
lib

#Selenium
__hubs_selenium_profile
__hubs_selenium_profile

#VSCode
.vscode
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"python.analysis.extraPaths": [
"./fake_bpy_modules_3.3-20221006"
],
"python.analysis.diagnosticSeverityOverrides": {
"reportInvalidTypeForm": "none",
},
"editor.defaultFormatter": "ms-python.autopep8",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
Expand Down
4 changes: 2 additions & 2 deletions addons/io_hubs_addon/components/definitions/media_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


def is_bone(ob):
return type(ob) == EditBone or type(ob) == Bone
return type(ob) is EditBone or type(ob) is Bone


class MediaFrameGizmo(Gizmo):
Expand Down Expand Up @@ -157,7 +157,7 @@ def migrate(self, migration_type, panel_type, instance_version, host, migration_
bounds = Vector((bounds.x, bounds.z, bounds.y))
self.bounds = bounds

if migration_type != MigrationType.GLOBAL or is_linked(ob) or type(ob) == bpy.types.Armature:
if migration_type is not MigrationType.GLOBAL or is_linked(ob) or type(ob) is bpy.types.Armature:
host_reference = get_host_reference_message(panel_type, host, ob=ob)
migration_report.append(
f"Warning: The Media Frame component's Y and Z bounds on the {panel_type.value} {host_reference} may not have migrated correctly")
Expand Down
1 change: 1 addition & 0 deletions addons/io_hubs_addon/components/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def find_active_undo_step_index(undo_steps):

@persistent
def undo_stack_handler(dummy, depsgraph):
return # this fails on windows, sys.stdout.fileno() is not supported
global previous_undo_steps_dump
global previous_undo_step_index
global file_loading
Expand Down
1 change: 1 addition & 0 deletions addons/io_hubs_addon/components/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def c_fflush():

@contextmanager
def redirect_c_stdout(binary_stream):
# this causes an error on windows when the addon is enabled using: bpy.ops.preferences.addon_enable(module="io_hubs_addon")
stdout_file_descriptor = sys.stdout.fileno()
original_stdout_file_descriptor_copy = os.dup(stdout_file_descriptor)
try:
Expand Down
1 change: 0 additions & 1 deletion addons/io_hubs_addon/io/gltf_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ def gather_material_hook(self, gltf2_object, blender_material, export_settings):

self.add_hubs_components(
gltf2_object, blender_material, export_settings)

from .utils import gather_lightmap_texture_info
if blender_material.node_tree and blender_material.use_nodes:
lightmap_texture_info = gather_lightmap_texture_info(
Expand Down
16 changes: 6 additions & 10 deletions addons/io_hubs_addon/io/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,8 @@ def gather_image(blender_image, export_settings):
mime_type = "image/png"
else:
mime_type = "image/jpeg"

data = HubsExportImage.from_blender_image(blender_image).encode(mime_type, export_settings)

if type(data) == tuple:
if type(data) is tuple:
data = data[0]

if export_settings['gltf_format'] == 'GLTF_SEPARATE':
Expand All @@ -105,7 +103,6 @@ def gather_image(blender_image, export_settings):
@cached
def gather_texture(blender_image, export_settings):
image = gather_image(blender_image, export_settings)

if not image:
return None

Expand Down Expand Up @@ -159,13 +156,13 @@ def gather_property(export_settings, blender_object, target, property_name):
return gather_vec_property(export_settings, blender_object, target, property_name)

elif (property_definition.bl_rna.identifier == 'PointerProperty'):
if type(property_value) == bpy.types.Object:
if type(property_value) is bpy.types.Object:
return gather_node_property(export_settings, blender_object, target, property_name)
elif type(property_value) == bpy.types.Material:
elif type(property_value) is bpy.types.Material:
return gather_material_property(export_settings, blender_object, target, property_name)
elif type(property_value) == bpy.types.Image:
elif type(property_value) is bpy.types.Image:
return gather_image_property(export_settings, blender_object, target, property_name)
elif type(property_value) == bpy.types.Texture:
elif type(property_value) is bpy.types.Texture:
return gather_texture_property(export_settings, blender_object, target, property_name)

return gltf2_blender_extras.__to_json_compatible(property_value)
Expand Down Expand Up @@ -337,14 +334,13 @@ def gather_lightmap_texture_info(blender_material, export_settings):

if not lightmap_node:
return

texture_socket = lightmap_node.inputs.get("Lightmap")
intensity = lightmap_node.intensity

# TODO this assumes a single image directly connected to the socket
blender_image = texture_socket.links[0].from_node.image
texture = gather_texture(blender_image, export_settings)
if bpy.app.version < (3, 2, 0):
if bpy.app.version < (3, 2, 0) or bpy.app.version >= (4, 0, 0):
tex_transform, tex_coord = gltf2_blender_gather_texture_info.__gather_texture_transform_and_tex_coord(
texture_socket, export_settings)
else:
Expand Down
49 changes: 46 additions & 3 deletions addons/io_hubs_addon/nodes/lightmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ def poll(cls, context):
]


class NODE_MT_mozilla_hubs_nodes(bpy.types.Menu):
"""Add node menu for Blender 4.x"""
bl_label = "Hubs"
bl_idname = "NODE_MT_mozilla_hubs_nodes"

def draw(self, context):
layout = self.layout
layout.operator("node.add_node", text="MOZ_lightmap settings").type = "moz_lightmap.node"


class MozLightmapNode(Node):
"""MOZ_lightmap settings node"""
bl_idname = 'moz_lightmap.node'
bl_label = 'MOZ_lightmap settings'
bl_icon = 'LIGHT'
bl_width_min = 216.3
bl_width_max = 330.0

intensity: bpy.props.FloatProperty(
name="Intensity", soft_min=0, soft_max=1, default=1)

Expand All @@ -46,11 +55,45 @@ def draw_label(self):
return "MOZ_lightmap"


def register():
def create_node_categories():
return [NodeCategory("MOZ_NODES", "Moz Nodes", items=node_categories)]


def menu_func(self, context):
self.layout.menu("NODE_MT_mozilla_hubs_nodes")


def register_blender_4():
bpy.utils.register_class(NODE_MT_mozilla_hubs_nodes)
bpy.types.NODE_MT_shader_node_add_all.append(menu_func)
bpy.utils.register_class(MozLightmapNode)


def unregister_blender_4():
bpy.types.NODE_MT_shader_node_add_all.remove(menu_func)
bpy.utils.unregister_class(NODE_MT_mozilla_hubs_nodes)
bpy.utils.unregister_class(MozLightmapNode)


def register_blender_3():
bpy.utils.register_class(MozLightmapNode)
nodeitems_utils.register_node_categories("MOZ_NODES", node_categories)


def unregister():
def unregister_blender_3():
bpy.utils.unregister_class(MozLightmapNode)
nodeitems_utils.unregister_node_categories("MOZ_NODES")


def register():
if bpy.app.version < (4, 0, 0):
register_blender_3()
else:
register_blender_4()


def unregister():
if bpy.app.version < (4, 0, 0):
unregister_blender_3()
else:
unregister_blender_4()
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 28 additions & 27 deletions tests/export_gltf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,35 @@
import os
import sys

bpy.ops.preferences.addon_enable(module="io_hubs_addon")

try:
argv = sys.argv
if "--" in argv:
argv = argv[argv.index("--") + 1:] # get all args after "--"
else:
argv = []
bpy.ops.preferences.addon_enable(module="io_hubs_addon") #it throws an error on windows and it's not necessary, since the commandline already enables the addon

extension = '.gltf'
if '--glb' in argv:
extension = '.glb'
#try:
argv = sys.argv
if "--" in argv:
argv = argv[argv.index("--") + 1:] # get all args after "--"
else:
argv = []

path = os.path.splitext(bpy.data.filepath)[0] + extension
path_parts = os.path.split(path)
output_dir = os.path.join(path_parts[0], argv[0])
if not os.path.exists(output_dir):
os.makedirs(output_dir)
args = {
# Settings from "Remember Export Settings"
**dict(bpy.context.scene.get('glTF2ExportSettings', {})),
extension = '.glb' if '--glb' in argv else '.gltf'

'export_format': ('GLB' if extension == '.glb' else 'GLTF_SEPARATE'),
'filepath': os.path.join(output_dir, path_parts[1]),
'export_cameras': True,
'export_extras': True
}
bpy.ops.export_scene.gltf(**args)
except Exception as err:
print(err, file=sys.stderr)
sys.exit(1)
path = os.path.splitext(bpy.data.filepath)[0] + extension
path_parts = os.path.split(path)
output_dir = os.path.join(path_parts[0], argv[0])
print("Saving to " + output_dir)
# if not os.path.exists(output_dir): #no need, Blender export always creates the dirs
# os.makedirs(output_dir)
args = {
# Settings from "Remember Export Settings"
**dict(bpy.context.scene.get('glTF2ExportSettings', {})),

'export_format': ('GLB' if extension == '.glb' else 'GLTF_SEPARATE'),
'filepath': output_dir,#, path_parts[1]),
'export_cameras': True,
'export_extras': True
}
print("Got args, exporting")
bpy.ops.export_scene.gltf(**args)
# except Exception as err:
# print(err, file=sys.stderr)
# sys.exit(1)
7 changes: 5 additions & 2 deletions tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
"name": "io-hubs-addon-tests",
"version": "1.0.0",
"description": "Test suite for io-hubs-addon",
"dependencies": {},
"dependencies": {
"g": "^2.0.1",
"yarn": "^1.22.22"
},
"devDependencies": {
"eslint": "^6.8.0",
"gltf-validator": "^2.0.0-dev.3.2",
Expand All @@ -19,4 +22,4 @@
"mocha": {
"timeout": 60000
}
}
}
62 changes: 31 additions & 31 deletions tests/roundtrip_gltf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,37 @@
import os
import sys

try:
argv = sys.argv
if "--" in argv:
argv = argv[argv.index("--") + 1:] # get all args after "--"
else:
argv = []
#try:
argv = sys.argv
if "--" in argv:
argv = argv[argv.index("--") + 1:] # get all args after "--"
else:
argv = []

filepath = argv[0]
filepath = argv[0]
print("Filepath: " + filepath)
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
bpy.ops.import_scene.gltf(filepath=argv[0])
print("Importing: " + argv[0])
extension = '.gltf'
export_format = 'GLTF_SEPARATE'
if '--glb' in argv:
extension = '.glb'
export_format = 'GLB'

bpy.ops.import_scene.gltf(filepath=argv[0])

extension = '.gltf'
export_format = 'GLTF_SEPARATE'
if '--glb' in argv:
extension = '.glb'
export_format = 'GLB'

path = os.path.splitext(filepath)[0] + extension
path_parts = os.path.split(path)
output_dir = os.path.join(path_parts[0], argv[1])
if not os.path.exists(output_dir):
os.makedirs(output_dir)
if '--no-sample-anim' in argv:
bpy.ops.export_scene.gltf(export_format=export_format, filepath=os.path.join(
output_dir, path_parts[1]), export_force_sampling=False)
else:
bpy.ops.export_scene.gltf(
export_format=export_format, filepath=os.path.join(output_dir, path_parts[1]))
except Exception as err:
print(err, file=sys.stderr)
sys.exit(1)
path = os.path.splitext(filepath)[0] + extension
path_parts = os.path.split(path)
output_dir = os.path.join(path_parts[0], argv[1])
if not os.path.exists(output_dir):
os.makedirs(output_dir)
if '--no-sample-anim' in argv:
bpy.ops.export_scene.gltf(export_format=export_format, filepath=os.path.join(
output_dir, path_parts[1]), export_force_sampling=False)
else:
bpy.ops.export_scene.gltf(
export_format=export_format, filepath=os.path.join(output_dir, path_parts[1]))
# except Exception as err:
# print(err, file=sys.stderr)
# sys.exit(1)
18 changes: 12 additions & 6 deletions tests/test/test_export.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const blenderVersions = (() => {
"blender"
];
}
else if (process.platform == 'win32') {
return [
"C:\\Program Files\\Blender Foundation\\Blender 3.6\\blender.exe",
];
}
})();

var utils = require('./utils.js').utils;
Expand All @@ -32,15 +37,16 @@ describe('Exporter', function () {

variants.forEach(function (variant) {
const args = variant[1];
describe(blenderVersion + '_export' + variant[0], function () {
describe(blenderVersion + ', exporting:' + variant[0], function () {
blenderSampleScenes.forEach((scene) => {
it(scene, function (done) {
let outDirName = 'out' + blenderVersion + variant[0];
let blenderPath = `scenes/${scene}.blend`;
let ext = args.indexOf('--glb') === -1 ? '.gltf' : '.glb';
let outDirPath = path.resolve(OUT_PREFIX, 'scenes', outDirName);
let outDirPath = path.resolve(OUT_PREFIX, 'scenes');
let dstPath = path.resolve(outDirPath, `${scene}${ext}`);
utils.blenderFileToGltf(blenderVersion, blenderPath, outDirPath, (error) => {
//utils.blenderFileToGltf(blenderVersion, blenderPath, outDirPath, (error) => {
utils.blenderFileToGltf(blenderVersion, blenderPath, dstPath, (error) => {
if (error)
return done(error);

Expand All @@ -51,9 +57,9 @@ describe('Exporter', function () {
});
});

describe(blenderVersion + '_export_results', function () {
let outDirName = 'out' + blenderVersion;
let outDirPath = path.resolve(OUT_PREFIX, 'scenes', outDirName);
describe(blenderVersion + ' export_results', function () {
let outDirName = 'out';// + blenderVersion;
let outDirPath = path.resolve(OUT_PREFIX, 'scenes');//, outDirName);

it('can export link', function () {
let gltfPath = path.resolve(outDirPath, 'link.gltf');
Expand Down
Loading
Loading