159 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # Example of a custom widget that defines it's own geometry.
 | |
| #
 | |
| # Usage: Select a light in the 3D view and drag the arrow at it's rear
 | |
| # to change it's energy value.
 | |
| #
 | |
| import bpy
 | |
| from bpy.types import (
 | |
|     Gizmo,
 | |
|     GizmoGroup,
 | |
| )
 | |
| 
 | |
| # Coordinates (each one is a triangle).
 | |
| custom_shape_verts = (
 | |
|     (3.0, 1.0, -1.0), (2.0, 2.0, -1.0), (3.0, 3.0, -1.0),
 | |
|     (1.0, 3.0, 1.0), (3.0, 3.0, -1.0), (1.0, 3.0, -1.0),
 | |
|     (3.0, 3.0, 1.0), (3.0, 1.0, -1.0), (3.0, 3.0, -1.0),
 | |
|     (2.0, 0.0, 1.0), (3.0, 1.0, -1.0), (3.0, 1.0, 1.0),
 | |
|     (2.0, 0.0, -1.0), (2.0, 2.0, 1.0), (2.0, 2.0, -1.0),
 | |
|     (2.0, 2.0, -1.0), (0.0, 2.0, 1.0), (0.0, 2.0, -1.0),
 | |
|     (1.0, 3.0, 1.0), (2.0, 2.0, 1.0), (3.0, 3.0, 1.0),
 | |
|     (0.0, 2.0, -1.0), (1.0, 3.0, 1.0), (1.0, 3.0, -1.0),
 | |
|     (2.0, 2.0, 1.0), (3.0, 1.0, 1.0), (3.0, 3.0, 1.0),
 | |
|     (2.0, 2.0, -1.0), (1.0, 3.0, -1.0), (3.0, 3.0, -1.0),
 | |
|     (-3.0, -1.0, -1.0), (-2.0, -2.0, -1.0), (-3.0, -3.0, -1.0),
 | |
|     (-1.0, -3.0, 1.0), (-3.0, -3.0, -1.0), (-1.0, -3.0, -1.0),
 | |
|     (-3.0, -3.0, 1.0), (-3.0, -1.0, -1.0), (-3.0, -3.0, -1.0),
 | |
|     (-2.0, 0.0, 1.0), (-3.0, -1.0, -1.0), (-3.0, -1.0, 1.0),
 | |
|     (-2.0, 0.0, -1.0), (-2.0, -2.0, 1.0), (-2.0, -2.0, -1.0),
 | |
|     (-2.0, -2.0, -1.0), (0.0, -2.0, 1.0), (0.0, -2.0, -1.0),
 | |
|     (-1.0, -3.0, 1.0), (-2.0, -2.0, 1.0), (-3.0, -3.0, 1.0),
 | |
|     (0.0, -2.0, -1.0), (-1.0, -3.0, 1.0), (-1.0, -3.0, -1.0),
 | |
|     (-2.0, -2.0, 1.0), (-3.0, -1.0, 1.0), (-3.0, -3.0, 1.0),
 | |
|     (-2.0, -2.0, -1.0), (-1.0, -3.0, -1.0), (-3.0, -3.0, -1.0),
 | |
|     (1.0, -1.0, 0.0), (-1.0, -1.0, 0.0), (0.0, 0.0, -5.0),
 | |
|     (-1.0, -1.0, 0.0), (1.0, -1.0, 0.0), (0.0, 0.0, 5.0),
 | |
|     (1.0, -1.0, 0.0), (1.0, 1.0, 0.0), (0.0, 0.0, 5.0),
 | |
|     (1.0, 1.0, 0.0), (-1.0, 1.0, 0.0), (0.0, 0.0, 5.0),
 | |
|     (-1.0, 1.0, 0.0), (-1.0, -1.0, 0.0), (0.0, 0.0, 5.0),
 | |
|     (-1.0, -1.0, 0.0), (-1.0, 1.0, 0.0), (0.0, 0.0, -5.0),
 | |
|     (-1.0, 1.0, 0.0), (1.0, 1.0, 0.0), (0.0, 0.0, -5.0),
 | |
|     (1.0, 1.0, 0.0), (1.0, -1.0, 0.0), (0.0, 0.0, -5.0),
 | |
|     (3.0, 1.0, -1.0), (2.0, 0.0, -1.0), (2.0, 2.0, -1.0),
 | |
|     (1.0, 3.0, 1.0), (3.0, 3.0, 1.0), (3.0, 3.0, -1.0),
 | |
|     (3.0, 3.0, 1.0), (3.0, 1.0, 1.0), (3.0, 1.0, -1.0),
 | |
|     (2.0, 0.0, 1.0), (2.0, 0.0, -1.0), (3.0, 1.0, -1.0),
 | |
|     (2.0, 0.0, -1.0), (2.0, 0.0, 1.0), (2.0, 2.0, 1.0),
 | |
|     (2.0, 2.0, -1.0), (2.0, 2.0, 1.0), (0.0, 2.0, 1.0),
 | |
|     (1.0, 3.0, 1.0), (0.0, 2.0, 1.0), (2.0, 2.0, 1.0),
 | |
|     (0.0, 2.0, -1.0), (0.0, 2.0, 1.0), (1.0, 3.0, 1.0),
 | |
|     (2.0, 2.0, 1.0), (2.0, 0.0, 1.0), (3.0, 1.0, 1.0),
 | |
|     (2.0, 2.0, -1.0), (0.0, 2.0, -1.0), (1.0, 3.0, -1.0),
 | |
|     (-3.0, -1.0, -1.0), (-2.0, 0.0, -1.0), (-2.0, -2.0, -1.0),
 | |
|     (-1.0, -3.0, 1.0), (-3.0, -3.0, 1.0), (-3.0, -3.0, -1.0),
 | |
|     (-3.0, -3.0, 1.0), (-3.0, -1.0, 1.0), (-3.0, -1.0, -1.0),
 | |
|     (-2.0, 0.0, 1.0), (-2.0, 0.0, -1.0), (-3.0, -1.0, -1.0),
 | |
|     (-2.0, 0.0, -1.0), (-2.0, 0.0, 1.0), (-2.0, -2.0, 1.0),
 | |
|     (-2.0, -2.0, -1.0), (-2.0, -2.0, 1.0), (0.0, -2.0, 1.0),
 | |
|     (-1.0, -3.0, 1.0), (0.0, -2.0, 1.0), (-2.0, -2.0, 1.0),
 | |
|     (0.0, -2.0, -1.0), (0.0, -2.0, 1.0), (-1.0, -3.0, 1.0),
 | |
|     (-2.0, -2.0, 1.0), (-2.0, 0.0, 1.0), (-3.0, -1.0, 1.0),
 | |
|     (-2.0, -2.0, -1.0), (0.0, -2.0, -1.0), (-1.0, -3.0, -1.0),
 | |
| )
 | |
