/
dihSmoothAttribTransfer.py
188 lines (174 loc) · 5.93 KB
/
dihSmoothAttribTransfer.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
'''..................................................................................................
Author: Diego Inácio
Script: dihSmoothAttribTransfer
Version: 1.0.0
Software: Houdini 12.1
Date Upadated: AUG/12/2013
www.diegoinacio.com
.....................................................................................................
This tool makes smoothly transfer of point attributes between two models. To create this tool,
please, follow the next steps:
1 - Create new operator... (File/New Operator Type...);
2 - Put a operator name and a operator label as you want;
3 - Select "Python Type" on Operator Style;
4 - On Network Type, select "Geometry Operator"(this is a very important step!!! pay attention =));
5 - Save where you want; (do not forget to put ".otl" extension, not ".py")
6 - On Type Properties window, in Basic tab, set to 2 a minimum and maximum inputs
6 - In Code tab, paste the code below.
If you have any comment, sent it to me at: diegodci@gmail.com
Thank you! :D
..................................................................................................'''
import math
###################
# Node initiation #
###################
node = hou.pwd()
geoA = node.geometry()
geoB = node.inputs()[1].geometry()
#############
# Functions #
#############
def makeTemplate():
'''
Create node parameters
'''
pGroup = hou.ParmTemplateGroup()
ttype = hou.MenuParmTemplate('ttype', 'transfer type', ('over', 'add'))
selAttrib = hou.ToggleParmTemplate('selAttrib', 'Selected Attributes', 1)
attList = hou.StringParmTemplate('attList', 'Attribute List', 1)
attList.setDefaultValue('*')
minrad = hou.FloatParmTemplate('minrad', 'Minimum Radius', 1)
maxrad = hou.FloatParmTemplate('maxrad', 'Maximum Radius', 1, (5.0, 0.0, 0.0))
gain = hou.FloatParmTemplate('gain', 'Gain', 1, (1.0, 0.0, 0.0), 0.0, 1.0)
igamma = hou.FloatParmTemplate('igamma', 'Interpolation Gamma', 1, (1.0, 0.0, 0.0), 0.0, 4.0)
matPos = hou.ToggleParmTemplate('matPos', 'Match Position', 0)
pGroup.append(ttype)
pGroup.append(selAttrib)
pGroup.append(attList)
pGroup.append(minrad)
pGroup.append(maxrad)
pGroup.append(gain)
pGroup.append(igamma)
pGroup.append(matPos)
node.setParmTemplateGroup(pGroup)
def distance(p1, p2):
'''
Calculate euclidean distance between two points.
'''
dx = math.pow(p2[0] - p1[0], 2)
dy = math.pow(p2[1] - p1[1], 2)
dz = math.pow(p2[2] - p1[2], 2)
d = math.sqrt(dx + dy + dz)
return d
def sumVectors(v1, v2):
'''
Add two vectors
'''
vx = v1[0] + v2[0]
vy = v1[1] + v2[1]
vz = v1[2] + v2[2]
return (vx, vy, vz)
def multVecFloat(v, f):
'''
Multiply a vector by a float
'''
vx = v[0]*f
vy = v[1]*f
vz = v[2]*f
return (vx, vy, vz)
def defaultValues(dataType):
'''
Returns a value of zero depending a type of the attribute.
'''
if(dataType == tuple): return (0.0, 0.0, 0.0)
elif(dataType == float): return 0.0
elif(dataType == int): return 0
else: return ''
########
# Main #
########
makeTemplate()
pointsA = geoA.points()
pointsB = geoB.points()
ttype = node.parm('ttype').eval()
selAttrib = node.parm('selAttrib').eval()
attList = node.parm('attList').eval()
minrad = node.parm('minrad').eval()
maxrad = node.parm('maxrad').eval()
gain = node.parm('gain').eval()
igamma = node.parm('igamma').eval()
matPos = node.parm('matPos').eval()
if(attList == '*'):
if(selAttrib == 1):
attribs = list(geoB.pointAttribs())
for i in range(len(attribs)):
attribs[i] = attribs[i].name()
else:
attribs = []
elif(attList == ''):
if(selAttrib == 0):
attribs = list(geoB.pointAttribs())
for i in range(len(attribs)):
attribs[i] = attribs[i].name()
else:
attribs = []
else:
attribs = list(geoB.pointAttribs())
for i in range(len(attribs)):
attribs[i] = attribs[i].name()
attList = attList.split(',')
for i in range(len(attList)):
attList[i] = attList[i].strip()
if(selAttrib == 1):
dnes = []
for att in attList:
if(att not in attribs):
dnes.append(att)
for dne in dnes:
print('attribute %s does not exist' %(dne))
attList.remove(dne)
attribs = attList
else:
for att in attList:
try:
attribs.remove(att)
except:
continue
if(matPos == 0):
attribs.remove('P')
attribs.remove('Pw')
for attrib in attribs:
if not geoA.findPointAttrib(attrib):
try:
geoA.addAttrib(hou.attribType.Point, attrib, defaultValues(type(pointsB[0].attribValue(attrib))))
except:
None
for pointB in pointsB:
pb = pointB.attribValue('P')
attribB = pointB.attribValue(attrib)
for pointA in pointsA:
pa = pointA.attribValue('P')
dist = distance(pa, pb)
if(dist > maxrad): continue
elif(dist <= minrad): alpha = 1.0
else:
alpha = (dist - maxrad)/(minrad - maxrad)
attribA = pointA.attribValue(attrib)
oalpha = math.pow(1 - alpha, 1/igamma)*gain
aalpha = math.pow(alpha, 1/igamma)*gain
if(type(attribB) == tuple):
if(ttype == 0):
attribA = sumVectors(multVecFloat(attribB, aalpha), multVecFloat(attribA, oalpha))
else:
attribA = sumVectors(multVecFloat(attribB, aalpha), attribA)
elif(type(attribB) == int):
if(ttype == 0):
attribA = int(attribB*aalpha + attribA*(oalpha))
else:
attribA += int(attribB*aalpha)
else:
if(ttype == 0):
attribA = attribB*aalpha + attribA*(oalpha)
else:
attribA += attribB*alpha
pointA.setAttribValue(attrib, attribA)