|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
|
import pymel.core as pm
''' #作者主页:http://blog.sina.com.cn/suyin67
一键批量在头发模型上生成骨骼或中心曲线。
【使用方法 1】
选择所有模型,
执行下面其中一条命令:
createNewObjectInHairModel('joint')
createNewObjectInHairModel('curve')
如遇到骨骼链层级方向不对,请使用本博客之前《从父对象获得下层单链(递归)、翻转层级结构》一文中的脚本进行反向。
【使用方法 2】
批量选择模型的一端开口的 边界边,(选中了其中一条边界边即可,多选没有关系)
执行下面其中一条命令:
createNewObjectInHairModel('joint')
createNewObjectInHairModel('curve')
骨骼的根部会处于选择的开口处
【使用方法 3】
批量选择模型的一端开口的 边界边,(选中了其中一条边界边即可,多选没有关系)
执行下面的命令:
reorderVertices_selectEdges()
然后跳转到【使用方法 1】进行。
骨骼链根部会处于选择的开口处
推荐【使用方法 2】
''' def reorderVertices_inputvertices(vertex1, vertex2, vertex3):
'''
输入同一面上连续的三个顶点,对网格顶点重新排序
'''
theMesh = vertex1.node().getTransform()
pm.delete(theMesh, ch = 1)
pm.meshReorder(vertex1, vertex2, vertex3)
def reorderVertices_inputEdge(inputEdge):
'''
输入一条多边形边,对网格顶点重新排序
'''
if type(inputEdge) != pm.general.MeshEdge or len(inputEdge.connectedFaces()) > 1:
pm.warning('—————— reorderVertices_inputEdge 非边界边!请检查输入的边是否处于边界。 ——————')
return
connectedVertices = inputEdge.connectedVertices()
inputEdge.select(r = 1)
pm.mel.PolySelectConvert(1)
pm.mel.PolySelectConvert(3)
verticesForReorder = pm.selected(fl = 1)
pm.select(cl = 1)
verticesForReorder = list(set(verticesForReorder) - set(connectedVertices))
vertex1 = connectedVertices[0]
vertex2 = connectedVertices[1]
vertex3 = verticesForReorder[0]
reorderVertices_inputvertices(vertex1, vertex2, vertex3)
def reorderVertices_inputMesh(inputMesh):
'''
输入一个边界开口的多边形网格,对网格顶点重新排序,序号[0]在原边界序号最小顶点处
'''
borderEdge = [each for each in inputMesh.e if each.isOnBoundary()]
inputEdge = borderEdge[0]
reorderVertices_inputEdge(inputEdge)
def reorderVertices(inputObject):
'''
输入 同一面上连续的三个顶点 或 一条多边形边 或 一个非闭合多边形网格,对网格顶点重新排序
'''
if type(inputObject) == pm.nodetypes.Transform:
reorderVertices_inputMesh(inputObject)
elif type(inputObject) == pm.general.MeshEdge:
reorderVertices_inputEdge(inputObject)
elif type(inputObject) == pm.general.MeshVertex:
reorderVertices_inputvertices(inputObject)
else:
pm.warning('—————— reorderVertices 输入参数有误!需要 同一面上连续的三个顶点 或一条多边形边 或 非闭合多边形网格。请检查。 ——————')
def createNewObjectInHairModel_main(willObjectType, inputObject):
'''
输入头发模型的 开口端一条边 或 一个多边形网格,在模型中心生成一条骨骼链或曲线,根部在选择处
willObjectType = `object` `joint`
'''
#inputObject = pm.selected()[0]
reorderVertices(inputObject)
theMesh = inputObject.node().getTransform()
theMesh.e[0].select(r = 1)
pm.polySelectSp(ring=1)
sel = pm.selected(fl = 1)
pos_list = []
for each in sel:
pm.select(each, r = 1)
pm.polySelectSp(loop = 1)
cl = pm.cluster()[1]
pos_list.append(pm.xform(cl, q = 1, ws = 1, rp = 1))
pm.delete(cl)
pm.select(cl = 1)
result = []
if willObjectType == 'joint':
for pos in pos_list:
result.append(pm.joint(p = pos))
result[0].select(r = 1)
elif willObjectType == 'curve':
result.append(pm.curve(d = 3, ep = pos_list))
result = result[0]
pm.mel.mprint('################################################\n')
pm.mel.mprint('—————— 创建成功 ! —————— \n网格 : {0} \n结果 : {1}。\n'.format(theMesh, result))
pm.mel.mprint('################################################\n')
return result
def classifyComponents(inputObjects):
'''
将输入的点、边、面按所属网格分组, 需要输入一个列表
'''
components_list = filter(lambda each : type(each) in [pm.general.MeshVertex, pm.general.MeshEdge, pm.general.MeshFace], inputObjects)
theMesh_list = list(set([each.node().getTransform().name() for each in components_list]))
componentsPerMesh_list = []
for i,each in enumerate(theMesh_list):
componentsPerMesh_list.append(filter(lambda element : element.node().getTransform().name() == each, components_list))
return componentsPerMesh_list
def reorderVertices_selectEdges():
'''#button
批量。
选择边,对网格顶点重新排序
'''
sel = pm.selected(fl = 1)
borderEdge_list = filter(lambda element : len(element.connectedFaces()) == 1, sel)
borderEdgesPerMesh_list = classifyComponents(borderEdge_list)
firstEdge_list = [each[0] for each in borderEdgesPerMesh_list]
for each in firstEdge_list:
reorderVertices_inputEdge(each)
pm.mel.mprint('—————— 对网格顶点重新排序成功。 ——————')
def createNewObjectInHairModel(willObjectType):
'''#button
批量生成。
选择头发模型 或 一条边界边 或 整条边界,在模型中心生成一条骨骼链或曲线,根部在选择处。
'''
sel = pm.selected(fl = 1)
if len(sel) < 1:
pm.warning('—————— 请选择 多个物体的边界边/或边界上的边 或 多个网格。——————')
return
#过滤列表,取同一物体的一条边界边
edge_list = filter(lambda each : type(each) == pm.general.MeshEdge, sel)
borderEdge_list = filter(lambda element : len(element.connectedFaces()) == 1, edge_list)
borderEdgesPerMesh_list = classifyComponents(borderEdge_list)
firstEdge_list = [each[0] for each in borderEdgesPerMesh_list]
#过滤列表,获得多边形
mesh_list = filter(lambda each : type(each) == pm.nodetypes.Transform, sel)
mesh_filterList = []
for each in mesh_list:
try:
if each.getChildren()[0].nodeType() == 'mesh':
mesh_filterList.append(each)
except:
pass
inputObject_list = firstEdge_list + mesh_filterList
result_list = []
for each in inputObject_list:
result_list.append(createNewObjectInHairModel_main(willObjectType, each))
pm.select(result_list, r = 1)
return result_list
|