概要
Blenderの任意の位置に(UVを崩さずに)辺をスライドさせたい!という場合、手段がありません。
Gキーを2回押すとUVの状態を崩さずに辺をスライドさせられますが、数値指定できるのは「係数」とかいう謎の値……。
この「係数」を計算するアドオンを作りました。
対応
Blenderアドオンをインストールしてください。
slide_coefficient_calculator.cs
bl_info = {
"name": "Slide Coefficient Calculator",
"blender": (2, 82, 0), # 対応するBlenderのバージョン
"category": "Object",
"author": "Your Name",
"version": (1, 0),
"description": "Calculates slide coefficient based on selected edge positions.",
"warning": "",
"doc_url": "",
"tracker_url": "",
"support": "COMMUNITY",
"location": "View3D > Tool Shelf",
"warning": "",
"category": "Object",
}
import bpy
# 選択した辺の座標を取得する関数
def get_selected_edge_coordinates(axis):
obj = bpy.context.object
# オブジェクトが選択されているか確認
if obj and obj.type == 'MESH':
# メッシュデータの更新
obj.update_from_editmode()
# 選択されたエッジを取得
edges = [e for e in obj.data.edges if e.select]
if edges:
# エッジの頂点座標をワールド座標に変換
edge_coords = []
for edge in edges:
v1_co = obj.matrix_world @ obj.data.vertices[edge.vertices[0]].co
v2_co = obj.matrix_world @ obj.data.vertices[edge.vertices[1]].co
edge_coords.append((v1_co, v2_co))
# ワールド座標の指定軸だけを抽出
if axis == 'X':
return [coord.x for edge in edge_coords for coord in edge]
elif axis == 'Y':
return [coord.y for edge in edge_coords for coord in edge]
elif axis == 'Z':
return [coord.z for edge in edge_coords for coord in edge]
return None
# オペレーターを作成
class SLIDE_OT_CalculateSlideCoefficient(bpy.types.Operator):
bl_idname = "object.calculate_slide_coefficient"
bl_label = "Calculate Slide Coefficient"
def execute(self, context):
target_edge_position = context.scene.target_edge_position
end_edge_position = context.scene.end_edge_position
world_destination_position = context.scene.world_destination_position
print(f"Target Edge Position: {target_edge_position}, End Edge Position: {end_edge_position}, World Destination Position: {world_destination_position}")
if end_edge_position == target_edge_position:
self.report({'ERROR'}, "Target Edge and End Edge cannot have the same position.")
return {'CANCELLED'}
try:
coefficient = (world_destination_position - target_edge_position) / (end_edge_position - target_edge_position)
self.report({'INFO'}, f"Calculated Coefficient: {coefficient:.9f}")
except ZeroDivisionError:
self.report({'ERROR'}, "Division by zero error.")
return {'CANCELLED'}
return {'FINISHED'}
class SLIDE_OT_SetEdgePosition(bpy.types.Operator):
bl_idname = "object.set_target_edge_position"
bl_label = "Set Target Edge Position"
def execute(self, context):
axis = context.scene.selected_axis
selected_edge_coords = get_selected_edge_coordinates(axis)
if selected_edge_coords is not None and selected_edge_coords:
context.scene.target_edge_position = selected_edge_coords[0]
else:
self.report({'ERROR'}, "No edge selected.")
return {'CANCELLED'}
return {'FINISHED'}
class SLIDE_OT_SetEndEdgePosition(bpy.types.Operator):
bl_idname = "object.set_end_edge_position"
bl_label = "Set End Edge Position"
def execute(self, context):
axis = context.scene.selected_axis
selected_edge_coords = get_selected_edge_coordinates(axis)
if selected_edge_coords is not None and selected_edge_coords:
context.scene.end_edge_position = selected_edge_coords[1]
else:
self.report({'ERROR'}, "No edge selected.")
return {'CANCELLED'}
return {'FINISHED'}
class SLIDE_OT_SetWorldDestinationPosition(bpy.types.Operator):
bl_idname = "object.set_world_destination_position"
bl_label = "Set World Destination Position"
def execute(self, context):
axis = context.scene.selected_axis
selected_edge_coords = get_selected_edge_coordinates(axis)
if selected_edge_coords is not None and selected_edge_coords:
context.scene.world_destination_position = selected_edge_coords[0]
else:
self.report({'ERROR'}, "No edge selected.")
return {'CANCELLED'}
return {'FINISHED'}
class SLIDE_PT_CalculateSlidePanel(bpy.types.Panel):
bl_label = "Slide Coefficient Calculator"
bl_idname = "OBJECT_PT_slide_coefficient"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Tool'
def draw(self, context):
layout = self.layout
layout.label(text="Select Axis:")
row = layout.row(align=True)
row.prop(context.scene, "selected_axis", expand=True)
row = layout.row(align=True)
row.prop(context.scene, "target_edge_position")
row.operator("object.set_target_edge_position", text="Set")
row = layout.row(align=True)
row.prop(context.scene, "end_edge_position")
row.operator("object.set_end_edge_position", text="Set")
row = layout.row(align=True)
row.prop(context.scene, "world_destination_position")
row.operator("object.set_world_destination_position", text="Set")
layout.operator("object.calculate_slide_coefficient")
def register():
bpy.utils.register_class(SLIDE_OT_CalculateSlideCoefficient)
bpy.utils.register_class(SLIDE_OT_SetEdgePosition)
bpy.utils.register_class(SLIDE_OT_SetEndEdgePosition)
bpy.utils.register_class(SLIDE_OT_SetWorldDestinationPosition)
bpy.utils.register_class(SLIDE_PT_CalculateSlidePanel)
bpy.types.Scene.selected_axis = bpy.props.EnumProperty(
name="Axis",
description="Choose the axis to use for edge coordinates",
items=[('X', 'X Axis', 'Use the X axis'),
('Y', 'Y Axis', 'Use the Y axis'),
('Z', 'Z Axis', 'Use the Z axis')],
default='X'
)
bpy.types.Scene.target_edge_position = bpy.props.FloatProperty(name="Target Edge Position", default=0.0)
bpy.types.Scene.end_edge_position = bpy.props.FloatProperty(name="End Edge Position", default=0.0)
bpy.types.Scene.world_destination_position = bpy.props.FloatProperty(name="World Destination Position", default=0.0)
def unregister():
bpy.utils.unregister_class(SLIDE_OT_CalculateSlideCoefficient)
bpy.utils.unregister_class(SLIDE_OT_SetEdgePosition)
bpy.utils.unregister_class(SLIDE_OT_SetEndEdgePosition)
bpy.utils.unregister_class(SLIDE_OT_SetWorldDestinationPosition)
bpy.utils.unregister_class(SLIDE_PT_CalculateSlidePanel)
del bpy.types.Scene.selected_axis
del bpy.types.Scene.target_edge_position
del bpy.types.Scene.end_edge_position
del bpy.types.Scene.world_destination_position
if __name__ == "__main__":
register()
インストールするとツールタブに新しく「Slide Coefficient Calculator」というウィンドウが表示されます。
今回はY軸方向にスライドさせたいので「Y軸」トグルボタンを選択します。
そうしたら3つの値を入力します。
・移動させたい辺を選択して「Set」
・目的の座標の辺を選択して「Set」(普通にスライドに手入力でもいいです)
3つの値を入力し終わったら、「Calculate Slide Cofficient」ボタンを押します。
すると、infoログに計算結果が出力されます。
この値をコピペして、スライド時の「係数」に入力します。
(EndEdgePositionとして選択した辺によっては符号が反転している場合があるので、必要に応じてマイナスをかけてください)
以上です。