Exemple #1
0
    def get_version_from_full_path(cls, full_path):
        """Finds the Version instance from the given full_path value.

        Finds and returns a :class:`~stalker.models.version.Version` instance
        from the given full_path value.

        Returns None if it can't find any matching.

        :param full_path: The full_path of the desired
            :class:`~stalker.models.version.Version` instance.

        :return: :class:`~stalker.models.version.Version`
        """
        logger.debug('full_path: %s' % full_path)
        # convert '\\' to '/'
        full_path = os.path.normpath(
            os.path.expandvars(full_path)
        ).replace('\\', '/')

        # trim repo path
        from stalker import Repository, Version
        os_independent_path = Repository.to_os_independent_path(full_path)

        # try to get a version with that info
        logger.debug('getting a version with path: %s' % full_path)

        version = Version.query\
            .filter(Version.full_path == os_independent_path).first()
        logger.debug('version: %s' % version)
        return version
Exemple #2
0
    def get_version_from_full_path(cls, full_path):
        """Finds the Version instance from the given full_path value.

        Finds and returns a :class:`~stalker.models.version.Version` instance
        from the given full_path value.

        Returns None if it can't find any matching.

        :param full_path: The full_path of the desired
            :class:`~stalker.models.version.Version` instance.

        :return: :class:`~stalker.models.version.Version`
        """
        logger.debug('full_path: %s' % full_path)
        # convert '\\' to '/'
        full_path = os.path.normpath(
            os.path.expandvars(full_path)
        ).replace('\\', '/')

        # trim repo path
        from stalker import Repository, Version
        os_independent_path = Repository.to_os_independent_path(full_path)

        # try to get a version with that info
        logger.debug('getting a version with path: %s' % full_path)

        version = Version.query\
            .filter(Version.full_path == os_independent_path).first()
        logger.debug('version: %s' % version)
        return version
Exemple #3
0
    def bind_to_original(cls):
        """binds the current scene references to original references from the
        repository
        """
        # get all reference paths
        import os
        from anima.env import mayaEnv
        from stalker import Repository, Version, Task
        m = mayaEnv.Maya()
        current_version = m.get_current_version()

        # get the current project
        project = None
        if current_version:
            project = current_version.task.project

        # no project then do nothing
        if project:
            for ref in pm.listReferences():
                unresolved_path = ref.unresolvedPath()
                filename = os.path.basename(unresolved_path)
                # find the corresponding version
                v = Version.query\
                    .join(Version.task, Task.versions)\
                    .filter(Task.project == project)\
                    .filter(Version.full_path.endswith(filename)).first()
                if v:
                    ref.replaceWith(
                        Repository.to_os_independent_path(
                            v.absolute_full_path
                        )
                    )
Exemple #4
0
def upload_thumbnail(task, thumbnail_full_path):
    """Uploads the given thumbnail for the given entity

    :param task: An instance of :class:`~stalker.models.entity.SimpleEntity`
      or a derivative.

    :param str thumbnail_full_path: A string which is showing the path
      of the thumbnail image
    """
    extension = os.path.splitext(thumbnail_full_path)[-1]

    # move the file to the task thumbnail folder
    # and mimic StalkerPyramids output format
    thumbnail_original_file_name = 'thumbnail%s' % extension
    thumbnail_final_full_path = os.path.join(
        task.absolute_path, 'Thumbnail', thumbnail_original_file_name
    )

    try:
        os.makedirs(os.path.dirname(thumbnail_final_full_path))
    except OSError:
        pass

    # # convert the thumbnail to jpg if it is a format that is not supported by
    # # browsers
    # ext_not_supported_by_browsers = ['.bmp', '.tga', '.tif', '.tiff', '.exr']
    # if extension in ext_not_supported_by_browsers:
    #     # use MediaManager to convert them
    #     from anima.utils import MediaManager
    #     mm = MediaManager()
    #     thumbnail_full_path = mm.generate_image_thumbnail(thumbnail_full_path)

    shutil.copy(thumbnail_full_path, thumbnail_final_full_path)

    from stalker import Link, Version, Repository

    thumbnail_os_independent_path = \
        Repository.to_os_independent_path(thumbnail_final_full_path)
    l_thumb = Link.query\
        .filter(Link.full_path == thumbnail_os_independent_path).first()

    if not l_thumb:
        l_thumb = Link(
            full_path=thumbnail_os_independent_path,
            original_filename=thumbnail_original_file_name
        )

    task.thumbnail = l_thumb

    # get a version of this Task
    from stalker.db.session import DBSession
    v = Version.query.filter(Version.task == task).first()
    if v:
        for naming_parent in v.naming_parents:
            if not naming_parent.thumbnail:
                naming_parent.thumbnail = l_thumb
                DBSession.add(naming_parent)

    DBSession.add(l_thumb)
    DBSession.commit()
