nortikin / sverchok

Sverchok
http://nortikin.github.io/sverchok/
GNU General Public License v3.0
2.26k stars 233 forks source link

Tag based node filtering search (demo implementation) #2085

Closed zeffii closed 6 years ago

zeffii commented 6 years ago

@Ribel78 mentions an alternative node finder approach, using tags to filter down from many to few

luckily we have much of the needed bookkeeping already implemented, the one thing left is to convert a tag cloud into a workable filter interface. Lately we added the node_classes lookup, which stores data like

image

meaning we can extract the menu /category and class name split by capitalized letter..

zeffii commented 6 years ago
import bpy
import sverchok
import re

def remove_if_present(set_name, item):
    if item in set_name:
        set_name.remove(item)

for node in sverchok.utils.node_classes.items():
    Node = lambda: None
    Node.ref = node[1]
    Node.name = node[0]
    tags = re.findall('[A-Z0-9]*[a-z0-9]*', Node.name)
    tags_set = set(list(tags))
    remove_if_present(tags_set, 'Sv')
    remove_if_present(tags_set, '')
    Node.tags = tags_set
    print(Node.name, Node.tags)

image

that based purely on class name, but there's also the category we can extract..

zeffii commented 6 years ago

import bpy
import sverchok
import re
from sverchok.utils.logging import info

def remove_if_present(set_name, item):
    if item in set_name:
        set_name.remove(item)

def get_tags_from_nodename(Node):
    tags = re.findall('[A-Z0-9]*[a-z0-9]*', Node.name)
    tags_set = set(list(tags))
    remove_if_present(tags_set, 'Sv')
    remove_if_present(tags_set, '')
    return tags_set

def get_tags_from_path(Node):
    path = Node.ref.__module__.split('.')[2].title()
    return set([path])

node_tags = {}
for node in sverchok.utils.node_classes.items():
    Node = lambda: None
    Node.ref = node[1]
    Node.name = node[0]

    tags_set = get_tags_from_nodename(Node)
    tags_set.update(get_tags_from_path(Node))

    Node.tags = tags_set
    # print(Node.tags)
    node_tags[Node.name] = Node.tags

print(node_tags)

image

zeffii commented 6 years ago

we can filter the word Node too..

portnov commented 6 years ago

MkN I think should be filtered out too.

zeffii commented 6 years ago
import bpy
import sverchok
import re
from sverchok.utils.logging import info

def remove_if_present(set_name, item=None, pattern=None):
    if not pattern:
        if item in set_name:
            set_name.remove(item)
    else:
        items_to_remove = set()

        for named_item in set_name:
            if named_item.lower().startswith(pattern):
                items_to_remove.add(named_item)

        for named_item in items_to_remove:
            set_name.remove(named_item)

def get_tags_from_nodename(Node):
    tags = re.findall('[A-Z0-9]*[a-z0-9]*', Node.name)
    tags_set = set(list(tags))
    remove_if_present(tags_set, 'Sv')
    remove_if_present(tags_set, '')
    remove_if_present(tags_set, 'Node')
    remove_if_present(tags_set, pattern='mk')

    return tags_set

def get_tags_from_path(Node):
    path = Node.ref.__module__.split('.')[2].title()
    return set([path])

node_tags = {}
for node in sverchok.utils.node_classes.items():
    Node = lambda: None
    Node.ref = node[1]
    Node.name = node[0]

    tags_set = get_tags_from_nodename(Node)
    tags_set.update(get_tags_from_path(Node))

    Node.tags = tags_set
    # print(Node.tags)
    node_tags[Node.name] = Node.tags

print(node_tags)
zeffii commented 6 years ago

so now all that's let to do is generate

portnov commented 6 years ago

Tag systems are usually used for searching. I.e. for situation when I want a box and I search for "box". This actually works now with usual blender's Space or our Ctrl-Space searchboxes. Where searchboxes are not good, is questions like "what do we have here?" ("explorability"). And I'm not sure if tagging system will solve this question better.

zeffii commented 6 years ago

i also don't think this is needed.. just want to see what it looks like.

zeffii commented 6 years ago

lol....

