Source code for liatool.ui_spot

import bpy
import math
from bpy.types import Panel, PropertyGroup, UIList, Operator
from bpy.props import (BoolProperty, EnumProperty, FloatProperty,
                       CollectionProperty, IntProperty, StringProperty,
                       PointerProperty)

from . ui_panel import ILSPpanel
from . thumbProcess import ThumbProcess
from . imageSpot import ImageSpot


########################################################################
# PROPERTIES
########################################################################
[docs] class SpotProperties(PropertyGroup):
[docs] def setDefaultValues(self, context): pass
[docs] def check(self, context): return True
[docs] class Profile(PropertyGroup): radius: FloatProperty( name="Radius", description="Radius", default=0.0, min=0, step=10, update=lambda self, context: context.scene.ilsp_beam.updateLaserBeam(context), ) # type: ignore value: FloatProperty( name="Value", description="Value", default=1.0, min=0, max=1, step=10, ) # type: ignore
profile: CollectionProperty(type=Profile) # type: ignore profile_idx: IntProperty( name="Index of spot profile", default=0, min=0 ) # type: ignore shape: EnumProperty( name="Laser Spot Shape", description="Laser Spot Shape", items=( ('image', "Image Data", ""), ('circle', "Circular Laser Spot", ""), ('square', "Square Laser Spot", ""), ), default='image', ) # type: ignore consider_face_normal: BoolProperty( name="Consider Face Normal", description="Consider Face Normal", default=True, ) # type: ignore pure_square_radius: FloatProperty( name="Pure Square Radius", description="Pure Square Radius", default=0.5, min=0, step=10, ) # type: ignore
[docs] def show_image_in_new_window(self, image): new_window = bpy.ops.screen.area_dupli('INVOKE_DEFAULT') bpy.context.window_manager.windows[-1].screen.areas[-1].type = 'IMAGE_EDITOR' # Get the latest window and its screen areas new_screen = bpy.context.window_manager.windows[-1].screen image_editor_area = None # Find the IMAGE_EDITOR area for area in new_screen.areas: if area.type == 'IMAGE_EDITOR': image_editor_area = area break if image_editor_area: # Override context for the IMAGE_EDITOR area override = bpy.context.copy() override['area'] = image_editor_area override['region'] = image_editor_area.regions[-1] # Set the image to be displayed in the IMAGE_EDITOR area with bpy.context.temp_override(**override): bpy.ops.image.open(filepath=image.filepath) bpy.data.screens[new_screen.name].areas[-1].spaces[0].image = image else: print("Could not find IMAGE_EDITOR area.")
[docs] def readImageFile(self, context): path = self.image_file_path for image in bpy.data.images: if image.name not in ['spot', 'colorBar']: bpy.data.images.remove(image) try: img = bpy.data.images.get('spot') img.filepath = path img.reload() except Exception: img = bpy.data.images.load(path, check_existing=True) img.name = 'spot' try: texture = bpy.data.textures["spot"] except Exception: texture = bpy.data.textures.new(name="spot", type="IMAGE") texture.image = img texture.extension = 'CLIP' self.show_image_in_new_window(img)
image_file_path: StringProperty( name="", description="Image File Path", default="", maxlen=1024, subtype='FILE_PATH', update=lambda self, context: self.readImageFile(context) ) # type: ignore
[docs] def readColorBarFile(self, context): path = self.color_bar_file_path for image in bpy.data.images: if image.name not in ['spot', 'colorBar']: bpy.data.images.remove(image) try: img = bpy.data.images.get('colorBar') img.filepath = path img.reload() except Exception: img = bpy.data.images.load(path, check_existing=True) img.name = 'colorBar' try: texture = bpy.data.textures["colorBar"] except Exception: texture = bpy.data.textures.new(name="colorBar", type="IMAGE") texture.image = img texture.extension = 'CLIP' self.show_image_in_new_window(img)
color_bar_file_path: StringProperty( name="", description="Color Bar File Path", default="", maxlen=1024, subtype='FILE_PATH', update=lambda self, context: self.readColorBarFile(context) ) # type: ignore first_treshold: FloatProperty( name="Bottom/Left Value", description="Color Bar Bottom/Left Value", default=0, ) # type: ignore second_treshold: FloatProperty( name="Top/Right Value", description="Color Bar Top/Right Value", default=1.0, ) # type: ignore spot_size: FloatProperty( name="Spot Size", description="Spot Size", default=0.5, min=0, step=10, ) # type: ignore
######################################################################## # PANELS ########################################################################
[docs] class ILSP_PT_spot(ILSPpanel, Panel): bl_label = "Laser Spot"
[docs] @classmethod def poll(cls, context): return True
[docs] def draw(self, context): layout = self.layout layout.use_property_split = False layout.use_property_decorate = False spot = context.scene.ilsp_spot row = layout.row(align=True) row.prop(spot, 'consider_face_normal') row = layout.row(align=True) row.prop_enum(spot, "shape", 'image', text='Image Data') col = row.column() col.prop_enum(spot, "shape", 'square', text='Square Laser Spot') col = row.column() col.prop_enum(spot, "shape", 'circle', text='Circular Laser Spot') if spot.shape == 'square' or spot.shape == 'circle': layout.template_list("ILSP_UL_spot_profile", "The_List", spot, "profile", spot, "profile_idx") layout.operator('ilsp_spot_profile.new_item', text='ADD', icon='ADD') layout.separator() if spot.shape == 'square': row = layout.row(align=True) row.prop(spot, 'pure_square_radius') if spot.shape == 'image': layout.prop(spot, "image_file_path", text="Image File Path") row = layout.row(align=True) row.prop(spot, 'spot_size') layout.prop(spot, "color_bar_file_path", text="Color Bar File Path") grid = layout.grid_flow(columns=2, align=True) grid.prop(spot, 'first_treshold') grid.prop(spot, 'second_treshold') col = self.layout.box().column() texture = bpy.data.textures.get('spot') if texture is not None: #col.template_preview(texture, show_buttons=True) row = layout.row() row.template_ID_preview(texture, 'image', open="image_user.open", hide_buttons=True, filter='AVAILABLE') row.scale_y = 2.0 status = spot.check(context) try: len(status) except Exception: return layout.label(text=status[1], icon_value=status[2])
[docs] class ILSP_UL_spot_profile(UIList):
[docs] def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): grid = layout.grid_flow(columns=3, align=True) grid.prop(item, 'radius') grid.prop(item, 'value', slider=True) op = grid.operator('ilsp_spot_profile.delete_item', text='', icon='X') op.index = index
[docs] class ILSP_OT_spot_profile_ADD(Operator): bl_idname = "ilsp_spot_profile.new_item" bl_label = "Add"
[docs] def execute(self, context): profile = context.scene.ilsp_spot.profile item = profile.add() item.radius = 0.0 item.value = 1.0 return {'FINISHED'}
[docs] class ILSP_OT_spot_profile_DELETE(Operator): bl_idname = "ilsp_spot_profile.delete_item" bl_label = "Delete" index: IntProperty()
[docs] @classmethod def poll(cls, context): return True
[docs] def execute(self, context): context.scene.ilsp_spot.spot_profile.remove(self.index) return {'FINISHED'}
[docs] class ILSP_OT_spot_profile_view_thumbnail(Operator): bl_idname = "ilsp_spot_profile.view_thumbnail" bl_label = "" bl_description = "View larger thumbnail" bl_options = {"INTERNAL"}
[docs] def execute(self, context): thumbProcess = ThumbProcess(context) thumbProcess.simulate(context) return {'FINISHED'}