Merge branch 'blender-v3.6-release'
[blender-addons.git] / io_mesh_ply / __init__.py
blobd3080a72f8b72ad4c7d31c9c7453440d2977d8d3
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 bl_info = {
4 "name": "Stanford PLY format",
5 "author": "Bruce Merry, Campbell Barton, Bastien Montagne, Mikhail Rachinsky",
6 "version": (2, 2, 0),
7 "blender": (3, 0, 0),
8 "location": "File > Import/Export",
9 "description": "Import-Export PLY mesh data with UVs and vertex colors",
10 "doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/mesh_ply.html",
11 "support": 'OFFICIAL',
12 "category": "Import-Export",
15 # Copyright (C) 2004, 2005: Bruce Merry, bmerry@cs.uct.ac.za
16 # Contributors: Bruce Merry, Campbell Barton
18 if "bpy" in locals():
19 import importlib
20 if "export_ply" in locals():
21 importlib.reload(export_ply)
22 if "import_ply" in locals():
23 importlib.reload(import_ply)
26 import bpy
27 from bpy.props import (
28 CollectionProperty,
29 StringProperty,
30 BoolProperty,
31 FloatProperty,
33 from bpy_extras.io_utils import (
34 ImportHelper,
35 ExportHelper,
36 axis_conversion,
37 orientation_helper,
41 class ImportPLY(bpy.types.Operator, ImportHelper):
42 """Load a PLY geometry file"""
43 bl_idname = "import_mesh.ply"
44 bl_label = "Import PLY"
45 bl_options = {'UNDO'}
47 files: CollectionProperty(
48 name="File Path",
49 description="File path used for importing the PLY file",
50 type=bpy.types.OperatorFileListElement,
53 # Hide opertator properties, rest of this is managed in C. See WM_operator_properties_filesel().
54 hide_props_region: BoolProperty(
55 name="Hide Operator Properties",
56 description="Collapse the region displaying the operator settings",
57 default=True,
60 directory: StringProperty()
62 filename_ext = ".ply"
63 filter_glob: StringProperty(default="*.ply", options={'HIDDEN'})
65 def execute(self, context):
66 import os
67 from . import import_ply
69 context.window.cursor_set('WAIT')
71 paths = [
72 os.path.join(self.directory, name.name)
73 for name in self.files
76 if not paths:
77 paths.append(self.filepath)
79 for path in paths:
80 import_ply.load(self, context, path)
82 context.window.cursor_set('DEFAULT')
84 return {'FINISHED'}
87 @orientation_helper(axis_forward='Y', axis_up='Z')
88 class ExportPLY(bpy.types.Operator, ExportHelper):
89 bl_idname = "export_mesh.ply"
90 bl_label = "Export PLY"
91 bl_description = "Export as a Stanford PLY with normals, vertex colors and texture coordinates"
93 filename_ext = ".ply"
94 filter_glob: StringProperty(default="*.ply", options={'HIDDEN'})
96 use_ascii: BoolProperty(
97 name="ASCII",
98 description="Export using ASCII file format, otherwise use binary",
100 use_selection: BoolProperty(
101 name="Selection Only",
102 description="Export selected objects only",
103 default=False,
105 use_mesh_modifiers: BoolProperty(
106 name="Apply Modifiers",
107 description="Apply Modifiers to the exported mesh",
108 default=True,
110 use_normals: BoolProperty(
111 name="Normals",
112 description="Export vertex normals",
113 default=True,
115 use_uv_coords: BoolProperty(
116 name="UVs",
117 description="Export the active UV layer (will split edges by seams)",
118 default=True,
120 use_colors: BoolProperty(
121 name="Vertex Colors",
122 description="Export the active vertex color layer",
123 default=True,
125 global_scale: FloatProperty(
126 name="Scale",
127 min=0.01,
128 max=1000.0,
129 default=1.0,
132 def execute(self, context):
133 from mathutils import Matrix
134 from . import export_ply
136 context.window.cursor_set('WAIT')
138 keywords = self.as_keywords(
139 ignore=(
140 "axis_forward",
141 "axis_up",
142 "global_scale",
143 "check_existing",
144 "filter_glob",
147 global_matrix = axis_conversion(
148 to_forward=self.axis_forward,
149 to_up=self.axis_up,
150 ).to_4x4() @ Matrix.Scale(self.global_scale, 4)
151 keywords["global_matrix"] = global_matrix
153 export_ply.save(context, **keywords)
155 context.window.cursor_set('DEFAULT')
157 return {'FINISHED'}
159 def draw(self, context):
160 layout = self.layout
161 layout.use_property_split = True
162 layout.use_property_decorate = False
164 sfile = context.space_data
165 operator = sfile.active_operator
167 col = layout.column(heading="Format")
168 col.prop(operator, "use_ascii")
171 class PLY_PT_export_include(bpy.types.Panel):
172 bl_space_type = 'FILE_BROWSER'
173 bl_region_type = 'TOOL_PROPS'
174 bl_label = "Include"
175 bl_parent_id = "FILE_PT_operator"
177 @classmethod
178 def poll(cls, context):
179 sfile = context.space_data
180 operator = sfile.active_operator
182 return operator.bl_idname == "EXPORT_MESH_OT_ply"
184 def draw(self, context):
185 layout = self.layout
186 layout.use_property_split = True
187 layout.use_property_decorate = False
189 sfile = context.space_data
190 operator = sfile.active_operator
192 layout.prop(operator, "use_selection")
195 class PLY_PT_export_transform(bpy.types.Panel):
196 bl_space_type = 'FILE_BROWSER'
197 bl_region_type = 'TOOL_PROPS'
198 bl_label = "Transform"
199 bl_parent_id = "FILE_PT_operator"
201 @classmethod
202 def poll(cls, context):
203 sfile = context.space_data
204 operator = sfile.active_operator
206 return operator.bl_idname == "EXPORT_MESH_OT_ply"
208 def draw(self, context):
209 layout = self.layout
210 layout.use_property_split = True
211 layout.use_property_decorate = False
213 sfile = context.space_data
214 operator = sfile.active_operator
216 layout.prop(operator, "axis_forward")
217 layout.prop(operator, "axis_up")
218 layout.prop(operator, "global_scale")
221 class PLY_PT_export_geometry(bpy.types.Panel):
222 bl_space_type = 'FILE_BROWSER'
223 bl_region_type = 'TOOL_PROPS'
224 bl_label = "Geometry"
225 bl_parent_id = "FILE_PT_operator"
227 @classmethod
228 def poll(cls, context):
229 sfile = context.space_data
230 operator = sfile.active_operator
232 return operator.bl_idname == "EXPORT_MESH_OT_ply"
234 def draw(self, context):
235 layout = self.layout
236 layout.use_property_split = True
237 layout.use_property_decorate = False
239 sfile = context.space_data
240 operator = sfile.active_operator
242 layout.prop(operator, "use_mesh_modifiers")
243 layout.prop(operator, "use_normals")
244 layout.prop(operator, "use_uv_coords")
245 layout.prop(operator, "use_colors")
248 def menu_func_import(self, context):
249 self.layout.operator(ImportPLY.bl_idname, text="Stanford (.ply)")
252 def menu_func_export(self, context):
253 self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)")
256 classes = (
257 ImportPLY,
258 ExportPLY,
259 PLY_PT_export_include,
260 PLY_PT_export_transform,
261 PLY_PT_export_geometry,
265 def register():
266 for cls in classes:
267 bpy.utils.register_class(cls)
269 bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
270 bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
273 def unregister():
274 for cls in classes:
275 bpy.utils.unregister_class(cls)
277 bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
278 bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
281 if __name__ == "__main__":
282 register()