['Adaptive', 'Along', 'Alt', 'Analyzer', 'Angles', 'Apply', 'Arc', 'Area', 'Array', 'Art', 'Asset', 'Attractor', 'Axis', 'BBox', 'BMOps', 'BMVerts', 'BMinput', 'BMoutput', 'BMto', 'Basic', 'Bend', 'Bevel', 'Bisect', 'Bmesh', 'Bmesh_Nodes', 'Boom', 'Box', 'Bricks', 'Bvh', 'CSGBoolean', 'Cache', 'Cast', 'Centers', 'Circle', 'Client', 'Color', 'Colors', 'Components', 'Connect', 'Contour', 'Convert', 'Converter', 'Convex', 'Cross', 'Curve', 'Cylinder', 'DNode', 'Data', 'Debug', 'Decompose', 'Deform', 'Del', 'Delaunay', 'Delete', 'Dissolve', 'Distance', 'Doubles', 'Drop', 'Dupli', 'Duplicate', 'Dview', 'Easing', 'Edge', 'Edges', 'Edgs', 'Edit', 'Element', 'Elman1', 'Empty', 'Euler', 'Eval', 'Evaluate', 'Exec', 'Exp', 'Exponential', 'Extrude', 'FLNode', 'Fibonacci', 'Field', 'Fills', 'Filter', 'Flip', 'Float', 'Float2', 'Formula', 'Formula2', 'Fractal', 'Frame', 'Func', 'GText', 'Gen', 'Generative', 'Generator', 'Generators_Extended', 'Generic', 'Get', 'Grease', 'Grid', 'Group', 'Heavy', 'Hexa', 'Hilbert', 'Hilbert3d', 'Hole', 'Homogenous', 'Hull', 'Icosphere', 'Image', 'In', 'Index', 'Info', 'Input', 'Inputs', 'Inset', 'Inside', 'Instancer', 'Instances', 'Int', 'Integer', 'Interpolation', 'Intersect', 'Item2', 'Iterate', 'Join', 'KDTree', 'Knot', 'LNode', 'Lacunarity', 'Lathe', 'Layout', 'Length', 'Lerp', 'Levels', 'Limited', 'Line', 'List', 'List_Main', 'List_Masks', 'List_Mutators', 'List_Struct', 'Lite', 'Logic', 'Loose', 'Map', 'Mask', 'Match', 'Math', 'Matrix', 'Mesh', 'Metaball', 'Mirror', 'Mix', 'Mod', 'Modifier', 'Modifier_Change', 'Modifier_Make', 'Monad', 'Move', 'Multi', 'NGon', 'Network', 'Neuro', 'New', 'Node2', 'Noise', 'Normal', 'Normals', 'Note', 'Num', 'Number', 'Numbers', 'Numpy', 'OBJRay', 'Obj', 'Object', 'Object_Nodes', 'Objects', 'Objs', 'Offset', 'On', 'Out', 'Outputs', 'Overlap', 'PPNode', 'Particles', 'Path', 'Pencil', 'Pipe', 'Plane', 'Point', 'Polar', 'Pols', 'Pols2', 'Polygon', 'Polyline', 'Print', 'Profile', 'Prop', 'Properties', 'Proportional', 'Props', 'Random', 'Randomize', 'Range', 'Raycaster', 'Recalc', 'Region', 'Remote', 'Remove', 'Repeater', 'Reverse', 'Rewire', 'Ring', 'Rnd', 'Rotation', 'Rounded', 'SCNRay', 'Scalar', 'Scale', 'Scene', 'Script', 'Sculpt', 'Section', 'Select', 'Separate', 'Set', 'Shape', 'Shear', 'Shift', 'Shuffle', 'Similar', 'Simple', 'Skin', 'Slice', 'Smooth', 'Solidify', 'Sort', 'Special', 'Sphere', 'Spiral', 'Spline', 'Split', 'Stethoscope', 'Stripes', 'Strokes', 'Subdivide', 'Sum', 'Surface', 'Suzanne', 'Sv3', 'Switch', 'Text', 'Texture', 'To', 'Torus', 'Track', 'Transform', 'Transforms', 'Triangles', 'Triangulate', 'Triangulation2', 'Tube', 'Turbulence', 'Type', 'UVtexture', 'Udp', 'Value', 'Vector', 'Vectors', 'Vert', 'Vertex', 'Vertices', 'Verts', 'Viewer', 'Viz', 'Volume', 'Voronoi2', 'Wafel', 'Wifi', 'Wireframe', 'Zip', 'sv']

zeffii commented 6 years ago

yeah, now i definitely don't see a practical use for this..

zeffii commented 6 years ago

further processing,

print(node_tags)
all_tags = set()
for tags in node_tags.values():
    all_tags.update(tags)

print(sorted(all_tags))
zeffii commented 6 years ago

initial list could be presented in order of Frequency, or Alphabetical

zeffii commented 6 years ago

This is still waaay to many to start an initial elastic search... by clicking on a word. https://gist.github.com/zeffii/d1db56a487aef0a12b0e61e1ddb95919

There is no UI box that can send a callback to the layout system while you're typing.. meh.. too much work man.