initial commit oscurart tools. re: T48708
This commit is contained in:
parent
84a93440fd
commit
3218a23e11
|
@ -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()
|
|
@ -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'}
|
|
@ -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'}
|
|
@ -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'}
|
|
@ -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'}
|
|
@ -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'}
|
|
@ -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'}
|
Loading…
Reference in New Issue