initial commit oscurart tools. re: T48708

This commit is contained in:
Brendon Murphy 2016-08-07 23:34:46 +10:00
parent 84a93440fd
commit 3218a23e11
7 changed files with 2467 additions and 0 deletions

391
oscurart_tools/__init__.py Normal file
View File

@ -0,0 +1,391 @@
# ##### 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, 2),
"blender": (2, 77, 0),
"location": "View3D > Tools > Oscurart Tools",
"description": "Tools for objects, render, shapes, and files.",
"warning": "",
"wiki_url":
"http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/3D_interaction/Oscurart_Tools",
"tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
"category": "Object",
}
import bpy
from bpy.types import (
AddonPreferences,
Panel,
PropertyGroup,
)
from bpy.props import (
StringProperty,
BoolProperty,
IntProperty,
)
from . import oscurart_files
from . import oscurart_meshes
from . import oscurart_objects
from . import oscurart_shapes
from . import oscurart_render
from . import oscurart_animation
class View3DOscPanel(PropertyGroup):
# CREA PANELES EN TOOLS
osc_object_tools = BoolProperty(default=True)
osc_mesh_tools = BoolProperty(default=True)
osc_shapes_tools = BoolProperty(default=True)
osc_render_tools = BoolProperty(default=True)
osc_files_tools = BoolProperty(default=True)
osc_animation_tools = BoolProperty(default=True)
quick_animation_in = IntProperty(
default=1
)
quick_animation_out = IntProperty(
default=250
)
# SETEO VARIABLE DE ENTORNO
SearchAndSelectOt = StringProperty(
default="Object name initials"
)
# RENDER CROP
rcPARTS = IntProperty(
default=1,
min=2,
max=50,
step=1
)
RenameObjectOt = StringProperty(
default="Type here"
)
class VarColArchivos(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
)
# PANELES
class OscPanelControl(Panel):
bl_idname = "Oscurart Panel Control"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_category = "Oscurart Tools"
bl_label = "Panels Switcher"
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")
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.oscurart, "SearchAndSelectOt", text="")
colrow.operator("object.search_and_select_osc", icon="ZOOM_SELECTED")
colrow = col.row(align=1)
colrow.prop(bpy.context.scene.oscurart, "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):
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")
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.overlap_uv_faces", icon="UV_FACESEL")
colrow = col.row(align=1)
colrow.operator("view3d.modal_operator", icon="STICKY_UVS_DISABLE")
colrow = col.row(align=1)
colrow.operator("file.export_groups_osc", icon='GROUP_VCOL')
colrow.operator("file.import_groups_osc", icon='GROUP_VCOL')
colrow = col.row(align=1)
colrow.operator("mesh.export_vertex_colors", icon='COLOR')
colrow.operator("mesh.import_vertex_colors", icon='COLOR')
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="SETTINGS")
colrow.operator("mesh.create_asymmetrical_layout_osc", icon="SETTINGS")
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)
colrow.operator(
"render.copy_render_settings_osc",
icon="LIBRARY_DATA_DIRECT",
text="Copy Render Settings").mode = "render"
colrow.operator(
"render.copy_render_settings_osc",
icon="LIBRARY_DATA_DIRECT",
text="Copy Cycles Settings").mode = "cycles"
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.oscurart, "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="> Frame").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("image.reload_images_osc", icon="IMAGE_COL")
col.operator("file.sync_missing_groups", icon="LINK_AREA")
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.oscurart, "quick_animation_in", text="")
row.prop(bpy.context.scene.oscurart, "quick_animation_out", text="")
class OscurartToolsAddonPreferences(bpy.types.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="Oscurart Tools",
)
def draw(self, context):
layout = self.layout
row = layout.row()
col = row.column()
col.label(text="Category:")
col.prop(self, "category", text="")
# ========================= FIN DE SCRIPTS =========================
def register():
bpy.utils.register_module(__name__)
bpy.types.Scene.oscurart = bpy.props.PointerProperty(
type=View3DOscPanel
)
bpy.types.Scene.use_render_scene = bpy.props.BoolProperty()
bpy.types.Scene.broken_files = bpy.props.CollectionProperty(
type=VarColArchivos
)
def unregister():
del bpy.types.Scene.oscurart
del bpy.types.Scene.use_render_scene
del bpy.types.Scene.broken_files
bpy.utils.unregister_module(__name__)
if __name__ == "__main__":
register()

View File

