Пример #1
0
def _replace_glow_mask(n, temp_channel='mask.a'):
    mask_knob = 'maskChannelMask' if n.input(1) else 'maskChannelInput'
    mask_channel = u(n[mask_knob].value())

    if mask_channel == 'none':
        return False

    copy_node = nuke.nodes.Copy(inputs=(n.input(0), n.input(1)),
                                from0=mask_channel,
                                to0=temp_channel)
    copy_node.setXYpos(n.xpos(),
                       n.ypos() - max(copy_node.screenHeight(), 32) - 10)
    width_channel = n['W'].value()
    if width_channel != 'none':
        input0 = nuke.nodes.ChannelMerge(
            inputs=(copy_node, copy_node),
            A=temp_channel,
            operation='in',
            B=width_channel,
        )
    else:
        input0 = copy_node

    n.setInput(0, input0)
    n.setInput(1, None)
    n['maskChannelMask'].setValue('none')
    n['maskChannelInput'].setValue('none')
    n['W'].setValue(temp_channel)

    u_print('修正Glow节点mask: {}'.format(u(n.name())))
    return True
Пример #2
0
    def import_resource(self, dir_path):
        """Import footages from config dictionary."""

        # Get all subdir
        dirs = list(x[0] for x in os.walk(dir_path))
        self.task_step('导入素材')
        for dir_ in dirs:
            # Get footage in subdir
            LOGGER.info('文件夹 %s:', dir_)
            if not re.match(BATCH_CONFIG['dir_pat'],
                            os.path.basename(dir_.rstrip('\\/'))):
                LOGGER.info('\t不匹配文件夹正则, 跳过')
                continue

            files = nuke.getFileNameList(utf8(dir_))
            footages = [
                u(i) for i in files if not u(i).endswith(('副本', '.lock'))
            ] if files else []
            if footages:
                for f in footages:
                    if os.path.isdir(e(os.path.join(dir_, f))):
                        LOGGER.info('\t文件夹: %s', f)
                        continue
                    LOGGER.info('\t素材: %s', f)
                    if re.match(CONFIG['footage_pat'], f, flags=re.I):
                        n = nuke.createNode(
                            'Read', utf8('file {{{}/{}}}'.format(dir_, f)))
                        n['on_error'].setValue(utf8('nearest frame'))
                    else:
                        LOGGER.info('\t\t不匹配素材正则, 跳过')
        LOGGER.info('{:-^30s}'.format('结束 导入素材'))

        if not nuke.allNodes('Read'):
            raise FootageError(dir_path)
Пример #3
0
def remove_duplicated_read(is_show_result=True):
    """Remove duplicated read to save memory.  """

    nodes = nuke.allNodes('Read')
    nodes.sort(key=lambda n: n.ypos())
    distinct_read = []
    removed_nodes = []

    for n in nodes:
        same_node = _find_same(n, distinct_read)
        if same_node:
            dot = nuke.nodes.Dot(inputs=[same_node],
                                 label='代替: {}\n{}'.format(
                                     u(n.name()),
                                     u(nuke.filename(n))).encode('utf-8'),
                                 hide_input=True)
            dot.setXYpos(n.xpos() + 34, n.ypos() + 57)
            core.replace_node(n, dot)
            n_name = u(n.name())
            removed_nodes.append(n_name)
            u_print('用 {0} 代替 {1} , 删除 {1}。'.format(u(same_node.name()),
                                                    n_name))
            nuke.delete(n)
        else:
            distinct_read.append(n)

    if not is_show_result:
        return
    if removed_nodes:
        nuke.message('合并时删除了{}个节点: \n{}'.format(
            len(removed_nodes), ', '.join(removed_nodes)).encode('utf-8'))
    else:
        nuke.message('没有发现重复读取节点。'.encode('utf-8'))
