__init__.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  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.
  7. #
  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.
  12. #
  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.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. import os
  19. import json
  20. import logging
  21. import bpy
  22. from bpy_extras.io_utils import ExportHelper
  23. from bpy.props import (
  24. EnumProperty,
  25. BoolProperty,
  26. FloatProperty,
  27. IntProperty
  28. )
  29. from . import constants
  30. logging.basicConfig(
  31. format='%(levelname)s:THREE:%(message)s',
  32. level=logging.DEBUG)
  33. SETTINGS_FILE_EXPORT = 'three_settings_export.js'
  34. bl_info = {
  35. 'name': "Three.js Format",
  36. 'author': "repsac, mrdoob, yomotsu, mpk, jpweeks",
  37. 'version': (1, 2, 2),
  38. 'blender': (2, 7, 3),
  39. 'location': "File > Export",
  40. 'description': "Export Three.js formatted JSON files.",
  41. 'warning': "Importer not included.",
  42. 'wiki_url': "https://github.com/mrdoob/three.js/tree/"\
  43. "master/utils/exporters/blender",
  44. 'tracker_url': "https://github.com/mrdoob/three.js/issues",
  45. 'category': 'Import-Export'
  46. }
  47. def _geometry_types():
  48. """The valid geometry types that are supported by Three.js
  49. :return: list of tuples
  50. """
  51. keys = (constants.GLOBAL,
  52. constants.GEOMETRY,
  53. constants.BUFFER_GEOMETRY)
  54. types = []
  55. for key in keys:
  56. types.append((key, key.title(), key))
  57. return types
  58. bpy.types.Mesh.THREE_geometry_type = EnumProperty(
  59. name="Geometry type",
  60. description="Geometry type",
  61. items=_geometry_types(),
  62. default=constants.GLOBAL)
  63. class ThreeMesh(bpy.types.Panel):
  64. """Creates custom properties on a mesh node"""
  65. bl_label = 'THREE'
  66. bl_space_type = 'PROPERTIES'
  67. bl_region_type = 'WINDOW'
  68. bl_context = 'data'
  69. def draw(self, context):
  70. """
  71. :param context:
  72. """
  73. row = self.layout.row()
  74. if context.mesh:
  75. row.prop(context.mesh,
  76. 'THREE_geometry_type',
  77. text="Type")
  78. def _blending_types(index):
  79. """Supported blending types for Three.js
  80. :param index:
  81. :type index: int
  82. :returns: tuple if types (str, str, str)
  83. """
  84. types = (constants.BLENDING_TYPES.NONE,
  85. constants.BLENDING_TYPES.NORMAL,
  86. constants.BLENDING_TYPES.ADDITIVE,
  87. constants.BLENDING_TYPES.SUBTRACTIVE,
  88. constants.BLENDING_TYPES.MULTIPLY,
  89. constants.BLENDING_TYPES.CUSTOM)
  90. return (types[index], types[index], types[index])
  91. bpy.types.Material.THREE_blending_type = EnumProperty(
  92. name="Blending type",
  93. description="Blending type",
  94. items=[_blending_types(x) for x in range(5)],
  95. default=constants.BLENDING_TYPES.NORMAL)
  96. bpy.types.Material.THREE_depth_write = BoolProperty(default=True)
  97. bpy.types.Material.THREE_depth_test = BoolProperty(default=True)
  98. class ThreeMaterial(bpy.types.Panel):
  99. """Adds custom properties to the Materials of an object"""
  100. bl_label = 'THREE'
  101. bl_space_type = 'PROPERTIES'
  102. bl_region_type = 'WINDOW'
  103. bl_context = 'material'
  104. def draw(self, context):
  105. """
  106. :param context:
  107. """
  108. layout = self.layout
  109. mat = context.material
  110. if mat is not None:
  111. row = layout.row()
  112. row.label(text="Selected material: %s" % mat.name)
  113. row = layout.row()
  114. row.prop(mat, 'THREE_blending_type',
  115. text="Blending type")
  116. row = layout.row()
  117. row.prop(mat, 'THREE_depth_write',
  118. text="Enable depth writing")
  119. row = layout.row()
  120. row.prop(mat, 'THREE_depth_test',
  121. text="Enable depth testing")
  122. def _mag_filters(index):
  123. """Three.js mag filters
  124. :param index:
  125. :type index: int
  126. :returns: tuple with the filter values
  127. """
  128. types = (constants.LINEAR_FILTERS.LINEAR,
  129. constants.NEAREST_FILTERS.NEAREST)
  130. return (types[index], types[index], types[index])
  131. bpy.types.Texture.THREE_mag_filter = EnumProperty(
  132. name="Mag Filter",
  133. items=[_mag_filters(x) for x in range(2)],
  134. default=constants.LINEAR_FILTERS.LINEAR)
  135. def _min_filters(index):
  136. """Three.js min filters
  137. :param index:
  138. :type index: int
  139. :returns: tuple with the filter values
  140. """
  141. types = (constants.LINEAR_FILTERS.LINEAR,
  142. constants.LINEAR_FILTERS.MIP_MAP_NEAREST,
  143. constants.LINEAR_FILTERS.MIP_MAP_LINEAR,
  144. constants.NEAREST_FILTERS.NEAREST,
  145. constants.NEAREST_FILTERS.MIP_MAP_NEAREST,
  146. constants.NEAREST_FILTERS.MIP_MAP_LINEAR)
  147. return (types[index], types[index], types[index])
  148. bpy.types.Texture.THREE_min_filter = EnumProperty(
  149. name="Min Filter",
  150. items=[_min_filters(x) for x in range(6)],
  151. default=constants.LINEAR_FILTERS.MIP_MAP_LINEAR)
  152. def _mapping(index):
  153. """Three.js texture mappings types
  154. :param index:
  155. :type index: int
  156. :returns: tuple with the mapping values
  157. """
  158. types = (constants.MAPPING_TYPES.UV,
  159. constants.MAPPING_TYPES.CUBE_REFLECTION,
  160. constants.MAPPING_TYPES.CUBE_REFRACTION,
  161. constants.MAPPING_TYPES.SPHERICAL_REFLECTION)
  162. return (types[index], types[index], types[index])
  163. bpy.types.Texture.THREE_mapping = EnumProperty(
  164. name="Mapping",
  165. items=[_mapping(x) for x in range(4)],
  166. default=constants.MAPPING_TYPES.UV)
  167. class ThreeTexture(bpy.types.Panel):
  168. """Adds custom properties to a texture"""
  169. bl_label = 'THREE'
  170. bl_space_type = 'PROPERTIES'
  171. bl_region_type = 'WINDOW'
  172. bl_context = 'texture'
  173. #@TODO: possible to make cycles compatible?
  174. def draw(self, context):
  175. """
  176. :param context:
  177. """
  178. layout = self.layout
  179. tex = context.texture
  180. if tex is not None:
  181. row = layout.row()
  182. row.prop(tex, 'THREE_mapping', text="Mapping")
  183. row = layout.row()
  184. row.prop(tex, 'THREE_mag_filter', text="Mag Filter")
  185. row = layout.row()
  186. row.prop(tex, 'THREE_min_filter', text="Min Filter")
  187. bpy.types.Object.THREE_export = bpy.props.BoolProperty(default=True)
  188. class ThreeObject(bpy.types.Panel):
  189. """Adds custom properties to an object"""
  190. bl_label = 'THREE'
  191. bl_space_type = 'PROPERTIES'
  192. bl_region_type = 'WINDOW'
  193. bl_context = 'object'
  194. def draw(self, context):
  195. """
  196. :param context:
  197. """
  198. layout = self.layout
  199. obj = context.object
  200. row = layout.row()
  201. row.prop(obj, 'THREE_export', text='Export')
  202. def get_settings_fullpath():
  203. """
  204. :returns: Full path to the settings file (temp directory)
  205. """
  206. return os.path.join(bpy.app.tempdir, SETTINGS_FILE_EXPORT)
  207. def save_settings_export(properties):
  208. """Save the current export settings to disk.
  209. :param properties:
  210. :returns: settings
  211. :rtype: dict
  212. """
  213. settings = {
  214. constants.VERTICES: properties.option_vertices,
  215. constants.FACES: properties.option_faces,
  216. constants.NORMALS: properties.option_normals,
  217. constants.SKINNING: properties.option_skinning,
  218. constants.BONES: properties.option_bones,
  219. constants.GEOMETRY_TYPE: properties.option_geometry_type,
  220. constants.MATERIALS: properties.option_materials,
  221. constants.UVS: properties.option_uv_coords,
  222. constants.FACE_MATERIALS: properties.option_face_materials,
  223. constants.MAPS: properties.option_maps,
  224. constants.COLORS: properties.option_colors,
  225. constants.MIX_COLORS: properties.option_mix_colors,
  226. constants.SCALE: properties.option_scale,
  227. constants.ENABLE_PRECISION: properties.option_round_off,
  228. constants.PRECISION: properties.option_round_value,
  229. constants.LOGGING: properties.option_logging,
  230. constants.COMPRESSION: properties.option_compression,
  231. constants.INDENT: properties.option_indent,
  232. constants.COPY_TEXTURES: properties.option_copy_textures,
  233. constants.SCENE: properties.option_export_scene,
  234. #constants.EMBED_GEOMETRY: properties.option_embed_geometry,
  235. constants.EMBED_ANIMATION: properties.option_embed_animation,
  236. constants.LIGHTS: properties.option_lights,
  237. constants.CAMERAS: properties.option_cameras,
  238. constants.MORPH_TARGETS: properties.option_animation_morph,
  239. constants.ANIMATION: properties.option_animation_skeletal,
  240. constants.FRAME_STEP: properties.option_frame_step,
  241. constants.FRAME_INDEX_AS_TIME: properties.option_frame_index_as_time,
  242. constants.INFLUENCES_PER_VERTEX: properties.option_influences
  243. }
  244. fname = get_settings_fullpath()
  245. logging.debug("Saving settings to %s", fname)
  246. with open(fname, 'w') as stream:
  247. json.dump(settings, stream)
  248. return settings
  249. def restore_settings_export(properties):
  250. """Restore the settings (if settings file is found on disk)
  251. If not found thend default to paramgers defined in
  252. constants.EXPORT_OPTIONS
  253. :param properties:
  254. """
  255. settings = {}
  256. fname = get_settings_fullpath()
  257. if os.path.exists(fname) and os.access(fname, os.R_OK):
  258. logging.debug("Settings cache found %s", fname)
  259. with open(fname, 'r') as fs:
  260. settings = json.load(fs)
  261. else:
  262. logging.debug("No settings file found, using defaults.")
  263. ## Geometry {
  264. properties.option_vertices = settings.get(
  265. constants.VERTICES,
  266. constants.EXPORT_OPTIONS[constants.VERTICES])
  267. properties.option_faces = settings.get(
  268. constants.FACES,
  269. constants.EXPORT_OPTIONS[constants.FACES])
  270. properties.option_normals = settings.get(
  271. constants.NORMALS,
  272. constants.EXPORT_OPTIONS[constants.NORMALS])
  273. properties.option_skinning = settings.get(
  274. constants.SKINNING,
  275. constants.EXPORT_OPTIONS[constants.SKINNING])
  276. properties.option_bones = settings.get(
  277. constants.BONES,
  278. constants.EXPORT_OPTIONS[constants.BONES])
  279. properties.option_influences = settings.get(
  280. constants.INFLUENCES_PER_VERTEX,
  281. constants.EXPORT_OPTIONS[constants.INFLUENCES_PER_VERTEX])
  282. properties.option_geometry_type = settings.get(
  283. constants.GEOMETRY_TYPE,
  284. constants.EXPORT_OPTIONS[constants.GEOMETRY_TYPE])
  285. ## }
  286. ## Materials {
  287. properties.option_materials = settings.get(
  288. constants.MATERIALS,
  289. constants.EXPORT_OPTIONS[constants.MATERIALS])
  290. properties.option_uv_coords = settings.get(
  291. constants.UVS,
  292. constants.EXPORT_OPTIONS[constants.UVS])
  293. properties.option_face_materials = settings.get(
  294. constants.FACE_MATERIALS,
  295. constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
  296. properties.option_maps = settings.get(
  297. constants.MAPS,
  298. constants.EXPORT_OPTIONS[constants.MAPS])
  299. properties.option_colors = settings.get(
  300. constants.COLORS,
  301. constants.EXPORT_OPTIONS[constants.COLORS])
  302. properties.option_mix_colors = settings.get(
  303. constants.MIX_COLORS,
  304. constants.EXPORT_OPTIONS[constants.MIX_COLORS])
  305. ## }
  306. ## Settings {
  307. properties.option_scale = settings.get(
  308. constants.SCALE,
  309. constants.EXPORT_OPTIONS[constants.SCALE])
  310. properties.option_round_off = settings.get(
  311. constants.ENABLE_PRECISION,
  312. constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
  313. properties.option_round_value = settings.get(
  314. constants.PRECISION,
  315. constants.EXPORT_OPTIONS[constants.PRECISION])
  316. properties.option_logging = settings.get(
  317. constants.LOGGING,
  318. constants.EXPORT_OPTIONS[constants.LOGGING])
  319. properties.option_compression = settings.get(
  320. constants.COMPRESSION,
  321. constants.NONE)
  322. properties.option_indent = settings.get(
  323. constants.INDENT,
  324. constants.EXPORT_OPTIONS[constants.INDENT])
  325. properties.option_copy_textures = settings.get(
  326. constants.COPY_TEXTURES,
  327. constants.EXPORT_OPTIONS[constants.COPY_TEXTURES])
  328. properties.option_embed_animation = settings.get(
  329. constants.EMBED_ANIMATION,
  330. constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
  331. ## }
  332. ## Scene {
  333. properties.option_export_scene = settings.get(
  334. constants.SCENE,
  335. constants.EXPORT_OPTIONS[constants.SCENE])
  336. #properties.option_embed_geometry = settings.get(
  337. # constants.EMBED_GEOMETRY,
  338. # constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
  339. properties.option_lights = settings.get(
  340. constants.LIGHTS,
  341. constants.EXPORT_OPTIONS[constants.LIGHTS])
  342. properties.option_cameras = settings.get(
  343. constants.CAMERAS,
  344. constants.EXPORT_OPTIONS[constants.CAMERAS])
  345. ## }
  346. ## Animation {
  347. properties.option_animation_morph = settings.get(
  348. constants.MORPH_TARGETS,
  349. constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
  350. properties.option_animation_skeletal = settings.get(
  351. constants.ANIMATION,
  352. constants.EXPORT_OPTIONS[constants.ANIMATION])
  353. properties.option_frame_step = settings.get(
  354. constants.FRAME_STEP,
  355. constants.EXPORT_OPTIONS[constants.FRAME_STEP])
  356. properties.option_frame_index_as_time = settings.get(
  357. constants.FRAME_INDEX_AS_TIME,
  358. constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
  359. ## }
  360. def compression_types():
  361. """Supported compression formats
  362. :rtype: tuple
  363. """
  364. types = [(constants.NONE, constants.NONE, constants.NONE)]
  365. try:
  366. import msgpack
  367. types.append((constants.MSGPACK, constants.MSGPACK,
  368. constants.MSGPACK))
  369. except ImportError:
  370. pass
  371. return types
  372. def animation_options():
  373. """The supported skeletal animation types
  374. :returns: list of tuples
  375. """
  376. anim = [
  377. (constants.OFF, constants.OFF.title(), constants.OFF),
  378. (constants.POSE, constants.POSE.title(), constants.POSE),
  379. (constants.REST, constants.REST.title(), constants.REST)
  380. ]
  381. return anim
  382. class ExportThree(bpy.types.Operator, ExportHelper):
  383. """Class that handles the export properties"""
  384. bl_idname = 'export.three'
  385. bl_label = 'Export THREE'
  386. filename_ext = constants.EXTENSION
  387. option_vertices = BoolProperty(
  388. name="Vertices",
  389. description="Export vertices",
  390. default=constants.EXPORT_OPTIONS[constants.VERTICES])
  391. option_faces = BoolProperty(
  392. name="Faces",
  393. description="Export faces",
  394. default=constants.EXPORT_OPTIONS[constants.FACES])
  395. option_normals = BoolProperty(
  396. name="Normals",
  397. description="Export normals",
  398. default=constants.EXPORT_OPTIONS[constants.NORMALS])
  399. option_colors = BoolProperty(
  400. name="Vertex Colors",
  401. description="Export vertex colors",
  402. default=constants.EXPORT_OPTIONS[constants.COLORS])
  403. option_mix_colors = BoolProperty(
  404. name="Mix Colors",
  405. description="Mix material and vertex colors",
  406. default=constants.EXPORT_OPTIONS[constants.MIX_COLORS])
  407. option_uv_coords = BoolProperty(
  408. name="UVs",
  409. description="Export texture coordinates",
  410. default=constants.EXPORT_OPTIONS[constants.UVS])
  411. option_materials = BoolProperty(
  412. name="Materials",
  413. description="Export materials",
  414. default=constants.EXPORT_OPTIONS[constants.MATERIALS])
  415. option_face_materials = BoolProperty(
  416. name="Face Materials",
  417. description="Face mapping materials",
  418. default=constants.EXPORT_OPTIONS[constants.FACE_MATERIALS])
  419. option_maps = BoolProperty(
  420. name="Textures",
  421. description="Include texture maps",
  422. default=constants.EXPORT_OPTIONS[constants.MAPS])
  423. option_skinning = BoolProperty(
  424. name="Skinning",
  425. description="Export skin data",
  426. default=constants.EXPORT_OPTIONS[constants.SKINNING])
  427. option_bones = BoolProperty(
  428. name="Bones",
  429. description="Export bones",
  430. default=constants.EXPORT_OPTIONS[constants.BONES])
  431. option_scale = FloatProperty(
  432. name="Scale",
  433. description="Scale vertices",
  434. min=0.01,
  435. max=1000.0,
  436. soft_min=0.01,
  437. soft_max=1000.0,
  438. default=constants.EXPORT_OPTIONS[constants.SCALE])
  439. option_round_off = BoolProperty(
  440. name="Enable Precision",
  441. description="Round off floating point values",
  442. default=constants.EXPORT_OPTIONS[constants.ENABLE_PRECISION])
  443. option_round_value = IntProperty(
  444. name="Precision",
  445. min=0,
  446. max=16,
  447. description="Floating point precision",
  448. default=constants.EXPORT_OPTIONS[constants.PRECISION])
  449. logging_types = [
  450. (constants.DEBUG, constants.DEBUG, constants.DEBUG),
  451. (constants.INFO, constants.INFO, constants.INFO),
  452. (constants.WARNING, constants.WARNING, constants.WARNING),
  453. (constants.ERROR, constants.ERROR, constants.ERROR),
  454. (constants.CRITICAL, constants.CRITICAL, constants.CRITICAL)]
  455. option_logging = EnumProperty(
  456. name="",
  457. description="Logging verbosity level",
  458. items=logging_types,
  459. default=constants.DEBUG)
  460. option_geometry_type = EnumProperty(
  461. name="Type",
  462. description="Geometry type",
  463. items=_geometry_types()[1:],
  464. default=constants.GEOMETRY)
  465. option_export_scene = BoolProperty(
  466. name="Scene",
  467. description="Export scene",
  468. default=constants.EXPORT_OPTIONS[constants.SCENE])
  469. #@TODO: removing this option since the ObjectLoader doesn't have
  470. # support for handling external geometry data
  471. #option_embed_geometry = BoolProperty(
  472. # name="Embed geometry",
  473. # description="Embed geometry",
  474. # default=constants.EXPORT_OPTIONS[constants.EMBED_GEOMETRY])
  475. option_embed_animation = BoolProperty(
  476. name="Embed animation",
  477. description="Embed animation data with the geometry data",
  478. default=constants.EXPORT_OPTIONS[constants.EMBED_ANIMATION])
  479. option_copy_textures = BoolProperty(
  480. name="Copy textures",
  481. description="Copy textures",
  482. default=constants.EXPORT_OPTIONS[constants.COPY_TEXTURES])
  483. option_lights = BoolProperty(
  484. name="Lights",
  485. description="Export default scene lights",
  486. default=False)
  487. option_cameras = BoolProperty(
  488. name="Cameras",
  489. description="Export default scene cameras",
  490. default=False)
  491. option_animation_morph = BoolProperty(
  492. name="Morph animation",
  493. description="Export animation (morphs)",
  494. default=constants.EXPORT_OPTIONS[constants.MORPH_TARGETS])
  495. option_animation_skeletal = EnumProperty(
  496. name="",
  497. description="Export animation (skeletal)",
  498. items=animation_options(),
  499. default=constants.OFF)
  500. option_frame_index_as_time = BoolProperty(
  501. name="Frame index as time",
  502. description="Use (original) frame index as frame time",
  503. default=constants.EXPORT_OPTIONS[constants.FRAME_INDEX_AS_TIME])
  504. option_frame_step = IntProperty(
  505. name="Frame step",
  506. description="Animation frame step",
  507. min=1,
  508. max=1000,
  509. soft_min=1,
  510. soft_max=1000,
  511. default=1)
  512. option_indent = BoolProperty(
  513. name="Indent JSON",
  514. description="Disable this to reduce the file size",
  515. default=constants.EXPORT_OPTIONS[constants.INDENT])
  516. option_compression = EnumProperty(
  517. name="",
  518. description="Compression options",
  519. items=compression_types(),
  520. default=constants.NONE)
  521. option_influences = IntProperty(
  522. name="Influences",
  523. description="Maximum number of bone influences",
  524. min=1,
  525. max=4,
  526. default=2)
  527. def invoke(self, context, event):
  528. restore_settings_export(self.properties)
  529. return ExportHelper.invoke(self, context, event)
  530. @classmethod
  531. def poll(cls, context):
  532. """
  533. :param context:
  534. """
  535. return context.active_object is not None
  536. def execute(self, context):
  537. """
  538. :param context:
  539. """
  540. if not self.properties.filepath:
  541. raise Exception("filename not set")
  542. settings = save_settings_export(self.properties)
  543. filepath = self.filepath
  544. if settings[constants.COMPRESSION] == constants.MSGPACK:
  545. filepath = "%s%s" % (filepath[:-4], constants.PACK)
  546. from io_three import exporter
  547. if settings[constants.SCENE]:
  548. exporter.export_scene(filepath, settings)
  549. else:
  550. exporter.export_geometry(filepath, settings)
  551. return {'FINISHED'}
  552. def draw(self, context):
  553. """
  554. :param context:
  555. """
  556. layout = self.layout
  557. ## Geometry {
  558. row = layout.row()
  559. row.label(text="GEOMETRY:")
  560. row = layout.row()
  561. row.prop(self.properties, 'option_vertices')
  562. row.prop(self.properties, 'option_faces')
  563. row = layout.row()
  564. row.prop(self.properties, 'option_normals')
  565. row.prop(self.properties, 'option_uv_coords')
  566. row = layout.row()
  567. row.prop(self.properties, 'option_bones')
  568. row.prop(self.properties, 'option_skinning')
  569. row = layout.row()
  570. row.prop(self.properties, 'option_geometry_type')
  571. ## }
  572. layout.separator()
  573. ## Materials {
  574. row = layout.row()
  575. row.label(text="- Shading:")
  576. row = layout.row()
  577. row.prop(self.properties, 'option_face_materials')
  578. row = layout.row()
  579. row.prop(self.properties, 'option_colors')
  580. row = layout.row()
  581. row.prop(self.properties, 'option_mix_colors')
  582. ## }
  583. layout.separator()
  584. ## Animation {
  585. row = layout.row()
  586. row.label(text="- Animation:")
  587. row = layout.row()
  588. row.prop(self.properties, 'option_animation_morph')
  589. row = layout.row()
  590. row.label(text="Skeletal animations:")
  591. row = layout.row()
  592. row.prop(self.properties, 'option_animation_skeletal')
  593. layout.row()
  594. row = layout.row()
  595. row.prop(self.properties, 'option_influences')
  596. row = layout.row()
  597. row.prop(self.properties, 'option_frame_step')
  598. row = layout.row()
  599. row.prop(self.properties, 'option_frame_index_as_time')
  600. row = layout.row()
  601. row.prop(self.properties, 'option_embed_animation')
  602. ## }
  603. layout.separator()
  604. ## Scene {
  605. row = layout.row()
  606. row.label(text="SCENE:")
  607. row = layout.row()
  608. row.prop(self.properties, 'option_export_scene')
  609. row.prop(self.properties, 'option_materials')
  610. #row = layout.row()
  611. #row.prop(self.properties, 'option_embed_geometry')
  612. row = layout.row()
  613. row.prop(self.properties, 'option_lights')
  614. row.prop(self.properties, 'option_cameras')
  615. ## }
  616. layout.separator()
  617. ## Settings {
  618. row = layout.row()
  619. row.label(text="SETTINGS:")
  620. row = layout.row()
  621. row.prop(self.properties, 'option_maps')
  622. row = layout.row()
  623. row.prop(self.properties, 'option_copy_textures')
  624. row = layout.row()
  625. row.prop(self.properties, 'option_scale')
  626. layout.row()
  627. row = layout.row()
  628. row.prop(self.properties, 'option_round_off')
  629. row = layout.row()
  630. row.prop(self.properties, 'option_round_value')
  631. layout.row()
  632. row = layout.row()
  633. row.label(text="Logging verbosity:")
  634. row = layout.row()
  635. row.prop(self.properties, 'option_logging')
  636. row = layout.row()
  637. row.label(text="File compression format:")
  638. row = layout.row()
  639. row.prop(self.properties, 'option_compression')
  640. row = layout.row()
  641. row.prop(self.properties, 'option_indent')
  642. ## }
  643. def menu_func_export(self, context):
  644. """
  645. :param self:
  646. :param context:
  647. """
  648. default_path = bpy.data.filepath.replace('.blend', constants.EXTENSION)
  649. text = "Three.js (%s)" % constants.EXTENSION
  650. operator = self.layout.operator(ExportThree.bl_idname, text=text)
  651. operator.filepath = default_path
  652. def register():
  653. """Registers the addon (Blender boilerplate)"""
  654. bpy.utils.register_module(__name__)
  655. bpy.types.INFO_MT_file_export.append(menu_func_export)
  656. def unregister():
  657. """Unregisters the addon (Blender boilerplate)"""
  658. bpy.utils.unregister_module(__name__)
  659. bpy.types.INFO_MT_file_export.remove(menu_func_export)
  660. if __name__ == '__main__':
  661. register()