def _on_sync_all_assets_of_type(self, asset_type, ask=True):
        """
        Synchronizes all the assets of a given type
        :param asset_type: str
        :param ask: bol
        """

        assets_to_sync = artellapipe.AssetsMgr().get_assets_by_type(asset_type)
        if not assets_to_sync:
            LOGGER.warning('No Assets found of type "{}" to sync!'.format(asset_type))
            return

        total_assets = len(assets_to_sync)
        if ask:
            result = qtutils.show_question(
                None, 'Synchronizing All {} Assets ({})'.format(asset_type, total_assets),
                'Are you sure you want to synchronize all {} assets ({})? This can take lot of time!'.format(
                    asset_type, total_assets))
            if result == QMessageBox.No:
                return

        for asset in assets_to_sync:
            asset.sync(sync_type=defines.ArtellaFileStatus.ALL)

        self.show_ok_message('All assets have been synced!')
Example #2
0
    def update_thumbnail_icon(self, force=False):
        """
        Function that updates the thumbnail icon
        :return:
        """

        try:
            thumbnail_path = self.get_thumbnail_path()
            if thumbnail_path and os.path.isfile(thumbnail_path) and not force:
                thumb_icon = QIcon(QPixmap(thumbnail_path))
                self._asset_btn.setIcon(thumb_icon)
                self._thumbnail_icon = thumb_icon
                return thumb_icon
            else:
                self._thumbnail_icon = tpDcc.ResourcesMgr().icon(
                    artellapipe.AssetsMgr().get_default_asset_thumb())
                self._asset_btn.setIcon(self._thumbnail_icon)
                asset_thumbnail_path = self._asset.get_thumbnail_path()
                if not asset_thumbnail_path:
                    return self._thumbnail_icon
                self._worker_started = True
                self._worker.set_path(thumbnail_path)
                self._worker.set_force(force)
                self._worker.set_preview_id(asset_thumbnail_path)
                self.ThreadPool.start(self._worker)
                return self._thumbnail_icon
        except Exception as exc:
            LOGGER.error('Impossible to update thumbnail icon: {} | {}'.format(
                exc, traceback.format_exc()))
Example #3
0
    def change_category(self, category=None):
        """
        Changes the category assets that are being showed by the viewer
        :param category: str
        """

        if not category:
            category = defines.ArtellaFileStatus.ALL

        if category != defines.ArtellaFileStatus.ALL and category not in artellapipe.AssetsMgr().get_asset_categories():
            LOGGER.warning(
                'Asset Type {} is not a valid asset type for project {}'.format(category, self._project.name.title()))
            category = defines.ArtellaFileStatus.ALL

        self.clear()

        new_assets = list()
        for new_asset in reversed(self._assets):
            if category == defines.ArtellaFileStatus.ALL:
                new_asset.setVisible(True)
                new_assets.insert(0, new_asset)
            else:
                if new_asset.asset.get_category() == category:
                    new_asset.setVisible(True)
                    new_assets.insert(0, new_asset)
                else:
                    new_asset.setVisible(False)
                    new_assets.append(new_asset)

        for new_asset in new_assets:
            self._add_widget(new_asset)
Example #4
0
    def get_asset_shaders_to_export(self,
                                    asset,
                                    return_only_shaders=True,
                                    skip_standard_shaders=True):
        """
        Returns a list shaders that should be exported
        :param asset:
        :param return_only_shaders:
        :param skip_standard_shaders:
        :return:
        """

        shading_file_type = artellapipe.AssetsMgr().get_shading_file_type()
        file_path = asset.get_file(file_type=shading_file_type,
                                   status=defines.ArtellaFileStatus.WORKING,
                                   fix_path=True)
        valid_open = asset.open_file(file_type=shading_file_type,
                                     status=defines.ArtellaFileStatus.WORKING)
        if not valid_open:
            LOGGER.warning(
                'Impossible to open Asset Shading File: {}'.format(file_path))
            return None

        asset_shaders = self.get_asset_shaders(
            asset=asset,
            return_only_shaders=return_only_shaders,
            skip_standard_shaders=skip_standard_shaders)

        if not asset_shaders:
            LOGGER.warning(
                'No shaders found in current Asset Shading File: {}'.format(
                    file_path))
            return None

        return asset_shaders
    def _get_asset_categories(self):
        """
        Returns a list with the asset categories supported
        :return: list(str)
        """

        return artellapipe.AssetsMgr().get_asset_categories()
