add pref and align tools
This commit is contained in:
		| @ -21,14 +21,18 @@ if "bpy" in locals(): | ||||
|         importlib.reload(utils) | ||||
|     if "config" in locals(): | ||||
|         importlib.reload(config) | ||||
| from . import config, utils, bm_import_export, floor_rail_uv | ||||
|     if "preferences" in locals(): | ||||
|         importlib.reload(preferences) | ||||
|     if "super_align" in locals(): | ||||
|         importlib.reload(super_align) | ||||
| from . import config, utils, bm_import_export, floor_rail_uv, preferences, super_align | ||||
|  | ||||
| # ============================================= func block | ||||
|  | ||||
| class ImportBM(bpy.types.Operator, bpy_extras.io_utils.ImportHelper): | ||||
|     """Load a Ballance Map File""" | ||||
|     """Load a Ballance Map File (BM file spec 1.0)""" | ||||
|     bl_idname = "import_scene.bm" | ||||
|     bl_label = "Import BM" | ||||
|     bl_label = "Import BM " | ||||
|     bl_options = {'PRESET', 'UNDO'} | ||||
|     filename_ext = ".bm" | ||||
|  | ||||
| @ -37,7 +41,7 @@ class ImportBM(bpy.types.Operator, bpy_extras.io_utils.ImportHelper): | ||||
|         return {'FINISHED'} | ||||
|          | ||||
| class ExportBM(bpy.types.Operator, bpy_extras.io_utils.ExportHelper): | ||||
|     """Save a Ballance Map File""" | ||||
|     """Save a Ballance Map File (BM file spec 1.0)""" | ||||
|     bl_idname = "export_scene.bm" | ||||
|     bl_label = 'Export BM' | ||||
|     bl_options = {'PRESET'} | ||||
| @ -84,6 +88,58 @@ class FloorUVOperator(bpy.types.Operator): | ||||
|         floor_rail_uv.virtoolize_floor_uv() | ||||
|         return {'FINISHED'} | ||||
|  | ||||
| class SuperAlignOperator(bpy.types.Operator): | ||||
|     bl_idname = "ballance.super_align" | ||||
|     bl_label = "Super Align" | ||||
|     bl_options = {'UNDO'} | ||||
|  | ||||
|     align_x: bpy.props.BoolProperty(name="X postion") | ||||
|     align_y: bpy.props.BoolProperty(name="Y postion") | ||||
|     align_z: bpy.props.BoolProperty(name="Z postion") | ||||
|  | ||||
|     current_references: bpy.props.EnumProperty( | ||||
|         name="Current", | ||||
|         items=(('MIN', "Min", ""), | ||||
|                 ('CENTER', "Center (bound box)", ""), | ||||
|                 ('POINT', "Center (axis)", ""), | ||||
|                 ('MAX', "Max", "") | ||||
|                 ), | ||||
|         ) | ||||
|  | ||||
|     target_references: bpy.props.EnumProperty( | ||||
|         name="Target", | ||||
|         items=(('MIN', "Min", ""), | ||||
|                 ('CENTER', "Center (bound box)", ""), | ||||
|                 ('POINT', "Center (axis)", ""), | ||||
|                 ('MAX', "Max", "") | ||||
|                 ), | ||||
|         ) | ||||
|  | ||||
|     @classmethod | ||||
|     def poll(self, context): | ||||
|         return super_align.check_align_target() | ||||
|  | ||||
|     def execute(self, context): | ||||
|         super_align.align_object(self.align_x, self.align_y, self.align_z, self.current_references, self.target_references) | ||||
|         return {'FINISHED'} | ||||
|  | ||||
|     def invoke(self, context, event): | ||||
|         wm = context.window_manager | ||||
|         return wm.invoke_props_dialog(self) | ||||
|  | ||||
|     def draw(self, context): | ||||
|         layout = self.layout | ||||
|         col = layout.column() | ||||
|         col.label(text="Align axis") | ||||
|  | ||||
|         row = col.row() | ||||
|         row.prop(self, "align_x") | ||||
|         row.prop(self, "align_y") | ||||
|         row.prop(self, "align_z") | ||||
|  | ||||
|         col.prop(self, "current_references") | ||||
|         col.prop(self, "target_references") | ||||
|  | ||||
| class ThreeDViewerMenu(bpy.types.Menu): | ||||
|     bl_label = "Ballance 3D" | ||||
|     bl_idname = "OBJECT_MT_ballance3d_menu" | ||||
| @ -91,16 +147,19 @@ class ThreeDViewerMenu(bpy.types.Menu): | ||||
|     def draw(self, context): | ||||
|         layout = self.layout | ||||
|  | ||||
|         layout.operator("ballance.super_align") | ||||
|         layout.operator("ballance.rail_uv") | ||||
|         layout.operator("ballance.floor_uv") | ||||
|  | ||||
| # ============================================= blender call system | ||||
|  | ||||
| classes = ( | ||||
|     preferences.BallanceBlenderPluginPreferences, | ||||
|     ImportBM, | ||||
|     ExportBM, | ||||
|     RailUVOperator, | ||||
|     FloorUVOperator, | ||||
|     SuperAlignOperator, | ||||
|     ThreeDViewerMenu | ||||
| ) | ||||
|  | ||||
|  | ||||
							
								
								
									
										17
									
								
								ballance_blender_plugin/preferences.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ballance_blender_plugin/preferences.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import bpy | ||||
