示例#1
0
文件: afanasy.py 项目: RISEFX/cgru
def getWriteParams( i_app, i_afparams, i_wnode):
	o_params = dict()

	pnames = ['filename']
	for pname in pnames:
		par = i_wnode.getParam(pname)
		if par:
			o_params[pname] = par.getValue()

	if len(o_params) == 0:
		NatronGui.natron.warningDialog('Error','No "filename" parameter found on "%s"' % i_wnode.getLabel())
		return None

	o_params['afanasy'] = False
	o_params['nodelabel'] = i_wnode.getLabel()
	o_params['nodename'] = i_wnode.getScriptName()

	files = o_params['filename']
	files = afcommon.patternFromStdC(files)
	files = afcommon.patternFromDigits(files)
	files = replaceProjectPaths( i_app, files)
	o_params['files'] = [files]

	return o_params
示例#2
0
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))
else:
    print('Unknown command: "%s"' % sys.argv[1])
示例#3
0
文件: __init__.py 项目: CGRU/cgru
    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)
示例#4
0
文件: afjob.py 项目: penthoy/cgru
			block.setSequential( seq)

		if scenetype == 'max':
			block.setCommand(cmd, False, False)
		else:
			block.setCommand(cmd)

		block.setCapacity(capacity)
		block.setVariableCapacity(capmin, capmax)
		if maxruntime != 0:
			block.setTasksMaxRunTime(maxruntime)

		if images != '':
			block.setFiles(
				afcommon.patternFromDigits(
					afcommon.patternFromStdC(images)
				).split(';')
			)

		blocks.append(block)
		i += 1

	if mname != '' and images != '':
		block = af.Block(mname + '-movie', 'movgen')
		blocks.append(block)
		block.setWorkingDirectory(pwd)
		block.setDependMask(blocknames[-1])
		task = af.Task(mname)
		block.tasks.append(task)
		cmd = os.getenv('CGRU_LOCATION')
		cmd = os.path.join(cmd, 'utilities')
示例#5
0
文件: afjob.py 项目: sachinpore/cgru
	blocknames.append( blockname)
if len(blockparsers) == 0 and blockparser != '':
	blockparsers.append( blockparser)
i = 0
for cmd in cmds:
	block = af.Block( blocknames[i], blocktype)
	if len( blockparsers):
		block.setParser( blockparsers[i])
	block.setWorkingDirectory( pwd )
	block.setNumeric( s, e, fpt, by)
	if scenetype == 'max': block.setCommand( cmd, False, False )
	else: block.setCommand( cmd )
	block.setCapacity( capacity)
	block.setVariableCapacity( capmin, capmax)
	if maxruntime != 0: block.setTasksMaxRunTime( maxruntime)
	if images != '': block.setFiles( afcommon.patternFromDigits( afcommon.patternFromStdC( images)))
	blocks.append( block)
	i += 1

# Create a Job:
job = af.Job( name)
job.setPriority( priority)
if maxruntasks	!= -1: job.setMaxRunningTasks( maxruntasks)
if hostsmask		!= '': job.setHostsMask( hostsmask)
if hostsexcl		!= '': job.setHostsMaskExclude( hostsexcl)
if dependmask	!= '': job.setDependMask( dependmask)
if dependglobal	!= '': job.setDependMaskGlobal( dependglobal)
if deletescene			: job.setCmdPost('deletefiles "%s"' % os.path.abspath(scene))
if startpaused			: job.offline()
if platform != '':
	if platform == 'any': job.setNeedOS('')
示例#6
0
文件: afanasy.py 项目: cgmafia/anima
    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()
            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 = 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.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
                )
                command = mrc_layer.build_command()
                block.setCommand(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
            )
            command = mrc.build_command()
            block.setCommand(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)
        else:
            job.setTimeLife(240 * 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)

            # disable abort on license fail
            redshift.abortOnLicenseFail.set(0)
示例#7
0
        if seq != 1:
            block.setSequential(seq)

        if scenetype == 'max':
            block.setCommand(cmd, False, False)
        else:
            block.setCommand(cmd)

        block.setCapacity(capacity)
        block.setVariableCapacity(capmin, capmax)
        if maxruntime != 0:
            block.setTasksMaxRunTime(maxruntime)

        if images != '':
            block.setFiles(
                afcommon.patternFromDigits(
                    afcommon.patternFromStdC(images)).split(';'))

        blocks.append(block)

    if mname != '' and images != '':
        block = af.Block(mname + '-movie', 'movgen')
        blocks.append(block)
        block.setWorkingDirectory(pwd)
        block.setDependMask(blocknames[-1])
        task = af.Task(mname)
        block.tasks.append(task)
        cmd = os.getenv('CGRU_LOCATION')
        cmd = os.path.join(cmd, 'utilities')
        cmd = os.path.join(cmd, 'moviemaker')
        cmd = os.path.join(cmd, 'makemovie.py')
        cmd = 'python "%s"' % cmd
示例#8
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)
示例#9
0
文件: afanasy.py 项目: eoyilmaz/anima
    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)