1 # SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
6 "name": "Web3D X3D/VRML2 format",
7 "author": "Campbell Barton, Bart, Bastien Montagne, Seva Alekseyev",
10 "location": "File > Import-Export",
11 "description": "Import-Export X3D, Import VRML2",
13 "doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/scene_x3d.html",
14 "category": "Import-Export",
19 if "import_x3d" in locals():
20 importlib
.reload(import_x3d
)
21 if "export_x3d" in locals():
22 importlib
.reload(export_x3d
)
25 from bpy
.props
import (
31 from bpy_extras
.io_utils
import (
40 @orientation_helper(axis_forward
='Z', axis_up
='Y')
41 class ImportX3D(bpy
.types
.Operator
, ImportHelper
):
42 """Import an X3D or VRML2 file"""
43 bl_idname
= "import_scene.x3d"
44 bl_label
= "Import X3D/VRML2"
45 bl_options
= {'PRESET', 'UNDO'}
48 filter_glob
: StringProperty(default
="*.x3d;*.wrl", options
={'HIDDEN'})
50 def execute(self
, context
):
51 from . import import_x3d
53 keywords
= self
.as_keywords(ignore
=("axis_forward",
57 global_matrix
= axis_conversion(from_forward
=self
.axis_forward
,
60 keywords
["global_matrix"] = global_matrix
62 return import_x3d
.load(context
, **keywords
)
64 def draw(self
, context
):
68 class X3D_PT_export_include(bpy
.types
.Panel
):
69 bl_space_type
= 'FILE_BROWSER'
70 bl_region_type
= 'TOOL_PROPS'
72 bl_parent_id
= "FILE_PT_operator"
75 def poll(cls
, context
):
76 sfile
= context
.space_data
77 operator
= sfile
.active_operator
79 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
81 def draw(self
, context
):
83 layout
.use_property_split
= True
84 layout
.use_property_decorate
= False # No animation.
86 sfile
= context
.space_data
87 operator
= sfile
.active_operator
89 layout
.prop(operator
, "use_selection")
90 layout
.prop(operator
, "use_hierarchy")
91 layout
.prop(operator
, "name_decorations")
92 layout
.prop(operator
, "use_h3d")
95 class X3D_PT_export_transform(bpy
.types
.Panel
):
96 bl_space_type
= 'FILE_BROWSER'
97 bl_region_type
= 'TOOL_PROPS'
98 bl_label
= "Transform"
99 bl_parent_id
= "FILE_PT_operator"
102 def poll(cls
, context
):
103 sfile
= context
.space_data
104 operator
= sfile
.active_operator
106 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
108 def draw(self
, context
):
110 layout
.use_property_split
= True
111 layout
.use_property_decorate
= False # No animation.
113 sfile
= context
.space_data
114 operator
= sfile
.active_operator
116 layout
.prop(operator
, "global_scale")
117 layout
.prop(operator
, "axis_forward")
118 layout
.prop(operator
, "axis_up")
121 class X3D_PT_export_geometry(bpy
.types
.Panel
):
122 bl_space_type
= 'FILE_BROWSER'
123 bl_region_type
= 'TOOL_PROPS'
124 bl_label
= "Geometry"
125 bl_parent_id
= "FILE_PT_operator"
128 def poll(cls
, context
):
129 sfile
= context
.space_data
130 operator
= sfile
.active_operator
132 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
134 def draw(self
, context
):
136 layout
.use_property_split
= True
137 layout
.use_property_decorate
= False # No animation.
139 sfile
= context
.space_data
140 operator
= sfile
.active_operator
142 layout
.prop(operator
, "use_mesh_modifiers")
143 layout
.prop(operator
, "use_triangulate")
144 layout
.prop(operator
, "use_normals")
145 layout
.prop(operator
, "use_compress")
148 @orientation_helper(axis_forward
='Z', axis_up
='Y')
149 class ExportX3D(bpy
.types
.Operator
, ExportHelper
):
150 """Export selection to Extensible 3D file (.x3d)"""
151 bl_idname
= "export_scene.x3d"
152 bl_label
= 'Export X3D'
153 bl_options
= {'PRESET'}
155 filename_ext
= ".x3d"
156 filter_glob
: StringProperty(default
="*.x3d", options
={'HIDDEN'})
158 use_selection
: BoolProperty(
159 name
="Selection Only",
160 description
="Export selected objects only",
163 use_mesh_modifiers
: BoolProperty(
164 name
="Apply Modifiers",
165 description
="Use transformed mesh data from each object",
168 use_triangulate
: BoolProperty(
170 description
="Write quads into 'IndexedTriangleSet'",
173 use_normals
: BoolProperty(
175 description
="Write normals with geometry",
178 use_compress
: BoolProperty(
180 description
="Compress the exported file",
183 use_hierarchy
: BoolProperty(
185 description
="Export parent child relationships",
188 name_decorations
: BoolProperty(
189 name
="Name decorations",
190 description
=("Add prefixes to the names of exported nodes to "
191 "indicate their type"),
194 use_h3d
: BoolProperty(
195 name
="H3D Extensions",
196 description
="Export shaders for H3D",
200 global_scale
: FloatProperty(
202 min=0.01, max=1000.0,
206 path_mode
: path_reference_mode
208 def execute(self
, context
):
209 from . import export_x3d
211 from mathutils
import Matrix
213 keywords
= self
.as_keywords(ignore
=("axis_forward",
219 global_matrix
= axis_conversion(to_forward
=self
.axis_forward
,
221 ).to_4x4() @ Matrix
.Scale(self
.global_scale
, 4)
222 keywords
["global_matrix"] = global_matrix
224 return export_x3d
.save(context
, **keywords
)
226 def draw(self
, context
):
230 class X3D_PT_import_transform(bpy
.types
.Panel
):
231 bl_space_type
= 'FILE_BROWSER'
232 bl_region_type
= 'TOOL_PROPS'
233 bl_label
= "Transform"
234 bl_parent_id
= "FILE_PT_operator"
237 def poll(cls
, context
):
238 sfile
= context
.space_data
239 operator
= sfile
.active_operator
241 return operator
.bl_idname
== "IMPORT_SCENE_OT_x3d"
243 def draw(self
, context
):
245 layout
.use_property_split
= True
246 layout
.use_property_decorate
= False # No animation.
248 sfile
= context
.space_data
249 operator
= sfile
.active_operator
251 layout
.prop(operator
, "axis_forward")
252 layout
.prop(operator
, "axis_up")
255 def menu_func_import(self
, context
):
256 self
.layout
.operator(ImportX3D
.bl_idname
,
257 text
="X3D Extensible 3D (.x3d/.wrl)")
260 def menu_func_export(self
, context
):
261 self
.layout
.operator(ExportX3D
.bl_idname
,
262 text
="X3D Extensible 3D (.x3d)")
267 X3D_PT_export_include
,
268 X3D_PT_export_transform
,
269 X3D_PT_export_geometry
,
271 X3D_PT_import_transform
,
277 bpy
.utils
.register_class(cls
)
279 bpy
.types
.TOPBAR_MT_file_import
.append(menu_func_import
)
280 bpy
.types
.TOPBAR_MT_file_export
.append(menu_func_export
)
284 bpy
.types
.TOPBAR_MT_file_import
.remove(menu_func_import
)
285 bpy
.types
.TOPBAR_MT_file_export
.remove(menu_func_export
)
288 bpy
.utils
.unregister_class(cls
)
291 if __name__
== "__main__":