1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
22 "name": "Web3D X3D/VRML2 format",
23 "author": "Campbell Barton, Bart, Bastien Montagne, Seva Alekseyev",
25 "blender": (2, 81, 6),
26 "location": "File > Import-Export",
27 "description": "Import-Export X3D, Import VRML2",
29 "doc_url": "{BLENDER_MANUAL_URL}/addons/import_export/scene_x3d.html",
30 "category": "Import-Export",
35 if "import_x3d" in locals():
36 importlib
.reload(import_x3d
)
37 if "export_x3d" in locals():
38 importlib
.reload(export_x3d
)
41 from bpy
.props
import (
47 from bpy_extras
.io_utils
import (
56 @orientation_helper(axis_forward
='Z', axis_up
='Y')
57 class ImportX3D(bpy
.types
.Operator
, ImportHelper
):
58 """Import an X3D or VRML2 file"""
59 bl_idname
= "import_scene.x3d"
60 bl_label
= "Import X3D/VRML2"
61 bl_options
= {'PRESET', 'UNDO'}
64 filter_glob
: StringProperty(default
="*.x3d;*.wrl", options
={'HIDDEN'})
66 def execute(self
, context
):
67 from . import import_x3d
69 keywords
= self
.as_keywords(ignore
=("axis_forward",
73 global_matrix
= axis_conversion(from_forward
=self
.axis_forward
,
76 keywords
["global_matrix"] = global_matrix
78 return import_x3d
.load(context
, **keywords
)
80 def draw(self
, context
):
84 class X3D_PT_export_include(bpy
.types
.Panel
):
85 bl_space_type
= 'FILE_BROWSER'
86 bl_region_type
= 'TOOL_PROPS'
88 bl_parent_id
= "FILE_PT_operator"
91 def poll(cls
, context
):
92 sfile
= context
.space_data
93 operator
= sfile
.active_operator
95 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
97 def draw(self
, context
):
99 layout
.use_property_split
= True
100 layout
.use_property_decorate
= False # No animation.
102 sfile
= context
.space_data
103 operator
= sfile
.active_operator
105 layout
.prop(operator
, "use_selection")
106 layout
.prop(operator
, "use_hierarchy")
107 layout
.prop(operator
, "name_decorations")
108 layout
.prop(operator
, "use_h3d")
111 class X3D_PT_export_transform(bpy
.types
.Panel
):
112 bl_space_type
= 'FILE_BROWSER'
113 bl_region_type
= 'TOOL_PROPS'
114 bl_label
= "Transform"
115 bl_parent_id
= "FILE_PT_operator"
118 def poll(cls
, context
):
119 sfile
= context
.space_data
120 operator
= sfile
.active_operator
122 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
124 def draw(self
, context
):
126 layout
.use_property_split
= True
127 layout
.use_property_decorate
= False # No animation.
129 sfile
= context
.space_data
130 operator
= sfile
.active_operator
132 layout
.prop(operator
, "global_scale")
133 layout
.prop(operator
, "axis_forward")
134 layout
.prop(operator
, "axis_up")
137 class X3D_PT_export_geometry(bpy
.types
.Panel
):
138 bl_space_type
= 'FILE_BROWSER'
139 bl_region_type
= 'TOOL_PROPS'
140 bl_label
= "Geometry"
141 bl_parent_id
= "FILE_PT_operator"
144 def poll(cls
, context
):
145 sfile
= context
.space_data
146 operator
= sfile
.active_operator
148 return operator
.bl_idname
== "EXPORT_SCENE_OT_x3d"
150 def draw(self
, context
):
152 layout
.use_property_split
= True
153 layout
.use_property_decorate
= False # No animation.
155 sfile
= context
.space_data
156 operator
= sfile
.active_operator
158 layout
.prop(operator
, "use_mesh_modifiers")
159 layout
.prop(operator
, "use_triangulate")
160 layout
.prop(operator
, "use_normals")
161 layout
.prop(operator
, "use_compress")
164 @orientation_helper(axis_forward
='Z', axis_up
='Y')
165 class ExportX3D(bpy
.types
.Operator
, ExportHelper
):
166 """Export selection to Extensible 3D file (.x3d)"""
167 bl_idname
= "export_scene.x3d"
168 bl_label
= 'Export X3D'
169 bl_options
= {'PRESET'}
171 filename_ext
= ".x3d"
172 filter_glob
: StringProperty(default
="*.x3d", options
={'HIDDEN'})
174 use_selection
: BoolProperty(
175 name
="Selection Only",
176 description
="Export selected objects only",
179 use_mesh_modifiers
: BoolProperty(
180 name
="Apply Modifiers",
181 description
="Use transformed mesh data from each object",
184 use_triangulate
: BoolProperty(
186 description
="Write quads into 'IndexedTriangleSet'",
189 use_normals
: BoolProperty(
191 description
="Write normals with geometry",
194 use_compress
: BoolProperty(
196 description
="Compress the exported file",
199 use_hierarchy
: BoolProperty(
201 description
="Export parent child relationships",
204 name_decorations
: BoolProperty(
205 name
="Name decorations",
206 description
=("Add prefixes to the names of exported nodes to "
207 "indicate their type"),
210 use_h3d
: BoolProperty(
211 name
="H3D Extensions",
212 description
="Export shaders for H3D",
216 global_scale
: FloatProperty(
218 min=0.01, max=1000.0,
222 path_mode
: path_reference_mode
224 def execute(self
, context
):
225 from . import export_x3d
227 from mathutils
import Matrix
229 keywords
= self
.as_keywords(ignore
=("axis_forward",
235 global_matrix
= axis_conversion(to_forward
=self
.axis_forward
,
237 ).to_4x4() @ Matrix
.Scale(self
.global_scale
, 4)
238 keywords
["global_matrix"] = global_matrix
240 return export_x3d
.save(context
, **keywords
)
242 def draw(self
, context
):
246 class X3D_PT_import_transform(bpy
.types
.Panel
):
247 bl_space_type
= 'FILE_BROWSER'
248 bl_region_type
= 'TOOL_PROPS'
249 bl_label
= "Transform"
250 bl_parent_id
= "FILE_PT_operator"
253 def poll(cls
, context
):
254 sfile
= context
.space_data
255 operator
= sfile
.active_operator
257 return operator
.bl_idname
== "IMPORT_SCENE_OT_x3d"
259 def draw(self
, context
):
261 layout
.use_property_split
= True
262 layout
.use_property_decorate
= False # No animation.
264 sfile
= context
.space_data
265 operator
= sfile
.active_operator
267 layout
.prop(operator
, "axis_forward")
268 layout
.prop(operator
, "axis_up")
271 def menu_func_import(self
, context
):
272 self
.layout
.operator(ImportX3D
.bl_idname
,
273 text
="X3D Extensible 3D (.x3d/.wrl)")
276 def menu_func_export(self
, context
):
277 self
.layout
.operator(ExportX3D
.bl_idname
,
278 text
="X3D Extensible 3D (.x3d)")
283 X3D_PT_export_include
,
284 X3D_PT_export_transform
,
285 X3D_PT_export_geometry
,
287 X3D_PT_import_transform
,
293 bpy
.utils
.register_class(cls
)
295 bpy
.types
.TOPBAR_MT_file_import
.append(menu_func_import
)
296 bpy
.types
.TOPBAR_MT_file_export
.append(menu_func_export
)
300 bpy
.types
.TOPBAR_MT_file_import
.remove(menu_func_import
)
301 bpy
.types
.TOPBAR_MT_file_export
.remove(menu_func_export
)
304 bpy
.utils
.unregister_class(cls
)
307 if __name__
== "__main__":