Пример #4
0
def delete_unused_nodes(nodes=None, message=False):
    """Delete all unused nodes."""

    if nodes is None:
        nodes = nuke.allNodes()
    nodes = sorted(nodes, key=lambda n: (n.ypos(), n.xpos()), reverse=True)

    # Split disabled nodes.
    disabled_nodes = [n for n in nodes if _is_disabled_and_no_expression(n)]

    for n in disabled_nodes:
        node_name = u(n.name())
        core.replace_node(n, n.input(0))
        u_print('分离已禁用的节点: {}'.format(node_name))

    # Delete unused nodes.
    is_used_result_cache = {}
    unused_nodes = [n for n in nodes if not _is_used(n, is_used_result_cache)]
    for n in unused_nodes:
        node_name = u(n.name())
        nuke.delete(n)
        u_print('删除节点: {}'.format(node_name))
    u_print('删除了 {} 个无用节点.'.format(len(unused_nodes)))

    if message:
        nuke.message(
            '<font size=5>删除了 {} 个未使用的节点。</font>\n'
            '<i>名称以"_"(下划线)开头的节点及其上游节点将不会被删除</i>'.format(
                len(unused_nodes)).encode('utf-8'))
Пример #5
0
def append_knob(node, knob):
    """Add @knob as @node's last knob.  """

    knob_name = u(knob.name())
    node_name = u(node.name())
    if nuke.exists('{}.{}'.format(node_name, knob_name).encode('utf-8')):
        knob.setValue(node[knob_name.encode('utf-8')].value())
        node.removeKnob(node[knob_name.encode('utf-8')])
    node.addKnob(knob)
Пример #6
0
def get_filenames(url):
    ret = []
    if not os.path.isdir(e(url)):
        return ret
    for dirpath, _, _ in os.walk(e(url)):
        dirpath = u(dirpath.replace('\\', '/'))
        filenames = nuke.getFileNameList(e(dirpath, 'UTF-8'))
        filenames = ['{}/{}'.format(dirpath, u(i)) for i in filenames]
        ret.extend(filenames)
    return ret
Пример #7
0
def _on_precomp_name_changed(self, knob):
    rootpath = PurePath(u(nuke.value('root.name')))
    name = u(knob.value()) or 'precomp1'
    script_path = (rootpath.parent /
                   ''.join([rootpath.stem] + ['.{}'.format(name)] +
                           rootpath.suffixes)).as_posix()
    render_path = 'precomp/{0}/{0}.%04d.exr'.format(
        ''.join([rootpath.stem] + ['.{}'.format(name)] +
                [i for i in rootpath.suffixes if i != '.nk']))
    self.scriptPath.setValue(script_path.encode('utf-8'))
    self.renderPath.setValue(render_path.encode('utf-8'))
Пример #8
0
def replace_sequence():
    # TODO: Need refactor and test.
    '''Replace all read node to specified frame range sequence.  '''

    # Prepare Panel
    panel = nuke.Panel(b'单帧替换为序列')
    label_path_prefix = b'限定只替换此文件夹中的读取节点'
    label_first = b'设置工程起始帧'
    label_last = b'设置工程结束帧'

    panel.addFilenameSearch(label_path_prefix, 'z:/')
    panel.addExpressionInput(label_first,
                             int(nuke.Root()['first_frame'].value()))
    panel.addExpressionInput(label_last,
                             int(nuke.Root()['last_frame'].value()))

    confirm = panel.show()
    if confirm:
        render_path = os.path.normcase(u(panel.value(label_path_prefix)))

        first = int(panel.value(label_first))
        last = int(panel.value(label_last))
        flag_frame = None

        nuke.Root()[b'proxy'].setValue(False)
        nuke.Root()[b'first_frame'].setValue(first)
        nuke.Root()[b'last_frame'].setValue(last)

        for n in nuke.allNodes('Read'):
            file_path = u(nuke.filename(n))
            if os.path.normcase(file_path).startswith(render_path):
                search_result = re.search(r'\.([\d]+)\.', file_path)
                if search_result:
                    flag_frame = search_result.group(1)
                file_path = re.sub(
                    r'\.([\d#]+)\.',
                    lambda matchobj: r'.%0{}d.'.format(len(matchobj.group(1))),
                    file_path)
                n[b'file'].setValue(file_path.encode('utf-8'))
                n[b'format'].setValue(b'HD_1080')
                n[b'first'].setValue(first)
                n[b'origfirst'].setValue(first)
                n[b'last'].setValue(last)
                n[b'origlast'].setValue(last)

        n = wlf_write_node()
        if n:
            if flag_frame:
                flag_frame = int(flag_frame)
                n[b'custom_frame'].setValue(flag_frame)
                nuke.frame(flag_frame)
            n[b'use_custom_frame'].setValue(True)
