Exemplo n.º 1
0
			cmd += ' -s @#@ -e @#@ -b %d' % by
		else:
			cmd += ' -an 1 -s @#@ -e @#@ -inc %d' % by

		if node != '':
			cmd += ' -cam "%s"' % node

		if take != '':
			if scenetype == 'maya_delight':
				cmd += ' -rp "%s"' % take
			else:
				cmd += ' -rl "%s"' % take
		if images != '':
			images = images.split(',')
			if len(images) > 1:
				images = afcommon.patternFromPaths(images[0], images[1])
			else:
				images = afcommon.patternFromFile(images[0])
		if pwd != '':
			cmd += ' -proj "%s"' % os.path.normpath(pwd)
		
		if output != '':
			cmd += ' -rd "%s"' % os.path.normpath(output)

		if scenetype == 'maya_mental':
			cmd += ' -art -v 5'

		if extrargs != '':
			cmd += ' ' + extrargs

		cmd += ' "%s"' % scene
Exemplo n.º 2
0
    def launch(self, *args, **kwargs):
        """launch renderer command
        """
        # do nothing if there is no window (called externally)
        if not self.window:
            return

        # warn the user about the ignore settings
        try:
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            ignore_attrs = [
                'ignoreSubdivision',
                'ignoreDisplacement',
                'ignoreBump',
                'ignoreMotionBlur'
            ]

            attr_values = [
                (attr, dAO.getAttr(attr))
                for attr in ignore_attrs
                if dAO.getAttr(attr) is True
            ]

            if any(attr_values):
                msg_text = '<br>'.join(
                    map(
                        lambda x: '%s: %s' % (x[0], x[1]),
                        attr_values
                    )
                )

                response = pm.confirmDialog(
                    title='Ignore These Settings?',
                    message='You have ignored:<br><br>%s<br><br><b>Is that ok?</b>' % msg_text,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
        except pm.MayaNodeError:
            # no Arnold
            pass

        # check if rendering with persp camera
        try:
            wrong_camera_names = [
                'perspShape',
                'topShape',
                'sideShape',
                'fontShape',

                'persp1Shape',
                'perspShape1',
            ]
            renderable_cameras = [node for node in pm.ls(type='camera') if node.getAttr('renderable')]
            if any(map(lambda x: x.name() in wrong_camera_names, renderable_cameras)):
                response = pm.confirmDialog(
                    title='Rendering with Persp?',
                    message='You are rendering with <b>Persp Camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return

            if len(renderable_cameras) > 1:
                response = pm.confirmDialog(
                    title='Rendering more than one Camera?',
                    message='You are rendering <b>more than one camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
            elif len(renderable_cameras) == 0:
                pm.confirmDialog(
                    title='No <b>Renderable</b> camera!!!',
                    message='There is no <b>renderable camera<b>!!!',
                    button=['Ok'],
                    defaultButton='Ok',
                    cancelButton='Ok',
                    dismissString='Ok'
                )
                return

        except pm.MayaNodeError:
            # no default render globals node
            pass

        # get values
        start_frame = pm.intField('cgru_afanasy__start_frame', q=1, v=1)
        end_frame = pm.intField('cgru_afanasy__end_frame', q=1, v=1)
        frames_per_task = \
            pm.intField('cgru_afanasy__frames_per_task', q=1, v=1)
        by_frame = pm.intField('cgru_afanasy__by_frame', q=1, v=1)
        hosts_mask = pm.textField('cgru_afanasy__hosts_mask', q=1, text=True)
        hosts_exclude = pm.textField('cgru_afanasy__hosts_exclude', q=1, text=True)
        separate_layers = \
            pm.checkBox('cgru_afanasy__separate_layers', q=1, v=1)
        pause = pm.checkBox('cgru_afanasy__paused', q=1, v=1)
        life_time = pm.intField('cgru_afanasy__life_time', q=1, v=1)

        # check values
        if start_frame > end_frame:
            temp = end_frame
            end_frame = start_frame
            start_frame = temp

        frames_per_task = max(1, frames_per_task)
        by_frame = max(1, by_frame)

        # store without quota sign
        hosts_mask = hosts_mask.replace('"', '')
        hosts_exclude = hosts_exclude.replace('"', '')

        # store field values
        pm.optionVar['cgru_afanasy__start_frame_ov'] = start_frame
        pm.optionVar['cgru_afanasy__end_frame_ov'] = end_frame
        pm.optionVar['cgru_afanasy__frames_per_task_ov'] = frames_per_task
        pm.optionVar['cgru_afanasy__by_frame_ov'] = by_frame
        pm.optionVar['cgru_afanasy__hosts_mask_ov'] = hosts_mask
        pm.optionVar['cgru_afanasy__hosts_exclude_ov'] = hosts_exclude
        pm.optionVar['cgru_afanasy__separate_layers_ov'] = separate_layers
        pm.optionVar['cgru_afanasy__life_time_ov'] = life_time

        # get paths
        scene_name = pm.sceneName()
        datetime = '%s%s' % (
            time.strftime('%y%m%d-%H%M%S-'),
            str(time.time() - int(time.time()))[2:5]
        )

        filename = '%s.%s.mb' % (scene_name, datetime)

        project_path = pm.workspace(q=1, rootDirectory=1)

        # get output paths, set the RenderPass token to Beauty,
        # this will at least guarantee to get something
        outputs = \
            pm.renderSettings(
                fullPath=1, firstImageName=1, lastImageName=1,
                leaveUnmatchedTokens=1, customTokenString="RenderPass=Beauty"
            )

        job_name = os.path.basename(scene_name)

        logger.debug('%ss %se %sr' % (start_frame, end_frame, by_frame))
        logger.debug('scene        = %s' % scene_name)
        logger.debug('file         = %s' % filename)
        logger.debug('job_name     = %s' % job_name)
        logger.debug('project_path = %s' % project_path)
        logger.debug('outputs      = %s' % outputs)

        if pm.checkBox('cgru_afanasy__close', q=1, v=1):
            pm.deleteUI(self.window)

        drg = pm.PyNode('defaultRenderGlobals')
        render_engine = drg.getAttr('currentRenderer')

        job = af.Job(job_name)

        stored_log_level = None
        if render_engine == 'arnold':
            # set the verbosity level to warning+info
            aro = pm.PyNode('defaultArnoldRenderOptions')
            stored_log_level = aro.getAttr('log_verbosity')
            aro.setAttr('log_verbosity', 1)
            # set output to console
            aro.setAttr("log_to_console", 1)
        elif render_engine == 'redshift':
            # set the verbosity level to detailed+info
            redshift = pm.PyNode('redshiftOptions')
            stored_log_level = redshift.logLevel.get()
            redshift.logLevel.set(2)

        # save file
        pm.saveAs(
            filename,
            force=1,
            type='mayaBinary'
        )

        # rename back to original name
        pm.renameFile(scene_name)

        # create the render command
        mrc = MayaRenderCommandBuilder(
            name=job_name, file_full_path=filename,
            render_engine=render_engine, project=project_path,
            by_frame=by_frame
        )

        # submit renders
        blocks = []
        if separate_layers:
            # render each layer separately
            rlm = pm.PyNode('renderLayerManager')
            layers = [layer for layer in rlm.connections()
                      if layer.renderable.get()]

            for layer in layers:
                mrc_layer = copy.copy(mrc)
                layer_name = layer.name()
                mrc_layer.name = layer_name
                mrc_layer.render_layer = layer_name

                # create a new block for this layer
                block = af.Block(
                    layer_name,
                    renderer_to_block_type.get(render_engine, 'maya')
                )

                block.setFiles(
                    afcommon.patternFromDigits(
                        afcommon.patternFromStdC(
                            afcommon.patternFromPaths(outputs[0], outputs[1])
                        )
                    ).split(';')
                )
                block.setNumeric(
                    start_frame, end_frame, frames_per_task, by_frame
                )
                block.setCommand(mrc_layer.build_command())

                blocks.append(block)
        else:
            # create only one block
            block = af.Block(
                'All Layers',
                renderer_to_block_type.get(render_engine, 'maya')
            )

            block.setFiles(
                afcommon.patternFromDigits(
                    afcommon.patternFromStdC(
                        afcommon.patternFromPaths(outputs[0], outputs[1])
                    )
                ).split(';')
            )
            block.setNumeric(
                start_frame, end_frame, frames_per_task, by_frame
            )
            block.setCommand(mrc.build_command())

            blocks.append(block)

        job.setFolder('input', os.path.dirname(filename))
        job.setFolder('output', os.path.dirname(outputs[0]))
        job.setHostsMask(hosts_mask)
        job.setHostsMaskExclude(hosts_exclude)
        if life_time > 0:
            job.setTimeLife(life_time * 3600)

        job.setCmdPost('deletefiles "%s"' % os.path.abspath(filename))
        if pause:
            job.offline()

        # add blocks
        job.blocks.extend(blocks)

        status, data = job.send()
        if not status:
            pm.PopupError('Something went wrong!')
        print('data: %s' % data)

        # restore log level
        if render_engine == 'arnold':
            aro = pm.PyNode('defaultArnoldRenderOptions')
            aro.setAttr('log_verbosity', stored_log_level)
            # disable set output to console
            aro.setAttr("log_to_console", 0)
        elif render_engine == 'redshift':
            redshift = pm.PyNode('redshiftOptions')
            redshift.logLevel.set(stored_log_level)
Exemplo n.º 3
0
    def launch(self, *args, **kwargs):
        """launch renderer command
        """
        # do nothing if there is no window (called externally)
        if not self.window:
            return

        # warn the user about the ignore settings
        try:
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            ignore_attrs = [
                'ignoreSubdivision',
                'ignoreDisplacement',
                'ignoreBump',
                'ignoreMotionBlur'
            ]

            attr_values = [
                (attr, dAO.getAttr(attr))
                for attr in ignore_attrs
                if dAO.getAttr(attr) is True
            ]

            if any(attr_values):
                msg_text = '<br>'.join(
                    map(
                        lambda x: '%s: %s' % (x[0], x[1]),
                        attr_values
                    )
                )

                response = pm.confirmDialog(
                    title='Ignore These Settings?',
                    message='You have ignored:<br><br>%s<br><br><b>Is that ok?</b>' % msg_text,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
        except pm.MayaNodeError:
            # no Arnold
            pass

        # check if rendering with persp camera
        try:
            wrong_camera_names = [
                'perspShape',
                'topShape',
                'sideShape',
                'fontShape',

                'persp1Shape',
                'perspShape1',
            ]
            renderable_cameras = [node for node in pm.ls(type='camera') if node.getAttr('renderable')]
            if any(map(lambda x: x.name() in wrong_camera_names, renderable_cameras)):
                response = pm.confirmDialog(
                    title='Rendering with Persp?',
                    message='You are rendering with <b>Persp Camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return

            if len(renderable_cameras) > 1:
                response = pm.confirmDialog(
                    title='Rendering more than one Camera?',
                    message='You are rendering <b>more than one camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
            elif len(renderable_cameras) == 0:
                pm.confirmDialog(
                    title='No <b>Renderable</b> camera!!!',
                    message='There is no <b>renderable camera<b>!!!',
                    button=['Ok'],
                    defaultButton='Ok',
                    cancelButton='Ok',
                    dismissString='Ok'
                )
                return

        except pm.MayaNodeError:
            # no default render globals node
            pass

        drg = pm.PyNode('defaultRenderGlobals')
        render_engine = drg.getAttr('currentRenderer')
        # RENDERER SPECIFIC CHECKS

        if render_engine == 'redshift':
            # if the renderer is RedShift
            # check if unifiedDisableDivision is 1 which will take too much time
            # to render
            dro = pm.PyNode('redshiftOptions')
            if dro.unifiedDisableDivision.get() == 1:
                response = pm.confirmDialog(
                    title="Enabled **Don't Automatically Reduce Samples of Other Effects**",
                    message='It is not allowed to render with the following option is enabled:<br>'
                            '<br>'
                            "Don't Automatically Reduce Samples of Other Effects: Enabled<br>"
                            "<br>"
                            "Please DISABLE it!",
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # Check dome light backgrounds
            domes_to_fix = []
            rs_domes = pm.ls(type='RedshiftDomeLight')
            if rs_domes:
                for rs_dome in rs_domes:
                    if rs_dome.getAttr('background_enable') == 1 \
                       or rs_dome.getAttr('backPlateEnabled') == 1:
                        domes_to_fix.append(rs_dome.name())

            if domes_to_fix:
                message = 'Some DomeLights have <b>BackGround Render ' \
                          'Enabled</b>:' \
                          '<br><br>%s<br><br>' \
                          'Are you Sure?' % '<br>'.join(domes_to_fix)

                response = pm.confirmDialog(
                    title='Dome Lights with Background Enabled?',
                    message=message,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )
                if response == 'No':
                    return

            # abort on license fail
            dro.abortOnLicenseFail.set(1)

        elif render_engine == 'arnold':
            # check if the samples are too high
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            aa_samples = dAO.AASamples.get()
            diff_samples = dAO.GIDiffuseSamples.get()
            try:
                glossy_samples = dAO.GIGlossySamples.get()
            except AttributeError:
                glossy_samples = dAO.GISpecularSamples.get()
            if int(pm.about(v=1)) >= 2017:
                sss_samples = dAO.GISssSamples.get()
            else:
                sss_samples = dAO.sssBssrdfSamples.get()

            total_diff_samples = aa_samples**2 * diff_samples**2
            total_glossy_samples = aa_samples**2 * glossy_samples**2
            total_sss_samples = aa_samples**2 * sss_samples**2

            max_allowed_diff_samples = 225
            max_allowed_glossy_samples = 100
            max_allowed_sss_samples = 800

            if total_diff_samples > max_allowed_diff_samples:
                pm.confirmDialog(
                    title="Too Much Diffuse Samples!!!",
                    message='You are using too much DIFFUSE SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of Diffuse '
                            'Samples!!!' % max_allowed_diff_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            if total_glossy_samples > max_allowed_glossy_samples:
                pm.confirmDialog(
                    title="Too Much Glossy Samples!!!",
                    message='You are using too much GLOSSY SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of Glossy '
                            'Samples!!!' % max_allowed_glossy_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            if total_sss_samples > max_allowed_sss_samples:
                pm.confirmDialog(
                    title="Too Much SSS Samples!!!",
                    message='You are using too much SSS SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of SSS '
                            'Samples!!!' % max_allowed_sss_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # check Light Samples
            # check point lights with zero radius but more than one samples
            all_point_lights = pm.ls(type='pointLight')
            ridiculous_point_lights = []
            for point_light in all_point_lights:
                if point_light.aiRadius.get() < 0.1 and point_light.aiSamples.get() > 1:
                    ridiculous_point_lights.append(point_light)

            if ridiculous_point_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Point Lights!!!",
                    message='You are using too much SAMPLES (>1)<br>'
                            '<br>'
                            'on <b>Point lights with zero radius</b><br>'
                            '<br>'
                            'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # Check area lights with more than 2 samples
            all_area_lights = pm.ls(type=['areaLight', 'aiAreaLight'])
            ridiculous_area_lights = []
            for area_light in all_area_lights:
                if area_light.aiSamples.get() > 2:
                    ridiculous_area_lights.append(area_light)

            if ridiculous_area_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Area Lights!!!",
                    message='You are using too much SAMPLES (>2) on<br>'
                            '<br>'
                            '<b>Area Lights</b><br>'
                            '<br>'
                            'Please reduce the samples to 2',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # Check directional lights with angle == 0 and samples > 1
            all_directional_lights = pm.ls(type='directionalLight')
            ridiculous_directional_lights = []
            dir_sample_attr_name = 'aiSamples'
            # if pm.about(v=1) == "2014":
            #     dir_sample_attr_name = 'aiSamples'

            for directional_light in all_directional_lights:
                if directional_light.aiAngle.get() == 0 and directional_light.attr(dir_sample_attr_name).get() > 1:
                    ridiculous_directional_lights.append(directional_light)

            if ridiculous_directional_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Directional Lights!!!",
                    message='You are using too much SAMPLES (>1) on <br>'
                            '<br>'
                            '<b>Directional lights with zero angle</b><br>'
                            '<br>'
                            'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

        # get values
        start_frame = pm.intField('cgru_afanasy__start_frame', q=1, v=1)
        end_frame = pm.intField('cgru_afanasy__end_frame', q=1, v=1)
        frames_per_task = \
            pm.intField('cgru_afanasy__frames_per_task', q=1, v=1)
        by_frame = pm.intField('cgru_afanasy__by_frame', q=1, v=1)
        hosts_mask = pm.textField('cgru_afanasy__hosts_mask', q=1, text=True)
        hosts_exclude = pm.textField('cgru_afanasy__hosts_exclude', q=1, text=True)
        separate_layers = \
            pm.radioButtonGrp('cgru_afanasy__separate_layers', q=1, sl=1)
        pause = pm.checkBox('cgru_afanasy__paused', q=1, v=1)
        life_time = pm.intField('cgru_afanasy__life_time', q=1, v=1)
        annotation = pm.textField('cgru_afanasy__annotation', q=1, text=True)
        submit_multiple_times = pm.intField('cgru_afanasy__submit_multiple_times', q=1, v=1)
        errors_avoid_host = pm.intField('cgru_afanasy__errors_avoid_host', q=1, v=1)
        errors_retries = pm.intField('cgru_afanasy__errors_retries', q=1, v=1)
        errors_task_same_host = pm.intField('cgru_afanasy__errors_task_same_host', q=1, v=1)
        errors_forgive_time = pm.intField('cgru_afanasy__errors_forgive_time', q=1, v=1)

        # check values
        if start_frame > end_frame:
            temp = end_frame
            end_frame = start_frame
            start_frame = temp

        frames_per_task = max(1, frames_per_task)
        by_frame = max(1, by_frame)

        # store without quota sign
        hosts_mask = hosts_mask.replace('"', '')
        hosts_exclude = hosts_exclude.replace('"', '')

        # store field values
        pm.optionVar['cgru_afanasy__start_frame_ov'] = start_frame
        pm.optionVar['cgru_afanasy__end_frame_ov'] = end_frame
        pm.optionVar['cgru_afanasy__frames_per_task_ov'] = frames_per_task
        pm.optionVar['cgru_afanasy__by_frame_ov'] = by_frame
        pm.optionVar['cgru_afanasy__hosts_mask_ov'] = hosts_mask
        pm.optionVar['cgru_afanasy__hosts_exclude_ov'] = hosts_exclude
        pm.optionVar['cgru_afanasy__separate_layers_ov'] = separate_layers
        pm.optionVar['cgru_afanasy__life_time_ov'] = life_time
        pm.optionVar['cgru_afanasy__annotation_ov'] = annotation

        pm.optionVar['cgru_afanasy__submit_multiple_times_ov'] = submit_multiple_times
        pm.optionVar['cgru_afanasy__errors_avoid_host_ov'] = errors_avoid_host
        pm.optionVar['cgru_afanasy__errors_retries_ov'] = errors_retries
        pm.optionVar['cgru_afanasy__errors_task_same_host_ov'] = errors_task_same_host
        pm.optionVar['cgru_afanasy__errors_errors_forgive_time_ov'] = errors_forgive_time

        # get paths
        scene_name = pm.sceneName()
        datetime = '%s%s' % (
            time.strftime('%y%m%d-%H%M%S-'),
            str(time.time() - int(time.time()))[2:5]
        )

        filename = '%s.%s.mb' % (scene_name, datetime)

        project_path = pm.workspace(q=1, rootDirectory=1)

        # outputs = \
        #     pm.renderSettings(fullPath=1, firstImageName=1, lastImageName=1)

        # get output paths, set the RenderPass token to Beauty,
        # this will at least guarantee to get something
        outputs = \
            pm.renderSettings(
                fullPath=1, firstImageName=1, lastImageName=1,
                leaveUnmatchedTokens=1, customTokenString="RenderPass=Beauty"
            )

        # job_name = os.path.basename(scene_name)
        job_name = self.generate_job_name()

        logger.debug('%ss %se %sr' % (start_frame, end_frame, by_frame))
        logger.debug('scene                 = %s' % scene_name)
        logger.debug('file                  = %s' % filename)
        logger.debug('job_name              = %s' % job_name)
        logger.debug('project_path          = %s' % project_path)
        logger.debug('outputs               = %s' % outputs)
        logger.debug('annotation            = %s' % annotation)
        logger.debug('separate_layers       = %s' % separate_layers)
        logger.debug('errors_avoid_host     = %s' % errors_avoid_host)
        logger.debug('errors_retries        = %s' % errors_retries)
        logger.debug('errors_task_same_host = %s' % errors_task_same_host)
        logger.debug('errors_forgive_time   = %s' % errors_forgive_time)

        if pm.checkBox('cgru_afanasy__close', q=1, v=1):
            pm.deleteUI(self.window)

        stored_log_level = None
        if render_engine == 'arnold':
            # set the verbosity level to warning+info
            aro = pm.PyNode('defaultArnoldRenderOptions')
            stored_log_level = aro.getAttr('log_verbosity')
            aro.setAttr('log_verbosity', 2)
            # set output to console
            aro.setAttr("log_to_console", 1)
        elif render_engine == 'redshift':
            # set the verbosity level to detailed+info
            redshift = pm.PyNode('redshiftOptions')
            stored_log_level = redshift.logLevel.get()
            redshift.logLevel.set(2)

        # save file
        pm.saveAs(
            filename,
            force=1,
            type='mayaBinary'
        )

        # rename back to original name
        pm.renameFile(scene_name)

        # create the render command
        mrc = MayaRenderCommandBuilder(
            name=job_name,
            file_full_path=filename,
            render_engine=render_engine,
            project=project_path,
            by_frame=by_frame
        )

        # submit renders
        jobs = []
        blocks = []

        #
        # separate_layers:
        # 1 -> None  -> submit one job with a single block with all layers
        # 2 -> Block -> submit one job with multiple blocks
        # 3 -> Job   -> submit multiple jobs with a single block per layer
        #
        if separate_layers in [1, 2]:
            job = af.Job(job_name)
            jobs.append(job)

        if separate_layers in [2, 3]:
            # render each layer separately
            rlm = pm.PyNode('renderLayerManager')
            layers = [layer for layer in rlm.connections()
                      if layer.renderable.get()]

            for layer in layers:
                mrc_layer = copy.copy(mrc)
                layer_name = layer.name()
                mrc_layer.name = layer_name
                mrc_layer.render_layer = layer_name

                # create a new block for this layer
                block = af.Block(
                    layer_name,
                    renderer_to_block_type.get(render_engine, 'maya')
                )

                # Fix the output path for this layer
                # by replacing the "masterLayer" with the layer name
                # without rs_ at the beginning
                layer_outputs = outputs
                if layer_name != 'defaultRenderLayer':
                    layer_outputs[0] = outputs[0].replace(
                        'masterLayer',
                        layer_name.replace('rs_', '')
                    )
                    layer_outputs[1] = outputs[1].replace(
                        'masterLayer',
                        layer_name.replace('rs_', '')
                    )

                outputs_split = afcommon.patternFromDigits(
                    afcommon.patternFromStdC(
                        afcommon.patternFromPaths(
                            layer_outputs[0],
                            layer_outputs[1]
                        )
                    )
                ).split(';')

                block.setFiles(outputs_split)

                block.setNumeric(
                    start_frame, end_frame, frames_per_task, by_frame
                )
                command = mrc_layer.build_command()

                block.setErrorsAvoidHost(errors_avoid_host)
                block.setErrorsRetries(errors_retries)
                block.setErrorsTaskSameHost(errors_task_same_host)
                block.setErrorsForgiveTime(errors_forgive_time)

                block.setCommand(command)

                if separate_layers == 2:
                    blocks.append(block)
                else:
                    job = af.Job('%s - %s' % (job_name, layer_name))
                    # add blocks
                    job.blocks = [block]
                    jobs.append(job)

        else:
            # create only one block
            block = af.Block(
                'All Layers',
                renderer_to_block_type.get(render_engine, 'maya')
            )

            block.setFiles(
                afcommon.patternFromDigits(
                    afcommon.patternFromStdC(
                        afcommon.patternFromPaths(outputs[0], outputs[1])
                    )
                ).split(';')
            )
            block.setNumeric(
                start_frame, end_frame, frames_per_task, by_frame
            )
            command = mrc.build_command()
            block.setCommand(command)

            blocks.append(block)

        for job in jobs:
            job.setAnnotation(annotation)
            job.setFolder('input', os.path.dirname(filename))
            job.setFolder('output', os.path.dirname(outputs[0]))
            job.setHostsMask(hosts_mask)
            job.setHostsMaskExclude(hosts_exclude)
            if life_time > 0:
                job.setTimeLife(life_time * 3600)
            else:
                job.setTimeLife(240 * 3600)

            job.setCmdPost('deletefiles -s "%s"' % os.path.abspath(filename))
            if pause:
                job.offline()

            # add blocks
            if separate_layers in [1, 2]:
                job.blocks.extend(blocks)

            for i in range(submit_multiple_times):
                orig_job_name = job.data['name']
                job.setName('%s - %03i' % (orig_job_name, i + 1))
                status, data = job.send()

                # restore job name
                job.setName(orig_job_name)
                if not status:
                    pm.PopupError('Something went wrong!')

        # restore log level
        if render_engine == 'arnold':
            aro = pm.PyNode('defaultArnoldRenderOptions')
            aro.setAttr('log_verbosity', stored_log_level)
            # disable set output to console
            aro.setAttr("log_to_console", 0)
        elif render_engine == 'redshift':
            redshift = pm.PyNode('redshiftOptions')
            redshift.logLevel.set(stored_log_level)

            # disable abort on license fail
            redshift.abortOnLicenseFail.set(0)
Exemplo n.º 4
0
Arquivo: afanasy.py Projeto: CGRU/cgru
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):

    params = []

    if ropnode is not None and ropnode.type().name() == 'ifd' and afnode.parm('sep_enable').eval():
        # Case mantra separate render:

        block_generate = \
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        blockname = block_generate.name
        block_generate.name += '-G'

        if not block_generate.valid:
            block_generate.doPost()
            return None

        run_rop = afnode.parm('sep_run_rop').eval()
        read_rop = afnode.parm('sep_read_rop_params').eval()
        join_render = afnode.parm('sep_join').eval()
        tile_render = afnode.parm('sep_tile').eval()
        tile_divx = afnode.parm('sep_tile_divx').eval()
        tile_divy = afnode.parm('sep_tile_divy').eval()
        use_tmp_img_folder = afnode.parm('sep_use_tmp_img_folder').eval()
        del_rop_files = afnode.parm('sep_del_rop_files').eval()

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage(
                    'Can`t find ROP for processing "%s"' % afnode.path()
                )

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage(
                    '"%s" is not a ROP node' % block_generate.ropnode.path()
                )

        if not run_rop:
            join_render = False

        if join_render:
            tile_render = False
        else:
            if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm('soho_outputmode').set(1)
                block_generate.soho_outputmode = 0
                block_generate.ropnode.parm('soho_diskfile').set(
                    block_generate.ropnode.parm(
                        'vm_picture').unexpandedString() + '.ifd'
                )

        if read_rop:
            parm_images = ropnode.parm('vm_picture')
            parm_files  = ropnode.parm('soho_diskfile')
        else:
            parm_images = afnode.parm('sep_images')
            parm_files  = afnode.parm('sep_files')

        images = afcommon.patternFromPaths(
            parm_images.evalAsStringAtFrame( block_generate.frame_first),
            parm_images.evalAsStringAtFrame( block_generate.frame_last))

        files = afcommon.patternFromPaths(
            parm_files.evalAsStringAtFrame( block_generate.frame_first),
            parm_files.evalAsStringAtFrame( block_generate.frame_last))

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.service = 'hbatch'
            else:
                block_generate.service = 'hbatch_mantra'
                block_generate.cmd = block_generate.cmd.replace(
                    'hrender_af', 'hrender_separate'
                )

                if use_tmp_img_folder:
                    block_generate.cmd += ' --tmpimg'

        if not join_render:
            tiles = tile_divx * tile_divy
            block_render = BlockParameters(afnode, ropnode, subblock, prefix,
                                           frame_range)
            block_render.name = blockname + '-R'
            block_render.cmd = 'mantra'
            block_render.service = block_render.cmd
            if run_rop:
                block_render.dependmask = block_generate.name

            if tile_render or del_rop_files or use_tmp_img_folder:
                block_render.cmd = 'mantrarender '

            if del_rop_files:
                block_render.delete_files.append(files)

            if use_tmp_img_folder:
                block_render.cmd += 't'

            if tile_render:
                block_render.numeric = False
                block_render.cmd += 'c %(tile_divx)d %(tile_divy)d' % vars()
                block_render.cmd += ' @#@'
                block_render.frame_pertask = -tiles
                for frame in range(block_generate.frame_first,
                                   block_generate.frame_last + 1,
                                   block_generate.frame_inc):
                    arguments = afnode.parm(
                        'sep_render_arguments').evalAsStringAtFrame(frame)
                    arguments = arguments.replace(
                        '@FILES@', parm_files.evalAsStringAtFrame( frame))

                    for tile in range(0, tiles):
                        block_render.tasks_names.append(
                            '%d tile %d' % (frame, tile))
                        block_render.tasks_cmds.append(
                            '%d -R %s' % (tile, arguments))
            else:
                if del_rop_files or use_tmp_img_folder:
                    block_render.cmd += ' -R '
                else:
                    block_render.cmd += ' -V a '
                block_render.cmd += afcommon.patternFromPaths(
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(block_generate.frame_first),
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(block_generate.frame_last)
                ).replace('@FILES@', files)
                block_render.preview = images

        if tile_render:
            cmd = 'exrjoin %(tile_divx)d %(tile_divy)d %(images)s d' % vars()

            block_join = BlockParameters(
                afnode, ropnode, subblock, prefix, frame_range
            )

            block_join.name = blockname + '-J'
            block_join.service = 'generic'
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

        if tile_render:
            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    elif len(str(afnode.parm('ds_node').eval())):
        # Case distribute simulation:
        ds_node_path = str(afnode.parm('ds_node').eval())
        ds_node = hou.node(ds_node_path)
        if not ds_node:
            hou.ui.displayMessage('No such control node: "%s"' % ds_node_path)
            return
        parms = ['address', 'port', 'slice']
        for parm in parms:
            if not ds_node.parm(parm):
                hou.ui.displayMessage('Control node "%s" does not have "%s" parameter' % (ds_node_path, parm))
                return

        enable_tracker = not afnode.parm('ds_tracker_manual').eval()
        if enable_tracker:
            # Tracker block:
            par_start = getTrackerParameters(afnode, ropnode, subblock, prefix, frame_range, True)
            params.append(par_start)

        # A block for each slice:
        ds_num_slices = int(afnode.parm('ds_num_slices').eval())
        for s in range(0, ds_num_slices):
            par = BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
            sim_blocks_mask = par.name + '.*'
            par.name += '-s%d' % s
            par.frame_pertask = par.frame_last - par.frame_first + 1
            if enable_tracker:
                par.addDependMask(par_start.name)
            par.fullrangedepend = True
            par.auxargs = ' --ds_node "%s"' % ds_node_path
            par.auxargs += ' --ds_address "%s"' % str(afnode.parm('ds_address').eval())
            par.auxargs += ' --ds_port %d' % int(afnode.parm('ds_port').eval())
            par.auxargs += ' --ds_slice %d' % s
            params.append(par)

        if enable_tracker:
            # Stop tracker block:
            par_stop = getTrackerParameters(afnode, ropnode, subblock, prefix, frame_range, False)
            par_stop.addDependMask(sim_blocks_mask)
            params.append(par_stop)

            # Set other block names for start tracker block.
            # As start tracker block will set other block environment
            # to specify started tracker and port.
            par_start.cmd += ' --envblocks "%s|%s"' % (sim_blocks_mask, par_stop.name)
            # On this block depend mask will be reset on tracker start:
            par_start.cmd += ' --depblocks "%s"' % sim_blocks_mask

    else:
        params.append(
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        )
    return params
Exemplo n.º 5
0
    def __init__(self,
                 afnode,
                 ropnode,
                 subblock,
                 prefix,
                 frame_range,
                 for_job_only=False):
        if VERBOSE == 2:
            if ropnode:
                print('Initializing block parameters for "%s" from "%s"' %
                      (ropnode.path(), afnode.path()))
            else:
                print('Initializing command block parameters from "%s"' %
                      afnode.path())

        # Init parameters:
        self.valid = False
        self.afnode = afnode
        self.ropnode = None
        self.subblock = subblock
        self.prefix = prefix
        self.preview = ''
        self.name = ''
        self.type = ''
        self.cmd = ''
        self.cmd_useprefix = True
        self.dependmask = ''
        self.fullrangedepend = False
        self.numeric = True
        self.frame_first, self.frame_last, \
        self.frame_inc, self.frame_pertask = frame_range
        self.tasks_names = []
        self.tasks_cmds = []
        self.tasks_previews = []
        # Parameters to restore ROP changes:
        self.soho_foreground = None
        self.soho_outputmode = None

        # Get parameters:
        self.job_name = str(afnode.parm('job_name').eval())
        self.start_paused = int(afnode.parm('start_paused').eval())
        self.platform = str(afnode.parm('platform').eval())
        self.subtaskdepend = int(afnode.parm('subtaskdepend').eval())
        self.priority = -1
        self.max_runtasks = -1
        self.maxperhost = -1
        self.maxruntime = -1
        self.capacity = -1
        self.capacity_min = -1
        self.capacity_max = -1
        self.hosts_mask = ''
        self.hosts_mask_exclude = ''
        self.depend_mask = ''
        self.depend_mask_global = ''

        if afnode.parm('enable_extended_parameters').eval():
            self.priority = int(afnode.parm('priority').eval())
            self.max_runtasks = int(afnode.parm('max_runtasks').eval())
            self.maxperhost = int(afnode.parm('maxperhost').eval())
            self.maxruntime = int(afnode.parm('maxruntime').eval())
            self.capacity = int(afnode.parm('capacity').eval())
            self.capacity_min = int(
                afnode.parm('capacity_coefficient1').eval())
            self.capacity_max = int(
                afnode.parm('capacity_coefficient2').eval())
            self.hosts_mask = str(afnode.parm('hosts_mask').eval())
            self.hosts_mask_exclude = str(
                afnode.parm('hosts_mask_exclude').eval())
            self.depend_mask = str(afnode.parm('depend_mask').eval())
            self.depend_mask_global = str(
                afnode.parm('depend_mask_global').eval())

        # Process frame range:
        opname = afnode.path()
        if afnode.parm('trange').eval() > 1:
            self.fullrangedepend = True

        if ropnode:
            opname = ropnode.path()
            trange = ropnode.parm('trange')

            if trange is not None:
                if int(trange.eval()) > 0:
                    if ropnode.parm('f1') is not None:
                        self.frame_first = int(ropnode.parm('f1').eval())

                    if ropnode.parm('f2') is not None:
                        self.frame_last = int(ropnode.parm('f2').eval())

                    if ropnode.parm('f3') is not None:
                        self.frame_inc = int(ropnode.parm('f3').eval())

                if int(trange.eval()) > 1:
                    self.fullrangedepend = True

        if self.frame_last < self.frame_first:
            hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
            return

        if self.frame_inc < 1:
            hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
            return

        if self.frame_pertask < 1:
            hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
            return

        # Process output driver type to construct a command:
        if ropnode:
            self.type = 'hbatch'

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      ropnode.path())
                return

            self.ropnode = ropnode
            self.name = str(ropnode.name())

            if self.prefix != '':
                self.name = '%s_%s' % (self.prefix, self.name)
            # Block type and preview:
            roptype = ropnode.type().name()

            if roptype == 'ifd':
                if not ropnode.parm('soho_outputmode').eval():
                    self.type = 'hbatch_mantra'

                vm_picture = ropnode.parm('vm_picture')

                if vm_picture is not None:
                    self.preview = \
                     afcommon.patternFromPaths(
                      vm_picture.evalAsStringAtFrame(self.frame_first),
                      vm_picture.evalAsStringAtFrame(self.frame_last)
                     )
            elif roptype == 'rib':
                self.type = 'hbatch_prman'

            # Block command:
            self.cmd = 'hrender_af'
            if afnode.parm('ignore_inputs').eval():
                self.cmd += ' -i'

            if self.capacity_min != -1 or self.capacity_max != -1:
                self.cmd += ' --numcpus ' + services.service.str_capacity

            self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (
                self.frame_inc, afnode.parm('take').eval())

            self.cmd += ' "%(hipfilename)s"'
            self.cmd += ' "%s"' % ropnode.path()
        else:
            # Custom command driver:
            if int(afnode.parm('cmd_add').eval()):
                # Command:
                cmd = self.afnode.parm('cmd_cmd')
                self.cmd = afcommon.patternFromPaths(
                    cmd.evalAsStringAtFrame(self.frame_first),
                    cmd.evalAsStringAtFrame(self.frame_last))

                # Name:
                self.name = self.afnode.parm('cmd_name').eval()
                if self.name is None or self.name == '':
                    self.name = self.cmd.split(' ')[0]

                # Service:
                self.type = self.afnode.parm('cmd_service').eval()
                if self.type is None or self.type == '':
                    self.type = self.cmd.split(' ')[0]

                # Prefix:
                self.cmd_useprefix = \
                 int(self.afnode.parm('cmd_use_afcmdprefix').eval())

            elif not for_job_only:
                hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
                return

        # Try to set driver foreground mode
        if ropnode:
            trange = ropnode.parm('trange')
            soho_foreground = ropnode.parm('soho_foreground')
            if trange is not None and int(trange.eval()) == 0:
                if soho_foreground is not None:
                    if soho_foreground.eval() == 0:
                        try:
                            soho_foreground.set(1)
                            self.soho_foreground = 0
                        except:  # TODO: too broad exception clause
                            hou.ui.displayMessage(
                                'Set "Block Until Render Complete" on "%s" '
                                'node' % ropnode.path())
                            return

        self.valid = True
Exemplo n.º 6
0
    def __init__(self,
                 afnode,
                 ropnode,
                 subblock,
                 prefix,
                 frame_range,
                 for_job_only=False):
        if VERBOSE == 2:
            if ropnode:
                print('Initializing block parameters for "%s" from "%s"' %
                      (ropnode.path(), afnode.path()))
            else:
                print('Initializing command block parameters from "%s"' %
                      afnode.path())

        # Init parameters:
        self.valid = False
        self.afnode = afnode
        self.ropnode = None
        self.subblock = subblock
        self.frame_pertask = 1
        self.frame_sequential = 1
        self.prefix = prefix
        self.preview = ''
        self.name = ''
        self.service = ''
        self.parser = ''
        self.cmd = ''
        self.cmd_useprefix = True
        self.dependmask = ''
        self.fullrangedepend = False
        self.numeric = True
        self.frame_first, self.frame_last, self.frame_inc = frame_range
        self.auxargs = ''
        self.tasks_names = []
        self.tasks_cmds = []
        self.tasks_previews = []
        # Fill in this array with files to delete in a block post command.
        # Files should have a common afanasy "@#*@" pattern,
        # it will be replaced with "*" for shell.
        self.delete_files = []
        # Parameters to restore ROP changes:
        self.soho_foreground = None
        self.soho_outputmode = None

        # Get parameters:
        self.frame_pertask = int(afnode.parm('frame_pertask').eval())
        self.frame_sequential = int(afnode.parm('frame_sequential').eval())
        self.job_name = str(afnode.parm('job_name').eval())
        self.job_branch = ''
        self.start_paused = int(afnode.parm('start_paused').eval())
        self.platform = str(afnode.parm('platform').eval())
        self.subtaskdepend = int(afnode.parm('subtaskdepend').eval())
        self.priority = -1
        self.max_runtasks = -1
        self.maxperhost = -1
        self.maxruntime = -1
        self.minruntime = -1
        self.capacity = -1
        self.capacity_min = -1
        self.capacity_max = -1
        self.hosts_mask = ''
        self.hosts_mask_exclude = ''
        self.depend_mask = ''
        self.depend_mask_global = ''
        self.min_memory = -1
        self.preview_approval = afnode.parm('preview_approval').eval()

        if afnode.parm('enable_extended_parameters').eval():
            self.job_branch = self.afnode.parm('job_branch').eval()
            self.parser = self.afnode.parm('override_parser').eval()
            self.priority = int(afnode.parm('priority').eval())
            self.max_runtasks = int(afnode.parm('max_runtasks').eval())
            self.maxperhost = int(afnode.parm('maxperhost').eval())
            self.maxruntime = int(afnode.parm('maxruntime').eval())
            self.minruntime = int(afnode.parm('minruntime').eval())
            self.min_memory = int(afnode.parm('min_memory').eval())
            self.capacity = int(afnode.parm('capacity').eval())
            self.capacity_min = int(
                afnode.parm('capacity_coefficient1').eval())
            self.capacity_max = int(
                afnode.parm('capacity_coefficient2').eval())
            self.hosts_mask = str(afnode.parm('hosts_mask').eval())
            self.hosts_mask_exclude = str(
                afnode.parm('hosts_mask_exclude').eval())
            self.depend_mask = str(afnode.parm('depend_mask').eval())
            self.depend_mask_global = str(
                afnode.parm('depend_mask_global').eval())

        # Process frame range:
        opname = afnode.path()
        if afnode.parm('trange').eval() > 1:
            self.fullrangedepend = True

        if ropnode:
            opname = ropnode.path()
            trange = ropnode.parm('trange')

            if trange is not None:
                if int(trange.eval()) > 0:
                    if ropnode.parm('f1') is not None:
                        self.frame_first = int(ropnode.parm('f1').eval())

                    if ropnode.parm('f2') is not None:
                        self.frame_last = int(ropnode.parm('f2').eval())

                    if ropnode.parm('f3') is not None:
                        self.frame_inc = int(ropnode.parm('f3').eval())

                if int(trange.eval()) > 1:
                    self.fullrangedepend = True

        if self.frame_last < self.frame_first:
            hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
            return

        if self.frame_inc < 1:
            hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
            return

        if self.frame_pertask < 1:
            hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
            return

        # Process output driver type to construct a command:
        if ropnode:
            self.service = 'hbatch'

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      ropnode.path())
                return

            self.ropnode = ropnode
            self.name = str(ropnode.name())

            if self.prefix != '':
                self.name = '%s_%s' % (self.prefix, self.name)
            # Block type and preview:
            roptype = ropnode.type().name()

            if roptype == 'ifd':
                if ropnode.node(ropnode.parm('camera').eval()) == None:
                    hou.ui.displayMessage("Camera in " + ropnode.name() +
                                          " is not valid",
                                          severity=hou.severityType.Error)
                    return

                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'hbatch_mantra'

                vm_picture = ropnode.parm('vm_picture')

                if vm_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            vm_picture.evalAsStringAtFrame(self.frame_first),
                            vm_picture.evalAsStringAtFrame(self.frame_last)
                        )
            elif roptype == 'rib':
                self.service = 'hbatch_prman'

            elif roptype == 'arnold':
                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'houdinitoarnold'

                ar_picture = ropnode.parm('ar_picture')

                if ar_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            ar_picture.evalAsStringAtFrame(self.frame_first),
                            ar_picture.evalAsStringAtFrame(self.frame_last)
                        )

            elif roptype == 'alembic':
                self.numeric = False
                taskname = ropnode.name()
                taskname += ' ' + str(self.frame_first)
                taskname += '-' + str(self.frame_last)
                self.tasks_names.append(taskname)
                self.tasks_cmds.append(self.frame_first)

            elif roptype == 'Redshift_ROP':
                self.service = 'hbatch_redshift'
                rs_picture = ropnode.parm('RS_outputFileNamePrefix')

                if rs_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            rs_picture.evalAsStringAtFrame(self.frame_first),
                            rs_picture.evalAsStringAtFrame(self.frame_last)
                        )

            # Block command:
            self.cmd = 'hrender_af'
            if afnode.parm('ignore_inputs').eval():
                self.cmd += ' -i'

            if self.capacity_min != -1 or self.capacity_max != -1:
                self.cmd += ' --numcpus ' + services.service.str_capacity

            self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (
                self.frame_inc, afnode.parm('take').eval())

            #            numWedges = computeWedge(ropnode, roptype)
            #            if numWedges:
            #                self.frame_first = 0
            #                self.frame_last = numWedges - 1
            #                self.frame_inc = 1
            #                self.frame_pertask = 1
            #                self.parser = "mantra"

            self.cmd += '%(auxargs)s'
            self.cmd += ' "%(hipfilename)s"'
            self.cmd += ' "%s"' % ropnode.path()

            if afnode.parm('enable_extended_parameters').eval():
                # Override service:
                override_service = self.afnode.parm('override_service').eval()
                if override_service is not None and len(override_service):
                    self.service = override_service

        else:
            # Custom command driver:
            if int(afnode.parm('cmd_mode').eval()):
                # Command:
                cmd = self.afnode.parm('cmd_cmd')
                self.cmd = afcommon.patternFromPaths(
                    cmd.evalAsStringAtFrame(self.frame_first),
                    cmd.evalAsStringAtFrame(self.frame_last))

                # Name:
                self.name = self.afnode.parm('cmd_name').eval()
                if self.name is None or self.name == '':
                    self.name = self.cmd.split(' ')[0]

                # Service:
                self.service = self.afnode.parm('cmd_service').eval()
                if self.service is None or self.service == '':
                    self.service = self.cmd.split(' ')[0]
                # Parser:
                self.parser = self.afnode.parm('cmd_parser').eval()

                # Prefix:
                self.cmd_useprefix = \
                    int(self.afnode.parm('cmd_use_afcmdprefix').eval())

                # Delete files on job deletion:
                if self.afnode.parm('cmd_delete_files').eval():
                    cmd_files = self.afnode.parm('cmd_files')
                    self.delete_files.append(
                        afcommon.patternFromPaths(
                            cmd_files.evalAsStringAtFrame(self.frame_first),
                            cmd_files.evalAsStringAtFrame(self.frame_last)))

            elif not for_job_only:
                hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
                return

        # Try to set driver foreground mode
        if ropnode:
            trange = ropnode.parm('trange')
            soho_foreground = ropnode.parm('soho_foreground')
            if trange is not None and int(trange.eval()) == 0:
                if soho_foreground is not None:
                    if soho_foreground.eval() == 0:
                        try:
                            soho_foreground.set(1)
                            self.soho_foreground = 0
                        except:  # TODO: too broad exception clause
                            hou.ui.displayMessage(
                                'Set "Block Until Render Complete" on "%s" '
                                'node' % ropnode.path())
                            return

        # Try to create output folder:
        if self.preview != '' and afnode.parm('check_output_folder').eval():
            folder = os.path.dirname(self.preview)
            if not os.path.isdir(folder):
                if hou.ui.displayMessage(folder,
                                         buttons=('Create', 'Abort'),
                                         default_choice=0,
                                         close_choice=1,
                                         title='Output Folder Does Not Exist',
                                         details=folder) == 0:
                    try:
                        os.makedirs(folder)
                    except Exception as e:
                        hou.ui.displayMessage(
                            folder,
                            buttons=('Abort', ),
                            default_choice=0,
                            close_choice=1,
                            title='Error Creating Output Folder',
                            details=str(e))
                        return
                    if not os.path.isdir(folder):
                        hou.ui.displayMessage(
                            folder,
                            buttons=('Abort', ),
                            default_choice=0,
                            close_choice=1,
                            title='Can`t Create Output Folder',
                            details=folder)
                        return
                else:
                    return

        self.valid = True
Exemplo n.º 7
0
            cmd += ' -s @#@ -e @#@ -b %d' % by
        else:
            cmd += ' -an 1 -s @#@ -e @#@ -inc %d' % by

        if node != '':
            cmd += ' -cam "%s"' % node

        if take != '':
            if scenetype == 'maya_delight':
                cmd += ' -rp "%s"' % take
            else:
                cmd += ' -rl "%s"' % take
        if images != '':
            images = images.split(',')
            if len(images) > 1:
                images = afcommon.patternFromPaths(images[0], images[1])
            else:
                images = afcommon.patternFromFile(images[0])

        if proj:
            cmd += ' -proj "%s"' % os.path.normpath(proj)
        # else:
        #     if pwd != '':
        #         cmd += ' -proj "%s"' % os.path.normpath(pwd)
        #     else:
        #         cmd += ' -proj "%s"' % os.path.normpath(os.path.dirname(scene))

        if output != '':
            cmd += ' -rd "%s"' % os.path.normpath(output)

        if scenetype == 'maya_mental':
Exemplo n.º 8
0
import os
import sys

import afcommon

if len(sys.argv) < 2:
    print('\nUsage: To check common functions class launch:')
    print('%s [func] [args...]\n' % os.path.basename(sys.argv[0]))
    sys.exit(1)

if sys.argv[1] == 'pat2':
    if len(sys.argv) < 4:
        print('Usage: %s %s str1 str2' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.patternFromPaths(sys.argv[2], sys.argv[3]))
elif sys.argv[1] == 'fillnum':
    if len(sys.argv) < 5:
        print('Usage: %s %s pattern start end' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.fillNumbers(sys.argv[2], int(sys.argv[3]), int(sys.argv[4])))
elif sys.argv[1] == 'patc':
    if len(sys.argv) < 3:
        print('Usage: %s %s str' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.patternFromStdC(sys.argv[2], True))
elif sys.argv[1] == 'patd':
    if len(sys.argv) < 3:
        print('Usage: %s %s str' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.patternFromDigits(sys.argv[2], True))
Exemplo n.º 9
0
    def __init__(self,
                 afnode,
                 ropnode,
                 subblock,
                 prefix,
                 frame_range,
                 for_job_only=False):
        if VERBOSE == 2:
            if ropnode:
                print('Initializing block parameters for "%s" from "%s"' %
                      (ropnode.path(), afnode.path()))
            else:
                print('Initializing command block parameters from "%s"' %
                      afnode.path())

        # Init parameters:
        self.valid = False
        self.afnode = afnode
        self.ropnode = None
        self.subblock = subblock
        self.single_task = False
        self.local_render = False
        self.frame_pertask = 1
        self.frame_sequential = 1
        self.prefix = prefix
        self.preview = ''
        self.name = ''
        self.service = ''
        self.tickets = dict()
        self.parser = ''
        self.cmd = ''
        self.cmd_useprefix = True
        self.dependmask = ''
        self.fullrangedepend = False
        self.numeric = True
        self.frame_first, self.frame_last, self.frame_inc = frame_range
        self.auxargs = ''
        self.tasks_names = []
        self.tasks_cmds = []
        self.tasks_previews = []
        self.file_check_enable = False
        self.file_check_size_mb_min = -1
        self.file_check_size_mb_max = -1
        self.file_check_skip_existing = True
        # Fill in this array with files to delete in a block post command.
        # Files should have a common afanasy "@#*@" pattern,
        # it will be replaced with "*" for shell.
        self.delete_files = []
        # Parameters to restore ROP changes:
        self.soho_foreground = None
        self.soho_outputmode = None
        self.pre_submit_script = None
        self.post_submit_script = None

        # Get parameters:
        self.single_task = bool(afnode.parm('single_task').eval())
        self.local_render = bool(afnode.parm('local_render').eval())
        self.job_name = str(afnode.parm('job_name').eval())
        self.job_branch = ''
        self.start_paused = int(afnode.parm('start_paused').eval())
        self.platform = str(afnode.parm('platform').eval())
        self.subtaskdepend = int(afnode.parm('subtaskdepend').eval())
        self.priority = -1
        self.max_runtasks = -1
        self.maxperhost = -1
        self.maxruntime = -1
        self.minruntime = -1
        self.progress_timeout = -1
        self.capacity = -1
        self.capacity_min = -1
        self.capacity_max = -1
        self.hosts_mask = ''
        self.hosts_mask_exclude = ''
        self.depend_mask = ''
        self.depend_mask_global = ''
        self.min_memory = -1
        self.min_gpu_mem = -1
        self.min_cpu_freq = -1
        self.min_cpu_cores = -1
        self.min_cpu_cores_freq = -1
        self.tickets_use = int(afnode.parm('tickets_use').eval())
        self.tickets_auto = int(afnode.parm('tickets_auto').eval())
        self.ticket_mem = int(afnode.parm('ticket_mem').eval())
        self.tickets_aux_use = int(afnode.parm('tickets_aux_use').eval())
        self.tickets_aux_data = afnode.parm('tickets_aux_data').eval()
        self.pools_use = int(afnode.parm('pools_use').eval())
        self.pools_data = afnode.parm('pools_data').eval()
        self.generate_previews = self.afnode.parm('generate_previews').eval()
        self.life_time = -1
        self.preview_approval = afnode.parm('preview_approval').eval()

        if afnode.parm('enable_extended_parameters').eval():
            self.job_branch = self.afnode.parm('job_branch').eval()
            self.parser = self.afnode.parm('override_parser').eval()
            self.priority = int(afnode.parm('priority').eval())
            self.max_runtasks = int(afnode.parm('max_runtasks').eval())
            self.maxperhost = int(afnode.parm('maxperhost').eval())
            self.maxruntime = float(afnode.parm('maxruntime').eval())
            self.minruntime = int(afnode.parm('minruntime').eval())
            self.progress_timeout = float(
                afnode.parm('progress_timeout').eval())
            self.min_memory = int(afnode.parm('min_memory').eval())
            self.min_gpu_mem = float(afnode.parm('min_gpu_mem').eval())
            self.min_cpu_freq = float(afnode.parm('min_cpu_freq').eval())
            self.min_cpu_cores = int(afnode.parm('min_cpu_cores').eval())
            self.min_cpu_cores_freq = float(
                afnode.parm('min_cpu_cores_freq').eval())
            self.capacity = int(afnode.parm('capacity').eval())
            self.capacity_min = int(
                afnode.parm('capacity_coefficient1').eval())
            self.capacity_max = int(
                afnode.parm('capacity_coefficient2').eval())
            self.hosts_mask = str(afnode.parm('hosts_mask').eval())
            self.hosts_mask_exclude = str(
                afnode.parm('hosts_mask_exclude').eval())
            self.depend_mask = str(afnode.parm('depend_mask').eval())
            self.depend_mask_global = str(
                afnode.parm('depend_mask_global').eval())
            self.life_time = self.afnode.parm('life_time').eval()

        if afnode.parm('file_check_enable').eval():
            self.file_check_enable = True
            self.file_check_size_mb_min = int(
                1024.0 * 1024.0 * afnode.parm('file_check_size_mb_min').eval())
            self.file_check_size_mb_max = int(
                1024.0 * 1024.0 * afnode.parm('file_check_size_mb_max').eval())
            self.file_check_skip_existing = afnode.parm(
                'file_check_skip_existing').eval()

        if self.local_render:
            self.hosts_mask = str(socket.gethostname())

        # Process frame range:
        opname = afnode.path()
        if afnode.parm('trange').eval() > 1:
            self.fullrangedepend = True

        if ropnode:
            opname = ropnode.path()
            trange = ropnode.parm('trange')

            if trange is not None:
                if int(trange.eval()) > 0:
                    if ropnode.parm('f1') is not None:
                        self.frame_first = int(ropnode.parm('f1').eval())

                    if ropnode.parm('f2') is not None:
                        self.frame_last = int(ropnode.parm('f2').eval())

                    if ropnode.parm('f3') is not None:
                        self.frame_inc = int(ropnode.parm('f3').eval())

                if int(trange.eval()) > 1:
                    self.fullrangedepend = True

        if self.frame_last < self.frame_first:
            hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
            return

        if self.frame_inc < 1:
            hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
            return

        if self.frame_pertask < 1:
            hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
            return

        if self.single_task:
            self.frame_pertask = self.frame_last - self.frame_first + 1
            self.frame_sequential = 1
        else:
            self.frame_pertask = int(afnode.parm('frame_pertask').eval())
            self.frame_sequential = int(afnode.parm('frame_sequential').eval())

        # Process output driver type to construct a command:
        if ropnode:
            self.service = 'hbatch'
            self.tickets['HYTHON'] = 1

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      ropnode.path())
                return

            self.ropnode = ropnode
            self.name = str(ropnode.name())

            if self.prefix != '':
                self.name = '%s_%s' % (self.prefix, self.name)
            # Block type and preview:
            roptype = ropnode.type().name()

            if roptype == 'ifd':
                if ropnode.node(ropnode.parm('camera').eval()) is None:
                    hou.ui.displayMessage("Camera in %s is not valid" %
                                          ropnode.name(),
                                          severity=hou.severityType.Error)
                    return

                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'hbatch_mantra'
                    self.tickets['MANTRA'] = 1

                vm_picture = ropnode.parm('vm_picture')

                if vm_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            vm_picture.evalAsStringAtFrame(self.frame_first),
                            vm_picture.evalAsStringAtFrame(self.frame_last)
                        )

            # TODO karma hydra delegate.

            elif roptype == 'rib':
                self.service = 'hbatch_prman'
                self.tickets['PRMAN'] = 1

            # TODO renderman hydra delegate.

            elif roptype == 'arnold':
                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'houdinitoarnold'

                ar_picture = ropnode.parm('ar_picture')

                if ar_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            ar_picture.evalAsStringAtFrame(self.frame_first),
                            ar_picture.evalAsStringAtFrame(self.frame_last)
                        )

            # Solaris. Arnold.
            elif roptype == 'usdrender_rop' and ropnode.parm(
                    'renderer').eval() == 'HdArnoldRendererPlugin':
                self.service = 'houdinitoarnold'

                ar_picture = ropnode.parm('outputimage')

                if ar_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            ar_picture.evalAsStringAtFrame(self.frame_first),
                            ar_picture.evalAsStringAtFrame(self.frame_last)
                        )

            elif roptype in ['alembic', 'usd_rop']:
                self.numeric = False
                taskname = ropnode.name()
                taskname += ' ' + str(self.frame_first)
                taskname += '-' + str(self.frame_last)
                self.tasks_names.append(taskname)
                self.tasks_cmds.append(self.frame_first)

            elif roptype == 'Redshift_ROP':
                self.service = 'hbatch_redshift'
                self.tickets['REDSHIFT'] = 1
                rs_picture = ropnode.parm('RS_outputFileNamePrefix')

                if rs_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            rs_picture.evalAsStringAtFrame(self.frame_first),
                            rs_picture.evalAsStringAtFrame(self.frame_last)
                        )

            # TODO redshift hydra delegate.

            # For files menu in watcher
            elif roptype == 'geometry':
                file_geo = ropnode.parm('sopoutput')

                if file_geo is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            file_geo.evalAsStringAtFrame(self.frame_first),
                            file_geo.evalAsStringAtFrame(self.frame_last)
                        )

            # Block command:
            self.cmd = 'hrender_af'

            # If this is a "rez" configured environment supply the same environment to
            # the render command
            if "REZ_USED_REQUEST" in os.environ:
                self.cmd = 'rez-env {} -- {}'.format(
                    os.environ["REZ_USED_REQUEST"], self.cmd)

            if self.single_task:
                # On a single task we can see progress as job report
                self.cmd += ' --report'

            if afnode.parm('ignore_inputs').eval():
                self.cmd += ' -i'

            if self.capacity_min != -1 or self.capacity_max != -1:
                self.cmd += ' --numcpus ' + services.service.str_capacity

            self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (
                self.frame_inc, afnode.parm('take').eval())

            self.cmd += '%(auxargs)s'
            self.cmd += ' "%(hipfilename)s"'
            self.cmd += ' "%s"' % ropnode.path()

            if afnode.parm('enable_extended_parameters').eval():
                # Override service:
                override_service = self.afnode.parm('override_service').eval()
                if override_service is not None and len(override_service):
                    self.service = override_service

        else:
            # Custom command driver:
            if int(afnode.parm('cmd_mode').eval()):
                # Command:
                cmd = self.afnode.parm('cmd_cmd')
                self.cmd = afcommon.patternFromPaths(
                    cmd.evalAsStringAtFrame(self.frame_first),
                    cmd.evalAsStringAtFrame(self.frame_last))

                # Name:
                self.name = self.afnode.parm('cmd_name').eval()
                if self.name is None or self.name == '':
                    self.name = self.cmd.split(' ')[0]
                if self.prefix != '':
                    self.name = '%s_%s' % (self.prefix, self.name)

                # Service:
                self.service = self.afnode.parm('cmd_service').eval()
                if self.service is None or self.service == '':
                    self.service = self.cmd.split(' ')[0]
                # Parser:
                self.parser = self.afnode.parm('cmd_parser').eval()

                # Prefix:
                self.cmd_useprefix = \
                    int(self.afnode.parm('cmd_use_afcmdprefix').eval())

                # Delete files on job deletion:
                if self.afnode.parm('cmd_delete_files').eval():
                    cmd_files = self.afnode.parm('cmd_files')
                    self.delete_files.append(
                        afcommon.patternFromPaths(
                            cmd_files.evalAsStringAtFrame(self.frame_first),
                            cmd_files.evalAsStringAtFrame(self.frame_last)))

            elif not for_job_only:
                hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
                return

        # Try to set driver foreground mode
        if ropnode:
            trange = ropnode.parm('trange')
            soho_foreground = ropnode.parm('soho_foreground')
            if trange is not None and int(trange.eval()) == 0:
                if soho_foreground is not None:
                    if soho_foreground.eval() == 0:
                        try:
                            soho_foreground.set(1)
                            self.soho_foreground = 0
                        except:  # TODO: too broad exception clause
                            hou.ui.displayMessage(
                                'Set "Block Until Render Complete" on "%s" '
                                'node' % ropnode.path())
                            return

        # Try to create output folder:
        if self.preview != '' and afnode.parm('check_output_folder').eval():
            folder = os.path.dirname(self.preview)
            if not os.path.isdir(folder):
                if hou.ui.displayMessage(folder,
                                         buttons=('Create', 'Abort'),
                                         default_choice=0,
                                         close_choice=1,
                                         title='Output Folder Does Not Exist',
                                         details=folder) == 0:
                    try:
                        os.makedirs(folder)
                    except Exception as e:
                        hou.ui.displayMessage(
                            folder,
                            buttons=('Abort', ),
                            default_choice=0,
                            close_choice=1,
                            title='Error Creating Output Folder',
                            details=str(e))
                        return
                    if not os.path.isdir(folder):
                        hou.ui.displayMessage(
                            folder,
                            buttons=('Abort', ),
                            default_choice=0,
                            close_choice=1,
                            title='Can`t Create Output Folder',
                            details=folder)
                        return
                else:
                    return

        self.valid = True
