applied black formatting to files changed in the future

This commit is contained in:
thecozies
2022-06-30 18:41:22 -05:00
parent 161b8dca0f
commit 1990eb7ff0
14 changed files with 21341 additions and 18417 deletions
+366 -352
View File
@@ -17,440 +17,454 @@ from . import addon_updater_ops
# info about add on
bl_info = {
"name": "Fast64",
"version": (1, 0, 0),
"author": "kurethedead",
"location": "3DView",
"description": "Plugin for exporting F3D display lists and other game data related to Super Mario 64.",
"category": "Import-Export",
"blender": (2, 82, 0),
}
"name": "Fast64",
"version": (1, 0, 0),
"author": "kurethedead",
"location": "3DView",
"description": "Plugin for exporting F3D display lists and other game data related to Super Mario 64.",
"category": "Import-Export",
"blender": (2, 82, 0),
}
gameEditorEnum = (
("SM64", "SM64", "Super Mario 64"),
("OOT", "OOT", "Ocarina Of Time"),
("SM64", "SM64", "Super Mario 64"),
("OOT", "OOT", "Ocarina Of Time"),
)
class ArmatureApplyWithMesh(bpy.types.Operator):
# set bl_ properties
bl_description = 'Applies current pose as default pose. Useful for ' + \
"rigging an armature that is not in T/A pose. Note that when using " +\
" with an SM64 armature, you must revert to the default pose after " +\
"skinning."
bl_idname = 'object.armature_apply_w_mesh'
bl_label = "Apply As Rest Pose"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
bl_description = (
"Applies current pose as default pose. Useful for "
+ "rigging an armature that is not in T/A pose. Note that when using "
+ " with an SM64 armature, you must revert to the default pose after "
+ "skinning."
)
bl_idname = "object.armature_apply_w_mesh"
bl_label = "Apply As Rest Pose"
bl_options = {"REGISTER", "UNDO", "PRESET"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode = "OBJECT")
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not\
bpy.types.Armature:
raise PluginError("Armature not selected.")
armatureObj = context.selected_objects[0]
for child in armatureObj.children:
if type(child.data) is not bpy.types.Mesh:
continue
armatureModifier = None
for modifier in child.modifiers:
if isinstance(modifier, bpy.types.ArmatureModifier):
armatureModifier = modifier
if armatureModifier is None:
continue
print(armatureModifier.name)
bpy.ops.object.select_all(action = "DESELECT")
context.view_layer.objects.active = child
bpy.ops.object.modifier_copy(modifier=armatureModifier.name)
print(len(child.modifiers))
attemptModifierApply(armatureModifier)
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
raise PluginError("Armature not selected.")
bpy.ops.object.select_all(action = "DESELECT")
context.view_layer.objects.active = armatureObj
bpy.ops.object.mode_set(mode = "POSE")
bpy.ops.pose.armature_apply()
if context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode = "OBJECT")
except Exception as e:
if context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode = "OBJECT")
raisePluginError(self, e)
return {"CANCELLED"}
armatureObj = context.selected_objects[0]
for child in armatureObj.children:
if type(child.data) is not bpy.types.Mesh:
continue
armatureModifier = None
for modifier in child.modifiers:
if isinstance(modifier, bpy.types.ArmatureModifier):
armatureModifier = modifier
if armatureModifier is None:
continue
print(armatureModifier.name)
bpy.ops.object.select_all(action="DESELECT")
context.view_layer.objects.active = child
bpy.ops.object.modifier_copy(modifier=armatureModifier.name)
print(len(child.modifiers))
attemptModifierApply(armatureModifier)
bpy.ops.object.select_all(action="DESELECT")
context.view_layer.objects.active = armatureObj
bpy.ops.object.mode_set(mode="POSE")
bpy.ops.pose.armature_apply()
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")
except Exception as e:
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")
raisePluginError(self, e)
return {"CANCELLED"}
self.report({"INFO"}, "Applied armature with mesh.")
return {"FINISHED"} # must return a set
self.report({'INFO'}, 'Applied armature with mesh.')
return {'FINISHED'} # must return a set
class AddBoneGroups(bpy.types.Operator):
# set bl_ properties
bl_description = 'Add bone groups respresenting other node types in ' +\
'SM64 geolayouts (ex. Shadow, Switch, Function).'
bl_idname = 'object.add_bone_groups'
bl_label = "Add Bone Groups"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
bl_description = (
"Add bone groups respresenting other node types in " + "SM64 geolayouts (ex. Shadow, Switch, Function)."
)
bl_idname = "object.add_bone_groups"
bl_label = "Add Bone Groups"
bl_options = {"REGISTER", "UNDO", "PRESET"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != 'OBJECT' and context.mode != 'POSE':
raise PluginError("Operator can only be used in object or pose mode.")
elif context.mode == 'POSE':
bpy.ops.object.mode_set(mode = "OBJECT")
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != "OBJECT" and context.mode != "POSE":
raise PluginError("Operator can only be used in object or pose mode.")
elif context.mode == "POSE":
bpy.ops.object.mode_set(mode="OBJECT")
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not\
bpy.types.Armature:
raise PluginError("Armature not selected.")
armatureObj = context.selected_objects[0]
createBoneGroups(armatureObj)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
raise PluginError("Armature not selected.")
armatureObj = context.selected_objects[0]
createBoneGroups(armatureObj)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
self.report({"INFO"}, "Created bone groups.")
return {"FINISHED"} # must return a set
self.report({'INFO'}, 'Created bone groups.')
return {'FINISHED'} # must return a set
class CreateMetarig(bpy.types.Operator):
# set bl_ properties
bl_description = 'SM64 imported armatures are usually not good for ' + \
'rigging. There are often intermediate bones between deform bones ' + \
'and they don\'t usually point to their children. This operator ' +\
'creates a metarig on armature layer 4 useful for IK.'
bl_idname = 'object.create_metarig'
bl_label = "Create Animatable Metarig"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
bl_description = (
"SM64 imported armatures are usually not good for "
+ "rigging. There are often intermediate bones between deform bones "
+ "and they don't usually point to their children. This operator "
+ "creates a metarig on armature layer 4 useful for IK."
)
bl_idname = "object.create_metarig"
bl_label = "Create Animatable Metarig"
bl_options = {"REGISTER", "UNDO", "PRESET"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != 'OBJECT':
bpy.ops.object.mode_set(mode = "OBJECT")
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != "OBJECT":
bpy.ops.object.mode_set(mode="OBJECT")
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not\
bpy.types.Armature:
raise PluginError("Armature not selected.")
armatureObj = context.selected_objects[0]
generateMetarig(armatureObj)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
if len(context.selected_objects) == 0:
raise PluginError("Armature not selected.")
elif type(context.selected_objects[0].data) is not bpy.types.Armature:
raise PluginError("Armature not selected.")
armatureObj = context.selected_objects[0]
generateMetarig(armatureObj)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
self.report({"INFO"}, "Created metarig.")
return {"FINISHED"} # must return a set
self.report({'INFO'}, 'Created metarig.')
return {'FINISHED'} # must return a set
class SM64_AddWaterBox(AddWaterBox):
bl_idname = 'object.sm64_add_water_box'
bl_idname = "object.sm64_add_water_box"
scale: bpy.props.FloatProperty(default=10)
preset: bpy.props.StringProperty(default="Shaded Solid")
matName: bpy.props.StringProperty(default="sm64_water_mat")
def setEmptyType(self, emptyObj):
emptyObj.sm64_obj_type = "Water Box"
scale : bpy.props.FloatProperty(default = 10)
preset : bpy.props.StringProperty(default = "Shaded Solid")
matName : bpy.props.StringProperty(default = "sm64_water_mat")
def setEmptyType(self, emptyObj):
emptyObj.sm64_obj_type = "Water Box"
class SM64_ArmatureToolsPanel(SM64_Panel):
bl_idname = "SM64_PT_armature_tools"
bl_label = "SM64 Tools"
bl_idname = "SM64_PT_armature_tools"
bl_label = "SM64 Tools"
# called every frame
def draw(self, context):
col = self.layout.column()
col.operator(ArmatureApplyWithMesh.bl_idname)
col.operator(AddBoneGroups.bl_idname)
col.operator(CreateMetarig.bl_idname)
col.operator(SM64_AddWaterBox.bl_idname)
# called every frame
def draw(self, context):
col = self.layout.column()
col.operator(ArmatureApplyWithMesh.bl_idname)
col.operator(AddBoneGroups.bl_idname)
col.operator(CreateMetarig.bl_idname)
col.operator(SM64_AddWaterBox.bl_idname)
class F3D_GlobalSettingsPanel(bpy.types.Panel):
bl_idname = "F3D_PT_global_settings"
bl_label = "F3D Global Settings"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Fast64'
bl_idname = "F3D_PT_global_settings"
bl_label = "F3D Global Settings"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Fast64"
@classmethod
def poll(cls, context):
return True
@classmethod
def poll(cls, context):
return True
# called every frame
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
prop_split(col, context.scene, "f3d_type", "F3D Microcode")
col.prop(context.scene, "isHWv1")
col.prop(context.scene, "saveTextures")
col.prop(context.scene, "f3d_simple", text="Simple Material UI")
col.prop(context.scene, "generateF3DNodeGraph", text="Generate F3D Node Graph For Materials")
col.prop(context.scene, "decomp_compatible", invert_checkbox=True, text="Homebrew Compatibility")
col.prop(context.scene, "ignoreTextureRestrictions")
if context.scene.ignoreTextureRestrictions:
col.box().label(text="Width/height must be < 1024. Must be RGBA32. Must be png format.")
# called every frame
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
prop_split(col, context.scene, 'f3d_type', "F3D Microcode")
col.prop(context.scene, 'isHWv1')
col.prop(context.scene, 'saveTextures')
col.prop(context.scene, 'f3d_simple', text = "Simple Material UI")
col.prop(context.scene, 'generateF3DNodeGraph', text = "Generate F3D Node Graph For Materials")
col.prop(context.scene, 'decomp_compatible', invert_checkbox = True, text = 'Homebrew Compatibility')
col.prop(context.scene, 'ignoreTextureRestrictions')
if context.scene.ignoreTextureRestrictions:
col.box().label(text = "Width/height must be < 1024. Must be RGBA32. Must be png format.")
class Fast64_GlobalObjectPanel(bpy.types.Panel):
bl_label = "Global Object Inspector"
bl_idname = "OBJECT_PT_OOT_Global_Object_Inspector"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
bl_options = {'HIDE_HEADER'}
bl_label = "Global Object Inspector"
bl_idname = "OBJECT_PT_OOT_Global_Object_Inspector"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
bl_options = {"HIDE_HEADER"}
@classmethod
def poll(cls, context):
return (context.object is not None and context.object.data is None)
@classmethod
def poll(cls, context):
return context.object is not None and context.object.data is None
def draw(self, context):
box = self.layout
prop_split(box, context.scene, "gameEditorMode", "Game")
def draw(self, context):
box = self.layout
prop_split(box, context.scene, 'gameEditorMode', "Game")
class Fast64_GlobalSettingsPanel(bpy.types.Panel):
bl_idname = "FAST64_PT_global_settings"
bl_label = "Fast64 Global Settings"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Fast64'
bl_idname = "FAST64_PT_global_settings"
bl_label = "Fast64 Global Settings"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Fast64"
@classmethod
def poll(cls, context):
return True
@classmethod
def poll(cls, context):
return True
# called every frame
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
prop_split(col, context.scene, "gameEditorMode", "Game")
col.prop(context.scene, "exportHiddenGeometry")
col.prop(context.scene, "fullTraceback")
prop_split(col, context.scene.fast64.settings, "anim_range_choice", "Anim Range")
# called every frame
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
prop_split(col, context.scene, 'gameEditorMode', "Game")
col.prop(context.scene, 'exportHiddenGeometry')
col.prop(context.scene, 'fullTraceback')
prop_split(col, context.scene.fast64.settings, 'anim_range_choice', 'Anim Range')
class Fast64_GlobalToolsPanel(bpy.types.Panel):
bl_idname = "FAST64_PT_global_tools"
bl_label = "Fast64 Tools"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Fast64'
bl_idname = "FAST64_PT_global_tools"
bl_label = "Fast64 Tools"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Fast64"
@classmethod
def poll(cls, context):
return True
@classmethod
def poll(cls, context):
return True
# called every frame
def draw(self, context):
col = self.layout.column()
col.operator(ArmatureApplyWithMesh.bl_idname)
# col.operator(CreateMetarig.bl_idname)
addon_updater_ops.update_notice_box_ui(self, context)
# called every frame
def draw(self, context):
col = self.layout.column()
col.operator(ArmatureApplyWithMesh.bl_idname)
#col.operator(CreateMetarig.bl_idname)
addon_updater_ops.update_notice_box_ui(self, context)
class Fast64Settings_Properties(bpy.types.PropertyGroup):
'''Settings affecting exports for all games found in scene.fast64.settings'''
version: bpy.props.IntProperty(name="Fast64Settings_Properties Version", default=0)
"""Settings affecting exports for all games found in scene.fast64.settings"""
version: bpy.props.IntProperty(name="Fast64Settings_Properties Version", default=0)
anim_range_choice: bpy.props.EnumProperty(
name="Anim Range",
description="What to use to determine what frames of the animation to export",
items=[
("action", "Action", "Export all frames from the action", 0),
(
"scene",
"Playback",
(
"Export all frames in the scene's animation preview playback range.\n"
"(export frames being played in Blender)"
),
1,
),
(
"intersect_action_and_scene",
"Smart",
(
"Intersect Action & Scene\n"
"Export all frames from the action that are also in the scene playback range.\n"
"(export frames being played in Blender that also are part of the action frames)"
),
2,
),
],
default="intersect_action_and_scene",
)
anim_range_choice: bpy.props.EnumProperty(
name="Anim Range",
description="What to use to determine what frames of the animation to export",
items=[
(
"action",
"Action",
"Export all frames from the action",
0
),
(
"scene",
"Playback",
(
"Export all frames in the scene's animation preview playback range.\n"
"(export frames being played in Blender)"
),
1,
),
(
"intersect_action_and_scene",
"Smart",
(
"Intersect Action & Scene\n"
"Export all frames from the action that are also in the scene playback range.\n"
"(export frames being played in Blender that also are part of the action frames)"
),
2,
),
],
default="intersect_action_and_scene",
)
class Fast64_Properties(bpy.types.PropertyGroup):
'''
Properties in scene.fast64.
All new properties should be children of one of these three property groups.
'''
sm64: bpy.props.PointerProperty(type=SM64_Properties, name="SM64 Properties")
oot: bpy.props.PointerProperty(type=OOT_Properties, name="OOT Properties")
settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings")
"""
Properties in scene.fast64.
All new properties should be children of one of these three property groups.
"""
sm64: bpy.props.PointerProperty(type=SM64_Properties, name="SM64 Properties")
oot: bpy.props.PointerProperty(type=OOT_Properties, name="OOT Properties")
settings: bpy.props.PointerProperty(type=Fast64Settings_Properties, name="Fast64 Settings")
class Fast64_BoneProperties(bpy.types.PropertyGroup):
'''
Properties in bone.fast64 (bpy.types.Bone)
All new bone properties should be children of this property group.
'''
sm64: bpy.props.PointerProperty(type=SM64_BoneProperties, name="SM64 Properties")
"""
Properties in bone.fast64 (bpy.types.Bone)
All new bone properties should be children of this property group.
"""
sm64: bpy.props.PointerProperty(type=SM64_BoneProperties, name="SM64 Properties")
class Fast64_ObjectProperties(bpy.types.PropertyGroup):
'''
Properties in object.fast64 (bpy.types.Object)
All new object properties should be children of this property group.
'''
sm64: bpy.props.PointerProperty(type=SM64_ObjectProperties, name="SM64 Object Properties")
oot: bpy.props.PointerProperty(type=OOT_ObjectProperties, name="OOT Object Properties")
"""
Properties in object.fast64 (bpy.types.Object)
All new object properties should be children of this property group.
"""
sm64: bpy.props.PointerProperty(type=SM64_ObjectProperties, name="SM64 Object Properties")
oot: bpy.props.PointerProperty(type=OOT_ObjectProperties, name="OOT Object Properties")
#def updateGameEditor(scene, context):
# if scene.currentGameEditorMode == 'SM64':
# sm64_panel_unregister()
# elif scene.currentGameEditorMode == 'Z64':
# oot_panel_unregister()
# else:
# raise PluginError("Unhandled game editor mode " + str(scene.currentGameEditorMode))
# def updateGameEditor(scene, context):
# if scene.currentGameEditorMode == 'SM64':
# sm64_panel_unregister()
# elif scene.currentGameEditorMode == 'Z64':
# oot_panel_unregister()
# else:
# raise PluginError("Unhandled game editor mode " + str(scene.currentGameEditorMode))
#
# if scene.gameEditorMode == 'SM64':
# sm64_panel_register()
# elif scene.gameEditorMode == 'Z64':
# oot_panel_register()
# else:
# raise PluginError("Unhandled game editor mode " + str(scene.gameEditorMode))
# if scene.gameEditorMode == 'SM64':
# sm64_panel_register()
# elif scene.gameEditorMode == 'Z64':
# oot_panel_register()
# else:
# raise PluginError("Unhandled game editor mode " + str(scene.gameEditorMode))
#
# scene.currentGameEditorMode = scene.gameEditorMode
# scene.currentGameEditorMode = scene.gameEditorMode
class ExampleAddonPreferences(bpy.types.AddonPreferences, addon_updater_ops.AddonUpdaterPreferences):
bl_idname = __package__
bl_idname = __package__
def draw(self, context):
addon_updater_ops.update_settings_ui(self, context)
def draw(self, context):
addon_updater_ops.update_settings_ui(self, context)
classes = (
Fast64Settings_Properties,
Fast64_Properties,
Fast64_BoneProperties,
Fast64_ObjectProperties,
ArmatureApplyWithMesh,
AddBoneGroups,
CreateMetarig,
SM64_AddWaterBox,
#Fast64_GlobalObjectPanel,
F3D_GlobalSettingsPanel,
Fast64_GlobalSettingsPanel,
SM64_ArmatureToolsPanel,
Fast64_GlobalToolsPanel,
Fast64Settings_Properties,
Fast64_Properties,
Fast64_BoneProperties,
Fast64_ObjectProperties,
ArmatureApplyWithMesh,
AddBoneGroups,
CreateMetarig,
SM64_AddWaterBox,
# Fast64_GlobalObjectPanel,
F3D_GlobalSettingsPanel,
Fast64_GlobalSettingsPanel,
SM64_ArmatureToolsPanel,
Fast64_GlobalToolsPanel,
)
def upgrade_changed_props():
'''Set scene properties after a scene loads, used for migrating old properties'''
SM64_Properties.upgrade_changed_props()
SM64_ObjectProperties.upgrade_changed_props()
"""Set scene properties after a scene loads, used for migrating old properties"""
SM64_Properties.upgrade_changed_props()
SM64_ObjectProperties.upgrade_changed_props()
@bpy.app.handlers.persistent
def after_load(_a, _b):
upgrade_changed_props()
upgrade_changed_props()
# called on add-on enabling
# register operators and panels here
# append menu layout drawing function to an existing window
def register():
if bpy.app.version >= (3, 1, 0):
msg = "\n".join(
(
"This version of Fast64 does not work properly in Blender 3.1.0 and later Blender versions.",
"Your Blender version is: " + ".".join(str(i) for i in bpy.app.version),
"This is a known issue, the fix is not trivial and is in progress.",
"See the GitHub issue: https://github.com/Fast-64/fast64/issues/85",
"If it has been resolved, update Fast64.",
)
)
print(msg)
blender_3_1_0_and_later_unsupported = Exception("\n\n" + msg)
raise blender_3_1_0_and_later_unsupported
if bpy.app.version >= (3, 1, 0):
msg = "\n".join(
(
"This version of Fast64 does not work properly in Blender 3.1.0 and later Blender versions.",
"Your Blender version is: " + ".".join(str(i) for i in bpy.app.version),
"This is a known issue, the fix is not trivial and is in progress.",
"See the GitHub issue: https://github.com/Fast-64/fast64/issues/85",
"If it has been resolved, update Fast64.",
)
)
print(msg)
blender_3_1_0_and_later_unsupported = Exception("\n\n" + msg)
raise blender_3_1_0_and_later_unsupported
# Register addon updater first,
# this way if a broken version fails to register the user can still pick another version.
register_class(ExampleAddonPreferences)
addon_updater_ops.register(bl_info)
# Register addon updater first,
# this way if a broken version fails to register the user can still pick another version.
register_class(ExampleAddonPreferences)
addon_updater_ops.register(bl_info)
mat_register()
render_engine_register()
bsdf_conv_register()
sm64_register(True)
oot_register(True)
mat_register()
render_engine_register()
bsdf_conv_register()
sm64_register(True)
oot_register(True)
for cls in classes:
register_class(cls)
for cls in classes:
register_class(cls)
bsdf_conv_panel_regsiter()
f3d_writer_register()
f3d_parser_register()
bsdf_conv_panel_regsiter()
f3d_writer_register()
f3d_parser_register()
# ROM
bpy.types.Scene.decomp_compatible = bpy.props.BoolProperty(
name = 'Decomp Compatibility', default = True)
bpy.types.Scene.ignoreTextureRestrictions = bpy.props.BoolProperty(
name = 'Ignore Texture Restrictions (Breaks CI Textures)')
bpy.types.Scene.fullTraceback = \
bpy.props.BoolProperty(name = 'Show Full Error Traceback', default = False)
bpy.types.Scene.gameEditorMode = bpy.props.EnumProperty(
name = 'Game', default = 'SM64', items = gameEditorEnum)
bpy.types.Scene.saveTextures = bpy.props.BoolProperty(
name = 'Save Textures As PNGs (Breaks CI Textures)')
bpy.types.Scene.generateF3DNodeGraph = bpy.props.BoolProperty(name = "Generate F3D Node Graph", default = True)
bpy.types.Scene.exportHiddenGeometry = bpy.props.BoolProperty(name = "Export Hidden Geometry", default = True)
bpy.types.Scene.blenderF3DScale = bpy.props.FloatProperty(name = "F3D Blender Scale", default = 100)
# ROM
bpy.types.Scene.fast64 = bpy.props.PointerProperty(type=Fast64_Properties, name="Fast64 Properties")
bpy.types.Bone.fast64 = bpy.props.PointerProperty(type=Fast64_BoneProperties, name="Fast64 Bone Properties")
bpy.types.Object.fast64 = bpy.props.PointerProperty(type=Fast64_ObjectProperties, name="Fast64 Object Properties")
bpy.types.Scene.decomp_compatible = bpy.props.BoolProperty(name="Decomp Compatibility", default=True)
bpy.types.Scene.ignoreTextureRestrictions = bpy.props.BoolProperty(
name="Ignore Texture Restrictions (Breaks CI Textures)"
)
bpy.types.Scene.fullTraceback = bpy.props.BoolProperty(name="Show Full Error Traceback", default=False)
bpy.types.Scene.gameEditorMode = bpy.props.EnumProperty(name="Game", default="SM64", items=gameEditorEnum)
bpy.types.Scene.saveTextures = bpy.props.BoolProperty(name="Save Textures As PNGs (Breaks CI Textures)")
bpy.types.Scene.generateF3DNodeGraph = bpy.props.BoolProperty(name="Generate F3D Node Graph", default=True)
bpy.types.Scene.exportHiddenGeometry = bpy.props.BoolProperty(name="Export Hidden Geometry", default=True)
bpy.types.Scene.blenderF3DScale = bpy.props.FloatProperty(name="F3D Blender Scale", default=100)
bpy.types.Scene.fast64 = bpy.props.PointerProperty(type=Fast64_Properties, name="Fast64 Properties")
bpy.types.Bone.fast64 = bpy.props.PointerProperty(type=Fast64_BoneProperties, name="Fast64 Bone Properties")
bpy.types.Object.fast64 = bpy.props.PointerProperty(type=Fast64_ObjectProperties, name="Fast64 Object Properties")
bpy.app.handlers.load_post.append(after_load)
bpy.app.handlers.load_post.append(after_load)
# called on add-on disabling
def unregister():
f3d_writer_unregister()
f3d_parser_unregister()
sm64_unregister(True)
oot_unregister(True)
mat_unregister()
bsdf_conv_unregister()
bsdf_conv_panel_unregsiter()
render_engine_unregister()
f3d_writer_unregister()
f3d_parser_unregister()
sm64_unregister(True)
oot_unregister(True)
mat_unregister()
bsdf_conv_unregister()
bsdf_conv_panel_unregsiter()
render_engine_unregister()
del bpy.types.Scene.fullTraceback
del bpy.types.Scene.decomp_compatible
del bpy.types.Scene.ignoreTextureRestrictions
del bpy.types.Scene.saveTextures
del bpy.types.Scene.gameEditorMode
del bpy.types.Scene.generateF3DNodeGraph
del bpy.types.Scene.exportHiddenGeometry
del bpy.types.Scene.blenderF3DScale
del bpy.types.Scene.fullTraceback
del bpy.types.Scene.decomp_compatible
del bpy.types.Scene.ignoreTextureRestrictions
del bpy.types.Scene.saveTextures
del bpy.types.Scene.gameEditorMode
del bpy.types.Scene.generateF3DNodeGraph
del bpy.types.Scene.exportHiddenGeometry
del bpy.types.Scene.blenderF3DScale
del bpy.types.Scene.fast64
del bpy.types.Bone.fast64
del bpy.types.Object.fast64
del bpy.types.Scene.fast64
del bpy.types.Bone.fast64
del bpy.types.Object.fast64
for cls in classes:
unregister_class(cls)
bpy.app.handlers.load_post.remove(after_load)
for cls in classes:
unregister_class(cls)
addon_updater_ops.unregister()
unregister_class(ExampleAddonPreferences)
bpy.app.handlers.load_post.remove(after_load)
addon_updater_ops.unregister()
unregister_class(ExampleAddonPreferences)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+256 -238
View File
@@ -7,292 +7,310 @@ from .sm64.sm64_collision import CollisionSettings
from .utility import *
from bl_operators.presets import AddPresetBase
def upgradeF3DVersionAll(objs, armatures, version):
# Remove original v2 node groups so that they can be recreated.
deleteGroups = []
for node_tree in bpy.data.node_groups:
if node_tree.name[-6:] == 'F3D v' + str(version):
deleteGroups.append(node_tree)
for deleteGroup in deleteGroups:
bpy.data.node_groups.remove(deleteGroup)
# Dict of non-f3d materials : converted f3d materials
# handles cases where materials are used in multiple objects
materialDict = {}
for obj in objs:
upgradeF3DVersionOneObject(obj, materialDict, version)
for armature in armatures:
for bone in armature.bones:
if bone.geo_cmd == "Switch":
for switchOption in bone.switch_options:
if switchOption.switchType == "Material":
if switchOption.materialOverride in materialDict:
switchOption.materialOverride = materialDict[switchOption.materialOverride]
for i in range(len(switchOption.specificOverrideArray)):
material = switchOption.specificOverrideArray[i].material
if material in materialDict:
switchOption.specificOverrideArray[i].material = materialDict[material]
for i in range(len(switchOption.specificIgnoreArray)):
material = switchOption.specificIgnoreArray[i].material
if material in materialDict:
switchOption.specificIgnoreArray[i].material = materialDict[material]
def upgradeF3DVersionAll(objs, armatures, version):
# Remove original v2 node groups so that they can be recreated.
deleteGroups = []
for node_tree in bpy.data.node_groups:
if node_tree.name[-6:] == "F3D v" + str(version):
deleteGroups.append(node_tree)
for deleteGroup in deleteGroups:
bpy.data.node_groups.remove(deleteGroup)
# Dict of non-f3d materials : converted f3d materials
# handles cases where materials are used in multiple objects
materialDict = {}
for obj in objs:
upgradeF3DVersionOneObject(obj, materialDict, version)
for armature in armatures:
for bone in armature.bones:
if bone.geo_cmd == "Switch":
for switchOption in bone.switch_options:
if switchOption.switchType == "Material":
if switchOption.materialOverride in materialDict:
switchOption.materialOverride = materialDict[switchOption.materialOverride]
for i in range(len(switchOption.specificOverrideArray)):
material = switchOption.specificOverrideArray[i].material
if material in materialDict:
switchOption.specificOverrideArray[i].material = materialDict[material]
for i in range(len(switchOption.specificIgnoreArray)):
material = switchOption.specificIgnoreArray[i].material
if material in materialDict:
switchOption.specificIgnoreArray[i].material = materialDict[material]
def upgradeF3DVersionOneObject(obj, materialDict, version):
for index in range(len(obj.material_slots)):
material = obj.material_slots[index].material
if material is not None and material.is_f3d:
if material in materialDict:
obj.material_slots[index].material = materialDict[material]
else:
convertF3DtoNewVersion(obj, index, material, materialDict, version)
for index in range(len(obj.material_slots)):
material = obj.material_slots[index].material
if material is not None and material.is_f3d:
if material in materialDict:
obj.material_slots[index].material = materialDict[material]
else:
convertF3DtoNewVersion(obj, index, material, materialDict, version)
V4PresetName = {
'Unlit Texture' : "sm64_unlit_texture",
'Unlit Texture Cutout' : "sm64_unlit_texture_cutout",
'Shaded Solid' : "sm64_shaded_solid",
'Shaded Texture' : "sm64_shaded_texture",
'Shaded Texture Cutout' : "sm64_shaded_texture_cutout",
'Shaded Texture Transparent' : "sm64_shaded_texture_transparent",
'Environment Mapped' : "sm64_environment_map",
'Decal On Shaded Solid' : "sm64_decal",
'Vertex Colored Texture' : "sm64_vertex_colored_texture",
'Fog Shaded Texture' : "sm64_fog_shaded_texture",
'Fog Shaded Texture Cutout' : "sm64_fog_shaded_texture_cutout",
'Fog Shaded Texture Transparent' : "sm64_fog_shaded_texture_transparent",
'Vertex Colored Texture Transparent' : "sm64_vertex_colored_texture_transparent",
'Shaded Noise' : "sm64_shaded_noise",
"Unlit Texture": "sm64_unlit_texture",
"Unlit Texture Cutout": "sm64_unlit_texture_cutout",
"Shaded Solid": "sm64_shaded_solid",
"Shaded Texture": "sm64_shaded_texture",
"Shaded Texture Cutout": "sm64_shaded_texture_cutout",
"Shaded Texture Transparent": "sm64_shaded_texture_transparent",
"Environment Mapped": "sm64_environment_map",
"Decal On Shaded Solid": "sm64_decal",
"Vertex Colored Texture": "sm64_vertex_colored_texture",
"Fog Shaded Texture": "sm64_fog_shaded_texture",
"Fog Shaded Texture Cutout": "sm64_fog_shaded_texture_cutout",
"Fog Shaded Texture Transparent": "sm64_fog_shaded_texture_transparent",
"Vertex Colored Texture Transparent": "sm64_vertex_colored_texture_transparent",
"Shaded Noise": "sm64_shaded_noise",
}
def getV4PresetName(name):
newName = None
if name in V4PresetName:
newName = V4PresetName[name]
else:
newName = "Custom"
return newName
newName = None
if name in V4PresetName:
newName = V4PresetName[name]
else:
newName = "Custom"
return newName
def convertF3DtoNewVersion(obj, index, material, materialDict, version):
if material.mat_ver > 3:
oldPreset = AddPresetBase.as_filename(material.f3d_mat.presetName)
else:
oldPreset = material.f3d_preset
if version > 3:
newMat = createF3DMat(obj, preset = getV4PresetName(oldPreset), index = index)
if material.mat_ver > 3:
copyPropertyGroup(material.f3d_mat, newMat.f3d_mat)
else:
convertToNewMat(newMat, material)
if newMat.f3d_mat.draw_layer.sm64 != obj.draw_layer_static:
newMat.f3d_mat.draw_layer.sm64 = obj.draw_layer_static
else:
newMat = createF3DMat(obj, preset = oldPreset, index = index)
matSettings = F3DMaterialSettings()
matSettings.loadFromMaterial(material, True)
matSettings.applyToMaterial(newMat, True, update_node_values_of_material, bpy.context)
if material.mat_ver > 3:
oldPreset = AddPresetBase.as_filename(material.f3d_mat.presetName)
else:
oldPreset = material.f3d_preset
copyPropertyGroup(material.ootMaterial, newMat.ootMaterial)
copyPropertyGroup(material.ootCollisionProperty, newMat.ootCollisionProperty)
if version > 3:
newMat = createF3DMat(obj, preset=getV4PresetName(oldPreset), index=index)
if material.mat_ver > 3:
copyPropertyGroup(material.f3d_mat, newMat.f3d_mat)
else:
convertToNewMat(newMat, material)
if newMat.f3d_mat.draw_layer.sm64 != obj.draw_layer_static:
newMat.f3d_mat.draw_layer.sm64 = obj.draw_layer_static
else:
newMat = createF3DMat(obj, preset=oldPreset, index=index)
matSettings = F3DMaterialSettings()
matSettings.loadFromMaterial(material, True)
matSettings.applyToMaterial(newMat, True, update_node_values_of_material, bpy.context)
colSettings = CollisionSettings()
colSettings.load(material)
colSettings.apply(newMat)
copyPropertyGroup(material.ootMaterial, newMat.ootMaterial)
copyPropertyGroup(material.ootCollisionProperty, newMat.ootCollisionProperty)
colSettings = CollisionSettings()
colSettings.load(material)
colSettings.apply(newMat)
updateMatWithNewVersionName(newMat, material, materialDict, version)
updateMatWithNewVersionName(newMat, material, materialDict, version)
def convertAllBSDFtoF3D(objs, renameUV):
# Dict of non-f3d materials : converted f3d materials
# handles cases where materials are used in multiple objects
materialDict = {}
for obj in objs:
if renameUV:
for uv_layer in obj.data.uv_layers:
uv_layer.name = "UVMap"
for index in range(len(obj.material_slots)):
material = obj.material_slots[index].material
if material is not None and not material.is_f3d:
if material in materialDict:
print("Existing material")
obj.material_slots[index].material = materialDict[material]
else:
print("New material")
convertBSDFtoF3D(obj, index, material, materialDict)
# Dict of non-f3d materials : converted f3d materials
# handles cases where materials are used in multiple objects
materialDict = {}
for obj in objs:
if renameUV:
for uv_layer in obj.data.uv_layers:
uv_layer.name = "UVMap"
for index in range(len(obj.material_slots)):
material = obj.material_slots[index].material
if material is not None and not material.is_f3d:
if material in materialDict:
print("Existing material")
obj.material_slots[index].material = materialDict[material]
else:
print("New material")
convertBSDFtoF3D(obj, index, material, materialDict)
def convertBSDFtoF3D(obj, index, material, materialDict):
if not material.use_nodes:
newMaterial = createF3DMat(obj, preset = 'Shaded Solid', index = index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.default_light_color = material.diffuse_color
updateMatWithName(newMaterial, material, materialDict)
if not material.use_nodes:
newMaterial = createF3DMat(obj, preset="Shaded Solid", index=index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.default_light_color = material.diffuse_color
updateMatWithName(newMaterial, material, materialDict)
elif "Principled BSDF" in material.node_tree.nodes:
tex0Node = material.node_tree.nodes["Principled BSDF"].inputs["Base Color"]
tex1Node = material.node_tree.nodes["Principled BSDF"].inputs["Subsurface Color"]
if len(tex0Node.links) == 0:
newMaterial = createF3DMat(obj, preset=getDefaultMaterialPreset("Shaded Solid"), index=index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.default_light_color = tex0Node.default_value
updateMatWithName(newMaterial, material, materialDict)
else:
if isinstance(tex0Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
if "convert_preset" in material:
presetName = material["convert_preset"]
if presetName not in [enumValue[0] for enumValue in enumMaterialPresets]:
raise PluginError(
"During BSDF to F3D conversion, for material '"
+ material.name
+ "',"
+ " enum '"
+ presetName
+ "' was not found in material preset enum list."
)
else:
presetName = getDefaultMaterialPreset("Shaded Texture")
newMaterial = createF3DMat(obj, preset=presetName, index=index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.tex0.tex = tex0Node.links[0].from_node.image
if len(tex1Node.links) > 0 and isinstance(tex1Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
f3dMat.tex1.tex = tex1Node.links[0].from_node.image
updateMatWithName(newMaterial, material, materialDict)
else:
print("Principled BSDF material does not have an Image Node attached to its Base Color.")
else:
print("Material is not a Principled BSDF or non-node material.")
elif "Principled BSDF" in material.node_tree.nodes:
tex0Node = material.node_tree.nodes['Principled BSDF'].inputs['Base Color']
tex1Node = material.node_tree.nodes['Principled BSDF'].inputs['Subsurface Color']
if len(tex0Node.links) == 0:
newMaterial = createF3DMat(obj, preset = getDefaultMaterialPreset("Shaded Solid"), index = index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.default_light_color = tex0Node.default_value
updateMatWithName(newMaterial, material, materialDict)
else:
if isinstance(tex0Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
if 'convert_preset' in material:
presetName = material['convert_preset']
if presetName not in [enumValue[0] for enumValue in enumMaterialPresets]:
raise PluginError('During BSDF to F3D conversion, for material \'' + material.name + '\',' + \
' enum \'' + presetName + '\' was not found in material preset enum list.')
else:
presetName = getDefaultMaterialPreset('Shaded Texture')
newMaterial = createF3DMat(obj, preset = presetName, index = index)
f3dMat = newMaterial.f3d_mat if newMaterial.mat_ver > 3 else newMaterial
f3dMat.tex0.tex = tex0Node.links[0].from_node.image
if len(tex1Node.links) > 0 and \
isinstance(tex1Node.links[0].from_node, bpy.types.ShaderNodeTexImage):
f3dMat.tex1.tex = tex1Node.links[0].from_node.image
updateMatWithName(newMaterial, material, materialDict)
else:
print("Principled BSDF material does not have an Image Node attached to its Base Color.")
else:
print("Material is not a Principled BSDF or non-node material.")
def updateMatWithName(f3dMat, oldMat, materialDict):
f3dMat.name = oldMat.name + "_f3d"
update_preset_manual(f3dMat, bpy.context)
materialDict[oldMat] = f3dMat
f3dMat.name = oldMat.name + "_f3d"
update_preset_manual(f3dMat, bpy.context)
materialDict[oldMat] = f3dMat
def updateMatWithNewVersionName(f3dMat, oldMat, materialDict, version):
name = oldMat.name
if oldMat.name[-3:-1] == '_v':
name = oldMat.name[:-3]
f3dMat.name = name + "_v" + str(version)
update_preset_manual(f3dMat, bpy.context)
materialDict[oldMat] = f3dMat
name = oldMat.name
if oldMat.name[-3:-1] == "_v":
name = oldMat.name[:-3]
f3dMat.name = name + "_v" + str(version)
update_preset_manual(f3dMat, bpy.context)
materialDict[oldMat] = f3dMat
class BSDFConvert(bpy.types.Operator):
# set bl_ properties
bl_idname = 'object.convert_bsdf'
bl_label = "Principled BSDF to F3D Converter"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
bl_idname = "object.convert_bsdf"
bl_label = "Principled BSDF to F3D Converter"
bl_options = {"REGISTER", "UNDO", "PRESET"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != 'OBJECT':
raise PluginError("Operator can only be used in object mode.")
if context.scene.bsdf_conv_all:
convertAllBSDFtoF3D([obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
context.scene.rename_uv_maps)
else:
if len(context.selected_objects) == 0:
raise PluginError("Mesh not selected.")
elif type(context.selected_objects[0].data) is not\
bpy.types.Mesh:
raise PluginError("Mesh not selected.")
obj = context.selected_objects[0]
convertAllBSDFtoF3D([obj], context.scene.rename_uv_maps)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != "OBJECT":
raise PluginError("Operator can only be used in object mode.")
if context.scene.bsdf_conv_all:
convertAllBSDFtoF3D(
[obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
context.scene.rename_uv_maps,
)
else:
if len(context.selected_objects) == 0:
raise PluginError("Mesh not selected.")
elif type(context.selected_objects[0].data) is not bpy.types.Mesh:
raise PluginError("Mesh not selected.")
obj = context.selected_objects[0]
convertAllBSDFtoF3D([obj], context.scene.rename_uv_maps)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
self.report({"INFO"}, "Created F3D material.")
return {"FINISHED"} # must return a set
self.report({'INFO'}, 'Created F3D material.')
return {'FINISHED'} # must return a set
class MatUpdateConvert(bpy.types.Operator):
# set bl_ properties
version = 4
bl_idname = 'object.convert_f3d_update'
bl_label = "Recreate F3D Materials As v" + str(version)
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
version = 4
bl_idname = "object.convert_f3d_update"
bl_label = "Recreate F3D Materials As v" + str(version)
bl_options = {"REGISTER", "UNDO", "PRESET"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != 'OBJECT':
raise PluginError("Operator can only be used in object mode.")
if context.scene.update_conv_all:
upgradeF3DVersionAll([obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
bpy.data.armatures, self.version)
else:
if len(context.selected_objects) == 0:
raise PluginError("Mesh not selected.")
elif type(context.selected_objects[0].data) is not\
bpy.types.Mesh:
raise PluginError("Mesh not selected.")
obj = context.selected_objects[0]
upgradeF3DVersionOneObject(obj, {}, self.version)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
# Called on demand (i.e. button press, menu item)
# Can also be called from operator search menu (Spacebar)
def execute(self, context):
try:
if context.mode != "OBJECT":
raise PluginError("Operator can only be used in object mode.")
if context.scene.update_conv_all:
upgradeF3DVersionAll(
[obj for obj in bpy.data.objects if isinstance(obj.data, bpy.types.Mesh)],
bpy.data.armatures,
self.version,
)
else:
if len(context.selected_objects) == 0:
raise PluginError("Mesh not selected.")
elif type(context.selected_objects[0].data) is not bpy.types.Mesh:
raise PluginError("Mesh not selected.")
obj = context.selected_objects[0]
upgradeF3DVersionOneObject(obj, {}, self.version)
except Exception as e:
raisePluginError(self, e)
return {"CANCELLED"}
self.report({"INFO"}, "Created F3D material.")
return {"FINISHED"} # must return a set
self.report({'INFO'}, 'Created F3D material.')
return {'FINISHED'} # must return a set
class F3DMaterialConverterPanel(bpy.types.Panel):
bl_label = "F3D Material Converter"
bl_idname = "MATERIAL_PT_F3D_Material_Converter"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Fast64'
bl_label = "F3D Material Converter"
bl_idname = "MATERIAL_PT_F3D_Material_Converter"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Fast64"
@classmethod
def poll(cls, context):
return True
#return hasattr(context, 'object') and context.object is not None and \
# isinstance(context.object.data, bpy.types.Mesh)
@classmethod
def poll(cls, context):
return True
# return hasattr(context, 'object') and context.object is not None and \
# isinstance(context.object.data, bpy.types.Mesh)
def draw(self, context):
#mesh = context.object.data
self.layout.operator(BSDFConvert.bl_idname)
self.layout.prop(context.scene, 'bsdf_conv_all')
self.layout.prop(context.scene, 'rename_uv_maps')
self.layout.operator(MatUpdateConvert.bl_idname)
self.layout.prop(context.scene, 'update_conv_all')
self.layout.operator(ReloadDefaultF3DPresets.bl_idname)
def draw(self, context):
# mesh = context.object.data
self.layout.operator(BSDFConvert.bl_idname)
self.layout.prop(context.scene, "bsdf_conv_all")
self.layout.prop(context.scene, "rename_uv_maps")
self.layout.operator(MatUpdateConvert.bl_idname)
self.layout.prop(context.scene, "update_conv_all")
self.layout.operator(ReloadDefaultF3DPresets.bl_idname)
bsdf_conv_classes = (
BSDFConvert,
MatUpdateConvert,
BSDFConvert,
MatUpdateConvert,
)
bsdf_conv_panel_classes = (
F3DMaterialConverterPanel,
)
bsdf_conv_panel_classes = (F3DMaterialConverterPanel,)
def bsdf_conv_panel_regsiter():
for cls in bsdf_conv_panel_classes:
register_class(cls)
for cls in bsdf_conv_panel_classes:
register_class(cls)
def bsdf_conv_panel_unregsiter():
for cls in bsdf_conv_panel_classes:
unregister_class(cls)
for cls in bsdf_conv_panel_classes:
unregister_class(cls)
def bsdf_conv_register():
for cls in bsdf_conv_classes:
register_class(cls)
for cls in bsdf_conv_classes:
register_class(cls)
# Moved to Level Root
bpy.types.Scene.bsdf_conv_all = bpy.props.BoolProperty(name="Convert all objects", default=True)
bpy.types.Scene.update_conv_all = bpy.props.BoolProperty(name="Convert all objects", default=True)
bpy.types.Scene.rename_uv_maps = bpy.props.BoolProperty(name="Rename UV maps", default=True)
# Moved to Level Root
bpy.types.Scene.bsdf_conv_all = bpy.props.BoolProperty(
name = 'Convert all objects', default = True)
bpy.types.Scene.update_conv_all = bpy.props.BoolProperty(
name = 'Convert all objects', default = True)
bpy.types.Scene.rename_uv_maps = bpy.props.BoolProperty(
name = 'Rename UV maps', default = True)
def bsdf_conv_unregister():
for cls in bsdf_conv_classes:
unregister_class(cls)
for cls in bsdf_conv_classes:
unregister_class(cls)
del bpy.types.Scene.bsdf_conv_all
del bpy.types.Scene.update_conv_all
del bpy.types.Scene.rename_uv_maps
del bpy.types.Scene.bsdf_conv_all
del bpy.types.Scene.update_conv_all
del bpy.types.Scene.rename_uv_maps
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+221 -221
View File
@@ -18,277 +18,277 @@ import bpy
from bpy.utils import register_class, unregister_class
enumRefreshVer = [
("Refresh 3", "Refresh 3", "Refresh 3"),
("Refresh 4", "Refresh 4", "Refresh 4"),
("Refresh 5", "Refresh 5", "Refresh 5"),
("Refresh 6", "Refresh 6", "Refresh 6"),
("Refresh 7", "Refresh 7", "Refresh 7"),
("Refresh 8", "Refresh 8", "Refresh 8"),
("Refresh 10", "Refresh 10", "Refresh 10"),
("Refresh 11", "Refresh 11", "Refresh 11"),
("Refresh 12", "Refresh 12", "Refresh 12"),
("Refresh 13", "Refresh 13", "Refresh 13"),
("Refresh 3", "Refresh 3", "Refresh 3"),
("Refresh 4", "Refresh 4", "Refresh 4"),
("Refresh 5", "Refresh 5", "Refresh 5"),
("Refresh 6", "Refresh 6", "Refresh 6"),
("Refresh 7", "Refresh 7", "Refresh 7"),
("Refresh 8", "Refresh 8", "Refresh 8"),
("Refresh 10", "Refresh 10", "Refresh 10"),
("Refresh 11", "Refresh 11", "Refresh 11"),
("Refresh 12", "Refresh 12", "Refresh 12"),
("Refresh 13", "Refresh 13", "Refresh 13"),
]
class SM64_AddrConv(bpy.types.Operator):
# set bl_ properties
bl_idname = 'object.addr_conv'
bl_label = "Convert Address"
bl_options = {'REGISTER', 'UNDO', 'PRESET'}
# set bl_ properties
bl_idname = "object.addr_conv"
bl_label = "Convert Address"
bl_options = {"REGISTER", "UNDO", "PRESET"}
segToVirt : bpy.props.BoolProperty()
segToVirt: bpy.props.BoolProperty()
def execute(self, context):
romfileSrc = None
try:
address = int(context.scene.convertibleAddr, 16)
importRom = context.scene.importRom
romfileSrc = open(bpy.path.abspath(importRom), "rb")
checkExpanded(bpy.path.abspath(importRom))
levelParsed = parseLevelAtPointer(romfileSrc, level_pointers[context.scene.levelConvert])
segmentData = levelParsed.segmentData
if self.segToVirt:
ptr = decodeSegmentedAddr(address.to_bytes(4, "big"), segmentData)
self.report({"INFO"}, "Virtual pointer is 0x" + format(ptr, "08X"))
else:
ptr = int.from_bytes(encodeSegmentedAddr(address, segmentData), "big")
self.report({"INFO"}, "Segmented pointer is 0x" + format(ptr, "08X"))
romfileSrc.close()
return {"FINISHED"}
except Exception as e:
if romfileSrc is not None:
romfileSrc.close()
raisePluginError(self, e)
return {"CANCELLED"} # must return a set
def execute(self, context):
romfileSrc = None
try:
address = int(context.scene.convertibleAddr, 16)
importRom = context.scene.importRom
romfileSrc = open(bpy.path.abspath(importRom), 'rb')
checkExpanded(bpy.path.abspath(importRom))
levelParsed = parseLevelAtPointer(romfileSrc,
level_pointers[context.scene.levelConvert])
segmentData = levelParsed.segmentData
if self.segToVirt:
ptr = decodeSegmentedAddr(
address.to_bytes(4, 'big'), segmentData)
self.report({'INFO'},
'Virtual pointer is 0x' + format(ptr, '08X'))
else:
ptr = int.from_bytes(
encodeSegmentedAddr(address, segmentData), 'big')
self.report({'INFO'},
'Segmented pointer is 0x' + format(ptr, '08X'))
romfileSrc.close()
return {'FINISHED'}
except Exception as e:
if romfileSrc is not None:
romfileSrc.close()
raisePluginError(self, e)
return {'CANCELLED'} # must return a set
class SM64_MenuVisibilityPanel(SM64_Panel):
bl_idname = "SM64_PT_menu_visibility_settings"
bl_label = "SM64 Menu Visibility Settings"
bl_options = set() # default to open
bl_order = 0 # force to front
bl_idname = "SM64_PT_menu_visibility_settings"
bl_label = "SM64 Menu Visibility Settings"
bl_options = set() # default to open
bl_order = 0 # force to front
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
sm64Props: SM64_Properties = context.scene.fast64.sm64
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
sm64Props: SM64_Properties = context.scene.fast64.sm64
prop_split(col, sm64Props, "goal", "Export goal")
prop_split(col, sm64Props, "showImportingMenus", "Show Importing Options")
prop_split(col, sm64Props, 'goal', 'Export goal')
prop_split(col, sm64Props, 'showImportingMenus', 'Show Importing Options')
class SM64_FileSettingsPanel(SM64_Panel):
bl_idname = "SM64_PT_file_settings"
bl_label = "SM64 File Settings"
bl_options = set()
bl_idname = "SM64_PT_file_settings"
bl_label = "SM64 File Settings"
bl_options = set()
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
sm64Props: SM64_Properties = context.scene.fast64.sm64
def draw(self, context):
col = self.layout.column()
col.scale_y = 1.1 # extra padding
sm64Props: SM64_Properties = context.scene.fast64.sm64
prop_split(col, sm64Props, 'exportType', 'Export type')
prop_split(col, context.scene, 'blenderToSM64Scale', 'Blender To SM64 Scale')
prop_split(col, sm64Props, "exportType", "Export type")
prop_split(col, context.scene, "blenderToSM64Scale", "Blender To SM64 Scale")
if sm64Props.showImportingMenus:
col.prop(context.scene, 'importRom')
if sm64Props.showImportingMenus:
col.prop(context.scene, "importRom")
if sm64Props.exportType == "Binary":
col.prop(context.scene, "exportRom")
col.prop(context.scene, "outputRom")
col.prop(context.scene, "extendBank4")
elif sm64Props.exportType == "C":
col.prop(context.scene, "disableScroll")
col.prop(context.scene, "decompPath")
prop_split(col, context.scene, "refreshVer", "Decomp Func Map")
prop_split(col, context.scene, "compressionFormat", "Compression Format")
if sm64Props.exportType == 'Binary':
col.prop(context.scene, 'exportRom')
col.prop(context.scene, 'outputRom')
col.prop(context.scene, 'extendBank4')
elif sm64Props.exportType == 'C':
col.prop(context.scene, 'disableScroll')
col.prop(context.scene, 'decompPath')
prop_split(col, context.scene, 'refreshVer', 'Decomp Func Map')
prop_split(col, context.scene, 'compressionFormat', 'Compression Format')
class SM64_AddressConvertPanel(SM64_Panel):
bl_idname = "SM64_PT_addr_conv"
bl_label = "SM64 Address Converter"
goal = sm64GoalImport
bl_idname = "SM64_PT_addr_conv"
bl_label = "SM64 Address Converter"
goal = sm64GoalImport
def draw(self, context):
col = self.layout.column()
segToVirtOp = col.operator(SM64_AddrConv.bl_idname, text="Convert Segmented To Virtual")
segToVirtOp.segToVirt = True
virtToSegOp = col.operator(SM64_AddrConv.bl_idname, text="Convert Virtual To Segmented")
virtToSegOp.segToVirt = False
prop_split(col, context.scene, "convertibleAddr", "Address")
col.prop(context.scene, "levelConvert")
def draw(self, context):
col = self.layout.column()
segToVirtOp = col.operator(SM64_AddrConv.bl_idname,
text = "Convert Segmented To Virtual")
segToVirtOp.segToVirt = True
virtToSegOp = col.operator(SM64_AddrConv.bl_idname,
text = "Convert Virtual To Segmented")
virtToSegOp.segToVirt = False
prop_split(col, context.scene, 'convertibleAddr', 'Address')
col.prop(context.scene, 'levelConvert')
def get_legacy_export_type():
legacy_export_types = ('C', 'Binary', 'Insertable Binary')
scene = bpy.context.scene
legacy_export_types = ("C", "Binary", "Insertable Binary")
scene = bpy.context.scene
for exportKey in ['animExportType', 'colExportType', 'DLExportType', 'geoExportType']:
eType = scene.pop(exportKey, None)
if eType is not None and legacy_export_types[eType] != 'C':
return legacy_export_types[eType]
for exportKey in ["animExportType", "colExportType", "DLExportType", "geoExportType"]:
eType = scene.pop(exportKey, None)
if eType is not None and legacy_export_types[eType] != "C":
return legacy_export_types[eType]
return "C"
return 'C'
class SM64_Properties(bpy.types.PropertyGroup):
'''Global SM64 Scene Properties found under scene.fast64.sm64'''
version: bpy.props.IntProperty(name="SM64_Properties Version", default=0)
cur_version = 1 # version after property migration
"""Global SM64 Scene Properties found under scene.fast64.sm64"""
# UI Selection
showImportingMenus: bpy.props.BoolProperty(name='Show Importing Menus', default=False)
exportType: bpy.props.EnumProperty(items = enumExportType, name = 'Export Type', default = 'C')
goal: bpy.props.EnumProperty(items=sm64GoalTypeEnum, name = 'Export Goal', default = 'All')
# TODO: Utilize these across all exports
# C exporting
# useCustomExportLocation = bpy.props.BoolProperty(name = 'Use Custom Export Path')
# customExportPath: bpy.props.StringProperty(name = 'Custom Export Path', subtype = 'FILE_PATH')
# exportLocation: bpy.props.EnumProperty(items = enumExportHeaderType, name = 'Export Location', default = 'Actor')
# useSelectedObjectName = bpy.props.BoolProperty(name = 'Use Name From Selected Object', default=False)
# exportName: bpy.props.StringProperty(name='Name', default='mario')
# exportGeolayoutName: bpy.props.StringProperty(name='Name', default='mario_geo')
version: bpy.props.IntProperty(name="SM64_Properties Version", default=0)
cur_version = 1 # version after property migration
# Actor exports
# exportGroup: bpy.props.StringProperty(name='Group', default='group0')
# UI Selection
showImportingMenus: bpy.props.BoolProperty(name="Show Importing Menus", default=False)
exportType: bpy.props.EnumProperty(items=enumExportType, name="Export Type", default="C")
goal: bpy.props.EnumProperty(items=sm64GoalTypeEnum, name="Export Goal", default="All")
# Level exports
# exportLevelName: bpy.props.StringProperty(name = 'Level', default = 'bob')
# exportLevelOption: bpy.props.EnumProperty(items = enumLevelNames, name = 'Level', default = 'bob')
# TODO: Utilize these across all exports
# C exporting
# useCustomExportLocation = bpy.props.BoolProperty(name = 'Use Custom Export Path')
# customExportPath: bpy.props.StringProperty(name = 'Custom Export Path', subtype = 'FILE_PATH')
# exportLocation: bpy.props.EnumProperty(items = enumExportHeaderType, name = 'Export Location', default = 'Actor')
# useSelectedObjectName = bpy.props.BoolProperty(name = 'Use Name From Selected Object', default=False)
# exportName: bpy.props.StringProperty(name='Name', default='mario')
# exportGeolayoutName: bpy.props.StringProperty(name='Name', default='mario_geo')
# Insertable Binary
# exportInsertableBinaryPath: bpy.props.StringProperty(name = 'Filepath', subtype = 'FILE_PATH')
# Actor exports
# exportGroup: bpy.props.StringProperty(name='Group', default='group0')
@staticmethod
def upgrade_changed_props():
if bpy.context.scene.fast64.sm64.version != SM64_Properties.cur_version:
bpy.context.scene.fast64.sm64.exportType = get_legacy_export_type()
bpy.context.scene.fast64.sm64.version = SM64_Properties.cur_version
# Level exports
# exportLevelName: bpy.props.StringProperty(name = 'Level', default = 'bob')
# exportLevelOption: bpy.props.EnumProperty(items = enumLevelNames, name = 'Level', default = 'bob')
# Insertable Binary
# exportInsertableBinaryPath: bpy.props.StringProperty(name = 'Filepath', subtype = 'FILE_PATH')
@staticmethod
def upgrade_changed_props():
if bpy.context.scene.fast64.sm64.version != SM64_Properties.cur_version:
bpy.context.scene.fast64.sm64.exportType = get_legacy_export_type()
bpy.context.scene.fast64.sm64.version = SM64_Properties.cur_version
sm64_classes = (
SM64_AddrConv,
SM64_Properties,
SM64_AddrConv,
SM64_Properties,
)
sm64_panel_classes = (
SM64_MenuVisibilityPanel,
SM64_FileSettingsPanel,
SM64_AddressConvertPanel,
SM64_MenuVisibilityPanel,
SM64_FileSettingsPanel,
SM64_AddressConvertPanel,
)
def sm64_panel_register():
for cls in sm64_panel_classes:
register_class(cls)
sm64_col_panel_register()
sm64_bone_panel_register()
sm64_cam_panel_register()
sm64_obj_panel_register()
sm64_geo_parser_panel_register()
sm64_geo_writer_panel_register()
sm64_level_panel_register()
sm64_spline_panel_register()
sm64_dl_writer_panel_register()
sm64_dl_parser_panel_register()
sm64_anim_panel_register()
def sm64_panel_register():
for cls in sm64_panel_classes:
register_class(cls)
sm64_col_panel_register()
sm64_bone_panel_register()
sm64_cam_panel_register()
sm64_obj_panel_register()
sm64_geo_parser_panel_register()
sm64_geo_writer_panel_register()
sm64_level_panel_register()
sm64_spline_panel_register()
sm64_dl_writer_panel_register()
sm64_dl_parser_panel_register()
sm64_anim_panel_register()
def sm64_panel_unregister():
for cls in sm64_panel_classes:
unregister_class(cls)
for cls in sm64_panel_classes:
unregister_class(cls)
sm64_col_panel_unregister()
sm64_bone_panel_unregister()
sm64_cam_panel_unregister()
sm64_obj_panel_unregister()
sm64_geo_parser_panel_unregister()
sm64_geo_writer_panel_unregister()
sm64_level_panel_unregister()
sm64_spline_panel_unregister()
sm64_dl_writer_panel_unregister()
sm64_dl_parser_panel_unregister()
sm64_anim_panel_unregister()
sm64_col_panel_unregister()
sm64_bone_panel_unregister()
sm64_cam_panel_unregister()
sm64_obj_panel_unregister()
sm64_geo_parser_panel_unregister()
sm64_geo_writer_panel_unregister()
sm64_level_panel_unregister()
sm64_spline_panel_unregister()
sm64_dl_writer_panel_unregister()
sm64_dl_parser_panel_unregister()
sm64_anim_panel_unregister()
def sm64_register(registerPanels):
for cls in sm64_classes:
register_class(cls)
for cls in sm64_classes:
register_class(cls)
sm64_col_register() # register first, so panel goes above mat panel
sm64_bone_register()
sm64_cam_register()
sm64_obj_register()
sm64_geo_parser_register()
sm64_geo_writer_register()
sm64_level_register()
sm64_spline_register()
sm64_dl_writer_register()
sm64_dl_parser_register()
sm64_anim_register()
sm64_col_register() # register first, so panel goes above mat panel
sm64_bone_register()
sm64_cam_register()
sm64_obj_register()
sm64_geo_parser_register()
sm64_geo_writer_register()
sm64_level_register()
sm64_spline_register()
sm64_dl_writer_register()
sm64_dl_parser_register()
sm64_anim_register()
if registerPanels:
sm64_panel_register()
if registerPanels:
sm64_panel_register()
bpy.types.Scene.importRom = bpy.props.StringProperty(
name ='Import ROM', subtype = 'FILE_PATH')
bpy.types.Scene.exportRom = bpy.props.StringProperty(
name ='Export ROM', subtype = 'FILE_PATH')
bpy.types.Scene.outputRom = bpy.props.StringProperty(
name ='Output ROM', subtype = 'FILE_PATH')
bpy.types.Scene.extendBank4 = bpy.props.BoolProperty(
name = 'Extend Bank 4 on Export?', default = True,
description = 'Sets bank 4 range to (' +\
hex(defaultExtendSegment4[0]) + ', ' + \
hex(defaultExtendSegment4[1]) + ') and copies data from old bank')
bpy.types.Scene.convertibleAddr = bpy.props.StringProperty(
name = 'Address')
bpy.types.Scene.levelConvert = bpy.props.EnumProperty(
items = level_enums, name = 'Level', default = 'IC')
bpy.types.Scene.refreshVer = bpy.props.EnumProperty(
items = enumRefreshVer, name = 'Refresh', default = 'Refresh 13')
bpy.types.Scene.disableScroll = bpy.props.BoolProperty(
name = 'Disable Scrolling Textures')
bpy.types.Scene.importRom = bpy.props.StringProperty(name="Import ROM", subtype="FILE_PATH")
bpy.types.Scene.exportRom = bpy.props.StringProperty(name="Export ROM", subtype="FILE_PATH")
bpy.types.Scene.outputRom = bpy.props.StringProperty(name="Output ROM", subtype="FILE_PATH")
bpy.types.Scene.extendBank4 = bpy.props.BoolProperty(
name="Extend Bank 4 on Export?",
default=True,
description="Sets bank 4 range to ("
+ hex(defaultExtendSegment4[0])
+ ", "
+ hex(defaultExtendSegment4[1])
+ ") and copies data from old bank",
)
bpy.types.Scene.convertibleAddr = bpy.props.StringProperty(name="Address")
bpy.types.Scene.levelConvert = bpy.props.EnumProperty(items=level_enums, name="Level", default="IC")
bpy.types.Scene.refreshVer = bpy.props.EnumProperty(items=enumRefreshVer, name="Refresh", default="Refresh 13")
bpy.types.Scene.disableScroll = bpy.props.BoolProperty(name="Disable Scrolling Textures")
bpy.types.Scene.blenderToSM64Scale = bpy.props.FloatProperty(name="Blender To SM64 Scale", default=100) # 212.766
bpy.types.Scene.decompPath = bpy.props.StringProperty(name="Decomp Folder", subtype="FILE_PATH")
bpy.types.Scene.compressionFormat = bpy.props.EnumProperty(
items=enumCompressionFormat, name="Compression", default="mio0"
)
bpy.types.Scene.blenderToSM64Scale = bpy.props.FloatProperty(
name = 'Blender To SM64 Scale', default = 100) # 212.766
bpy.types.Scene.decompPath = bpy.props.StringProperty(
name ='Decomp Folder', subtype = 'FILE_PATH')
bpy.types.Scene.compressionFormat = bpy.props.EnumProperty(
items = enumCompressionFormat, name = 'Compression', default = 'mio0')
def sm64_unregister(unregisterPanels):
for cls in reversed(sm64_classes):
unregister_class(cls)
for cls in reversed(sm64_classes):
unregister_class(cls)
sm64_col_unregister() # register first, so panel goes above mat panel
sm64_bone_unregister()
sm64_cam_unregister()
sm64_obj_unregister()
sm64_geo_parser_unregister()
sm64_geo_writer_unregister()
sm64_level_unregister()
sm64_spline_unregister()
sm64_dl_writer_unregister()
sm64_dl_parser_unregister()
sm64_anim_unregister()
sm64_col_unregister() # register first, so panel goes above mat panel
sm64_bone_unregister()
sm64_cam_unregister()
sm64_obj_unregister()
sm64_geo_parser_unregister()
sm64_geo_writer_unregister()
sm64_level_unregister()
sm64_spline_unregister()
sm64_dl_writer_unregister()
sm64_dl_parser_unregister()
sm64_anim_unregister()
if unregisterPanels:
sm64_panel_unregister()
if unregisterPanels:
sm64_panel_unregister()
del bpy.types.Scene.importRom
del bpy.types.Scene.exportRom
del bpy.types.Scene.outputRom
del bpy.types.Scene.extendBank4
del bpy.types.Scene.convertibleAddr
del bpy.types.Scene.levelConvert
del bpy.types.Scene.refreshVer
del bpy.types.Scene.importRom
del bpy.types.Scene.exportRom
del bpy.types.Scene.outputRom
del bpy.types.Scene.extendBank4
del bpy.types.Scene.disableScroll
del bpy.types.Scene.blenderToSM64Scale
del bpy.types.Scene.decompPath
del bpy.types.Scene.compressionFormat
del bpy.types.Scene.convertibleAddr
del bpy.types.Scene.levelConvert
del bpy.types.Scene.refreshVer
del bpy.types.Scene.disableScroll
del bpy.types.Scene.blenderToSM64Scale
del bpy.types.Scene.decompPath
del bpy.types.Scene.compressionFormat
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+969 -846
View File
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -6,8 +6,7 @@
line-length = 120
target-version = [
'py37', # used by Blender 2.80
'py39', # used by Blender 3.0.1
'py310', # used by Blender 3.1
]
# What files to exclude when running Black on directories (for example `black .`)