1 # SPDX-License-Identifier: GPL-2.0-or-later
4 "name": "Stanford PLY format",
5 "author": "Bruce Merry, Campbell Barton, Bastien Montagne, Mikhail Rachinsky",
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
20 if "export_ply" in locals():
21 importlib
.reload(export_ply
)
22 if "import_ply" in locals():
23 importlib
.reload(import_ply
)
27 from bpy
.props
import (
33 from bpy_extras
.io_utils
import (
41 class ImportPLY(bpy
.types
.Operator
, ImportHelper
):
42 """Load a PLY geometry file"""
43 bl_idname
= "import_mesh.ply"
44 bl_label
= "Import PLY"
47 files
: CollectionProperty(
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",
60 directory
: StringProperty()
63 filter_glob
: StringProperty(default
="*.ply", options
={'HIDDEN'})
65 def execute(self
, context
):
67 from . import import_ply
69 context
.window
.cursor_set('WAIT')
72 os
.path
.join(self
.directory
, name
.name
)
73 for name
in self
.files
77 paths
.append(self
.filepath
)
80 import_ply
.load(self
, context
, path
)
82 context
.window
.cursor_set('DEFAULT')
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"
94 filter_glob
: StringProperty(default
="*.ply", options
={'HIDDEN'})
96 use_ascii
: BoolProperty(
98 description
="Export using ASCII file format, otherwise use binary",
100 use_selection
: BoolProperty(
101 name
="Selection Only",
102 description
="Export selected objects only",
105 use_mesh_modifiers
: BoolProperty(
106 name
="Apply Modifiers",
107 description
="Apply Modifiers to the exported mesh",
110 use_normals
: BoolProperty(
112 description
="Export vertex normals",
115 use_uv_coords
: BoolProperty(
117 description
="Export the active UV layer (will split edges by seams)",
120 use_colors
: BoolProperty(
121 name
="Vertex Colors",
122 description
="Export the active vertex color layer",
125 global_scale
: FloatProperty(
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(
147 global_matrix
= axis_conversion(
148 to_forward
=self
.axis_forward
,
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')
159 def draw(self
, context
):
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'
175 bl_parent_id
= "FILE_PT_operator"
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
):
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"
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
):
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"
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
):
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)")
259 PLY_PT_export_include
,
260 PLY_PT_export_transform
,
261 PLY_PT_export_geometry
,
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
)
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__":