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