Example #6
0
    def get_path(self):
        """
        Implements abstract get_path function
        Returns the path of the asset
        :return: str
        """

        path_template_name = artellapipe.AssetsMgr().config.get(
            'data', 'path_template_name')
        template = artellapipe.FilesMgr().get_template(path_template_name)
        if not template:
            LOGGER.warning(
                'Impossible to retrieve asset path because template "{}" is not in configuration file'
                .format(path_template_name))
            return None

        template_dict = {
            'project_id': self._project.id,
            'project_id_number': self._project.id_number,
            'asset_type': self.get_category(),
            'asset_name': self.get_name()
        }
        asset_path = template.format(template_dict)

        if not asset_path:
            LOGGER.warning(
                'Impossible to retrieve asset path from template: "{} | {} | {}"'
                .format(template.name, template.pattern, template_dict))
            return None

        asset_path = os.path.expandvars(asset_path)
        asset_path = artellapipe.FilesMgr().prefix_path_with_project_path(
            asset_path)

        return asset_path
Example #7
0
    def _init(self):
        """
        Internal function that initializes asset info widget
        """

        if not self._asset_widget:
            return

        self._title_breadcrumb.set_items([{
            'text':
            self._asset_widget.asset.get_name()
        }])
        thumb_icon = self._asset_widget.get_thumbnail_icon()
        thumb_size = artellapipe.AssetsMgr().config.get('thumb_size')
        self._asset_icon_lbl.setPixmap(
            thumb_icon.pixmap(thumb_icon.availableSizes()[-1]).scaled(
                thumb_size[0], thumb_size[1], Qt.KeepAspectRatio))

        self._asset_toolbar = self._create_asset_toolbar()
        self._status_stack = StatusStack(asset_widget=self._asset_widget)
        self._status_stack.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Expanding)

        self._asset_toolbar_layout.addWidget(self._asset_toolbar)
        self.main_layout.addWidget(self._status_stack)
Example #8
0
    def get_ocurrences_of_asset_in_shot(self,
                                        asset_name,
                                        shot_name,
                                        force_update=False):
        """
        Returns the number of ocurrences of given asset in given shot
        :param asset_name: str, name of the asset
        :param shot_name: str, name of the shot
        :return: int or None
        """

        if not self._check_project():
            return None

        asset = artellapipe.AssetsMgr().find_asset(asset_name)
        if not asset:
            LOGGER.warning(
                'Impossible to return occurrences because asset "{}" does not exists!'
                .format(asset_name))
            return None

        shot = shots.ShotsManager().find_shot(shot_name)
        if not shot:
            LOGGER.warning(
                'Impossible to return occurrences because shot "{}" does not exists!'
                .format(shot_name))
            return None

        shot_id = shot.get_id()

        tracker = artellapipe.Tracker()
        total_occurrences = tracker.get_occurrences_of_asset_in_shot(
            shot_id, asset_name, force_update=force_update)

        return total_occurrences
Example #9
0
    def get_assets_from_breakdown(self):
        """
        Returns all the assets contained in shot breakdown defined in production tracker
        :return: list(ArtellaAsset)
        """

        shot_id = self.get_id()
        return artellapipe.AssetsMgr().get_assets_in_shot(shot_id)
Example #10
0
    def get_latest_published_versions(self):
        """
        Implements base ArtellaFile get_path function
        Returns latest published version of file
        :return: str
        """

        file_path = self.get_path()
        return artellapipe.AssetsMgr().get_latest_published_versions(
            file_path, file_type=self.FILE_TYPE)
Example #11
0
    def get_thumbnail_path(self):
        """
        Returns path where asset thumbnail is located
        :return: str
        """

        asset_name = self._asset.get_name()

        return artellapipe.AssetsMgr().get_asset_thumbnail_path(
            asset_name=asset_name, create_folder=True)