| 
 | |
| 
 | |
| class MyCustomShapeWidget(Gizmo):
 | |
|     bl_idname = "VIEW3D_GT_auto_facemap"
 | |
|     bl_target_properties = (
 | |
|         {"id": "offset", "type": 'FLOAT', "array_length": 1},
 | |
|     )
 | |
| 
 | |
|     __slots__ = (
 | |
|         "custom_shape",
 | |
|         "init_mouse_y",
 | |
|         "init_value",
 | |
|     )
 | |
| 
 | |
|     def _update_offset_matrix(self):
 | |
|         # offset behind the light
 | |
|         self.matrix_offset.col[3][2] = self.target_get_value("offset") / -10.0
 | |
| 
 | |
|     def draw(self, context):
 | |
|         self._update_offset_matrix()
 | |
|         self.draw_custom_shape(self.custom_shape)
 | |
| 
 | |
|     def draw_select(self, context, select_id):
 | |
|         self._update_offset_matrix()
 | |
|         self.draw_custom_shape(self.custom_shape, select_id=select_id)
 | |
| 
 | |
|     def setup(self):
 | |
|         if not hasattr(self, "custom_shape"):
 | |
|             self.custom_shape = self.new_custom_shape('TRIS', custom_shape_verts)
 | |
| 
 | |
|     def invoke(self, context, event):
 | |
|         self.init_mouse_y = event.mouse_y
 | |
|         self.init_value = self.target_get_value("offset")
 | |
|         return {'RUNNING_MODAL'}
 | |
| 
 | |
|     def exit(self, context, cancel):
 | |
|         context.area.header_text_set("")
 | |
|         if cancel:
 | |
|             self.target_set_value("offset", self.init_value)
 | |
| 
 | |
|     def modal(self, context, event, tweak):
 | |
|         delta = (event.mouse_y - self.init_mouse_y) / 10.0
 | |
|         if 'SNAP' in tweak:
 | |
|             delta = round(delta)
 | |
|         if 'PRECISE' in tweak:
 | |
|             delta /= 10.0
 | |
|         value = self.init_value + delta
 | |
|         self.target_set_value("offset", value)
 | |
|         context.area.header_text_set("My Gizmo: %.4f" % value)
 | |
|         return {'RUNNING_MODAL'}
 | |
| 
 | |
| 
 | |
| class MyCustomShapeWidgetGroup(GizmoGroup):
 | |
|     bl_idname = "OBJECT_GGT_light_test"
 | |
|     bl_label = "Test Light Widget"
 | |
|     bl_space_type = 'VIEW_3D'
 | |
|     bl_region_type = 'WINDOW'
 | |
|     bl_options = {'3D', 'PERSISTENT'}
 | |
| 
 | |
|     @classmethod
 | |
|     def poll(cls, context):
 | |
|         ob = context.object
 | |
|         return (ob and ob.type == 'LIGHT')
 | |
| 
 | |
|     def setup(self, context):
 | |
|         # Assign the 'offset' target property to the light energy.
 | |
|         ob = context.object
 | |
|         mpr = self.gizmos.new(MyCustomShapeWidget.bl_idname)
 | |
|         mpr.target_set_prop("offset", ob.data, "energy")
 | |
|         mpr.matrix_basis = ob.matrix_world.normalized()
 | |
| 
 | |
|         mpr.color = 1.0, 0.5, 1.0
 | |
|         mpr.alpha = 0.5
 | |
| 
 | |
|         mpr.color_highlight = 1.0, 1.0, 1.0
 | |
|         mpr.alpha_highlight = 0.5
 | |
| 
 | |
|         # units are large, so shrink to something more reasonable.
 | |
|         mpr.scale_basis = 0.1
 | |
|         mpr.use_draw_modal = True
 | |
| 
 | |
|         self.energy_widget = mpr
 | |
| 
 | |
|     def refresh(self, context):
 | |
|         ob = context.object
 | |
|         mpr = self.energy_widget
 | |
|         mpr.matrix_basis = ob.matrix_world.normalized()
 | |
| 
 | |
| 
 | |
| classes = (
 | |
|     MyCustomShapeWidget,
 | |
|     MyCustomShapeWidgetGroup,
 | |
| )
 | |
| 
 | |
| for cls in classes:
 | |
|     bpy.utils.register_class(cls)
 |