216 lines
5.1 KiB
Python
216 lines
5.1 KiB
Python
|
|
import bpy
|
|
from mathutils import Vector
|
|
from mathutils.geometry import intersect_line_line_2d
|
|
|
|
|
|
def get_mat(ob):
|
|
for sl in ob.material_slots:
|
|
if sl.material:
|
|
return sl.material
|
|
|
|
def link_mat_to_object(ob):
|
|
for sl in ob.material_slots:
|
|
m = sl.material
|
|
sl.link = 'OBJECT'
|
|
sl.material = m
|
|
|
|
def get_operator_from_id(idname):
|
|
if not '.' in idname:
|
|
return
|
|
|
|
m, o = idname.split(".")
|
|
try:
|
|
op = getattr(getattr(bpy.ops, m), o)
|
|
op.get_rna_type()
|
|
except Exception:
|
|
return
|
|
|
|
return op
|
|
'''
|
|
def canvas_space(point,scale,offset):
|
|
return scale*Vector(point)+Vector(offset)
|
|
'''
|
|
|
|
def get_object_color(ob):
|
|
if not ob.data.materials:
|
|
return
|
|
|
|
mat = get_mat(ob)
|
|
if not mat or not mat.node_tree or not mat.node_tree.nodes:
|
|
return
|
|
|
|
emit_node = mat.node_tree.nodes.get('Emission')
|
|
if not emit_node:
|
|
return
|
|
|
|
return emit_node.inputs['Color'].default_value
|
|
|
|
def intersect_rectangles(bound, border): # returns None if rectangles don't intersect
|
|
dx = min(border[1][0],bound[1][0]) - max(border[0][0],bound[0][0])
|
|
dy = min(border[0][1],bound[0][1]) - max(border[2][1],bound[2][1])
|
|
|
|
if (dx>=0) and (dy>=0):
|
|
return dx*dy
|
|
|
|
def point_inside_rectangle(point, rect):
|
|
return rect[0][0]< point[0]< rect[1][0] and rect[2][1]< point[1]< rect[0][1]
|
|
|
|
def point_over_shape(point,verts,loops,outside_point=(-1,-1)):
|
|
out = Vector(outside_point)
|
|
pt = Vector(point)
|
|
|
|
intersections = 0
|
|
for loop in loops:
|
|
for i,p in enumerate(loop):
|
|
a = Vector(verts[loop[i-1]])
|
|
b = Vector(verts[p])
|
|
|
|
if intersect_line_line_2d(pt,out,a,b):
|
|
intersections += 1
|
|
|
|
if intersections%2 == 1: #chek if the nb of intersection is odd
|
|
return True
|
|
|
|
|
|
def border_over_shape(border,verts,loops):
|
|
for loop in loops:
|
|
for i,p in enumerate(loop):
|
|
a = Vector(verts[loop[i-1]])
|
|
b = Vector(verts[p])
|
|
|
|
for j in range(0,4):
|
|
c = border[j-1]
|
|
d = border[j]
|
|
if intersect_line_line_2d(a,b,c,d):
|
|
return True
|
|
|
|
for point in verts:
|
|
if point_inside_rectangle(point,border):
|
|
return True
|
|
|
|
for point in border:
|
|
if point_over_shape(point,verts,loops):
|
|
return True
|
|
|
|
|
|
|
|
def border_loop(vert, loop):
|
|
border_edge =[e for e in vert.link_edges if e.is_boundary]
|
|
|
|
if border_edge:
|
|
for edge in border_edge:
|
|
other_vert = edge.other_vert(vert)
|
|
|
|
if not other_vert in loop:
|
|
loop.append(other_vert)
|
|
border_loop(other_vert, loop)
|
|
|
|
return loop
|
|
else:
|
|
return [vert]
|
|
|
|
|
|
def contour_loops(bm, vert_index=0, loops=None, vert_indices=None):
|
|
loops = loops or []
|
|
vert_indices = vert_indices or [v.index for v in bm.verts]
|
|
|
|
bm.verts.ensure_lookup_table()
|
|
|
|
loop = border_loop(bm.verts[vert_index], [bm.verts[vert_index]])
|
|
if len(loop) >1:
|
|
loops.append(loop)
|
|
|
|
for v in loop:
|
|
vert_indices.remove(v.index)
|
|
|
|
if len(vert_indices):
|
|
contour_loops(bm, vert_indices[0], loops, vert_indices)
|
|
|
|
return loops
|
|
|
|
|
|
def get_IK_bones(IK_last):
|
|
ik_chain = IK_last.parent_recursive
|
|
ik_len = 0
|
|
|
|
#Get IK len:
|
|
for c in IK_last.constraints:
|
|
if c.type == 'IK':
|
|
ik_len = c.chain_count -2
|
|
break
|
|
|
|
IK_root = ik_chain[ik_len]
|
|
|
|
IK_mid= ik_chain[:ik_len]
|
|
|
|
IK_mid.reverse()
|
|
IK_mid.append(IK_last)
|
|
|
|
return IK_root,IK_mid
|
|
|
|
def find_mirror(name):
|
|
mirror = None
|
|
prop= False
|
|
|
|
if name:
|
|
|
|
if name.startswith('[')and name.endswith(']'):
|
|
prop = True
|
|
name= name[:-2][2:]
|
|
|
|
match={
|
|
'R': 'L',
|
|
'r': 'l',
|
|
'L': 'R',
|
|
'l': 'r',
|
|
}
|
|
|
|
separator=['.','_']
|
|
|
|
if name.startswith(tuple(match.keys())):
|
|
if name[1] in separator:
|
|
mirror = match[name[0]]+name[1:]
|
|
|
|
if name.endswith(tuple(match.keys())):
|
|
if name[-2] in separator:
|
|
mirror = name[:-1]+match[name[-1]]
|
|
|
|
if mirror and prop == True:
|
|
mirror='["%s"]'%mirror
|
|
|
|
return mirror
|
|
|
|
else:
|
|
return None
|
|
|
|
def is_shape(ob):
|
|
scn = bpy.context.scene
|
|
canvas = scn.rig_picker.canvas
|
|
if not canvas or ob.hide_render:
|
|
return False
|
|
|
|
shapes = {ob for col in canvas.users_collection for ob in col.all_objects}
|
|
|
|
if ob.type in ('MESH', 'CURVE', 'FONT') and ob in shapes:
|
|
return True
|
|
|
|
return False
|
|
|
|
def is_over_region(self,context,event):
|
|
inside = 2 < event.mouse_region_x < context.region.width -2 and \
|
|
2 < event.mouse_region_y < context.region.height -2 and \
|
|
[a for a in context.screen.areas if a.as_pointer()==self.adress] and \
|
|
not context.screen.show_fullscreen
|
|
|
|
return inside
|
|
|
|
def bound_box_center(ob):
|
|
points = [ob.matrix_world@Vector(p) for p in ob.bound_box]
|
|
|
|
x = [v[0] for v in points]
|
|
y = [v[1] for v in points]
|
|
z = [v[2] for v in points]
|
|
|
|
return (sum(x) / len(points), sum(y) / len(points),sum(z) / len(points))
|