diff options
author | meta-androcto <meta.androcto1@gmail.com> | 2017-04-24 03:33:31 +0300 |
---|---|---|
committer | meta-androcto <meta.androcto1@gmail.com> | 2017-04-24 03:33:31 +0300 |
commit | 8b7a78110f4a702018e23672361f228d15d2e6f5 (patch) | |
tree | 39c69af0c076a2d340d45fea9394c9bf1393c851 /materials_library_vx | |
parent | 7fc71a4856f65c42f5c0711d440d2e2136df0de3 (diff) |
Initial Commit materials library: T51230 T50357
Diffstat (limited to 'materials_library_vx')
-rw-r--r-- | materials_library_vx/__init__.py | 1203 | ||||
-rw-r--r-- | materials_library_vx/cycles_templates.blend | bin | 0 -> 174321 bytes | |||
-rw-r--r-- | materials_library_vx/materials.blend | bin | 0 -> 98014 bytes |
3 files changed, 1203 insertions, 0 deletions
diff --git a/materials_library_vx/__init__.py b/materials_library_vx/__init__.py new file mode 100644 index 00000000..39bb55d2 --- /dev/null +++ b/materials_library_vx/__init__.py @@ -0,0 +1,1203 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### +# contributed to by meta-androcto + +bl_info = { + "name": "Material Library VX", + "author": "Mackraken", + "version": (1, 0, 1), + "blender": (2, 77, 0), + "location": "Properties > Material", + "description": "Material Library VX", + "warning": "", + "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/matlib-vx-5-6", + "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/", + "category": "Material"} + +# TODO: translate comments, cleanup imports, remove dead code, fix xml set fiter crash + +import bpy +import json +import zipfile +import urllib.request +import os +import sys +import re +import csv +import codecs +import collections +import subprocess +import webbrowser +from bpy.types import ( + Operator, + Menu, + Panel, + PropertyGroup, + AddonPreferences, + ) +from bpy.props import ( + BoolProperty, + CollectionProperty, + EnumProperty, + IntProperty, + StringProperty, + PointerProperty, + ) + + +dev = False +matlib_path = os.path.dirname(__file__) + +if dev: + matlib_path = r"D:\Blender Foundation\Blender\2.72\scripts\addons\matlib" + + +# debug print variables +def dd(*args, dodir=False): + if dev: + if dodir: + print(dir(*args)) + print(*args) + + +# add-on settings +def addon_settings(): + # separate function just for more convience + addon = bpy.context.user_preferences.addons[__name__] + compact = addon.preferences.use_brushes_menu_type + + return compact + + +# Regular Functions +def winpath(path): + return path.replace("\\", "\\\\") + + +def update_search_index(self, context): + search = self.search + for i, it in enumerate(self.materials): + if it.name == search: + self.mat_index = i + break + + +def check_path(path): + # isabs sometimes returns true on relpaths + if path and os.path.exists(path) and os.path.isfile(path) and os.path.isabs(path): + try: + if bpy.data.filepath and bpy.path.relpath(bpy.data.filepath) == bpy.path.relpath(path): + return False + except: + pass + # paths are on different drives. No problem then + return True + return False + + +def update_lib_index(self, context): + self.load_library() + + +def update_cat_index(self, context): + dd("cat index:", self.current_category, self.filters) + + if self.filters: + self.filters = True + + +def update_filter(self, context): + + dd("filter:", self.filters, self.cat_index, self.current_category) + """ + index = self.cat_index + + if self.filters: + cat = self.current_category + else: + cat = "" + + self.current_library.filters = cat + """ + self.update_list() + + +def check_index(collection, index): + count = len(collection) + return count > 0 and index < count and index >= 0 + + +def send_command(cmd, output="sendmat.py"): + bin = winpath(bpy.app.binary_path) + scriptpath = winpath(os.path.join(matlib_path, output)) + + with open(scriptpath, "w") as f: + f.write(cmd) + + if output == "createlib.py": + code = subprocess.call([bin, "-b", "-P", scriptpath]) + else: + libpath = winpath(bpy.context.scene.matlib.current_library.path) + code = subprocess.call([bin, "-b", libpath, "-P", scriptpath]) + + # code returns 0 if ok, 1 if not + return abs(code - 1) + + +def list_materials(path, sort=False): + list = [] + with bpy.data.libraries.load(path) as (data_from, data_to): + for mat in data_from.materials: + list.append(mat) + + if sort: + list = sorted(list) + return list + + +# category properties (none atm) +class EmptyGroup(PropertyGroup): + pass + + +bpy.utils.register_class(EmptyGroup) + + +class matlibMaterials(PropertyGroup): + category = StringProperty() + + +bpy.utils.register_class(matlibMaterials) + + +# bpy.types.Scene.matlib_categories = CollectionProperty(type=EmptyGroup) + + +# CATEGORIES +class Categories(): + + # cats = bpy.context.scene.matlib.categories + + def __init__(self, cats): + self.cats = cats + + def save(self): + scn = bpy.context.scene + cats = set([cat.name for cat in self.cats]) + libpath = bpy.context.scene.matlib.current_library.path + + cmd = """ +print(30*"+") +import bpy +if not hasattr(bpy.context.scene, "matlib_categories"): + class EmptyProps(bpy.types.PropertyGroup): + pass + bpy.utils.register_class(EmptyProps) + bpy.types.Scene.matlib_categories = bpy.props.CollectionProperty(type=EmptyProps) +cats = bpy.context.scene.matlib_categories +for cat in cats: + cats.remove(0) +""" + for cat in cats: + cmd += """ +cat = cats.add() +cat.name = "%s" """ % cat.capitalize() + cmd += ''' +bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % winpath(libpath) + + return send_command(cmd, "save_categories.py") + + def read(self, pull=True): + # mandar a imprimir el listado + catfile = winpath(os.path.join(matlib_path, "categories.txt")) + cmd = """ +import bpy, json +class EmptyProps(bpy.types.PropertyGroup): + pass +bpy.utils.register_class(EmptyProps) +bpy.types.Scene.matlib_categories = bpy.props.CollectionProperty(type=EmptyProps) +cats = [] +for cat in bpy.context.scene.matlib_categories: + materials = [] + for mat in bpy.data.materials: + if "category" in mat.keys() and mat['category'] == cat.name: + materials.append(mat.name) + cats.append([cat.name, materials]) +with open("%s", "w") as f: + f.write(json.dumps(cats, sort_keys=True, indent=4)) +""" % catfile + if pull: + send_command(cmd) + + # leer el fichero + with open(catfile, "r") as f: + cats = json.loads(f.read()) + + dd(cats) + """ + # refrescar categorias + for cat in self.cats: + self.cats.remove(0) + + for cat in cats: + item = self.cats.add() + item.name = cat + """ + return cats + + def view(self): + for cat in self.cats: + dd(cat.name) + + def add(self, name): + if name and name not in [item.name for item in self.cats]: + name = name.strip().capitalize() + item = self.cats.add() + item.name = name + if self.save(): + dd(name, "added") + return True + else: + dd("duplicated?") + + def remove(self, index): + self.cats.remove(index) + self.save() + + +class Library(): + + def __init__(self, name): + self.name = name + self.path = os.path.join(matlib_path, name) + """ + @property + def default(self): + return self.name == default_library + """ + @property + def shortname(self): + # if self.default: + # return "Default Library" + return bpy.path.display_name(self.name).title() + + def __repr__(self): + return str(type(self).__name__) + "('" + self.name + "')" + + +# bpy.utils.register_class(Library) + +def get_libraries(): + libs = [Library(f) for f in os.listdir(matlib_path) if f[-5::] == "blend"] + return sorted(libs, key=lambda x: bpy.path.display_name(x.name)) + + +libraries = get_libraries() + + +# MATLIB CLASS +class matlibProperties(PropertyGroup): + + # MATLIB PROPERTIES + + # libraries are read from the xml + lib_index = IntProperty( + min=-1, + default=-1, + update=update_lib_index + ) + all_materials = CollectionProperty( + type=matlibMaterials + ) + materials = CollectionProperty( + type=matlibMaterials + ) + mat_index = IntProperty( + min=-1, default=-1 + ) + categories = CollectionProperty( + type=EmptyGroup + ) + cat_index = IntProperty( + min=-1, + default=-1, + update=update_cat_index + ) + search = StringProperty( + name="Search", + description="Find By Name", + update=update_search_index + ) + + # MATLIB OPTIONS + # link: import material linked + # force import: + # if disable it wont import a material if its present in the scene,(avoid duplicates) + # instead it will apply the scene material rather than importing the same one from the library + # filters: enable or disable category filter + # last selected: store the last selected object to regain focus when apply a material. + # hide_search: Hides Search Field + + link = BoolProperty( + name="Linked", + description="Link the material", + default=False + ) + force_import = BoolProperty( + name="Force Import", + description="Use Scene Materials by default", + default=False + ) + filters = BoolProperty( + name="Filter", + description="Filter Categories", + default=False, + update=update_filter + ) + show_prefs = BoolProperty( + name="show_prefs", + description="Preferences", + default=False + ) + last_selected = StringProperty( + name="Last Selected" + ) + hide_search = BoolProperty( + name="Hide Search", + description="Use Blender Search Only" + ) + + # import_file = StringProperty("Import File", subtype="FILE_PATH") + # path = os.path.dirname(path) + # Development only + + @property + def libraries(self): + global libraries + return libraries + + @property + def current_library(self): + if check_index(libraries, self.lib_index): + return libraries[self.lib_index] + + @property + def active_material(self): + if check_index(self.materials, self.mat_index): + return self.materials[self.mat_index] + + def reload(self): + dd("loading libraries") + + if self.current_library: + self.load_library() + elif self.lib_index == -1 and len(libraries): + self.lib_index = 0 + + def add_library(self, path, setEnabled=False): + # sanitize path + ext = os.path.extsep + "blend" + if not path.endswith(ext): + path += ext + + if check_path(path): + # if path == default_library: + # return 'ERROR', "Cannot add default library." + # if path in [lib.path for lib in self.libraries]: + return 'ERROR', "Library already exists." + else: + dd("Can't find " + path) + # create file + cmd = ''' +import bpy +bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % winpath(path) + if not (send_command(cmd, "createlib.py")): + return 'ERROR', "There was an error creating the file. Make sure you run Blender with admin rights." + + # self.libraries = sorted(self.libraries, key=lambda lib: sortlibs(lib)) + dd("adding library", path) + global libraries + libraries = get_libraries() + return "INFO", "Library added" + + def load_library(self): + self.empty_list(True) + if not self.current_library: + return 'ERROR', "Library not found!." + + path = self.current_library.path + + dd("loading library", self.lib_index, path) + + if check_path(path): + self.filters = False + self.cat_index = -1 + + categories = Categories(self.categories) + self.cats = categories.read(True) + self.load_categories() + + for mat in self.all_materials: + self.all_materials.remove(0) + + for mat in list_materials(self.current_library.path, True): + item = self.all_materials.add() + item.name = mat + for cat in self.cats: + if mat in cat[1]: + item.category = cat[0] + break + + self.update_list() + else: + return 'ERROR', "Library not found!" + + def update_list(self): + # THIS HAS TO SORT + self.empty_list() + if self.current_library: + current_category = self.current_category + # sorteditems = sorted(self.all_materials, key=lambda x: x.name) + for mat in self.all_materials: + # print(current_category, mat.category) + if not self.filters or (self.filters and mat.category == current_category) or \ + current_category == "": + item = self.materials.add() + item.name = mat.name + item.category = mat.category + + def empty_list(self, cats=False): + # self.mat_index = -1 + for it in self.materials: + self.materials.remove(0) + + if cats: + for c in self.categories: + self.categories.remove(0) + + # CATEGORIES + @property + def current_category(self): + # print(self.mat_index) + if check_index(self.categories, self.cat_index): + return self.categories[self.cat_index].name + return "" + + def load_categories(self): + + for c in self.categories: + self.categories.remove(0) + + for c in self.cats: + cat = self.categories.add() + cat.name = c[0] + + def add_category(self, name): + if name: + name = name.strip().title() + dd("add category", name) + categories = Categories(self.categories) + + categories.add(name) + """ + if lib: + cat = xml.find("category", name, lib, create = True) + self.load_categories() + else: + return 'ERROR', "Library not found" + """ + def remove_category(self): + dd("removing category", self.current_category) + categories = Categories(self.categories) + categories.remove(self.cat_index) + + def set_category(self): + mat = self.active_material + # dd(lib, mat, self.current_category) + if mat: + # set mat to category + if self.cat_index > -1: + dd(self.current_category) + cat = self.current_category + if cat == self.all_materials[self.mat_index].category: + return + cmd = """ +import bpy +try: + mat = bpy.data.materials['%s'] +except: + mat = None +if mat: + mat['category'] = "%s" + bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True) +""" % (mat.name, cat, winpath(self.current_library.path)) + if send_command(cmd): + self.all_materials[self.mat_index].category = cat + mat.category = cat + else: + return "WARNING", "There was an error." + + # catnode = xml.find("category", self.current_category, lib, True) + # matnode = xml.find("material", mat.name, lib) + # if matnode: + # catnode.appendChild(matnode) + # else: + # matnode = xml.find("material", mat.name, catnode, True) + # xml.save() + # mat.category = cat + # self.current_library.materials[self.mat_index].category = cat + # remove mat from any category + else: + """ + matnode = xml.find("material", mat.name, lib) + if matnode: + xml.deleteNode(matnode) + """ + mat.category = "" + self.current_library.materials[self.mat_index].category = "" + else: + return "WARNING", "Select a material" + + def get_material(self, name, link=False): + with bpy.data.libraries.load(self.current_library.path, link, False) as (data_from, data_to): + data_to.materials = [name] + if link: + print(name + " linked.") + else: + print(name + " appended.") + + def apply(self, context, preview=False): + name = self.active_material.name + if not name: + return "WARNING", "Select a material from the list." + + linked = self.link or preview + force = self.force_import or linked + + objects = [] + active = context.object + dummy = self.get_dummy(context) + + # setup objects + if preview: + if context.mode == "EDIT_MESH": + return "WARNING", "Can't preview on EDIT MODE" + + if dummy != active: + self.last_selected = context.object.name + context.scene.objects.active = dummy + objects.append(dummy) + # apply + else: + objects = [obj for obj in context.selected_objects if hasattr(obj.data, "materials")] + + if not objects: + return "INFO", "Please select an object" + + if dummy == context.object and not preview: + if (len(objects) == 1 and dummy.select): + return "ERROR", "Apply is disabled for the Material Preview Object" + try: + last = context.scene.objects[self.last_selected] + if last in context.selected_objects: + context.scene.objects.active = last + else: + self.last_selected = "" + except: + context.scene.objects.active = None + dummy.select = False +# objects = context.selected_objects + + material = None + + # mira si hay materiales linkados de la libreria actual + for mat in bpy.data.materials: + try: + samelib = bpy.path.relpath(mat.library.filepath) == bpy.path.relpath(self.current_library.path) + except: + samelib = False + + if mat.name == name and mat.library and samelib: + material = mat + dd("encontre linked", name, "no importo nada") + break + + if not force: + # busca materiales no linkados + for mat in bpy.data.materials: + if mat.name == name and not mat.library: + material = mat + dd("encontre no linkado", name, "no importo nada") + break + + if not material: + # go get it + dd("voy a buscarlo") + nmats = len(bpy.data.materials) + self.get_material(name, linked) + if nmats == len(bpy.data.materials) and not linked: + return "ERROR", name + " doesn't exists at library " + str(linked) + else: + for mat in reversed(bpy.data.materials): + if mat.name[0:len(name)] == name: + # careful on how blender writes library paths + try: + samelib = bpy.path.relpath(mat.library.filepath) == \ + bpy.path.relpath(self.current_library.path) + except: + samelib = False + + if linked and mat.library and samelib: + material = mat + dd(name, "importado con link") + break + else: + if not mat.library: + dd(name, "importado sin link") + material = mat + break + if material: + material.use_fake_user = False + material.user_clear() + + # print ("Material", material) + + # if material: + # maybe some test cases doesnt return a material, gotta take care of that + # i cannot think of any case like that right now + # maybe import linked when the database isnt sync + if context.mode == "EDIT_MESH": + obj = context.object + dd(material) + index = -1 + for i, mat in enumerate(obj.data.materials): + if mat == material: + index = i + break + + if index == -1: + obj.data.materials.append(material) + index = len(obj.data.materials) - 1 + dd(index) + import bmesh + bm = bmesh.from_edit_mesh(obj.data) + for f in bm.faces: + if f.select: + f.material_index = index + + else: + for obj in objects: + index = obj.active_material_index + if index < len(obj.material_slots): + obj.material_slots[index].material = None + obj.material_slots[index].material = material + else: + obj.data.materials.append(material) + + if not linked: + bpy.ops.object.make_local(type="SELECT_OBDATA_MATERIAL") + + def add_material(self, mat): + + if not mat: + return 'WARNING', "Select a material from the scene." + + name = mat.name + thispath = winpath(bpy.data.filepath) + libpath = winpath(self.current_library.path) + + if not thispath: + return 'WARNING', "Save this file before export." + + if not libpath: + return 'WARNING', "Library not found!." + + elif bpy.data.is_dirty: + bpy.ops.wm.save_mainfile(check_existing=True) + + if mat.library: + return 'WARNING', 'Cannot export linked materials.' + + dd("adding material", name, libpath) + + overwrite = "" + if name in list_materials(libpath): + overwrite = ''' +mat = bpy.data.materials["%s"] +mat.name = "tmp" +mat.use_fake_user = False +mat.user_clear()''' % name + + cmd = ''' +import bpy{0} +with bpy.data.libraries.load("{1}") as (data_from, data_to): + data_to.materials = ["{2}"] +mat = bpy.data.materials["{2}"] +mat.use_fake_user=True +bpy.ops.file.pack_all() +bpy.ops.wm.save_mainfile(filepath="{3}", check_existing=False, compress=True) +'''.format(overwrite, thispath, name, libpath) + + if send_command(cmd): + # self.load_library() + if not overwrite: + item = self.all_materials.add() + item.name = name + if "category" in mat.keys(): + item.category = mat['category'] + # reorder all_materials + items = sorted([[item.name, item.category] for item in self.all_materials], + key=lambda x: x[0]) + + self.all_materials.clear() + for it in items: + item = self.all_materials.add() + item.name = it[0] + item.category = it[1] + + self.update_list() + + return 'INFO', "Material added." + else: + print("Save Material Error: Run Blender with administrative priviledges.") + return 'WARNING', "There was an error saving the material" + + def remove_material(self): + name = self.active_material.name + libpath = winpath(self.current_library.path) + if name and libpath and name in list_materials(libpath): + cmd = '''import bpy +mat = bpy.data.materials["%s"] +mat.use_fake_user = False +mat.user_clear() +bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % (name, libpath) + if send_command(cmd, "removemat.py"): + self.all_materials.remove(self.mat_index) + self.update_list() + else: + return 'ERROR', "There was an error." + return "INFO", name + " removed." + + def get_dummy(self, context): + dummy_name = "Material_Preview_Dummy" + dummy_mesh = "Material_Preview_Mesh" + scn = context.scene + try: + dummy = scn.objects[dummy_name] + except: + # create dummy + try: + me = bpy.data.meshes(dummy_mesh) + except: + me = bpy.data.meshes.new(dummy_mesh) + dummy = bpy.data.objects.new(dummy_name, me) + scn.objects.link(dummy) + + dummy.hide = True + dummy.hide_render = True + dummy.hide_select = True + return dummy + + +bpy.utils.register_class(matlibProperties) +bpy.types.Scene.matlib = PointerProperty(type=matlibProperties) + + +# MENUS +class matlibLibsMenu(Menu): + bl_idname = "matlib.libs_menu" + bl_label = "Libraries Menu" + bl_description = "Main Categories Menu" + + def draw(self, context): + layout = self.layout + libs = libraries + # layout.operator("matlib.operator", text="Default Library").cmd = "lib-1" + + for i, lib in enumerate(libs): + layout.operator("matlib.operator", text=lib.shortname).cmd = "lib" + str(i) + + +class matlibCatsMenu(Menu): + bl_idname = "matlib.cats_menu" + bl_label = "Categories Menu" + bl_description = "Sub Categories Menu" + + def draw(self, context): + layout = self.layout + cats = context.scene.matlib.categories + layout.operator("matlib.operator", text="All").cmd = "cat-1" + + for i, cat in enumerate(cats): + layout.operator("matlib.operator", text=cat.name).cmd = "cat" + str(i) + + +# OPERATORS + +class matlibOperator(Operator): + """Add, Remove, Reload, Apply, Preview, Clean Material""" + bl_label = "New" + bl_idname = "matlib.operator" + __doc__ = "Add, Remove, Reload, Apply, Preview, Clean Material" + + category = StringProperty( + name="Category" + ) + filepath = StringProperty( + options={'HIDDEN'} + ) + cmd = StringProperty( + name="Command", + options={'HIDDEN'} + ) + filter_glob = StringProperty( + default="*.blend", + options={'HIDDEN'} + ) + + @classmethod + def poll(cls, context): + return context.active_object is not None + + def draw(self, context): + layout = self.layout + # cmd = LIBRARY_ADD + if self.cmd == "LIBRARY_ADD": + # layout.label("Select a blend file as library or") + # layout.label("Type a name to create a new library.") + layout.prop(self, "category", text="Library") + elif self.cmd == "FILTER_ADD": + layout.prop(self, "category") + + def invoke(self, context, event): + cmd = self.cmd + print("invoke", cmd) + + if cmd == "LIBRARY_ADD": + self.filepath = matlib_path + os.path.sep + dd("filepath", self.filepath, matlib_path) + # context.window_manager.fileselect_add(self) + context.window_manager.invoke_props_dialog(self) + return {'RUNNING_MODAL'} + elif cmd == "FILTER_ADD": + context.window_manager.invoke_props_dialog(self) + return {'RUNNING_MODAL'} + return self.execute(context) + + def execute(self, context): + # TODO: execute doesnt trigger remove + success = "" + matlib = context.scene.matlib + + if self.cmd == "init": + print("initialize") + return {'FINISHED'} + + # Library Commands + if self.cmd[0:3] == "lib": + index = int(self.cmd[3::]) + matlib.lib_index = index + # success = matlib.load_library() + elif self.cmd == "LIBRARY_ADD": + dd("execute lib add") + libname = self.category + if libname[-6::] != ".blend": + libname += ".blend" + libname = os.path.join(matlib_path, libname) + print(libname) + + success = matlib.add_library(libname, True) + for i, l in enumerate(libraries): + if l.name == self.category: + matlib.lib_index = i + break + + elif self.cmd == "RELOAD": + success = matlib.reload() + + if not matlib.current_library: + self.report({'ERROR'}, "Select a Library") + return {'CANCELLED'} + + if self.cmd == "FILTER_ADD": + success = matlib.add_category(self.category) + for i, cat in enumerate(matlib.categories): + if cat.name == self.category: + matlib.cat_index = i + break + + elif self.cmd == "FILTER_REMOVE": + matlib.remove_category() + + elif self.cmd == "FILTER_SET": + success = matlib.set_category() + + elif self.cmd[0:3] == "cat": + index = int(self.cmd[3::]) + matlib.cat_index = index + + # Common Commands + elif self.cmd == "ADD": + success = matlib.add_material(context.object.active_material) + + elif self.cmd == "REMOVE": + success = matlib.remove_material() + + elif self.cmd == "APPLY": + success = matlib.apply(context) + + elif self.cmd == "PREVIEW": + success = matlib.apply(context, True) + + elif self.cmd == "FLUSH": + # release dummy materials + dummy = matlib.get_dummy(context) + if dummy == context.object: + try: + context.scene.objects.active = scn.objects[matlib.last_selected] + except: + pass + + for slot in dummy.material_slots: + slot.material = None + i = 0 + for mat in bpy.data.materials: + if mat.users == 0: + i += 1 + print(mat.name, "removed.") + bpy.data.materials.remove(mat) + + plural = "s" + if i == 1: + plural = "" + + self.report({'INFO'}, str(i) + " material" + plural + " removed.") + + # CONVERT + elif self.cmd == "CONVERT": + return {'FINISHED'} + lib = matlib.current_library + if lib: + + path = os.path.join(matlib_path, "www") + if not os.path.exists(path): + os.mkdir(path) + path = os.path.join(path, lib.shortname) + if not os.path.exists(path): + os.mkdir(path) + + path = winpath(path) + libpath = winpath(lib.name) + + print(path) + print(libpath) + +# decirle a la libreria que cree un fichero blend por cada material que tenga. + cmd = """ +print(30*"+") +import bpy, os +def list_materials(): + list = [] + with bpy.data.libraries.load("{0}") as (data_from, data_to): + for mat in data_from.materials: + list.append(mat) + return sorted(list) + +def get_material(name, link=False): + with bpy.data.libraries.load("{0}", link, False) as (data_from, data_to): + data_to.materials = [name] + if link: + print(name + " linked.") + else: + print(name + " appended.") + +for scn in bpy.data.scenes: + for obj in scn.objects: + scn.objects.unlink(obj) + obj.user_clear() + bpy.data.objects.remove(obj) + +def clean_materials(): + for mat in bpy.data.materials: + mat.user_clear() + bpy.data.materials.remove(mat) + +bin = bpy.app.binary_path +mats = list_materials() +bpy.context.user_preferences.filepaths.save_version = 0 +for mat in mats: + clean_materials() + matpath = os.path.join("{1}", mat + ".blend") + print(matpath) + get_material(mat) + material = bpy.data.materials[0] + material.use_fake_user = True + bpy.ops.wm.save_mainfile(filepath = matpath, compress=True, check_existing=False) +""".format(libpath, path) + print(cmd) + send_command(cmd, "createlib.py") + + if type(success).__name__ == "tuple": + print(success) + self.report({success[0]}, success[1]) + + return {'FINISHED'} + + +class matlibvxPanel(Panel): + bl_label = "Material Library VX" + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "material" + + @classmethod + def poll(self, context): + return context.active_object.active_material is not None + + def draw(self, context): + layout = self.layout + matlib = context.scene.matlib + """ + # hyper ugly trick but i dont know how to init classes at register time + if matlibProperties.init: + matlibProperties.init = False + matlib.__init__() + """ + # libaries + row = layout.row(align=True) + if matlib.current_library: + text = matlib.current_library.shortname + else: + text = "Select Library" + row.menu("matlib.libs_menu", text=text) + if matlib.active_material: + row.label(matlib.active_material.category) + else: + row.label("") + + # search + if not matlib.hide_search: + row = layout.row() + row.prop_search(matlib, "search", matlib, "materials", text="", icon="VIEWZOOM") + + # list + col = self.layout.column(align=True) + row = col.row(align=True) + row.template_list("UI_UL_list", " ", matlib, "materials", matlib, "mat_index", rows=6) + + col = self.layout.column(align=True) + row = col.row(align=True) + # operators + row.operator("matlib.operator", icon="MATERIAL", text="Apply").cmd = "APPLY" + row.operator("matlib.operator", icon="COLOR", text="Preview").cmd = "PREVIEW" + + col = self.layout.column(align=True) + row = col.row(align=True) + row.operator("matlib.operator", icon="ZOOMIN", text="Add Mat").cmd = "ADD" + row.operator("matlib.operator", icon="ZOOMOUT", text="Remove Mat").cmd = "REMOVE" + + col = self.layout.column(align=True) + row = col.row(align=True) + row.operator("matlib.operator", icon="FILE_REFRESH", text="Reload").cmd = "RELOAD" + row.operator("matlib.operator", icon="GHOST_DISABLED", text="Flush Unused").cmd = "FLUSH" + + col = self.layout.column(align=True) + row = col.row(align=True) + col.prop(matlib, "show_prefs", icon="MODIFIER", text="Advanced") + + # prefs + if matlib.show_prefs: + row = layout.row() + row.prop(matlib, "force_import") + row.prop(matlib, "link") + row = layout.row() + row.prop(matlib, "hide_search") + # row = layout.row(align=True) + # row = layout.row() + # row.operator("matlib.operator", icon="URL", text="Convert Library").cmd = "CONVERT" + # categories + row = layout.row() + row.operator("matlib.operator", icon="ZOOMIN", text="Add library").cmd = "LIBRARY_ADD" + row = layout.row(align=True) + text = "All" + if matlib.current_category: + text = matlib.current_category + + if addon_settings() == "normal": + col = self.layout.column(align=True) + row = col.row(align=True) + row.menu("matlib.cats_menu", text=text) + col = self.layout.column(align=True) + row = col.row(align=True) + row.prop(matlib, "filters", icon="FILTER", text="Filter Category") + row.operator("matlib.operator", icon="FILE_PARENT", text="Set Filter").cmd = "FILTER_SET" + col = self.layout.column(align=True) + row = col.row(align=True) + row.operator("matlib.operator", icon="ZOOMIN", text="Add Filter").cmd = "FILTER_ADD" + row.operator("matlib.operator", icon="ZOOMOUT", text="Remove Filter").cmd = "FILTER_REMOVE" + else: + row.menu("matlib.cats_menu", text=text) + row.prop(matlib, "filters", icon="FILTER", text="") + row.operator("matlib.operator", icon="FILE_PARENT", text="").cmd = "FILTER_SET" + row.operator("matlib.operator", icon="ZOOMIN", text="").cmd = "FILTER_ADD" + row.operator("matlib.operator", icon="ZOOMOUT", text="").cmd = "FILTER_REMOVE" + + +class matlibvxPref(AddonPreferences): + bl_idname = __name__ + + use_brushes_menu_type = EnumProperty( + name="Choose Panel layout", + description="", + items=[('compact', "Icon only panels", + "Use more compact layout"), + ('normal', "Icon and text panels", + "Use an usually spaced layout") + ], + default='normal' + ) + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + row = col.row(align=True) + row.prop(self, "use_brushes_menu_type", expand=True) + + +classes = ( + matlibvxPanel, + matlibOperator, + matlibLibsMenu, + matlibCatsMenu, + matlibvxPref, + ) + + +def register(): + for cls in classes: + bpy.utils.register_class(cls) + + +def unregister(): + for cls in classes: + bpy.utils.unregister_class(cls) + + +if __name__ == "__main__": + register()
\ No newline at end of file diff --git a/materials_library_vx/cycles_templates.blend b/materials_library_vx/cycles_templates.blend Binary files differnew file mode 100644 index 00000000..ce97446a --- /dev/null +++ b/materials_library_vx/cycles_templates.blend diff --git a/materials_library_vx/materials.blend b/materials_library_vx/materials.blend Binary files differnew file mode 100644 index 00000000..abd0bb00 --- /dev/null +++ b/materials_library_vx/materials.blend |