Exemple #5
0
def upload_thumbnail(task, thumbnail_full_path):
    """Uploads the given thumbnail for the given entity

    :param task: An instance of :class:`~stalker.models.entity.SimpleEntity`
      or a derivative.

    :param str thumbnail_full_path: A string which is showing the path
      of the thumbnail image
    """
    extension = os.path.splitext(thumbnail_full_path)[-1]

    # move the file to the task thumbnail folder
    # and mimic StalkerPyramids output format
    thumbnail_original_file_name = 'thumbnail%s' % extension
    thumbnail_final_full_path = os.path.join(task.absolute_path, 'Thumbnail',
                                             thumbnail_original_file_name)

    try:
        os.makedirs(os.path.dirname(thumbnail_final_full_path))
    except OSError:
        pass

    # # convert the thumbnail to jpg if it is a format that is not supported by
    # # browsers
    # ext_not_supported_by_browsers = ['.bmp', '.tga', '.tif', '.tiff', '.exr']
    # if extension in ext_not_supported_by_browsers:
    #     # use MediaManager to convert them
    #     from anima.utils import MediaManager
    #     mm = MediaManager()
    #     thumbnail_full_path = mm.generate_image_thumbnail(thumbnail_full_path)

    import shutil
    shutil.copy(thumbnail_full_path, thumbnail_final_full_path)

    from stalker import Link, Version, Repository

    thumbnail_os_independent_path = \
        Repository.to_os_independent_path(thumbnail_final_full_path)
    l_thumb = Link.query\
        .filter(Link.full_path == thumbnail_os_independent_path).first()

    if not l_thumb:
        l_thumb = Link(full_path=thumbnail_os_independent_path,
                       original_filename=thumbnail_original_file_name)

    task.thumbnail = l_thumb

    # get a version of this Task
    from stalker.db.session import DBSession
    v = Version.query.filter(Version.task == task).first()
    if v:
        for naming_parent in v.naming_parents:
            if not naming_parent.thumbnail:
                naming_parent.thumbnail = l_thumb
                DBSession.add(naming_parent)

    DBSession.add(l_thumb)
    DBSession.commit()
Exemple #6
0
    def test_to_os_independent_path_is_working_properly(self):
        """testing if to_os_independent_path class method is working properly
        """
        from stalker.db.session import DBSession
        DBSession.add(self.test_repo)
        DBSession.commit()

        relative_part = 'some/path/to/a/file.ma'
        test_path = '%s/%s' % (self.test_repo.path, relative_part)
        from stalker import Repository
        assert Repository.to_os_independent_path(test_path) == \
            '$REPO%s/%s' % (self.test_repo.id, relative_part)
Exemple #7
0
    def to_repr(self, repr_name):
        """Replaces the current reference with the representation with the
        given repr_name.

        :param str repr_name: The desired repr name
        :return:
        """
        rep_v = self.find_repr(repr_name)
        from stalker import Repository
        if rep_v is not None and rep_v != self.version:
            self.replaceWith(
                Repository.to_os_independent_path(rep_v.absolute_full_path))
