Ejemplo n.º 1
0
class SvListModifierNode(bpy.types.Node, SverchCustomTreeNode):
    ''' List Modifier'''
    bl_idname = 'SvListModifierNode'
    bl_label = 'List Modifier'
    bl_icon = 'MODIFIER'
    sv_icon = 'SV_LIST_MODIFIER'

    mode_items = [(no_space(name), name, "", idx)
                  for _, idx, name, _ in node_item_list]

    func_: EnumProperty(name="Modes",
                        description="Mode Choices",
                        default=SET,
                        items=mode_items,
                        update=updateNode)

    listify: BoolProperty(default=True,
                          description='Output lists or proper sets',
                          update=updateNode)

    help_url: StringProperty(default='list_main/list_modifier')

    def draw_buttons(self, context, layout):
        layout.prop(self, "func_", text='')
        layout.prop(self, "listify", text='output as list')

    def sv_init(self, context):
        self.inputs.new('SvStringsSocket', "Data1")
        self.inputs.new('SvStringsSocket', "Data2")
        self.outputs.new('SvStringsSocket', "Result")

    def draw_label(self):
        return self.func_

    def process(self):
        inputs = self.inputs
        outputs = self.outputs

        if not outputs[0].is_linked:
            return

        unary = (num_inputs[no_space(self.func_)] == 1)
        f = self.get_f(unary)

        if unary:
            if inputs['Data1'].is_linked:
                data1 = inputs['Data1'].sv_get()
            elif inputs['Data2'].is_linked:
                data1 = inputs['Data2'].sv_get()
            else:
                return
            out = f(data1)
        else:
            data1 = inputs['Data1'].sv_get()
            data2 = inputs['Data2'].sv_get()
            out = f(data1, data2)
            # params = match_long_repeat([data1, data2])
            # out = f(*params)

        outputs[0].sv_set(out)

    def get_f(self, unary):
        operation = func_dict[no_space(self.func_)]

        do_post = (no_space(self.func_) in SET_OPS) and self.listify
        post_process = list if do_post else lambda x: x  # identity function

        if unary:

            def f(d):
                if isinstance(d[0], (int, float)):
                    return post_process(operation(d))
                else:
                    return [f(x) for x in d]
        else:

            def f(a, b):
                if isinstance(a[0], (int, float)):
                    return post_process(operation(a, b))
                else:
                    return [f(*_) for _ in zip(a, b)]

        return f
Ejemplo n.º 2
0
# using a purposely broad indexing value range incase other functions get into this..
node_item_list = [
    (1, 1, SET, set), (1, 10, "Ordered Set by input", ordered_set),
    (1, 20, "Unique Consecutives", unique_consecutives),
    (1, 30, "Sequential Set", lambda a: sorted(set(a))),
    (1, 40, "Sequential Set Rev", lambda a: sorted(set(a), reverse=True)),
    (1, 50, "Normalize", normalize),
    (1, 60, "Accumulating Sum", lambda a: list(accumulate(a))),
    (2, 69, "Mask subset (A in B)", mask_subset),
    (2, 70, INTX, lambda a, b: set(a) & set(b)),
    (2, 80, UNION, lambda a, b: set(a) | set(b)),
    (2, 90, DIFF, lambda a, b: set(a) - set(b)),
    (2, 100, SYMDIFF, lambda a, b: set(a) ^ set(b))
]

func_dict = {no_space(k): v for _, _, k, v in node_item_list}
num_inputs = {no_space(k): v for v, _, k, _ in node_item_list}


