diff options
author | Eugenio Pignataro <info@oscurart.com.ar> | 2018-12-21 17:31:26 +0300 |
---|---|---|
committer | Eugenio Pignataro <info@oscurart.com.ar> | 2018-12-21 17:31:26 +0300 |
commit | 7fbe716603d46e6718893c15fe9548e0f1ff646f (patch) | |
tree | c1381325b0afaea2edf5a76c62332c0fe777e4a2 /oscurart_tools | |
parent | f1eda54f481169d89108353831ba1462cfb01411 (diff) |
Remove Old Oscurart Tools
Diffstat (limited to 'oscurart_tools')
-rw-r--r-- | oscurart_tools/__init__.py | 477 | ||||
-rw-r--r-- | oscurart_tools/oscurart_animation.py | 66 | ||||
-rw-r--r-- | oscurart_tools/oscurart_files.py | 142 | ||||
-rw-r--r-- | oscurart_tools/oscurart_meshes.py | 752 | ||||
-rw-r--r-- | oscurart_tools/oscurart_objects.py | 553 | ||||
-rw-r--r-- | oscurart_tools/oscurart_overrides.py | 307 | ||||
-rw-r--r-- | oscurart_tools/oscurart_render.py | 511 | ||||
-rw-r--r-- | oscurart_tools/oscurart_shapes.py | 473 |
8 files changed, 0 insertions, 3281 deletions
diff --git a/oscurart_tools/__init__.py b/oscurart_tools/__init__.py deleted file mode 100644 index bf8896de..00000000 --- a/oscurart_tools/__init__.py +++ /dev/null @@ -1,477 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -bl_info = { - "name": "Oscurart Tools", - "author": "Oscurart, CodemanX", - "version": (3, 5, 2), - "blender": (2, 77, 0), - "location": "View3D > Tools > Oscurart Tools", - "description": "Tools for objects, render, shapes, and files.", - "warning": "", - "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/" - "Scripts/3D_interaction/Oscurart_Tools", - "category": "Object", - } - -if "bpy" in locals(): - import importlib - importlib.reload(oscurart_files) - importlib.reload(oscurart_meshes) - importlib.reload(oscurart_objects) - importlib.reload(oscurart_shapes) - importlib.reload(oscurart_render) - importlib.reload(oscurart_overrides) - importlib.reload(oscurart_animation) - -else: - from . import oscurart_files - from . import oscurart_meshes - from . import oscurart_objects - from . import oscurart_shapes - from . import oscurart_render - from . import oscurart_overrides - from . import oscurart_animation - -import bpy - -from bpy.types import ( - AddonPreferences, - Panel, - PropertyGroup, - ) -from bpy.props import ( - StringProperty, - BoolProperty, - IntProperty, - PointerProperty, - CollectionProperty, - ) - - -class View3DOscPanel(PropertyGroup): - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - - # Create Panels and Tools - osc_object_tools = BoolProperty(default=False) - osc_mesh_tools = BoolProperty(default=False) - osc_shapes_tools = BoolProperty(default=False) - osc_render_tools = BoolProperty(default=False) - osc_files_tools = BoolProperty(default=False) - osc_overrides_tools = BoolProperty(default=False) - osc_animation_tools = BoolProperty(default=False) - - # For new Scenes - overrides = StringProperty(default="[]") - - -class OscOverridesProp(PropertyGroup): - matoverride = StringProperty() - grooverride = StringProperty() - - -# Panels -class OscPanelControl(Panel): - bl_idname = "Oscurart Panel Control" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_category = "Oscurart Tools" - bl_label = "Oscurart Tools" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - layout = self.layout - scene = context.scene - oscurart = scene.oscurart - - col = layout.column(align=1) - col.prop(oscurart, "osc_object_tools", text="Object", icon="OBJECT_DATAMODE") - col.prop(oscurart, "osc_mesh_tools", text="Mesh", icon="EDITMODE_HLT") - col.prop(oscurart, "osc_shapes_tools", text="Shapes", icon="SHAPEKEY_DATA") - col.prop(oscurart, "osc_animation_tools", text="Animation", icon="POSE_DATA") - col.prop(oscurart, "osc_render_tools", text="Render", icon="SCENE") - col.prop(oscurart, "osc_files_tools", text="Files", icon="IMASEL") - col.prop(oscurart, "osc_overrides_tools", text="Overrides", icon="GREASEPENCIL") - - -class OscPanelObject(Panel): - bl_idname = "Oscurart Object Tools" - bl_label = "Object Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_object_tools - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - - colrow = col.row(align=1) - colrow.operator("object.relink_objects_between_scenes", icon="LINKED") - colrow = col.row(align=1) - colrow.operator("object.copy_objects_groups_layers", icon="LINKED") - colrow.operator("object.set_layers_to_other_scenes", icon="LINKED") - colrow = col.row(align=1) - colrow.operator("object.objects_to_groups", icon="GROUP") - colrow = col.row(align=1) - colrow.prop(bpy.context.scene, "SearchAndSelectOt", text="") - colrow.operator("object.search_and_select_osc", icon="ZOOM_SELECTED") - colrow = col.row(align=1) - colrow.prop(bpy.context.scene, "RenameObjectOt", text="") - colrow.operator("object.rename_objects_osc", icon="SHORTDISPLAY") - col.operator( - "object.distribute_osc", - icon="OBJECT_DATAMODE", - text="Distribute") - col.operator( - "object.duplicate_object_symmetry_osc", - icon="OUTLINER_OB_EMPTY", - text="Duplicate Sym") - colrow = col.row(align=1) - colrow.operator( - "object.modifiers_remove_osc", - icon="MODIFIER", - text="Remove Modifiers") - colrow.operator( - "object.modifiers_apply_osc", - icon="MODIFIER", - text="Apply Modifiers") - colrow = col.row(align=1) - colrow.operator( - "group.group_in_out_camera", - icon="RENDER_REGION", - text="Make Groups in out Camera") - - -class OscPanelMesh(Panel): - bl_idname = "Oscurart Mesh Tools" - bl_label = "Mesh Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_mesh_tools - - def draw(self, context): - scene = context.scene - layout = self.layout - col = layout.column(align=1) - - col.operator("mesh.object_to_mesh_osc", icon="MESH_MONKEY") - col.operator("mesh.select_side_osc", icon="VERTEXSEL") - col.operator("mesh.select_doubles", icon="VERTEXSEL") - colrow = col.row(align=1) - colrow.operator("mesh.resym_save_map", icon="UV_SYNC_SELECT") - colrow = col.row(align=1) - colrow.operator( - "mesh.resym_mesh", - icon="UV_SYNC_SELECT", - text="Resym Mesh") - colrow.operator("mesh.resym_vertex_weights_osc", icon="UV_SYNC_SELECT") - colrow = col.row(align=1) - colrow.operator("mesh.reconst_osc", icon="UV_SYNC_SELECT") - colrow = col.row(align=1) - colrow.operator("mesh.vertex_color_mask", icon="GROUP_VCOL") - colrow = col.row(align=1) - colrow.operator("mesh.overlap_uv_faces", icon="UV_FACESEL") - colrow = col.row(align=1) - colrow.operator("mesh.uv_island_copy", icon="COPYDOWN") - colrow.operator("mesh.uv_island_paste", icon="PASTEDOWN") - colrow = col.row(align=1) - colrow.operator("view3d.modal_operator", icon="STICKY_UVS_DISABLE") - colrow = col.row(align=1) - colrow.operator("lattice.mirror_selected", icon="LATTICE_DATA") - colrow = col.row(align=1) - colrow.label(text="Edit Multimesh") - colrow.prop_search(scene, "multimeshedit", bpy.data, "collections", text="") - colrow = col.row(align=1) - colrow.operator("mesh.create_edit_multimesh", icon="IMPORT", text= "StartEdit") - colrow.operator("mesh.apply_edit_multimesh", icon="EXPORT", text="FinishEdit") - - -class OscPanelShapes(Panel): - bl_idname = "Oscurart Shapes Tools" - bl_label = "Shapes Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_shapes_tools - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - - col.operator("object.shape_key_to_objects_osc", icon="OBJECT_DATAMODE") - col.operator("mesh.create_lmr_groups_osc", icon="GROUP_VERTEX") - col.operator("mesh.split_lr_shapes_osc", icon="SHAPEKEY_DATA") - colrow = col.row(align=1) - colrow.operator("mesh.create_symmetrical_layout_osc", icon="IMPORT") - colrow.operator("mesh.create_asymmetrical_layout_osc", icon="EXPORT") - - -class OscPanelRender(Panel): - bl_idname = "Oscurart Render Tools" - bl_label = "Render Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_render_tools - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - - colrow = col.row(align=1) - col.operator( - "file.create_batch_maker_osc", - icon="LINENUMBERS_ON", - text="Make Render Batch") - col.operator( - "file.create_batch_python", - icon="LINENUMBERS_ON", - text="Make Python Batch") - colrow = col.row(align=1) - colrow.operator( - "render.render_all_scenes_osc", - icon="RENDER_STILL", - text="All Scenes").frametype = False - colrow.operator( - "render.render_all_scenes_osc", - text="> Frame").frametype = True - colrow = col.row(align=1) - colrow.operator( - "render.render_current_scene_osc", - icon="RENDER_STILL", - text="Active Scene").frametype = False - colrow.operator( - "render.render_current_scene_osc", - text="> Frame").frametype = True - - colrow = col.row(align=1) - colrow.operator("render.render_crop_osc", icon="RENDER_REGION") - colrow.prop(bpy.context.scene, "rcPARTS", text="Parts") - - boxcol = layout.box().column(align=1) - colrow = boxcol.row(align=1) - colrow.operator( - "render.render_selected_scenes_osc", - icon="RENDER_STILL", - text="Selected Scenes").frametype = False - colrow.operator( - "render.render_selected_scenes_osc", - text="> Fame").frametype = True - - for sc in bpy.data.scenes[:]: - boxcol.prop(sc, "use_render_scene", text=sc.name) - - -class OscPanelFiles(Panel): - bl_idname = "Oscurart Files Tools" - bl_label = "Files Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_files_tools - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - col.operator("file.save_incremental_osc", icon="NEW") - col.operator("image.reload_images_osc", icon="IMAGE_COL") - col.operator("file.collect_all_images", icon="IMAGE_COL") - col.operator("file.sync_missing_groups", icon="LINK_AREA") - col = layout.column(align=1) - colrow = col.row(align=1) - colrow.prop(bpy.context.scene, "oscSearchText", text="") - colrow.prop(bpy.context.scene, "oscReplaceText", text="") - col.operator("file.replace_file_path_osc", icon="SHORTDISPLAY") - - -class OscPanelOverrides(Panel): - bl_idname = "Oscurart Overrides" - bl_label = "Overrides Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_overrides_tools - - def draw(self, context): - layout = self.layout - box = layout.box() - col = box.column(align=1) - - # col.operator("render.overrides_set_list", text="Create Override - # List", icon="GREASEPENCIL") - col.label(text="Active Scene: " + bpy.context.scene.name) - col.label(text="Example: [[Group,Material]]") - col.prop(bpy.context.scene.oscurart, "overrides", text="") - col.operator( - "render.check_overrides", - text="Check List", - icon="ZOOM_ALL") - col.operator("render.overrides_on", text="On / Off", icon="QUIT") - col.label( - text=str("OVERRIDES: ON" if bpy.use_overrides else "OVERRIDES: OFF")) - - box = layout.box() - boxcol = box.column(align=1) - boxcol.label(text="Danger Zone") - boxcolrow = boxcol.row(align=1) - boxcolrow.operator( - "render.apply_overrides", - text="Apply Overrides", - icon="ERROR") - boxcolrow.operator( - "render.restore_overrides", - text="Restore Overrides", - icon="ERROR") - - -class OscPanelAnimation(Panel): - bl_idname = "Oscurart Animation Tools" - bl_label = "Animation Tools" - bl_category = "Oscurart Tools" - bl_space_type = 'VIEW_3D' - bl_region_type = 'TOOLS' - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.scene.oscurart.osc_animation_tools - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - row = col.row() - - col.operator("anim.quick_parent_osc", icon="OUTLINER_DATA_POSE") - row = col.row(align=1) - row.prop(bpy.context.scene, "quick_animation_in", text="") - row.prop(bpy.context.scene, "quick_animation_out", text="") - - -# Addons Preferences Update Panel - -# Define Panel classes for updating -panels = ( - OscPanelControl, - OscPanelObject, - OscPanelMesh, - OscPanelShapes, - OscPanelRender, - OscPanelFiles, - OscPanelOverrides, - OscPanelAnimation, - ) - - -def update_panel(self, context): - message = "Oscurart Tools: Updating Panel locations has failed" - try: - for panel in panels: - if "bl_rna" in panel.__dict__: - bpy.utils.unregister_class(panel) - - for panel in panels: - panel.bl_category = context.preferences.addons[__name__].preferences.category - bpy.utils.register_class(panel) - - except Exception as e: - print("\n[{}]\n{}\n\nError:\n{}".format(__name__, message, e)) - pass - - -class OscurartToolsAddonPreferences(AddonPreferences): - # this must match the addon name, use '__package__' - # when defining this in a submodule of a python package. - bl_idname = __name__ - - category = StringProperty( - name="Category", - description="Choose a name for the category of the panel", - default="Tools", - update=update_panel, - ) - - def draw(self, context): - layout = self.layout - row = layout.row() - col = row.column() - col.label(text="Category:") - col.prop(self, "category", text="") - -# ========================= End of Scripts ========================= - - -def register(): - from bpy.types import Scene - bpy.utils.register_module(__name__) - - bpy.types.Scene.oscurart = PointerProperty(type=View3DOscPanel) - - bpy.types.Scene.ovlist = CollectionProperty(type=OscOverridesProp) - - bpy.types.Scene.quick_animation_in = IntProperty(default=1) - bpy.types.Scene.quick_animation_out = IntProperty(default=250) - - Scene.multimeshedit = StringProperty() - - # SETEO VARIABLE DE ENTORNO - bpy.types.Scene.SearchAndSelectOt = StringProperty( - default="Object name initials" - ) - update_panel(None, bpy.context) - - -def unregister(): - del bpy.types.Scene.oscurart - del bpy.types.Scene.quick_animation_in - del bpy.types.Scene.quick_animation_out - del bpy.types.Scene.SearchAndSelectOt - - bpy.utils.unregister_module(__name__) - - -if __name__ == "__main__": - register() diff --git a/oscurart_tools/oscurart_animation.py b/oscurart_tools/oscurart_animation.py deleted file mode 100644 index 16806690..00000000 --- a/oscurart_tools/oscurart_animation.py +++ /dev/null @@ -1,66 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from mathutils import Matrix - -# ---------------------------QUICK PARENT------------------ - - -def DefQuickParent(inf, out): - ob = bpy.context.object - if ob.type == "ARMATURE": - target = [object for object in bpy.context.selected_objects if object != ob][0] - ob = bpy.context.active_pose_bone if bpy.context.object.type == 'ARMATURE' else bpy.context.object - target.select = False - bpy.context.scene.frame_set(frame=bpy.context.scene.quick_animation_in) - a = Matrix(target.matrix_world) - a.invert() - i = Matrix(ob.matrix) - for frame in range(inf, out): - bpy.context.scene.frame_set(frame=frame) - ob.matrix = target.matrix_world * a * i - bpy.ops.anim.keyframe_insert(type="LocRotScale") - else: - target = [object for object in bpy.context.selected_objects if object != ob][0] - ob = bpy.context.active_pose_bone if bpy.context.object.type == 'ARMATURE' else bpy.context.object - target.select = False - bpy.context.scene.frame_set(frame=bpy.context.scene.quick_animation_in) - a = Matrix(target.matrix_world) - a.invert() - i = Matrix(ob.matrix_world) - for frame in range(inf, out): - bpy.context.scene.frame_set(frame=frame) - ob.matrix_world = target.matrix_world * a * i - bpy.ops.anim.keyframe_insert(type="LocRotScale") - - -class QuickParent(bpy.types.Operator): - """Creates a parent from one object to other in a selected frame range""" - bl_idname = "anim.quick_parent_osc" - bl_label = "Quick Parent" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefQuickParent( - bpy.context.scene.quick_animation_in, - bpy.context.scene.quick_animation_out, - ) - return {'FINISHED'} diff --git a/oscurart_tools/oscurart_files.py b/oscurart_tools/oscurart_files.py deleted file mode 100644 index 6c2f371d..00000000 --- a/oscurart_tools/oscurart_files.py +++ /dev/null @@ -1,142 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from bpy.types import Operator -import os -import shutil - - -# ---------------------------RELOAD IMAGES------------------ - - -class reloadImages (Operator): - """Reloads all bitmaps in the scene""" - bl_idname = "image.reload_images_osc" - bl_label = "Reload Images" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - for imgs in bpy.data.images: - imgs.reload() - return {'FINISHED'} - - -# ------------------------ SAVE INCREMENTAL ------------------------ - -class saveIncremental(Operator): - """Saves incremental version of the blend file Ex: "_v01", "_v02\"""" - bl_idname = "file.save_incremental_osc" - bl_label = "Save Incremental File" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - filepath = bpy.data.filepath - if os.path.basename(filepath).rpartition(".")[0][-5:].count("_v"): - strnum = filepath.rpartition("_v")[-1].rpartition(".blend")[0] - intnum = int(strnum) - modnum = "%02d" % (intnum+1) - output = filepath.replace(strnum, modnum) - basename = os.path.basename(filepath) - bpy.ops.wm.save_as_mainfile( - filepath=os.path.join(os.path.dirname(filepath), "%s_v%s.blend" % - (basename.rpartition("_v")[0], str(modnum)))) - - else: - output = filepath.rpartition(".blend")[0] + "_v01" - bpy.ops.wm.save_as_mainfile(filepath=output) - - return {'FINISHED'} - -# ------------------------ REPLACE FILE PATHS ------------------------ - -bpy.types.Scene.oscSearchText = bpy.props.StringProperty(default="Search Text") -bpy.types.Scene.oscReplaceText = bpy.props.StringProperty( - default="Replace Text") - - -class replaceFilePath(Operator): - """Replace the paths set on the “search test” field by the ones in “replace” field. "_v01" »» "_v02" /folder1/render_v01.png »» /folder1/render_v02.png""" - bl_idname = "file.replace_file_path_osc" - bl_label = "Replace File Path" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - TEXTSEARCH = bpy.context.scene.oscSearchText - TEXTREPLACE = bpy.context.scene.oscReplaceText - - for image in bpy.data.images: - image.filepath = image.filepath.replace(TEXTSEARCH, TEXTREPLACE) - - return {'FINISHED'} - - -# ---------------------- SYNC MISSING GROUPS -------------------------- - -class reFreshMissingGroups(Operator): - """Search on the libraries of the linked source and relink groups and link newones if there are. Useful to use with the mesh cache tools""" - bl_idname = "file.sync_missing_groups" - bl_label = "Sync Missing Groups" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - for group in bpy.data.collections: - if group.library is not None: - with bpy.data.libraries.load(group.library.filepath, link=True) as (linked, local): - local.collections = linked.collections - return {'FINISHED'} - - -# ---------------------- COLLECT IMAGES -------------------------- - - -class collectImagesOsc(Operator): - """Collect all images in the blend file and put them in IMAGES folder""" - bl_idname = "file.collect_all_images" - bl_label = "Collect Images" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - - imagespath = "%s/IMAGES" % (os.path.dirname(bpy.data.filepath)) - - if not os.path.exists(imagespath): - os.mkdir(imagespath) - - bpy.ops.file.make_paths_absolute() - - for image in bpy.data.images: - try: - image.update() - - if image.has_data: - if not os.path.exists(os.path.join(imagespath,os.path.basename(image.filepath))): - shutil.copy(image.filepath, os.path.join(imagespath,os.path.basename(image.filepath))) - image.filepath = os.path.join(imagespath,os.path.basename(image.filepath)) - else: - print("%s exists." % (image.name)) - else: - print("%s missing path." % (image.name)) - except: - print("%s missing path." % (image.name)) - - bpy.ops.file.make_paths_relative() - - return {'FINISHED'} diff --git a/oscurart_tools/oscurart_meshes.py b/oscurart_tools/oscurart_meshes.py deleted file mode 100644 index 39257542..00000000 --- a/oscurart_tools/oscurart_meshes.py +++ /dev/null @@ -1,752 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from mathutils import Vector -from bpy.types import Operator -from bpy.props import ( - IntProperty, - BoolProperty, - FloatProperty, - EnumProperty, - ) -import os -import bmesh -import time -import blf -from bpy_extras.view3d_utils import location_3d_to_region_2d -from random import uniform - -C = bpy.context -D = bpy.data - - -# -----------------------------RECONST--------------------------- - -def defReconst(self, OFFSET): - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - bpy.context.tool_settings.mesh_select_mode = (True, True, True) - ob = bpy.context.active_object - bm = bmesh.from_edit_mesh(ob.data) - bm.select_flush(False) - for vertice in bm.verts[:]: - if abs(vertice.co[0]) < OFFSET: - vertice.co[0] = 0 - for vertice in bm.verts[:]: - if vertice.co[0] < 0: - bm.verts.remove(vertice) - bmesh.update_edit_mesh(ob.data) - mod = ob.modifiers.new("Mirror", "MIRROR") - uv = ob.data.uv_textures.new(name="SYMMETRICAL") - for v in bm.faces: - v.select = 1 - bmesh.update_edit_mesh(ob.data) - ob.data.uv_textures.active = ob.data.uv_textures['SYMMETRICAL'] - bpy.ops.uv.unwrap( - method='ANGLE_BASED', - fill_holes=True, - correct_aspect=False, - use_subsurf_data=0) - bpy.ops.object.mode_set(mode="OBJECT", toggle=False) - bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Mirror") - bpy.ops.object.mode_set(mode="EDIT", toggle=False) - bm = bmesh.from_edit_mesh(ob.data) - bm.select_flush(0) - uv = ob.data.uv_textures.new(name="ASYMMETRICAL") - ob.data.uv_textures.active = ob.data.uv_textures['ASYMMETRICAL'] - bpy.ops.uv.unwrap( - method='ANGLE_BASED', - fill_holes=True, - correct_aspect=False, - use_subsurf_data=0) - - -class reConst(Operator): - """Erase vertices below cero X position value and rebuilds the symmetry. """ - """It also creates two uv channels, one symmetrical and one asymmetrical""" - bl_idname = "mesh.reconst_osc" - bl_label = "ReConst Mesh" - bl_options = {"REGISTER", "UNDO"} - - OFFSET = FloatProperty( - name="Offset", - default=0.001, - min=-0, - max=0.1 - ) - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - def execute(self, context): - defReconst(self, self.OFFSET) - return {'FINISHED'} - - -# -----------------------------------SELECT LEFT--------------------- - -def side(self, nombre, offset): - - bpy.ops.object.mode_set(mode="EDIT", toggle=0) - OBJECT = bpy.context.active_object - ODATA = bmesh.from_edit_mesh(OBJECT.data) - bpy.context.tool_settings.mesh_select_mode = (True, False, False) - for VERTICE in ODATA.verts[:]: - VERTICE.select = False - if nombre is False: - for VERTICES in ODATA.verts[:]: - if VERTICES.co[0] < (offset): - VERTICES.select = 1 - else: - for VERTICES in ODATA.verts[:]: - if VERTICES.co[0] > (offset): - VERTICES.select = 1 - ODATA.select_flush(False) - bpy.ops.object.mode_set(mode="EDIT", toggle=0) - - -class SelectMenor(Operator): - """Selects the vertex with an N position value on the X axis""" - bl_idname = "mesh.select_side_osc" - bl_label = "Select Side" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - side = BoolProperty( - name="Greater than zero", - default=False - ) - offset = FloatProperty( - name="Offset", - default=0 - ) - - def execute(self, context): - - side(self, self.side, self.offset) - - return {'FINISHED'} - - -# -------------------------RESYM VG---------------------------------- - - -class rvg(Operator): - bl_idname = "mesh.resym_vertex_weights_osc" - bl_label = "Resym Vertex Weights" - bl_description = ("Copies the symmetrical weight value of the vertices on the X axys\n" - "(It needs the XML map and the Active Object is not in Edit mode)") - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - obj = context.active_object - return obj is not None and obj.mode != "EDIT" - - def execute(self, context): - ob = bpy.context.object - actgr = ob.vertex_groups.active if ob else None - if not actgr: - self.report({'WARNING'}, - "Object doesn't have active Vertex groups. Operation Cancelled") - return {"CANCELLED"} - - with open("%s_%s_SYM_TEMPLATE.xml" % (os.path.join(os.path.dirname(bpy.data.filepath), - bpy.context.scene.name), bpy.context.object.name)) as file: - actind = ob.vertex_groups.active_index - ls = eval(file.read()) - wdict = {left: actgr.weight(right) for left, right in ls.items() - for group in ob.data.vertices[right].groups if group.group == actind} - actgr.remove( - [vert.index for vert in ob.data.vertices if vert.co[0] <= 0]) - for ind, weight in wdict.items(): - actgr.add([ind], weight, 'REPLACE') - bpy.context.object.data.update() - - return {'FINISHED'} - - -# --------------------------- RESYM MESH------------------------- - - -def reSymSave(self, quality): - - bpy.ops.object.mode_set(mode='OBJECT') - - object = bpy.context.object - - rdqual = quality - rd = lambda x: round(x, rdqual) - absol = lambda x: (abs(x[0]), x[1], x[2]) - - inddict = { - tuple(map(rd, vert.co[:])): vert.index for vert in object.data.vertices[:] - } - reldict = {inddict[vert]: inddict.get(absol(vert), inddict[vert]) - for vert in inddict if vert[0] <= 0} - - ENTFILEPATH = "%s_%s_SYM_TEMPLATE.xml" % ( - os.path.join(os.path.dirname(bpy.data.filepath), - bpy.context.scene.name), - bpy.context.object.name) - - with open(ENTFILEPATH, mode="w") as file: - file.writelines(str(reldict)) - reldict.clear() - - -def reSymMesh(self, SELECTED, SIDE): - bpy.ops.object.mode_set(mode='EDIT') - ENTFILEPATH = "%s_%s_SYM_TEMPLATE.xml" % ( - os.path.join(os.path.dirname(bpy.data.filepath), - bpy.context.scene.name), - bpy.context.object.name) - with open(ENTFILEPATH, mode="r") as file: - SYMAP = eval(file.readlines()[0]) - bm = bmesh.from_edit_mesh(bpy.context.object.data) - object = bpy.context.object - - def MAME(SYMAP): - bm.verts.ensure_lookup_table() - if SELECTED: - for vert in SYMAP: - if bm.verts[SYMAP[vert]].select: - bm.verts[vert].co = (-1 * bm.verts[SYMAP[vert]].co[0], - bm.verts[SYMAP[vert]].co[1], - bm.verts[SYMAP[vert]].co[2]) - else: - for vert in SYMAP: - bm.verts[vert].co = (-1 * bm.verts[SYMAP[vert]].co[0], - bm.verts[SYMAP[vert]].co[1], - bm.verts[SYMAP[vert]].co[2]) - bmesh.update_edit_mesh(object.data) - - def MEMA(SYMAP): - bm.verts.ensure_lookup_table() - if SELECTED: - for vert in SYMAP: - if bm.verts[vert].select: - bm.verts[SYMAP[vert]].co = (-1 * bm.verts[vert].co[0], - bm.verts[vert].co[1], - bm.verts[vert].co[2]) - else: - for vert in SYMAP: - bm.verts[SYMAP[vert]].co = (-1 * bm.verts[vert].co[0], - bm.verts[vert].co[1], - bm.verts[vert].co[2]) - bmesh.update_edit_mesh(object.data) - - if SIDE == "+-": - MAME(SYMAP) - else: - MEMA(SYMAP) - - -class OscResymSave(Operator): - """Creates a file on disk that saves the info of every vertex but in simmetry, """ \ - """this info its going to be later used by “Resym Mesh” and “Resym Vertex Weights”""" - bl_idname = "mesh.resym_save_map" - bl_label = "Resym save XML Map" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - quality = IntProperty( - default=4, - name="Quality" - ) - - def execute(self, context): - reSymSave(self, self.quality) - return {'FINISHED'} - - -class OscResymMesh(Operator): - """Copies the symmetrical position of the vertices on the X axys. It needs the XML map""" - bl_idname = "mesh.resym_mesh" - bl_label = "Resym save Apply XML" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return context.active_object is not None - - selected = BoolProperty( - default=False, - name="Only Selected" - ) - side = EnumProperty( - name="Side:", - description="Select Side", - items=(('+-', "+X to -X", "+X to -X"), - ('-+', "-X to +X", "-X to +X")), - default='+-', - ) - - def execute(self, context): - reSymMesh(self, self.selected, self.side) - return {'FINISHED'} - - -# -------------------------- OBJECT TO MESH ------------------------------ - -def DefOscObjectToMesh(): - ACTOBJ = bpy.context.object - MESH = ACTOBJ.to_mesh( - scene=bpy.context.scene, - apply_modifiers=True, - settings="RENDER") - OBJECT = bpy.data.objects.new(("%s_Freeze") % (ACTOBJ.name), MESH) - bpy.context.scene.objects.link(OBJECT) - - -class OscObjectToMesh(Operator): - """It creates a copy of the final state of the object as it being see in the viewport""" - bl_idname = "mesh.object_to_mesh_osc" - bl_label = "Object To Mesh" - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type in - {'MESH', 'META', 'CURVE', 'SURFACE'}) - - def execute(self, context): - print("Active type object is", context.object.type) - DefOscObjectToMesh() - - return {'FINISHED'} - - -# ----------------------------- OVERLAP UV ------------------------------- - - -def DefOscOverlapUv(self,offset,rotate): - me = bpy.context.object.data - bm = bmesh.from_edit_mesh(me) - bm.faces.ensure_lookup_table() - faces = [face for face in bm.faces if face.select] - uv_layer = bm.loops.layers.uv[bpy.context.object.data.uv_layers.active.name] - - faceDict = {} - faceReverse = [] - bm.select_mode = {'FACE'} - for face in faces: - bpy.ops.mesh.select_all(action="DESELECT") - face.select = True - bpy.ops.mesh.select_mirror() - faceDict[face.index] = [mirrorface for mirrorface in bm.faces if mirrorface.select][0].index - faceReverse.append([mirrorface for mirrorface in bm.faces if mirrorface.select][0]) - - - - for selFace,mirrorFace in faceDict.items(): - for loop,mirrorLoop in zip(bm.faces[selFace].loops,bm.faces[mirrorFace].loops): - mirrorLoop.copy_from(loop) - if offset: - for loop,mirrorLoop in zip(bm.faces[selFace].loops,bm.faces[mirrorFace].loops): - mirrorLoop[uv_layer].uv += Vector((1,0)) - - - #invierto direcciones - bmesh.ops.reverse_uvs(bm, faces=[f for f in faceReverse]) - bmesh.ops.rotate_uvs(bm, faces=[f for f in faceReverse]) - if rotate: - bmesh.ops.rotate_uvs(bm, faces=[f for f in faceReverse]) - - bmesh.update_edit_mesh(me) - - -class OscOverlapUv(Operator): - """Overlaps the uvs on one side of the model symmetry plane. """ \ - """Useful to get more detail on fixed resolution bitmaps""" - bl_idname = "mesh.overlap_uv_faces" - bl_label = "Overlap Uvs" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - - offset = BoolProperty( - default=True, - name="Offset" - ) - rotate = BoolProperty( - default=False, - name="Rotate" - ) - - def execute(self, context): - DefOscOverlapUv(self,self.offset,self.rotate) - return {'FINISHED'} - - -# ------------------ PRINT VERTICES ---------------------- - -def dibuja_callback(self, context): - font_id = 0 - bm = bmesh.from_edit_mesh(bpy.context.object.data) - for v in bm.verts: - cord = location_3d_to_region_2d( - context.region, - context.space_data.region_3d, - self.matr * v.co) - blf.position(font_id, cord[0], cord[1], 0) - blf.size(font_id, self.tsize, 72) - blf.draw(font_id, str(v.index)) - - -class ModalIndexOperator(Operator): - """Allow to visualize the index number for vertices in the viewport""" - bl_idname = "view3d.modal_operator" - bl_label = "Print Vertices" - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - def modal(self, context, event): - context.area.tag_redraw() - if event.type == 'MOUSEMOVE': - self.x = event.mouse_region_x - self.matr = context.object.matrix_world - elif event.type == 'LEFTMOUSE': - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - return {'FINISHED'} - elif event.type == 'PAGE_UP': - self.tsize += 1 - elif event.type == 'PAGE_DOWN': - self.tsize -= 1 - elif event.type in {'RIGHTMOUSE', 'ESC', 'TAB'}: - bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW') - context.area.header_text_set(None) - return {'CANCELLED'} - - return {'PASS_THROUGH'} - - def invoke(self, context, event): - if context.area.type == "VIEW_3D": - context.area.header_text_set("Esc: exit, PageUP/Down: text size") - bpy.ops.object.mode_set(mode="EDIT") - self.tsize = 20 - args = (self, context) - self._handle = bpy.types.SpaceView3D.draw_handler_add( - dibuja_callback, args, "WINDOW", "POST_PIXEL") - context.window_manager.modal_handler_add(self) - return{'RUNNING_MODAL'} - else: - self.report({"WARNING"}, "Is not a 3D Space") - return {'CANCELLED'} - - -# -------------------------- SELECT DOUBLES - -def SelDoubles(self, context): - bm = bmesh.from_edit_mesh(bpy.context.object.data) - - for v in bm.verts: - v.select = 0 - - dictloc = {} - - rd = lambda x: (round(x[0], 4), round(x[1], 4), round(x[2], 4)) - - for vert in bm.verts: - dictloc.setdefault(rd(vert.co), []).append(vert.index) - - for loc, ind in dictloc.items(): - if len(ind) > 1: - for v in ind: - bm.verts[v].select = 1 - - bpy.context.scene.objects.active = bpy.context.scene.objects.active - - -class SelectDoubles(Operator): - """Selects duplicated vertex without merge them""" - bl_idname = "mesh.select_doubles" - bl_label = "Select Doubles" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH' and - context.active_object.mode == "EDIT") - - def execute(self, context): - SelDoubles(self, context) - return {'FINISHED'} - - -# -------------------------- SELECT DOUBLES - -def defLatticeMirror(self, context): - - ob = bpy.context.object - u = ob.data.points_u - v = ob.data.points_v - w = ob.data.points_w - total = u * v * w - - # guardo indices a cada punto - libIndex = {point: index for point, index in zip(bpy.context.object.data.points, range(0, total))} - - # guardo puntos seleccionados - selectionPoint = [libIndex[i] for i in ob.data.points if i.select] - - for point in selectionPoint: - rango = list(range(int(point / u) * u, int(point / u) * u + (u))) - rango.reverse() - indPorcion = range(int(point / u) * u, int(point / u) * u + (u)).index(point) - ob.data.points[rango[indPorcion]].co_deform.x = -ob.data.points[point].co_deform.x - ob.data.points[rango[indPorcion]].co_deform.y = ob.data.points[point].co_deform.y - ob.data.points[rango[indPorcion]].co_deform.z = ob.data.points[point].co_deform.z - - -class LatticeMirror(Operator): - """Mirror Lattice""" - bl_idname = "lattice.mirror_selected" - bl_label = "Mirror Lattice" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'LATTICE' and - context.active_object.mode == "EDIT") - - def execute(self, context): - defLatticeMirror(self, context) - return {'FINISHED'} - - -# -------------------------- OVERLAP UV ISLANDS - -def defCopyUvsIsland(self, context): - bpy.ops.object.mode_set(mode="OBJECT") - global obLoop - global islandFaces - obLoop = [] - islandFaces = [] - for poly in bpy.context.object.data.polygons: - if poly.select: - islandFaces.append(poly.index) - for li in poly.loop_indices: - obLoop.append(li) - - bpy.ops.object.mode_set(mode="EDIT") - -def defPasteUvsIsland(self, uvOffset, rotateUv,context): - bpy.ops.object.mode_set(mode="OBJECT") - selPolys = [poly.index for poly in bpy.context.object.data.polygons if poly.select] - - for island in selPolys: - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.select_all(action="DESELECT") - bpy.ops.object.mode_set(mode="OBJECT") - bpy.context.object.data.polygons[island].select = True - bpy.ops.object.mode_set(mode="EDIT") - bpy.ops.mesh.select_linked() - bpy.ops.object.mode_set(mode="OBJECT") - TobLoop = [] - TislandFaces = [] - for poly in bpy.context.object.data.polygons: - if poly.select: - TislandFaces.append(poly.index) - for li in poly.loop_indices: - TobLoop.append(li) - - for source,target in zip(range(min(obLoop),max(obLoop)+1),range(min(TobLoop),max(TobLoop)+1)): - bpy.context.object.data.uv_layers.active.data[target].uv = bpy.context.object.data.uv_layers.active.data[source].uv + Vector((uvOffset,0)) - - bpy.ops.object.mode_set(mode="EDIT") - - if rotateUv: - bpy.ops.object.mode_set(mode="OBJECT") - for poly in selPolys: - bpy.context.object.data.polygons[poly].select = True - bpy.ops.object.mode_set(mode="EDIT") - bm = bmesh.from_edit_mesh(bpy.context.object.data) - bmesh.ops.reverse_uvs(bm, faces=[f for f in bm.faces if f.select]) - bmesh.ops.rotate_uvs(bm, faces=[f for f in bm.faces if f.select]) - #bmesh.update_edit_mesh(bpy.context.object.data, loop_triangles=False, destructive=False) - - - -class CopyUvIsland(Operator): - """Copy Uv Island""" - bl_idname = "mesh.uv_island_copy" - bl_label = "Copy Uv Island" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH' and - context.active_object.mode == "EDIT") - - def execute(self, context): - defCopyUvsIsland(self, context) - return {'FINISHED'} - -class PasteUvIsland(Operator): - """Paste Uv Island""" - bl_idname = "mesh.uv_island_paste" - bl_label = "Paste Uv Island" - bl_options = {"REGISTER", "UNDO"} - - uvOffset = BoolProperty( - name="Uv Offset", - default=False - ) - - rotateUv = BoolProperty( - name="Rotate Uv Corner", - default=False - ) - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH' and - context.active_object.mode == "EDIT") - - def execute(self, context): - defPasteUvsIsland(self, self.uvOffset, self.rotateUv, context) - return {'FINISHED'} - - - -class createEditMultimesh(Operator): - """Create Edit Multi Mesh""" - bl_idname = "mesh.create_edit_multimesh" - bl_label = "Create edit multimesh" - bl_options = {"REGISTER", "UNDO"} - - - # creo el merge para editar - def execute(self,context): - global relvert - global me - global ob - temp = [[ob , [vert.co for vert in ob.data.vertices]]for ob in bpy.data.collections[bpy.context.scene.multimeshedit].objects] - vi = 0 - pi = 0 - relvert = {} - vertlist = [] - polylist = [] - for ob in temp: - objectMatrix = ob[0].matrix_world.copy() - for vert in ob[0].data.vertices: - vertlist.append(objectMatrix*vert.co) - for poly in ob[0].data.polygons: - polylist.append(tuple([vert+vi for vert in poly.vertices[:]])) - relvert[ob[0]] = {vert.index:vert.index+vi for vert in ob[0].data.vertices} - vi += len(ob[0].data.vertices) - ob[0].hide = 1 - me = bpy.data.meshes.new("editMesh") - ob = bpy.data.objects.new("editMesh", me) - bpy.context.scene.objects.link(ob) - me.from_pydata(vertlist,[],polylist) - bpy.ops.object.select_all(action="DESELECT") - bpy.context.scene.objects.active = ob - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - return {'FINISHED'} - - -class ApplyEditMultimesh(Operator): - """Apply Edit Multi Mesh""" - bl_idname = "mesh.apply_edit_multimesh" - bl_label = "Apply edit multimesh" - bl_options = {"REGISTER", "UNDO"} - - def execute(self,context): - bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - for object,rv in relvert.items(): - objectMatrix = object.matrix_world.inverted().copy() - for source, target in rv.items(): - object.data.vertices[source].co = objectMatrix * me.vertices[target].co - object.hide = 0 - bpy.context.scene.objects.unlink(ob) - return {'FINISHED'} - -# -------------------------VERTEX COLOR MASK---------------------------------- - - -class resymVertexGroups(Operator): - bl_idname = "mesh.vertex_color_mask" - bl_label = "Vertex Color Mask" - bl_description = ("Create a Vertex Color Mask") - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - obj = context.active_object - return obj is not None - - def execute(self, context): - obj = bpy.context.active_object - mesh= obj.data - - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - bpy.ops.mesh.select_all(action="DESELECT") - - bm = bmesh.from_edit_mesh(mesh) - bm.faces.ensure_lookup_table() - - islands = [] - faces = bm.faces - - try: - color_layer = bm.loops.layers.color["RGBMask"] - except: - color_layer = bm.loops.layers.color.new("RGBMask") - - while faces: - faces[0].select_set(True) - bpy.ops.mesh.select_linked() - islands.append([f for f in faces if f.select]) - bpy.ops.mesh.hide(unselected=False) - faces = [f for f in bm.faces if not f.hide] - - bpy.ops.mesh.reveal() - - for island in islands: - color = (uniform(0,1),uniform(0,1),uniform(0,1),1) - for face in island: - for loop in face.loops: - loop[color_layer] = color - - bpy.ops.object.mode_set(mode="VERTEX_PAINT") - - return {'FINISHED'} diff --git a/oscurart_tools/oscurart_objects.py b/oscurart_tools/oscurart_objects.py deleted file mode 100644 index b3773b7a..00000000 --- a/oscurart_tools/oscurart_objects.py +++ /dev/null @@ -1,553 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -import os -from bpy.types import Operator -from bpy.props import BoolProperty -from bpy_extras.object_utils import world_to_camera_view - -# ------------------------ SEARCH AND SELECT ------------------------ - - -class SearchAndSelectOt(bpy.types.Operator): - """Search and select objects, by name""" - bl_idname = "object.search_and_select_osc" - bl_label = "Search And Select" - bl_options = {"REGISTER", "UNDO"} - - start = BoolProperty(name="Start With", default=True) - count = BoolProperty(name="Contain", default=True) - end = BoolProperty(name="End", default=True) - - def execute(self, context): - for objeto in bpy.context.scene.objects: - variableNombre = bpy.context.scene.SearchAndSelectOt - if self.start: - if objeto.name.startswith(variableNombre): - objeto.select = True - if self.count: - if objeto.name.count(variableNombre): - objeto.select = True - if self.end: - if objeto.name.count(variableNombre): - objeto.select = True - return {'FINISHED'} - - -# -------------------------RENAME OBJECTS---------------------------------- - -# CREO VARIABLE -bpy.types.Scene.RenameObjectOt = bpy.props.StringProperty(default="Type here") - - -class renameObjectsOt (Operator): - """Batch rename objects, supports selection order""" - bl_idname = "object.rename_objects_osc" - bl_label = "Rename Objects" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - i = 0 - listaObj = bpy.selection_osc - for objeto in listaObj: - objeto.name = "%s_%04d" % (bpy.context.scene.RenameObjectOt, i) - i += 1 - return {'FINISHED'} - - -# ---------------------------REMOVE MODIFIERS Y APPLY MODIFIERS----------- - -class oscRemModifiers (Operator): - """Removes all modifiers in the selected objects""" - bl_idname = "object.modifiers_remove_osc" - bl_label = "Remove modifiers" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - for objeto in bpy.context.selected_objects: - for modificador in objeto.modifiers: - print(modificador.type) - bpy.context.scene.objects.active = objeto - bpy.ops.object.modifier_remove(modifier=modificador.name) - return {'FINISHED'} - - -class oscApplyModifiers (Operator): - """Applies all the modifiers in the selected objects.(This does not work in objects with shapekeys)""" - bl_idname = "object.modifiers_apply_osc" - bl_label = "Apply modifiers" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - for objeto in bpy.context.selected_objects: - bpy.ops.object.select_all(action='DESELECT') - bpy.context.scene.objects.active = objeto - objeto.select = True - if objeto.data.users >= 2: - bpy.ops.object.make_single_user( - type='SELECTED_OBJECTS', - object=True, - obdata=True, - material=False, - texture=False, - animation=False) - for modificador in objeto.modifiers: - try: - bpy.ops.object.modifier_apply( - apply_as="DATA", - modifier=modificador.name) - except: - bpy.ops.object.modifier_remove(modifier=modificador.name) - print("* Modifier %s skipping apply" % (modificador.name)) - - return {'FINISHED'} - - -# ------------------------------------ RELINK OBJECTS--------------------- - - -def relinkObjects(self): - - - LISTSCENE = [] - if bpy.selection_osc: - for SCENE in bpy.data.scenes[:]: - if SCENE.objects: - if bpy.selection_osc[-1] in SCENE.objects[:]: - LISTSCENE.append(SCENE) - - - if LISTSCENE: - OBJECTS = bpy.selection_osc[:-1] - ACTOBJ = bpy.selection_osc[-1] - OBJSEL = bpy.selection_osc[:] - - LISTSCENE.remove(bpy.context.scene) - - bpy.ops.object.select_all(action='DESELECT') - - - for OBJETO in OBJECTS: - if OBJETO.users != len(bpy.data.scenes): - print(OBJETO.name) - OBJETO.select = True - - for SCENE in LISTSCENE: - bpy.ops.object.make_links_scene(scene=SCENE.name) - - bpy.context.scene.objects.active = ACTOBJ - for OBJ in OBJSEL: - OBJ.select = True - else: - self.report({'INFO'}, message="Scenes are empty") - - -class OscRelinkObjectsBetween (Operator): - """Copies from the selected object the scenes where this is. Its similar to 'Objects to Scene'""" - bl_idname = "object.relink_objects_between_scenes" - bl_label = "Relink Objects Between Scenes" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - relinkObjects(self) - return {'FINISHED'} - - -# ------------------------------------ COPY GROUPS AND LAYERS------------- - - -def CopyObjectGroupsAndLayers(self): - - OBSEL = bpy.selection_osc[:] - - if OBSEL: - GLOBALLAYERS = list(OBSEL[-1].layers[:]) - ACTSCENE = bpy.context.scene - GROUPS = OBSEL[-1].users_group - ACTOBJ = OBSEL[-1] - - for OBJECT in OBSEL[:-1]: - for scene in bpy.data.scenes[:]: - - # SI EL OBJETO ACTIVO ESTA EN LA ESCENA - if ACTOBJ in scene.objects[:] and OBJECT in scene.objects[:]: - scene.object_bases[ - OBJECT.name].layers[ - :] = scene.object_bases[ - ACTOBJ.name].layers[ - :] - elif ACTOBJ not in scene.objects[:] and OBJECT in scene.objects[:]: - scene.object_bases[OBJECT.name].layers[:] = list(GLOBALLAYERS) - - # REMUEVO DE TODO GRUPO - for GROUP in bpy.data.collections[:]: - if GROUP in OBJECT.users_group[:]: - GROUP.objects.unlink(OBJECT) - - # INCLUYO OBJETO EN GRUPOS - for GROUP in GROUPS: - GROUP.objects.link(OBJECT) - - bpy.context.window.screen.scene = ACTSCENE - bpy.context.scene.objects.active = ACTOBJ - - -class OscCopyObjectGAL (Operator): - """Copies to scenes the layers setup in the active scene of the selected object""" - bl_idname = "object.copy_objects_groups_layers" - bl_label = "Copy Groups And Layers" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - CopyObjectGroupsAndLayers(self) - return {'FINISHED'} - - -# ------------------------------------ SELECTION ------------------------- -bpy.selection_osc = [] - - -def select_osc(): - if bpy.context.mode == "OBJECT": - obj = bpy.context.object - sel = len(bpy.context.selected_objects) - - if sel == 0: - bpy.selection_osc = [] - else: - if sel == 1: - bpy.selection_osc = [] - bpy.selection_osc.append(obj) - elif sel > len(bpy.selection_osc): - for sobj in bpy.context.selected_objects: - if (sobj in bpy.selection_osc) is False: - bpy.selection_osc.append(sobj) - - elif sel < len(bpy.selection_osc): - for it in bpy.selection_osc: - if (it in bpy.context.selected_objects) is False: - bpy.selection_osc.remove(it) - - -class OscSelection(bpy.types.Header): - bl_label = "Selection Osc" - bl_space_type = "VIEW_3D" - - def __init__(self): - select_osc() - - def draw(self, context): - """ - layout = self.layout - row = layout.row() - row.label("Sels: "+str(len(bpy.selection_osc))) - """ - -# =============== DISTRIBUTE ====================== - - -def ObjectDistributeOscurart(self, X, Y, Z): - if len(bpy.selection_osc[:]) > 1: - # VARIABLES - dif = bpy.selection_osc[-1].location - bpy.selection_osc[0].location - chunkglobal = dif / (len(bpy.selection_osc[:]) - 1) - chunkx = 0 - chunky = 0 - chunkz = 0 - deltafst = bpy.selection_osc[0].location - - # ORDENA - for OBJECT in bpy.selection_osc[:]: - if X: - OBJECT.location.x = deltafst[0] + chunkx - if Y: - OBJECT.location[1] = deltafst[1] + chunky - if Z: - OBJECT.location.z = deltafst[2] + chunkz - chunkx += chunkglobal[0] - chunky += chunkglobal[1] - chunkz += chunkglobal[2] - else: - self.report({'INFO'}, "Needs at least two selected objects") - - -class DialogDistributeOsc(Operator): - """Distribute evenly the selected objects in x y z""" - bl_idname = "object.distribute_osc" - bl_label = "Distribute Objects" - Boolx = BoolProperty(name="X") - Booly = BoolProperty(name="Y") - Boolz = BoolProperty(name="Z") - - def execute(self, context): - ObjectDistributeOscurart(self, self.Boolx, self.Booly, self.Boolz) - return {'FINISHED'} - - def invoke(self, context, event): - self.Boolx = True - self.Booly = True - self.Boolz = True - return context.window_manager.invoke_props_dialog(self) - - -# ======================== SET LAYERS TO OTHER SCENES ==================== - - -def DefSetLayersToOtherScenes(): - actsc = bpy.context.screen.scene - for object in bpy.context.selected_objects[:]: - bpy.context.screen.scene = actsc - lyrs = object.layers[:] - for scene in bpy.data.scenes[:]: - if object in scene.objects[:]: - bpy.context.screen.scene = scene - object.layers = lyrs - else: - print("* %s is not in %s" % (object.name, scene.name)) - - bpy.context.screen.scene = actsc - - -class SetLayersToOtherScenes (Operator): - """Copies to scenes the layers setup in the active scene of the selected object""" - bl_idname = "object.set_layers_to_other_scenes" - bl_label = "Copy actual Layers to Other Scenes" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefSetLayersToOtherScenes() - return {'FINISHED'} - - -# ======================== RENDER OBJECTS IN CAMERA ====================== - - -def DefRenderOnlyInCamera(): - # crea grupos - if "INCAMERA" not in bpy.data.collections: - bpy.data.collections.new("INCAMERA") - if "NOTINCAMERA" not in bpy.data.collections: - bpy.data.collections.new("NOTINCAMERA") - - # limpio grupos - for ob in bpy.data.objects: - if ob.name in bpy.data.collections["INCAMERA"].objects: - bpy.data.collections["INCAMERA"].objects.unlink(ob) - if ob.name in bpy.data.collections["NOTINCAMERA"].objects: - bpy.data.collections["NOTINCAMERA"].objects.unlink(ob) - - # ordeno grupos - for ob in bpy.data.objects: - obs = False - if ob.type == "MESH": - tm = ob.to_mesh(bpy.context.scene, True, "RENDER") - for vert in tm.vertices: - cam = world_to_camera_view( - bpy.context.scene, - bpy.context.scene.camera, - vert.co + ob.location) - if cam[0] >= -0 and cam[0] <= 1 and cam[1] >= 0 and cam[1] <= 1: - obs = True - del(tm) - else: - obs = True - if obs: - bpy.data.collections["INCAMERA"].objects.link(ob) - else: - bpy.data.collections["NOTINCAMERA"].objects.link(ob) - - -class RenderOnlyInCamera (Operator): - """Create two different groups, one group contains the objects that are in the camera frame, """ \ - """those that camera can see, and then a second group that contains the object that the camera can`t see""" - bl_idname = "group.group_in_out_camera" - bl_label = "Make a group for objects in outer camera" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefRenderOnlyInCamera() - return {'FINISHED'} - - -# ------------------------ DUPLICATE OBJECTS SYMMETRY ------------------------ - -def duplicateSymmetrical(self, disconnect): - for objeto in bpy.context.selected_objects: - - bpy.ops.object.select_all(action='DESELECT') - objeto.select = 1 - bpy.context.scene.objects.active = objeto - bpy.ops.object.duplicate(linked=1) - OBDUP = bpy.context.active_object - print(OBDUP) - OBDUP.driver_add("location") - OBDUP.animation_data.drivers[0].driver.expression = "-var" - OBDUP.animation_data.drivers[0].driver.variables.new() - OBDUP.animation_data.drivers[0].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 0].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 0].driver.variables[ - 0].targets[ - 0].transform_type = 'LOC_X' - OBDUP.animation_data.drivers[1].driver.expression = "var" - OBDUP.animation_data.drivers[1].driver.variables.new() - OBDUP.animation_data.drivers[1].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 1].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 1].driver.variables[ - 0].targets[ - 0].transform_type = 'LOC_Y' - OBDUP.animation_data.drivers[2].driver.expression = "var" - OBDUP.animation_data.drivers[2].driver.variables.new() - OBDUP.animation_data.drivers[2].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 2].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 2].driver.variables[ - 0].targets[ - 0].transform_type = 'LOC_Z' - OBDUP.driver_add("scale") - OBDUP.animation_data.drivers[3].driver.expression = "-var" - OBDUP.animation_data.drivers[3].driver.variables.new() - OBDUP.animation_data.drivers[3].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 3].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 3].driver.variables[ - 0].targets[ - 0].transform_type = 'SCALE_X' - OBDUP.animation_data.drivers[4].driver.expression = "var" - OBDUP.animation_data.drivers[4].driver.variables.new() - OBDUP.animation_data.drivers[4].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 4].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 4].driver.variables[ - 0].targets[ - 0].transform_type = 'SCALE_Y' - OBDUP.animation_data.drivers[5].driver.expression = "var" - OBDUP.animation_data.drivers[5].driver.variables.new() - OBDUP.animation_data.drivers[5].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 5].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 5].driver.variables[ - 0].targets[ - 0].transform_type = 'SCALE_Z' - OBDUP.driver_add("rotation_euler") - OBDUP.animation_data.drivers[6].driver.expression = "var" - OBDUP.animation_data.drivers[6].driver.variables.new() - OBDUP.animation_data.drivers[6].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 6].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 6].driver.variables[ - 0].targets[ - 0].transform_type = 'ROT_X' - OBDUP.animation_data.drivers[7].driver.expression = "-var" - OBDUP.animation_data.drivers[7].driver.variables.new() - OBDUP.animation_data.drivers[7].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 7].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 7].driver.variables[ - 0].targets[ - 0].transform_type = 'ROT_Y' - OBDUP.animation_data.drivers[8].driver.expression = "-var" - OBDUP.animation_data.drivers[8].driver.variables.new() - OBDUP.animation_data.drivers[8].driver.variables[0].type = "TRANSFORMS" - OBDUP.animation_data.drivers[ - 8].driver.variables[ - 0].targets[ - 0].id = objeto - OBDUP.animation_data.drivers[ - 8].driver.variables[ - 0].targets[ - 0].transform_type = 'ROT_Z' - - if disconnect is not True: - bpy.ops.object.make_single_user(obdata=True, object=True) - bpy.context.active_object.driver_remove("location") - bpy.context.active_object.driver_remove("rotation_euler") - bpy.context.active_object.driver_remove("scale") - - -class oscDuplicateSymmetricalOp (Operator): - """Creates a symmetrical copy on the X axys, also Links by drivers position, rotation and scale""" - bl_idname = "object.duplicate_object_symmetry_osc" - bl_label = "Oscurart Duplicate Symmetrical" - bl_options = {"REGISTER", "UNDO"} - - desconecta = BoolProperty(name="Keep Connection", default=True) - - def execute(self, context): - - duplicateSymmetrical(self, self.desconecta) - - return {'FINISHED'} - - -# ------------------------ OBJECTS TO GROUPS ------------------------ - -def DefObjectToGroups(): - try: - "%s_MSH" % (os.path.basename(bpy.data.filepath).replace(".blend", "")) - scgr = bpy.data.collections["%s_MSH" % (os.path.basename(bpy.data.filepath).replace(".blend", ""))] - except: - scgr = bpy.data.collections.new( - "%s_MSH" % - (os.path.basename(bpy.data.filepath).replace(".blend", ""))) - for ob in bpy.data.objects: - if ob.select: - if ob.type == "MESH": - gr = bpy.data.collections.new(ob.name) - gr.objects.link(ob) - scgr.objects.link(ob) - - -class ObjectsToGroups (Operator): - """Creates a group("_MESH") containing all the mesh type objects in the scene. """ \ - """Creates a group(“object_name”) per mesh type object""" - bl_idname = "object.objects_to_groups" - bl_label = "Objects to Groups" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefObjectToGroups() - return {'FINISHED'} diff --git a/oscurart_tools/oscurart_overrides.py b/oscurart_tools/oscurart_overrides.py deleted file mode 100644 index 9924fda5..00000000 --- a/oscurart_tools/oscurart_overrides.py +++ /dev/null @@ -1,307 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from bpy.types import Operator, Panel -import os - - -# ------------------APPLY AND RESTORE OVERRIDES ------------------ - -def DefOscApplyOverrides(self): - types = {'MESH', 'META', 'CURVE'} - for ob in bpy.data.objects: - if ob.type in types: - if not len(ob.material_slots): - ob.data.materials.append(None) - slotlist = {ob: [sl.material for sl in ob.material_slots] - for ob in bpy.data.objects if ob.type in types if len(ob.material_slots)} - with open("%s_override.txt" % (os.path.join(os.path.dirname(bpy.data.filepath), - bpy.context.scene.name)), mode="w") as file: - file.write(str(slotlist)) - scene = bpy.context.scene - proptolist = list(eval(scene.oscurart.overrides)) - for group, material in proptolist: - for object in bpy.data.collections[group].objects: - lenslots = len(object.material_slots) - if object.type in types: - if len(object.data.materials): - object.data.materials.clear() - for newslot in range(lenslots): - object.data.materials.append( - bpy.data.materials[material]) - - -def DefOscRestoreOverrides(self): - with open("%s_override.txt" % (os.path.join(os.path.dirname(bpy.data.filepath), - bpy.context.scene.name)), mode="r") as file: - slotlist = eval(file.read()) - for ob, slots in slotlist.items(): - ob.data.materials.clear() - for slot in slots: - ob.data.materials.append(slot) - - -# HAND OPERATOR - -class OscApplyOverrides(Operator): - """>>>Danger Option<<< Apply and restore override materials, """ \ - """similar as ON/OFF its basically the same, save before try it""" - bl_idname = "render.apply_overrides" - bl_label = "Apply Overrides in this Scene" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefOscApplyOverrides(self) - return {'FINISHED'} - - -class OscRestoreOverrides(Operator): - """>>>Danger Option<<< Apply and restore override materials, """ \ - """similar as ON/OFF its basically the same, save before try it""" - bl_idname = "render.restore_overrides" - bl_label = "Restore Overrides in this Scene" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - DefOscRestoreOverrides(self) - return {'FINISHED'} - -bpy.use_overrides = False - - -class OscOverridesOn(Operator): - """>>>Danger Option<<< its recommended to save before try it, """ \ - """it replace all materials by the override materials, """ \ - """its possible once active to see the objects rendering as override render by pressing F12""" - bl_idname = "render.overrides_on" - bl_label = "Turn On Overrides" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - if bpy.use_overrides is False: - bpy.app.handlers.render_pre.append(DefOscApplyOverrides) - bpy.app.handlers.render_post.append(DefOscRestoreOverrides) - bpy.use_overrides = True - print("Overrides on!") - else: - bpy.app.handlers.render_pre.remove(DefOscApplyOverrides) - bpy.app.handlers.render_post.remove(DefOscRestoreOverrides) - bpy.use_overrides = False - print("Overrides off!") - return {'FINISHED'} - - -# -------------------- CHECK OVERRIDES ------------------- - -class OscCheckOverrides(Operator): - """Check all overrides to verify if there is all set up properly, info its display in the console""" - bl_idname = "render.check_overrides" - bl_label = "Check Overrides" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - GROUPI = False - GLOBAL = 0 - GLOBALERROR = 0 - - print("==== STARTING CHECKING ====") - print("") - - for SCENE in bpy.data.scenes[:]: - MATLIST = [] - MATI = False - - for MATERIAL in bpy.data.materials[:]: - MATLIST.append(MATERIAL.name) - - GROUPLIST = [] - for GROUP in bpy.data.collections[:]: - if GROUP.users > 0: - GROUPLIST.append(GROUP.name) - - print(" %s Scene is checking" % (SCENE.name)) - - for OVERRIDE in list(eval(SCENE.oscurart.overrides)): - # REVISO OVERRIDES EN GRUPOS - if OVERRIDE[0] in GROUPLIST: - pass - else: - print("** %s group are in conflict." % (OVERRIDE[0])) - GROUPI = True - GLOBALERROR += 1 - # REVISO OVERRIDES EN GRUPOS - if OVERRIDE[1] in MATLIST: - pass - else: - print("** %s material are in conflict." % (OVERRIDE[1])) - MATI = True - GLOBALERROR += 1 - - if MATI is False: - print("-- Materials are ok.") - else: - GLOBAL += 1 - if GROUPI is False: - print("-- Groups are ok.") - else: - GLOBAL += 1 - - if GLOBAL < 1: - self.report({'INFO'}, "Materials And Groups are Ok") - if GLOBALERROR > 0: - self.report({'WARNING'}, "Override Error: Look in the Console") - print("") - - return {'FINISHED'} - -# --------------------------------- OVERRIDES PANEL ---------------------- - - -class OscOverridesGUI(Panel): - bl_label = "Oscurart Material Overrides" - bl_idname = "Oscurart Overrides List" - bl_space_type = "PROPERTIES" - bl_region_type = "WINDOW" - bl_context = "render" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - - layout = self.layout - col = layout.column(align=1) - colrow = col.row(align=1) - colrow.operator("render.overrides_add_slot", icon="ZOOMIN") - colrow.operator("render.overrides_remove_slot", icon="ZOOMOUT") - col.operator("render.overrides_transfer", icon="SHORTDISPLAY") - - for i, m in enumerate(bpy.context.scene.ovlist): - colrow = col.row(align=1) - colrow.prop_search(m, "grooverride", bpy.data, "collections", text="") - colrow.prop_search( - m, - "matoverride", - bpy.data, - "materials", - text="") - if i != len(bpy.context.scene.ovlist) - 1: - pa = colrow.operator( - "ovlist.move_down", - text="", - icon="TRIA_DOWN") - pa.index = i - if i > 0: - p = colrow.operator("ovlist.move_up", text="", icon="TRIA_UP") - p.index = i - pb = colrow.operator("ovlist.kill", text="", icon="X") - pb.index = i - - -class OscOverridesUp(Operator): - """Move override slot up""" - bl_idname = 'ovlist.move_up' - bl_label = 'Move Override up' - bl_options = {'INTERNAL'} - - index = bpy.props.IntProperty(min=0) - - @classmethod - def poll(self, context): - return len(context.scene.ovlist) - - def execute(self, context): - ovlist = context.scene.ovlist - ovlist.move(self.index, self.index - 1) - - return {'FINISHED'} - - -class OscOverridesDown(Operator): - """Move override slot down""" - bl_idname = 'ovlist.move_down' - bl_label = 'Move Override down' - bl_options = {'INTERNAL'} - - index = bpy.props.IntProperty(min=0) - - @classmethod - def poll(self, context): - return len(context.scene.ovlist) - - def execute(self, context): - ovlist = context.scene.ovlist - ovlist.move(self.index, self.index + 1) - return {'FINISHED'} - - -class OscOverridesKill(Operator): - """Remove override slot""" - bl_idname = 'ovlist.kill' - bl_label = 'Kill Override' - bl_options = {'INTERNAL'} - - index = bpy.props.IntProperty(min=0) - - @classmethod - def poll(self, context): - return len(context.scene.ovlist) - - def execute(self, context): - ovlist = context.scene.ovlist - ovlist.remove(self.index) - return {'FINISHED'} - - -class OscTransferOverrides(Operator): - """Applies the previously configured slots (Groups < Material) to the Scene. """ \ - """This should be transfer once the override groups are set""" - bl_idname = "render.overrides_transfer" - bl_label = "Transfer Overrides" - - def execute(self, context): - # CREO LISTA - OSCOV = [[OVERRIDE.grooverride, OVERRIDE.matoverride] - for OVERRIDE in bpy.context.scene.ovlist[:] - if OVERRIDE.matoverride != "" and OVERRIDE.grooverride != ""] - - bpy.context.scene.oscurart.overrides = str(OSCOV) - return {'FINISHED'} - - -class OscAddOverridesSlot(Operator): - """Add override slot""" - bl_idname = "render.overrides_add_slot" - bl_label = "Add Override Slot" - - def execute(self, context): - prop = bpy.context.scene.ovlist.add() - prop.matoverride = "" - prop.grooverride = "" - return {'FINISHED'} - - -class OscRemoveOverridesSlot(Operator): - """Remove override slot""" - bl_idname = "render.overrides_remove_slot" - bl_label = "Remove Override Slot" - - def execute(self, context): - context.scene.ovlist.remove(len(bpy.context.scene.ovlist) - 1) - return {'FINISHED'} diff --git a/oscurart_tools/oscurart_render.py b/oscurart_tools/oscurart_render.py deleted file mode 100644 index 67dacfb2..00000000 --- a/oscurart_tools/oscurart_render.py +++ /dev/null @@ -1,511 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from bpy.types import ( - Operator, - Panel, - ) -import os - -# -------------------------------- RENDER ALL SCENES --------------------- - -def defRenderAll(frametype, scenes): - - activescene = bpy.context.scene - FC = bpy.context.scene.frame_current - FS = bpy.context.scene.frame_start - FE = bpy.context.scene.frame_end - print("---------------------") - types = {'MESH', 'META', 'CURVE'} - - for ob in bpy.data.objects: - if ob.type in types: - if not len(ob.material_slots): - ob.data.materials.append(None) - - slotlist = {ob: [sl.material for sl in ob.material_slots] - for ob in bpy.data.objects if ob.type in types if len(ob.material_slots)} - - for scene in scenes: - proptolist = list(eval(scene.oscurart.overrides)) - renpath = scene.render.filepath - - if frametype: - scene.frame_start = FC - scene.frame_end = FC - scene.frame_end = FC - scene.frame_start = FC - - for group, material in proptolist: - for object in bpy.data.collections[group].objects: - lenslots = len(object.material_slots) - if object.type in types: - if len(object.data.materials): - object.data.materials.clear() - for newslot in range(lenslots): - object.data.materials.append( - bpy.data.materials[material]) - filename = os.path.basename(bpy.data.filepath.rpartition(".")[0]) - uselayers = {layer: layer.use for layer in scene.render.layers} - for layer, usado in uselayers.items(): - if usado: - for i in scene.render.layers: - i.use = False - layer.use = 1 - - print("SCENE: %s" % scene.name) - print("LAYER: %s" % layer.name) - print("OVERRIDE: %s" % str(proptolist)) - #scene.render.filepath = os.path.join( - # os.path.dirname(renpath), filename, scene.name, layer.name, "%s_%s_%s" % - # (filename, scene.name, layer.name)) - tokens = { - "$Scene":scene.name, - "$File":os.path.basename(bpy.data.filepath).split(".")[0], - "$Layer":layer.name, - "$Camera":scene.camera.name} - - scene.render.filepath = renpath.replace("$Scene",tokens["$Scene"]).replace("$File",tokens["$File"]).replace("$Layer",tokens["$Layer"]).replace("$Camera",tokens["$Camera"]) - - bpy.context.window.screen.scene = scene - bpy.ops.render.render( - animation=True, - write_still=True, - layer=layer.name, - scene=scene.name) - print("DONE") - print("---------------------") - for layer, usado in uselayers.items(): - layer.use = usado - scene.render.filepath = renpath - for ob, slots in slotlist.items(): - ob.data.materials.clear() - for slot in slots: - ob.data.materials.append(slot) - if frametype: - scene.frame_start = FS - scene.frame_end = FE - scene.frame_end = FE - scene.frame_start = FS - - bpy.context.window.screen.scene = activescene - - -class renderAll (Operator): - """Renders all scenes executing the Oscurart overrides if those are set up. """ \ - """Saves the renders in their respective folders using the scenes and render layers names""" - bl_idname = "render.render_all_scenes_osc" - bl_label = "Render All Scenes" - - frametype = bpy.props.BoolProperty(default=False) - - def execute(self, context): - defRenderAll(self.frametype, [scene for scene in bpy.data.scenes]) - return {'FINISHED'} - - -# --------------------------------RENDER SELECTED SCENES------------------ - -bpy.types.Scene.use_render_scene = bpy.props.BoolProperty() - - -class renderSelected (Operator): - """Renders the seleccted scenes on the checkboxes, executing the Oscurart overrides if it was set up. """ \ - """Saves the renders in their respective folders using the scenes and render layers names""" - bl_idname = "render.render_selected_scenes_osc" - bl_label = "Render Selected Scenes" - - frametype = bpy.props.BoolProperty(default=False) - - def execute(self, context): - defRenderAll( - self.frametype, - [sc for sc in bpy.data.scenes if sc.use_render_scene]) - return {'FINISHED'} - -# --------------------------------RENDER CURRENT SCENE-------------------- - - -class renderCurrent (Operator): - """Renders the active scene executing the Oscurart overrides if it was set up. """ \ - """Saves the renders in their respective folders using the scenes and render layers names""" - bl_idname = "render.render_current_scene_osc" - bl_label = "Render Current Scene" - - frametype = bpy.props.BoolProperty(default=False) - - def execute(self, context): - - defRenderAll(self.frametype, [bpy.context.scene]) - - return {'FINISHED'} - - -# --------------------------RENDER CROP---------------------- -bpy.types.Scene.rcPARTS = bpy.props.IntProperty( - default=0, min=2, max=50, step=1) - - -def OscRenderCropFunc(): - - SCENENAME = os.path.split(bpy.data.filepath)[-1].partition(".")[0] - PARTS = bpy.context.scene.rcPARTS - CHUNKYSIZE = 1 / PARTS - FILEPATH = bpy.context.scene.render.filepath - bpy.context.scene.render.use_border = True - bpy.context.scene.render.use_crop_to_border = True - for PART in range(PARTS): - bpy.context.scene.render.border_min_y = PART * CHUNKYSIZE - bpy.context.scene.render.border_max_y = ( - PART * CHUNKYSIZE) + CHUNKYSIZE - bpy.context.scene.render.filepath = "%s_part%s" % ( - os.path.join(FILEPATH, - SCENENAME, - bpy.context.scene.name, - SCENENAME), - PART) - bpy.ops.render.render(animation=False, write_still=True) - - bpy.context.scene.render.filepath = FILEPATH - - -class renderCrop (Operator): - """It renders croping the image in to a X number of pieces. """ \ - """Useful for rendering really big images""" - bl_idname = "render.render_crop_osc" - bl_label = "Render Crop: Render!" - - def execute(self, context): - OscRenderCropFunc() - return {'FINISHED'} - -# ---------------------------BATCH MAKER------------------ - - -def defoscBatchMaker(TYPE, BIN): - - if os.name == "nt": - print("PLATFORM: WINDOWS") - SYSBAR = os.sep - EXTSYS = ".bat" - QUOTES = '"' - else: - print("PLATFORM:LINUX") - SYSBAR = os.sep - EXTSYS = ".sh" - QUOTES = '' - - FILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0] - BINDIR = bpy.app[4] - SHFILE = os.path.join( - bpy.data.filepath.rpartition(SYSBAR)[0], - FILENAME + EXTSYS) - - renpath = bpy.context.scene.render.filepath - tokens = { - "$Scene":bpy.context.scene.name, - "$File":os.path.basename(bpy.data.filepath).split(".")[0], - "$Layer":bpy.context.scene.render.layers.active.name, - "$Camera":bpy.context.scene.camera.name} - - rfp = bpy.context.scene.render.filepath.replace("$Scene",tokens["$Scene"]).replace("$File",tokens["$File"]).replace("$Layer",tokens["$Layer"]).replace("$Camera",tokens["$Camera"]) - with open(SHFILE, "w") as FILE: - # assign permission in linux - if EXTSYS == ".sh": - try: - os.chmod(SHFILE, stat.S_IRWXU) - except: - print( - "** Oscurart Batch maker can not modify the permissions.") - if not BIN: - FILE.writelines("%s%s%s -b %s -x 1 -P %s%s.py -s %s -e %s " % - (QUOTES, BINDIR, QUOTES, bpy.data.filepath, - bpy.data.filepath.rpartition(SYSBAR)[0] + SYSBAR, TYPE, - str(bpy.context.scene.frame_start), str(bpy.context.scene.frame_end))) - else: - FILE.writelines("%s -b %s -x 1 -P %s%s.py -s %s -e %s " % - ("blender", bpy.data.filepath, - bpy.data.filepath.rpartition(SYSBAR)[0] + SYSBAR, TYPE, - str(bpy.context.scene.frame_start), str(bpy.context.scene.frame_end))) - - RLATFILE = "%s%sosRlat.py" % ( - bpy.data.filepath.rpartition(SYSBAR)[0], - SYSBAR) - if not os.path.isfile(RLATFILE): - with open(RLATFILE, "w") as file: - if EXTSYS == ".sh": - try: - os.chmod(RLATFILE, stat.S_IRWXU) - except: - print( - "** Oscurart Batch maker can not modify the permissions.") - file.writelines( - "import bpy \nbpy.ops.render.render_all_scenes_osc()\nbpy.ops.wm.quit_blender()") - - else: - print("The All Python files Skips: Already exist!") - - RSLATFILE = "%s%sosRSlat.py" % ( - bpy.data.filepath.rpartition(SYSBAR)[0], - SYSBAR) - if not os.path.isfile(RSLATFILE): - with open(RSLATFILE, "w") as file: - if EXTSYS == ".sh": - try: - os.chmod(RSLATFILE, stat.S_IRWXU) - except: - print( - "** Oscurart Batch maker can not modify the permissions.") - file.writelines( - "import bpy \nbpy.ops.render.render_selected_scenes_osc()\nbpy.ops.wm.quit_blender()") - else: - print("The Selected Python files Skips: Already exist!") - - -class oscBatchMaker (Operator): - """It creates .bat(win) or .sh(unix) file, to execute and render from Console/Terminal""" - bl_idname = "file.create_batch_maker_osc" - bl_label = "Make render batch" - bl_options = {'REGISTER', 'UNDO'} - - type = bpy.props.EnumProperty( - name="Render Mode", - description="Select Render Mode", - items=(('osRlat', "All Scenes", "Render All Layers At Time"), - ('osRSlat', "Selected Scenes", "Render Only The Selected Scenes")), - default='osRlat', - ) - - bin = bpy.props.BoolProperty( - default=False, - name="Use Environment Variable") - - def execute(self, context): - defoscBatchMaker(self.type, self.bin) - return {'FINISHED'} - -# --------------------------------------PYTHON BATCH---------------------- - - -def defoscPythonBatchMaker(BATCHTYPE, SIZE): - - # REVISO SISTEMA - if os.name == "nt": - print("PLATFORM: WINDOWS") - SYSBAR = "\\" - EXTSYS = ".bat" - QUOTES = '"' - else: - print("PLATFORM:LINUX") - SYSBAR = "/" - EXTSYS = ".sh" - QUOTES = '' - - # CREO VARIABLES - FILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0] - SHFILE = "%s%s%s_PythonSecureBatch.py" % ( - bpy.data.filepath.rpartition(SYSBAR)[0], - SYSBAR, - FILENAME) - BATCHLOCATION = "%s%s%s%s" % ( - bpy.data.filepath.rpartition(SYSBAR)[0], - SYSBAR, - FILENAME, - EXTSYS) - - with open(SHFILE, "w") as FILEBATCH: - - if EXTSYS == ".bat": - BATCHLOCATION = BATCHLOCATION.replace("\\", "/") - - # SI EL OUTPUT TIENE DOBLE BARRA LA REEMPLAZO - FRO = bpy.context.scene.render.filepath - if bpy.context.scene.render.filepath.count("//"): - FRO = bpy.context.scene.render.filepath.replace( - "//", - bpy.data.filepath.rpartition(SYSBAR)[0] + SYSBAR) - if EXTSYS == ".bat": - FRO = FRO.replace("\\", "/") - - # CREO BATCH - bpy.ops.file.create_batch_maker_osc(type=BATCHTYPE) - - SCRIPT = (''' -import os -REPITE= True -BAT= '%s' -SCENENAME ='%s' -DIR='%s%s' -def RENDER(): - os.system(BAT) -def CLEAN(): - global REPITE - FILES = [root+'/'+FILE for root, dirs, files in os.walk(os.getcwd()) if - len(files) > 0 for FILE in files if FILE.count('~') == False] - RESPUESTA=False - for FILE in FILES: - if os.path.getsize(FILE) < %s: - os.remove(FILE) - RESPUESTA= True - if RESPUESTA: - REPITE=True - else: - REPITE=False -REPITE=True -while REPITE: - REPITE=False - RENDER() - os.chdir(DIR) - CLEAN() -''' % (BATCHLOCATION, FILENAME, FRO, FILENAME, SIZE)) - - # DEFINO ARCHIVO DE BATCH - FILEBATCH.writelines(SCRIPT) - - # ARCHIVO CALL - CALLFILENAME = bpy.data.filepath.rpartition(SYSBAR)[-1].rpartition(".")[0] - CALLFILE = "%s%s%s_CallPythonSecureBatch%s" % ( - bpy.data.filepath.rpartition(SYSBAR)[0], - SYSBAR, - CALLFILENAME, - EXTSYS) - - with open(CALLFILE, "w") as CALLFILEBATCH: - - SCRIPT = "python %s" % (SHFILE) - CALLFILEBATCH.writelines(SCRIPT) - - if EXTSYS == ".sh": - try: - os.chmod(CALLFILE, stat.S_IRWXU) - os.chmod(SHFILE, stat.S_IRWXU) - except: - print("** Oscurart Batch maker can not modify the permissions.") - - -class oscPythonBatchMaker (Operator): - """It creates a file as “Make Render Batch” but it requires Phyton installed and """ \ - """the respective environment variables set up. """ \ - """If the render crashes, the batch automatically erase the broken frame and writes it again. """ \ - """Its not recommended if there is more than one machine rendering""" - bl_idname = "file.create_batch_python" - bl_label = "Make Batch Python" - bl_options = {'REGISTER', 'UNDO'} - - size = bpy.props.IntProperty(name="Size in Bytes", default=10, min=0) - - type = bpy.props.EnumProperty( - name="Render Mode", - description="Select Render Mode", - items=(('osRlat', "All Scenes", "Render All Layers At Time"), - ('osRSlat', "Selected Scenes", "Render Only The Selected Scenes")), - default='osRlat', - ) - - def execute(self, context): - defoscPythonBatchMaker(self.type, self.size) - return {'FINISHED'} - - -# ---------------------------------- BROKEN FRAMES --------------------- - -class VarColArchivos (bpy.types.PropertyGroup): - filename = bpy.props.StringProperty(name="", default="") - value = bpy.props.IntProperty(name="", default=10) - fullpath = bpy.props.StringProperty(name="", default="") - checkbox = bpy.props.BoolProperty(name="", default=True) -bpy.utils.register_class(VarColArchivos) - - -class SumaFile(Operator): - """Look for broken rendered files and shows it""" - bl_idname = "object.add_broken_file" - bl_label = "Add Broken Files" - - def execute(self, context): - os.chdir(os.path.dirname(bpy.data.filepath)) - absdir = os.path.join( - os.path.dirname(bpy.data.filepath), - bpy.context.scene.render.filepath.replace(r"//", - "")) - for root, folder, files in os.walk(absdir): - for f in files: - if os.path.getsize(os.path.join(root, f)) < 10: - print(f) - i = bpy.context.scene.broken_files.add() - i.filename = f - i.fullpath = os.path.join(root, f) - i.value = os.path.getsize(os.path.join(root, f)) - i.checkbox = True - return {'FINISHED'} - - -class ClearFile(Operator): - """Erase the list of broken frames""" - bl_idname = "object.clear_broken_file" - bl_label = "Clear Broken Files" - - def execute(self, context): - bpy.context.scene.broken_files.clear() - return {'FINISHED'} - - -class DeleteFiles(Operator): - """Erase the broken frames files from Disk""" - bl_idname = "object.delete_broken_file" - bl_label = "Delete Broken Files" - - def execute(self, context): - for file in bpy.context.scene.broken_files: - if file.checkbox: - os.remove(file.fullpath) - bpy.context.scene.broken_files.clear() - return {'FINISHED'} - - -bpy.types.Scene.broken_files = bpy.props.CollectionProperty( - type=VarColArchivos) - - -class BrokenFramesPanel (Panel): - bl_label = "Oscurart Broken Render Files" - bl_idname = "OBJECT_PT_osc_broken_files" - bl_space_type = 'PROPERTIES' - bl_region_type = 'WINDOW' - bl_context = "render" - bl_options = {'DEFAULT_CLOSED'} - - def draw(self, context): - layout = self.layout - col = layout.column(align=1) - - for i in bpy.context.scene.broken_files: - colrow = col.row(align=1) - colrow.prop(i, "filename") - colrow.prop(i, "value") - colrow.prop(i, "checkbox") - - col = layout.column(align=1) - colrow = col.row(align=1) - colrow.operator("object.add_broken_file") - colrow.operator("object.clear_broken_file") - colrow = col.row(align=1) - colrow.operator("object.delete_broken_file") diff --git a/oscurart_tools/oscurart_shapes.py b/oscurart_tools/oscurart_shapes.py deleted file mode 100644 index ec094c2d..00000000 --- a/oscurart_tools/oscurart_shapes.py +++ /dev/null @@ -1,473 +0,0 @@ -# ##### 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 ##### - -# <pep8 compliant> - -import bpy -from bpy.types import Operator -from bpy.props import ( - BoolProperty, - FloatProperty, - ) -import math - - -# ---------------------CREATE SHAPES---------------- - -def DefSplitShapes(self, ACTIVESHAPE, LAYOUTCOMPAT): - bpy.ops.object.mode_set(mode='OBJECT', toggle=False) - - ACTOBJ = bpy.context.active_object - has_keys = hasattr(getattr(ACTOBJ.data, "shape_keys", None), "key_blocks") - if has_keys: - INDEX = ACTOBJ.active_shape_key_index - - if LAYOUTCOMPAT: - for SHAPE in ACTOBJ.data.shape_keys.key_blocks: - if len(SHAPE.name) > 7: - SHAPE.name = SHAPE.name[:8] - - if ACTIVESHAPE: - ACTOBJ.active_shape_key_index = INDEX - AS = ACTOBJ.active_shape_key - AS.value = 1 - SHAPE = ACTOBJ.shape_key_add(name=AS.name[:8] + "_L", from_mix=True) - SHAPE.vertex_group = "_L" - SHAPE2 = ACTOBJ.shape_key_add(name=AS.name[:8] + "_R", from_mix=True) - SHAPE2.vertex_group = "_R" - bpy.ops.object.shape_key_clear() - else: - for SHAPE in ACTOBJ.data.shape_keys.key_blocks[1:]: - SHAPE.value = 1 - SHAPE1 = ACTOBJ.shape_key_add( - name=SHAPE.name[:8] + "_L", - from_mix=True) - SHAPE1.vertex_group = "_L" - SHAPE2 = ACTOBJ.shape_key_add( - name=SHAPE.name[:8] + "_R", - from_mix=True) - SHAPE2.vertex_group = "_R" - bpy.ops.object.shape_key_clear() - ACTOBJ.active_shape_key_index = INDEX - - return has_keys - - -class CreaShapes(Operator): - """Divide on left and right the diffenrent Shapekeys. “Create Mix Groups” its required""" - bl_idname = "mesh.split_lr_shapes_osc" - bl_label = "Split LR Shapes" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type in - {'MESH', 'SURFACE', 'CURVE'}) - - activeshape = BoolProperty( - name="Only Active Shape", - default=False - ) - layoutcompat = BoolProperty( - name="Layout Compatible", - default=True - ) - - def execute(self, context): - - is_done = DefSplitShapes(self, self.activeshape, - self.layoutcompat) - if not is_done: - self.report({'INFO'}, message="Active object doesn't have shape keys") - return {'CANCELLED'} - - return {'FINISHED'} - - -# ----------------------------SHAPES LAYOUT----------------------- - -class CreaShapesLayout(Operator): - """Creates an interface to control the Shapekeys of symmetrical Objects. “Create Mix Groups” its required""" - bl_idname = "mesh.create_symmetrical_layout_osc" - bl_label = "Symmetrical Layout" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type in - {'MESH', 'SURFACE', 'CURVE'}) - - def execute(self, context): - - SEL_OBJ = bpy.context.active_object - has_keys = hasattr(getattr(SEL_OBJ.data, "shape_keys", None), "key_blocks") - if has_keys: - LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks[1:] - - EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')" - OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')" - POSEMODE = "bpy.ops.object.mode_set(mode='POSE')" - - amt = bpy.data.armatures.new("ArmatureData") - ob = bpy.data.objects.new("RIG_LAYOUT_" + SEL_OBJ.name, amt) - - scn = bpy.context.scene - scn.objects.link(ob) - scn.objects.active = ob - ob.select = True - - verticess = [(-1, 1, 0), (1, 1, 0), (1, -1, 0), (-1, -1, 0)] - edgess = [(0, 1), (1, 2), (2, 3), (3, 0)] - mesh = bpy.data.meshes.new("%s_data_container" % (SEL_OBJ)) - object = bpy.data.objects.new("GRAPHIC_CONTAINER", mesh) - bpy.context.scene.objects.link(object) - mesh.from_pydata(verticess, edgess, []) - - gx = 0 - gy = 0 - - for keyblock in LISTA_KEYS: - if keyblock.name[-2:] != "_L": - if keyblock.name[-2:] != "_R": - - scn.objects.active = ob - eval(EDITMODE) - - bone = amt.edit_bones.new(keyblock.name) - bone.head = (gx, 0, 0) - bone.tail = (gx, 0, 1) - - bonectrl = amt.edit_bones.new(keyblock.name + "_CTRL") - bonectrl.head = (gy, 0, 0) - bonectrl.tail = (gy, 0, 0.2) - - ob.data.edit_bones[ - bonectrl.name].parent = ob.data.edit_bones[ - bone.name] - bpy.context.scene.objects.active = ob - - for SIDE in ["L", "R"]: - DR = SEL_OBJ.data.shape_keys.key_blocks[ - keyblock.name + "_" + SIDE].driver_add("value") - if SIDE == "L": - DR.driver.expression = "var+var_001" - else: - DR.driver.expression = "-var+var_001" - VAR1 = DR.driver.variables.new() - VAR2 = DR.driver.variables.new() - - VAR1.targets[0].id = ob - VAR1.type = 'TRANSFORMS' - VAR1.targets[0].bone_target = bonectrl.name - VAR1.targets[0].transform_space = "LOCAL_SPACE" - VAR1.targets[0].transform_type = "LOC_X" - VAR2.targets[0].id = ob - VAR2.type = 'TRANSFORMS' - VAR2.targets[0].bone_target = bonectrl.name - VAR2.targets[0].transform_space = "LOCAL_SPACE" - VAR2.targets[0].transform_type = "LOC_Y" - - eval(POSEMODE) - - ob.pose.bones[keyblock.name].custom_shape = object - ob.pose.bones[ - keyblock.name + - "_CTRL"].custom_shape = object - CNS = ob.pose.bones[ - keyblock.name + - "_CTRL"].constraints.new( - type='LIMIT_LOCATION') - CNS.min_x = -1 - CNS.use_min_x = 1 - CNS.min_z = 0 - CNS.use_min_z = 1 - CNS.min_y = -1 - CNS.use_min_y = 1 - CNS.max_x = 1 - CNS.use_max_x = 1 - CNS.max_z = 0 - CNS.use_max_z = 1 - CNS.max_y = 1 - CNS.use_max_y = 1 - CNS.owner_space = "LOCAL" - CNS.use_transform_limit = True - - eval(OBJECTMODE) - - bpy.ops.object.text_add(location=(gx, 0, 0)) - gx = gx + 2.2 - gy = gy + 2.2 - texto = bpy.context.object - - texto.data.body = keyblock.name - texto.name = "TEXTO_" + keyblock.name - - texto.rotation_euler[0] = math.pi / 2 - texto.location.x = -1 - texto.location.z = -1 - texto.data.size = .2 - - CNS = texto.constraints.new(type="COPY_LOCATION") - CNS.target = ob - CNS.subtarget = ob.pose.bones[keyblock.name].name - CNS.use_offset = True - else: - self.report({'INFO'}, message="Active object doesn't have shape keys") - return {'CANCELLED'} - - return {'FINISHED'} - - -# ----------------------------CREATE LMR GROUPS------------------- - -def createLMRGroups(self, FACTORVG, ADDVG): - bpy.context.window.screen.scene.tool_settings.mesh_select_mode = ( - True, False, False) - - ACTOBJ = bpy.context.active_object - bpy.ops.object.mode_set(mode="EDIT", toggle=False) - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode="OBJECT") - GRUPOS = ["_L", "_R"] - MIRRORINDEX = 0 - - for LADO in GRUPOS: - if MIRRORINDEX == 0: - bpy.ops.object.vertex_group_add() - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.object.vertex_group_assign() - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False) - for VERTICE in ACTOBJ.data.vertices: - VERTICE.groups[-1].weight = (VERTICE.co[0] * FACTORVG) + ADDVG - ACTOBJ.vertex_groups[-1].name = LADO - else: - bpy.ops.object.vertex_group_add() - bpy.ops.object.mode_set(mode='EDIT', toggle=False) - bpy.ops.mesh.select_all(action='SELECT') - bpy.ops.object.vertex_group_assign() - bpy.ops.mesh.select_all(action='DESELECT') - bpy.ops.object.mode_set(mode='WEIGHT_PAINT', toggle=False) - for VERTICE in ACTOBJ.data.vertices: - VERTICE.groups[-1].weight = (-VERTICE.co[0] * FACTORVG) + ADDVG - ACTOBJ.vertex_groups[-1].name = LADO - MIRRORINDEX += 1 - - ACTOBJ.vertex_groups.active_index = len(ACTOBJ.vertex_groups) - - -class CreaGrupos(Operator): - """It creates a vertex group in symmetrical objects, ideal for smoothly mixing shapekeys""" - bl_idname = "mesh.create_lmr_groups_osc" - bl_label = "Create Mix groups" - bl_options = {'REGISTER', 'UNDO'} - - FACTORVG = FloatProperty( - name="Factor", - default=1, - min=0, - max=1000 - ) - ADDVG = FloatProperty( - name="Addition", - default=.5, - min=0, - max=1000 - ) - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type == 'MESH') - - def execute(self, context): - - createLMRGroups(self, self.FACTORVG, self.ADDVG) - - return {'FINISHED'} - - -# ------------------------ SHAPES LAYOUT SYMMETRICA ------------------------ - -class CreateLayoutAsymmetrical(Operator): - """Creates an interface to control the Shapekeys of symmetrical Objects. “Create Mix Groups” its required""" - bl_idname = "mesh.create_asymmetrical_layout_osc" - bl_label = "Asymmetrical Layout" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type in - {'MESH', 'SURFACE', 'CURVE'}) - - def execute(self, context): - - SEL_OBJ = bpy.context.active_object - - has_keys = hasattr(getattr(SEL_OBJ.data, "shape_keys", None), "key_blocks") - if has_keys: - LISTA_KEYS = bpy.context.active_object.data.shape_keys.key_blocks[1:] - - EDITMODE = "bpy.ops.object.mode_set(mode='EDIT')" - OBJECTMODE = "bpy.ops.object.mode_set(mode='OBJECT')" - POSEMODE = "bpy.ops.object.mode_set(mode='POSE')" - - amtas = bpy.data.armatures.new("ArmatureData") - obas = bpy.data.objects.new("RIG_LAYOUT_" + SEL_OBJ.name, amtas) - - scn = bpy.context.scene - scn.objects.link(obas) - scn.objects.active = obas - obas.select = True - - verticess = [(-.1, 1, 0), (.1, 1, 0), (.1, 0, 0), (-.1, 0, 0)] - edgess = [(0, 1), (1, 2), (2, 3), (3, 0)] - mesh = bpy.data.meshes.new("%s_data_container" % (SEL_OBJ)) - object = bpy.data.objects.new("GRAPHIC_CONTAINER_AS", mesh) - bpy.context.scene.objects.link(object) - mesh.from_pydata(verticess, edgess, []) - - eval(EDITMODE) - gx = 0 - gy = 0 - - for keyblock in LISTA_KEYS: - if keyblock.name[-2:] != "_L": - if keyblock.name[-2:] != "_R": - scn.objects.active = obas - eval(EDITMODE) - bone = amtas.edit_bones.new(keyblock.name) - bone.head = (gx, 0, 0) - bone.tail = (gx, 0, 1) - - bonectrl = amtas.edit_bones.new(keyblock.name + "_CTRL") - bonectrl.head = (gy, 0, 0) - bonectrl.tail = (gy, 0, 0.2) - - obas.data.edit_bones[ - bonectrl.name].parent = obas.data.edit_bones[ - bone.name] - bpy.context.scene.objects.active = obas - - bpy.ops.armature.select_all(action="DESELECT") - - DR1 = keyblock.driver_add("value") - DR1.driver.expression = "var" - VAR2 = DR1.driver.variables.new() - VAR2.targets[0].id = obas - VAR2.targets[0].bone_target = bonectrl.name - VAR2.type = 'TRANSFORMS' - VAR2.targets[0].transform_space = "LOCAL_SPACE" - VAR2.targets[0].transform_type = "LOC_Y" - - eval(POSEMODE) - - obas.pose.bones[keyblock.name].custom_shape = object - obas.pose.bones[ - keyblock.name + - "_CTRL"].custom_shape = object - - bpy.data.objects[ - "RIG_LAYOUT_" + - SEL_OBJ.name].data.bones.active = bpy.data.objects[ - "RIG_LAYOUT_" + - SEL_OBJ.name].data.bones[ - keyblock.name + - "_CTRL"] - - eval(POSEMODE) - CNS = obas.pose.bones[ - keyblock.name + - "_CTRL"].constraints.new( - type='LIMIT_LOCATION') - CNS.min_x = 0 - CNS.use_min_x = 1 - CNS.min_z = 0 - CNS.use_min_z = 1 - CNS.min_y = 0 - CNS.use_min_y = 1 - - CNS.max_x = 0 - CNS.use_max_x = 1 - CNS.max_z = 0 - CNS.use_max_z = 1 - CNS.max_y = 1 - CNS.use_max_y = 1 - - CNS.owner_space = "LOCAL" - CNS.use_transform_limit = True - - eval(OBJECTMODE) - - bpy.ops.object.text_add(location=(0, 0, 0)) - gx = gx + 2.2 - gy = gy + 2.2 - texto = bpy.context.object - texto.data.body = keyblock.name - texto.name = "TEXTO_" + keyblock.name - - texto.rotation_euler[0] = math.pi / 2 - texto.location.x = -.15 - texto.location.z = -.15 - texto.data.size = .2 - - CNS = texto.constraints.new(type="COPY_LOCATION") - CNS.target = obas - CNS.subtarget = obas.pose.bones[keyblock.name].name - CNS.use_offset = True - else: - self.report({'INFO'}, message="Active object doesn't have shape keys") - return {'CANCELLED'} - - return {'FINISHED'} - - -# ---------------------------SHAPES TO OBJECTS------------------ - -class ShapeToObjects(Operator): - """It creates a new object for every shapekey in the selected object, ideal to export to other 3D software Apps""" - bl_idname = "object.shape_key_to_objects_osc" - bl_label = "Shapes To Objects" - bl_options = {"REGISTER", "UNDO"} - - @classmethod - def poll(cls, context): - return (context.active_object is not None and - context.active_object.type in - {'MESH', 'SURFACE', 'CURVE'}) - - def execute(self, context): - OBJACT = bpy.context.active_object - has_keys = hasattr(getattr(OBJACT.data, "shape_keys", None), "key_blocks") - if has_keys: - for SHAPE in OBJACT.data.shape_keys.key_blocks[:]: - print(SHAPE.name) - bpy.ops.object.shape_key_clear() - SHAPE.value = 1 - mesh = OBJACT.to_mesh(bpy.context.scene, True, 'PREVIEW') - object = bpy.data.objects.new(SHAPE.name, mesh) - bpy.context.scene.objects.link(object) - else: - self.report({'INFO'}, message="Active object doesn't have shape keys") - return {'CANCELLED'} - - return {'FINISHED'} |