Beispiel #1
0
 def __init__(self, rr_job):
     super(self.__class__, self).__init__()
     self.job = rr_job
     self.hook = Hook(self)
     self.GLOABAL_STARTUP_PLUGINS = ["xgenMR", "xgenToolkit", "AbcImport"]
     self.WORK_SPACE = {"images": self.job.image_dir, "depth": self.job.image_dir}
Beispiel #2
0
class RRMaya(RRApp):
    def __init__(self, rr_job):
        super(self.__class__, self).__init__()
        self.job = rr_job
        self.hook = Hook(self)
        self.GLOABAL_STARTUP_PLUGINS = ["xgenMR", "xgenToolkit", "AbcImport"]
        self.WORK_SPACE = {"images": self.job.image_dir, "depth": self.job.image_dir}

    def version(self):
        """
        returns: Maya app version e.g 2015.
        """
        # Return full api version as 201516
        # We trim two last digits to produce 2015
        version = cmds.about(apiVersion=True) / 100
        self.log.info("Maya version: %s" % version)
        return version

    def open_scene(self, scene):
        """
        Open maya scene.
        param scene: Path to maya scene file.
        """
        scene = pm.openFile(scene, force=True)
        self.log.info("Open scene file: %s" % scene)
        return scene

    def set_workspace(self):
        # workspace.open doesn't do anything if workspace.open = None
        pm.workspace.open(self.job.workspace)
        self.log.info("Maya workspace: %s" % pm.workspace.getcwd())
        for file_rule, path in self.WORK_SPACE.items():
            pm.workspace.fileRules[file_rule] = path

    def load_plugin(self, plugin_name):
        # Maya will skip this action if plugin is alredy loaded.
        maya.mel.eval("loadPlugin %s;" % plugin_name)

    def override_attr(self, attr, value):
        """
        Override attribute value.
        param attr: PyMel attribute object.
        param value: New value for the attribute.
        """
        # Removes any render layer adjustments and unlocks the attr,
        # so that command line rendering can override the value.
        maya.mel.eval("removeRenderLayerAdjustmentAndUnlock %s;" % attr.name())
        attr.set(value)

        return attr

    def set_attrs(self, node, attr_dict):
        """
        param node: PyMel note to assign attributes to.
        param attr_dict: Dictionary of attributes.
        """
        for name, value in attr_dict.items():
            if value is not None:
                node.setAttr(name, value)
            else:
                # self.log.debug('Attribute %s is %s. Skipped!' % (name, value))
                pass

    def set_default_render_resolution(self, x, y):
        """
        Set resolution for all native Maya renders.
        param x: Resolution X
        param y: Resolution Y
        """
        default_res = pm.PyNode("defaultResolution")
        if x is not None:
            default_res.setAttr("width", x)
            self.log.info("Render width: %s" % x)
        if y is not None:
            default_res.setAttr("height", y)
            self.log.info("Render height: %s" % y)

    def init_mayasoftware(self):

        render_globals = pm.PyNode("defaultRenderGlobals")
        render_quality = pm.PyNode("defaultRenderQuality")

        self.set_default_render_resolution(self.job.resx, self.job.resy)
        if self.job.image_format is not None:
            pm.mel.setMayaSoftwareImageFormat(self.job.image_format)

        self.set_attrs(render_globals, {"numCpusToUse": self.job.threads, "motionBlur": self.job.motion_blur})

        self.set_attrs(
            render_quality,
            {
                "edgeAntiAliasing": self.job.edge_aa,
                "shadingSamples": self.job.samples,
                "maxShadingSamples": self.job.max_samples,
                "redThreshold": self.job.treshold,
                "greenThreshold": self.job.treshold,
                "blueThreshold": self.job.treshold,
                "coverageThreshold": self.job.treshold,
            },
        )

        # Set render region. Need for multi-tiled rendering.
        region = (self.job.rx1, self.job.rx2, self.job.ry1, self.job.ry2)
        if not None in region:
            pm.mel.setMayaSoftwareRegion(*region)

    def init_mentalray(self):

        mi_default = pm.PyNode("miDefaultOptions")

        self.load_plugin("Mayatomr")
        # This function call from mentalrayUI.mel required
        # to initialize render properly.
        pm.mel.miCreateDefaultNodes()

        self.set_default_render_resolution(self.job.resx, self.job.resy)
        if self.job.image_format is not None:
            pm.mel.setMentalRayImageFormat(self.job.image_format)

        # Set global Mental Ray variables.
        for name, value in {
            "VerbosityOn": "true",
            "Verbosity": self.job.verbose,
            "NumThreadOn": "true",
            "NumThread": self.job.threads,
            "NumThreadAutoOn": "true",
            "NumThreadAuto": "true",
        }.items():
            if value is not None:
                cmd = "global int $g_mrBatchRenderCmdOption_%s = %s;" % (name, value)
                maya.mel.eval(cmd)

        self.set_attrs(
            mi_default,
            {
                "displacementShaders": self.job.render_displace,
                "miDefaultOptions": self.job.edge_aa,
                "maxSamples": self.job.samples,
                "contrastR": self.job.max_samples,
                "contrastG": self.job.max_samples,
                "contrastB": self.job.max_samples,
                "contrastA": self.job.max_samples,
                "motionBlur": self.job.motion_blur,
            },
        )

    def init_vray(self):

        vray_settings = pm.PyNode("vraySettings")

        self.load_plugin("vrayformaya")
        # pm.mel.loadPreferredRenderGlobalsPreset('vray') # Not sure that we need it.
        pm.mel.vrayRegisterRenderer()
        pm.mel.vrayCreateVRaySettingsNode()

        self.set_attrs(
            vray_settings,
            {
                "animation": True,
                "fileNamePrefix": self.job.file_name,
                "sys_max_threads": self.job.threads,
                "width": self.job.resx,
                "height": self.job.resy,
                "fileNamePadding": self.job.frame_padding,
                "batchCamera": self.job.camera,
                "imageFormatStr": self.job.image_format,
            },
        )

    def init_arnold(self):

        self.load_plugin("mtoa")

        ai_render = pm.PyNode("defaultArnoldRenderOptions")
        ai_driver = pm.PyNode("defaultArnoldDriver")
        ai_translator = ai_driver.ai_translator

        ext_dict = {".exr": "exr", ".jpeg": "jpeg", ".jpg": "jpeg", ".maya": "maya", ".png": "png", ".tif": "tif"}

        self.set_attrs(
            ai_render,
            {
                "renderType": 0,
                "threads_autodetect": False,
                "threads": self.job.threads,
                "motion_blur_enable": self.job.motion_blur,
                "ignoreMotionBlur": not self.job.motion_blur,
                "ignoreDisplacement": not self.job.render_displace,
                "abortOnLicenseFail": not self.job.render_demo,
                "skipLicenseCheck": self.job.render_demo,
                "log_verbosity": self.job.verbose,
            },
        )

        if self.job.image_format is not None:
            ai_translator.set(self.job.image_format)
        if self.job.ext_override is not None:
            new_ext = ext_dict[self.job.file_ext.lower()]
            ai_translator.set(new_ext)

    def init_redshift(self):
        raise NotImplementedError

    def render_frame(self, frame_number):
        """
        Render one frame.
        :param frame_number: Frame to render.
        """
        render_globals = pm.PyNode("defaultRenderGlobals")

        before_frame = datetime.datetime.now()

        self.set_attrs(
            render_globals,
            {
                "startFrame": frame_number,
                "endFrame": frame_number,
                "startExtension": frame_number + self.job.frame_offset,
            },
        )

        self.log.info("Starting to render frame %s..." % frame_number)
        # global proc mayaBatchRenderProcedure(
        # 	int $isInteractiveBatch,	// interactive batch or command line rendering
        # 	string $sceneName,			// the original scene name before export
        # 	string $layer,				// render specific layer
        # 	string $renderer,			// use specific renderer is not empty string.
        # 	string $option				// optional arg to the render command
        # )
        # TODO(Kirill): Test with user custom render layers.
        pm.mel.mayaBatchRenderProcedure(0, "", self.job.render_layer, self.job.render_name, "")

        after_frame = datetime.datetime.now() - before_frame

        self.log.info("Rendering of frame: %s finished in %s (h:m:s.ms)" % (frame_number, after_frame))

    def render_frames(self):

        render_globals = pm.PyNode("defaultRenderGlobals")
        renderer = self.job.render_name

        # Before starting render execute user script.
        self.hook.before_segment_render()

        self.log.info("Changing scene frame to frame %s..." % self.job.frame_start)

        render_globals.setAttr("byFrameStep", self.job.frame_step)
        render_globals.setAttr("byExtension", self.job.frame_step)

        pm.mel.setImageSizePercent(-1.0)
        render_globals.setAttr("renderAll", 1)

        frange = (self.job.frame_start, self.job.frame_end + 1, self.job.frame_step)

        for frame in xrange(*frange):
            self.hook.before_frame_render()
            file_name = "%s/%s" % (self.job.file_dir, self.job.file_name_no_var)
            rrtcp.create_placeholder(file_name, frame, self.job.frame_padding, self.job.file_ext)

            self.render_frame(frame)

        # Run user code after render of segment is finished
        self.hook.after_segment_render()

    def initialize(self):

        default_res = pm.PyNode("defaultResolution")
        render_globals = pm.PyNode("defaultRenderGlobals")

        self.set_env("PYTHONPATH", self.job.python_path)

        for p in self.GLOABAL_STARTUP_PLUGINS:
            self.load_plugin(p)

        self.set_workspace()
        self.open_scene(self.job.maya_scene)
        # self.set_render_layer(self.job.render_layer)

        renderer = self.job.render_name
        if renderer == "mayaSoftware":
            self.init_mayasoftware()
        elif renderer == "mentalRay":
            self.init_mentalray()
        elif renderer == "vray":
            self.init_vray()
        elif renderer == "arnold":
            self.init_arnold()
        elif renderer == "redshift":
            self.init_redshift()

        if self.job.kso_mode:
            self.log.info("Starting KSO mode...")
            self.start_kso_server()
        else:
            self.render_frames()