Пример #9
0
def throtted_warning(msg):
    """Only show each warning message once.  """

    msg = u(msg)
    if msg not in SHOWED_WARNING:
        nuke.warning(utf8(msg))
        SHOWED_WARNING.append(msg)
Пример #10
0
def upload_image(filename, folder, token):
    """Upload image to server.

    Args:
        filename (str): Filename.
        folder (str): Server upload folder, usually same with project name.
        token (str): Server session token.

    Returns:
        ImageInfo: Uploaded image information.
    """

    filename = u(filename)
    basename = os.path.basename(filename)
    data = post('web_upload_file', {
        'folder': folder,
        'type': 'project',
        'method': 'convert_image',
        'filename': basename
    },
                token=token,
                files={
                    'file':
                    (basename, open(e(filename),
                                    'rb'), mimetypes.guess_type(basename)[0])
                })
    assert isinstance(data, dict), type(data)
    data['path'] = filename
    return ImageInfo(**data)
Пример #11
0
    def get_shot_list(self):
        """Return shot_list generator from a config dict."""

        _dir = self.input_dir
        _out_dir = self.output_dir
        if not os.path.isdir(_dir):
            return []

        _ret = os.listdir(_dir)
        if isinstance(_ret[0], str):
            _ret = tuple(u(i) for i in _ret)
        self._all_shots = _ret
        if self.flags & IGNORE_EXISTED:
            _ret = (i for i in _ret
                    if not os.path.exists(os.path.join(_out_dir, u'{}_v0.nk'.format(i)))
                    and not os.path.exists(os.path.join(_out_dir, u'{}.nk'.format(i))))
        _ret = (i for i in _ret if (
            re.match(CONFIG['dir_pat'], i) and os.path.isdir(os.path.join(_dir, i))))

        if not _ret:
            _dir = _dir.rstrip('\\/')
            _dirname = os.path.basename(_dir)
            if re.match(CONFIG['dir_pat'], _dir):
                _ret = [_dir]
        return sorted(_ret)
Пример #12
0
    def __new__(cls, filename, frame_ranges=None):
        # Skip new from other Asset objet.
        if isinstance(filename, Footage):
            return filename

        frame_ranges = filename if frame_ranges is None else frame_ranges
        filename = cls.filename_factory(filename)

        # Try find cached asset.
        for i in core.CACHED_ASSET:
            assert isinstance(i, Footage)
            if u(i.filename) == u(filename):
                if filename.with_frame(1) != filename.with_frame(2):
                    i.frame_ranges += FrameRanges(frame_ranges)
                return i
        return super(Footage, cls).__new__(cls)
Пример #13
0
 def process(self, instance):
     filename = instance.data['name']
     if nuke.numvalue('preferences.wlf_send_to_dir', 0.0):
         render_dir = u(nuke.value('preferences.wlf_render_dir'))
         copy(filename, render_dir + '/')
     else:
         self.log.info('因为首选项设置而跳过')
Пример #14
0
def dropdata_handler(mime_type, data, hook):
    """Handling dropdata."""

    if mime_type != 'text/plain':
        return None
    data = u(data)
    if hook.is_ignore_data(data=data):
        return None

    LOGGER.debug('Handling dropdata: %s %s', mime_type, data)
    urls = chain([data], *hook.get_url(data=data))
    filenames = chain(*(chain([i], *hook.get_filenames(url=i)) for i in urls))

    try:
        ret = None
        for filename in progress(tuple(filenames)):
            if hook.is_ignore_filename(filename=filename):
                LOGGER.debug('Ignore filename: %s', filename)
                ret = True
                continue
            LOGGER.debug('Handling filename: %s', filename)
            context = {'is_created': False}
            nodes = tuple(
                chain(*hook.create_node(filename=filename, context=context)))
            if any(nodes):
                ret = True
                LOGGER.debug('Created nodes: %s', nodes)
                hook.after_created(nodes=nodes)
        return ret
    except CancelledError:
        return True
