CM3D2 Converter.misc_MESH_MT_attribute_context_menu
1# 「プロパティ」エリア → 「メッシュデータ」タブ → 「頂点グループ」パネル → ▼ボタン 2import time 3import bpy 4import bmesh 5import mathutils 6from . import common 7from . import compat 8from .translations.pgettext_functions import * 9 10 11# メニュー等に項目追加 12def menu_func(self, context): 13 icon_id = common.kiss_icon() 14 self.layout.separator() 15 self.layout.operator('geometry.attribute_from_custom_normals', icon_value=icon_id) 16 if (self.__class__.__name__ == 'MESH_MT_attribute_context_menu'): 17 self.layout.operator('geometry.attribute_convert_normals', icon_value=icon_id) 18 #self.layout.operator('geometry.attribute_from_custom_normals', icon_value=compat.icon('NORMALS_VERTEX_FACE')) 19 20 21@compat.BlRegister() 22class CNV_OT_attribute_from_custom_normals(bpy.types.Operator): 23 bl_idname = 'geometry.attribute_from_custom_normals' 24 bl_label = "From Custom Normals" 25 bl_description = "Creates a new attribute from the custom split normals" 26 bl_options = {'REGISTER', 'UNDO'} 27 28 items = [ 29 ('FLOAT_VECTOR', "Vector" , "3D vector with floating point values" , 'NONE', 1), 30 ('FLOAT_COLOR' , "Float Color", "RGBA color with floating point precisions", 'NONE', 2), 31 ('BYTE_COLOR' , "Byte Color" , "RGBA color with 8-bit precision" , 'NONE', 3), 32 ] 33 34 data_type = bpy.props.EnumProperty(items=items, name="Data Type", default='FLOAT_COLOR') 35 36 @classmethod 37 def poll(cls, context): 38 obs = context.selected_objects 39 active_ob = context.active_object 40 if active_ob.type != 'MESH': 41 return False 42 return True 43 44 def invoke(self, context, event): 45 return context.window_manager.invoke_props_dialog(self) 46 47 def draw(self, context): 48 self.layout.prop(self, 'data_type') 49 pass 50 51 def execute(self, context): 52 ob = context.active_object 53 me = ob.data 54 55 pre_mode = ob.mode 56 bpy.ops.object.mode_set(mode='OBJECT') 57 58 me.calc_normals_split() 59 60 if (compat.IS_LEGACY or bpy.app.version < (2, 91)): 61 return {'ERROR'} 62 else: 63 attribute = me.attributes.new('custom_normals', self.data_type, 'CORNER') 64 attribute_data = attribute.data 65 66 for key in attribute.data.keys(): 67 print(repr(key)) 68 69 for loop_index, loop in enumerate(me.loops): 70 if isinstance(attribute, bpy.types.FloatVectorAttribute): 71 attribute.data[loop_index].vector = loop.normal 72 else: 73 attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 74 loop.normal[0] * 0.5 + 0.5, 75 loop.normal[1] * 0.5 + 0.5, 76 loop.normal[2] * 0.5 + 0.5, 77 1, 78 ) 79 80 81 82 bpy.ops.object.mode_set(mode=pre_mode) 83 return {'FINISHED'} 84 85@compat.BlRegister() 86class CNV_OT_attribute_convert_normals(bpy.types.Operator): 87 bl_idname = 'geometry.attribute_convert_normals' 88 bl_label = "Convert Normals" 89 bl_description = "Converts the data type of the normals attribute" 90 bl_options = {'REGISTER', 'UNDO'} 91 92 items = [ 93 ('FLOAT_VECTOR', "Vector" , "3D vector with floating point values" , 'NONE', 1), 94 ('FLOAT_COLOR' , "Float Color", "RGBA color with floating point precisions", 'NONE', 2), 95 ('BYTE_COLOR' , "Byte Color" , "RGBA color with 8-bit precision" , 'NONE', 3), 96 ] 97 98 data_type = bpy.props.EnumProperty(items=items, name="Data Type", default='FLOAT_COLOR') 99 100 @classmethod 101 def poll(cls, context): 102 obs = context.selected_objects 103 active_ob = context.active_object 104 if active_ob.type != 'MESH': 105 return False 106 return True 107 108 def invoke(self, context, event): 109 me = context.active_object.data 110 111 if isinstance(me.attributes.active, bpy.types.FloatVectorAttribute): 112 self.data_type = 'FLOAT_COLOR' 113 else: 114 self.data_type = 'FLOAT_VECTOR' 115 116 return context.window_manager.invoke_props_dialog(self) 117 118 def draw(self, context): 119 self.layout.prop(self, 'data_type') 120 pass 121 122 def execute(self, context): 123 ob = context.active_object 124 me = ob.data 125 126 pre_mode = ob.mode 127 bpy.ops.object.mode_set(mode='OBJECT') 128 129 if (compat.IS_LEGACY or bpy.app.version < (3,1)): 130 return {'ERROR'} 131 132 old_attribute = me.attributes.active 133 name = old_attribute.name 134 135 old_data = [None] * len(me.loops) 136 137 # store old data 138 for loop_index, loop in enumerate(me.loops): 139 if isinstance(old_attribute, bpy.types.FloatVectorAttribute): 140 old_data[loop_index] = old_attribute.data[loop_index].vector 141 else: 142 color = old_attribute.data[loop_index].color 143 old_data[loop_index] = ( # convert from range (0, 1) to range (-1, 1) 144 (color[0] - 0.5) / 0.5, 145 (color[1] - 0.5) / 0.5, 146 (color[2] - 0.5) / 0.5, 147 ) 148 149 # create new attribute 150 new_attribute = me.attributes.new(f'temp_{name}', self.data_type, 'CORNER') 151 152 # set new data 153 for loop_index, loop in enumerate(me.loops): 154 old_loop_data = old_data[loop_index] 155 if isinstance(new_attribute, bpy.types.FloatVectorAttribute): 156 new_attribute.data[loop_index].vector = old_loop_data 157 else: 158 new_attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 159 old_loop_data[0] * 0.5 + 0.5, 160 old_loop_data[1] * 0.5 + 0.5, 161 old_loop_data[2] * 0.5 + 0.5, 162 1, 163 ) 164 165 # delete old attribute 166 me.attributes.remove(me.attributes[name]) 167 168 # restore state 169 new_attribute.name = name 170 bpy.ops.object.mode_set(mode=pre_mode) 171 return {'FINISHED'}
@compat.BlRegister()
class
CNV_OT_attribute_from_custom_normals22@compat.BlRegister() 23class CNV_OT_attribute_from_custom_normals(bpy.types.Operator): 24 bl_idname = 'geometry.attribute_from_custom_normals' 25 bl_label = "From Custom Normals" 26 bl_description = "Creates a new attribute from the custom split normals" 27 bl_options = {'REGISTER', 'UNDO'} 28 29 items = [ 30 ('FLOAT_VECTOR', "Vector" , "3D vector with floating point values" , 'NONE', 1), 31 ('FLOAT_COLOR' , "Float Color", "RGBA color with floating point precisions", 'NONE', 2), 32 ('BYTE_COLOR' , "Byte Color" , "RGBA color with 8-bit precision" , 'NONE', 3), 33 ] 34 35 data_type = bpy.props.EnumProperty(items=items, name="Data Type", default='FLOAT_COLOR') 36 37 @classmethod 38 def poll(cls, context): 39 obs = context.selected_objects 40 active_ob = context.active_object 41 if active_ob.type != 'MESH': 42 return False 43 return True 44 45 def invoke(self, context, event): 46 return context.window_manager.invoke_props_dialog(self) 47 48 def draw(self, context): 49 self.layout.prop(self, 'data_type') 50 pass 51 52 def execute(self, context): 53 ob = context.active_object 54 me = ob.data 55 56 pre_mode = ob.mode 57 bpy.ops.object.mode_set(mode='OBJECT') 58 59 me.calc_normals_split() 60 61 if (compat.IS_LEGACY or bpy.app.version < (2, 91)): 62 return {'ERROR'} 63 else: 64 attribute = me.attributes.new('custom_normals', self.data_type, 'CORNER') 65 attribute_data = attribute.data 66 67 for key in attribute.data.keys(): 68 print(repr(key)) 69 70 for loop_index, loop in enumerate(me.loops): 71 if isinstance(attribute, bpy.types.FloatVectorAttribute): 72 attribute.data[loop_index].vector = loop.normal 73 else: 74 attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 75 loop.normal[0] * 0.5 + 0.5, 76 loop.normal[1] * 0.5 + 0.5, 77 loop.normal[2] * 0.5 + 0.5, 78 1, 79 ) 80 81 82 83 bpy.ops.object.mode_set(mode=pre_mode) 84 return {'FINISHED'}
items =
[('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)]
data_type: <_PropertyDeferred, <built-in function EnumProperty>, {'items': [('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)], 'name': 'Data Type', 'default': 'FLOAT_COLOR', 'attr': 'data_type'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'items': [('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)], 'name': 'Data Type', 'default': 'FLOAT_COLOR', 'attr': 'data_type'}>
def
execute(self, context):
52 def execute(self, context): 53 ob = context.active_object 54 me = ob.data 55 56 pre_mode = ob.mode 57 bpy.ops.object.mode_set(mode='OBJECT') 58 59 me.calc_normals_split() 60 61 if (compat.IS_LEGACY or bpy.app.version < (2, 91)): 62 return {'ERROR'} 63 else: 64 attribute = me.attributes.new('custom_normals', self.data_type, 'CORNER') 65 attribute_data = attribute.data 66 67 for key in attribute.data.keys(): 68 print(repr(key)) 69 70 for loop_index, loop in enumerate(me.loops): 71 if isinstance(attribute, bpy.types.FloatVectorAttribute): 72 attribute.data[loop_index].vector = loop.normal 73 else: 74 attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 75 loop.normal[0] * 0.5 + 0.5, 76 loop.normal[1] * 0.5 + 0.5, 77 loop.normal[2] * 0.5 + 0.5, 78 1, 79 ) 80 81 82 83 bpy.ops.object.mode_set(mode=pre_mode) 84 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data
@compat.BlRegister()
class
CNV_OT_attribute_convert_normals86@compat.BlRegister() 87class CNV_OT_attribute_convert_normals(bpy.types.Operator): 88 bl_idname = 'geometry.attribute_convert_normals' 89 bl_label = "Convert Normals" 90 bl_description = "Converts the data type of the normals attribute" 91 bl_options = {'REGISTER', 'UNDO'} 92 93 items = [ 94 ('FLOAT_VECTOR', "Vector" , "3D vector with floating point values" , 'NONE', 1), 95 ('FLOAT_COLOR' , "Float Color", "RGBA color with floating point precisions", 'NONE', 2), 96 ('BYTE_COLOR' , "Byte Color" , "RGBA color with 8-bit precision" , 'NONE', 3), 97 ] 98 99 data_type = bpy.props.EnumProperty(items=items, name="Data Type", default='FLOAT_COLOR') 100 101 @classmethod 102 def poll(cls, context): 103 obs = context.selected_objects 104 active_ob = context.active_object 105 if active_ob.type != 'MESH': 106 return False 107 return True 108 109 def invoke(self, context, event): 110 me = context.active_object.data 111 112 if isinstance(me.attributes.active, bpy.types.FloatVectorAttribute): 113 self.data_type = 'FLOAT_COLOR' 114 else: 115 self.data_type = 'FLOAT_VECTOR' 116 117 return context.window_manager.invoke_props_dialog(self) 118 119 def draw(self, context): 120 self.layout.prop(self, 'data_type') 121 pass 122 123 def execute(self, context): 124 ob = context.active_object 125 me = ob.data 126 127 pre_mode = ob.mode 128 bpy.ops.object.mode_set(mode='OBJECT') 129 130 if (compat.IS_LEGACY or bpy.app.version < (3,1)): 131 return {'ERROR'} 132 133 old_attribute = me.attributes.active 134 name = old_attribute.name 135 136 old_data = [None] * len(me.loops) 137 138 # store old data 139 for loop_index, loop in enumerate(me.loops): 140 if isinstance(old_attribute, bpy.types.FloatVectorAttribute): 141 old_data[loop_index] = old_attribute.data[loop_index].vector 142 else: 143 color = old_attribute.data[loop_index].color 144 old_data[loop_index] = ( # convert from range (0, 1) to range (-1, 1) 145 (color[0] - 0.5) / 0.5, 146 (color[1] - 0.5) / 0.5, 147 (color[2] - 0.5) / 0.5, 148 ) 149 150 # create new attribute 151 new_attribute = me.attributes.new(f'temp_{name}', self.data_type, 'CORNER') 152 153 # set new data 154 for loop_index, loop in enumerate(me.loops): 155 old_loop_data = old_data[loop_index] 156 if isinstance(new_attribute, bpy.types.FloatVectorAttribute): 157 new_attribute.data[loop_index].vector = old_loop_data 158 else: 159 new_attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 160 old_loop_data[0] * 0.5 + 0.5, 161 old_loop_data[1] * 0.5 + 0.5, 162 old_loop_data[2] * 0.5 + 0.5, 163 1, 164 ) 165 166 # delete old attribute 167 me.attributes.remove(me.attributes[name]) 168 169 # restore state 170 new_attribute.name = name 171 bpy.ops.object.mode_set(mode=pre_mode) 172 return {'FINISHED'}
items =
[('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)]
data_type: <_PropertyDeferred, <built-in function EnumProperty>, {'items': [('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)], 'name': 'Data Type', 'default': 'FLOAT_COLOR', 'attr': 'data_type'}> =
<_PropertyDeferred, <built-in function EnumProperty>, {'items': [('FLOAT_VECTOR', 'Vector', '3D vector with floating point values', 'NONE', 1), ('FLOAT_COLOR', 'Float Color', 'RGBA color with floating point precisions', 'NONE', 2), ('BYTE_COLOR', 'Byte Color', 'RGBA color with 8-bit precision', 'NONE', 3)], 'name': 'Data Type', 'default': 'FLOAT_COLOR', 'attr': 'data_type'}>
def
execute(self, context):
123 def execute(self, context): 124 ob = context.active_object 125 me = ob.data 126 127 pre_mode = ob.mode 128 bpy.ops.object.mode_set(mode='OBJECT') 129 130 if (compat.IS_LEGACY or bpy.app.version < (3,1)): 131 return {'ERROR'} 132 133 old_attribute = me.attributes.active 134 name = old_attribute.name 135 136 old_data = [None] * len(me.loops) 137 138 # store old data 139 for loop_index, loop in enumerate(me.loops): 140 if isinstance(old_attribute, bpy.types.FloatVectorAttribute): 141 old_data[loop_index] = old_attribute.data[loop_index].vector 142 else: 143 color = old_attribute.data[loop_index].color 144 old_data[loop_index] = ( # convert from range (0, 1) to range (-1, 1) 145 (color[0] - 0.5) / 0.5, 146 (color[1] - 0.5) / 0.5, 147 (color[2] - 0.5) / 0.5, 148 ) 149 150 # create new attribute 151 new_attribute = me.attributes.new(f'temp_{name}', self.data_type, 'CORNER') 152 153 # set new data 154 for loop_index, loop in enumerate(me.loops): 155 old_loop_data = old_data[loop_index] 156 if isinstance(new_attribute, bpy.types.FloatVectorAttribute): 157 new_attribute.data[loop_index].vector = old_loop_data 158 else: 159 new_attribute.data[loop_index].color = ( # convert from range(-1, 1) to range(0, 1) 160 old_loop_data[0] * 0.5 + 0.5, 161 old_loop_data[1] * 0.5 + 0.5, 162 old_loop_data[2] * 0.5 + 0.5, 163 1, 164 ) 165 166 # delete old attribute 167 me.attributes.remove(me.attributes[name]) 168 169 # restore state 170 new_attribute.name = name 171 bpy.ops.object.mode_set(mode=pre_mode) 172 return {'FINISHED'}
Inherited Members
- bpy_types.Operator
- as_keywords
- poll_message_set
- builtins.bpy_struct
- keys
- values
- get
- pop
- as_pointer
- keyframe_insert
- keyframe_delete
- driver_add
- driver_remove
- is_property_set
- property_unset
- is_property_readonly
- is_property_overridable_library
- property_overridable_library_set
- path_resolve
- path_from_id
- type_recast
- bl_rna_get_subclass_py
- bl_rna_get_subclass
- id_properties_ensure
- id_properties_clear
- id_properties_ui
- id_data