Example #12
0
    def get_artella_url(self):
        """
        Returns Artella URL of the file
        :return: str
        """

        assets_relative_path = os.path.relpath(self.get_path(), artellapipe.AssetsMgr().get_assets_path())
        assets_url = self._project.get_artella_assets_url()
        artella_url = '{}{}'.format(assets_url, assets_relative_path)

        return artella_url
    def _on_hires_assets(self):
        """
        Internal function that is called when High Res Assets menubar button is pressed
        """

        scene_assets = artellapipe.AssetsMgr().get_scene_assets()
        if not scene_assets:
            return

        for scene_asset in scene_assets:
            scene_asset.switch_to_hires()
 def _set_path(self, driver, setter, k):
     """
     Sets path to the text widget
     """
     asset_name = driver.currentText()
     if asset_name:
         save_path = os.path.join(
             artellapipe.AssetsMgr().get_assets_path(), "Characters", asset_name, "__working__",
             "groom", "groom_package.groom")
         setter.setText(save_path)
         return
     setter.setText("")
Example #15
0
    def get_asset_shaders(self,
                          asset,
                          return_only_shaders=True,
                          skip_standard_shaders=True):
        """
        Returns list of shaders applied to the given asset
        :param asset: list of dict
        """

        if not asset:
            return

        asset_shaders = dict()
        only_shaders = list()

        renderable_shapes = artellapipe.AssetsMgr(
        ).get_asset_renderable_shapes(asset, full_path=False)
        if not renderable_shapes:
            LOGGER.warning('No renderable shapes found in asset: "{}"'.format(
                asset.get_name()))
            return asset_shaders

        default_scene_shaders = tp.Dcc.default_shaders() or list()

        for shape in renderable_shapes:
            if shape not in asset_shaders:
                asset_shaders[shape] = dict()
            shading_groups = tp.Dcc.list_connections_of_type(
                shape, connection_type='shadingEngine')
            if not shading_groups:
                shading_groups = ['initialShadingGroup']
            for shading_grp in shading_groups:
                shading_grp_mat = tp.Dcc.list_materials(
                    nodes=tp.Dcc.list_node_connections(shading_grp))
                if skip_standard_shaders:
                    for mat in shading_grp_mat:
                        if mat in default_scene_shaders:
                            continue

                for mat in shading_grp_mat:
                    if mat not in only_shaders:
                        only_shaders.append(mat)
                asset_shaders[shape][shading_grp] = shading_grp_mat

        if not asset_shaders:
            LOGGER.warning('No shaders found in current Asset: {}'.format(
                asset.get_name()))
            return None

        if return_only_shaders:
            return only_shaders

        return asset_shaders
Example #16
0
    def update_cache(self, force=False):
        """
        Updates internal cache with the current assets located in Artella server
        """

        if self._cache and not force:
            return self._cache

        python.clear_list(self._cache)
        self._cache = artellapipe.AssetsMgr().find_all_assets() or list()

        return self._cache
Example #17
0
    def get_thumbnail_path(self):
        """
        Implements abstract get_path function
        Returns the path where asset thumbnail is located
        :return: str
        """

        thumb_attr = artellapipe.AssetsMgr().config.get(
            'data', 'thumb_attribute')
        thumb_path = self._asset_data.get(thumb_attr, None)

        return thumb_path
Example #18
0
    def get_shaders_paths(self):
        """
        Returns path where shaders are located in the project
        :return: str
        """

        shaders_paths = self.config.get('paths')
        return [
            path_utils.clean_path(
                os.path.join(artellapipe.AssetsMgr().get_assets_path(), p))
            for p in shaders_paths
        ]