Exemplo n.º 10
0
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):

    params = []

    if ropnode is not None and ropnode.type().name() == 'ifd' and afnode.parm(
            'sep_enable').eval():
        # Case mantra separate render:

        run_rop = afnode.parm('sep_run_rop').eval()
        read_rop = afnode.parm('sep_read_rop_params').eval()
        join_render = afnode.parm('sep_join').eval()
        tile_render = afnode.parm('sep_tile').eval()
        tile_divx = afnode.parm('sep_tile_divx').eval()
        tile_divy = afnode.parm('sep_tile_divy').eval()
        tiles_count = tile_divx * tile_divy
        tiles_stitch_service = afnode.parm('tiles_stitch_service').eval()
        tiles_stitch_capacity = afnode.parm('tiles_stitch_capacity').eval()
        del_rop_files = afnode.parm('sep_del_rop_files').eval()

        if not run_rop:
            join_render = False

        block_generate = BlockParameters(afnode, ropnode, join_render == False,
                                         prefix, frame_range)
        blockname = block_generate.name

        if not block_generate.valid:
            block_generate.doPost()
            return None

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage('Can`t find ROP for processing "%s"' %
                                      afnode.path())

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      block_generate.ropnode.path())

        if join_render:
            block_generate.name += '-Separate'
            tile_render = False
        else:
            block_generate.name += '-GenIFD'

            # Get some generation specific parameters:
            capacity = int(afnode.parm('sep_gen_capacity').eval())
            hosts_mask = str(afnode.parm('sep_gen_hosts_mask').eval())
            hosts_exclude = str(
                afnode.parm('sep_gen_hosts_mask_exclude').eval())
            max_runtasks = int(afnode.parm('sep_gen_max_runtasks').eval())
            maxperhost = int(afnode.parm('sep_gen_maxperhost').eval())
            min_memory = int(afnode.parm('sep_gen_min_memory').eval())
            if capacity > 0:
                block_generate.capacity = capacity
            if hosts_mask != '':
                block_generate.hosts_mask = hosts_mask
            if hosts_exclude != '':
                block_generate.hosts_mask_exclude = hosts_exclude
            if max_runtasks > -1:
                block_generate.max_runtasks = max_runtasks
            if maxperhost > -1:
                block_generate.maxperhost = maxperhost
            if min_memory > -1:
                block_generate.min_memory = min_memory

            if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm('soho_outputmode').set(1)
                block_generate.soho_outputmode = 0

                # We use unexpandedString() here to keep $F4 as expression.
                # If we eval() the value,
                # we will 'bake' the frame number when user submit the job.
                block_generate.ropnode.parm('soho_diskfile').set(
                    block_generate.ropnode.parm(
                        'vm_picture').unexpandedString() + '.ifd')

        if read_rop:
            parm_images = ropnode.parm('vm_picture')
            parm_files = ropnode.parm('soho_diskfile')
        else:
            parm_images = afnode.parm('sep_images')
            parm_files = afnode.parm('sep_files')

        images = afcommon.patternFromPaths(
            parm_images.evalAsStringAtFrame(block_generate.frame_first),
            parm_images.evalAsStringAtFrame(block_generate.frame_last))

        files = afcommon.patternFromPaths(
            parm_files.evalAsStringAtFrame(block_generate.frame_first),
            parm_files.evalAsStringAtFrame(block_generate.frame_last))

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.service = 'hbatch'
                block_generate.tickets = {'HYTHON': 1}
            else:
                block_generate.service = 'hbatch_mantra'
                block_generate.tickets = {'HYTHON': 1, 'MANTRA': 1}
                block_generate.cmd = block_generate.cmd.replace(
                    'hrender_af', 'hrender_separate')

        if not join_render:
            block_render = BlockParameters(afnode, ropnode, subblock, prefix,
                                           frame_range)
            block_render.cmd = 'mantra'
            block_render.service = 'mantra'
            block_render.tickets = {'MANTRA': 1}

            if run_rop:
                block_render.dependmask = block_generate.name

            if del_rop_files:
                block_render.delete_files.append(files)

            if tile_render:
                block_render.name = blockname + '-TileRender'
                block_render.numeric = False
                block_render.cmd += ' -t count=%(tile_divx)dx%(tile_divy)d,index=@#@' % vars(
                )
                block_render.frame_pertask = -tiles_count
                for frame in range(block_generate.frame_first,
                                   block_generate.frame_last + 1,
                                   block_generate.frame_inc):
                    arguments = afnode.parm(
                        'sep_render_arguments').evalAsStringAtFrame(frame)
                    arguments = arguments.replace(
                        '@FILES@', parm_files.evalAsStringAtFrame(frame))

                    for tile in range(0, tiles_count):
                        block_render.tasks_names.append('frame %d tile %d' %
                                                        (frame, tile))
                        block_render.tasks_cmds.append('%d %s' %
                                                       (tile, arguments))
            else:
                block_render.name = blockname + '-Render'
                block_render.cmd += ' ' + afcommon.patternFromPaths(
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_first),
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_last)).replace('@FILES@', files)
                block_render.preview = images

        if tile_render:
            cmd = 'itilestitch "%s"' % images
            tile_suffix = '_tile%02d_'
            timg = os.path.relpath(images)

            # Now we should find a dot before frame number,
            # as matra places tile_suffix there.
            tpos = timg.find('@')
            if tpos > 0:
                # We found Afanasy digits pattern start
                tpos -= 1
            else:
                # We do not have Afanay numeric pattern.
                # May be aftist sent just one frame to render.
                name, ext = os.path.splitext(timg)
                # Shitf to name w/o extension
                tpos = len(name) - 1
                # Shift frame digits
                while name[tpos].isdigit() and tpos > 0:
                    tpos -= 1
                # Shitf a dot before frame digits
                if name[tpos] == '.':
                    tpos -= 1
                # It will be used as a length to cut, not as index
                tpos += 1

            # Insert tile suffix
            timg = timg[:tpos] + tile_suffix + timg[tpos:]

            # List all tiles in the command
            for i in range(0, tiles_count):
                cmd += ' "%s"' % (timg % i)

            block_join = BlockParameters(afnode, ropnode, subblock, prefix,
                                         frame_range)

            block_join.name = blockname + '-TilesStitch'
            block_join.service = tiles_stitch_service
            block_join.capacity = tiles_stitch_capacity
            block_join.tickets = dict()
            # block render might be referenced before assignment
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

            # Disable minimum running time as it can be set on Afanasy ROP.
            # As tile stich can be much fast
            block_join.minruntime = 0

            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    elif len(str(afnode.parm('ds_node').eval())):
        # Case distribute simulation:
        ds_node_path = str(afnode.parm('ds_node').eval())
        ds_node = hou.node(ds_node_path)
        if not ds_node:
            hou.ui.displayMessage('No such control node: "%s"' % ds_node_path)
            return
        parms = ['address', 'port', 'slice']
        for parm in parms:
            if not ds_node.parm(parm):
                hou.ui.displayMessage(
                    'Control node "%s" does not have "%s" parameter' %
                    (ds_node_path, parm))
                return

        enable_tracker = not afnode.parm('ds_tracker_manual').eval()
        if enable_tracker:
            # Tracker block:
            par_start = getTrackerParameters(afnode, ropnode, subblock, prefix,
                                             frame_range, True)
            params.append(par_start)

        # A block for each slice:
        ds_num_slices = int(afnode.parm('ds_num_slices').eval())
        for s in range(0, ds_num_slices):
            par = BlockParameters(afnode, ropnode, subblock, prefix,
                                  frame_range)
            sim_blocks_mask = par.name + '.*'
            par.name += '-s%d' % s
            par.frame_pertask = par.frame_last - par.frame_first + 1
            if enable_tracker:
                par.addDependMask(par_start.name)
            par.fullrangedepend = True
            par.auxargs = ' --ds_node "%s"' % ds_node_path
            par.auxargs += ' --ds_address "%s"' % str(
                afnode.parm('ds_address').eval())
            par.auxargs += ' --ds_port %d' % int(afnode.parm('ds_port').eval())
            par.auxargs += ' --ds_slice %d' % s
            params.append(par)

        if enable_tracker:
            # Stop tracker block:
            par_stop = getTrackerParameters(afnode, ropnode, subblock, prefix,
                                            frame_range, False)
            par_stop.addDependMask(sim_blocks_mask)
            params.append(par_stop)

            # Set other block names for start tracker block.
            # As start tracker block will set other block environment
            # to specify started tracker and port.
            par_start.cmd += ' --envblocks "%s|%s"' % (sim_blocks_mask,
                                                       par_stop.name)
            # On this block depend mask will be reset on tracker start:
            par_start.cmd += ' --depblocks "%s"' % sim_blocks_mask

    else:
        params.append(
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range))
    return params
