Advertisement
Guest User

Vraag

a guest
Apr 7th, 2015
40
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.94 KB | None
  1. import bpy
  2. from functools import partial
  3.  
  4. id_name_legal_chars = set([c for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  5.             "abcdefghijklmnopqrstuvxyz"
  6.             "1234567890._"])
  7.  
  8.  
  9. class Token(object):
  10.     def __init__(self, query_string=""):
  11.         self.child = None
  12.         self.siblings = []
  13.         self.query_string = query_string
  14.     def add(self, token, mode):
  15.         if mode in ["begin", "descendant"]:
  16.             if self.child is None:
  17.                 self.child = token
  18.             else:
  19.                 self.child.add(token, mode)
  20.         else:
  21.             if self.child is None:
  22.                 self.siblings.append(token)
  23.             else:
  24.                 self.child.add(token, mode)
  25.     def __str__(self):
  26.         s = self.__class__.__name__
  27.         s += " %s " % repr(self.query_string)
  28.         s +="("
  29.         if self.siblings:
  30.             s += ( ",".join(["%s"%o for o in self.siblings]))
  31.         if self.child is not None:
  32.             s += "-->%s" % self.child
  33.         s += ")"
  34.         return s
  35.     def build_list(self):
  36.         """ Builds a list from just the query_string. Used for the first token."""
  37.         return []
  38.  
  39.  
  40. def find_children(elements):
  41.     visited = {}
  42.     new_elements = []
  43.     def add(element):
  44.         addr = element.as_pointer()
  45.         if not addr in visited:
  46.             new_elements.append(element)
  47.             visited[addr] = True
  48.             search(element)
  49.  
  50.     def search(element):
  51.         rna = element.rna_type.name
  52.         if rna == "Scene":
  53.             for o in element.objects:
  54.                 add(o)
  55.         if rna == "Object":
  56.             add(element.data)
  57.     for element in elements:
  58.         search(element)
  59.     return new_elements
  60.  
  61. class RootToken(Token):
  62.     def search(self):
  63.         elements = self.child.build_list()
  64.         base = self.child
  65.         while 1:
  66.             for token in base.siblings:
  67.                 elements = token.filter(elements)
  68.             if base.child is None:
  69.                 break
  70.             else:
  71.                 elements = find_children(elements)
  72.             base = base.child
  73.             elements = base.filter(elements)
  74.         return elements
  75.  
  76.  
  77. class TypeToken(Token):
  78.     types = {"object": "objects",
  79.              "scene": "scenes",
  80.              "camera": "cameras",
  81.              "light": "lights",
  82.              "material": "materials"}
  83.  
  84.     def build_list(self):
  85.         l = []
  86.         q = self.query_string.lower()
  87.         if q in self.types:
  88.             attribute = self.types[q]
  89.             for o in getattr(bpy.data, attribute):
  90.                 l.append(o)
  91.         return l
  92.  
  93.  
  94.     def filter(self, elements):
  95.         new_elements = []
  96.         q = self.query_string.lower()
  97.         for element in elements:
  98.             if (element.rna_type.name).lower() == q:
  99.                 new_elements.append(element)
  100.         return new_elements
  101.  
  102.  
  103. class NameToken(Token):
  104.     collections = ["objects", "actions", "scenes", "materials"]
  105.     def build_list(self):
  106.         elements = []
  107.         for c in self.collections:
  108.             collection = getattr(bpy.data, c)
  109.             if self.query_string in collection:
  110.                 elements.append(collection[self.query_string])
  111.         return elements
  112.  
  113.  
  114.  
  115.     def filter(self, elements):
  116.         new_elements = []
  117.         for element in elements:
  118.             if hasattr(element, "name"):
  119.                 if element.name == self.query_string:
  120.                     new_elements.append(element)
  121.         return new_elements
  122.  
  123.  
  124. class ContextToken(Token):
  125.     """ Search and filter by context """
  126.     context_single_items = ["scene", "active_object", "window", "area"]
  127.     def build_list(self):
  128.         elements = []
  129.         if self.query_string in self.context_single_items:
  130.             item = getattr(bpy.context, self.query_string)
  131.             elements.append(item)
  132.         return elements
  133.     def filter(self):
  134.         return []
  135.  
  136. def hide(elements):
  137.     for element in elements:
  138.         try:
  139.             element.hide = True
  140.         except:
  141.             continue
  142.  
  143. def show(elements):
  144.     for element in elements:
  145.         try:
  146.             element.hide = False
  147.         except:
  148.             continue
  149.  
  150. def set_prop(elements, property_name, value):
  151.     for element in elements:
  152.         try:
  153.             setattr(element, property_name, value)
  154.         except:
  155.             continue
  156.     return VraagList(elements)
  157.  
  158. def iset_prop(elements, property_name, value):
  159.     for element in elements:
  160.         try:
  161.             yield setattr(element, property_name, value)
  162.         except:
  163.             continue
  164.  
  165. def get_prop(elements, property_name):
  166.     l = []
  167.     for element in elements:
  168.         try:
  169.             l.append(getattr(element, property_name))
  170.         except:
  171.             continue
  172.     return l
  173.  
  174. def iget_prop(elements, property_name):
  175.     for element in elements:
  176.         try:
  177.             yield getattr(element, property_name)
  178.         except:
  179.             continue
  180.  
  181. def iprop(elements, property_name, value=None):
  182.     l = []
  183.     if value is None:
  184.         yield iget_prop(elements, property_name)
  185.     else:
  186.         yield iset_prop(elements, property_name, value)
  187. def prop(elements, property_name, value=None):
  188.     l = []
  189.     if value is None:
  190.         return get_prop(elements, property_name)
  191.     else:
  192.         return set_prop(elements, property_name, value)
  193.  
  194. def apply(elements, func):
  195.     for element in elements:
  196.         yield func(element)
  197.  
  198. def each(elements, func):
  199.     for result in apply(elements, func):
  200.         pass
  201.     return VraagList(elements)
  202.  
  203.  
  204. verbs = {'hide': hide,
  205.          'show':show,
  206.          'prop': prop,
  207.          'set_prop': set_prop,
  208.          'get_prop': get_prop,
  209.          'iset_prop': iset_prop,
  210.          'iget_prop': iget_prop,
  211.          'apply': apply,
  212.          'each': each,
  213.          'location': partial(prop,property_name="location")
  214.          }
  215.  
  216. class VraagList(object):
  217.     def __init__(self, elements):
  218.         self.elements = elements
  219.     def __getattr__(self, name):
  220.         if name in verbs:
  221.             return partial(verbs[name], self.elements)
  222.         else:
  223.             raise NameError("No Vraag function called '{0}'.".format(name))
  224.  
  225.  
  226.     def __len__(self):
  227.         return len(self.elements)
  228.     def __iter__(self):
  229.         return iter(self.elements)
  230.  
  231.  
  232.     def __getitem__(self, i):
  233.         return self.elements[i]
  234.  
  235.  
  236.     def __str__(self):
  237.         return "VraagList {0}".format(self.elements)
  238.  
  239. class Selector(object):
  240.     def __init__(self, query):
  241.         self.query = query
  242.         self.token = RootToken()
  243.         self.tokenize(query)
  244.  
  245.     def parse(self):
  246.         def white_space():
  247.             c = " "
  248.             while c==" " :
  249.                 c = yield
  250.             return c
  251.         def id_name():
  252.             name = ""
  253.             c = yield
  254.             while c in id_name_legal_chars:
  255.                 name += c
  256.                 c = yield
  257.             yield 1
  258.             return name
  259.  
  260.         mode = "begin"
  261.         c = yield from white_space()
  262.         while 1:
  263.             if mode is "descendant" and c==" ":
  264.                 c = yield from white_space()
  265.             if c == "\n":
  266.                 break
  267.             if c == "#":
  268.                 name = yield from id_name()
  269.                 self.token.add(NameToken(name), mode)
  270.             elif c == "§":
  271.                 group_name = yield from id_name()
  272.                 print("By Group:", group_name)
  273.             elif c == "@":
  274.                 name = yield from id_name()
  275.                 self.token.add(ContextToken(name), mode)
  276.             else:
  277.                 name = c + (yield from id_name())
  278.                 self.token.add(TypeToken(name), mode)
  279.             c = yield
  280.             if c in "#§@":
  281.                 mode = "attach"
  282.             else:
  283.                 mode = "descendant"
  284.  
  285.     def tokenize(self, query):
  286.         tokenizer = self.parse()
  287.         next(tokenizer)
  288.         pos = 0
  289.         while 1:
  290.             if pos < len(query):
  291.                 # Send current character
  292.                 c = query[pos]
  293.             else:
  294.                 # Send end of line
  295.                 c = "\n"
  296.  
  297.             try:
  298.                 backsteps = tokenizer.send(c)
  299.             except StopIteration:
  300.                 break
  301.  
  302.             # Handle backstepping
  303.             if backsteps is not None:
  304.                 pos -= backsteps
  305.             else:
  306.                 pos += 1
  307.  
  308.  
  309.  
  310.  
  311. def V(query_string):
  312.     s = Selector(query_string)
  313.     elements = s.token.search()
  314.     return VraagList(elements)
  315. if __name__ == "Main":
  316.     test_queries = ["object",
  317.                     "object#Cube",
  318.                     "#Cube",
  319.                     "@scene object",
  320.                     "@scene camera",
  321.                     "#Scene1 object#Suzanne"
  322.                     ]
  323.  
  324.  
  325.     for q in test_queries:
  326.         s = Selector(q)
  327.         print(repr(q))
  328.         print(s.token)
  329.         elements = s.token.search()
  330.         for o in elements:
  331.             print(o)
Advertisement
RAW Paste Data Copied
Advertisement