class SvListModifierNode(bpy.types.Node, SverchCustomTreeNode):
    ''' List Modifier'''
    bl_idname = 'SvListModifierNode'
    bl_label = 'List Modifier'
    bl_icon = 'MODIFIER'
    sv_icon = 'SV_LIST_MODIFIER'

    mode_items = [(no_space(name), name, "", idx)
                  for _, idx, name, _ in node_item_list]

    func_: EnumProperty(name="Modes",
                        description="Mode Choices",
Ejemplo n.º 3
0
class SvGetAssetPropertiesMK2(bpy.types.Node, SverchCustomTreeNode,
                              SvAnimatableNode):
    ''' Get Asset Props '''
    bl_idname = 'SvGetAssetPropertiesMK2'
    bl_label = 'Object ID Selector+'
    bl_icon = 'SELECT_SET'
    sv_icon = 'SV_OBJECT_ID_SELECTOR'

    def type_filter(self, object):
        return object.type == self.Type

    def frame_updateNode(self, context):
        ''' must rebuild for each update'''
        self.frame_collection_name.clear()

        if not (self.gp_pointer and self.gp_layer):
            return

        layer_ref = self.gp_pointer.layers.get(self.gp_layer)
        if not layer_ref:
            return

        for idx, f in enumerate(layer_ref.frames):
            self.frame_collection_name.add().name = str(idx) + ' | ' + str(
                f.frame_number)

        # updateNode(self, context)
        if self.gp_selected_frame_mode == 'active_frame':
            if len(self.inputs) == 0:
                self.inputs.new("SvStringsSocket", 'frame#')
        else:
            if len(self.inputs) > 0:
                self.inputs.remove(self.inputs[-1])

        self.process()

    type_collection_name: bpy.props.CollectionProperty(
        type=bpy.types.PropertyGroup)
    frame_collection_name: bpy.props.CollectionProperty(
        type=bpy.types.PropertyGroup)

    M = [
        'actions', 'brushes', 'filepath', 'grease_pencils', 'groups', 'images',
        'libraries', 'linestyles', 'masks', 'materials', 'movieclips',
        'node_groups', 'particles', 'scenes', 'screens', 'shape_keys',
        'sounds', 'speakers', 'texts', 'textures', 'worlds', 'objects'
    ]

    T = [
        'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'ARMATURE', 'GPENCIL',
        'LATTICE', 'EMPTY', 'CAMERA', 'LIGHT', 'SPEAKER'
    ]

    Mode: EnumProperty(name="get modes",
                       default="objects",
                       items=e(M),
                       update=updateNode)
    Type: EnumProperty(name="get types",
                       default="MESH",
                       items=e(T),
                       update=updateNode)

    properties_to_skip_iojson: [
        "object_pointer", "image_pointer", "text_pointer"
    ]

    text_pointer: PointerProperty(type=bpy.types.Text,
                                  poll=lambda s, o: True,
                                  update=updateNode)
    object_pointer: PointerProperty(type=bpy.types.Object,
                                    poll=type_filter,
                                    update=updateNode)
    image_pointer: PointerProperty(type=bpy.types.Image,
                                   poll=lambda s, o: True,
                                   update=updateNode)
    pass_pixels: bpy.props.BoolProperty(update=updateNode)

    # GP props
    gp_pointer: PointerProperty(type=bpy.types.GreasePencil,
                                poll=lambda s, o: True,
                                update=updateNode)
    # i can't get this to work. so am revering to StringProperty for gp_layer.
    # gp_layer_pointer: PointerProperty(type=bpy.types.GreasePencilLayers, poll=lambda s, o: True, update=updateNode) # <---- no?
    gp_layer: bpy.props.StringProperty(update=updateNode)
    gp_frame_current: bpy.props.BoolProperty(default=True, update=updateNode)
    gp_frame_override: bpy.props.IntProperty(default=1, update=updateNode)
    gp_stroke_idx: bpy.props.IntProperty(update=updateNode)

    gp_frame_mode_options = [
        (no_space(k), k, '', i)
        for i, k in enumerate(["pick frame", "active frame"])
    ]
    gp_selected_frame_mode: bpy.props.EnumProperty(
        items=gp_frame_mode_options,
        description="offers choice between current frame or available frames",
        default="pick_frame",
        update=frame_updateNode)
    gp_frame_pick: bpy.props.StringProperty(update=frame_updateNode)
    gp_pass_points: bpy.props.BoolProperty(default=True, update=updateNode)

    def draw_gp_options(self, context, layout):
        layout.prop_search(self,
                           'gp_pointer',
                           bpy.data,
                           'grease_pencils',
                           text='name')
        if not self.gp_pointer:
            return

        layout.prop_search(self,
                           'gp_layer',
                           self.gp_pointer,
                           'layers',
                           text='layer')
        layer_ref = self.gp_pointer.layers.get(self.gp_layer)
        if not layer_ref:
            return

        layout.prop(self, 'gp_selected_frame_mode', expand=True)
        frame_data = None
        if self.gp_selected_frame_mode == 'active_frame':
            frame_data = layer_ref.active_frame
        else:
            # maybe display uilist with frame_index and frame_nmber.
            layout.prop_search(self, 'gp_frame_pick', self,
                               'frame_collection_name')
        layout.prop(self, 'gp_pass_points', text='pass points')

    def process_mode_grease_pencils(self):
        data_list = bpy.data.grease_pencils
        if not (self.gp_pointer and self.gp_layer):
            return data_list[:]

        layer_ref = self.gp_pointer.layers.get(self.gp_layer)
        if not layer_ref:
            return data_list[:]

        if self.gp_selected_frame_mode == 'active_frame':
            if len(self.inputs) > 0 and self.inputs[0].is_linked:

                frame_number = self.inputs[0].sv_get()[0][0]
                key = frame_from_available2(frame_number, layer_ref)
                strokes = layer_ref.frames[key].strokes
            else:
                strokes = layer_ref.active_frame.strokes

            if not strokes:
                return []

            if self.gp_pass_points:
                return [[p.co[:] for p in s.points] for s in strokes]
            else:
                return strokes
        else:
            if self.gp_frame_pick:
                idx_from_frame_pick = int(self.gp_frame_pick.split(' | ')[0])
                frame_data = layer_ref.frames[idx_from_frame_pick]
                if frame_data:
                    if self.gp_pass_points:
                        return [[p.co[:] for p in s.points]
                                for s in frame_data.strokes]
                    else:
                        return frame_data.strokes

    def process_mode_objects(self):
        data_list = bpy.data.objects
        if self.object_pointer:
            return [self.object_pointer]
        else:
            return [i for i in data_list if i.type == self.Type]

    def process_mode_texts(self):
        data_list = bpy.data.texts
        if self.text_pointer:
            return [[self.text_pointer.as_string()]]
        else:
            return data_list[:]

    def process_mode_images(self):
        data_list = bpy.data.images
        if self.image_pointer:
            if self.pass_pixels:
                return [[self.image_pointer.pixels[:]],
                        self.image_pointer.size[:]]
            else:
                return [self.image_pointer]
        else:
            return data_list[:]

    def draw_buttons(self, context, layout):
        # layout.operator('node.'   ,text='refresh from scene')
        self.draw_animatable_buttons(layout, icon_only=True)
        layout.row().prop(self, "Mode", text="data")

        if self.Mode == 'objects':
            layout.prop(self, "Type", text="type")
            layout.prop_search(self,
                               'object_pointer',
                               bpy.data,
                               'objects',
                               text='name',
                               icon='OBJECT_DATA')
        elif self.Mode == 'texts':
            layout.prop_search(self,
                               'text_pointer',
                               bpy.data,
                               'texts',
                               text='name')
        elif self.Mode == 'images':
            layout.prop_search(self,
                               'image_pointer',
                               bpy.data,
                               'images',
                               text='name')
            if self.image_pointer and self.image_pointer.name:
                layout.prop(self, 'pass_pixels', text='pixels')
                layout.label(text=f"dimensions: {self.image_pointer.size[:]}")
        elif self.Mode == 'grease_pencils':
            self.draw_gp_options(context, layout)
        else:
            col = layout.column()
            col.alert = True
            col.label(text=f"This node is not yet programmed to do")
            col.label(text=f"anything sensible with bpy.data.{self.Mode}")

    def sv_init(self, context):
        self.outputs.new('SvStringsSocket', "Objects")
        self.width = 210

    def process(self):
        output_socket = self.outputs['Objects']
        if not output_socket.is_linked:
            return

        if self.Mode in {'objects', 'texts', 'images', 'grease_pencils'}:
            data_output = getattr(self, f"process_mode_{self.Mode}")()
        else:
            data_list = getattr(bpy.data, self.Mode)
            data_output = data_list[:]

        output_socket.sv_set(data_output)
Ejemplo n.º 4
0
    result = []
    color_channel, mapping_mode, match_mode = constant
    params = matching_f(params)
    local_match = iter_list_match_func[match_mode]
    mapper_func = mapper_funcs[mapping_mode]
    extract_func = color_channels[color_channel][1]
    for props in zip(*params):
        verts, texture = props
        if  not type(texture) == list:
            texture = [texture]
        m_texture = local_match([texture])[0]
        result.append([texture_evaluate(v_prop, mapper_func, extract_func) for v_prop in zip(verts, m_texture)])

    return result

color_channels_modes = [(no_space(t), t, t, '', color_channels[t][0]) for t in color_channels if not t == 'RGBA']

mapper_funcs = {
    'UV': lambda v_uv: Vector((v_uv[0]*2-1, v_uv[1]*2-1, v_uv[2])),
    'Object': lambda v: Vector(v),
}

class SvTextureEvaluateNode(bpy.types.Node, SverchCustomTreeNode, SvAnimatableNode):
    """
    Triggers: Scence Texture In
    Tooltip: Evaluate Scene texture at input coordinates

    """

    bl_idname = 'SvTextureEvaluateNode'
    bl_label = 'Texture Evaluate'
Ejemplo n.º 5
0
    mapper_func = mapper_funcs[mapping_mode]
    extract_func = color_channels[color_channel][1]
    for props in zip(*params):
        verts, texture = props
        if not type(texture) == list:
            texture = [texture]
        m_texture = local_match([texture])[0]
        result.append([
            texture_evaluate(v_prop, mapper_func, extract_func)
            for v_prop in zip(verts, m_texture)
        ])

    return result


color_channels_modes = [(no_space(t), t, t, '', color_channels[t][0])
                        for t in color_channels if not t == 'RGBA']

mapper_funcs = {
    'UV': lambda v_uv: Vector((v_uv[0] * 2 - 1, v_uv[1] * 2 - 1, v_uv[2])),
    'Object': lambda v: Vector(v),
}


class SvTextureEvaluateNode(bpy.types.Node, SverchCustomTreeNode,
                            SvAnimatableNode):
    """
    Triggers: Scence Texture In
    Tooltip: Evaluate Scene texture at input coordinates

    """
Ejemplo n.º 6
0
class SvMergeMesh2DLite(ModifierLiteNode, bpy.types.Node,
                        SverchCustomTreeNode):
    """
    Triggers: Merge 2D mesh into one
    Tooltip: Takes in account intersections and holes

    Has hidden output socket, look N panel
    """
    bl_idname = 'SvMergeMesh2DLite'
    bl_label = 'Merge mesh 2D lite'
    bl_icon = 'AUTOMERGE_ON'

    def update_sockets(self, context):
        links = {
            sock.name: [link.to_socket for link in sock.links]
            for sock in self.outputs
        }
        [self.outputs.remove(sock) for sock in self.outputs[2:]]
        new_socks = []
        if self.face_index:
            new_socks.append(self.outputs.new('SvStringsSocket', 'Face index'))
        if self.overlap_number:
            new_socks.append(
                self.outputs.new('SvStringsSocket', 'Overlap number'))
        [[self.id_data.links.new(sock, link) for link in links[sock.name]]
         for sock in new_socks if sock.name in links]
        updateNode(self, context)

    alg_mode_items = [(no_space(k), k, "", i)
                      for i, k in enumerate(['Sweep line', 'Blender'])]

    face_index: bpy.props.BoolProperty(
        name="Show face mask",
        update=update_sockets,
        description="Show output socket of index face mask")
    overlap_number: bpy.props.BoolProperty(
        name="Show number of overlapping",
        update=update_sockets,
        description="Show socket with information about number "
        "of overlapping of polygon with other polygons")
    accuracy: bpy.props.IntProperty(
        name='Accuracy',
        update=updateNode,
        default=5,
        min=3,
        max=12,
        description=
        'Some errors of the node can be fixed by changing this value')
    alg_mode: bpy.props.EnumProperty(items=alg_mode_items,
                                     name="Name of algorithm",
                                     update=updateNode)

    def draw_buttons(self, context, layout):
        layout.prop(self, 'alg_mode', expand=True)
        if self.alg_mode == "Blender" and not bl_merge_mesh:
            layout.label(text="For 2.81+ only", icon='ERROR')

    def draw_buttons_ext(self, context, layout):
        col = layout.column(align=True)
        col.prop(self, 'face_index', toggle=True)
        col.prop(self, 'overlap_number', toggle=True)
        layout.prop(self, 'accuracy')

    def sv_init(self, context):
        self.inputs.new('SvVerticesSocket', 'Verts')
        self.inputs.new('SvStringsSocket', "Faces")
        self.outputs.new('SvVerticesSocket', 'Verts')
        self.outputs.new('SvStringsSocket', "Faces")

    def process(self):
        if not all([sock.is_linked for sock in self.inputs]):
            return
        if self.alg_mode == "Blender" and not bl_merge_mesh:
            return
        out = []
        for sv_verts, sv_faces in zip(self.inputs['Verts'].sv_get(),
                                      self.inputs['Faces'].sv_get()):
            if self.alg_mode == "Sweep_line":
                out.append(
                    merge_mesh_light(sv_verts, sv_faces, self.face_index,
                                     self.overlap_number, self.accuracy))
            else:
                out.append(
                    get_bl_merge_mesh(sv_verts, sv_faces,
                                      1 / 10**self.accuracy))
        out_verts, out_faces, face_index, overlap_number = zip(*out)
        self.outputs['Verts'].sv_set(out_verts)
        self.outputs['Faces'].sv_set(out_faces)
        if self.face_index:
            self.outputs['Face index'].sv_set(face_index)
        if self.overlap_number:
            self.outputs['Overlap number'].sv_set(overlap_number)