Exemple #8
0
    def test_to_os_independent_path_is_working_properly(self):
        """testing if stalker.Repository.to_os_independent_path() is working
        as we are expecting it to work
        """
        # repo4
        linux_path = '/test/repo/4/linux/path/PRJ1/Assets/test.ma'
        windows_path = 'T:/test/repo/4/windows/path/PRJ1/Assets/test.ma'
        osx_path = '/test/repo/4/osx/path/PRJ1/Assets/test.ma'

        os_independent_path = '$REPO%s/PRJ1/Assets/test.ma' % self.repo4.id

        self.assertEqual(Repository.to_os_independent_path(linux_path),
                         os_independent_path)

        self.assertEqual(Repository.to_os_independent_path(windows_path),
                         os_independent_path)

        self.assertEqual(Repository.to_os_independent_path(osx_path),
                         os_independent_path)

        # repo5
        linux_path = '/test/repo/5/linux/path/PRJ1/Assets/test.ma'
        windows_path = 'T:/test/repo/5/windows/path/PRJ1/Assets/test.ma'
        osx_path = '/test/repo/5/osx/path/PRJ1/Assets/test.ma'

        os_independent_path = '$REPO%s/PRJ1/Assets/test.ma' % self.repo5.id

        self.assertEqual(Repository.to_os_independent_path(linux_path),
                         os_independent_path)

        self.assertEqual(Repository.to_os_independent_path(windows_path),
                         os_independent_path)

        self.assertEqual(Repository.to_os_independent_path(osx_path),
                         os_independent_path)
Exemple #9
0
    def to_repr(self, repr_name):
        """Replaces the current reference with the representation with the
        given repr_name.

        :param str repr_name: The desired repr name
        :return:
        """
        rep_v = self.find_repr(repr_name)
        from stalker import Repository
        if rep_v is not None and rep_v != self.version:
            self.replaceWith(
                Repository.to_os_independent_path(rep_v.absolute_full_path)
            )
Exemple #10
0
def upload_thumbnail(task, thumbnail_full_path):
    """Uploads the given thumbnail for the given entity

    :param task: An instance of :class:`~stalker.models.entity.SimpleEntity`
      or a derivative.

    :param str thumbnail_full_path: A string which is showing the path
      of the thumbnail image
    """
    extension = os.path.splitext(thumbnail_full_path)[-1]

    # move the file to the task thumbnail folder
    # and mimic StalkerPyramids output format
    thumbnail_original_file_name = 'thumbnail%s' % extension
    thumbnail_final_full_path = os.path.join(
        task.absolute_path, 'Thumbnail', thumbnail_original_file_name
    )

    try:
        os.makedirs(os.path.dirname(thumbnail_final_full_path))
    except OSError:
        pass

    shutil.copy(thumbnail_full_path, thumbnail_final_full_path)

    from stalker import db, Link, Version, Repository

    thumbnail_os_independent_path = \
        Repository.to_os_independent_path(thumbnail_final_full_path)
    l_thumb = Link.query\
        .filter(Link.full_path == thumbnail_os_independent_path).first()

    if not l_thumb:
        l_thumb = Link(
            full_path=thumbnail_os_independent_path,
            original_filename=thumbnail_original_file_name
        )

    task.thumbnail = l_thumb

    # get a version of this Task
    v = Version.query.filter(Version.task == task).first()
    if v:
        for naming_parent in v.naming_parents:
            if not naming_parent.thumbnail:
                naming_parent.thumbnail = l_thumb
                db.DBSession.add(naming_parent)

    db.DBSession.add(l_thumb)
    db.DBSession.commit()
Exemple #11
0
def upload_thumbnail(task, thumbnail_full_path):
    """Uploads the given thumbnail for the given entity

    :param task: An instance of :class:`~stalker.models.entity.SimpleEntity`
      or a derivative.

    :param str thumbnail_full_path: A string which is showing the path
      of the thumbnail image
    """
    extension = os.path.splitext(thumbnail_full_path)[-1]

    # move the file to the task thumbnail folder
    # and mimic StalkerPyramids output format
    thumbnail_original_file_name = 'thumbnail%s' % extension
    thumbnail_final_full_path = os.path.join(task.absolute_path, 'Thumbnail',
                                             thumbnail_original_file_name)

    try:
        os.makedirs(os.path.dirname(thumbnail_final_full_path))
    except OSError:
        pass

    shutil.copy(thumbnail_full_path, thumbnail_final_full_path)

    from stalker import db, Link, Version, Repository

    thumbnail_os_independent_path = \
        Repository.to_os_independent_path(thumbnail_final_full_path)
    l_thumb = Link.query\
        .filter(Link.full_path == thumbnail_os_independent_path).first()

    if not l_thumb:
        l_thumb = Link(full_path=thumbnail_os_independent_path,
                       original_filename=thumbnail_original_file_name)

    task.thumbnail = l_thumb

    # get a version of this Task
    v = Version.query.filter(Version.task == task).first()
    if v:
        for naming_parent in v.naming_parents:
            if not naming_parent.thumbnail:
                naming_parent.thumbnail = l_thumb
                db.DBSession.add(naming_parent)

    db.DBSession.add(l_thumb)
    db.DBSession.commit()
