-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.py
194 lines (160 loc) · 4.64 KB
/
main.py
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
"""
:Danny Wynne
:dannywynne.com
Mean value coordinates implimatation prototype
DESCRIPTION:
This script is a python implimation of part of this paper:
http://folk.uio.no/martinre/Publications/mv3d.pdf
Theorems 1 and 2 at the top of page 4
Helpful website to ease the maths:
http://www.ams.org/samplings/feature-column/fcarc-harmonic
The script also sets up the maya scene.
USAGE:
put mayamvc folder into maya/scripts and run:
import mayamvc.main as mvc
reload(mvc)
mvc.main()
turn on interactive playback or run mvc.update() after moving verts on the cage
"""
#import cgcg_rigging.lib.utils as u
import maya.OpenMaya as om
from math import *
import maya.cmds as cmds
import utils
reload(utils)
mvc_node = None
def ut(v,vi,tris):
"""calculates the value that is used to get the barycentric coordinates
Args:
v(MPoint) = kernal of the starshaped polyhedron. this is the point that will be deformed
vi(MPoint) = the current vert we are iterating over on the bounding polyhedron
tris(list of MPoints) = all triangle facets on the polyhedron that vi is a member of
"""
def A(vr,vs):
#get an angle
vec1 = vr-v
vec2 = vs-v
return vec1.angle(vec2)
def N(vr, vs):
#get the normal
vecr = vr-v
vecs = vs-v
norm = vecr^vecs
norm.normalize()
return norm
def _ut(i,j,k):
#floater's equation for ut
vecvi = (v-i)
vecvi.normalize()
top = A(j,k) + A(i,j)*( N(i, j)*N(j, k) ) + A(k,i)*(N(k, i)*N(j, k))
bot = 2*( vecvi*N(j,k) )
return top/bot
ri = v.distanceTo(vi)
ut_sum = 0
for t in tris:
ut_sum += _ut(t[0], t[1], t[2])
return ut_sum/ri
class MVC():
def __init__(self, cage, loc):
"""set weights and update mean value coordinates for a point in a cage
Args:
cage(MayaPolyWrapper) - deform this then call update to
"""
self.cage = cage
self.loc = loc
self.calculate_bary_coords()
def update(self):
#refresh the list p with the current location of the locators in maya
pnts = self.cage.get_vert_pnts()
x,y,z = 0,0,0
for i in range(len(pnts)):
x += pnts[i].x*self.bary[i]
y += pnts[i].y*self.bary[i]
z += pnts[i].z*self.bary[i]
cmds.setAttr(self.loc+".t", x,y,z)
def calculate_bary_coords(self):
pnt_map = self.cage.get_poly_pnt_map()
#calculate ut
ut_values = []
for m in pnt_map:
tris= list(m[1])
tris.reverse()
ut_values.append(ut(utils.pnt(self.loc), m[0], tris))
#barycentric coordinates
bary=[]
ut_sum = sum(ut_values)
for u in ut_values:
bary.append(u/ut_sum)
self.bary = bary
class MayaPolyWrapper():
"""interface wrapper for mvc to use maya polygons
Args:
poly_map [[vert, [all triangles that contain this vert],] - map of all verts
in the poly and the tris they are a member of
"""
def __init__(self, poly_map):
self.poly_map = poly_map
def get_poly_pnt_map(self):
"""return poly_map as MPoints
"""
pnt_map = []
for m in self.poly_map:
tris = []
for t in m[1]:
tris.append([utils.pnt(x) for x in t])
pnt_map.append([utils.pnt(m[0]), tris])
return pnt_map
def get_vert_pnts(self):
"""return list of verts pos as MPoints
"""
return [utils.pnt(x[0]) for x in self.poly_map]
def setup_scene():
#manually create a simple tetrahedron
p1 = cmds.polyCreateFacet(p=[(0,0,0), (1,0,0), (0,0,1)])
p2 = cmds.polyCreateFacet(p=[(0,0,0), (0,1,0), (1,0,0)])
p3 = cmds.polyCreateFacet(p=[(0,0,0), (0,0,1), (0,1,0)])
p4 = cmds.polyCreateFacet(p=[(0,0,1), (1,0,0), (0,1,0)])
cmds.polyMergeVertex(cmds.polyUnite(p1,p2,p3,p4, ch=0, name = "cage"), ch=0)
poly_map =[
["cage.vtx[0]", [ ("cage.vtx[0]","cage.vtx[2]","cage.vtx[3]"),
("cage.vtx[0]","cage.vtx[3]","cage.vtx[1]"),
("cage.vtx[0]","cage.vtx[1]","cage.vtx[2]"),
]
],
["cage.vtx[1]", [ ("cage.vtx[1]","cage.vtx[0]","cage.vtx[3]"),
("cage.vtx[1]","cage.vtx[3]","cage.vtx[2]"),
("cage.vtx[1]","cage.vtx[2]","cage.vtx[0]"),
]
],
["cage.vtx[2]", [ ("cage.vtx[2]","cage.vtx[3]","cage.vtx[0]"),
("cage.vtx[2]","cage.vtx[1]","cage.vtx[3]"),
("cage.vtx[2]","cage.vtx[0]","cage.vtx[1]"),
]
],
["cage.vtx[3]", [ ("cage.vtx[3]","cage.vtx[2]","cage.vtx[1]"),
("cage.vtx[3]","cage.vtx[1]","cage.vtx[0]"),
("cage.vtx[3]","cage.vtx[0]","cage.vtx[2]"),
]
]
]
#debug tetra
"""
for p in poly_map:
tris = p[1]
for t in tris:
pnts = []
for vert in t:
pnt = utils.pnt(vert)
pnts.append([pnt.x, pnt.y, pnt.z])
cmds.polyCreateFacet(p=pnts)
"""
cage = MayaPolyWrapper(poly_map)
loc = utils.loc([.1,.1,.1])
return cage, loc
def main():
global mvc_node
cage, loc = setup_scene()
mvc_node = MVC(cage, loc)
cmds.expression(s='python("mvc.update()");')
def update():
mvc_node.update()