Exemplo n.º 11
0
    def launch(self, *args, **kwargs):
        """launch renderer command
        """
        # do nothing if there is no window (called externally)
        if not self.window:
            return

        # warn the user about the ignore settings
        try:
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            ignore_attrs = [
                'ignoreSubdivision',
                'ignoreDisplacement',
                'ignoreBump',
                'ignoreMotionBlur'
            ]

            attr_values = [
                (attr, dAO.getAttr(attr))
                for attr in ignore_attrs
                if dAO.getAttr(attr) is True
            ]

            if any(attr_values):
                msg_text = '<br>'.join(
                    map(
                        lambda x: '%s: %s' % (x[0], x[1]),
                        attr_values
                    )
                )

                response = pm.confirmDialog(
                    title='Ignore These Settings?',
                    message='You have ignored:<br><br>%s<br><br><b>Is that ok?</b>' % msg_text,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
        except pm.MayaNodeError:
            # no Arnold
            pass

        # check if rendering with persp camera
        try:
            wrong_camera_names = [
                'perspShape',
                'topShape',
                'sideShape',
                'fontShape',

                'persp1Shape',
                'perspShape1',
            ]
            renderable_cameras = [node for node in pm.ls(type='camera') if node.getAttr('renderable')]
            if any(map(lambda x: x.name() in wrong_camera_names, renderable_cameras)):
                response = pm.confirmDialog(
                    title='Rendering with Persp?',
                    message='You are rendering with <b>Persp Camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return

            if len(renderable_cameras) > 1:
                response = pm.confirmDialog(
                    title='Rendering more than one Camera?',
                    message='You are rendering <b>more than one camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No'
                )

                if response == 'No':
                    return
            elif len(renderable_cameras) == 0:
                pm.confirmDialog(
                    title='No <b>Renderable</b> camera!!!',
                    message='There is no <b>renderable camera<b>!!!',
                    button=['Ok'],
                    defaultButton='Ok',
                    cancelButton='Ok',
                    dismissString='Ok'
                )
                return

        except pm.MayaNodeError:
            # no default render globals node
            pass

        drg = pm.PyNode('defaultRenderGlobals')
        render_engine = drg.getAttr('currentRenderer')
        # RENDERER SPECIFIC CHECKS

        if render_engine == 'redshift':
            # if the renderer is RedShift
            # check if unifiedDisableDivision is 1 which will take too much time
            # to render
            dro = pm.PyNode('redshiftOptions')
            if dro.unifiedDisableDivision.get() == 1:
                response = pm.confirmDialog(
                    title="Enabled **Don't Automatically Reduce Samples of Other Effects**",
                    message='It is not allowed to render with the following option is enabled:<br>'
                            '<br>'
                            "Don't Automatically Reduce Samples of Other Effects: Enabled<br>"
                            "<br>"
                            "Please DISABLE it!",
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

        elif render_engine == 'arnold':
            # check if the samples are too high
            dAO = pm.PyNode('defaultArnoldRenderOptions')


            aa_samples = dAO.AASamples.get()
            diff_samples = dAO.GIDiffuseSamples.get()
            glossy_samples = dAO.GIGlossySamples.get()
            if int(pm.about(v=1)) >= 2017:
                sss_samples = dAO.GISssSamples.get()
            else:
                sss_samples = dAO.sssBssrdfSamples.get()

            total_diff_samples = aa_samples**2 * diff_samples**2
            total_glossy_samples = aa_samples**2 * glossy_samples**2
            total_sss_samples = aa_samples**2 * sss_samples**2

            max_allowed_diff_samples = 225
            max_allowed_glossy_samples = 100
            max_allowed_sss_samples = 450

            if total_diff_samples > max_allowed_diff_samples:
                pm.confirmDialog(
                    title="Too Much Diffuse Samples!!!",
                    message='You are using too much DIFFUSE SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of Diffuse '
                            'Samples!!!' % max_allowed_diff_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            if total_glossy_samples > max_allowed_glossy_samples:
                pm.confirmDialog(
                    title="Too Much Glossy Samples!!!",
                    message='You are using too much GLOSSY SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of Glossy '
                            'Samples!!!' % max_allowed_glossy_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            if total_sss_samples > max_allowed_sss_samples:
                pm.confirmDialog(
                    title="Too Much SSS Samples!!!",
                    message='You are using too much SSS SAMPLES (>%s)<br>'
                            '<br>'
                            'Please either reduce AA samples of SSS '
                            'Samples!!!' % max_allowed_sss_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # check Light Samples
            # check point lights with zero radius but more than one samples
            all_point_lights = pm.ls(type='pointLight')
            ridiculous_point_lights = []
            for point_light in all_point_lights:
                if point_light.aiRadius.get() < 0.1 and point_light.aiSamples.get() > 1:
                    ridiculous_point_lights.append(point_light)

            if ridiculous_point_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Point Lights!!!",
                    message='You are using too much SAMPLES (>1)<br>'
                            '<br>'
                            'on <b>Point lights with zero radius</b><br>'
                            '<br>'
                            'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # Check area lights with more than 2 samples
            all_area_lights = pm.ls(type=['areaLight', 'aiAreaLight'])
            ridiculous_area_lights = []
            for area_light in all_area_lights:
                if area_light.aiSamples.get() > 2:
                    ridiculous_area_lights.append(area_light)

            if ridiculous_area_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Area Lights!!!",
                    message='You are using too much SAMPLES (>2) on<br>'
                            '<br>'
                            '<b>Area Lights</b><br>'
                            '<br>'
                            'Please reduce the samples to 2',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

            # Check directional lights with angle == 0 and samples > 1
            all_directional_lights = pm.ls(type='directionalLight')
            ridiculous_directional_lights = []
            for directional_light in all_directional_lights:
                if directional_light.aiAngle.get() == 0 and directional_light.aiSample.get() > 1:
                    ridiculous_directional_lights.append(directional_light)

            if ridiculous_directional_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Directional Lights!!!",
                    message='You are using too much SAMPLES (>1) on <br>'
                            '<br>'
                            '<b>Directional lights with zero angle</b><br>'
                            '<br>'
                            'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK'
                )
                return

        # get values
        start_frame = pm.intField('cgru_afanasy__start_frame', q=1, v=1)
        end_frame = pm.intField('cgru_afanasy__end_frame', q=1, v=1)
        frames_per_task = \
            pm.intField('cgru_afanasy__frames_per_task', q=1, v=1)
        by_frame = pm.intField('cgru_afanasy__by_frame', q=1, v=1)
        hosts_mask = pm.textField('cgru_afanasy__hosts_mask', q=1, text=True)
        hosts_exclude = pm.textField('cgru_afanasy__hosts_exclude', q=1, text=True)
        separate_layers = \
            pm.checkBox('cgru_afanasy__separate_layers', q=1, v=1)
        pause = pm.checkBox('cgru_afanasy__paused', q=1, v=1)
        life_time = pm.intField('cgru_afanasy__life_time', q=1, v=1)

        # check values
        if start_frame > end_frame:
            temp = end_frame
            end_frame = start_frame
            start_frame = temp

        frames_per_task = max(1, frames_per_task)
        by_frame = max(1, by_frame)

        # store without quota sign
        hosts_mask = hosts_mask.replace('"', '')
        hosts_exclude = hosts_exclude.replace('"', '')

        # store field values
        pm.optionVar['cgru_afanasy__start_frame_ov'] = start_frame
        pm.optionVar['cgru_afanasy__end_frame_ov'] = end_frame
        pm.optionVar['cgru_afanasy__frames_per_task_ov'] = frames_per_task
        pm.optionVar['cgru_afanasy__by_frame_ov'] = by_frame
        pm.optionVar['cgru_afanasy__hosts_mask_ov'] = hosts_mask
        pm.optionVar['cgru_afanasy__hosts_exclude_ov'] = hosts_exclude
        pm.optionVar['cgru_afanasy__separate_layers_ov'] = separate_layers
        pm.optionVar['cgru_afanasy__life_time_ov'] = life_time

        # get paths
        scene_name = pm.sceneName()
        datetime = '%s%s' % (
            time.strftime('%y%m%d-%H%M%S-'),
            str(time.time() - int(time.time()))[2:5]
        )

        filename = '%s.%s.mb' % (scene_name, datetime)

        project_path = pm.workspace(q=1, rootDirectory=1)

        outputs = \
            pm.renderSettings(fullPath=1, firstImageName=1, lastImageName=1)

        # job_name = os.path.basename(scene_name)
        job_name = self.generate_job_name()

        logger.debug('%ss %se %sr' % (start_frame, end_frame, by_frame))
        logger.debug('scene        = %s' % scene_name)
        logger.debug('file         = %s' % filename)
        logger.debug('job_name     = %s' % job_name)
        logger.debug('project_path = %s' % project_path)
        logger.debug('outputs      = %s' % outputs)

        if pm.checkBox('cgru_afanasy__close', q=1, v=1):
            pm.deleteUI(self.window)



        job = af.Job(job_name)

        stored_log_level = None
        if render_engine == 'arnold':
            # set the verbosity level to warning+info
            aro = pm.PyNode('defaultArnoldRenderOptions')
            stored_log_level = aro.getAttr('log_verbosity')
            aro.setAttr('log_verbosity', 1)
            # set output to console
            aro.setAttr("log_to_console", 1)
        elif render_engine == 'redshift':
            # set the verbosity level to detailed+info
            redshift = pm.PyNode('redshiftOptions')
            stored_log_level = redshift.logLevel.get()
            redshift.logLevel.set(2)

        # save file
        pm.saveAs(
            filename,
            force=1,
            type='mayaBinary'
        )

        # rename back to original name
        pm.renameFile(scene_name)

        # create the render command
        mrc = MayaRenderCommandBuilder(
            name=job_name, file_full_path=filename,
            render_engine=render_engine, project=project_path,
            by_frame=by_frame
        )

        # submit renders
        blocks = []
        if separate_layers:
            # render each layer separately
            rlm = pm.PyNode('renderLayerManager')
            layers = [layer for layer in rlm.connections()
                      if layer.renderable.get()]

            for layer in layers:
                mrc_layer = copy.copy(mrc)
                layer_name = layer.name()
                mrc_layer.name = layer_name
                mrc_layer.render_layer = layer_name

                # create a new block for this layer
                block = af.Block(
                    layer_name,
                    renderer_to_block_type.get(render_engine, 'maya')
                )

                block.setFiles(
                    afcommon.patternFromDigits(
                        afcommon.patternFromStdC(
                            afcommon.patternFromPaths(outputs[0], outputs[1])
                        )
                    ).split(';')
                )
                block.setNumeric(
                    start_frame, end_frame, frames_per_task, by_frame
                )
                block.setCommand(mrc_layer.build_command())

                blocks.append(block)
        else:
            # create only one block
            block = af.Block(
                'All Layers',
                renderer_to_block_type.get(render_engine, 'maya')
            )

            block.setFiles(
                afcommon.patternFromDigits(
                    afcommon.patternFromStdC(
                        afcommon.patternFromPaths(outputs[0], outputs[1])
                    )
                ).split(';')
            )
            block.setNumeric(
                start_frame, end_frame, frames_per_task, by_frame
            )
            block.setCommand(mrc.build_command())

            blocks.append(block)

        job.setFolder('input', os.path.dirname(filename))
        job.setFolder('output', os.path.dirname(outputs[0]))
        job.setHostsMask(hosts_mask)
        job.setHostsMaskExclude(hosts_exclude)
        if life_time > 0:
            job.setTimeLife(life_time * 3600)

        job.setCmdPost('deletefiles "%s"' % os.path.abspath(filename))
        if pause:
            job.offline()

        # add blocks
        job.blocks.extend(blocks)

        status, data = job.send()
        if not status:
            pm.PopupError('Something went wrong!')
        print('data: %s' % data)

        # restore log level
        if render_engine == 'arnold':
            aro = pm.PyNode('defaultArnoldRenderOptions')
            aro.setAttr('log_verbosity', stored_log_level)
            # disable set output to console
            aro.setAttr("log_to_console", 0)
        elif render_engine == 'redshift':
            redshift = pm.PyNode('redshiftOptions')
            redshift.logLevel.set(stored_log_level)
Exemplo n.º 12
0
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):

    params = []

    if ropnode is not None and ropnode.type().name() == "ifd" and afnode.parm("sep_enable").eval():
        # Case mantra separate render:

        block_generate = BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        blockname = block_generate.name
        block_generate.name += "-G"

        if not block_generate.valid:
            return None

        run_rop = afnode.parm("sep_run_rop").eval()
        read_rop = afnode.parm("sep_read_rop_params").eval()
        join_render = afnode.parm("sep_join").eval()
        tile_render = afnode.parm("sep_tile").eval()
        tile_divx = afnode.parm("sep_tile_divx").eval()
        tile_divy = afnode.parm("sep_tile_divy").eval()
        use_tmp_img_folder = afnode.parm("sep_use_tmp_img_folder").eval()
        del_rop_files = afnode.parm("sep_del_rop_files").eval()

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage('Can`t find ROP for processing "%s"' % afnode.path())

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' % block_generate.ropnode.path())

        if not run_rop:
            join_render = False

        if join_render:
            tile_render = False
        else:
            if block_generate.ropnode.parm("soho_outputmode").eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm("soho_outputmode").set(1)
                block_generate.soho_outputmode = 0
                block_generate.ropnode.parm("soho_diskfile").set(
                    block_generate.ropnode.parm("vm_picture").unexpandedString() + ".ifd"
                )

        if read_rop:
            images = ropnode.parm("vm_picture")
            files = ropnode.parm("soho_diskfile")
            afnode.parm("sep_images").set(images.unexpandedString())
            afnode.parm("sep_files").set(files.unexpandedString())

        images = afcommon.patternFromPaths(
            afnode.parm("sep_images").evalAsStringAtFrame(block_generate.frame_first),
            afnode.parm("sep_images").evalAsStringAtFrame(block_generate.frame_last),
        )

        files = afcommon.patternFromPaths(
            afnode.parm("sep_files").evalAsStringAtFrame(block_generate.frame_first),
            afnode.parm("sep_files").evalAsStringAtFrame(block_generate.frame_last),
        )

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.service = "hbatch"
            else:
                block_generate.service = "hbatch_mantra"
                block_generate.cmd = block_generate.cmd.replace("hrender_af", "hrender_separate")

                if use_tmp_img_folder:
                    block_generate.cmd += " --tmpimg"

        if not join_render:
            tiles = tile_divx * tile_divy
            block_render = BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
            block_render.name = blockname + "-R"
            block_render.cmd = "mantra"
            block_render.service = block_render.cmd
            if run_rop:
                block_render.dependmask = block_generate.name

            if tile_render or del_rop_files or use_tmp_img_folder:
                block_render.cmd = "mantrarender "

            if del_rop_files:
                block_render.delete_files.append(files)

            if use_tmp_img_folder:
                block_render.cmd += "t"

            if tile_render:
                block_render.numeric = False
                block_render.cmd += "c %(tile_divx)d %(tile_divy)d" % vars()
                block_render.cmd += " @#@"
                block_render.frame_pertask = -tiles
                for frame in range(block_generate.frame_first, block_generate.frame_last + 1, block_generate.frame_inc):
                    arguments = afnode.parm("sep_render_arguments").evalAsStringAtFrame(frame)
                    for tile in range(0, tiles):
                        block_render.tasks_names.append("%d tile %d" % (frame, tile))
                        block_render.tasks_cmds.append("%d -R %s" % (tile, arguments))
            else:
                if del_rop_files or use_tmp_img_folder:
                    block_render.cmd += " -R "
                else:
                    block_render.cmd += " -V a "
                block_render.cmd += afcommon.patternFromPaths(
                    afnode.parm("sep_render_arguments").evalAsStringAtFrame(block_generate.frame_first),
                    afnode.parm("sep_render_arguments").evalAsStringAtFrame(block_generate.frame_last),
                )
                block_render.preview = images

        if tile_render:
            cmd = "exrjoin %(tile_divx)d %(tile_divy)d %(images)s d" % vars()

            block_join = BlockParameters(afnode, ropnode, subblock, prefix, frame_range)

            block_join.name = blockname + "-J"
            block_join.service = "generic"
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

        if read_rop:
            afnode.parm("sep_images").set("")
            afnode.parm("sep_files").set("")

        if tile_render:
            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    elif len(str(afnode.parm("ds_node").eval())):
        # Case distribute simulation:
        ds_node_path = str(afnode.parm("ds_node").eval())
        ds_node = hou.node(ds_node_path)
        if not ds_node:
            hou.ui.displayMessage('No such control node: "%s"' % ds_node_path)
            return
        parms = ["address", "port", "slice"]
        for parm in parms:
            if not ds_node.parm(parm):
                hou.ui.displayMessage('Control node "%s" does not have "%s" parameter' % (ds_node_path, parm))
                return

        enable_tracker = not afnode.parm("ds_tracker_manual").eval()
        if enable_tracker:
            # Tracker block:
            par_start = getTrackerParameters(afnode, ropnode, subblock, prefix, frame_range, True)
            params.append(par_start)

        # A block for each slice:
        ds_num_slices = int(afnode.parm("ds_num_slices").eval())
        stop_dep_mask = None
        for s in range(0, ds_num_slices):
            par = BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
            sim_blocks_mask = par.name + ".*"
            par.name += "-s%d" % s
            par.frame_pertask = par.frame_last - par.frame_first + 1
            if enable_tracker:
                par.addDependMask(par_start.name)
            par.fullrangedepend = True
            par.auxargs = ' --ds_node "%s"' % ds_node_path
            par.auxargs += ' --ds_address "%s"' % str(afnode.parm("ds_address").eval())
            par.auxargs += " --ds_port %d" % int(afnode.parm("ds_port").eval())
            par.auxargs += " --ds_slice %d" % s
            params.append(par)

        if enable_tracker:
            # Stop tracker block:
            par_stop = getTrackerParameters(afnode, ropnode, subblock, prefix, frame_range, False)
            par_stop.addDependMask(sim_blocks_mask)
            params.append(par_stop)

            # Set other block names for start tracker block.
            # As start tracker block will set other block environment
            # to specify started tracker and port.
            par_start.cmd += ' --envblocks "%s|%s"' % (sim_blocks_mask, par_stop.name)
            # On this block depend mask will be reset on tracker start:
            par_start.cmd += ' --depblocks "%s"' % sim_blocks_mask

    else:
        params.append(BlockParameters(afnode, ropnode, subblock, prefix, frame_range))
    return params
Exemplo n.º 13
0
    def __init__(self, afnode, ropnode, subblock, prefix, frame_range, for_job_only=False):
        if VERBOSE == 2:
            if ropnode:
                print('Initializing block parameters for "%s" from "%s"' % (ropnode.path(), afnode.path()))
            else:
                print('Initializing command block parameters from "%s"' % afnode.path())

        # Init parameters:
        self.valid = False
        self.afnode = afnode
        self.ropnode = None
        self.subblock = subblock
        self.frame_pertask = 1
        self.frame_sequential = 1
        self.prefix = prefix
        self.preview = ""
        self.name = ""
        self.service = ""
        self.parser = ""
        self.cmd = ""
        self.cmd_useprefix = True
        self.dependmask = ""
        self.fullrangedepend = False
        self.numeric = True
        self.frame_first, self.frame_last, self.frame_inc = frame_range
        self.auxargs = ""
        self.tasks_names = []
        self.tasks_cmds = []
        self.tasks_previews = []
        # Fill in this array with files to delete in a block post command.
        # Files should have a common afanasy "@#*@" pattern,
        # it will be replaced with "*" for shell.
        self.delete_files = []
        # Parameters to restore ROP changes:
        self.soho_foreground = None
        self.soho_outputmode = None

        # Get parameters:
        self.frame_pertask = int(afnode.parm("frame_pertask").eval())
        self.frame_sequential = int(afnode.parm("frame_sequential").eval())
        self.job_name = str(afnode.parm("job_name").eval())
        self.start_paused = int(afnode.parm("start_paused").eval())
        self.platform = str(afnode.parm("platform").eval())
        self.subtaskdepend = int(afnode.parm("subtaskdepend").eval())
        self.priority = -1
        self.max_runtasks = -1
        self.maxperhost = -1
        self.maxruntime = -1
        self.capacity = -1
        self.capacity_min = -1
        self.capacity_max = -1
        self.hosts_mask = ""
        self.hosts_mask_exclude = ""
        self.depend_mask = ""
        self.depend_mask_global = ""
        self.min_memory = -1
        self.preview_approval = afnode.parm("preview_approval").eval()

        if afnode.parm("enable_extended_parameters").eval():
            self.parser = self.afnode.parm("override_parser").eval()
            self.priority = int(afnode.parm("priority").eval())
            self.max_runtasks = int(afnode.parm("max_runtasks").eval())
            self.maxperhost = int(afnode.parm("maxperhost").eval())
            self.maxruntime = int(afnode.parm("maxruntime").eval())
            self.min_memory = int(afnode.parm("min_memory").eval())
            self.capacity = int(afnode.parm("capacity").eval())
            self.capacity_min = int(afnode.parm("capacity_coefficient1").eval())
            self.capacity_max = int(afnode.parm("capacity_coefficient2").eval())
            self.hosts_mask = str(afnode.parm("hosts_mask").eval())
            self.hosts_mask_exclude = str(afnode.parm("hosts_mask_exclude").eval())
            self.depend_mask = str(afnode.parm("depend_mask").eval())
            self.depend_mask_global = str(afnode.parm("depend_mask_global").eval())

        # Process frame range:
        opname = afnode.path()
        if afnode.parm("trange").eval() > 1:
            self.fullrangedepend = True

        if ropnode:
            opname = ropnode.path()
            trange = ropnode.parm("trange")

            if trange is not None:
                if int(trange.eval()) > 0:
                    if ropnode.parm("f1") is not None:
                        self.frame_first = int(ropnode.parm("f1").eval())

                    if ropnode.parm("f2") is not None:
                        self.frame_last = int(ropnode.parm("f2").eval())

                    if ropnode.parm("f3") is not None:
                        self.frame_inc = int(ropnode.parm("f3").eval())

                if int(trange.eval()) > 1:
                    self.fullrangedepend = True

        if self.frame_last < self.frame_first:
            hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
            return

        if self.frame_inc < 1:
            hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
            return

        if self.frame_pertask < 1:
            hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
            return

        # Process output driver type to construct a command:
        if ropnode:
            self.service = "hbatch"

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' % ropnode.path())
                return

            self.ropnode = ropnode
            self.name = str(ropnode.name())

            if self.prefix != "":
                self.name = "%s_%s" % (self.prefix, self.name)
            # Block type and preview:
            roptype = ropnode.type().name()

            if roptype == "ifd":
                if not ropnode.parm("soho_outputmode").eval():
                    self.service = "hbatch_mantra"

                vm_picture = ropnode.parm("vm_picture")

                if vm_picture is not None:
                    self.preview = afcommon.patternFromPaths(
                        vm_picture.evalAsStringAtFrame(self.frame_first),
                        vm_picture.evalAsStringAtFrame(self.frame_last),
                    )
            elif roptype == "rib":
                self.service = "hbatch_prman"

            # Block command:
            self.cmd = "hrender_af"
            if afnode.parm("ignore_inputs").eval():
                self.cmd += " -i"

            if self.capacity_min != -1 or self.capacity_max != -1:
                self.cmd += " --numcpus " + services.service.str_capacity

            self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (self.frame_inc, afnode.parm("take").eval())

            numWedges = computeWedge(ropnode, roptype)
            if numWedges:
                self.frame_first = 0
                self.frame_last = numWedges - 1
                self.frame_inc = 1
                self.frame_pertask = 1
                self.parser = "mantra"

            self.cmd += "%(auxargs)s"
            self.cmd += ' "%(hipfilename)s"'
            self.cmd += ' "%s"' % ropnode.path()

            if afnode.parm("enable_extended_parameters").eval():
                # Override service:
                override_service = self.afnode.parm("override_service").eval()
                if override_service is not None and len(override_service):
                    self.service = override_service

        else:
            # Custom command driver:
            if int(afnode.parm("cmd_mode").eval()):
                # Command:
                cmd = self.afnode.parm("cmd_cmd")
                self.cmd = afcommon.patternFromPaths(
                    cmd.evalAsStringAtFrame(self.frame_first), cmd.evalAsStringAtFrame(self.frame_last)
                )

                # Name:
                self.name = self.afnode.parm("cmd_name").eval()
                if self.name is None or self.name == "":
                    self.name = self.cmd.split(" ")[0]

                # Service:
                self.service = self.afnode.parm("cmd_service").eval()
                if self.service is None or self.service == "":
                    self.service = self.cmd.split(" ")[0]
                # Parser:
                self.parser = self.afnode.parm("cmd_parser").eval()

                # Prefix:
                self.cmd_useprefix = int(self.afnode.parm("cmd_use_afcmdprefix").eval())

                # Delete files on job deletion:
                if self.afnode.parm("cmd_delete_files").eval():
                    cmd_files = self.afnode.parm("cmd_files")
                    self.delete_files.append(
                        afcommon.patternFromPaths(
                            cmd_files.evalAsStringAtFrame(self.frame_first),
                            cmd_files.evalAsStringAtFrame(self.frame_last),
                        )
                    )

            elif not for_job_only:
                hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
                return

        # Try to set driver foreground mode
        if ropnode:
            trange = ropnode.parm("trange")
            soho_foreground = ropnode.parm("soho_foreground")
            if trange is not None and int(trange.eval()) == 0:
                if soho_foreground is not None:
                    if soho_foreground.eval() == 0:
                        try:
                            soho_foreground.set(1)
                            self.soho_foreground = 0
                        except:  # TODO: too broad exception clause
                            hou.ui.displayMessage('Set "Block Until Render Complete" on "%s" ' "node" % ropnode.path())
                            return

        # Try to create output folder:
        if self.preview != "" and afnode.parm("check_output_folder").eval():
            folder = os.path.dirname(self.preview)
            if not os.path.isdir(folder):
                if (
                    hou.ui.displayMessage(
                        folder,
                        buttons=("Create", "Abort"),
                        default_choice=0,
                        close_choice=1,
                        title="Output Folder Does Not Exist",
                        details=folder,
                    )
                    == 0
                ):
                    try:
                        os.makedirs(folder)
                    except Exception as e:
                        hou.ui.displayMessage(
                            folder,
                            buttons=("Abort",),
                            default_choice=0,
                            close_choice=1,
                            title="Error Creating Output Folder",
                            details=str(e),
                        )
                        return
                    if not os.path.isdir(folder):
                        hou.ui.displayMessage(
                            folder,
                            buttons=("Abort",),
                            default_choice=0,
                            close_choice=1,
                            title="Can`t Create Output Folder",
                            details=folder,
                        )
                        return
                else:
                    return

        self.valid = True
Exemplo n.º 14
0
import os
import sys

import afcommon

if len(sys.argv) < 2:
    print('\nUsage: To check common functions class launch:')
    print('%s [func] [args...]\n' % os.path.basename(sys.argv[0]))
    sys.exit(1)

if sys.argv[1] == 'pat2':
    if len(sys.argv) < 4:
        print('Usage: %s %s str1 str2' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.patternFromPaths(sys.argv[2], sys.argv[3]))
elif sys.argv[1] == 'fillnum':
    if len(sys.argv) < 5:
        print('Usage: %s %s pattern start end' % (sys.argv[0], sys.argv[1]))
    else:
        print(
            afcommon.fillNumbers(sys.argv[2], int(sys.argv[3]),
                                 int(sys.argv[4])))
elif sys.argv[1] == 'patc':
    if len(sys.argv) < 3:
        print('Usage: %s %s str' % (sys.argv[0], sys.argv[1]))
    else:
        print(afcommon.patternFromStdC(sys.argv[2], True))
elif sys.argv[1] == 'patd':
    if len(sys.argv) < 3:
        print('Usage: %s %s str' % (sys.argv[0], sys.argv[1]))
Exemplo n.º 15
0
	def __init__(self, afnode, ropnode, subblock, prefix, frame_range, for_job_only=False):
		if VERBOSE == 2:
			if ropnode:
				print('Initializing block parameters for "%s" from "%s"' %
					  (ropnode.path(), afnode.path()))
			else:
				print('Initializing command block parameters from "%s"' %
					  afnode.path())

		# Init parameters:
		self.valid = False
		self.afnode = afnode
		self.ropnode = None
		self.subblock = subblock
		self.frame_pertask = 1
		self.frame_sequential = 1
		self.prefix = prefix
		self.preview = ''
		self.name = ''
		self.type = ''
		self.parser = ''
		self.cmd = ''
		self.cmd_useprefix = True
		self.dependmask = ''
		self.fullrangedepend = False
		self.numeric = True
		self.frame_first, self.frame_last, self.frame_inc = frame_range
		self.tasks_names = []
		self.tasks_cmds = []
		self.tasks_previews = []
		# Parameters to restore ROP changes:
		self.soho_foreground = None
		self.soho_outputmode = None
		# ############################################################################
		# Dict of parameters to restore ROP changes: added by DavidPower
		self.param_restoreList = {}
		# ############################################################################

		# Get parameters:
		self.frame_pertask = int(afnode.parm('frame_pertask').eval())
		self.frame_sequential = int(afnode.parm('frame_sequential').eval())
		self.job_name = str(afnode.parm('job_name').eval())
		self.start_paused = int(afnode.parm('start_paused').eval())
		self.platform = str(afnode.parm('platform').eval())
		self.subtaskdepend = int(afnode.parm('subtaskdepend').eval())
		self.parser = self.afnode.parm('override_parser').eval()
		self.priority = -1
		self.max_runtasks = -1
		self.maxperhost = -1
		self.maxruntime = -1
		self.capacity = -1
		self.capacity_min = -1
		self.capacity_max = -1
		self.hosts_mask = ''
		self.hosts_mask_exclude = ''
		self.depend_mask = ''
		self.depend_mask_global = ''

		if afnode.parm('enable_extended_parameters').eval():
			self.priority = int(afnode.parm('priority').eval())
			self.max_runtasks = int(afnode.parm('max_runtasks').eval())
			self.maxperhost = int(afnode.parm('maxperhost').eval())
			self.maxruntime = int(afnode.parm('maxruntime').eval())
			self.capacity = int(afnode.parm('capacity').eval())
			self.capacity_min = int(
				afnode.parm('capacity_coefficient1').eval())
			self.capacity_max = int(
				afnode.parm('capacity_coefficient2').eval())
			self.hosts_mask = str(afnode.parm('hosts_mask').eval())
			self.hosts_mask_exclude = str(
				afnode.parm('hosts_mask_exclude').eval())
			self.depend_mask = str(afnode.parm('depend_mask').eval())
			self.depend_mask_global = str(
				afnode.parm('depend_mask_global').eval())

		# Process frame range:
		opname = afnode.path()
		if afnode.parm('trange').eval() > 1:
			self.fullrangedepend = True

		if ropnode:
			opname = ropnode.path()
			trange = ropnode.parm('trange')

			if trange is not None:
				if int(trange.eval()) > 0:
					if ropnode.parm('f1') is not None:
						self.frame_first = int(ropnode.parm('f1').eval())

					if ropnode.parm('f2') is not None:
						self.frame_last = int(ropnode.parm('f2').eval())

					if ropnode.parm('f3') is not None:
						self.frame_inc = int(ropnode.parm('f3').eval())

				if int(trange.eval()) > 1:
					self.fullrangedepend = True

		if self.frame_last < self.frame_first:
			hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
			return

		if self.frame_inc < 1:
			hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
			return

		if self.frame_pertask < 1:
			hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
			return

		# Process output driver type to construct a command:
		if ropnode:
			self.type = 'hbatch'

			if not isinstance(ropnode, hou.RopNode):
				hou.ui.displayMessage(
					'"%s" is not a ROP node' % ropnode.path()
				)
				return

			self.ropnode = ropnode
			self.name = str(ropnode.name())

			if self.prefix != '':
				self.name = '%s_%s' % (self.prefix, self.name)
			# Block type and preview:
			roptype = ropnode.type().name()

			if roptype == 'ifd':
				if not ropnode.parm('soho_outputmode').eval():
					self.type = 'hbatch_mantra'

				vm_picture = ropnode.parm('vm_picture')

				if vm_picture is not None:
					self.preview = \
						afcommon.patternFromPaths(
							vm_picture.evalAsStringAtFrame(self.frame_first),
							vm_picture.evalAsStringAtFrame(self.frame_last)
						)
			elif roptype == 'rib':
				self.type = 'hbatch_prman'

			# Block command:
			self.cmd = 'hrender_af'
			if afnode.parm('ignore_inputs').eval():
				self.cmd += ' -i'

			if self.capacity_min != -1 or self.capacity_max != -1:
				self.cmd += ' --numcpus ' + services.service.str_capacity

			self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (
				self.frame_inc, afnode.parm('take').eval()
			)

			self.cmd += ' "%(hipfilename)s"'
			self.cmd += ' "%s"' % ropnode.path()

			# Override service:
			override_service = self.afnode.parm('override_service').eval()
			if override_service is not None and len(override_service):
				self.type = override_service

		else:
			# Custom command driver:
			if int(afnode.parm('cmd_mode').eval()):
				# Command:
				cmd = self.afnode.parm('cmd_cmd')
				self.cmd = afcommon.patternFromPaths(
					cmd.evalAsStringAtFrame(self.frame_first),
					cmd.evalAsStringAtFrame(self.frame_last)
				)

				# Name:
				self.name = self.afnode.parm('cmd_name').eval()
				if self.name is None or self.name == '':
					self.name = self.cmd.split(' ')[0]

				# Service:
				self.type = self.afnode.parm('cmd_service').eval()
				if self.type is None or self.type == '':
					self.type = self.cmd.split(' ')[0]
				# Parser:
				self.parser = self.afnode.parm('cmd_parser').eval()

				# Prefix:
				self.cmd_useprefix = \
					int(self.afnode.parm('cmd_use_afcmdprefix').eval())

			elif not for_job_only:
				hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
				return

		# Try to set driver foreground mode
		if ropnode:
			trange = ropnode.parm('trange')
			soho_foreground = ropnode.parm('soho_foreground')
			if trange is not None and int(trange.eval()) == 0:
				
				# ############################################################################
				# fixed [Render Current Frame] error
				# added by DavidPower
				# ############################################################################
				self.frame_first = int(hou.frame())
				self.frame_last = int(hou.frame())
				# ############################################################################

				if soho_foreground is not None:
					if soho_foreground.eval() == 0:
						try:
							soho_foreground.set(1)
							self.soho_foreground = 0
						except:  # TODO: too broad exception clause
							hou.ui.displayMessage(
								'Set "Block Until Render Complete" on "%s" '
								'node' % ropnode.path()
							)
							return

		# Try to create output folder:
		if self.preview != '' and afnode.parm('check_output_folder').eval():
			folder = os.path.dirname( self.preview)
			if not os.path.isdir( folder):
				if hou.ui.displayMessage( folder, buttons=('Create','Abort'),default_choice=0,close_choice=1,
					title='Output Folder Does Not Exist',details=folder) == 0:
					try:
						os.makedirs(folder)
					except Exception as e:
						hou.ui.displayMessage( folder, buttons=('Abort',),default_choice=0,close_choice=1,
							title='Error Creating Output Folder',details=str(e))
						return
					if not os.path.isdir( folder):
						hou.ui.displayMessage( folder, buttons=('Abort',),default_choice=0,close_choice=1,
							title='Can`t Create Output Folder',details=folder)
						return
				else:
					return

		self.valid = True
Exemplo n.º 16
0
    def launch(self, *args, **kwargs):
        """launch renderer command
        """
        # do nothing if there is no window (called externally)
        if not self.window:
            return

        # warn the user about the ignore settings
        try:
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            ignore_attrs = [
                'ignoreSubdivision', 'ignoreDisplacement', 'ignoreBump',
                'ignoreMotionBlur'
            ]

            attr_values = [(attr, dAO.getAttr(attr)) for attr in ignore_attrs
                           if dAO.getAttr(attr) is True]

            if any(attr_values):
                msg_text = '<br>'.join(
                    map(lambda x: '%s: %s' % (x[0], x[1]), attr_values))

                response = pm.confirmDialog(
                    title='Ignore These Settings?',
                    message=
                    'You have ignored:<br><br>%s<br><br><b>Is that ok?</b>' %
                    msg_text,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return
        except pm.MayaNodeError:
            # no Arnold
            pass

        # check if rendering with persp camera
        try:
            wrong_camera_names = [
                'perspShape',
                'topShape',
                'sideShape',
                'fontShape',
                'persp1Shape',
                'perspShape1',
            ]
            renderable_cameras = [
                node for node in pm.ls(type='camera')
                if node.getAttr('renderable')
            ]
            if any(
                    map(lambda x: x.name() in wrong_camera_names,
                        renderable_cameras)):
                response = pm.confirmDialog(
                    title='Rendering with Persp?',
                    message=
                    'You are rendering with <b>Persp Camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return

            if len(renderable_cameras) > 1:
                response = pm.confirmDialog(
                    title='Rendering more than one Camera?',
                    message=
                    'You are rendering <b>more than one camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return
            elif len(renderable_cameras) == 0:
                pm.confirmDialog(
                    title='No <b>Renderable</b> camera!!!',
                    message='There is no <b>renderable camera<b>!!!',
                    button=['Ok'],
                    defaultButton='Ok',
                    cancelButton='Ok',
                    dismissString='Ok')
                return

        except pm.MayaNodeError:
            # no default render globals node
            pass

        # get values
        start_frame = pm.intField('cgru_afanasy__start_frame', q=1, v=1)
        end_frame = pm.intField('cgru_afanasy__end_frame', q=1, v=1)
        frames_per_task = \
            pm.intField('cgru_afanasy__frames_per_task', q=1, v=1)
        by_frame = pm.intField('cgru_afanasy__by_frame', q=1, v=1)
        hosts_mask = pm.textField('cgru_afanasy__hosts_mask', q=1, text=True)
        hosts_exclude = pm.textField('cgru_afanasy__hosts_exclude',
                                     q=1,
                                     text=True)
        separate_layers = \
            pm.checkBox('cgru_afanasy__separate_layers', q=1, v=1)
        pause = pm.checkBox('cgru_afanasy__paused', q=1, v=1)
        life_time = pm.intField('cgru_afanasy__life_time', q=1, v=1)

        # check values
        if start_frame > end_frame:
            temp = end_frame
            end_frame = start_frame
            start_frame = temp

        frames_per_task = max(1, frames_per_task)
        by_frame = max(1, by_frame)

        # store without quota sign
        hosts_mask = hosts_mask.replace('"', '')
        hosts_exclude = hosts_exclude.replace('"', '')

        # store field values
        pm.optionVar['cgru_afanasy__start_frame_ov'] = start_frame
        pm.optionVar['cgru_afanasy__end_frame_ov'] = end_frame
        pm.optionVar['cgru_afanasy__frames_per_task_ov'] = frames_per_task
        pm.optionVar['cgru_afanasy__by_frame_ov'] = by_frame
        pm.optionVar['cgru_afanasy__hosts_mask_ov'] = hosts_mask
        pm.optionVar['cgru_afanasy__hosts_exclude_ov'] = hosts_exclude
        pm.optionVar['cgru_afanasy__separate_layers_ov'] = separate_layers
        pm.optionVar['cgru_afanasy__life_time_ov'] = life_time

        # get paths
        scene_name = pm.sceneName()
        datetime = '%s%s' % (time.strftime('%y%m%d-%H%M%S-'),
                             str(time.time() - int(time.time()))[2:5])

        filename = '%s.%s.mb' % (scene_name, datetime)

        project_path = pm.workspace(q=1, rootDirectory=1)

        # get output paths, set the RenderPass token to Beauty,
        # this will at least guarantee to get something
        outputs = \
            pm.renderSettings(
                fullPath=1, firstImageName=1, lastImageName=1,
                leaveUnmatchedTokens=1, customTokenString="RenderPass=Beauty"
            )

        job_name = os.path.basename(scene_name)

        logger.debug('%ss %se %sr' % (start_frame, end_frame, by_frame))
        logger.debug('scene        = %s' % scene_name)
        logger.debug('file         = %s' % filename)
        logger.debug('job_name     = %s' % job_name)
        logger.debug('project_path = %s' % project_path)
        logger.debug('outputs      = %s' % outputs)

        if pm.checkBox('cgru_afanasy__close', q=1, v=1):
            pm.deleteUI(self.window)

        drg = pm.PyNode('defaultRenderGlobals')
        render_engine = drg.getAttr('currentRenderer')

        job = af.Job(job_name)

        stored_log_level = None
        if render_engine == 'arnold':
            # set the verbosity level to warning+info
            aro = pm.PyNode('defaultArnoldRenderOptions')
            stored_log_level = aro.getAttr('log_verbosity')
            aro.setAttr('log_verbosity', 1)
            # set output to console
            aro.setAttr("log_to_console", 1)
        elif render_engine == 'redshift':
            # set the verbosity level to detailed+info
            redshift = pm.PyNode('redshiftOptions')
            stored_log_level = redshift.logLevel.get()
            redshift.logLevel.set(2)

        # save file
        pm.saveAs(filename, force=1, type='mayaBinary')

        # rename back to original name
        pm.renameFile(scene_name)

        # create the render command
        mrc = MayaRenderCommandBuilder(name=job_name,
                                       file_full_path=filename,
                                       render_engine=render_engine,
                                       project=project_path,
                                       by_frame=by_frame)

        # submit renders
        blocks = []
        if separate_layers:
            # render each layer separately
            rlm = pm.PyNode('renderLayerManager')
            layers = [
                layer for layer in rlm.connections() if layer.renderable.get()
            ]

            for layer in layers:
                mrc_layer = copy.copy(mrc)
                layer_name = layer.name()
                mrc_layer.name = layer_name
                mrc_layer.render_layer = layer_name

                # create a new block for this layer
                block = af.Block(
                    layer_name,
                    renderer_to_block_type.get(render_engine, 'maya'))

                block.setFiles(
                    afcommon.patternFromDigits(
                        afcommon.patternFromStdC(
                            afcommon.patternFromPaths(outputs[0],
                                                      outputs[1]))).split(';'))
                block.setNumeric(start_frame, end_frame, frames_per_task,
                                 by_frame)
                block.setCommand(mrc_layer.build_command())

                blocks.append(block)
        else:
            # create only one block
            block = af.Block('All Layers',
                             renderer_to_block_type.get(render_engine, 'maya'))

            block.setFiles(
                afcommon.patternFromDigits(
                    afcommon.patternFromStdC(
                        afcommon.patternFromPaths(outputs[0],
                                                  outputs[1]))).split(';'))
            block.setNumeric(start_frame, end_frame, frames_per_task, by_frame)
            block.setCommand(mrc.build_command())

            blocks.append(block)

        job.setFolder('input', os.path.dirname(filename))
        job.setFolder('output', os.path.dirname(outputs[0]))
        job.setHostsMask(hosts_mask)
        job.setHostsMaskExclude(hosts_exclude)
        if life_time > 0:
            job.setTimeLife(life_time * 3600)

        job.setCmdPost('deletefiles "%s"' % os.path.abspath(filename))
        if pause:
            job.offline()

        # add blocks
        job.blocks.extend(blocks)

        status, data = job.send()
        if not status:
            pm.PopupError('Something went wrong!')
        print('data: %s' % data)

        # restore log level
        if render_engine == 'arnold':
            aro = pm.PyNode('defaultArnoldRenderOptions')
            aro.setAttr('log_verbosity', stored_log_level)
            # disable set output to console
            aro.setAttr("log_to_console", 0)
        elif render_engine == 'redshift':
            redshift = pm.PyNode('redshiftOptions')
            redshift.logLevel.set(stored_log_level)
Exemplo n.º 17
0
   def __init__( self, afnode, ropnode, subblock, prefix, frame_range, for_job_only = False):
      if VERBOSE == 2:
         if ropnode:
            print 'Initializing block parameters for "%s" from "%s"' % (ropnode.path(), afnode.path())
         else:
            print 'Initializing command block parameters from "%s"' % (afnode.path())

      # Init parameters:
      self.valid           = False
      self.afnode          = afnode
      self.ropnode         = None
      self.subblock        = subblock
      self.prefix          = prefix
      self.preview         = ''
      self.name            = ''
      self.type            = ''
      self.cmd             = ''
      self.cmd_useprefix   = True
      self.dependmask      = ''
      self.fullrangedepend = False
      self.numeric         = True
      self.frame_first, self.frame_last, self.frame_inc, self.frame_pertask = frame_range
      self.tasks_names     = []
      self.tasks_cmds      = []
      self.tasks_previews  = []
      # Parameters to restore ROP changes:
      self.soho_foreground = None
      self.soho_outputmode = None

      # Get parameters:
      self.job_name           = str( afnode.parm('job_name').eval())
      self.start_paused       = int( afnode.parm('start_paused').eval())
      self.platform           = str( afnode.parm('platform').eval())
      self.subtaskdepend      = int( afnode.parm('subtaskdepend').eval())
      self.priority           = -1
      self.max_runtasks       = -1
      self.capacity           = -1
      self.capacity_min       = -1
      self.capacity_max       = -1
      self.hosts_mask         = ''
      self.hosts_mask_exclude = ''
      self.depend_mask        = ''
      self.depend_mask_global = ''
      if afnode.parm('enable_extended_parameters').eval():
         self.priority           = int( afnode.parm('priority').eval())
         self.max_runtasks       = int( afnode.parm('max_runtasks').eval())
         self.capacity           = int( afnode.parm('capacity').eval())
         self.capacity_min       = int( afnode.parm('capacity_coefficient1').eval())
         self.capacity_max       = int( afnode.parm('capacity_coefficient2').eval())
         self.hosts_mask         = str( afnode.parm('hosts_mask').eval())
         self.hosts_mask_exclude = str( afnode.parm('hosts_mask_exclude').eval())
         self.depend_mask        = str( afnode.parm('depend_mask').eval())
         self.depend_mask_global = str( afnode.parm('depend_mask_global').eval())

      # Process frame range:
      opname = afnode.path()
      if afnode.parm('trange').eval() > 1: self.fullrangedepend = True
      if ropnode:
         opname = ropnode.path()
         trange = ropnode.parm('trange')
         if trange is not None:
            if int(trange.eval()) > 0:
               if ropnode.parm('f1') is not None: self.frame_first = int( ropnode.parm('f1').eval())
               if ropnode.parm('f2') is not None: self.frame_last  = int( ropnode.parm('f2').eval())
               if ropnode.parm('f3') is not None: self.frame_inc   = int( ropnode.parm('f3').eval())
            if int(trange.eval()) > 1: self.fullrangedepend = True
      if self.frame_last < self.frame_first:
         hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
         return
      if self.frame_inc < 1:
         hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
         return
      if self.frame_pertask < 1:
         hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
         return

      # Process output driver type to construct a command:
      if ropnode:
         self.type = 'hbatch'
         if not isinstance( ropnode, hou.RopNode):
            hou.ui.displayMessage('"%s" is not a ROP node' % ropnode.path())
            return
         self.ropnode = ropnode
         self.name    = str( ropnode.name())
         if self.prefix != '': self.name = self.prefix + '_' + self.name
         # Block type and preview:
         roptype = ropnode.type().name()
         if roptype == 'ifd':
            if not ropnode.parm('soho_outputmode').eval(): self.type = 'hbatch_mantra'
            vm_picture = ropnode.parm('vm_picture')
            if vm_picture != None:
               self.preview = afcommon.patternFromPaths( vm_picture.evalAsStringAtFrame( self.frame_first), vm_picture.evalAsStringAtFrame( self.frame_last))
         elif roptype == 'rib':
            self.type = 'hbatch_prman'
         # Block command:
         self.cmd = 'hrender_af'
         if afnode.parm('ignore_inputs').eval(): self.cmd += ' -i'
         if self.capacity_min != -1 or self.capacity_max != -1: self.cmd += ' --numcpus '+ services.service.str_capacity
         self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (self.frame_inc, afnode.parm('take').eval())
         self.cmd += ' "%(hipfilename)s"'
         self.cmd += ' "%s"' % ropnode.path()
      else:
         # Custom command driver:
         if int( afnode.parm('cmd_add').eval()):
            # Command:
            cmd = self.afnode.parm('cmd_cmd')
            self.cmd = afcommon.patternFromPaths( cmd.evalAsStringAtFrame( self.frame_first), cmd.evalAsStringAtFrame( self.frame_last))
            # Name:
            self.name = self.afnode.parm('cmd_name').eval()
            if self.name is None or self.name == '': self.name = self.cmd.split(' ')[0]
            # Service:
            self.type = self.afnode.parm('cmd_service').eval()
            if self.type is None or self.type == '': self.type = self.cmd.split(' ')[0]
            # Prefix:
            self.cmd_useprefix = int( self.afnode.parm('cmd_use_afcmdprefix').eval())
         elif not for_job_only:
            hou.ui.displayMessage('Can\'t process "%s"' % str(afnode.path()))
            return

      # Try to set driver foreground mode
      if ropnode:
         trange = ropnode.parm('trange')
         soho_foreground = ropnode.parm('soho_foreground')
         if trange != None and int(trange.eval()) == 0:
            if soho_foreground != None:
               if soho_foreground.eval() == 0:
                  try:
                     soho_foreground.set( 1)
                     self.soho_foreground = 0
                  except:
                     hou.ui.displayMessage('Set "Block Until Render Complete" on "%s" node' % ropnode.path())
                     return

      self.valid = True
Exemplo n.º 18
0
    def launch(self, *args, **kwargs):
        """launch renderer command
        """
        # do nothing if there is no window (called externally)
        if not self.window:
            return

        # warn the user about the ignore settings
        try:
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            ignore_attrs = [
                'ignoreSubdivision', 'ignoreDisplacement', 'ignoreBump',
                'ignoreMotionBlur'
            ]

            attr_values = [(attr, dAO.getAttr(attr)) for attr in ignore_attrs
                           if dAO.getAttr(attr) is True]

            if any(attr_values):
                msg_text = '<br>'.join(
                    map(lambda x: '%s: %s' % (x[0], x[1]), attr_values))

                response = pm.confirmDialog(
                    title='Ignore These Settings?',
                    message=
                    'You have ignored:<br><br>%s<br><br><b>Is that ok?</b>' %
                    msg_text,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return
        except (pm.MayaNodeError, pm.MayaAttributeError):
            # no Arnold
            pass

        # check if rendering with persp camera
        try:
            wrong_camera_names = [
                'perspShape',
                'topShape',
                'sideShape',
                'fontShape',
                'persp1Shape',
                'perspShape1',
            ]
            renderable_cameras = [
                node for node in pm.ls(type='camera')
                if node.getAttr('renderable')
            ]
            if any(
                    map(lambda x: x.name() in wrong_camera_names,
                        renderable_cameras)):
                response = pm.confirmDialog(
                    title='Rendering with Persp?',
                    message=
                    'You are rendering with <b>Persp Camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return

            if len(renderable_cameras) > 1:
                response = pm.confirmDialog(
                    title='Rendering more than one Camera?',
                    message=
                    'You are rendering <b>more than one camera<b><br><br>Is that ok?</b>',
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')

                if response == 'No':
                    return
            elif len(renderable_cameras) == 0:
                pm.confirmDialog(
                    title='No <b>Renderable</b> camera!!!',
                    message='There is no <b>renderable camera<b>!!!',
                    button=['Ok'],
                    defaultButton='Ok',
                    cancelButton='Ok',
                    dismissString='Ok')
                return

        except pm.MayaNodeError:
            # no default render globals node
            pass

        drg = pm.PyNode('defaultRenderGlobals')
        render_engine = drg.getAttr('currentRenderer')
        # RENDERER SPECIFIC CHECKS

        if render_engine == 'redshift':
            # if the renderer is RedShift
            # check if unifiedDisableDivision is 1 which will take too much time
            # to render
            dro = pm.PyNode('redshiftOptions')
            if dro.unifiedDisableDivision.get() == 1:
                response = pm.confirmDialog(
                    title=
                    "Enabled **Don't Automatically Reduce Samples of Other Effects**",
                    message=
                    'It is not allowed to render with the following option is enabled:<br>'
                    '<br>'
                    "Don't Automatically Reduce Samples of Other Effects: Enabled<br>"
                    "<br>"
                    "Please DISABLE it!",
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            # Check dome light backgrounds
            domes_to_fix = []
            rs_domes = pm.ls(type='RedshiftDomeLight')
            if rs_domes:
                for rs_dome in rs_domes:
                    if rs_dome.getAttr('background_enable') == 1 \
                       or rs_dome.getAttr('backPlateEnabled') == 1:
                        domes_to_fix.append(rs_dome.name())

            if domes_to_fix:
                message = 'Some DomeLights have <b>BackGround Render ' \
                          'Enabled</b>:' \
                          '<br><br>%s<br><br>' \
                          'Are you Sure?' % '<br>'.join(domes_to_fix)

                response = pm.confirmDialog(
                    title='Dome Lights with Background Enabled?',
                    message=message,
                    button=['Yes', 'No'],
                    defaultButton='No',
                    cancelButton='No',
                    dismissString='No')
                if response == 'No':
                    return

            # abort on license fail
            dro.abortOnLicenseFail.set(1)

        elif render_engine == 'arnold':
            # check if the samples are too high
            dAO = pm.PyNode('defaultArnoldRenderOptions')

            aa_samples = dAO.AASamples.get()
            diff_samples = dAO.GIDiffuseSamples.get()
            try:
                glossy_samples = dAO.GIGlossySamples.get()
            except AttributeError:
                glossy_samples = dAO.GISpecularSamples.get()
            if int(pm.about(v=1)) >= 2017:
                sss_samples = dAO.GISssSamples.get()
            else:
                sss_samples = dAO.sssBssrdfSamples.get()

            total_diff_samples = aa_samples**2 * diff_samples**2
            total_glossy_samples = aa_samples**2 * glossy_samples**2
            total_sss_samples = aa_samples**2 * sss_samples**2

            max_allowed_diff_samples = 225
            max_allowed_glossy_samples = 100
            max_allowed_sss_samples = 800

            if total_diff_samples > max_allowed_diff_samples:
                pm.confirmDialog(
                    title="Too Much Diffuse Samples!!!",
                    message='You are using too much DIFFUSE SAMPLES (>%s)<br>'
                    '<br>'
                    'Please either reduce AA samples of Diffuse '
                    'Samples!!!' % max_allowed_diff_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            if total_glossy_samples > max_allowed_glossy_samples:
                pm.confirmDialog(
                    title="Too Much Glossy Samples!!!",
                    message='You are using too much GLOSSY SAMPLES (>%s)<br>'
                    '<br>'
                    'Please either reduce AA samples of Glossy '
                    'Samples!!!' % max_allowed_glossy_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            if total_sss_samples > max_allowed_sss_samples:
                pm.confirmDialog(
                    title="Too Much SSS Samples!!!",
                    message='You are using too much SSS SAMPLES (>%s)<br>'
                    '<br>'
                    'Please either reduce AA samples of SSS '
                    'Samples!!!' % max_allowed_sss_samples,
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            # check Light Samples
            # check point lights with zero radius but more than one samples
            all_point_lights = pm.ls(type='pointLight')
            ridiculous_point_lights = []
            for point_light in all_point_lights:
                if point_light.aiRadius.get(
                ) < 0.1 and point_light.aiSamples.get() > 1:
                    ridiculous_point_lights.append(point_light)

            if ridiculous_point_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Point Lights!!!",
                    message='You are using too much SAMPLES (>1)<br>'
                    '<br>'
                    'on <b>Point lights with zero radius</b><br>'
                    '<br>'
                    'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            # Check area lights with more than 2 samples
            all_area_lights = pm.ls(type=['areaLight', 'aiAreaLight'])
            ridiculous_area_lights = []
            for area_light in all_area_lights:
                if area_light.aiSamples.get() > 2:
                    ridiculous_area_lights.append(area_light)

            if ridiculous_area_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Area Lights!!!",
                    message='You are using too much SAMPLES (>2) on<br>'
                    '<br>'
                    '<b>Area Lights</b><br>'
                    '<br>'
                    'Please reduce the samples to 2',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

            # Check directional lights with angle == 0 and samples > 1
            all_directional_lights = pm.ls(type='directionalLight')
            ridiculous_directional_lights = []
            dir_sample_attr_name = 'aiSamples'
            # if pm.about(v=1) == "2014":
            #     dir_sample_attr_name = 'aiSamples'

            for directional_light in all_directional_lights:
                if directional_light.aiAngle.get(
                ) == 0 and directional_light.attr(
                        dir_sample_attr_name).get() > 1:
                    ridiculous_directional_lights.append(directional_light)

            if ridiculous_directional_lights:
                pm.confirmDialog(
                    title="Unnecessary Samples on Directional Lights!!!",
                    message='You are using too much SAMPLES (>1) on <br>'
                    '<br>'
                    '<b>Directional lights with zero angle</b><br>'
                    '<br>'
                    'Please reduce the samples to 1',
                    button=['OK'],
                    defaultButton='OK',
                    cancelButton='OK',
                    dismissString='OK')
                return

        # get values
        start_frame = pm.intField('cgru_afanasy__start_frame', q=1, v=1)
        end_frame = pm.intField('cgru_afanasy__end_frame', q=1, v=1)
        frames_per_task = \
            pm.intField('cgru_afanasy__frames_per_task', q=1, v=1)
        by_frame = pm.intField('cgru_afanasy__by_frame', q=1, v=1)
        depend_mask_global = pm.textField('cgru_afanasy__depend_mask_global',
                                          q=1,
                                          text=True)
        hosts_mask = pm.textField('cgru_afanasy__hosts_mask', q=1, text=True)
        hosts_exclude = pm.textField('cgru_afanasy__hosts_exclude',
                                     q=1,
                                     text=True)
        separate_layers = \
            pm.radioButtonGrp('cgru_afanasy__separate_layers', q=1, sl=1)
        pause = pm.checkBox('cgru_afanasy__paused', q=1, v=1)
        life_time = pm.intField('cgru_afanasy__life_time', q=1, v=1)
        annotation = pm.textField('cgru_afanasy__annotation', q=1, text=True)
        submit_multiple_times = pm.intField(
            'cgru_afanasy__submit_multiple_times', q=1, v=1)
        errors_avoid_host = pm.intField('cgru_afanasy__errors_avoid_host',
                                        q=1,
                                        v=1)
        errors_retries = pm.intField('cgru_afanasy__errors_retries', q=1, v=1)
        errors_task_same_host = pm.intField(
            'cgru_afanasy__errors_task_same_host', q=1, v=1)
        errors_forgive_time = pm.intField('cgru_afanasy__errors_forgive_time',
                                          q=1,
                                          v=1)

        generate_previews = pm.checkBox('cgru_afanasy__generate_previews',
                                        q=1,
                                        v=1)

        # check values
        if start_frame > end_frame:
            temp = end_frame
            end_frame = start_frame
            start_frame = temp

        frames_per_task = max(1, frames_per_task)
        by_frame = max(1, by_frame)

        # store without quota sign
        depend_mask_global = depend_mask_global.replace('"', '')
        hosts_mask = hosts_mask.replace('"', '')
        hosts_exclude = hosts_exclude.replace('"', '')

        # store field values
        pm.optionVar['cgru_afanasy__start_frame_ov'] = start_frame
        pm.optionVar['cgru_afanasy__end_frame_ov'] = end_frame
        pm.optionVar['cgru_afanasy__frames_per_task_ov'] = frames_per_task
        pm.optionVar['cgru_afanasy__by_frame_ov'] = by_frame
        pm.optionVar['cgru_afanasy__depend_mask_global_ov'] = \
            depend_mask_global
        pm.optionVar['cgru_afanasy__hosts_mask_ov'] = hosts_mask
        pm.optionVar['cgru_afanasy__hosts_exclude_ov'] = hosts_exclude
        pm.optionVar['cgru_afanasy__separate_layers_ov'] = separate_layers
        pm.optionVar['cgru_afanasy__life_time_ov'] = life_time
        pm.optionVar['cgru_afanasy__annotation_ov'] = annotation

        pm.optionVar[
            'cgru_afanasy__submit_multiple_times_ov'] = submit_multiple_times
        pm.optionVar['cgru_afanasy__errors_avoid_host_ov'] = errors_avoid_host
        pm.optionVar['cgru_afanasy__errors_retries_ov'] = errors_retries
        pm.optionVar[
            'cgru_afanasy__errors_task_same_host_ov'] = errors_task_same_host
        pm.optionVar[
            'cgru_afanasy__errors_errors_forgive_time_ov'] = errors_forgive_time
        pm.optionVar['cgru_afanasy__paused_ov'] = pause

        pm.optionVar['cgru_afanasy__generate_previews_ov'] = generate_previews

        # get paths
        scene_name = pm.sceneName()
        datetime = '%s%s' % (time.strftime('%y%m%d-%H%M%S-'),
                             str(time.time() - int(time.time()))[2:5])

        filename = '%s.%s.mb' % (scene_name, datetime)

        project_path = pm.workspace(q=1, rootDirectory=1)

        # outputs = \
        #     pm.renderSettings(fullPath=1, firstImageName=1, lastImageName=1)

        # get output paths, set the RenderPass token to Beauty,
        # this will at least guarantee to get something
        outputs = \
            pm.renderSettings(
                fullPath=1, firstImageName=1, lastImageName=1,
                leaveUnmatchedTokens=1, customTokenString="RenderPass=Beauty"
            )

        # job_name = os.path.basename(scene_name)
        job_name = self.generate_job_name()

        logger.debug('%ss %se %sr' % (start_frame, end_frame, by_frame))
        logger.debug('scene                 = %s' % scene_name)
        logger.debug('file                  = %s' % filename)
        logger.debug('job_name              = %s' % job_name)
        logger.debug('project_path          = %s' % project_path)
        logger.debug('outputs               = %s' % outputs)
        logger.debug('annotation            = %s' % annotation)
        logger.debug('separate_layers       = %s' % separate_layers)
        logger.debug('errors_avoid_host     = %s' % errors_avoid_host)
        logger.debug('errors_retries        = %s' % errors_retries)
        logger.debug('errors_task_same_host = %s' % errors_task_same_host)
        logger.debug('errors_forgive_time   = %s' % errors_forgive_time)
        logger.debug('generate_previews     = %s' % generate_previews)

        if pm.checkBox('cgru_afanasy__close', q=1, v=1):
            pm.deleteUI(self.window)

        stored_log_level = None
        if render_engine == 'arnold':
            # set the verbosity level to warning+info
            aro = pm.PyNode('defaultArnoldRenderOptions')
            stored_log_level = aro.getAttr('log_verbosity')
            aro.setAttr('log_verbosity', 2)
            # set output to console
            aro.setAttr("log_to_console", 1)
        elif render_engine == 'redshift':
            # set the verbosity level to detailed+info
            redshift = pm.PyNode('redshiftOptions')
            stored_log_level = redshift.logLevel.get()
            redshift.logLevel.set(2)

        # save file
        pm.saveAs(filename, force=1, type='mayaBinary')

        # rename back to original name
        pm.renameFile(scene_name)

        # create the render command
        mrc = MayaRenderCommandBuilder(name=job_name,
                                       file_full_path=filename,
                                       render_engine=render_engine,
                                       project=project_path,
                                       by_frame=by_frame)

        # submit renders
        jobs = []
        blocks = []

        #
        # separate_layers:
        # 1 -> None  -> submit one job with a single block with all layers
        # 2 -> Block -> submit one job with multiple blocks
        # 3 -> Job   -> submit multiple jobs with a single block per layer
        #
        if separate_layers in [1, 2]:
            job = af.Job(job_name)
            jobs.append(job)

        if separate_layers in [2, 3]:
            # render each layer separately
            rlm = pm.PyNode('renderLayerManager')
            layers = [
                layer for layer in rlm.connections(type=pm.nt.RenderLayer)
                if layer.renderable.get()
            ]

            for layer in layers:
                mrc_layer = copy.copy(mrc)
                layer_name = layer.name()
                mrc_layer.name = layer_name
                mrc_layer.render_layer = layer_name

                # create a new block for this layer
                block = af.Block(
                    layer_name,
                    renderer_to_block_type.get(render_engine, 'maya'))

                # Fix the output path for this layer
                # by replacing the "masterLayer" with the layer name
                # without rs_ at the beginning
                layer_outputs = outputs
                if layer_name != 'defaultRenderLayer':
                    layer_outputs[0] = outputs[0].replace(
                        'masterLayer', layer_name.replace('rs_', ''))
                    layer_outputs[1] = outputs[1].replace(
                        'masterLayer', layer_name.replace('rs_', ''))

                if generate_previews:
                    outputs_split = afcommon.patternFromDigits(
                        afcommon.patternFromStdC(
                            afcommon.patternFromPaths(
                                layer_outputs[0],
                                layer_outputs[1]))).split(';')
                    block.setFiles(outputs_split)

                block.setNumeric(start_frame, end_frame, frames_per_task,
                                 by_frame)
                command = mrc_layer.build_command()

                block.setErrorsAvoidHost(errors_avoid_host)
                block.setErrorsRetries(errors_retries)
                block.setErrorsTaskSameHost(errors_task_same_host)
                block.setErrorsForgiveTime(errors_forgive_time)

                block.setCommand(command)

                if separate_layers == 2:
                    blocks.append(block)
                else:
                    job = af.Job('%s - %s' % (job_name, layer_name))
                    # add blocks
                    job.blocks = [block]
                    jobs.append(job)

        else:
            # create only one block
            block = af.Block('All Layers',
                             renderer_to_block_type.get(render_engine, 'maya'))

            if generate_previews:
                block.setFiles(
                    afcommon.patternFromDigits(
                        afcommon.patternFromStdC(
                            afcommon.patternFromPaths(outputs[0],
                                                      outputs[1]))).split(';'))

            block.setNumeric(start_frame, end_frame, frames_per_task, by_frame)
            command = mrc.build_command()
            block.setCommand(command)

            blocks.append(block)

        for job in jobs:
            job.setAnnotation(annotation)
            job.setFolder('input', os.path.dirname(filename))
            job.setFolder('output', os.path.dirname(outputs[0]))
            job.setDependMaskGlobal(depend_mask_global)
            job.setHostsMask(hosts_mask)
            job.setHostsMaskExclude(hosts_exclude)
            if life_time > 0:
                job.setTimeLife(life_time * 3600)
            else:
                job.setTimeLife(240 * 3600)

            job.setCmdPost('deletefiles -s "%s"' % os.path.abspath(filename))
            if pause:
                job.offline()

            # add blocks
            if separate_layers in [1, 2]:
                job.blocks.extend(blocks)

            for i in range(submit_multiple_times):
                orig_job_name = job.data['name']
                job.setName('%s - %03i' % (orig_job_name, i + 1))
                status, data = job.send()

                # restore job name
                job.setName(orig_job_name)
                if not status:
                    pm.PopupError('Something went wrong!')

        # restore log level
        if render_engine == 'arnold':
            aro = pm.PyNode('defaultArnoldRenderOptions')
            aro.setAttr('log_verbosity', stored_log_level)
            # disable set output to console
            aro.setAttr("log_to_console", 0)
        elif render_engine == 'redshift':
            redshift = pm.PyNode('redshiftOptions')
            redshift.logLevel.set(stored_log_level)

            # disable abort on license fail
            redshift.abortOnLicenseFail.set(0)
Exemplo n.º 19
0
def getBlockParameters( afnode, ropnode, subblock, prefix, frame_range):
   params = []
   if ropnode is not None and ropnode.type().name() == 'ifd' and afnode.parm('sep_enable').eval():

      # Mantra separate render:
      block_generate = BlockParameters( afnode, ropnode, subblock, prefix, frame_range)
      blockname = block_generate.name
      block_generate.name += '-G'
      if not block_generate.valid: return None

      run_rop = afnode.parm('sep_run_rop').eval()
      read_rop = afnode.parm('sep_read_rop_params').eval()
      join_render = afnode.parm('sep_join').eval()
      tile_render = afnode.parm('sep_tile').eval()
      tile_divx = afnode.parm('sep_tile_divx').eval()
      tile_divy = afnode.parm('sep_tile_divy').eval()
      use_tmp_img_folder = afnode.parm('sep_use_tmp_img_folder').eval()
      del_rop_files = afnode.parm('sep_del_rop_files').eval()

      if read_rop or run_rop:
         if not block_generate.ropnode:
            hou.ui.displayMessage('Can`t find ROP for processing "%s"' % afnode.path())
         if not isinstance( ropnode, hou.RopNode):
            hou.ui.displayMessage('"%s" is not a ROP node' % block_generate.ropnode.path())
      if not run_rop: join_render = False
      if join_render:
         tile_render = False
         delete_files = True
      else:
         if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
            # Set output mode to produce ifd files:
            block_generate.ropnode.parm('soho_outputmode').set(1)
            block_generate.soho_outputmode = 0
            block_generate.ropnode.parm('soho_diskfile').set( block_generate.ropnode.parm('vm_picture').unexpandedString() + '.ifd')

      if read_rop:
         images = ropnode.parm('vm_picture')
         files  = ropnode.parm('soho_diskfile')
         afnode.parm('sep_images').set(images.unexpandedString())
         afnode.parm('sep_files' ).set( files.unexpandedString())

      images = afcommon.patternFromPaths( afnode.parm('sep_images').evalAsStringAtFrame(block_generate.frame_first), afnode.parm('sep_images').evalAsStringAtFrame(block_generate.frame_last))
      files  = afcommon.patternFromPaths( afnode.parm('sep_files' ).evalAsStringAtFrame(block_generate.frame_first), afnode.parm('sep_files' ).evalAsStringAtFrame(block_generate.frame_last))

      if run_rop:
         if join_render: block_generate.preview = images
         if not join_render:
            block_generate.type = 'hbatch'
         else:
            block_generate.type = 'hbatch_mantra'
            block_generate.cmd = block_generate.cmd.replace( 'hrender_af', 'hrender_separate')
            if use_tmp_img_folder: block_generate.cmd += ' --tmpimg'

      if not join_render:
         tiles = tile_divx * tile_divy
         block_render = BlockParameters( afnode, ropnode, subblock, prefix, frame_range)
         block_render.name = blockname + '-R'
         block_render.cmd = 'mantra'
         block_render.type = block_render.cmd
         if run_rop: block_render.dependmask = block_generate.name
         if tile_render or del_rop_files or use_tmp_img_folder: block_render.cmd = 'mantrarender '
         if del_rop_files and not tile_render: block_render.cmd += 'd'
         if use_tmp_img_folder: block_render.cmd += 't'
         if tile_render:
            block_render.numeric = False
            block_render.cmd += 'c %(tile_divx)d %(tile_divy)d' % vars()
            block_render.cmd += ' @#@'
            block_render.frame_pertask = -tiles
            for frame in range( block_generate.frame_first, block_generate.frame_last + 1, block_generate.frame_inc):
               arguments = afnode.parm('sep_render_arguments').evalAsStringAtFrame( frame)
               for tile in range( 0, tiles):
                  block_render.tasks_names.append('%d tile %d' % ( frame, tile))
                  block_render.tasks_cmds.append('%d -R %s' % ( tile, arguments))
         else:
            if del_rop_files or use_tmp_img_folder: block_render.cmd += ' -R '
            else: block_render.cmd +=  ' -V a '
            block_render.cmd += afcommon.patternFromPaths( afnode.parm('sep_render_arguments').evalAsStringAtFrame(block_generate.frame_first), afnode.parm('sep_render_arguments').evalAsStringAtFrame(block_generate.frame_last))
            block_render.previw = images

      if tile_render:
         cmd = 'exrjoin %(tile_divx)d %(tile_divy)d %(images)s d' % vars()
         if del_rop_files: cmd += ' && deletefiles -s "%s"' % files
         block_join = BlockParameters( afnode, ropnode, subblock, prefix, frame_range)
         block_join.name = blockname + '-J'
         block_join.type = 'generic'
         block_join.dependmask = block_render.name
         block_join.cmd = cmd
         block_join.cmd_useprefix = False
         block_join.preview = images

      if read_rop:
         afnode.parm('sep_images').set('')
         afnode.parm('sep_files' ).set('')

      if tile_render: params.append( block_join)
      if not join_render: params.append( block_render)
      if run_rop: params.append( block_generate)

   else:
      params.append( BlockParameters( afnode, ropnode, subblock, prefix, frame_range))
   return params
Exemplo n.º 20
0
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):
    params = []
    if ropnode is not None \
     and ropnode.type().name() == 'ifd' \
     and afnode.parm('sep_enable').eval():

        # Mantra separate render:
        block_generate = \
         BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        blockname = block_generate.name
        block_generate.name += '-G'

        if not block_generate.valid:
            return None

        run_rop = afnode.parm('sep_run_rop').eval()
        read_rop = afnode.parm('sep_read_rop_params').eval()
        join_render = afnode.parm('sep_join').eval()
        tile_render = afnode.parm('sep_tile').eval()
        tile_divx = afnode.parm('sep_tile_divx').eval()
        tile_divy = afnode.parm('sep_tile_divy').eval()
        use_tmp_img_folder = afnode.parm('sep_use_tmp_img_folder').eval()
        del_rop_files = afnode.parm('sep_del_rop_files').eval()

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage('Can`t find ROP for processing "%s"' %
                                      afnode.path())

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      block_generate.ropnode.path())

        if not run_rop:
            join_render = False

        if join_render:
            tile_render = False
            delete_files = True  # This variable seems not used
        else:
            if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm('soho_outputmode').set(1)
                block_generate.soho_outputmode = 0
                block_generate.ropnode.parm('soho_diskfile').set(
                    block_generate.ropnode.parm(
                        'vm_picture').unexpandedString() + '.ifd')

        if read_rop:
            images = ropnode.parm('vm_picture')
            files = ropnode.parm('soho_diskfile')
            afnode.parm('sep_images').set(images.unexpandedString())
            afnode.parm('sep_files').set(files.unexpandedString())

        images = afcommon.patternFromPaths(
            afnode.parm('sep_images').evalAsStringAtFrame(
                block_generate.frame_first),
            afnode.parm('sep_images').evalAsStringAtFrame(
                block_generate.frame_last))

        files = afcommon.patternFromPaths(
            afnode.parm('sep_files').evalAsStringAtFrame(
                block_generate.frame_first),
            afnode.parm('sep_files').evalAsStringAtFrame(
                block_generate.frame_last))

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.type = 'hbatch'
            else:
                block_generate.type = 'hbatch_mantra'
                block_generate.cmd = block_generate.cmd.replace(
                    'hrender_af', 'hrender_separate')

                if use_tmp_img_folder:
                    block_generate.cmd += ' --tmpimg'

        if not join_render:
            tiles = tile_divx * tile_divy
            block_render = BlockParameters(afnode, ropnode, subblock, prefix,
                                           frame_range)
            block_render.name = blockname + '-R'
            block_render.cmd = 'mantra'
            block_render.type = block_render.cmd
            if run_rop:
                block_render.dependmask = block_generate.name

            if tile_render or del_rop_files or use_tmp_img_folder:
                block_render.cmd = 'mantrarender '

            if del_rop_files and not tile_render:
                block_render.cmd += 'd'

            if use_tmp_img_folder:
                block_render.cmd += 't'

            if tile_render:
                block_render.numeric = False
                block_render.cmd += 'c %(tile_divx)d %(tile_divy)d' % vars()
                block_render.cmd += ' @#@'
                block_render.frame_pertask = -tiles
                for frame in range(block_generate.frame_first,
                                   block_generate.frame_last + 1,
                                   block_generate.frame_inc):
                    arguments = afnode.parm(
                        'sep_render_arguments').evalAsStringAtFrame(frame)
                    for tile in range(0, tiles):
                        block_render.tasks_names.append('%d tile %d' %
                                                        (frame, tile))
                        block_render.tasks_cmds.append('%d -R %s' %
                                                       (tile, arguments))
            else:
                if del_rop_files or use_tmp_img_folder:
                    block_render.cmd += ' -R '
                else:
                    block_render.cmd += ' -V a '
                block_render.cmd += afcommon.patternFromPaths(
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_first),
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_last))
                block_render.preview = images

        if tile_render:
            cmd = 'exrjoin %(tile_divx)d %(tile_divy)d %(images)s d' % vars()

            if del_rop_files:
                cmd += ' && deletefiles -s "%s"' % files

            block_join = BlockParameters(afnode, ropnode, subblock, prefix,
                                         frame_range)

            block_join.name = blockname + '-J'
            block_join.type = 'generic'
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

        if read_rop:
            afnode.parm('sep_images').set('')
            afnode.parm('sep_files').set('')

        if tile_render:
            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    else:
        params.append(
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range))
    return params
Exemplo n.º 21
0
Arquivo: afanasy.py Projeto: CGRU/cgru
    def __init__(self, afnode, ropnode, subblock, prefix, frame_range, for_job_only=False):
        if VERBOSE == 2:
            if ropnode:
                print('Initializing block parameters for "%s" from "%s"' %
                      (ropnode.path(), afnode.path()))
            else:
                print('Initializing command block parameters from "%s"' %
                      afnode.path())

        # Init parameters:
        self.valid = False
        self.afnode = afnode
        self.ropnode = None
        self.subblock = subblock
        self.frame_pertask = 1
        self.frame_sequential = 1
        self.prefix = prefix
        self.preview = ''
        self.name = ''
        self.service = ''
        self.parser = ''
        self.cmd = ''
        self.cmd_useprefix = True
        self.dependmask = ''
        self.fullrangedepend = False
        self.numeric = True
        self.frame_first, self.frame_last, self.frame_inc = frame_range
        self.auxargs = ''
        self.tasks_names = []
        self.tasks_cmds = []
        self.tasks_previews = []
        # Fill in this array with files to delete in a block post command.
        # Files should have a common afanasy "@#*@" pattern,
        # it will be replaced with "*" for shell.
        self.delete_files = []
        # Parameters to restore ROP changes:
        self.soho_foreground = None
        self.soho_outputmode = None

        # Get parameters:
        self.frame_pertask = int(afnode.parm('frame_pertask').eval())
        self.frame_sequential = int(afnode.parm('frame_sequential').eval())
        self.job_name = str(afnode.parm('job_name').eval())
        self.job_branch = ''
        self.start_paused = int(afnode.parm('start_paused').eval())
        self.platform = str(afnode.parm('platform').eval())
        self.subtaskdepend = int(afnode.parm('subtaskdepend').eval())
        self.priority = -1
        self.max_runtasks = -1
        self.maxperhost = -1
        self.maxruntime = -1
        self.minruntime = -1
        self.capacity = -1
        self.capacity_min = -1
        self.capacity_max = -1
        self.hosts_mask = ''
        self.hosts_mask_exclude = ''
        self.depend_mask = ''
        self.depend_mask_global = ''
        self.min_memory = -1
        self.preview_approval = afnode.parm('preview_approval').eval()

        if afnode.parm('enable_extended_parameters').eval():
            self.job_branch = self.afnode.parm('job_branch').eval()
            self.parser = self.afnode.parm('override_parser').eval()
            self.priority = int(afnode.parm('priority').eval())
            self.max_runtasks = int(afnode.parm('max_runtasks').eval())
            self.maxperhost = int(afnode.parm('maxperhost').eval())
            self.maxruntime = int(afnode.parm('maxruntime').eval())
            self.minruntime = int(afnode.parm('minruntime').eval())
            self.min_memory = int(afnode.parm('min_memory').eval())
            self.capacity = int(afnode.parm('capacity').eval())
            self.capacity_min = int(
                afnode.parm('capacity_coefficient1').eval())
            self.capacity_max = int(
                afnode.parm('capacity_coefficient2').eval())
            self.hosts_mask = str(afnode.parm('hosts_mask').eval())
            self.hosts_mask_exclude = str(
                afnode.parm('hosts_mask_exclude').eval())
            self.depend_mask = str(afnode.parm('depend_mask').eval())
            self.depend_mask_global = str(
                afnode.parm('depend_mask_global').eval())

        # Process frame range:
        opname = afnode.path()
        if afnode.parm('trange').eval() > 1:
            self.fullrangedepend = True

        if ropnode:
            opname = ropnode.path()
            trange = ropnode.parm('trange')

            if trange is not None:
                if int(trange.eval()) > 0:
                    if ropnode.parm('f1') is not None:
                        self.frame_first = int(ropnode.parm('f1').eval())

                    if ropnode.parm('f2') is not None:
                        self.frame_last = int(ropnode.parm('f2').eval())

                    if ropnode.parm('f3') is not None:
                        self.frame_inc = int(ropnode.parm('f3').eval())

                if int(trange.eval()) > 1:
                    self.fullrangedepend = True

        if self.frame_last < self.frame_first:
            hou.ui.displayMessage('Last frame < first frame for "%s"' % opname)
            return

        if self.frame_inc < 1:
            hou.ui.displayMessage('Frame increment < 1 for "%s"' % opname)
            return

        if self.frame_pertask < 1:
            hou.ui.displayMessage('Frames per task < 1 for "%s"' % opname)
            return

        # Process output driver type to construct a command:
        if ropnode:
            self.service = 'hbatch'

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage(
                    '"%s" is not a ROP node' % ropnode.path()
                )
                return

            self.ropnode = ropnode
            self.name = str(ropnode.name())

            if self.prefix != '':
                self.name = '%s_%s' % (self.prefix, self.name)
            # Block type and preview:
            roptype = ropnode.type().name()

            if roptype == 'ifd':
                if ropnode.node(ropnode.parm('camera').eval())==None:
                    hou.ui.displayMessage("Camera in "+ropnode.name()+" is not valid",severity = hou.severityType.Error)
                    return

                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'hbatch_mantra'

                vm_picture = ropnode.parm('vm_picture')

                if vm_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            vm_picture.evalAsStringAtFrame(self.frame_first),
                            vm_picture.evalAsStringAtFrame(self.frame_last)
                        )
            elif roptype == 'rib':
                self.service = 'hbatch_prman'

            elif roptype == 'arnold':
                if not ropnode.parm('soho_outputmode').eval():
                    self.service = 'houdinitoarnold'

                ar_picture = ropnode.parm('ar_picture')

                if ar_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            ar_picture.evalAsStringAtFrame(self.frame_first),
                            ar_picture.evalAsStringAtFrame(self.frame_last)
                        )

            elif roptype == 'alembic':
                self.numeric = False
                taskname = ropnode.name()
                taskname += ' ' + str(self.frame_first)
                taskname += '-' + str(self.frame_last)
                self.tasks_names.append(taskname)
                self.tasks_cmds.append(self.frame_first)
                
            elif roptype == 'Redshift_ROP':
                self.service = 'hbatch_redshift'
                rs_picture = ropnode.parm('RS_outputFileNamePrefix')

                if rs_picture is not None:
                    self.preview = \
                        afcommon.patternFromPaths(
                            rs_picture.evalAsStringAtFrame(self.frame_first),
                            rs_picture.evalAsStringAtFrame(self.frame_last)
                        )

            # Block command:
            self.cmd = 'hrender_af'
            if afnode.parm('ignore_inputs').eval():
                self.cmd += ' -i'

            if self.capacity_min != -1 or self.capacity_max != -1:
                self.cmd += ' --numcpus ' + services.service.str_capacity

            self.cmd += ' -s @#@ -e @#@ --by %d -t "%s"' % (
                self.frame_inc, afnode.parm('take').eval()
            )

#            numWedges = computeWedge(ropnode, roptype)
#            if numWedges:
#                self.frame_first = 0
#                self.frame_last = numWedges - 1
#                self.frame_inc = 1
#                self.frame_pertask = 1
#                self.parser = "mantra"

            self.cmd += '%(auxargs)s'
            self.cmd += ' "%(hipfilename)s"'
            self.cmd += ' "%s"' % ropnode.path()

            if afnode.parm('enable_extended_parameters').eval():
                # Override service:
                override_service = self.afnode.parm('override_service').eval()
                if override_service is not None and len(override_service):
                    self.service = override_service

        else:
            # Custom command driver:
            if int(afnode.parm('cmd_mode').eval()):
                # Command:
                cmd = self.afnode.parm('cmd_cmd')
                self.cmd = afcommon.patternFromPaths(
                    cmd.evalAsStringAtFrame(self.frame_first),
                    cmd.evalAsStringAtFrame(self.frame_last)
                )

                # Name:
                self.name = self.afnode.parm('cmd_name').eval()
                if self.name is None or self.name == '':
                    self.name = self.cmd.split(' ')[0]

                # Service:
                self.service = self.afnode.parm('cmd_service').eval()
                if self.service is None or self.service == '':
                    self.service = self.cmd.split(' ')[0]
                # Parser:
                self.parser = self.afnode.parm('cmd_parser').eval()

                # Prefix:
                self.cmd_useprefix = \
                    int(self.afnode.parm('cmd_use_afcmdprefix').eval())

                # Delete files on job deletion:
                if self.afnode.parm('cmd_delete_files').eval():
                    cmd_files = self.afnode.parm('cmd_files')
                    self.delete_files.append(afcommon.patternFromPaths(
                        cmd_files.evalAsStringAtFrame(self.frame_first),
                        cmd_files.evalAsStringAtFrame(self.frame_last)
                    ))

            elif not for_job_only:
                hou.ui.displayMessage('Can\'t process "%s"' % afnode.path())
                return

        # Try to set driver foreground mode
        if ropnode:
            trange = ropnode.parm('trange')
            soho_foreground = ropnode.parm('soho_foreground')
            if trange is not None and int(trange.eval()) == 0:
                if soho_foreground is not None:
                    if soho_foreground.eval() == 0:
                        try:
                            soho_foreground.set(1)
                            self.soho_foreground = 0
                        except:  # TODO: too broad exception clause
                            hou.ui.displayMessage(
                                'Set "Block Until Render Complete" on "%s" '
                                'node' % ropnode.path()
                            )
                            return

        # Try to create output folder:
        if self.preview != '' and afnode.parm('check_output_folder').eval():
            folder = os.path.dirname(self.preview)
            if not os.path.isdir(folder):
                if hou.ui.displayMessage(folder, buttons=('Create', 'Abort'),
                                         default_choice=0, close_choice=1,
                                         title='Output Folder Does Not Exist',
                                         details=folder) == 0:
                    try:
                        os.makedirs(folder)
                    except Exception as e:
                        hou.ui.displayMessage(folder, buttons=('Abort',),
                                              default_choice=0, close_choice=1,
                                              title='Error Creating Output Folder',
                                              details=str(e))
                        return
                    if not os.path.isdir(folder):
                        hou.ui.displayMessage(folder, buttons=('Abort',),
                                              default_choice=0, close_choice=1,
                                              title='Can`t Create Output Folder',
                                              details=folder)
                        return
                else:
                    return

        self.valid = True
Exemplo n.º 22
0
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):

    params = []

    if ropnode is not None and ropnode.type().name() == 'ifd' and afnode.parm(
            'sep_enable').eval():
        # Case mantra separate render:

        block_generate = \
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        blockname = block_generate.name
        block_generate.name += '-G'

        if not block_generate.valid:
            block_generate.doPost()
            return None

        run_rop = afnode.parm('sep_run_rop').eval()
        read_rop = afnode.parm('sep_read_rop_params').eval()
        join_render = afnode.parm('sep_join').eval()
        tile_render = afnode.parm('sep_tile').eval()
        tile_divx = afnode.parm('sep_tile_divx').eval()
        tile_divy = afnode.parm('sep_tile_divy').eval()
        use_tmp_img_folder = afnode.parm('sep_use_tmp_img_folder').eval()
        del_rop_files = afnode.parm('sep_del_rop_files').eval()

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage('Can`t find ROP for processing "%s"' %
                                      afnode.path())

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      block_generate.ropnode.path())

        if not run_rop:
            join_render = False

        if join_render:
            tile_render = False
        else:
            if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm('soho_outputmode').set(1)
                block_generate.soho_outputmode = 0
                block_generate.ropnode.parm('soho_diskfile').set(
                    block_generate.ropnode.parm(
                        'vm_picture').unexpandedString() + '.ifd')

        if read_rop:
            parm_images = ropnode.parm('vm_picture')
            parm_files = ropnode.parm('soho_diskfile')
        else:
            parm_images = afnode.parm('sep_images')
            parm_files = afnode.parm('sep_files')

        images = afcommon.patternFromPaths(
            parm_images.evalAsStringAtFrame(block_generate.frame_first),
            parm_images.evalAsStringAtFrame(block_generate.frame_last))

        files = afcommon.patternFromPaths(
            parm_files.evalAsStringAtFrame(block_generate.frame_first),
            parm_files.evalAsStringAtFrame(block_generate.frame_last))

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.service = 'hbatch'
            else:
                block_generate.service = 'hbatch_mantra'
                block_generate.cmd = block_generate.cmd.replace(
                    'hrender_af', 'hrender_separate')

                if use_tmp_img_folder:
                    block_generate.cmd += ' --tmpimg'

        if not join_render:
            tiles = tile_divx * tile_divy
            block_render = BlockParameters(afnode, ropnode, subblock, prefix,
                                           frame_range)
            block_render.name = blockname + '-R'
            block_render.cmd = 'mantra'
            block_render.service = block_render.cmd
            if run_rop:
                block_render.dependmask = block_generate.name

            if tile_render or del_rop_files or use_tmp_img_folder:
                block_render.cmd = 'mantrarender '

            if del_rop_files:
                block_render.delete_files.append(files)

            if use_tmp_img_folder:
                block_render.cmd += 't'

            if tile_render:
                block_render.numeric = False
                block_render.cmd += 'c %(tile_divx)d %(tile_divy)d' % vars()
                block_render.cmd += ' @#@'
                block_render.frame_pertask = -tiles
                for frame in range(block_generate.frame_first,
                                   block_generate.frame_last + 1,
                                   block_generate.frame_inc):
                    arguments = afnode.parm(
                        'sep_render_arguments').evalAsStringAtFrame(frame)
                    arguments = arguments.replace(
                        '@FILES@', parm_files.evalAsStringAtFrame(frame))

                    for tile in range(0, tiles):
                        block_render.tasks_names.append('%d tile %d' %
                                                        (frame, tile))
                        block_render.tasks_cmds.append('%d -R %s' %
                                                       (tile, arguments))
            else:
                if del_rop_files or use_tmp_img_folder:
                    block_render.cmd += ' -R '
                else:
                    block_render.cmd += ' -V a '
                block_render.cmd += afcommon.patternFromPaths(
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_first),
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_last)).replace('@FILES@', files)
                block_render.preview = images

        if tile_render:
            cmd = 'exrjoin %(tile_divx)d %(tile_divy)d %(images)s d' % vars()

            block_join = BlockParameters(afnode, ropnode, subblock, prefix,
                                         frame_range)

            block_join.name = blockname + '-J'
            block_join.service = 'generic'
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

        if tile_render:
            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    elif len(str(afnode.parm('ds_node').eval())):
        # Case distribute simulation:
        ds_node_path = str(afnode.parm('ds_node').eval())
        ds_node = hou.node(ds_node_path)
        if not ds_node:
            hou.ui.displayMessage('No such control node: "%s"' % ds_node_path)
            return
        parms = ['address', 'port', 'slice']
        for parm in parms:
            if not ds_node.parm(parm):
                hou.ui.displayMessage(
                    'Control node "%s" does not have "%s" parameter' %
                    (ds_node_path, parm))
                return

        enable_tracker = not afnode.parm('ds_tracker_manual').eval()
        if enable_tracker:
            # Tracker block:
            par_start = getTrackerParameters(afnode, ropnode, subblock, prefix,
                                             frame_range, True)
            params.append(par_start)

        # A block for each slice:
        ds_num_slices = int(afnode.parm('ds_num_slices').eval())
        for s in range(0, ds_num_slices):
            par = BlockParameters(afnode, ropnode, subblock, prefix,
                                  frame_range)
            sim_blocks_mask = par.name + '.*'
            par.name += '-s%d' % s
            par.frame_pertask = par.frame_last - par.frame_first + 1
            if enable_tracker:
                par.addDependMask(par_start.name)
            par.fullrangedepend = True
            par.auxargs = ' --ds_node "%s"' % ds_node_path
            par.auxargs += ' --ds_address "%s"' % str(
                afnode.parm('ds_address').eval())
            par.auxargs += ' --ds_port %d' % int(afnode.parm('ds_port').eval())
            par.auxargs += ' --ds_slice %d' % s
            params.append(par)

        if enable_tracker:
            # Stop tracker block:
            par_stop = getTrackerParameters(afnode, ropnode, subblock, prefix,
                                            frame_range, False)
            par_stop.addDependMask(sim_blocks_mask)
            params.append(par_stop)

            # Set other block names for start tracker block.
            # As start tracker block will set other block environment
            # to specify started tracker and port.
            par_start.cmd += ' --envblocks "%s|%s"' % (sim_blocks_mask,
                                                       par_stop.name)
            # On this block depend mask will be reset on tracker start:
            par_start.cmd += ' --depblocks "%s"' % sim_blocks_mask

    else:
        params.append(
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range))
    return params
Exemplo n.º 23
0
def getBlockParameters(afnode, ropnode, subblock, prefix, frame_range):

    params = []

    if ropnode is not None and ropnode.type().name() == 'ifd' and afnode.parm(
            'sep_enable').eval():
        # Case mantra separate render:

        block_generate = \
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range)
        blockname = block_generate.name
        block_generate.name += '-G'

        if not block_generate.valid:
            return None

        run_rop = afnode.parm('sep_run_rop').eval()
        read_rop = afnode.parm('sep_read_rop_params').eval()
        join_render = afnode.parm('sep_join').eval()
        tile_render = afnode.parm('sep_tile').eval()
        tile_divx = afnode.parm('sep_tile_divx').eval()
        tile_divy = afnode.parm('sep_tile_divy').eval()
        use_tmp_img_folder = afnode.parm('sep_use_tmp_img_folder').eval()
        del_rop_files = afnode.parm('sep_del_rop_files').eval()

        if read_rop or run_rop:
            if not block_generate.ropnode:
                hou.ui.displayMessage('Can`t find ROP for processing "%s"' %
                                      afnode.path())

            if not isinstance(ropnode, hou.RopNode):
                hou.ui.displayMessage('"%s" is not a ROP node' %
                                      block_generate.ropnode.path())

        if not run_rop:
            join_render = False

        if join_render:
            tile_render = False
        else:
            if block_generate.ropnode.parm('soho_outputmode').eval() == 0:
                # Set output mode to produce ifd files:
                block_generate.ropnode.parm('soho_outputmode').set(1)
                block_generate.soho_outputmode = 0
                block_generate.ropnode.parm('soho_diskfile').set(
                    block_generate.ropnode.parm(
                        'vm_picture').unexpandedString() + '.ifd')

        if read_rop:
            images = ropnode.parm('vm_picture')
            files = ropnode.parm('soho_diskfile')
            afnode.parm('sep_images').set(images.unexpandedString())
            afnode.parm('sep_files').set(files.unexpandedString())

        images = afcommon.patternFromPaths(
            afnode.parm('sep_images').evalAsStringAtFrame(
                block_generate.frame_first),
            afnode.parm('sep_images').evalAsStringAtFrame(
                block_generate.frame_last))

        files = afcommon.patternFromPaths(
            afnode.parm('sep_files').evalAsStringAtFrame(
                block_generate.frame_first),
            afnode.parm('sep_files').evalAsStringAtFrame(
                block_generate.frame_last))

        if run_rop:
            if join_render:
                block_generate.preview = images

            if not join_render:
                block_generate.type = 'hbatch'
            else:
                block_generate.type = 'hbatch_mantra'
                block_generate.cmd = block_generate.cmd.replace(
                    'hrender_af', 'hrender_separate')

                if use_tmp_img_folder:
                    block_generate.cmd += ' --tmpimg'

        if not join_render:
            tiles = tile_divx * tile_divy
            block_render = BlockParameters(afnode, ropnode, subblock, prefix,
                                           frame_range)
            block_render.name = blockname + '-R'
            block_render.cmd = 'mantra'
            block_render.type = block_render.cmd
            if run_rop:
                block_render.dependmask = block_generate.name

            if tile_render or del_rop_files or use_tmp_img_folder:
                block_render.cmd = 'mantrarender '

            if del_rop_files and not tile_render:
                block_render.cmd += 'd'

            if use_tmp_img_folder:
                block_render.cmd += 't'

            if tile_render:
                block_render.numeric = False
                block_render.cmd += 'c %(tile_divx)d %(tile_divy)d' % vars()
                block_render.cmd += ' @#@'
                block_render.frame_pertask = -tiles
                for frame in range(block_generate.frame_first,
                                   block_generate.frame_last + 1,
                                   block_generate.frame_inc):
                    arguments = afnode.parm(
                        'sep_render_arguments').evalAsStringAtFrame(frame)
                    for tile in range(0, tiles):
                        block_render.tasks_names.append('%d tile %d' %
                                                        (frame, tile))
                        block_render.tasks_cmds.append('%d -R %s' %
                                                       (tile, arguments))
            else:
                if del_rop_files or use_tmp_img_folder:
                    block_render.cmd += ' -R '
                else:
                    block_render.cmd += ' -V a '
                block_render.cmd += afcommon.patternFromPaths(
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_first),
                    afnode.parm('sep_render_arguments').evalAsStringAtFrame(
                        block_generate.frame_last))
                block_render.preview = images

        if tile_render:
            cmd = 'exrjoin %(tile_divx)d %(tile_divy)d %(images)s d' % vars()

            if del_rop_files:
                cmd += ' && deletefiles -s "%s"' % files

            block_join = BlockParameters(afnode, ropnode, subblock, prefix,
                                         frame_range)

            block_join.name = blockname + '-J'
            block_join.type = 'generic'
            block_join.dependmask = block_render.name
            block_join.cmd = cmd
            block_join.cmd_useprefix = False
            block_join.preview = images

        if read_rop:
            afnode.parm('sep_images').set('')
            afnode.parm('sep_files').set('')

        if tile_render:
            params.append(block_join)

        if not join_render:
            params.append(block_render)

        if run_rop:
            params.append(block_generate)

    elif len(str(afnode.parm('ds_node').eval())):
        # Case distribute simulation:
        ds_node_path = str(afnode.parm('ds_node').eval())
        ds_node = hou.node(ds_node_path)
        if not ds_node:
            hou.ui.displayMessage('No such control node: "%s"' % ds_node_path)
            return
        parms = ['address', 'port', 'slice']
        for parm in parms:
            if not ds_node.parm(parm):
                hou.ui.displayMessage(
                    'Control node "%s" does not have "%s" parameter' %
                    (ds_node_path, parm))
                return
        ds_num_slices = int(afnode.parm('ds_num_slices').eval())
        for s in range(0, ds_num_slices):
            par = BlockParameters(afnode, ropnode, subblock, prefix,
                                  frame_range)
            par.name += '-s%d' % s
            par.frame_pertask = par.frame_last - par.frame_first + 1
            par.auxargs = ' --ds_node "%s"' % ds_node_path
            par.auxargs += ' --ds_address "%s"' % str(
                afnode.parm('ds_address').eval())
            par.auxargs += ' --ds_port %d' % int(afnode.parm('ds_port').eval())
            par.auxargs += ' --ds_slice %d' % s
            params.append(par)

    else:
        params.append(
            BlockParameters(afnode, ropnode, subblock, prefix, frame_range))
    return params