[Blender] 마우스 좌클릭으로 원하는 곳에 오브젝트 쉽게 복제하기(2)
2024. 11. 11. 09:51ㆍBlender
728x90
반응형
지난 글에서 만들었던 스크립트를 발전시켜서 기능을 추가해보았다.
전체 스크립트
import bpy
import mathutils
import random
from math import radians
from bpy_extras.view3d_utils import region_2d_to_vector_3d, region_2d_to_origin_3d
# Configuration variables
ObjectA = "TreeA"
ObjectB = "TreeB"
Zrotate = True # Set to True for random Z rotation, False for no rotation
def get_mouse_ray(context, event):
"""Calculate ray origin and direction from the mouse point in 3D view"""
region = context.region
region_3d = context.space_data.region_3d
# Get the 2D mouse coordinates
coord = (event.mouse_region_x, event.mouse_region_y)
# Calculate the ray origin and direction using bpy_extras utilities
ray_origin = region_2d_to_origin_3d(region, region_3d, coord)
ray_direction = region_2d_to_vector_3d(region, region_3d, coord)
return ray_origin, ray_direction
def place_tree(context, event, object_name):
"""Ray cast from the mouse point and place a tree at the hit location"""
# Get the object to duplicate
object_template = bpy.data.objects.get(object_name)
if object_template:
# Get the ray origin and direction from the mouse click
ray_origin, ray_direction = get_mouse_ray(context, event)
# Cast the ray from the mouse point
depsgraph = context.evaluated_depsgraph_get()
result, location, normal, index, object, matrix = context.scene.ray_cast(
depsgraph, ray_origin, ray_direction)
if result:
# Duplicate the object and place it at the hit location
new_object = object_template.copy()
new_object.data = object_template.data.copy()
new_object.location = location
# Apply random Z rotation if enabled
if Zrotate:
random_angle = random.uniform(0, 360) # Random angle between 0 and 360 degrees
new_object.rotation_euler[2] = radians(random_angle) # Apply rotation in radians
context.collection.objects.link(new_object)
print(f"{object_name} placed at {location}" + (f" with {random_angle:.1f}° rotation" if Zrotate else ""))
else:
print("No valid surface detected to place the object.")
else:
print(f"Error: Object not found. Make sure the object is named '{object_name}'")
class PlaceTreeOperator(bpy.types.Operator):
"""Place Objects on Mouse Click - Left Click for ObjectA, Shift+Left Click for ObjectB"""
bl_idname = "object.place_tree"
bl_label = "Place Object Operator"
def modal(self, context, event):
# Exit when pressing the right mouse button or ESC
if event.type in {'RIGHTMOUSE', 'ESC'}:
return {'CANCELLED'}
# Place object when left mouse button is clicked
if event.type == 'LEFTMOUSE' and event.value == 'PRESS':
if event.shift:
place_tree(context, event, ObjectB) # Place ObjectB with Shift+Left Click
else:
place_tree(context, event, ObjectA) # Place ObjectA with Left Click
return {'RUNNING_MODAL'}
return {'PASS_THROUGH'}
def invoke(self, context, event):
if context.area.type == 'VIEW_3D':
context.window_manager.modal_handler_add(self)
print("Object Placement Active - Left Click for ObjectA, Shift+Left Click for ObjectB, Right Click/ESC to exit")
return {'RUNNING_MODAL'}
else:
self.report({'ERROR'}, "Operator only works in the 3D Viewport.")
return {'CANCELLED'}
# Add keyboard shortcut
addon_keymaps = []
def register():
bpy.utils.register_class(PlaceTreeOperator)
# Add the keymap
wm = bpy.context.window_manager
kc = wm.keyconfigs.addon
if kc:
km = kc.keymaps.new(name='3D View', space_type='VIEW_3D')
kmi = km.keymap_items.new(
PlaceTreeOperator.bl_idname,
type='F',
value='PRESS',
shift=True
)
addon_keymaps.append((km, kmi))
def unregister():
# Remove the keymap
for km, kmi in addon_keymaps:
km.keymap_items.remove(kmi)
addon_keymaps.clear()
bpy.utils.unregister_class(PlaceTreeOperator)
if __name__ == "__main__":
register()
추가된 기능은, 두 가지 오브젝트를 선택하여 마우스 좌클릭으로 배치할 수 있다는 점이다.
원하는 오브젝트의 이름을 적어서 복제 배치할 수 있다.
ObjectA = "TreeA"
ObjectB = "TreeB"
또한 Z축 랜덤 회전 기능으로 랜덤성을 부여해야할 때 True/False로 스위치처럼 사용할 수 있다.
Zrotate = True
스크립트의 사용 방법은 이전 글과 동일하다.
Operator의 이름이 "Place Tree Operator"에서 "Place Obejct Operator"로 바뀌었다.
단축키를 설정한 후 단축키를 이용해 Operator를 실행한 후 [마우스 좌클릭]을 할 때는 ObjectA가, [Shift + 마우스 좌클릭]을 할 때는 ObjectB가 나오도록 설정했다. [Esc]로 기능을 끌 수 있다.
728x90
반응형
'Blender' 카테고리의 다른 글
[Blender] 마우스 좌클릭으로 원하는 곳에 오브젝트 쉽게 복제하기 (6) | 2024.10.29 |
---|---|
[Blender] glb, gltf 파일 Alpha 애니메이션 자동화 스크립트 (1) | 2024.09.27 |
[Blender] 블렌더에서 플립북 텍스쳐(FlipBook Texture) 스크립트 자동화 적용 (2) | 2024.09.24 |
[Blender] Collection Instancing을 통한 최적화 (1) | 2024.07.05 |
[Blender] 블렌더에서 플립북 텍스쳐(FlipBook Texture) 사용하기 (1) | 2024.06.19 |