Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeta-androcto <meta.androcto1@gmail.com>2017-07-05 04:18:23 +0300
committermeta-androcto <meta.androcto1@gmail.com>2017-07-05 04:18:23 +0300
commitce5538eca22a69ddaa6e1efd342a32749651623e (patch)
tree827fb62353afce20f015c48461220f803499e32d /materials_library_vx
parent99ed610784b804c175d9e189d9a1b3036973ed61 (diff)
matlibvx: addons prefs custom file path by stephen-l
Diffstat (limited to 'materials_library_vx')
-rw-r--r--materials_library_vx/__init__.py2202
1 files changed, 1136 insertions, 1066 deletions
diff --git a/materials_library_vx/__init__.py b/materials_library_vx/__init__.py
index 01dac494..fe456e6d 100644
--- a/materials_library_vx/__init__.py
+++ b/materials_library_vx/__init__.py
@@ -1,3 +1,5 @@
+# -*- coding:utf-8 -*-
+
# #####BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
@@ -17,1170 +19,1238 @@
# #####END GPL LICENSE BLOCK #####
bl_info = {
- "name": "Material Library",
- "author": "Mackraken (mackraken2023@hotmail.com)",
- "version": (0, 5, 7),
- "blender": (2, 7, 8),
- "api": 60995,
- "location": "Properties > Material",
- "description": "Material Library VX",
- "warning": "",
- "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/matlib-vx",
- "tracker_url": "",
- "category": "Material"}
-
-
-import bpy, os, json
-from bpy.props import *
+ "name": "Material Library",
+ "author": "Mackraken (mackraken2023@hotmail.com)",
+ "version": (0, 5, 7),
+ "blender": (2, 7, 8),
+ "api": 60995,
+ "location": "Properties > Material",
+ "description": "Material Library VX",
+ "warning": "",
+ "wiki_url": "https://sites.google.com/site/aleonserra/home/scripts/matlib-vx",
+ "tracker_url": "",
+ "category": "Material"}
+
+
+import bpy
+import os
+import json
+from bpy.app.handlers import persistent
+from bpy.props import (
+ StringProperty, IntProperty, BoolProperty,
+ PointerProperty, CollectionProperty
+)
+from bpy.types import (
+ Panel, Menu, AddonPreferences, Operator,
+ PropertyGroup,
+ Scene
+)
+
dev = False
matlib_path = os.path.dirname(__file__)
if dev:
- print (30*"-")
- matlib_path = r"D:\Blender Foundation\Blender\2.72\scripts\addons\matlib"
+ print (30*"-")
+ 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)
+ if dev:
+ if dodir:
+ print(dir(*args))
+ print(*args)
#Regular Functions
def winpath(path):
- return path.replace("\\", "\\\\")
-
+ 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
-
+ 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
+ #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()
+ self.load_library()
def update_cat_index(self, context):
- dd("cat index:", self.current_category, self.filter)
+ dd("cat index:", self.current_category, self.filter)
+
+ if self.filter:
+ self.filter = True
- if self.filter:
- self.filter = True
-
def update_filter(self, context):
-
- dd("filter:", self.filter, self.cat_index, self.current_category)
-# index = self.cat_index
-#
-# if self.filter:
-# cat = self.current_category
-# else:
-# cat = ""
-#
-# self.current_library.filter = cat
- self.update_list()
-
+
+ dd("filter:", self.filter, self.cat_index, self.current_category)
+# index = self.cat_index
+#
+# if self.filter:
+# cat = self.current_category
+# else:
+# cat = ""
+#
+# self.current_library.filter = cat
+ self.update_list()
+
def check_index(collection, index):
- count = len(collection)
- return count>0 and index<count and index>=0
+ 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)
-
- import subprocess
-
- 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)
-
+ bin = winpath(bpy.app.binary_path)
+ scriptpath = winpath(os.path.join(matlib_path, output))
+
+ with open(scriptpath, "w") as f:
+ f.write(cmd)
+
+ import subprocess
+
+ 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
+ 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(bpy.types.PropertyGroup):
- pass
-bpy.utils.register_class(EmptyGroup)
+class EmptyGroup(PropertyGroup):
+ pass
+# bpy.utils.register_class(EmptyGroup)
-class matlibMaterials(bpy.types.PropertyGroup):
- category = StringProperty()
-bpy.utils.register_class(matlibMaterials)
+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 = """
+
+ #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)
+ 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)
+ cats.remove(0)
"""
- for cat in cats:
- cmd += """
+ for cat in cats:
+ cmd += """
cat = cats.add()
cat.name = "%s" """ % cat.capitalize()
- cmd +='''
+ cmd +='''
bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)''' % winpath(libpath)
- return send_command(cmd, "save_categories.py")
+ 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 = """
+ 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
+ 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))
+ 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()
+ 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 + "')"
-
+
+ def __init__(self, matlib_path, 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()
+ libs = [Library(matlib_path, f) for f in os.listdir(matlib_path) if f[-5::] == "blend"]
+ try:
+ user_path = bpy.context.user_preferences.addons[__name__].preferences.matlib_path
+ if os.path.exists(user_path):
+ libs.extend([Library(user_path, f) for f in os.listdir(user_path) if f[-5::] == "blend"])
+ else:
+ print("path not found %s" % user_path)
+ except:
+ pass
+ return sorted(libs, key=lambda x: bpy.path.display_name(x.name))
+
+libraries = []
+# get_libraries()
### MATLIB CLASS
-class matlibProperties(bpy.types.PropertyGroup):
-
- #MATLIB PROPERTIES
-
- #libraries are read from the xml
- lib_index = IntProperty(min = -1, default = 2, 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
- #filter: 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)
- filter = 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 = '''
+class matlibProperties(PropertyGroup):
+
+ #MATLIB PROPERTIES
+
+ #libraries are read from the xml
+ lib_index = IntProperty(min = -1, default = 2, 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
+ #filter: 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)
+ filter = 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.filter = 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.filter or (self.filter 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 = """
+ 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.filter = 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.filter or (self.filter 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']
+ mat = bpy.data.materials['%s']
except:
- mat = None
+ mat = None
if mat:
- mat['category'] = "%s"
- bpy.ops.wm.save_mainfile(filepath="%s", check_existing=False, compress=True)
+ 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 not self.force_import:
- try:
- material = bpy.data.materials[name]
- except:
- pass
-
- if not material:
- 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, force)
-
- #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 = '''
+ 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 not self.force_import:
+ try:
+ material = bpy.data.materials[name]
+ except:
+ pass
+
+ if not material:
+ 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, force)
+
+ #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 = '''
+mat.user_clear()''' % name
+
+ cmd = '''
import bpy{0}
with bpy.data.libraries.load("{1}") as (data_from, data_to):
- data_to.materials = ["{2}"]
+ 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
+
+ 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)
+ 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)
+# Scene.matlib = PointerProperty(type = matlibProperties)
### MENUS
-class matlibLibsMenu(bpy.types.Menu):
- bl_idname = "matlib.libs_menu"
- bl_label = "Libraries 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(bpy.types.Menu):
- bl_idname = "matlib.cats_menu"
- bl_label = "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)
-
+class matlibLibsMenu(Menu):
+ bl_idname = "matlib.libs_menu"
+ bl_label = "Libraries 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"
+
+ 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 MATLIB_OT_add(bpy.types.Operator):
-# """Add Active Material"""
-# bl_label = "Add"
-# bl_idname = "matlib.add_material"
-#
-# @classmethod
-# def poll(cls, context):
-# return context.active_object is not None
-#
-# def exectute(self, context):
-# print("executing")
-# return {"FINISHED"}
-
-
-
-class MatlibAdd(bpy.types.Operator):
- """Add active material to library"""
- bl_idname = "matlib.add"
- bl_label = "Add active material"
-
- @classmethod
- def poll(cls, context):
- obj = context.active_object
- return obj is not None and obj.active_material is not None
-
- def execute(self, context):
- matlib = context.scene.matlib
- success = matlib.add_material(context.object.active_material)
- if type(success).__name__ == "tuple":
- print(success)
- self.report({success[0]}, success[1])
- return {'FINISHED'}
-
-class MatlibRemove(bpy.types.Operator):
- """Remove material from library"""
- bl_idname = "matlib.remove"
- bl_label = "Remove material from library"
-
- @classmethod
- def poll(cls, context):
- matlib = context.scene.matlib
- return check_index(matlib.materials, matlib.mat_index)
-
- def execute(self, context):
- matlib = context.scene.matlib
- success = matlib.remove_material()
- if type(success).__name__ == "tuple":
- print(success)
- self.report({success[0]}, success[1])
- return {'FINISHED'}
-
-class MatlibReload(bpy.types.Operator):
- """Reload library"""
- bl_idname = "matlib.reload"
- bl_label = "Reload library"
-
-# @classmethod
-# def poll(cls, context):
-# matlib = context.scene.matlib
-# index = matlib.mat_index
-# l = len(matlib.materials)
-# return l>0 and index >=0 and index < l
-
- def execute(self, context):
- matlib = context.scene.matlib
- success = matlib.reload()
- if type(success).__name__ == "tuple":
- print(success)
- self.report({success[0]}, success[1])
- return {'FINISHED'}
-
-class MatlibApply(bpy.types.Operator):
- """Apply selected material"""
- bl_idname = "matlib.apply"
- bl_label = "Apply material"
-
- @classmethod
- def poll(cls, context):
- matlib = context.scene.matlib
- index = matlib.mat_index
- l = len(matlib.materials)
- obj = context.active_object
- return l>0 and index >=0 and index < l and obj is not None
-
- def execute(self, context):
- matlib = context.scene.matlib
- success = matlib.apply(context, False)
- if type(success).__name__ == "tuple":
- print(success)
- self.report({success[0]}, success[1])
- return {'FINISHED'}
-
-class MatlibPreview(bpy.types.Operator):
- """Preview selected material"""
- bl_idname = "matlib.preview"
- bl_label = "Preview selected material"
-
- @classmethod
- def poll(cls, context):
- matlib = context.scene.matlib
- index = matlib.mat_index
- l = len(matlib.materials)
- obj = context.active_object
- return l>0 and index >=0 and index < l
-
- def execute(self, context):
- matlib = context.scene.matlib
- success = matlib.apply(context, True)
- if type(success).__name__ == "tuple":
- print(success)
- self.report({success[0]}, success[1])
- return {'FINISHED'}
-
-class MatlibFlush(bpy.types.Operator):
- """Flush unused materials"""
- bl_idname = "matlib.flush"
- bl_label = "Flush unused materials"
-
- @classmethod
- def poll(cls, context):
- matlib = context.scene.matlib
- index = matlib.mat_index
- l = len(matlib.materials)
- obj = context.active_object
- return l>0 and index >=0 and index < l
-
- def execute(self, context):
- matlib = context.scene.matlib
- dummy = matlib.get_dummy(context)
- if dummy == context.object:
- try:
- context.scene.objects.active = context.scene.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 = "" if i == 1 else "s"
- self.report({'INFO'}, str(i) + " material"+plural+" removed.")
-
- return {'FINISHED'}
-class matlibOperator(bpy.types.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 = bpy.props.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)
-
- ### TODO: execute doesnt trigger remove
- def execute(self, context):
-
- 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 = context.scene.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 = """
+#class MATLIB_OT_add(Operator):
+# """Add Active Material"""
+# bl_label = "Add"
+# bl_idname = "matlib.add_material"
+#
+# @classmethod
+# def poll(cls, context):
+# return context.active_object is not None
+#
+# def exectute(self, context):
+# print("executing")
+# return {"FINISHED"}
+
+
+
+class MatlibAdd(Operator):
+ """Add active material to library"""
+ bl_idname = "matlib.add"
+ bl_label = "Add active material"
+
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return obj is not None and obj.active_material is not None
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ success = matlib.add_material(context.object.active_material)
+ if type(success).__name__ == "tuple":
+ print(success)
+ self.report({success[0]}, success[1])
+ return {'FINISHED'}
+
+class MatlibRemove(Operator):
+ """Remove material from library"""
+ bl_idname = "matlib.remove"
+ bl_label = "Remove material from library"
+
+ @classmethod
+ def poll(cls, context):
+ matlib = context.scene.matlib
+ return check_index(matlib.materials, matlib.mat_index)
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ success = matlib.remove_material()
+ if type(success).__name__ == "tuple":
+ print(success)
+ self.report({success[0]}, success[1])
+ return {'FINISHED'}
+
+class MatlibReload(Operator):
+ """Reload library"""
+ bl_idname = "matlib.reload"
+ bl_label = "Reload library"
+
+# @classmethod
+# def poll(cls, context):
+# matlib = context.scene.matlib
+# index = matlib.mat_index
+# l = len(matlib.materials)
+# return l>0 and index >=0 and index < l
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ success = matlib.reload()
+ if type(success).__name__ == "tuple":
+ print(success)
+ self.report({success[0]}, success[1])
+ return {'FINISHED'}
+
+
+class MatlibApply(Operator):
+ """Apply selected material"""
+ bl_idname = "matlib.apply"
+ bl_label = "Apply material"
+
+ @classmethod
+ def poll(cls, context):
+ matlib = context.scene.matlib
+ index = matlib.mat_index
+ l = len(matlib.materials)
+ obj = context.active_object
+ return l>0 and index >=0 and index < l and obj is not None
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ success = matlib.apply(context, False)
+ if type(success).__name__ == "tuple":
+ print(success)
+ self.report({success[0]}, success[1])
+ return {'FINISHED'}
+
+
+class MatlibPreview(Operator):
+ """Preview selected material"""
+ bl_idname = "matlib.preview"
+ bl_label = "Preview selected material"
+
+ @classmethod
+ def poll(cls, context):
+ matlib = context.scene.matlib
+ index = matlib.mat_index
+ l = len(matlib.materials)
+ obj = context.active_object
+ return l>0 and index >=0 and index < l
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ success = matlib.apply(context, True)
+ if type(success).__name__ == "tuple":
+ print(success)
+ self.report({success[0]}, success[1])
+ return {'FINISHED'}
+
+
+class MatlibFlush(Operator):
+ """Flush unused materials"""
+ bl_idname = "matlib.flush"
+ bl_label = "Flush unused materials"
+
+ @classmethod
+ def poll(cls, context):
+ matlib = context.scene.matlib
+ index = matlib.mat_index
+ l = len(matlib.materials)
+ obj = context.active_object
+ return l>0 and index >=0 and index < l
+
+ def execute(self, context):
+ matlib = context.scene.matlib
+ dummy = matlib.get_dummy(context)
+ if dummy == context.object:
+ try:
+ context.scene.objects.active = context.scene.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 = "" if i == 1 else "s"
+ self.report({'INFO'}, str(i) + " material"+plural+" removed.")
+
+ return {'FINISHED'}
+
+
+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 = bpy.props.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)
+
+ ### TODO: execute doesnt trigger remove
+ def execute(self, context):
+
+ 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 = context.scene.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.")
-
+ 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)
+ 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)
-
+ 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)
+ 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(bpy.types.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!=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 a Library"
-
- row.menu("matlib.libs_menu",text=text)
- row.operator("matlib.operator", icon="ZOOMIN", text="").cmd = "LIBRARY_ADD"
- if matlib.active_material:
- row.label(matlib.active_material.category)
- else:
- row.label("")
-#
-# #search
- if not matlib.hide_search:
- row = layout.row(align=True)
- row.prop_search(matlib, "search", matlib, "materials", text="", icon="VIEWZOOM")
-
-# #list
- row = layout.row()
- row.template_list("UI_UL_list", " ", matlib, "materials", matlib, "mat_index", rows=6)
- col = row.column(align=True)
- row = layout.row()
-
- #operators
- col.operator("matlib.add", icon="ZOOMIN", text="")
- col.operator("matlib.remove", icon="ZOOMOUT", text="")
- col.operator("matlib.reload", icon="FILE_REFRESH", text="")
- col.operator("matlib.apply", icon="MATERIAL", text="")
- col.operator("matlib.preview", icon="COLOR", text="")
- col.operator("matlib.flush", icon="GHOST_DISABLED", text="")
- col.prop(matlib, "show_prefs", icon="MODIFIER", text="")
-
- #categories
- row = layout.row(align=True)
- text = "All"
- if matlib.current_category: text = matlib.current_category
- row.menu("matlib.cats_menu",text=text)
- row.prop(matlib, "filter", 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"
-
- #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"
-
-# row = layout.row()
-# if (matlib.current_library):
-# row.label(matlib.current_library.name)
-# else:
-# row.label("Library not found!.")
-
+ 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!=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 a Library"
+
+ row.menu("matlib.libs_menu",text=text)
+ row.operator("matlib.operator", icon="ZOOMIN", text="").cmd = "LIBRARY_ADD"
+ if matlib.active_material:
+ row.label(matlib.active_material.category)
+ else:
+ row.label("")
+#
+# #search
+ if not matlib.hide_search:
+ row = layout.row(align=True)
+ row.prop_search(matlib, "search", matlib, "materials", text="", icon="VIEWZOOM")
+
+# #list
+ row = layout.row()
+ row.template_list("UI_UL_list", " ", matlib, "materials", matlib, "mat_index", rows=6)
+ col = row.column(align=True)
+ row = layout.row()
+
+ #operators
+ col.operator("matlib.add", icon="ZOOMIN", text="")
+ col.operator("matlib.remove", icon="ZOOMOUT", text="")
+ col.operator("matlib.reload", icon="FILE_REFRESH", text="")
+ col.operator("matlib.apply", icon="MATERIAL", text="")
+ col.operator("matlib.preview", icon="COLOR", text="")
+ col.operator("matlib.flush", icon="GHOST_DISABLED", text="")
+ col.prop(matlib, "show_prefs", icon="MODIFIER", text="")
+
+ #categories
+ row = layout.row(align=True)
+ text = "All"
+ if matlib.current_category: text = matlib.current_category
+ row.menu("matlib.cats_menu",text=text)
+ row.prop(matlib, "filter", 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"
+
+ #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"
+
+# row = layout.row()
+# if (matlib.current_library):
+# row.label(matlib.current_library.name)
+# else:
+# row.label("Library not found!.")
+
#classes = [matlibvxPanel, matlibOperator, matlibLibsMenu, matlibCatsMenu]
#print(bpy.context.scene)
+
+@persistent
+def refresh_libs(dummy=None):
+ global libraries
+ libraries = get_libraries()
+
+
+def reload_library(self, context):
+ refresh_libs(self)
+
+
+class matlibvxPref(AddonPreferences):
+ bl_idname = __name__
+
+ matlib_path = StringProperty(
+ name="Additional Path",
+ description="User defined path to .blend libraries files",
+ default="",
+ update=reload_library
+ )
+
+ def draw(self, context):
+ layout = self.layout
+ layout.prop(self, "matlib_path")
+
+
def register():
- bpy.utils.register_module(__name__)
-# for c in classes:
-# bpy.utils.register_class(c)
+ global libraries
+ bpy.utils.register_module(__name__)
+ # for c in classes:
+ # bpy.utils.register_class(c)
+ Scene.matlib_categories = CollectionProperty(type=EmptyGroup)
+ Scene.matlib = PointerProperty(type = matlibProperties)
+ bpy.app.handlers.load_post.append(refresh_libs)
+ libraries = get_libraries()
+
def unregister():
- bpy.utils.unregister_module(__name__)
- # for c in classes:
- # bpy.utils.unregister_class(c)
+ global libraries
+ bpy.utils.unregister_module(__name__)
+ try:
+ # raise ValueError list.remove(x): x not in list
+ del Scene.matlib_categories
+ except:
+ pass
+ del Scene.matlib
+ libraries.clear()
+ bpy.app.handlers.load_post.remove(refresh_libs)
+ # for c in classes:
+ # bpy.utils.unregister_class(c)
-if __name__ == "__main__":
- register()
+if __name__ == "__main__":
+ register()