Пример #15
0
def escape_for_channel(text):
    """Escape text for channel name.

    Args:
        text (str): Text for escaped

    Returns:
        str: Esacped text.

    Example:
        >>> escape_for_channel('apple')
        'mask_extra.apple'
        >>> escape_for_channel('tree.apple')
        'tree.apple'
        >>> escape_for_channel('tree.apple.leaf')
        'tree.apple_leaf'
        >>> escape_for_channel('tree.apple.leaf.ца╣')
        'tree.apple_leaf_?'
        >>> escape_for_channel(None)
        'mask_extra.None'

    """

    ret = u(text)
    if '.' not in ret:
        ret = 'mask_extra.{}'.format(ret)
    ret = ret.replace(' ', '_')
    ret = '{0[0]}{0[1]}{1}'.format(
        ret.partition('.')[:-1],
        ret.partition('.')[-1].replace('.', '_'))
    ret = ret.encode('ascii', 'replace')
    return ret
Пример #16
0
    def l10n(self, value):
        """Return translated value.  """

        if not value:
            return ''
        for pat in self._translate_dict:
            if re.match(pat, value):
                return re.sub(pat, self._translate_dict[pat], value)
        return u(value)
Пример #17
0
 def process(self, instance):
     is_ok = True
     for i in instance:
         assert isinstance(i, FootageInfo)
         if not os.path.normcase(u(i.filename)).startswith(self.valid_dir):
             self.log.error('使用了本地素材: %s', i.filename)
             is_ok = False
     if not is_ok:
         raise ValueError('Local file used.')
Пример #18
0
def _gizmo_to_group_update_ui():
    n = nuke.thisNode()
    _temp_knob_name = 'wlf_gizmo_to_group'
    _has_temp_knob = nuke.exists(
        utf8('{}.{}'.format(u(n.name()), _temp_knob_name)))

    if _has_temp_knob:
        n = edit.gizmo_to_group(n)
        n.removeKnob(n[_temp_knob_name])
        n.removeKnob(n['User'])
Пример #19
0
    def process(self, instance):
        assert isinstance(instance, pyblish.api.Instance)
        dest = instance.context.data['workfileFileboxInfo'].path + '/'

        for n in nuke.allNodes('Precomp'):
            src = u(nuke.filename(n))
            if src.startswith(dest.replace('\\', '/')):
                continue
            n['file'].setValue(copy(src, dest))
        nuke.scriptSave()
Пример #20
0
 def _shuffle():
     channels = dict.fromkeys(['in', 'in2', 'out', 'out2'], '')
     for i in channels.keys():
         channel_value = u(nuke.value('this.' + i))
         if channel_value != 'none':
             channels[i] = channel_value + ' '
     label = (channels['in'] + channels['in2'] + '-> ' + channels['out'] +
              channels['out2']).rstrip(' ')
     ret = _add_to_autolabel(label)
     return ret
Пример #21
0
def _knob_changed(self, knob):
    {
        self.precompName: _on_precomp_name_changed,
    }.get(knob, lambda *_: None)(self, knob)
    options = {name: k.value() for name, k in self.knobs().items()}
    options = {
        k: u(v) if isinstance(v, six.binary_type) else v
        for k, v in options.items()
    }
    PatchPrecompSelected.current_options = options
    assert PatchPrecompSelected.current_options
Пример #22
0
    def _add_to_autolabel(text, center=False):

        if not isinstance(text, (str, unicode)):
            return
        ret = u(autolabel()).split('\n')
        ret.insert(1, text)
        ret = '\n'.join(ret).rstrip('\n')
        if center:
            ret = ('<div align="center" '
                   'style="margin:0px;padding:0px">{}</div>').format(ret)
        return ret
