Any
/
vae
/com3d
/[CM3D2]English Mod Tools Pack
/CM3D2 Converter (English)
/misc_INFO_MT_curve_add.py
# 「3Dビュー」エリア → 追加(Shift+A) → カーブ | |
import os, re, sys, bpy, time, bmesh, mathutils | |
from . import common | |
# メニュー等に項目追加 | |
def menu_func(self, context): | |
self.layout.separator() | |
self.layout.operator('curve.hair_bunch_add', text="Add Hair Curve", icon_value=common.preview_collections['main']['KISS'].icon_id) | |
class hair_bunch_add(bpy.types.Operator): | |
bl_idname = 'curve.hair_bunch_add' | |
bl_label = "Add A Lock of Hair" | |
bl_description = "Will add an anime style hair lock at the 3D Cursor." | |
bl_options = {'REGISTER', 'UNDO'} | |
radius = bpy.props.FloatProperty(name="Radius", default=0.1, min=0, max=10, soft_min=0, soft_max=10, step=10, precision=2) | |
random_multi = bpy.props.FloatProperty(name="Randomness", default=0.5, min=0, max=10, soft_min=0, soft_max=10, step=10, precision=2) | |
z_plus = bpy.props.FloatProperty(name="Medium Z Axis Height", default=0.1, min=0, max=10, soft_min=0, soft_max=10, step=10, precision=2) | |
def poll(cls, context): | |
return True | |
def invoke(self, context, event): | |
import bpy_extras.view3d_utils | |
self.pre_draw = bpy.types.VIEW3D_HT_header.draw | |
def header_draw(self, context): | |
row = self.layout.row(align=True) | |
row.label(text="Mouse Wheel:Change Thickness") | |
row.label(text="Middle Mouse Button:Random Intensity Change") | |
row.label(text="Z/X Keys:Height Change") | |
bpy.types.VIEW3D_HT_header.draw = header_draw | |
if context.active_object: | |
if context.active_object.mode != 'OBJECT': | |
self.report(type={'ERROR'}, message="Please add in Object mode only.") | |
return {'CANCELLED'} | |
self.end_location = bpy_extras.view3d_utils.region_2d_to_location_3d(context.region, context.region_data, (event.mouse_region_x, event.mouse_region_y), context.space_data.cursor_location) | |
curve = context.blend_data.curves.new("Hair Bunch", 'CURVE') | |
ob = context.blend_data.objects.new("Hair Bunch", curve) | |
context.scene.objects.link(ob) | |
context.scene.objects.active = ob | |
ob.select = True | |
curve.dimensions = '3D' | |
curve.resolution_u = 5 | |
spline = curve.splines.new('NURBS') | |
spline.points.add(3) | |
spline.points[0].radius = 0.0 | |
spline.points[-1].radius = 0.0 | |
spline.use_endpoint_u = True | |
spline.order_u = 4 | |
spline.resolution_u = 5 | |
self.set_spline(spline, context) | |
self.object = ob | |
self.curve = curve | |
self.spline = spline | |
bevel_curve = context.blend_data.curves.new("Hair Bunch Bevel", 'CURVE') | |
bevel_ob = context.blend_data.objects.new("Hair Bunch Bevel", bevel_curve) | |
context.scene.objects.link(bevel_ob) | |
bevel_ob.select = True | |
curve.bevel_object = bevel_ob | |
bevel_ob.parent = ob | |
bevel_ob.parent_type = 'VERTEX' | |
bevel_ob.parent_vertices = (3, 3, 3) | |
bevel_curve.dimensions = '2D' | |
bevel_curve.fill_mode = 'NONE' | |
bevel_curve.resolution_u = 2 | |
spline = bevel_curve.splines.new('NURBS') | |
spline.points.add(7) | |
spline.use_cyclic_u = True | |
spline.order_u = 4 | |
spline.resolution_u = 2 | |
self.bevel_object = bevel_ob | |
self.bevel_curve = bevel_curve | |
self.bevel_spline = spline | |
self.set_bevel_spline(spline) | |
context.window_manager.modal_handler_add(self) | |
return {'RUNNING_MODAL'} | |
def modal(self, context, event): | |
import bpy_extras.view3d_utils | |
#print(event.type, event.value) | |
if event.type == 'MOUSEMOVE': | |
self.end_location = bpy_extras.view3d_utils.region_2d_to_location_3d(context.region, context.region_data, (event.mouse_region_x, event.mouse_region_y), context.space_data.cursor_location) | |
self.execute(context) | |
elif event.type == 'WHEELUPMOUSE' and event.value == 'PRESS': | |
self.radius += 0.05 | |
self.set_bevel_spline(self.bevel_spline) | |
self.object.update_tag({'OBJECT', 'DATA'}) | |
elif event.type == 'WHEELDOWNMOUSE' and event.value == 'PRESS': | |
self.radius -= 0.05 | |
self.set_bevel_spline(self.bevel_spline) | |
self.object.update_tag({'OBJECT', 'DATA'}) | |
elif event.type == 'MIDDLEMOUSE' and event.value == 'PRESS': | |
if 0.9 < self.random_multi: | |
self.random_multi = 0.0 | |
elif 0.4 < self.random_multi: | |
self.random_multi = 1.0 | |
else: | |
self.random_multi = 0.5 | |
self.set_bevel_spline(self.bevel_spline) | |
elif event.type == 'Z' and event.value == 'PRESS': | |
self.z_plus += 0.1 | |
self.execute(context) | |
elif event.type == 'X' and event.value == 'PRESS': | |
self.z_plus -= 0.1 | |
self.execute(context) | |
elif event.type == 'LEFTMOUSE' and event.value == 'PRESS': | |
bpy.types.VIEW3D_HT_header.draw = self.pre_draw | |
context.area.tag_redraw() | |
return {'FINISHED'} | |
elif event.type in {'RIGHTMOUSE', 'ESC'} and event.value == 'PRESS': | |
common.remove_data([self.object, self.bevel_object, self.curve, self.bevel_curve]) | |
bpy.types.VIEW3D_HT_header.draw = self.pre_draw | |
context.area.tag_redraw() | |
return {'CANCELLED'} | |
return {'RUNNING_MODAL'} | |
def get_random_point(self, co): | |
import random | |
r = self.radius * self.random_multi | |
co.x = co.x + random.uniform(-r, r) | |
co.y = co.y + random.uniform(-r, r) | |
return co | |
def set_bevel_spline(self, spline): | |
import math, mathutils | |
r = self.radius | |
vec = mathutils.Vector((0, r, 0)) | |
min_rad = -math.radians(360 / len(spline.points)) | |
for index, point in enumerate(spline.points): | |
eul = mathutils.Euler((0, 0, min_rad * index), 'XYZ') | |
now_vec = vec.copy() | |
now_vec.rotate(eul) | |
now_vec = self.get_random_point(now_vec) | |
point.co = list(now_vec[:]) + [1] | |
def set_spline(self, spline, context): | |
diff_co = self.end_location - context.space_data.cursor_location | |
plus_co = diff_co * 0.333333 | |
plus_co.z = -plus_co.z + self.z_plus | |
point1 = diff_co * 0.333333 | |
point1 += plus_co * 1 | |
point1 += context.space_data.cursor_location | |
point2 = diff_co * 0.666666 | |
point2 += plus_co * 1 | |
point2 += context.space_data.cursor_location | |
spline.points[0].co = list(context.space_data.cursor_location[:]) + [1] | |
spline.points[1].co = list(point1[:]) + [1] | |
spline.points[2].co = list(point2[:]) + [1] | |
spline.points[-1].co = list(self.end_location[:]) + [1] | |
def execute(self, context): | |
try: | |
self.set_spline(self.spline, context) | |
except: | |
self.report(type={'ERROR'}, message="Please run in Object mode. Note: Script is Buggy.") | |
return {'CANCELLED'} | |
return {'FINISHED'} | |