@ -0,0 +1,70 @@
# ##### 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):
if bpy.context.object.type == "ARMATURE":
ob = bpy.context.object
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.oscurart.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:
ob = bpy.context.object
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.oscurart.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):
bl_idname = "anim.quick_parent_osc"
bl_label = "Quick Parent"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
len(context.selected_objects) > 1)
def execute(self, context):
DefQuickParent(
bpy.context.scene.oscurart.quick_animation_in,
bpy.context.scene.oscurart.quick_animation_out)
return {'FINISHED'}

View File

@ -0,0 +1,50 @@
# ##### 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
# ---------------------RELOAD IMAGES------------------
class reloadImages(Operator):
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'}
# --------------- SYNC MISSING GROUPS -----------------
class reFreshMissingGroups(Operator):
bl_idname = "file.sync_missing_groups"
bl_label = "Sync Missing Groups"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
for group in bpy.data.groups:
if group.library is not None:
with bpy.data.libraries.load(group.library.filepath, link=True) as (linked, local):
local.groups = linked.groups
return {'FINISHED'}

View File

@ -0,0 +1,562 @@
# ##### 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 (
IntProperty,
BoolProperty,
FloatProperty,
EnumProperty,
)
import os
import bmesh
import time
import blf
from bpy_extras.view3d_utils import location_3d_to_region_2d
# -----------------------------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):
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):
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 resymVertexGroups(Operator):
bl_idname = "mesh.resym_vertex_weights_osc"
bl_label = "Resym Vertex Weights"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
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:
ob = bpy.context.object
actgr = ob.vertex_groups.active
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'}
# ------------------------IMPORT EXPORT GROUPS--------------------
class OscExportVG(Operator):
bl_idname = "file.export_groups_osc"
bl_label = "Export Groups"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
ob = bpy.context.object
with open(os.path.join(os.path.dirname(bpy.data.filepath), ob.name + ".txt"), mode="w") as file:
vgindex = {vg.index: vg.name for vg in ob.vertex_groups[:]}
vgdict = {}
for vert in ob.data.vertices:
for vg in vert.groups:
vgdict.setdefault(vg.group, []).append(
(vert.index, vg.weight))
file.write(str(vgdict) + "\n")
file.write(str(vgindex))
return {'FINISHED'}
class OscImportVG(Operator):
bl_idname = "file.import_groups_osc"
bl_label = "Import Groups"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
ob = bpy.context.object
with open(os.path.join(os.path.dirname(bpy.data.filepath), ob.name + ".txt"), mode="r") as file:
vgdict = eval(file.readlines(1)[0].replace("\n", ""))
vgindex = eval(file.readlines(2)[0].replace("\n", ""))
for index, name in vgindex.items():
ob.vertex_groups.new(name=name)
for group, vdata in vgdict.items():
for index, weight in vdata:
ob.vertex_groups[group].add(
index=[index],
weight=weight,
type="REPLACE")
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):
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):
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):
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):
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 and
context.active_object.type == 'MESH')
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",
calc_tessface=True)
OBJECT = bpy.data.objects.new(("%s_Freeze") % (ACTOBJ.name), MESH)
bpy.context.scene.objects.link(OBJECT)
class OscObjectToMesh(Operator):
bl_idname = "mesh.object_to_mesh_osc"
bl_label = "Object To Mesh"
bl_description = "Works on Meshes, Meta objects, Curves and Surfaces"
@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(valpresicion):
inicio = time.time()
mode = bpy.context.object.mode
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
rd = valpresicion
ob = bpy.context.object
absco = lambda x: (abs(round(x[0], rd)), round(x[1], rd), round(x[2], rd))
rounder = lambda x: (round(x[0], rd), round(x[1], rd), round(x[2], rd))
# vertice a vertex
vertvertex = {}
for vert in ob.data.loops:
vertvertex.setdefault(vert.vertex_index, []).append(vert.index)
vertexvert = {}
for vertex in ob.data.loops:
vertexvert[vertex.index] = vertex.vertex_index
# posicion de cada vertice y cada face
vertloc = {rounder(vert.co[:]): vert for vert in ob.data.vertices}
faceloc = {rounder(poly.center[:]): poly for poly in ob.data.polygons}
# relativo de cada vertice y cada face
verteqind = {vert.index: vertloc.get(
absco(co),
vertloc[co]).index for co,
vert in vertloc.items() if co[0] <= 0}
polyeq = {face: faceloc.get(
absco(center),
faceloc[center]) for center,
face in faceloc.items() if center[0] <= 0}
# loops in faces
lif = {poly: [i for i in poly.loop_indices] for poly in ob.data.polygons}
# acomoda
for l, r in polyeq.items():
if l.select:
for lloop in lif[l]:
for rloop in lif[r]:
if (verteqind[vertexvert[lloop]] == vertexvert[rloop] and
ob.data.uv_layers.active.data[rloop].select):
ob.data.uv_layers.active.data[
lloop].uv = ob.data.uv_layers.active.data[
rloop].uv
bpy.ops.object.mode_set(mode=mode, toggle=False)
print("Time elapsed: %4s seconds" % (time.time() - inicio))
class OscOverlapUv(Operator):
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')
presicion = IntProperty(
default=4,
min=1,
max=10,
name="precision"
)
def execute(self, context):
DefOscOverlapUv(self.presicion)
return {'FINISHED'}
# ------------------------------- IO VERTEX COLORS --------------------
def DefOscExportVC():
with open(os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.object.name) + ".vc", mode="w") as file:
ob = bpy.context.object
di = {loopind: ob.data.vertex_colors.active.data[loopind].color[:]
for face in ob.data.polygons for loopind in face.loop_indices[:]}
file.write(str(di))
def DefOscImportVC():
with open(os.path.join(os.path.dirname(bpy.data.filepath), bpy.context.object.name) + ".vc", mode="r") as file:
di = eval(file.read())
for loopind in di:
bpy.context.object.data.vertex_colors.active.data[
loopind].color = di[loopind]
class OscExportVC(Operator):
bl_idname = "mesh.export_vertex_colors"
bl_label = "Export Vertex Colors"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
DefOscExportVC()
return {'FINISHED'}
class OscImportVC(Operator):
bl_idname = "mesh.import_vertex_colors"
bl_label = "Import Vertex Colors"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return (context.active_object is not None and
context.active_object.type == 'MESH')
def execute(self, context):
DefOscImportVC()
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):
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()
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'}