Пример #23
0
def _is_used(n, cache):
    assert isinstance(cache, dict)
    node_name = u(n.name())
    if cache.has_key(n):
        return cache[n]

    if (node_name.startswith('_')
            or node_name == 'VIEWER_INPUT'
            or u(n.Class()) in ('BackdropNode',
                                'Read',
                                'Write',
                                'Viewer',
                                'GenerateLUT',
                                'wlf_Write')):
        ret = True
    else:
        ret = (not _is_disabled_and_no_expression(n)
               and any(_is_used(n, cache) for n in n.dependent()))

    cache[n] = ret
    return ret
Пример #24
0
    def process(self, instance):
        context = instance.context
        task = self.get_task(context)
        assert isinstance(task, Task)

        n = wlf_write_node()
        path = u(nuke.filename(n.node('Write_JPG_1')))
        dest = task.filebox.get('image').path + '/{}.jpg'.format(task.shot)
        # dest = 'E:/test_pyblish/{}.jpg'.format(task.shot)
        copy(path, dest)

        context.data['submitImage'] = task.set_image(dest)
Пример #25
0
    def __init__(self, node):
        assert isinstance(node, nuke.Node)
        n = node

        self._filename = u(nuke.filename(n))
        path = PurePath(self._filename)

        tag = (nuke.value(
            '{}.{}'.format(u(n.name()), self.tag_knob_name).encode('utf-8'),
            '') or path.tag)

        k = nuke.String_Knob(self.tag_knob_name, '标签'.encode('utf-8'))
        append_knob(node, k)
        k.setValue(tag)

        layer = path.layer
        k = nuke.String_Knob(self.layer_knob_name, '层'.encode('utf-8'))
        append_knob(node, k)
        k.setValue(path.layer)

        n.setName('_'.join(i for i in (tag, layer) if i).encode('utf-8'),
                  updateExpressions=True)
Пример #26
0
 def _run(asset):
     assert isinstance(asset, Footage)
     try:
         missing_frames = asset.missing_frames()
         if missing_frames:
             key = u(asset.filename.as_posix())
             if key in ret:
                 ret[key].add(missing_frames)
             else:
                 ret[key] = missing_frames
     except:
         import traceback
         raise RuntimeError(traceback.format_exc())
Пример #27
0
 def _get_mtime_info():
     ret = {}
     for n in nuke.allNodes('Read', nuke.Root()):
         try:
             mtime = time.mktime(
                 time.strptime(n.metadata('input/mtime'),
                               '%Y-%m-%d %H:%M:%S'))
         except TypeError:
             continue
         if mtime > since:
             ret[nuke.filename(n)] = mtime
             ftime = time.strftime('%m-%d %H:%M:%S', time.localtime(mtime))
             throtted_warning('{}: [new footage]{}'.format(
                 u(n.name()), ftime))
     return ret
Пример #28
0
def mark_enable(nodes):
    """Mark nodes enable later then disabled them.  """

    if isinstance(nodes, nuke.Node):
        nodes = (nodes, )
    for n in nodes:
        try:
            label_knob = n['label']
            label = u(label_knob.value())
            if ENABLE_MARK not in label:
                label_knob.setValue('{}\n{}'.format(
                    label, ENABLE_MARK).encode('utf-8'))
            n['disable'].setValue(True)
        except NameError:
            continue
Пример #29
0
def create_out_dirs(node=None):
    """Create this read node's output dir if need."""

    n = node or nuke.thisNode()
    try:
        if n['disable'].value():
            return
    except NameError:
        pass

    filename = u(nuke.filename(n))
    if filename:
        target_dir = e(os.path.dirname(filename))
        if not os.path.isdir(target_dir):
            LOGGER.debug('Create dir: %s', target_dir)
            os.makedirs(target_dir)
Пример #30
0
def glow_no_mask(temp_channel='mask.a', is_show_result=True):
    """Use width channel on `Glow2` node, instead of mask.  """

    channel.add_channel(temp_channel)
    nodes = nuke.allNodes('Glow2')
    result = [n for n in nodes if _replace_glow_mask(n, temp_channel)]

    if not is_show_result:
        return
    if result:

        nuke.message('将{}个Glow节点的mask更改为了width channel:\n{}'.format(
            len(result),
            ','.join(u(n.name()) for n in result)).encode('utf-8'))
    else:
        nuke.message('没有发现使用了mask的Glow节点。'.encode('utf-8'))