add pref and align tools
This commit is contained in:
		@ -21,12 +21,16 @@ 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_options = {'PRESET', 'UNDO'}
 | 
			
		||||
@ -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