Example #19
0
    def replace_by_rig(self, rig_control=None):
        """
        Replaces current asset by its rig file
        :param rig_control: str
        :return:
        """

        if not rig_control:
            rig_control = 'root_ctrl'

        if self.is_rig():
            return

        rig_file_class = artellapipe.FilesMgr().get_file_class('rig')
        if not rig_file_class:
            LOGGER.warning(
                'Impossible to reference rig file because Rig File Class (rig) was not found!'
            )
            return

        node_namespace = tp.Dcc.node_namespace(self.node, clean=True)
        current_matrix = tp.Dcc.node_matrix(self.node)
        parent_node = tp.Dcc.node_parent(self.node)

        self.remove()

        rig_file = rig_file_class(self.asset)
        ref_nodes = rig_file.import_file(reference=True,
                                         namespace=node_namespace,
                                         unique_namespace=False)
        if not ref_nodes:
            LOGGER.warning(
                'No nodes imported into current scene for rig file!')
            return None

        root_ctrl = None
        for node in ref_nodes:
            root_ctrl = utils.get_control(node=node, rig_control=rig_control)
            if root_ctrl:
                break
        if not root_ctrl:
            return False

        tp.Dcc.set_node_matrix(root_ctrl, current_matrix)
        if parent_node and tp.Dcc.object_exists(parent_node):
            asset_node = artellapipe.AssetsMgr().get_asset_node_in_scene(
                root_ctrl)
            if not asset_node:
                return
            tp.Dcc.set_parent(asset_node.node, parent_node)

        return True
    def _setup_synchronize_menu(self):
        """
        Internal function that creates the synchronize menu
        """

        sync_menu = QMenu(self)
        sync_icon = tpDcc.ResourcesMgr().icon('sync')

        for asset_type in artellapipe.AssetsMgr().get_asset_types():
            action_icon = tpDcc.ResourcesMgr().icon(asset_type.lower())
            if action_icon:
                sync_action = QAction(action_icon, asset_type.title(), self)
            else:
                sync_action = QAction(asset_type.title(), self)
            sync_menu.addAction(sync_action)
            asset_file_types = artellapipe.AssetsMgr().get_asset_type_files(asset_type=asset_type) or list()
            if asset_file_types:
                asset_files_menu = QMenu(sync_menu)
                sync_action.setMenu(asset_files_menu)
                for asset_file_type in asset_file_types:
                    asset_type_icon = tpDcc.ResourcesMgr().icon(asset_file_type)
                    asset_file_action = QAction(asset_type_icon, asset_file_type.title(), asset_files_menu)
                    asset_files_menu.addAction(asset_file_action)
                    asset_file_template = artellapipe.FilesMgr().get_template(asset_file_type)
                    if not asset_file_template:
                        LOGGER.warning('No File Template found for File Type: "{}"'.format(asset_file_type))
                        asset_file_action.setEnabled(False)
                        continue
                    asset_file_action.triggered.connect(partial(self._on_sync_file_type, asset_type, asset_file_type))
                all_asset_types_action = QAction(sync_icon, 'All', asset_files_menu)
                all_asset_types_action.triggered.connect(partial(self._on_sync_all_assets_of_type, asset_type))
                asset_files_menu.addAction(all_asset_types_action)

        sync_menu.addSeparator()
        sync_all_action = QAction(sync_icon, 'All', self)
        sync_all_action.triggered.connect(self._on_sync_all_types)
        sync_menu.addAction(sync_all_action)

        self._synchronize_btn.setMenu(sync_menu)
Example #21
0
    def __init__(self, asset, text=None, parent=None):

        self._asset = asset
        self._text = text or artellapipe.AssetsMgr().get_default_asset_name()
        self._thumbnail_icon = None

        super(ArtellaAssetWidget, self).__init__(parent=parent)

        self._worker = worker.ThumbDownloaderWorker()
        self._worker.setAutoDelete(False)
        self._worker.signals.triggered.connect(self._on_thumbnail_from_image)
        self._worker_started = False

        self._init()
    def _populate_data(self):
        self.ui.collection_cbx.addItems(self._get_all_collections())
        self.ui.renderer_cbx.addItems(["None", "Arnold Renderer"])
        self.ui.renderer_cbx.setCurrentIndex(1)
        self.ui.renderer_mode_cbx.addItems(["Live", "Batch Render"])
        self.ui.renderer_mode_cbx.setCurrentIndex(1)
        self.ui.motion_blur_cbx.addItems(["Use Global Settings", "On", "Off"])
        self.ui.extra_depth_sbx.setValue(16)
        self.ui.extra_samples_sbx.setValue(0)

        characters_to_set = os.listdir(os.path.join(artellapipe.AssetsMgr().get_assets_path(), "Characters"))
        characters_to_set.insert(0, "")
        self.ui.export_character_cbx.addItems(characters_to_set)
        self.ui.import_character_cbx.addItems(characters_to_set)
