Small updates on pinkified theme for some object types, background gradient and other...
[blender-addons-contrib.git] / oscurart_mesh_cache_tools.py
1 bl_info = {
2     "name": "Mesh Cache Tools",
3     "author": "Oscurart",
4     "version": (1, 0),
5     "blender": (2, 6, 4),
6     "location": "Tools > Mesh Cache Tools",
7     "description": "Tools for Management Mesh Cache Process",
8     "warning": "",
9     "wiki_url": "",
10     "tracker_url": "",
11     "category": "Import-Export"}
12
13
14 import bpy
15 import sys
16 import os
17 import struct
18
19 bpy.types.Scene.muu_pc2_rotx = bpy.props.BoolProperty(default=True, name="Rotx = 90")
20 bpy.types.Scene.muu_pc2_world_space = bpy.props.BoolProperty(default=True, name="World Space")
21 bpy.types.Scene.muu_pc2_modifiers = bpy.props.BoolProperty(default=True, name="Apply Modifiers")
22 bpy.types.Scene.muu_pc2_subsurf = bpy.props.BoolProperty(default=True, name="Turn Off SubSurf")
23 bpy.types.Scene.muu_pc2_start = bpy.props.IntProperty(default=0, name="Frame Start")
24 bpy.types.Scene.muu_pc2_end = bpy.props.IntProperty(default=100, name="Frame End")
25 bpy.types.Scene.muu_pc2_group = bpy.props.StringProperty()
26 bpy.types.Scene.muu_pc2_folder = bpy.props.StringProperty(default="Set me Please!")
27 bpy.types.Scene.muu_pc2_relative_path = bpy.props.StringProperty(default="")
28
29 class OscEPc2ExporterPanel(bpy.types.Panel):
30     """Creates a Panel in the Object properties window"""
31     bl_label = "Mesh Cache Tools"
32     bl_idname = "Mesh Cache Tools"
33     bl_space_type = 'VIEW_3D'
34     bl_region_type = 'TOOLS'
35
36     def draw(self, context):
37         layout = self.layout
38
39         obj = context.object
40         row = layout.column(align=1)
41         row.prop(bpy.context.scene, "muu_pc2_folder", text="Folder")
42         row.operator("import_shape.pc2_copy", icon='FILESEL', text="Set Filepath")
43         row.prop(bpy.context.scene, "muu_pc2_relative_path", text="Relative Path (Optional):")
44         row = layout.box().column(align=1)
45         row.label("EXPORTER:")
46         row.operator("group.linked_group_to_local", text="Linked To Local", icon="LINKED")
47         row.operator("object.remove_subsurf_modifier", text="Remove Gen Modifiers", icon="MOD_SUBSURF")
48         row.operator("export_shape.pc2_selection", text="Export!", icon="POSE_DATA")
49         row.prop(bpy.context.scene, "muu_pc2_world_space", text="World Space")
50         row = layout.column(align=1)
51         row.prop(bpy.context.scene, "muu_pc2_start", text="Frame Start")
52         row.prop(bpy.context.scene, "muu_pc2_end", text="Frame End")
53         row.prop_search(bpy.context.scene, "muu_pc2_group", bpy.data, "groups", text="")
54         row = layout.box().column(align=1)
55         row.label("IMPORTER:")
56         row.operator("import_shape.pc2_selection", text="Import", icon="POSE_DATA")
57         row.operator("object.modifier_mesh_cache_up", text="MC Top", icon="TRIA_UP")
58
59 def OscFuncExportPc2(self):
60     start = bpy.context.scene.muu_pc2_start
61     end = bpy.context.scene.muu_pc2_end
62     folderpath = bpy.context.scene.muu_pc2_folder
63
64     for ob in bpy.data.groups[bpy.context.scene.muu_pc2_group].objects[:]:
65         pc2list = []
66         if ob.type == "MESH":
67             with open("%s/%s.pc2" % (os.path.normpath(folderpath), ob.name), mode="wb") as file:
68                 #encabezado
69                 headerFormat = '<12siiffi'
70                 headerStr = struct.pack(headerFormat,
71                          b'POINTCACHE2\0', 1, len(ob.data.vertices[:]), 0, 1.0, (end + 1) - start)
72                 file.write(headerStr)
73                 #bakeado
74                 obmat = ob.matrix_world
75                 for frame in range((end + 1) - start):
76                     print("Percentage of %s bake: %s " % (ob.name, frame / end * 100))
77                     bpy.context.scene.frame_set(frame)
78                     me = bpy.data.meshes.new_from_object(
79                         scene=bpy.context.scene,
80                         object=ob,
81                         apply_modifiers=True,
82                         settings="RENDER",
83                         calc_tessface=True,
84                         calc_undeformed=False)
85                     #rotate
86                     if bpy.context.scene.muu_pc2_world_space:
87                         me.transform(obmat)
88                         me.calc_normals()
89                     #creo archivo
90                     for vert in me.vertices[:]:
91                         pc2list.append((
92                             float(vert.co[0]),
93                             float(vert.co[1]),
94                             float(vert.co[2])
95                             ))
96
97                     #dreno mesh
98                     bpy.data.meshes.remove(me)
99
100                 print("%s Bake finished! \nAwaiting Compile file..." % (ob.name))
101
102                 # write file
103                 for i, frame in enumerate(pc2list):
104                     file.write(struct.pack("<3f", *frame))
105                 print("%s File Compiled Write finished!" % (ob.name))
106                 del(pc2list)
107
108     print("Bake Finished!")
109
110 class OscPc2ExporterBatch(bpy.types.Operator):
111     bl_idname = "export_shape.pc2_selection"
112     bl_label = "Export pc2 for selected Objects"
113     bl_description = "Export pc2 for selected Objects"
114     bl_options = {'REGISTER', 'UNDO'}
115
116     @classmethod
117     def poll(cls, context):
118         return(bpy.context.scene.muu_pc2_group != "" and bpy.context.scene.muu_pc2_folder != 'Set me Please!')
119
120     def execute(self, context):
121         OscFuncExportPc2(self)
122         return {'FINISHED'}
123
124 class OscRemoveSubsurf(bpy.types.Operator):
125     bl_idname = "object.remove_subsurf_modifier"
126     bl_label = "Remove SubSurf Modifier"
127     bl_description = "Remove SubSurf Modifier"
128     bl_options = {'REGISTER', 'UNDO'}
129
130     @classmethod
131     def poll(cls, context):
132         return(bpy.context.scene.muu_pc2_group != "")
133
134     def execute(self, context):
135         GENERATE = ['MULTIRES', 'ARRAY', 'BEVEL', 'BOOLEAN', 'BUILD', 'DECIMATE', 'MASK', 'MIRROR', 'REMESH', 'SCREW', 'SKIN', 'SOLIDIFY', 'SUBSURF', 'TRIANGULATE']
136         for OBJ in bpy.data.groups[bpy.context.scene.muu_pc2_group].objects[:]:
137             for MOD in OBJ.modifiers[:]:
138                 if MOD.type in GENERATE:
139                     OBJ.modifiers.remove(MOD)
140         return {'FINISHED'}
141
142
143 class OscPc2iMporterBatch(bpy.types.Operator):
144     bl_idname = "import_shape.pc2_selection"
145     bl_label = "Import pc2 for selected Objects"
146     bl_description = "Import pc2 for selected Objects"
147     bl_options = {'REGISTER', 'UNDO'}
148
149     @classmethod
150     def poll(cls, context):
151         return(bpy.context.scene.muu_pc2_folder != 'Set me Please!')
152
153     def execute(self, context):
154         for OBJ in bpy.context.selected_objects[:]:
155             MOD = OBJ.modifiers.new("MeshCache", 'MESH_CACHE')
156             MOD.filepath = "%s%s%s.pc2" % (bpy.context.scene.muu_pc2_folder, os.sep, OBJ.name)
157             MOD.cache_format = "PC2"
158             MOD.forward_axis = "POS_Y"
159             MOD.up_axis = "POS_Z"
160             MOD.flip_axis = set(())
161
162         return {'FINISHED'}
163
164 class OscPc2iMporterCopy(bpy.types.Operator):
165     bl_idname = "import_shape.pc2_copy"
166     bl_label = "Copy Filepath"
167     bl_description = "Copy Filepath"
168     bl_options = {'REGISTER', 'UNDO'}
169
170     def execute(self, context):
171         filefolder = os.path.dirname(bpy.data.filepath)
172         os.chdir(filefolder)
173         if bpy.context.scene.muu_pc2_relative_path != "":            
174             if os.path.exists("%s" % (os.path.join(filefolder,bpy.context.scene.muu_pc2_relative_path))):
175                 print("Folder Already Exists.")
176             else:
177                 os.mkdir("%s" % (os.path.join(filefolder,bpy.context.scene.muu_pc2_relative_path)))
178             bpy.context.scene.muu_pc2_folder = "%s" % (os.path.join(filefolder,bpy.context.scene.muu_pc2_relative_path))
179         else:
180             bpy.context.scene.muu_pc2_folder = "%s" % (filefolder)
181
182         return {'FINISHED'}
183
184 def OscLinkedGroupToLocal():
185     ACTOBJ = bpy.context.active_object
186     GROBJS = [ob for ob in ACTOBJ.id_data.dupli_group.objects[:] if ob.type == "MESH"]
187
188     for ob in ACTOBJ.id_data.dupli_group.objects[:]:
189         bpy.context.scene.objects.link(ob)
190     NEWGROUP = bpy.data.groups.new("%s_CLEAN" % (ACTOBJ.name))
191     bpy.context.scene.objects.unlink(ACTOBJ)
192     NEWOBJ = []
193     for ob in GROBJS:
194         NEWGROUP.objects.link(ob)
195         NEWOBJ.append(ob)
196     for ob in NEWOBJ:
197         if ob.type == "MESH":
198             if len(ob.modifiers):
199                 for MODIFIER in ob.modifiers[:]:
200                     if MODIFIER.type == "SUBSURF" or MODIFIER.type == "MASK":
201                         ob.modifiers.remove(MODIFIER)
202
203 class OscGroupLinkedToLocal(bpy.types.Operator):
204     bl_idname = "group.linked_group_to_local"
205     bl_label = "Group Linked To Local"
206     bl_description = "Group Linked To Local"
207     bl_options = {'REGISTER', 'UNDO'}
208
209     @classmethod
210     def poll(cls, context):
211         return(bpy.context.scene.muu_pc2_group != "")
212
213     def execute(self, context):
214         OscLinkedGroupToLocal()
215         return {'FINISHED'}
216     
217 class OscMeshCacheUp(bpy.types.Operator):
218     bl_idname = "object.modifier_mesh_cache_up"
219     bl_label = "Mesh Cache To Top"
220     bl_description = "Send Mesh Cache Modifiers top"
221     bl_options = {'REGISTER', 'UNDO'}
222
223     @classmethod
224     def poll(cls, context):
225         return(bpy.context.object.type == "MESH")
226
227     def execute(self, context):
228
229         actob = bpy.context.scene.objects.active
230
231         for ob in bpy.context.selected_objects[:]:
232             bpy.context.scene.objects.active = ob
233             for mod in ob.modifiers[:]:
234                 if mod.type == "MESH_CACHE":
235                     for up in range(ob.modifiers.keys().index(mod.name)):
236                         bpy.ops.object.modifier_move_up(modifier=mod.name)
237
238         bpy.context.scene.objects.active = actob
239         
240         return {'FINISHED'}    
241     
242
243 def register():
244     bpy.utils.register_module(__name__)
245
246 def unregister():
247     bpy.utils.unregister_module(__name__)
248
249 if __name__ == "__main__":
250     register()