def importAnimation(self, scenePath, charactersData): ''' 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 :param charactersData: list of characters dics for the current shot :param scenePath: Full path to Houdini render scene :return: ''' for characterData in charactersData: characterName = characterData['code'] # BUILD CACHE PATH (LATEST VERSION) # Build a path to the 001 version of cache pathCache = dna.buildFliePath('001', dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) # Check latest existing version, build new path if exists pathCacheFolder = self.convertPathCache(pathCache) latestCacheVersion = dna.extractLatestVersionFolder(pathCacheFolder) if latestCacheVersion != '001': pathCache = dna.buildFliePath(latestCacheVersion, dna.fileTypes['cacheAnim'], scenePath=scenePath, characterName=characterName) # SET FILE CACHE NODE PARAM # Get cache node cache = hou.node('{0}/{1}/CACHE_{2}'.format(sceneRoot, dna.nameChars, characterName)) # Set path cache.parm('file').set(pathCache)
def createFlipbook(): # Setup flipbook settings settings.resolution(dna.resolution) settings.frameRange((dna.frameStart, hou.playbar.frameRange()[1])) # Build 001 version of flipbook file path flipbookPath = dna.buildFliePath('001', dna.fileTypes['flipbook'], 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.buildFliePath(latestVersion, dna.fileTypes['flipbook'], scenePath=hou.hipFile.path()) # Ask user to save next version or overwrite latest win = SNV(flipbookPath) win.show()
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.buildFliePath(nextVersion, dna.fileTypes['flipbook'], scenePath=hou.hipFile.path()) os.makedirs(dna.analyzeFliePath(filePath)['fileLocation']) runFB(filePath)
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 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 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 buildSceneContent(self, fileType, sequenceNumber, shotNumber): ''' Create scene content: import characters, environments, materials etc. :param fileType: :param sequenceNumber: :param shotNumber: :return: ''' # Create Render scene if fileType == dna.fileTypes['renderScene']: # Get shot data shotData, assetsData, environmentData, charactersData = dna.getShotGenes(sequenceNumber, shotNumber) # Initialize scene scenePath = hou.hipFile.path() # BUILD ENVIRONMENT # Proxy ENV_PRX = self.createContainer(sceneRoot, dna.nameEnvProxy) self.createHDA(ENV_PRX, environmentData['proxy_hda']['hda_name'], environmentData['proxy_hda']['name']) ENV_PRX.setPosition([0, 0]) # Base ENVIRONMENT = self.createContainer(sceneRoot, dna.nameEnv, bbox=2, disp=0) self.createHDA(ENVIRONMENT, environmentData['hda_name'], environmentData['code']) ENVIRONMENT.setPosition([0, -dna.nodeDistance_y]) # Animation ENV_ANM = self.createContainer(sceneRoot, dna.nameEnvAnim, bbox=2, mb=1) self.createHDA(ENV_ANM, environmentData['animation_hda']['hda_name'], environmentData['animation_hda']['name']) ENV_ANM.setPosition([0, -2 * dna.nodeDistance_y]) CROWDS = self.createContainer(sceneRoot, dna.nameCrowds, bbox=2, mb=1) self.createHDA(CROWDS, environmentData['crowds_hda']['hda_name'], environmentData['crowds_hda']['name']) CROWDS.setPosition([0, -3 * dna.nodeDistance_y]) # BUILD CHARACTERS # Create characters container CHARACTERS = self.createContainer(sceneRoot, dna.nameChars, mb=1) CHARACTERS.setPosition([0, -4 * dna.nodeDistance_y]) # Create nodes to pull character caches self.buildCharacterLoaders(CHARACTERS, charactersData) # IMPORT MATERIALS # Create Geometry node in scene root ML = sceneRoot.createNode('ml_general', dna.nameMats) ML.setPosition([dna.nodeDistance_x, 0]) # IMPORT ENV LIGHTS LIT = sceneRoot.createNode(environmentData['light_hda']['hda_name'], environmentData['light_hda']['name']) LIT.setPosition([dna.nodeDistance_x, -dna.nodeDistance_y]) # SETUP OUTPUT # Create mantra render node mantra = outRoot.createNode('ifd', 'RENDER') # Render file version setup # renderFile = '$JOB/render/010/SHOT_040/001/E010_S040_001.$F.exr' renderFile = dna.buildFliePath('001', dna.fileTypes['renderFile'], scenePath=scenePath) 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.buildFliePath(nextVersion, dna.fileTypes['renderFile'], 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) mantra.parm('camera').set('/obj/E{0}_S{1}'.format(sequenceNumber, shotNumber)) # 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) # SETUP SCENE (end frame ...) frameEnd = shotData['sg_cut_out'] hou.playbar.setFrameRange(dna.frameStart, frameEnd) hou.playbar.setPlaybackRange(dna.frameStart, frameEnd) # IMPORT ANIMATION # Import characters caches self.importAnimation(scenePath, charactersData) # Save scene hou.hipFile.save()
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