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