Exemple #12
0
    def bind_to_original(cls):
        """binds the current scene references to original references from the
        repository
        """
        # get all reference paths
        import os
        from stalker import Repository, Version

        for ref in pm.listReferences():
            unresolved_path = ref.unresolvedPath()
            filename = os.path.basename(unresolved_path)
            # find the corresponding version
            # TODO: get the versions from current project
            v = Version.query\
                .filter(Version.full_path.endswith(filename))\
                .first()
            if v:
                ref.replaceWith(
                    Repository.to_os_independent_path(v.absolute_full_path)
                )
Exemple #13
0
    def test_to_os_independent_path_is_working_properly(self):
        """testing if stalker.Repository.to_os_independent_path() is working
        as we are expecting it to work
        """
        # repo4
        linux_path = '/test/repo/4/linux/path/PRJ1/Assets/test.ma'
        windows_path = 'T:/test/repo/4/windows/path/PRJ1/Assets/test.ma'
        osx_path = '/test/repo/4/osx/path/PRJ1/Assets/test.ma'

        os_independent_path = '$REPO%s/PRJ1/Assets/test.ma' % self.repo4.id

        self.assertEqual(
            Repository.to_os_independent_path(linux_path),
            os_independent_path
        )

        self.assertEqual(
            Repository.to_os_independent_path(windows_path),
            os_independent_path
        )

        self.assertEqual(
            Repository.to_os_independent_path(osx_path),
            os_independent_path
        )

        # repo5
        linux_path = '/test/repo/5/linux/path/PRJ1/Assets/test.ma'
        windows_path = 'T:/test/repo/5/windows/path/PRJ1/Assets/test.ma'
        osx_path = '/test/repo/5/osx/path/PRJ1/Assets/test.ma'

        os_independent_path = '$REPO%s/PRJ1/Assets/test.ma' % self.repo5.id

        self.assertEqual(
            Repository.to_os_independent_path(linux_path),
            os_independent_path
        )

        self.assertEqual(
            Repository.to_os_independent_path(windows_path),
            os_independent_path
        )

        self.assertEqual(
            Repository.to_os_independent_path(osx_path),
            os_independent_path
        )
Exemple #14
0
    def get_versions_from_path(self, path):
        """Finds Version instances from the given path value.

        Finds and returns the :class:`~stalker.models.version.Version`
        instances from the given path value.

        Returns an empty list if it can't find any matching.

        This method is different than
        :meth:`~stalker.env.EnvironmentBase.get_version_from_full_path`
        because it returns a list of
        :class:`~stalker.models.version.Version` instances which are
        residing in that path. The list is ordered by the ``id``\ s of the
        instances.

        :param path: A path which has possible
            :class:`~stalker.models.version.Version` instances.

        :return: A list of :class:`~stalker.models.version.Version` instances.
        """
        if not path:
            return []

        # convert '\\' to '/'
        path = os.path.normpath(path).replace('\\', '/')
        from stalker import Repository
        os_independent_path = Repository.to_os_independent_path(path)
        logger.debug('os_independent_path: %s' % os_independent_path)

        from stalker import Version
        from stalker.db.session import DBSession

        # try to get all versions with that info
        with DBSession.no_autoflush:
            versions = Version.query.\
                filter(Version.full_path.startswith(os_independent_path)).all()

        return versions
Exemple #15
0
    def get_versions_from_path(self, path):
        """Finds Version instances from the given path value.

        Finds and returns the :class:`~stalker.models.version.Version`
        instances from the given path value.

        Returns an empty list if it can't find any matching.

        This method is different than
        :meth:`~stalker.env.EnvironmentBase.get_version_from_full_path`
        because it returns a list of
        :class:`~stalker.models.version.Version` instances which are
        residing in that path. The list is ordered by the ``id``\ s of the
        instances.

        :param path: A path which has possible
            :class:`~stalker.models.version.Version` instances.

        :return: A list of :class:`~stalker.models.version.Version` instances.
        """
        if not path:
            return []

        # convert '\\' to '/'
        path = os.path.normpath(path).replace('\\', '/')
        from stalker import Repository
        os_independent_path = Repository.to_os_independent_path(path)
        logger.debug('os_independent_path: %s' % os_independent_path)

        from stalker import Version
        from stalker.db.session import DBSession

        # try to get all versions with that info
        with DBSession.no_autoflush:
            versions = Version.query.\
                filter(Version.full_path.startswith(os_independent_path)).all()

        return versions