Example #23
0
    def set_id(self, new_id):
        """
        Sets the ID of this asset
        :param new_id: str
        """

        id_attr = artellapipe.AssetsMgr().config.get('data', 'id_attribute')
        asset_id = self._asset_data.get(id_attr, None)
        if not asset_id:
            LOGGER.warning(
                'Impossible to retrieve asset ID because asset data does not contains "{}" attribute.'
                '\nAsset Data: {}'.format(id_attr, self._asset_data))
            return None

        self._asset_data[id_attr] = new_id
    def _open_asset_shaders_file(self):
        if not self._asset:
            return

        shading_file_type = artellapipe.AssetsMgr().get_shading_file_type()
        file_path = self._asset.get_file(
            file_type=shading_file_type,
            status=defines.ArtellaFileStatus.WORKING,
            fix_path=True)
        valid_open = self._asset.open_file(
            file_type=shading_file_type,
            status=defines.ArtellaFileStatus.WORKING)
        if not valid_open:
            LOGGER.warning(
                'Impossible to open Asset Shading File: {}'.format(file_path))
            return None
Example #25
0
    def get_tags(self):
        """
        Returns tags of the asset
        Implements abstract get_tags function
        :return: list(str)
        """

        tags_attr = artellapipe.AssetsMgr().config.get('data', 'tag_attribute')
        tags_list = self._asset_data.get(tags_attr, None)
        if not tags_list:
            LOGGER.warning(
                'Impossible to retrieve tags name because asset data does not contains "{}" attribute.'
                '\nAsset Data: {}'.format(tags_attr, self._asset_data))
            return None

        return tags_list
Example #26
0
    def get_id(self):
        """
        Implements abstract get_id function
        Returns the id of the asset
        :return: str
        """

        id_attr = artellapipe.AssetsMgr().config.get('data', 'id_attribute')
        asset_id = self._asset_data.get(id_attr, None)
        if not asset_id:
            LOGGER.warning(
                'Impossible to retrieve asset ID because asset data does not contains "{}" attribute.'
                '\nAsset Data: {}'.format(id_attr, self._asset_data))
            return None

        return asset_id.rstrip()
    def _on_sync_file_type(self, asset_type, file_type, sync_type=defines.ArtellaFileStatus.ALL):
        """
        Internal callback function that is called when a file is selected from the sync menu
        :param file_type: str, file type to sync
        :param sync_type: ArtellaFileStatus, type of sync we want to do
        """

        assets_to_sync = artellapipe.AssetsMgr().get_assets_by_type(asset_type)
        if not assets_to_sync:
            LOGGER.warning('No Assets found of type "{}" to sync!'.format(asset_type))
            return

        for asset in assets_to_sync:
            asset.sync(file_type=file_type, sync_type=defines.ArtellaFileStatus.ALL)

        self.show_ok_message('Files of type {} has been synced!'.format(file_type))
Example #28
0
    def get_category(self):
        """
        Implements abstract get_category function
        Returns the category of the asset
        :return: str
        """

        category_attr = artellapipe.AssetsMgr().config.get(
            'data', 'category_attribute')

        category = self._asset_data.get(category_attr, None)
        if not category:
            LOGGER.warning(
                'Impossible to retrieve asset category because asset data does not contains "{}" attribute.'
                '\nAsset Data: {}'.format(category_attr, self._asset_data))

        return category
 def _init(self):
     assets = artellapipe.AssetsMgr().get_scene_assets(
         allowed_types=self.CATEGORIES,
         allowed_tags=self.CATEGORIES) or list()
     for asset in assets:
         asset_widget = self.OUTLINER_ITEM(asset)
         # asset_widget.overrideAdded.connect(self._on_override_added)
         # asset_widget.overrideRemoved.connect(self._on_override_removed)
         asset_widget.contextRequested.connect(self._on_show_context_menu)
         asset_widget.clicked.connect(self._on_item_clicked)
         asset_widget.viewToggled.connect(self._on_toggle_view)
         self.append_widget(asset_widget)
         self._widget_tree[asset_widget] = list()
         overrides = asset.get_overrides()
         if overrides:
             for override in overrides:
                 self._add_override(override=override, parent=asset_widget)
Example #30
0
    def load_scene_shaders(self,
                           status=defines.ArtellaFileStatus.PUBLISHED,
                           apply_shaders=True):
        """
        Loads all shaders of the current assets in the scene
        :param status:
        :param apply_shaders: bool
        :return:
        """

        scene_assets = artellapipe.AssetsMgr().get_scene_assets()
        if not scene_assets:
            LOGGER.warning(
                'Impossible to load shaders because there are no assets in current scene!'
            )
        for asset in scene_assets:
            asset.load_shaders(status=status, apply_shaders=apply_shaders)