def createScene(self, fileType, catch = None): ''' Save new scene, build scene content. :param sceneType: type of created scene, Render, Animation etc :param catch: determinate if procedure were run for the firs time from this class, or it returns user reply from SNV class :return: ''' print '>> Building Render scene...' # Get sequence and shot from UI sequenceNumber = self.ui.lin_episode.text() shotNumber = self.ui.lin_shot.text() # If createRenderScene() runs first time if catch == None: # Build path to 001 version pathScene = dna.buildFilePath('001', fileType, sequenceNumber=sequenceNumber, shotNumber=shotNumber) # Start new Houdini session without saving current hou.hipFile.clear(suppress_save_prompt=True) # Check if file exists if not os.path.exists(pathScene): # Save first version if NOT EXISTS hou.hipFile.save(pathScene) hou.ui.displayMessage('File created:\n{}'.format(pathScene.split('/')[-1])) # print '>> First version of file saved!' else: # If 001 version exists, get latest existing version pathScene = dna.buildPathLatestVersion(pathScene) # Run Save Next Version dialog if EXISTS winSNV = SNV(pathScene, fileType) winSNV.show() return # If createRenderScene() runs from SNV class: return user choice, OVR or SNV elif catch == 'SNV': # Save latest version newPath = dna.buildPathNextVersion(dna.buildPathLatestVersion(dna.buildFilePath('001', fileType, sequenceNumber=sequenceNumber, shotNumber=shotNumber))) hou.hipFile.save(newPath) hou.ui.displayMessage('New version saved:\n{}'.format(newPath.split('/')[-1])) elif catch == 'OVR': # Overwrite existing file pathScene = dna.buildPathLatestVersion(dna.buildFilePath('001', fileType, sequenceNumber=sequenceNumber, shotNumber=shotNumber)) hou.hipFile.save(pathScene) hou.ui.displayMessage('File overwited:\n{}'.format(pathScene.split('/')[-1])) else: return # Build scene content self.buildSceneContent(fileType, sequenceNumber=sequenceNumber, shotNumber=shotNumber) # Save scene hou.hipFile.save() print '>> Building Render scene done!'
def createFlipbook(): # Setup flipbook settings settings.resolution(dna.resolution_LR) settings.frameRange((dna.frameStart, hou.playbar.frameRange()[1])) # Build 001 version of flipbook file path flipbookPath = dna.buildFilePath('001', dna.fileTypes['flipbookSequence'], scenePath=hou.hipFile.path()) fileLocation = dna.analyzeFliePath(flipbookPath)['fileLocation'] if not os.path.exists(fileLocation): # Write flipbook if not exists os.makedirs(fileLocation) runFB(flipbookPath) else: # If 001 file exists get latest version latestVersion = dna.extractLatestVersionFolder(fileLocation) # Build latest existing path flipbookPath = dna.buildFilePath(latestVersion, dna.fileTypes['flipbookSequence'], scenePath=hou.hipFile.path()) # Ask user to save next version or overwrite latest win = SNV(flipbookPath) win.show()
def importCharacterAnim(): ''' Import character animation for the current render scene: set FileCache nodes paths. pathCache = $JOB/geo/SHOTS/010/SHOT_010/ROMA/GEO/001/E010_S010_ROMA_001.$F.bgeo.sc :return: ''' # For each character in shot for characterData in shotGenes['charactersData']: characterName = characterData['code'] fileCacheName = dna.fileCacheName.format(characterName) # Get character container or create if not exists characterContainer = hou.node('/obj/{0}'.format(characterName)) if not characterContainer: characterContainer = dna.createContainer(sceneRoot, characterName, mb=1) # Get Character Cache node or create if not exists characterCache = hou.node('/obj/{0}/{1}'.format( characterName, fileCacheName)) if not characterCache: # Create File Cache SOP characterCache = characterContainer.createNode( 'filecache', fileCacheName) characterNull = characterContainer.createNode( 'null', 'OUT_{0}'.format(characterName)) characterNull.setInput(0, characterCache) characterNull.setDisplayFlag(1) characterNull.setRenderFlag(1) characterContainer.layoutChildren() print '>>>> Created Cache Network: {0}'.format(fileCacheName) # BUILD CACHE PATH (LATEST VERSION) # Build a path to the 001 version of cache pathCache = dna.buildFilePath('001', dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) # Check latest existing version, build new path if exists pathCacheFolder = dna.convertPathCache(pathCache) latestCacheVersion = dna.extractLatestVersionFolder(pathCacheFolder) if latestCacheVersion != '001': pathCache = dna.buildFilePath(latestCacheVersion, dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) # Set path to character cache characterCache.parm('file').set(pathCache) characterCache.parm('loadfromdisk').set(1)
def importCameraAnim(): # HIP format # Build camera path to the 001 version of ABC: '<root3D>/geo/SHOTS/010/SHOT_010/CAM/E010_S010_001.abc' pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) print pathCamera # Build path latest version. TBD sceneRoot.loadItemsFromFile(pathCamera) # ABC format """
def SNV(self, filePath): # Save NEXT version of flipbook fileLocation = dna.analyzeFliePath(filePath)['fileLocation'] fileName = dna.analyzeFliePath(filePath)['fileName'] latestVersion = dna.extractLatestVersionFolder(fileLocation) # '002' nextVersion = '{:03d}'.format(int(latestVersion) + 1) filePath = dna.buildFilePath(nextVersion, dna.fileTypes['flipbookSequence'], scenePath=hou.hipFile.path()) os.makedirs(dna.analyzeFliePath(filePath)['fileLocation']) runFB(filePath)
def importCameraAnim(): # Build camera path to the 001 version of ABC: '$JOB/geo/SHOTS/010/SHOT_010/CAM/E010_S010_001.abc' pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) # Build path latest version. TBD cameraName = dna.nameCamera.format(sequenceNumber, shotNumber) CAM = sceneRoot.createNode('alembicarchive', cameraName) CAM.parm('fileName').set(pathCamera) CAM.parm('buildSubnet').set(0) CAM.parm('buildHierarchy').pressButton() CAM.setPosition([0, -2 * dna.nodeDistance_y])
def createCacheNetwork(): ''' Create output character nodes for exporting cache from animation scene Expect each character node network exists in geometry container named as character (ROMA) :return: ''' print '>> Create Character caches network ...' for character in characterData: characterName = character['code'] charContainer = hou.node('/obj/{0}'.format(characterName)) if charContainer is not None: renderNode = getRenderNode(charContainer) # Check if character has proper network: if renderNode.name() != 'OUT_{}'.format(characterName): # Create trail for Motion Blur trail = charContainer.createNode('trail', 'MB_{}'.format(characterName)) trail.parm('result').set(3) # Create Cache node cache = charContainer.createNode( 'filecache', dna.fileCacheName.format(characterName)) # Build path to a file cache pathCache = dna.buildFilePath('001', dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) cache.parm('file').set(pathCache) cache.parm('loadfromdisk').set(1) # Create OUT null null = charContainer.createNode('null', 'OUT_{}'.format(characterName)) # Link nodes trail.setInput(0, renderNode) cache.setInput(0, trail) null.setInput(0, cache) # Layout and set render flag null.setDisplayFlag(1) null.setRenderFlag(1) charContainer.layoutChildren() print '>> Character caches network created!' else: print '>> There is no character node named {}'.format( characterName)
def importCharacterAnim(): ''' Import character animation for the current render scene: set FileCache nodes paths. pathCache = $JOB/geo/SHOTS/010/SHOT_010/ROMA/GEO/001/E010_S010_ROMA_001.$F.bgeo.sc :return: ''' # For each character in shot for character in shotGenes['charactersData']: characterName = character['code'] # Get character container CHAR = hou.node('/obj/{0}'.format(characterName)) # Create File Cache SOP CACHE = CHAR.createNode('filecache', dna.fileCacheName.format(characterName)) # BUILD CACHE PATH (LATEST VERSION) # Build a path to the 001 version of cache pathCache = dna.buildFilePath('001', dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) # Check latest existing version, build new path if exists pathCacheFolder = dna.convertPathCache(pathCache) latestCacheVersion = dna.extractLatestVersionFolder(pathCacheFolder) if latestCacheVersion != '001': pathCache = dna.buildFilePath(latestCacheVersion, dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) CACHE.parm('file').set(pathCache) CACHE.parm('loadfromdisk').set(1) NULL = CHAR.createNode('null', 'OUT_{0}'.format(characterName)) NULL.setInput(0, CACHE) NULL.setDisplayFlag(1) NULL.setRenderFlag(1) CHAR.layoutChildren()
def openHip(self): splitter = self.sender().parent() index = self.ui.tab_shots.indexAt(splitter.pos()) sequenceNumber = self.ui.tab_shots.item(index.row(), 0).text() shotNumber = self.ui.tab_shots.item(index.row(), 1).text() hipVersion = self.ui.tab_shots.item(index.row(), 2).text() renderScenePath = dna.buildFilePath(hipVersion, dna.fileTypes['renderScene'], sequenceNumber=sequenceNumber, shotNumber=shotNumber) hou.hipFile.load(renderScenePath)
def openFolder(self): splitter = self.sender().parent() index = self.ui.tab_shots.indexAt(splitter.pos()) sequenceNumber = self.ui.tab_shots.item(index.row(), 0).text() shotNumber = self.ui.tab_shots.item(index.row(), 1).text() exrVersion = self.ui.tab_shots.item(index.row(), 3).text() renderFilePath = dna.buildFilePath(exrVersion, dna.fileTypes['renderSequence'], sequenceNumber=sequenceNumber, shotNumber=shotNumber) renderFileFloder = dna.analyzeFliePath(renderFilePath)['fileLocation'] subprocess.Popen('explorer "{}"'.format( renderFileFloder.replace('/', '\\')))
def exportCamera(): ''' Export shot camera Two options avalable, ABC and HIP. Use HIP currently. :return: ''' print '>> Exporting camera...' cameraName = dna.cameraName.format(sequenceNumber, shotNumber) camera = hou.node('obj/{}'.format(cameraName)) pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) dna.createFolder(dna.convertPathCache(pathCamera)) # Set camera parameters camera.parm('far').set(5000) camera.parm('resx').set(dna.resolution_HR[0]) camera.parm('resy').set(dna.resolution_HR[1]) # HIP export listCameraNodes = dna.collectCamera(camera) # Export camera to a file sceneRoot.saveItemsToFile(listCameraNodes, pathCamera) """ # ABC export # Get Camera parent nodes listCameraNodes = '{}'.format(camera.name()) for i in camera.inputAncestors(): listCameraNodes += ' {}'.format(i.name()) # Create ROP network ROP = sceneRoot.createNode('ropnet') ABC = ROP.createNode('alembic') ABC.parm('trange').set(1) ABC.parm('filename').set(pathCamera) ABC.parm('objects').set(listCameraNodes) ABC.parm('execute').pressButton() ROP.destroy() """ print '>> Exporting camera done: {}'.format(pathCamera)
def exportCamera(): ''' Export shot camera Two options avalable, ABC and HIP. Use HIP currently. :return: ''' cameraName = dna.nameCamera.format(sequenceNumber, shotNumber) camera = hou.node('obj/{}'.format(cameraName)) pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) dna.createFolder(dna.convertPathCache(pathCamera)) # HIP export listCameraNodes = [] listCameraNodes.extend(camera.inputAncestors()) listCameraNodes.append(camera) # Export camera to a file sceneRoot.saveItemsToFile(listCameraNodes, pathCamera) """
def importCameraAnim(): ''' Import camera to the render scene :return: ''' print '>> Importing Camera...' # HIP format # Check if shot camera exists - skip import cameraName = dna.cameraName.format(sequenceNumber, shotNumber) camera = hou.node('/obj/{}'.format(cameraName)) if camera: print '>>>> Camera exists in scene! Delete camera and import again to update animation.' # listCameraNodes = dna.collectCamera(camera) else: # Build camera path to the 001 version of ABC: '<root3D>/geo/SHOTS/010/SHOT_010/CAM/E010_S010_001.hiplc' pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) # Build path latest version. TBD sceneRoot.loadItemsFromFile(pathCamera) # ABC format """ # Build camera path to the 001 version of ABC: '$JOB/geo/SHOTS/010/SHOT_010/CAM/E010_S010_001.abc' pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) # Build path latest version. TBD cameraName = dna.nameCamera.format(sequenceNumber, shotNumber) CAM = sceneRoot.createNode('alembicarchive', cameraName) CAM.parm('fileName').set(pathCamera) CAM.parm('buildSubnet').set(0) CAM.parm('buildHierarchy').pressButton() CAM.setPosition([0, -2*dna.nodeDistance_y]) """ print '>> Importing Camera done!'
def exportCamera(): ''' Export shot camera :return: ''' cameraName = dna.nameCamera.format(sequenceNumber, shotNumber) camera = hou.node('obj/{}'.format(cameraName)) pathCamera = dna.buildFilePath('001', dna.fileTypes['cacheCamera'], scenePath=scenePath) # Get Camera parent nodes listCameraNodes = '{}'.format(camera.name()) for i in camera.inputAncestors(): listCameraNodes += ' {}'.format(i.name()) # Create ROP network ROP = sceneRoot.createNode('ropnet') ABC = ROP.createNode('alembic') ABC.parm('trange').set(1) ABC.parm('filename').set(pathCamera) ABC.parm('objects').set(listCameraNodes) ABC.parm('execute').pressButton() ROP.destroy()
def render(self, shotItems): ''' Render list of shots :param shotItems: list of shot dictionaries to render :return: ''' print '>> Rendering list of shots...' if self.needRender(shotItems): for n, shotItem in enumerate(shotItems): renderScenePath = dna.buildFilePath( shotItem['hip'], dna.fileTypes['renderScene'], sequenceNumber=shotItem['E'], shotNumber=shotItem['S']) print '>> Rendering shot [ {0} - {1} ]...'.format( shotItem['E'], shotItem['S']) try: hou.hipFile.load(renderScenePath, suppress_save_prompt=True) rop = hou.node('/out/{}'.format(dna.mantra)) rop.render(frame_range=(int(shotItem['start']), int(shotItem['end']))) print '>> Shot complete' except: print '>> Rendering of shot FAILS! Reload render...' self.addShots() # Reload shots shotItems = self.readShotTable() # read table self.render([shotItems[n]]) print '>> Rendering list of shots done!' self.addShots() # Reload shots
def buildSceneContent(self, fileType, sequenceNumber, shotNumber): ''' Create scene content: import characters, environments, props, materials etc. Render scene schema: [Render obj] [Environment] [Characters] [Props] [FX] - materials - Env - char 1 - prop 1 - fx 1 - lights - char 2 - prop 2 - fx 2 - camera - ... - ... - ... :param fileType: :param sequenceNumber: :param shotNumber: :return: ''' # Create Render scene if fileType == dna.fileTypes['renderScene']: # Get shot data shotGenes = dna.getShotGenes(sequenceNumber, shotNumber) env_data = shotGenes['environmentData'] # Initialize scene scenePath = hou.hipFile.path() # SETUP SCENE (end frame ...) frameEnd = shotGenes['shotData']['sg_cut_out'] hou.playbar.setFrameRange(dna.frameStart, frameEnd) hou.playbar.setPlaybackRange(dna.frameStart, frameEnd) # [Render obj] # Add Material lib HDA mat_data = env_data['materials'] ML = sceneRoot.createNode(mat_data['hda_name'], mat_data['name']) ML.setPosition([0, 0]) # Add lights HDA lit_data = env_data['lights'] LIT = sceneRoot.createNode(lit_data['hda_name'], lit_data['name']) LIT.setPosition([0, -dna.nodeDistance_y]) # Add Camera via ABC. Done in Import ANM # [Environment] ENV = sceneRoot.createNode(env_data['hda_name'], env_data['code']) ENV.setPosition([dna.nodeDistance_x, 0]) # [Characters] char_data = shotGenes['charactersData'] for n, character in enumerate(char_data): CHAR = self.createContainer(sceneRoot, char_data[n]['code'], mb=1) CHAR.setPosition( [2 * dna.nodeDistance_x, n * dna.nodeDistance_y]) # [Props] # No props for NSI project. Skipnig # [FX] fx_data = shotGenes['fxData'] for n, FX in enumerate(fx_data): FX = self.createContainer(sceneRoot, fx_data[n]['code'], mb=1) FX.setPosition( [3 * dna.nodeDistance_x, n * dna.nodeDistance_y]) # SETUP MANTRA OUTPUT # Create mantra render node mantra = outRoot.createNode('ifd', 'RENDER') # Render file version setup renderFile = dna.buildFilePath('001', dna.fileTypes['renderSequence'], scenePath=scenePath) # Create folder for render file fileLocation = dna.analyzeFliePath(renderFile)['fileLocation'] if not os.path.exists(fileLocation): # Make 001 folder os.makedirs(fileLocation) else: # If 001 file exists get latest version latestVersion = dna.extractLatestVersionFolder(fileLocation) nextVersion = '{:03d}'.format(int(latestVersion) + 1) # Build latest existing path renderFile = dna.buildFilePath(nextVersion, dna.fileTypes['renderSequence'], scenePath=scenePath) os.makedirs(dna.analyzeFliePath(renderFile)['fileLocation']) # Localize path (add $JOB) renderFile = renderFile.replace(dna.root3D, '$JOB') # Setup Mantra parameters mantra.parm('vm_picture').set(renderFile) cameraName = dna.nameCamera.format(sequenceNumber, shotNumber) mantra.parm('camera').set( '/obj/{}/cameraProperties'.format(cameraName)) # Set common parameters from preset for param, value in dna.renderSettings['common'].iteritems(): mantra.parm(param).set(value) # Set DRAFT parameters for param, value in dna.renderSettings['draft'].iteritems(): mantra.parm(param).set(value)
def populateShotItem(self, shotItem): ''' Build shot items from database and populate UI :param shotItem: render shot data dictionary :return: ''' sequenceNumber, shotNumber = shotItem[shotItemParams[0]], shotItem[ shotItemParams[1]] # Get shot frame range from database shotData = dna.getShotData(sequenceNumber, shotNumber) shotItem['range'] = '{0:03d} - {1:03d}'.format(dna.frameStart, shotData['sg_cut_out']) # Get latest render hip and latest render folder # Assume that in latest hip the render path set to the latest render folder # (TBD switch to published version) renderScenePath = dna.buildFilePath('001', dna.fileTypes['renderScene'], sequenceNumber=sequenceNumber, shotNumber=shotNumber) latestHIP = dna.buildPathLatestVersion(renderScenePath) pathMapHIP = dna.analyzeFliePath(latestHIP) renderSequencePath = dna.buildFilePath('001', dna.fileTypes['renderSequence'], sequenceNumber=sequenceNumber, shotNumber=shotNumber) shotItem['hip'] = pathMapHIP['fileVersion'] pathMapEXR = dna.analyzeFliePath(renderSequencePath) fileLocation = pathMapEXR['fileLocation'] # Check if folder exists, create if not if not os.path.exists(fileLocation): os.makedirs(fileLocation) latestEXR = dna.extractLatestVersionFolder(fileLocation) shotItem['exr'] = latestEXR renderFilePath = dna.buildFilePath(latestEXR, dna.fileTypes['renderSequence'], sequenceNumber=sequenceNumber, shotNumber=shotNumber) pathMapEXR = dna.analyzeFliePath(renderFilePath) latestFolderPath = pathMapEXR['fileLocation'] listExisted = glob.glob('{0}*.exr'.format(latestFolderPath)) # Clean list from partially rendered files 'E010_S060_012.1.exr.mantra_checkpoint' listCorruptedFiles = glob.glob( '{0}*.exr.mantra_checkpoint'.format(latestFolderPath)) listCorrupted = [] for file in listCorruptedFiles: file = file.replace('\\', '/').replace('.mantra_checkpoint', '') listCorrupted.append(file.split('/')[-1]) doneStart, doneEnd = self.extractFrames(listExisted, listCorrupted) if doneStart != 0: shotItem['done'] = '{0:03d} - {1:03d}'.format(doneStart, doneEnd) else: shotItem['done'] = '' # Check if sequence is not rendered completely # Otherwise set START to a blank value. This will be skipped when render if not doneEnd == shotData['sg_cut_out']: shotItem['start'] = str(doneEnd + 1) shotItem['end'] = str(shotData['sg_cut_out']) else: shotItem['start'] = '' shotItem['end'] = '' self.addShotRow(shotItem) return shotItem