View File

@ -0,0 +1,526 @@
# ##### 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
import os
from bpy_extras.object_utils import world_to_camera_view
# ------------------------ SEARCH AND SELECT ------------------------
class SearchAndSelectOt(Operator):
bl_idname = "object.search_and_select_osc"
bl_label = "Search And Select"
bl_description = "Selection based upon object names in the scene"
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.oscurart.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----------------------------------
class renameObjectsOt (Operator):
bl_idname = "object.rename_objects_osc"
bl_label = "Rename Objects"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
listaObj = bpy.context.selected_objects[:]
for objeto in listaObj:
objeto.name = bpy.context.scene.oscurart.RenameObjectOt
return {'FINISHED'}
# ---------------------------REMOVE MODIFIERS Y APPLY MODIFIERS-----------
class oscRemModifiers (Operator):
bl_idname = "object.modifiers_remove_osc"
bl_label = "Remove modifiers"
bl_description = "Removes all modifiers on all selected objects"
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):
bl_idname = "object.modifiers_apply_osc"
bl_label = "Apply modifiers"
bl_description = ("Applies all modifiers on all selected objects \n"
"Warning: Make single user will be applied on Linked Object data")
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):
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.groups[:]:
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):
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):
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):
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.groups:
bpy.data.groups.new("INCAMERA")
if "NOTINCAMERA" not in bpy.data.groups:
bpy.data.groups.new("NOTINCAMERA")
# limpio grupos
for ob in bpy.data.objects:
if ob.name in bpy.data.groups["INCAMERA"].objects:
bpy.data.groups["INCAMERA"].objects.unlink(ob)
if ob.name in bpy.data.groups["NOTINCAMERA"].objects:
bpy.data.groups["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.groups["INCAMERA"].objects.link(ob)
else:
bpy.data.groups["NOTINCAMERA"].objects.link(ob)
class RenderOnlyInCamera (Operator):
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, disconect):
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 disconect 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):
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():
scgr = bpy.data.groups.new(
"%s_MSH" %
(os.path.basename(bpy.data.filepath).replace(".blend", "")))
for ob in bpy.data.objects:
if ob.type == "MESH":
gr = bpy.data.groups.new(ob.name)
gr.objects.link(ob)
scgr.objects.link(ob)
class ObjectsToGroups(Operator):
bl_idname = "object.objects_to_groups"
bl_label = "Objects to Groups"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
DefObjectToGroups()
return {'FINISHED'}

View File