|  | ||||
| class BallanceBlenderPluginPreferences(bpy.types.AddonPreferences): | ||||
|     bl_idname = __package__ | ||||
|  | ||||
|     external_folder: bpy.props.StringProperty( | ||||
|         name="External texture folder", | ||||
|         description="The Ballance texture folder which will be used buy this plugin to get external texture.", | ||||
|         ) | ||||
|  | ||||
|     def draw(self, context): | ||||
|         layout = self.layout | ||||
|          | ||||
|         row = layout.row() | ||||
|         col = row.column() | ||||
|  | ||||
|         col.prop(self, "external_folder") | ||||
							
								
								
									
										73
									
								
								ballance_blender_plugin/super_align.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								ballance_blender_plugin/super_align.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| import bpy,mathutils | ||||
| from . import utils | ||||
|  | ||||
| def check_align_target(): | ||||
|     if bpy.context.active_object is None: | ||||
|         return False | ||||
|  | ||||
|     selected = bpy.context.selected_objects[:] | ||||
|     length = len(selected) | ||||
|     if bpy.context.active_object in selected: | ||||
|         length -= 1 | ||||
|     if length == 0: | ||||
|         return False | ||||
|      | ||||
|     return True | ||||
|  | ||||
| def align_object(use_x, use_y, use_z, currentMode, targetMode): | ||||
|     if not (use_x or use_y or use_z): | ||||
|         return | ||||
|  | ||||
|     # calc active object data | ||||
|     currentObj = bpy.context.active_object | ||||
|     currentObjBbox = [currentObj.matrix_world @ mathutils.Vector(corner) for corner in currentObj.bound_box] | ||||
|     currentObjRef = provideObjRefPoint(currentObj, currentObjBbox, currentMode) | ||||
|  | ||||
|     # calc target | ||||
|     targetObjList = bpy.context.selected_objects[:] | ||||
|     if currentObj in targetObjList: | ||||
|         targetObjList.remove(currentObj) | ||||
|          | ||||
|     # process each obj | ||||
|     for targetObj in targetObjList: | ||||
|         targetObjBbox = [targetObj.matrix_world @ mathutils.Vector(corner) for corner in targetObj.bound_box] | ||||
|         targetObjRef = provideObjRefPoint(targetObj, targetObjBbox, targetMode) | ||||
|  | ||||
|         if use_x: | ||||
|             targetObj.location.x += currentObjRef.x - targetObjRef.x | ||||
|         if use_y: | ||||
|             targetObj.location.y += currentObjRef.y - targetObjRef.y | ||||
|         if use_z: | ||||
|             targetObj.location.z += currentObjRef.z - targetObjRef.z | ||||
|  | ||||
| def provideObjRefPoint(obj, vecList, mode): | ||||
|     refPoint = mathutils.Vector((0, 0, 0)) | ||||
|  | ||||
|     if (mode == 'MIN'): | ||||
|         refPoint.x = min([vec.x for vec in vecList]) | ||||
|         refPoint.y = min([vec.y for vec in vecList]) | ||||
|         refPoint.z = min([vec.z for vec in vecList]) | ||||
|     elif (mode == 'MAX'): | ||||
|         refPoint.x = max([vec.x for vec in vecList]) | ||||
|         refPoint.y = max([vec.y for vec in vecList]) | ||||
|         refPoint.z = max([vec.z for vec in vecList]) | ||||
|     elif (mode == 'CENTER'): | ||||
|         maxVecCache = mathutils.Vector((0, 0, 0)) | ||||
|         minVecCache = mathutils.Vector((0, 0, 0)) | ||||
|  | ||||
|         minVecCache.x = min([vec.x for vec in vecList]) | ||||
|         minVecCache.y = min([vec.y for vec in vecList]) | ||||
|         minVecCache.z = min([vec.z for vec in vecList]) | ||||
|         maxVecCache.x = max([vec.x for vec in vecList]) | ||||
|         maxVecCache.y = max([vec.y for vec in vecList]) | ||||
|         maxVecCache.z = max([vec.z for vec in vecList]) | ||||
|  | ||||
|         refPoint.x = (maxVecCache.x + minVecCache.x) / 2 | ||||
|         refPoint.y = (maxVecCache.y + minVecCache.y) / 2 | ||||
|         refPoint.z = (maxVecCache.z + minVecCache.z) / 2 | ||||
|     else: | ||||
|         refPoint.x = obj.location.x | ||||
|         refPoint.y = obj.location.y | ||||
|         refPoint.z = obj.location.z | ||||
|  | ||||
|     return refPoint | ||||
		Reference in New Issue
	
	Block a user