Samples/Referencing/MBFileRefDemo/ReferencingSample.py

Samples/Referencing/MBFileRefDemo/ReferencingSample.py
1 import os
2 
3 from pyfbsdk import *
4 from pyfbsdk_additions import *
5 
6 from PySide2 import QtCore, QtWidgets
7 from ReferencingSampleUI2 import Ui_ReferencingSample
8 
9 import NamespaceTableModel
10 
11 ######################################################
12 # Functions
13 ######################################################
14 def PickRefName():
15  lFileRefName = ''
16  lBtnClicked, lFileRefName = FBMessageBoxGetUserValue( 'File Reference', 'Enter your file reference name', '', FBPopupInputType.kFBPopupString, 'OK', 'Cancel', None, 1, True )
17  if lBtnClicked == 2: return lBtnClicked, lFileRefName
18 
19  lFileRefName = lFileRefName.replace(' ','')
20  while lFileRefName is '':
21  FBMessageBox('File Reference', 'Error, please enter a file reference name', "OK")
22  lBtnClicked, lFileRefName = PickRefName()
23  if lBtnClicked == 2: break
24 
25  return lBtnClicked, lFileRefName
26 
27 class MainForm( QtWidgets.QWidget, Ui_ReferencingSample ):
28  def __init__( self, parent ):
29  QtWidgets.QWidget.__init__( self, parent )
30 
31  self.setupUi( self )
32 
33  import inspect
34  self.mDefaultPath = inspect.currentframe().f_code.co_filename
35  self.mSingleSelection = False
36 
37  self.mSys = FBSystem()
38  self.mApp = FBApplication()
39  self.mApp.OnFileNew.Add( self.OnFileNew )
40 
41  self.mNSModel = NamespaceTableModel.NamespaceTableModel( self )
42  self.uiTableNamespace.setModel( self.mNSModel )
43 
44  self.mTimer = QtCore.QTimer( self )
45 
46  self.mIsInitialized = False
47  self.Init()
48 
49  def Init( self ):
50  self.mNSModel.namespaceRenamed.connect( self.OnNamespaceRenamed )
51 
52  lSelectionModel = self.uiTableNamespace.selectionModel()
53  QtCore.QObject.connect( lSelectionModel, QtCore.SIGNAL( 'selectionChanged(const QItemSelection&, const QItemSelection&)' ), self.OnTableNamespaceSelectionChanged )
54 
55  QtCore.QObject.connect( self.mTimer, QtCore.SIGNAL( 'timeout()' ), self.OnTimer )
56  self.mTimer.start( 2000 )
57  self.UpdateUI()
58 
59  self.mIsInitialized = True
60 
61  def Fini( self ):
62  # disconnecting the update timer
63  self.mTimer.stop()
64  QtCore.QObject.disconnect( self.mTimer, QtCore.SIGNAL( 'timeout()' ), self.OnTimer )
65 
66  # disconnecting the selectionChanged signal
67  lSelectionModel = self.uiTableNamespace.selectionModel()
68  QtCore.QObject.disconnect( lSelectionModel, QtCore.SIGNAL( 'selectionChanged(const QItemSelection&, const QItemSelection&)' ), self.OnTableNamespaceSelectionChanged )
69 
70  self.mNSModel.namespaceRenamed.disconnect( self.OnNamespaceRenamed )
71 
72  self.mIsInitialized = False
73 
74  def OnShow( self ):
75  if not self.mIsInitialized:
76  self.Init()
77  self.mNSModel.Connect()
78 
79  def OnHide( self ):
80  if self.mIsInitialized:
81  self.Fini()
82  self.mNSModel.Disconnect()
83 
84  def OnFileNew( self, pControl, pEvent ):
85  self.mNSModel.Fini()
86  self.mNSModel.Init()
87 
88  def OnNamespaceRenamed( self, pOldName, pNewName ):
89  self.UpdateTreeNamespace()
90 
91  def OnBtnBrowsePathClicked( self ):
92  lFileToLoad = QtWidgets.QFileDialog.getOpenFileName(self, "Pick FBX to reference", self.mDefaultPath, "*.fbx" )[0] # Returns a Tuple. Get the filename only
93  lQFileInfo = QtCore.QFileInfo( lFileToLoad )
94  if lQFileInfo.exists() and lQFileInfo.suffix() == 'fbx':
95  self.uiEditFilePath.setText( lFileToLoad )
96  self.mDefaultPath = lQFileInfo.filePath()
97  self.UpdateUI()
98 
99  def OnBtnLoadClicked( self ):
100  print 'Load as a file reference'
101 
102  lLoadCount = self.uiSpinLoadTimes.value()
103  lBtnClicked, lName = PickRefName()
104  if lBtnClicked == 2: return
105 
106  lNameList = FBStringList()
107  if lLoadCount == 1:
108  lNameList.Add( lName )
109  else:
110  for lCount in range( 0, lLoadCount ):
111  if self.mSys.Scene.NamespaceGet( lName + str(lCount+1) ) <> None:
112  lMsgBox = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Information, 'Loading', 'Creation of file reference %s will be skipped as it is already there.' % ( lName + str(lCount+1) ), QtWidgets.QMessageBox.Ok, self )
113  lMsgBox.exec_()
114  else:
115  lNameList.Add( lName + str(lCount+1) )
116 
117  self.mSys.Scene.NamespaceImportToMultiple( lNameList, str(self.uiEditFilePath.text()), True )
118  self.mNSModel.Refresh()
119  self.UpdateUI()
120 
121  def OnBtnUnloadClicked( self ):
122  lIndexes = self.uiTableNamespace.selectedIndexes()
123  for lIndex in lIndexes:
124  if lIndex.column() == 0:
125  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
126  self.mNSModel.RemoveFileFromWatcher( lNSObj )
127  lNSObj.IsLoaded = False
128 
129  self.mNSModel.Refresh( lIndex )
130  self.UpdateUI()
131  self.UpdateTreeNamespace()
132 
133  def OnBtnReloadClicked( self ):
134  lIndexes = self.uiTableNamespace.selectedIndexes()
135  for lIndex in lIndexes:
136  if lIndex.column() == 0:
137  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
138  lNSObj.IsLoaded = True
139  self.mNSModel.Refresh( lIndex )
140  self.UpdateUI()
141  self.UpdateTreeNamespace()
142 
143  def OnBtnDeleteClicked( self ):
144  lIndexes = self.uiTableNamespace.selectedIndexes()
145  lNameList = []
146  for lIndex in lIndexes:
147  if lIndex.column() == 0:
148  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
149  lNameList.append( lNSObj.LongName )
150  self.mNSModel.RemoveFileFromWatcher( lNSObj )
151 
152  for lName in lNameList:
153  self.mSys.Scene.NamespaceDelete( lName )
154 
155  self.mNSModel.Refresh()
156  self.UpdateUI()
157  self.UpdateTreeNamespace()
158 
159  def OnBtnInstanceClicked( self ):
160  lIndexes = self.uiTableNamespace.selectedIndexes()
161  for lIndex in lIndexes:
162  if lIndex.column() == 0:
163  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
164 
165  lInstanceCount = self.uiSpinInstanceTimes.value()
166  lBtnClicked, lName = PickRefName()
167  if lBtnClicked == 2: return
168 
169  lNameList = FBStringList()
170  if lInstanceCount == 1:
171  lNameList.Add( lName )
172  else:
173  for lCount in range( 0, lInstanceCount ):
174  lNameList.Add( lName + str(lCount+1) )
175 
176  lApplyRefEdits = False
177  if lNSObj.GetContentModified( FBPlugModificationFlag.kFBContentAllModifiedMask ):
178  lMsgBox = QtWidgets.QMessageBox( QtWidgets.QMessageBox.Question, 'Instancing', 'Do you want to apply reference edits after instancing?', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, self )
179  if lMsgBox.exec_() == QtWidgets.QMessageBox.Yes:
180  lApplyRefEdits = True
181 
182  lNSObj.DuplicateFileRef( lNameList, lApplyRefEdits )
183 
184  self.mNSModel.Refresh()
185  self.UpdateUI()
186  self.UpdateTreeNamespace()
187 
188  def OnBtnRestoreClicked( self ):
189  lIndexes = self.uiTableNamespace.selectedIndexes()
190  for lIndex in lIndexes:
191  if lIndex.column() == 0:
192  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
193  lNSObj.RevertRefEdit()
194  self.mNSModel.Refresh( lIndex )
195  self.UpdateUI()
196 
197  def OnBtnShowEditsClicked( self ):
198  lIndexes = self.uiTableNamespace.selectedIndexes()
199  for lIndex in lIndexes:
200  if lIndex.column() == 0:
201  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
202  if lNSObj.GetContentModified( FBPlugModificationFlag.kFBContentAllModifiedMask ):
203  lMsgBox = QtWidgets.QMessageBox( self )
204  lMsgBox.setText( lNSObj.GetRefEdit() )
205  lMsgBox.exec_()
206 
207  def OnTableNamespaceSelectionChanged( self, pSelected, pUnselected ):
208  self.UpdateUI()
209  self.UpdateTreeNamespace()
210 
211  def UpdateTreeNamespace( self ):
212  self.uiTreeNamespace.clear()
213 
214  if self.mSingleSelection:
215  lIndexes = self.uiTableNamespace.selectedIndexes()
216  lNSObj = self.mSys.Scene.Namespaces[lIndexes[0].row()]
217 
218  lStrList = [lNSObj.LongName]
219  if lNSObj.ClassGroupName <> '':
220  lStrList.append( lNSObj.ClassGroupName )
221 
222  lItem = QtWidgets.QTreeWidgetItem( lStrList )
223  self.uiTreeNamespace.addTopLevelItem( lItem )
224  self.UpdateTreeNamespaceRecursively( lItem, lNSObj )
225  self.uiTreeNamespace.expandItem( lItem )
226 
227  def UpdateTreeNamespaceRecursively( self, pParentItem, pNSObj ):
228  lList = FBComponentList()
229  pNSObj.GetContentList( lList, FBPlugModificationFlag.kFBPlugAllContent, False )
230  for lPlug in lList:
231  lStrList = [lPlug.LongName]
232  if lPlug.ClassGroupName <> '':
233  lStrList.append( lPlug.ClassGroupName )
234 
235  lItem = QtWidgets.QTreeWidgetItem( lStrList )
236  pParentItem.addChild( lItem )
237  self.uiTreeNamespace.expandItem( lItem )
238  if lPlug.TypeInfo == FBNamespace.TypeInfo:
239  self.UpdateTreeNamespaceRecursively( lItem, lPlug )
240 
241 
242  #def OnSceneChanged( self, pComp, pEvent ):
243  # self.UpdateRefEditStatus()
244 
245  #def UpdateRefEditStatus( self ):
246  # lRowSize = self.mNSModel.rowCount()
247  # for lRow in range( 0, lRowSize ):
248  # lIndex = self.mNSModel.index( lRow, 0 )
249  # self.mNSModel.dataChanged.emit( lIndex, lIndex )
250 
251  def UpdateUI( self ):
252  luiBtnBrowsePath = True
253  luiBtnLoad = False
254  luiSpinLoadTimes = False
255  luiBtnUnload = False
256  luiBtnReload = False
257  luiBtnDelete = False
258  luiBtnInstance = False
259  luiBtnRestore = False
260  luiBtnShowEdits = False
261  luiSpinInstanceTimes = False
262 
263  if os.path.exists( self.uiEditFilePath.text() ):
264  luiBtnLoad = True
265  luiSpinLoadTimes = True
266 
267  #
268  # Update file reference related UI
269  #
270  lIndexes = self.uiTableNamespace.selectedIndexes()
271 
272  lRows = []
273  lHasSelection = False
274  if len( lIndexes ) > 0:
275  lHasSelection = True
276 
277  lAllSelectionFileReference = True
278  lAllSelectionLoaded = True
279  lAllSelectionUnLoaded = True
280  lSelectionHasRefEdits = False
281  for lIndex in lIndexes:
282  if lIndex.column() == 0:
283  lRows.append( lIndex.row() )
284  lNSObj = self.mSys.Scene.Namespaces[lIndex.row()]
285  if lNSObj.TypeInfo == FBNamespace.TypeInfo:
286  lAllSelectionFileReference = False
287  else:
288  if lNSObj.IsLoaded:
289  if lNSObj.GetContentModified( FBPlugModificationFlag.kFBContentAllModifiedMask ):
290  lSelectionHasRefEdits = True
291  lAllSelectionUnLoaded = False
292  else:
293  lAllSelectionLoaded = False
294 
295  self.mSingleSelection = False
296  if len( lRows ) == 1:
297  self.mSingleSelection = True
298 
299  if lHasSelection:
300  luiBtnDelete = True
301 
302  if lAllSelectionFileReference:
303  if lSelectionHasRefEdits:
304  luiBtnRestore = True
305 
306  if self.mSingleSelection:
307  if lSelectionHasRefEdits:
308  luiBtnShowEdits = True
309  luiBtnInstance = True
310  luiSpinInstanceTimes = True
311 
312  luiBtnUnload = True
313  luiBtnReload = True
314  if lAllSelectionLoaded:
315  luiBtnReload = False
316  if lAllSelectionUnLoaded:
317  luiBtnUnload = False
318 
319  self.uiBtnBrowsePath.setEnabled( luiBtnBrowsePath )
320  self.uiBtnLoad.setEnabled( luiBtnLoad )
321  self.uiSpinLoadTimes.setEnabled( luiSpinLoadTimes )
322  self.uiBtnUnload.setEnabled( luiBtnUnload )
323  self.uiBtnReload.setEnabled( luiBtnReload )
324  self.uiBtnDelete.setEnabled( luiBtnDelete )
325  self.uiBtnInstance.setEnabled( luiBtnInstance )
326  self.uiBtnRestore.setEnabled( luiBtnRestore )
327  self.uiBtnShowEdits.setEnabled( luiBtnShowEdits )
328  self.uiSpinInstanceTimes.setEnabled( luiSpinInstanceTimes )
329 
330  def OnTimer( self ):
331  for lFilePath, lReload in self.mNSModel.mRefFileReload.items():
332  if lReload:
333  FBMessageBox( "External File Changed", "The referenced file '%s' has been changed externally!" % ( lFilePath ), "OK" )
334  if lFilePath in self.mNSModel.mRefFilePath:
335  for lFileRefName in self.mNSModel.mRefFilePath[lFilePath]:
336  lFileRefObj = FBFindObjectByFullName( 'FileReference::' + lFileRefName )
337  lOption = FBMessageBox( "External File Changed", "Please choose the following action for Reference: %s!" % ( lFileRefName ), "Load", "Merge", "Ignore" )
338  if lOption <> 3:
339  lUndo = FBUndoManager()
340  lUndo.Clear()
341  lFileRefObj.IsLoaded = False
342  lFileRefObj.IsLoaded = True
343 
344  if lOption == 2:
345  if lFileRefObj.GetContentModified( FBPlugModificationFlag.kFBContentAllModifiedMask ):
346  lFileRefObj.ApplyRefEditPyScriptFromString( lFileRefObj.GetRefEdit() )
347 
348  self.mNSModel.mRefFileReload[lFilePath] = False
349 
350  self.mNSModel.UpdateFileWatcher()