@ -0,0 +1,399 @@
# ##### 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:
renpath = scene.render.filepath
if frametype:
scene.frame_start = FC
scene.frame_end = FC
scene.frame_end = FC
scene.frame_start = FC
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)
scene.render.filepath = os.path.join(
os.path.dirname(renpath), filename, scene.name, layer.name, "%s_%s_%s" %
(filename, scene.name, layer.name))
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):
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------------------
class renderSelected (Operator):
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.oscurart.use_render_scene])
return {'FINISHED'}
# --------------------------------RENDER CURRENT SCENE--------------------
class renderCurrent (Operator):
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----------------------
def OscRenderCropFunc():
SCENENAME = os.path.split(bpy.data.filepath)[-1].partition(".")[0]
rcParts = bpy.context.scene.oscurart.rcPARTS
# don't divide by zero
PARTS = (rcParts if rcParts and rcParts > 0 else 1)
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):
bl_idname = "render.render_crop_osc"
bl_label = "Render Crop: Render!"
def execute(self, context):
OscRenderCropFunc()
return {'FINISHED'}
# ---------------------------------- BROKEN FRAMES ---------------------
class SumaFile(Operator):
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):
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):
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'}
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"
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")
# --------------------------------COPY RENDER SETTINGS--------------------
def defCopyRenderSettings(mode):
sc = bpy.context.scene
sceneslist = bpy.data.scenes[:]
sceneslist.remove(sc)
excludes = {
'name',
'objects',
'object_bases',
'has_multiple_engines',
'display_settings',
'broken_files',
'rna_type',
'frame_subframe',
'view_settings',
'tool_settings',
'render',
'user_clear',
'animation_data_create',
'collada_export',
'keying_sets',
'icon_props',
'image_settings',
'library',
'bake',
'active_layer',
'frame_current_final',
'sequence_editor_clear',
'rigidbody_world',
'unit_settings',
'orientations',
'__slots__',
'ray_cast',
'sequencer_colorspace_settings',
'ffmpeg',
'is_movie_format',
'frame_path',
'frame_set',
'network_render',
'animation_data_clear',
'is_nla_tweakmode',
'keying_sets_all',
'sequence_editor',
'__doc__',
'file_extension',
'users',
'node_tree',
'is_updated_data',
'bl_rna',
'is_library_indirect',
'cycles_curves',
'timeline_markers',
'statistics',
'use_shading_nodes',
'use_game_engine',
'sequence_editor_create',
'is_updated',
'__module__',
'update_tag',
'update',
'animation_data',
'cycles',
'copy',
'game_settings',
'layers',
'__weakref__',
'string',
'double',
'use_render_scene',
'engine',
'use_nodes',
'world'}
if mode == "render":
scenerenderdict = {}
scenedict = {}
sceneimagesettingdict = {}
for prop in dir(bpy.context.scene.render):
if prop not in excludes:
try:
scenerenderdict[prop] = getattr(
bpy.context.scene.render, prop)
except:
print("%s does not exist." % (prop))
for prop in dir(bpy.context.scene):
if prop not in excludes:
try:
scenedict[prop] = getattr(bpy.context.scene, prop)
except:
print("%s does not exist." % (prop))
for prop in dir(bpy.context.scene.render.image_settings):
if prop not in excludes:
try:
sceneimagesettingdict[prop] = getattr(
bpy.context.scene.render.image_settings,
prop)
except:
print("%s does not exist." % (prop))
# render
for escena in sceneslist:
for prop, value in scenerenderdict.items():
try:
setattr(escena.render, prop, value)
except:
print("%s was not copied!" % (prop))
pass
# scene
for escena in sceneslist:
for prop, value in scenedict.items():
try:
setattr(escena, prop, value)
except:
print("%s was not copied!" % (prop))
pass
# imageSettings
for escena in sceneslist:
for prop, value in sceneimagesettingdict.items():
try:
setattr(escena.render.image_settings, prop, value)
except:
print("%s was not copied!" % (prop))
pass
if mode == "cycles":
scenecyclesdict = {}
for prop in dir(bpy.context.scene.cycles):
if prop not in excludes:
try:
scenecyclesdict[prop] = getattr(
bpy.context.scene.cycles, prop)
except:
print("%s does not exist." % (prop))
# cycles
for escena in sceneslist:
for prop, value in scenecyclesdict.items():
try:
setattr(escena.cycles, prop, value)
except:
print("%s was not copied!" % (prop))
pass
class copyRenderSettings(Operator):
bl_idname = "render.copy_render_settings_osc"
bl_label = "Copy Render Settings"
mode = bpy.props.StringProperty(default="")
def execute(self, context):
defCopyRenderSettings(self.mode)
return {'FINISHED'}

View File

@ -0,0 +1,469 @@
# ##### 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):
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):
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):
bl_idname = "mesh.create_lmr_groups_osc"
bl_label = "Create Mix groups"
bl_description = "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):
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):
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'}