Exemple #16
0
    def generate_ass(self):
        """generates the ASS representation of the current scene

        For Model Tasks the ASS is generated over the LookDev Task because it
        is not possible to assign a material to an object inside an ASS file.
        """
        # before doing anything, check if this is a look dev task
        # and export the objects from the referenced files with their current
        # shadings, then replace all of the references to ASS repr and than
        # add Stand-in nodes and parent them under the referenced models

        # load necessary plugins
        pm.loadPlugin('mtoa')

        # disable "show plugin shapes"
        active_panel = auxiliary.Playblaster.get_active_panel()
        show_plugin_shapes = pm.modelEditor(active_panel, q=1, pluginShapes=1)
        pm.modelEditor(active_panel, e=1, pluginShapes=False)

        # validate the version first
        self.version = self._validate_version(self.version)

        self.open_version(self.version)

        task = self.version.task

        # export_command = 'arnoldExportAss -f "%(path)s" -s -mask 24 ' \
        #                  '-lightLinks 0 -compressed -boundingBox ' \
        #                  '-shadowLinks 0 -cam perspShape;'

        export_command = 'arnoldExportAss -f "%(path)s" -s -mask 60' \
                         '-lightLinks 1 -compressed -boundingBox ' \
                         '-shadowLinks 1 -cam perspShape;'

        # calculate output path
        output_path = \
            os.path.join(self.version.absolute_path, 'Outputs/ass/')\
            .replace('\\', '/')

        # check if all references have an ASS repr first
        refs_with_no_ass_repr = []
        for ref in pm.listReferences():
            if ref.version and not ref.has_repr('ASS'):
                refs_with_no_ass_repr.append(ref)

        if len(refs_with_no_ass_repr):
            raise RuntimeError(
                'Please generate the ASS Representation of the references '
                'first!!!\n%s' %
                '\n'.join(map(lambda x: str(x.path), refs_with_no_ass_repr))
            )

        if self.is_look_dev_task(task):
            # in look dev files, we export the ASS files directly from the Base
            # version and parent the resulting Stand-In node to the parent of
            # the child node

            # load only Model references
            for ref in pm.listReferences():
                v = ref.version
                load_ref = False
                if v:
                    ref_task = v.task
                    if self.is_model_task(ref_task):
                        load_ref = True

                if load_ref:
                    ref.load()
                    ref.importContents()

            # Make all texture paths relative
            # replace all "$REPO#" from all texture paths first
            #
            # This is needed to properly render textures with any OS
            types_and_attrs = {
                'aiImage': 'filename',
                'file': 'fileTextureName',
                'imagePlane': 'imageName'
            }

            for node_type in types_and_attrs.keys():
                attr_name = types_and_attrs[node_type]
                for node in pm.ls(type=node_type):
                    orig_path = node.getAttr(attr_name).replace("\\", "/")
                    path = re.sub(
                        r'(\$REPO[0-9/]+)',
                        '',
                        orig_path
                    )
                    tx_path = self.make_tx(path)
                    inputs = node.attr(attr_name).inputs(p=1)
                    if len(inputs):
                        # set the input attribute
                        for input_node_attr in inputs:
                            input_node_attr.set(tx_path)
                    else:
                        node.setAttr(attr_name, tx_path)

            # randomize all render node names
            # This is needed to prevent clashing of materials in a bigger scene
            for node in pm.ls(type=RENDER_RELATED_NODE_TYPES):
                if node.referenceFile() is None and \
                   node.name() not in READ_ONLY_NODE_NAMES:
                    node.rename('%s_%s' % (node.name(), uuid.uuid4().hex))

            nodes_to_ass_files = {}

            # export all root ass files as they are
            for root_node in auxiliary.get_root_nodes():
                for child_node in root_node.getChildren():
                    # check if it is a transform node
                    if not isinstance(child_node, pm.nt.Transform):
                        continue

                    if not auxiliary.has_shape(child_node):
                        continue

                    # randomize child node name
                    # TODO: This is not working as intended, node names are like |NS:node1|NS:node2
                    #       resulting a child_node_name as "node2"
                    child_node_name = child_node\
                        .fullPath()\
                        .replace('|', '_')\
                        .split(':')[-1]

                    child_node_full_path = child_node.fullPath()

                    pm.select(child_node)
                    child_node.rename('%s_%s' % (child_node.name(), uuid.uuid4().hex))

                    output_filename =\
                        '%s_%s.ass' % (
                            self.version.nice_name,
                            child_node_name
                        )

                    output_full_path = \
                        os.path.join(output_path, output_filename)

                    # run the mel command
                    pm.mel.eval(
                        export_command % {
                            'path': output_full_path.replace('\\', '/')
                        }
                    )
                    nodes_to_ass_files[child_node_full_path] = \
                        '%s.gz' % output_full_path
                    # print('%s -> %s' % (
                    #     child_node_full_path,
                    #     output_full_path)
                    # )

            # reload the scene
            pm.newFile(force=True)
            self.open_version(self.version)

            # convert all references to ASS
            # we are doing it a little bit early here, but we need to
            for ref in pm.listReferences():
                ref.to_repr('ASS')

            all_stand_ins = pm.ls(type='aiStandIn')
            for ass_node in all_stand_ins:
                ass_tra = ass_node.getParent()
                full_path = ass_tra.fullPath()
                if full_path in nodes_to_ass_files:
                    ass_file_path = \
                        Repository.to_os_independent_path(
                            nodes_to_ass_files[full_path]
                        )
                    ass_node.setAttr('dso', ass_file_path)

        elif self.is_vegetation_task(task):
            # in vegetation files, we export the ASS files directly from the
            # Base version, also we use the geometry under "pfxPolygons"
            # and parent the resulting Stand-In nodes to the
            # pfxPolygons
            # load all references
            for ref in pm.listReferences():
                ref.load()

            # Make all texture paths relative
            # replace all "$REPO#" from all texture paths first
            #
            # This is needed to properly render textures with any OS
            types_and_attrs = {
                'aiImage': 'filename',
                'file': 'fileTextureName',
                'imagePlane': 'imageName'
            }

            for node_type in types_and_attrs.keys():
                attr_name = types_and_attrs[node_type]
                for node in pm.ls(type=node_type):
                    orig_path = node.getAttr(attr_name).replace("\\", "/")
                    path = re.sub(
                        r'(\$REPO[0-9/]+)',
                        '',
                        orig_path
                    )
                    tx_path = self.make_tx(path)
                    inputs = node.attr(attr_name).inputs(p=1)
                    if len(inputs):
                        # set the input attribute
                        for input_node_attr in inputs:
                            input_node_attr.set(tx_path)
                    else:
                        node.setAttr(attr_name, tx_path)

            # randomize all render node names
            # This is needed to prevent clashing of materials in a bigger scene
            for node in pm.ls(type=RENDER_RELATED_NODE_TYPES):
                if node.referenceFile() is None and \
                   node.name() not in READ_ONLY_NODE_NAMES:
                    node.rename('%s_%s' % (node.name(), uuid.uuid4().hex))

            # find the _pfxPolygons node
            pfx_polygons_node = pm.PyNode('kks___vegetation_pfxPolygons')

            for node in pfx_polygons_node.getChildren():
                for child_node in node.getChildren():
                    #print('processing %s' % child_node.name())
                    child_node_name = child_node.name().split('___')[-1]

                    pm.select(child_node)
                    output_filename =\
                        '%s_%s.ass' % (
                            self.version.nice_name,
                            child_node_name.replace(':', '_').replace('|', '_')
                        )

                    output_full_path = \
                        os.path.join(output_path, output_filename)

                    # run the mel command
                    pm.mel.eval(
                        export_command % {
                            'path': output_full_path.replace('\\', '/')
                        }
                    )

                    # generate an aiStandIn node and set the path
                    ass_node = auxiliary.create_arnold_stand_in(
                        path='%s.gz' % output_full_path
                    )
                    ass_tra = ass_node.getParent()

                    # parent the ass node under the current node
                    # under pfx_polygons_node
                    pm.parent(ass_tra, node)

                    # set pivots
                    rp = pm.xform(child_node, q=1, ws=1, rp=1)
                    sp = pm.xform(child_node, q=1, ws=1, sp=1)
                    # rpt = child_node.getRotatePivotTranslation()

                    pm.xform(ass_node, ws=1, rp=rp)
                    pm.xform(ass_node, ws=1, sp=sp)
                    # ass_node.setRotatePivotTranslation(rpt)

                    # delete the child_node
                    pm.delete(child_node)

                    # give it the same name with the original
                    ass_tra.rename('%s' % child_node_name)

            # clean up other nodes
            pm.delete('kks___vegetation_pfxStrokes')
            pm.delete('kks___vegetation_paintableGeos')

        elif self.is_model_task(task):
            # convert all children of the root node
            # to an empty aiStandIn node
            # and save it as it is
            root_nodes = self.get_local_root_nodes()

            for root_node in root_nodes:
                for child_node in root_node.getChildren():
                    child_node_name = child_node.name()

                    rp = pm.xform(child_node, q=1, ws=1, rp=1)
                    sp = pm.xform(child_node, q=1, ws=1, sp=1)

                    pm.delete(child_node)

                    ass_node = auxiliary.create_arnold_stand_in(path='')
                    ass_tra = ass_node.getParent()
                    pm.parent(ass_tra, root_node)
                    ass_tra.rename(child_node_name)

                    # set pivots
                    pm.xform(ass_tra, ws=1, rp=rp)
                    pm.xform(ass_tra, ws=1, sp=sp)

                    # because there will be possible material assignments
                    # in look dev disable overrideShaders
                    ass_node.setAttr('overrideShaders', False)

                    # we definitely do not use light linking in our studio,
                    # which seems to create more problems then it solves.
                    ass_node.setAttr('overrideLightLinking', False)

        # convert all references to ASS
        for ref in pm.listReferences():
            ref.to_repr('ASS')
            ref.load()

        # fix an arnold bug
        for node_name in ['initialShadingGroup', 'initialParticleSE']:
            node = pm.PyNode(node_name)
            node.setAttr("ai_surface_shader", (0, 0, 0), type="float3")
            node.setAttr("ai_volume_shader", (0, 0, 0), type="float3")

        # if this is an Exterior/Interior -> Layout -> Hires task flatten it
        is_exterior_or_interior_task = self.is_exterior_or_interior_task(task)
        if is_exterior_or_interior_task:
            # and import all of the references
            all_refs = pm.listReferences()
            while len(all_refs) != 0:
                for ref in all_refs:
                    if not ref.isLoaded():
                        ref.load()
                    ref.importContents()
                all_refs = pm.listReferences()

            # assign lambert1 to all GPU nodes
            pm.sets('initialShadingGroup', e=1, fe=auxiliary.get_root_nodes())

            # now remove them from the group
            pm.sets('initialShadingGroup', e=1, rm=pm.ls())

            # and to make sure that no override is enabled
            [node.setAttr('overrideLightLinking', False)
             for node in pm.ls(type='aiStandIn')]

            # clean up
            self.clean_up()

        # check if all aiStandIn nodes are included in
        # ArnoldStandInDefaultLightSet set
        try:
            arnold_stand_in_default_light_set = \
                pm.PyNode('ArnoldStandInDefaultLightSet')
        except pm.MayaNodeError:
            # just create it
            arnold_stand_in_default_light_set = \
                pm.createNode(
                    'objectSet',
                    name='ArnoldStandInDefaultLightSet'
                )

        pm.select(None)
        pm.sets(
            arnold_stand_in_default_light_set,
            fe=pm.ls(type='aiStandIn')
        )

        # save the scene as {{original_take}}___ASS
        # use maya
        take_name = '%s%s%s' % (
            self.base_take_name, Representation.repr_separator, 'ASS'
        )
        v = self.get_latest_repr_version(take_name)
        self.maya_env.save_as(v)

        # export the root nodes under the same file
        if is_exterior_or_interior_task:
            pm.select(auxiliary.get_root_nodes())
            pm.exportSelected(
                v.absolute_full_path,
                type='mayaAscii',
                force=True
            )

        # new scene
        pm.newFile(force=True)

        # reset show plugin shapes option
        active_panel = auxiliary.Playblaster.get_active_panel()
        pm.modelEditor(active_panel, e=1, pluginShapes=show_plugin_shapes)