Merge branch 'blender-v3.3-release'
[blender-addons.git] / io_scene_x3d / __init__.py
blobdd41fd15c802c1784c59284a5d60117ee7ec879b
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 bl_info = {
4 "name": "Web3D X3D/VRML2 format",
5 "author": "Campbell Barton, Bart, Bastien Montagne, Seva Alekseyev",
6 "version": (2, 3, 0),
7 "blender": (2, 93, 0),
8 "location": "File > Import-Export",
9 "description": "Import-Export X3D, Import VRML2",
10 "warning": "",
11 "doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/scene_x3d.html",
12 "category": "Import-Export",
15 if "bpy" in locals():
16 import importlib
17 if "import_x3d" in locals():
18 importlib.reload(import_x3d)
19 if "export_x3d" in locals():
20 importlib.reload(export_x3d)
22 import bpy
23 from bpy.props import (
24 BoolProperty,
25 EnumProperty,
26 FloatProperty,
27 StringProperty,
29 from bpy_extras.io_utils import (
30 ImportHelper,
31 ExportHelper,
32 orientation_helper,
33 axis_conversion,
34 path_reference_mode,
38 @orientation_helper(axis_forward='Z', axis_up='Y')
39 class ImportX3D(bpy.types.Operator, ImportHelper):
40 """Import an X3D or VRML2 file"""
41 bl_idname = "import_scene.x3d"
42 bl_label = "Import X3D/VRML2"
43 bl_options = {'PRESET', 'UNDO'}
45 filename_ext = ".x3d"
46 filter_glob: StringProperty(default="*.x3d;*.wrl", options={'HIDDEN'})
48 def execute(self, context):
49 from . import import_x3d
51 keywords = self.as_keywords(ignore=("axis_forward",
52 "axis_up",
53 "filter_glob",
55 global_matrix = axis_conversion(from_forward=self.axis_forward,
56 from_up=self.axis_up,
57 ).to_4x4()
58 keywords["global_matrix"] = global_matrix
60 return import_x3d.load(context, **keywords)
62 def draw(self, context):
63 pass
66 class X3D_PT_export_include(bpy.types.Panel):
67 bl_space_type = 'FILE_BROWSER'
68 bl_region_type = 'TOOL_PROPS'
69 bl_label = "Include"
70 bl_parent_id = "FILE_PT_operator"
72 @classmethod
73 def poll(cls, context):
74 sfile = context.space_data
75 operator = sfile.active_operator
77 return operator.bl_idname == "EXPORT_SCENE_OT_x3d"
79 def draw(self, context):
80 layout = self.layout
81 layout.use_property_split = True
82 layout.use_property_decorate = False # No animation.
84 sfile = context.space_data
85 operator = sfile.active_operator
87 layout.prop(operator, "use_selection")
88 layout.prop(operator, "use_hierarchy")
89 layout.prop(operator, "name_decorations")
90 layout.prop(operator, "use_h3d")
93 class X3D_PT_export_transform(bpy.types.Panel):
94 bl_space_type = 'FILE_BROWSER'
95 bl_region_type = 'TOOL_PROPS'
96 bl_label = "Transform"
97 bl_parent_id = "FILE_PT_operator"
99 @classmethod
100 def poll(cls, context):
101 sfile = context.space_data
102 operator = sfile.active_operator
104 return operator.bl_idname == "EXPORT_SCENE_OT_x3d"
106 def draw(self, context):
107 layout = self.layout
108 layout.use_property_split = True
109 layout.use_property_decorate = False # No animation.
111 sfile = context.space_data
112 operator = sfile.active_operator
114 layout.prop(operator, "global_scale")
115 layout.prop(operator, "axis_forward")
116 layout.prop(operator, "axis_up")
119 class X3D_PT_export_geometry(bpy.types.Panel):
120 bl_space_type = 'FILE_BROWSER'
121 bl_region_type = 'TOOL_PROPS'
122 bl_label = "Geometry"
123 bl_parent_id = "FILE_PT_operator"
125 @classmethod
126 def poll(cls, context):
127 sfile = context.space_data
128 operator = sfile.active_operator
130 return operator.bl_idname == "EXPORT_SCENE_OT_x3d"
132 def draw(self, context):
133 layout = self.layout
134 layout.use_property_split = True
135 layout.use_property_decorate = False # No animation.
137 sfile = context.space_data
138 operator = sfile.active_operator
140 layout.prop(operator, "use_mesh_modifiers")
141 layout.prop(operator, "use_triangulate")
142 layout.prop(operator, "use_normals")
143 layout.prop(operator, "use_compress")
146 @orientation_helper(axis_forward='Z', axis_up='Y')
147 class ExportX3D(bpy.types.Operator, ExportHelper):
148 """Export selection to Extensible 3D file (.x3d)"""
149 bl_idname = "export_scene.x3d"
150 bl_label = 'Export X3D'
151 bl_options = {'PRESET'}
153 filename_ext = ".x3d"
154 filter_glob: StringProperty(default="*.x3d", options={'HIDDEN'})
156 use_selection: BoolProperty(
157 name="Selection Only",
158 description="Export selected objects only",
159 default=False,
161 use_mesh_modifiers: BoolProperty(
162 name="Apply Modifiers",
163 description="Use transformed mesh data from each object",
164 default=True,
166 use_triangulate: BoolProperty(
167 name="Triangulate",
168 description="Write quads into 'IndexedTriangleSet'",
169 default=False,
171 use_normals: BoolProperty(
172 name="Normals",
173 description="Write normals with geometry",
174 default=False,
176 use_compress: BoolProperty(
177 name="Compress",
178 description="Compress the exported file",
179 default=False,
181 use_hierarchy: BoolProperty(
182 name="Hierarchy",
183 description="Export parent child relationships",
184 default=True,
186 name_decorations: BoolProperty(
187 name="Name decorations",
188 description=("Add prefixes to the names of exported nodes to "
189 "indicate their type"),
190 default=True,
192 use_h3d: BoolProperty(
193 name="H3D Extensions",
194 description="Export shaders for H3D",
195 default=False,
198 global_scale: FloatProperty(
199 name="Scale",
200 min=0.01, max=1000.0,
201 default=1.0,
204 path_mode: path_reference_mode
206 def execute(self, context):
207 from . import export_x3d
209 from mathutils import Matrix
211 keywords = self.as_keywords(ignore=("axis_forward",
212 "axis_up",
213 "global_scale",
214 "check_existing",
215 "filter_glob",
217 global_matrix = axis_conversion(to_forward=self.axis_forward,
218 to_up=self.axis_up,
219 ).to_4x4() @ Matrix.Scale(self.global_scale, 4)
220 keywords["global_matrix"] = global_matrix
222 return export_x3d.save(context, **keywords)
224 def draw(self, context):
225 pass
228 class X3D_PT_import_transform(bpy.types.Panel):
229 bl_space_type = 'FILE_BROWSER'
230 bl_region_type = 'TOOL_PROPS'
231 bl_label = "Transform"
232 bl_parent_id = "FILE_PT_operator"
234 @classmethod
235 def poll(cls, context):
236 sfile = context.space_data
237 operator = sfile.active_operator
239 return operator.bl_idname == "IMPORT_SCENE_OT_x3d"
241 def draw(self, context):
242 layout = self.layout
243 layout.use_property_split = True
244 layout.use_property_decorate = False # No animation.
246 sfile = context.space_data
247 operator = sfile.active_operator
249 layout.prop(operator, "axis_forward")
250 layout.prop(operator, "axis_up")
253 def menu_func_import(self, context):
254 self.layout.operator(ImportX3D.bl_idname,
255 text="X3D Extensible 3D (.x3d/.wrl)")
258 def menu_func_export(self, context):
259 self.layout.operator(ExportX3D.bl_idname,
260 text="X3D Extensible 3D (.x3d)")
263 classes = (
264 ExportX3D,
265 X3D_PT_export_include,
266 X3D_PT_export_transform,
267 X3D_PT_export_geometry,
268 ImportX3D,
269 X3D_PT_import_transform,
273 def register():
274 for cls in classes:
275 bpy.utils.register_class(cls)
277 bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
278 bpy.types.TOPBAR_MT_file_export.append(menu_func_export)
281 def unregister():
282 bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
283 bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
285 for cls in classes:
286 bpy.utils.unregister_class(cls)
289 if __name__ == "__main__":
290 register()