This repository has been archived by the owner on Dec 15, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Daz2Hou.py
295 lines (243 loc) · 12.7 KB
/
Daz2Hou.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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
'''
Daz to Houdini Helper Tool.
Created by Bilal Malik. (Ver 0.65)
Contact:[email protected]
This tool aims to provide easier starts for using FBX Exports from Daz to Houdini workflows.
Currently in development with more features to come.
Code Partially Generated by PYQT-UI Generator Also on my Github.
'''
import os, sys, hou
#Location of Assets
app_location = os.path.join("PATH_HERE")
#Add Path to Qt Module
qt_module = os.path.join(app_location+"\Assets\Qt.pyc")
sys.path.insert(0, qt_module)
#Qt Import Block
from Qt import QtCore, QtWidgets, QtCompat , QtGui
from Qt.QtWidgets import QFileDialog
#Class Creation
class H2Dz(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(H2Dz, self).__init__(parent, QtCore.Qt.WindowStaysOnTopHint)
#File Interface File goes here
file_interface = os.path.join(app_location+"\Assets\Hou2Daz.ui")
self.mw = QtCompat.loadUi(file_interface)
self.setCentralWidget(self.mw)
#Set Window Title Here
self.setWindowTitle("Daz Helper Script (Houdini)")
stylesheet = hou.qt.styleSheet()
self.setStyleSheet(stylesheet)
#Set Windows Flags
self.setWindowFlag(QtCore.Qt.WindowMaximizeButtonHint, False)
self.setWindowFlag(QtCore.Qt.MSWindowsFixedSizeDialogHint, True)
self.setWindowFlag(QtCore.Qt.WindowMinimizeButtonHint, False)
#Pixmap
header = os.path.join(app_location+"\Assets\header_daz2hou.png")
pixmap = QtGui.QPixmap(header)
self.mw.lbl_Header.setPixmap(pixmap)
helper = os.path.join(app_location+"\Assets\help_daz2hou.png")
pixmap2 = QtGui.QPixmap(helper)
self.mw.lbl_help.setPixmap(pixmap2)
#Button Assignment
self.mw.bttn_ImportFBX.clicked.connect(self.importFbx)
self.mw.bttn_SelectSubnet.clicked.connect(self.selectSubnet)
self.mw.bttn_PreviewSubnet.clicked.connect(self.previewSubnet)
self.mw.bttn_conTex.clicked.connect(self.manualArnold)
self.mw.bttn_scale_1.clicked.connect(lambda: self.setScale(1))
self.mw.bttn_scale_01.clicked.connect(lambda: self.setScale(0.1))
self.mw.bttn_scale_001.clicked.connect(lambda: self.setScale(0.01))
self.mw.bttn_lockObjMerges.clicked.connect(self.lockObjMergeNodes)
self.mw.bttn_clearList.clicked.connect(self.clearList)
self.mw.bttn_createHairGeo.clicked.connect(self.hairGroomGeo)
def clearList(self):
self.mw.lst_preview.clear()
def importFbx(self):
#Opens File Dialog
options = QFileDialog.Options()
#options |= QFileDialog.DontUseNativeDialog
fbx_fileName, _ = QFileDialog.getOpenFileName(self,"Select FBX File.", "","Filmbox FBX (*fbx);;All Files (*)", options=options)
if fbx_fileName:
#Debug Line
print(fbx_fileName)
#Try importing FBX
try:
print("Importing FBX...")
fbx = hou.hipFile.importFBX(fbx_fileName)
print("Imported Complete.")
#Call Fill Routine
except:
print("ERROR_IMPORTING_FBX 001")
def previewSubnet(self):
self.mw.lst_preview.clear()
FBX = hou.selectedNodes()[0]
if FBX.type().name() == "subnet":
geometry_FBX = [node for node in FBX.children() if node.type().name() == 'geo']
for geo in geometry_FBX:
self.mw.lst_preview.addItem(geo.name())
else:
print("ERROR, No Subnet Selected.")
def selectSubnet(self):
FBX = hou.selectedNodes()[0]
#Root Location
OBJ = hou.node('/obj/')
if not FBX:
#Error no fbx sub detected.
print("Error: No objects selected.")
elif FBX:
if FBX.type().name() == "subnet":
# Create Geometry node to store FBX parts
geometry = OBJ.createNode('geo', run_init_scripts = False)
geometry.setName('GEO_{}'.format(FBX.name()))
geometry.moveToGoodPosition()
# Get all parts inside FBX container
geometry_FBX = [node for node in FBX.children() if node.type().name() == 'geo']
# Create merge node for parts
merge = geometry.createNode('merge')
merge.setName('master_merge')
#Create Null Object at the end
oNull = geometry.createNode('null')
oNull.setName('OUT_DAZ')
#Link MergeOut to NullIn
oNull.setInput(0, merge)
# Replicate FBX structure in Geometry node
for geo in geometry_FBX:
# Create Object Merge node
objectMerge = geometry.createNode('object_merge')
objectMerge.setName(geo.name())
# Set path to FBX part object
objectMerge.parm('objpath1').set(geo.path())
objectMerge.parm('xformtype').set(1)
# MATERIAL HANDLING
# Copy Material from Geo
matName = hou.node("obj/" + FBX.name() + "/" + geo.name() + "/" + geo.name() + "_material")
if matName is not None:
parentH = hou.node("obj/" + geometry.name())
hou.copyNodesTo([matName], parentH)
material = hou.node("obj/" + geometry.name() + "/" + geo.name() + "_material")
#Call process to convert materials.
if self.mw.rdo_Arnold.isChecked() == True:
print("Converting to Arnold Materials.")
self.convertArnold(material)
else:
# Create Material node if none exist. No materials are added if none are detected.
material = geometry.createNode('material')
material.setName('MAT_{}'.format(geo.name()))
# LINK NODES
# Link Material to Object MergeName
material.setNextInput(objectMerge)
# Link part to Merge
merge.setNextInput(material)
# Set Null Node flags to Render
oNull.setDisplayFlag(1)
oNull.setRenderFlag(1)
# Layout geometry content in Network View
geometry.layoutChildren()
else:
print("NON-SUBNET Node Selected. Hint:You may only select one node at a time.")
def convertArnold(self,node):
#Root Shop
SHOP = hou.node('/shop/')
#Get Number of materials to create
nMats = node.parm('num_materials').eval()
#Loop for each material creating a new arnold one.
for i in range(1,nMats+1):
#Get Group Name of current loop.
grp = "Ai_"+(node.parm('group'+str(i)).eval())
#Check If Shader Exists
if hou.node("/"+SHOP.name()+"/"+grp) is None:
#Create Arnold VOP in Root location
arnoldNode = SHOP.createNode('arnold_vopnet', run_init_scripts = True)
arnoldNode.setName(grp)
arnoldNode.moveToGoodPosition()
#Create Shader Inside
#Create 'smart' type indicator
type = 'Surface'
if type == 'Surface':
surfNode = arnoldNode.createNode('arnold::standard_surface')
elif type == 'Hair':
surfNode = arnoldNode.createNode('arnold::standard_hair')
surfNode.moveToGoodPosition()
outNode = hou.node(SHOP.name()+ "/" + arnoldNode.name()+"/"+"OUT_material")
outNode.setInput(0,surfNode)
#Assign Material to Material Group.
node.parm("shop_materialpath"+str(i)).set("/"+SHOP.name()+"/"+grp)
def manualArnold(self):
nodeToSend = hou.selectedNodes()[0]
print(nodeToSend.type())
if nodeToSend.type().name() == 'material':
self.convertArnold(nodeToSend)
else:
print("ERROR Please Select a Material Node.")
def setScale(self,value):
node = hou.selectedNodes()[0]
if node.type().name() == 'subnet':
node.parm('scale').set(value)
elif node.type().name() == 'geo':
node.parm('scale').set(value)
else:
print("ERROR Please select a subnet or geo node.")
def lockObjMergeNodes(self):
nodeS = hou.selectedNodes()[0]
obj_merges = [node for node in nodeS.children() if node.type().name() == 'object_merge']
for each in obj_merges:
each.setHardLocked(1)
def hairGroomGeo(self):
node = hou.selectedNodes()[0]
OBJ = hou.node('/obj/')
if node.type().name() == 'geo':
#Create Geo in OBJ level.
geometry = OBJ.createNode('geo', run_init_scripts = False)
geometry.setName('Hair_GEO_{}'.format(node.name()))
geometry.moveToGoodPosition()
#Obj Merge
objectMerge = geometry.createNode('object_merge')
objectMerge.setName(node.name())
objectMerge.parm('objpath1').set(node.path())
#Transform
xform = geometry.createNode('xform')
xform.setInput(0,objectMerge)
#Delete
delnode = geometry.createNode('delete')
delnode.setInput(0,xform)
#Null Out_Char
nullChar = geometry.createNode('null')
nullChar.setName('OUT_CHAR')
nullChar.setInput(0,delnode)
#AttrbPaint
attribpaint = geometry.createNode('attribpaint')
attribpaint.setInput(0,nullChar)
#Set AttrbPaint Density paramter
attribpaint.parm('attribname1').set('density')
#Null Out_Density
nullDen = geometry.createNode('null')
nullDen.setName('OUT_DENSITY')
nullDen.setInput(0,attribpaint)
#VDB from Polygons
vdbN = geometry.createNode('vdbfrompolygons')
vdbN.setInput(0,attribpaint)
#Null Out_VDB
nullVDB = geometry.createNode('null')
nullVDB.setInput(0,vdbN)
nullVDB.setName('OUT_VDB')
#Set Render Flags
nullChar.setDisplayFlag(1)
nullChar.setRenderFlag(1)
#Layout Geo
geometry.layoutChildren()
isPanel = False
#Create the UI Block
if isPanel == True:
#Create Interface Python Panel
def onCreateInterface():
my_window = H2Dz()
my_window.show()
return my_window
elif isPanel == False:
#Create Interface Shelf.
try:
my_window.close()
except:
pass
my_window = H2Dz()
my_window.resize(270,625)
my_window.show()