21 "name":
"Export Selected",
22 "author":
"dairin0d, rking",
25 "location":
"File > Export > Selected",
26 "description":
"Export selected objects to a chosen format",
28 "wiki_url":
"http://wiki.blender.org/index.php/Extensions:2.6/Py/"\
29 "Scripts/Import-Export/Export_Selected",
30 "tracker_url":
"http://projects.blender.org/tracker/"\
31 "?func=detail&aid=30942",
32 "category":
"Import-Export"}
37 from bpy_extras.io_utils
import ExportHelper
39 join_before_export = {
44 bpy.props.BoolProperty,
45 bpy.props.BoolVectorProperty,
46 bpy.props.IntProperty,
47 bpy.props.IntVectorProperty,
48 bpy.props.FloatProperty,
49 bpy.props.FloatVectorProperty,
50 bpy.props.StringProperty,
51 bpy.props.EnumProperty,
52 bpy.props.PointerProperty,
53 bpy.props.CollectionProperty,
57 if isinstance(value, tuple)
and (len(value) == 2):
58 if (value[0]
in bpy_props)
and isinstance(value[1], dict):
64 if key.startswith(
"_"):
66 value = getattr(cls, key)
69 options = value[1].get(
"options",
"")
70 if 'HIDDEN' in options:
75 category_name, op_name = idname.split(
".")
76 category = getattr(bpy.ops, category_name)
77 return getattr(category, op_name)
81 if not isinstance(mode, str):
82 mode = (
'OBJECT' if mode
else None)
84 obj = bpy.context.object
85 if obj
and (obj.mode != mode):
93 edit_preferences = bpy.context.user_preferences.edit
99 if self.
undo is not None:
100 edit_preferences.use_global_undo = self.
undo 101 bpy.ops.object.mode_set(mode=self.
mode)
107 edit_preferences = bpy.context.user_preferences.edit
110 bpy.ops.object.mode_set(mode=self.
prev_mode)
111 edit_preferences.use_global_undo = self.
global_undo 115 categories = [
"export_anim",
"export_mesh",
"export_scene"]
116 for category_name
in categories:
117 op_category = getattr(bpy.ops, category_name)
119 for name
in dir(op_category):
120 total_name = category_name +
"." + name
122 if total_name == ExportSelected.bl_idname:
125 if "export" in total_name:
126 op = getattr(op_category, name)
133 keys_to_remove = list(cls.
_keys())
135 for key
in keys_to_remove:
138 CurrentFormatProperties.__dict =
None 143 setattr(cls, key, value)
145 CurrentFormatProperties.__dict = {}
146 for key
in dir(template):
147 value = getattr(template, key)
149 CurrentFormatProperties.__dict[key] = value
152 def _keys(cls, exclude_hidden=False):
157 return CurrentFormatProperties.__dict[name]
160 if hasattr(self.__class__, name)
and (
not name.startswith(
"_")):
161 supercls = super(CurrentFormatProperties, self.__class__)
162 supercls.__setattr__(self, name, value)
164 CurrentFormatProperties.__dict[name] = value
168 apply_modifiers = bpy.props.BoolProperty(name=
"Apply Modifiers", description=
"Apply modifiers to exported mesh (non destructive)", default=
False)
170 export_mesh_type_selection = bpy.props.EnumProperty(name=
"Type of modifiers", description=
"Modifier resolution for export", default=
'view', items=[(
'render',
"Render",
"Apply modifier's render settings"), (
'view',
"View",
"Apply modifier's view settings")])
171 selected = bpy.props.BoolProperty(name=
"Selection Only", description=
"Export only selected elements", default=
False)
172 include_children = bpy.props.BoolProperty(name=
"Include Children", description=
"Export all children of selected objects (even if not selected)", default=
False)
173 include_armatures = bpy.props.BoolProperty(name=
"Include Armatures", description=
"Export related armatures (even if not selected)", default=
False)
174 include_shapekeys = bpy.props.BoolProperty(name=
"Include Shape Keys", description=
"Export all Shape Keys from Mesh Objects", default=
True)
175 deform_bones_only = bpy.props.BoolProperty(name=
"Deform Bones only", description=
"Only export deforming bones with armatures", default=
False)
176 active_uv_only = bpy.props.BoolProperty(name=
"Only Active UV layer", description=
"Export textures assigned to the object UV maps", default=
False)
177 include_uv_textures = bpy.props.BoolProperty(name=
"Include UV Textures", description=
"Export textures assigned to the object UV maps", default=
False)
178 include_material_textures = bpy.props.BoolProperty(name=
"Include Material Textures", description=
"Export textures assigned to the object Materials", default=
False)
179 use_texture_copies = bpy.props.BoolProperty(name=
"Copy Textures", description=
"Copy textures to the same folder where .dae file is exported", default=
True)
180 triangulate = bpy.props.BoolProperty(name=
"Triangulate", description=
"Export Polygons (Quads & NGons) as Triangles", default=
True)
181 use_object_instantiation = bpy.props.BoolProperty(name=
"Use Object Instances", description=
"Instantiate multiple Objects from same Data", default=
True)
182 sort_by_name = bpy.props.BoolProperty(name=
"Sort by Object name", description=
"Sort exported data by Object name", default=
False)
184 export_transformation_type_selection = bpy.props.EnumProperty(name=
"Transformation Type", description=
"Transformation type for translation, scale and rotation", default=
'matrix', items=[(
'both',
"Both",
"Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"), (
'transrotloc',
"TransLocRot",
"Use <translate>, <rotate>, <scale> to specify transformations"), (
'matrix',
"Matrix",
"Use <matrix> to specify transformations")])
185 open_sim = bpy.props.BoolProperty(name=
"Export for OpenSim", description=
"Compatibility mode for OpenSim and compatible online worlds", default=
False)
191 box.label(text=
"Export Data Options", icon=
'MESH_DATA')
193 row.prop(self,
"apply_modifiers")
194 row.prop(self,
"export_mesh_type_selection", text=
"")
195 box.prop(self,
"selected")
196 box.prop(self,
"include_children")
197 box.prop(self,
"include_armatures")
198 box.prop(self,
"include_shapekeys")
201 box.label(text=
"Texture Options", icon=
'TEXTURE')
202 box.prop(self,
"active_uv_only")
203 box.prop(self,
"include_uv_textures")
204 box.prop(self,
"include_material_textures")
205 box.prop(self,
"use_texture_copies", text=
"Copy")
208 box.label(text=
"Armature Options", icon=
'ARMATURE_DATA')
209 box.prop(self,
"deform_bones_only")
210 box.prop(self,
"open_sim")
213 box.label(text=
"Collada Options", icon=
'MODIFIER')
214 box.prop(self,
"triangulate")
215 box.prop(self,
"use_object_instantiation")
217 row.label(text=
"Transformation Type")
218 row.prop(self,
"export_transformation_type_selection", text=
"")
219 box.prop(self,
"sort_by_name")
222 '''Export selected objects to a chosen format''' 223 bl_idname =
"export_scene.selected" 224 bl_label =
"Export Selected" 226 filename_ext = bpy.props.StringProperty(
231 filter_glob = bpy.props.StringProperty(
236 selection_mode = bpy.props.EnumProperty(
237 name=
"Selection Mode",
238 description=
"Limit/expand the selection",
241 (
'SELECTED',
"Selected",
""),
242 (
'VISIBLE',
"Visible",
""),
247 include_children = bpy.props.BoolProperty(
248 name=
"Include Children",
249 description=
"Keep children even if they're not selected",
253 remove_orphans = bpy.props.BoolProperty(
254 name=
"Remove Orphans",
255 description=
"Remove datablocks that have no users",
259 keep_materials = bpy.props.BoolProperty(
260 name=
"Keep Materials",
261 description=
"Keep Materials",
265 keep_textures = bpy.props.BoolProperty(
266 name=
"Keep Textures",
267 description=
"Keep Textures",
271 keep_world_textures = bpy.props.BoolProperty(
272 name=
"Keep World Textures",
273 description=
"Keep World Textures",
277 object_types = bpy.props.EnumProperty(
279 description=
"Object type(s) to export",
283 (
'MESH',
"Mesh",
""),
284 (
'CURVE',
"Curve",
""),
285 (
'SURFACE',
"Surface",
""),
286 (
'META',
"Meta",
""),
287 (
'FONT',
"Font",
""),
288 (
'ARMATURE',
"Armature",
""),
289 (
'LATTICE',
"Lattice",
""),
290 (
'EMPTY',
"Empty",
""),
291 (
'CAMERA',
"Camera",
""),
292 (
'LAMP',
"Lamp",
""),
293 (
'SPEAKER',
"Speaker",
""),
295 options={
'ENUM_FLAG'},
298 visible_name = bpy.props.StringProperty(
300 description=
"Visible name",
304 format = bpy.props.StringProperty(
306 description=
"Export format",
310 format_props = bpy.props.PointerProperty(
311 type=CurrentFormatProperties,
315 props_initialized = bpy.props.BoolProperty(
322 return len(context.scene.objects) != 0
327 CurrentFormatProperties._clear_props()
331 op_class =
type(op.get_instance())
333 if self.
format ==
"wm.collada_export":
334 op_class = ColladaEmulator
336 CurrentFormatProperties._add_props(op_class)
347 return ExportHelper.invoke(self, context, event)
350 bpy.ops.ed.undo_push(message=
"Delete unselected")
352 for scene
in bpy.data.scenes:
353 if scene != context.scene:
354 bpy.data.scenes.remove(scene)
356 scene = context.scene
361 if self.object_types.intersection({
'ALL', obj.type}):
365 for child
in obj.children:
368 for obj
in scene.objects:
371 elif (self.
selection_mode ==
'VISIBLE')
and obj.is_visible(scene):
372 obj.hide_select =
False 375 obj.hide_select =
False 378 for obj
in scene.objects:
382 scene.objects.unlink(obj)
383 bpy.data.objects.remove(obj)
388 for material
in bpy.data.materials:
389 material.user_clear()
390 bpy.data.materials.remove(material)
393 for world
in bpy.data.worlds:
394 for i
in range(len(world.texture_slots)):
395 world.texture_slots.clear(i)
396 for material
in bpy.data.materials:
397 for i
in range(len(material.texture_slots)):
398 material.texture_slots.clear(i)
399 for brush
in bpy.data.brushes:
401 for texture
in bpy.data.textures:
403 bpy.data.textures.remove(texture)
405 for world
in bpy.data.worlds:
406 for i
in range(len(world.texture_slots)):
407 world.texture_slots.clear(i)
410 datablocks_cleanup_order = [
446 for datablocks_name
in datablocks_cleanup_order:
447 datablocks = getattr(bpy.data, datablocks_name)
448 if type(datablocks).__name__ ==
"bpy_prop_collection":
449 for datablock
in datablocks:
450 if datablock.users == 0:
451 datablocks.remove(datablock)
453 if self.
format in join_before_export:
454 bpy.ops.object.convert()
455 bpy.ops.object.join()
463 for key
in CurrentFormatProperties._keys():
471 bpy.ops.wm.save_as_mainfile(
477 bpy.ops.ed.undo_push(message=
"Export Selected")
486 layout.prop(self,
"selection_mode", text=
"")
487 layout.prop(self,
"include_children")
488 layout.prop_menu_enum(self,
"object_types")
493 layout.prop(self,
"remove_orphans")
494 layout.prop(self,
"keep_materials")
495 layout.prop(self,
"keep_textures")
496 sublayout = layout.row()
498 sublayout.prop(self,
"keep_world_textures")
502 op_class =
type(op.get_instance())
504 if self.
format ==
"wm.collada_export":
505 op_class = ColladaEmulator
507 if hasattr(op_class,
"draw"):
508 self.format_props.layout = layout
511 for key
in CurrentFormatProperties._keys(
True):
512 if key ==
'filepath':
continue 516 bl_idname =
"OBJECT_MT_selected_export" 517 bl_label =
"Selected" 522 def def_op(visible_name, total_name="", layout=layout):
523 if visible_name.lower().startswith(
"export "):
524 visible_name = visible_name[len(
"export "):]
529 layout = layout.row()
530 layout.enabled =
False 532 op_info = layout.operator(
533 ExportSelected.bl_idname,
536 op_info.format = total_name
537 op_info.visible_name = visible_name
547 op_info = def_op(
"Collada",
"wm.collada_export")
548 op_info.filename_ext =
".dae" 549 op_info.filter_glob =
"*.dae" 552 op_class =
type(op.get_instance())
555 op_info = def_op(rna.rna_type.name, total_name)
557 if hasattr(op_class,
"filename_ext"):
558 op_info.filename_ext = op_class.filename_ext
560 if hasattr(rna,
"filter_glob"):
561 op_info.filter_glob = rna.filter_glob
564 self.layout.menu(
"OBJECT_MT_selected_export", text=
"Selected")
567 bpy.utils.register_class(CurrentFormatProperties)
568 bpy.utils.register_class(ExportSelected)
569 bpy.utils.register_class(OBJECT_MT_selected_export)
570 bpy.types.INFO_MT_file_export.prepend(menu_func_export)
573 bpy.types.INFO_MT_file_export.remove(menu_func_export)
574 bpy.utils.unregister_class(OBJECT_MT_selected_export)
575 bpy.utils.unregister_class(ExportSelected)
576 bpy.utils.unregister_class(CurrentFormatProperties)
578 if __name__ ==
"__main__":
def __exit__(self, type, value, traceback)
def iter_public_bpy_props(cls, exclude_hidden=False)
def menu_func_export(self, context)
def invoke(self, context, event)
def __init__(self, mode='OBJECT', undo=False)
def execute(self, context)
def clear_world(self, context)