Fix for invalid break statement outside loop.
[blender-addons-contrib.git] / io_scene_fpx / fpx_ui.py
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
19 # <pep8 compliant>
20
21 ###############################################################################
22 #234567890123456789012345678901234567890123456789012345678901234567890123456789
23 #--------1---------2---------3---------4---------5---------6---------7---------
24
25
26 # ##### BEGIN COPYRIGHT BLOCK #####
27 #
28 # initial script copyright (c)2013 Alexander Nussbaumer
29 #
30 # ##### END COPYRIGHT BLOCK #####
31
32
33 #import python stuff
34
35
36 # import io_scene_fpx stuff
37 from io_scene_fpx.fpx_strings import (
38         fpx_str,
39         )
40 #from io_scene_fpx.fpx_spec import ()
41 from io_scene_fpx.fpx_utils import (
42         FpxUtilities,
43         )
44
45
46 #import blender stuff
47 from bpy.utils import (
48         register_class,
49         unregister_class,
50         )
51 from bpy_extras.io_utils import (
52         ImportHelper,
53         )
54 from bpy.props import (
55         BoolProperty,
56         CollectionProperty,
57         EnumProperty,
58         FloatProperty,
59         FloatVectorProperty,
60         IntProperty,
61         StringProperty,
62         PointerProperty,
63         )
64 from bpy.types import (
65         Operator,
66         PropertyGroup,
67         Panel,
68         Object,
69         UIList,
70         )
71 from bpy.app import (
72         debug,
73         )
74
75
76 from addon_utils import (
77         check,
78         )
79
80
81 class FpxUI:
82     VERBOSE_MODE_NONE = 'NONE'
83     VERBOSE_MODE_NORMAL = 'NORMAL'
84     VERBOSE_MODE_MAXIMAL = 'MAXIMAL'
85
86     VERBOSE_NONE = {}
87     VERBOSE_NORMAL = { VERBOSE_MODE_NORMAL, VERBOSE_MODE_MAXIMAL, }
88     VERBOSE_MAXIMAL = { VERBOSE_MODE_MAXIMAL, }
89
90     DEFAULT_VERBOSE = VERBOSE_MODE_NONE
91
92     ###########################################################################
93     PROP_DEFAULT_RESOLUTION_WIRE_BEVEL = 8
94     PROP_DEFAULT_RESOLUTION_WIRE = 8
95     PROP_DEFAULT_RESOLUTION_RUBBER_BEVEL = 8
96     PROP_DEFAULT_RESOLUTION_RUBBER = 8
97     PROP_DEFAULT_RESOLUTION_SHAPE = 8
98     PROP_DEFAULT_CONVERT_TO_MESH = True
99     PROP_DEFAULT_USE_HERMITE_HANDLE = True
100
101     ###########################################################################
102     ICON_OPTIONS = 'LAMP'
103     ICON_EXTERNAL_DATA = 'EXTERNAL_DATA'
104     ICON_ERROR = 'ERROR'
105     ICON_MODEL = "OBJECT_DATA"
106     ICON_TABLE = "IMPORT"
107
108     ###########################################################################
109     PROP_DEFAULT_VERBOSE = DEFAULT_VERBOSE
110
111     PROP_DEFAULT_SCENE = False
112     PROP_DEFAULT_ALL_MODELS = False
113     PROP_DEFAULT_MODEL_ADJUST_FPM = False
114     PROP_DEFAULT_MODEL_ADJUST_FPL = True
115     PROP_DEFAULT_MODEL_ADJUST_FPT = True
116     PROP_DEFAULT_NAME_EXTRA = None
117
118     PROP_DEFAULT_LIBRARIES_PATH = "C:\\Games\\Future Pinball\\Libraries"
119     PROP_DEFAULT_DMDFONTS_PATH = "C:\\Games\\Future Pinball\\DmdFonts"
120     PROP_DEFAULT_TABLES_PATH = "C:\\Games\\Future Pinball\\Tables"
121
122     USE_MODEL_FILTER_SECONDARY = 'SECONDARY'
123     USE_MODEL_FILTER_REFLECTION = 'REFLECTION'
124     USE_MODEL_FILTER_MASK = 'MASK'
125     USE_MODEL_FILTER_COLLISION = 'COLLISION'
126     #PROP_DEFAULT_USE_MODEL_FILTER = { USE_MODEL_FILTER_SECONDARY, USE_MODEL_FILTER_REFLECTION, USE_MODEL_FILTER_MASK, USE_MODEL_FILTER_COLLISION, }
127     PROP_DEFAULT_USE_MODEL_FILTER = { USE_MODEL_FILTER_MASK, }
128     #PROP_DEFAULT_USE_MODEL_FILTER = set()
129
130     USE_LIBRARY_FILTER_DMDFONT = 'DMDFONT'
131     USE_LIBRARY_FILTER_GRAPHIC = 'GRAPHIC'
132     USE_LIBRARY_FILTER_MODEL = 'MODEL'
133     USE_LIBRARY_FILTER_MUSIC = 'MUSIC'
134     USE_LIBRARY_FILTER_SCRIPT = 'SCRIPT'
135     USE_LIBRARY_FILTER_SOUND = 'SOUND'
136     #PROP_DEFAULT_USE_LIBRARY_FILTER = { USE_LIBRARY_FILTER_DMDFONT, USE_LIBRARY_FILTER_GRAPHIC, USE_LIBRARY_FILTER_MODEL, USE_LIBRARY_FILTER_MUSIC, USE_LIBRARY_FILTER_SCRIPT, USE_LIBRARY_FILTER_SOUND, }
137     PROP_DEFAULT_USE_LIBRARY_FILTER = { USE_LIBRARY_FILTER_MODEL, USE_LIBRARY_FILTER_GRAPHIC, }
138
139     PROP_DEFAULT_ALL_LIBRARIES = False
140
141     PROP_DEFAULT_KEEP_TEMP = False
142
143 def NotImplemented(layout):
144     box = layout.box()
145     box.label(fpx_str['LABEL_NAME_NOT_IMPLEMENTED'], icon='ERROR')
146     flow = box.column_flow()
147     flow.label(fpx_str['LABEL_NAME_NOT_IMPLEMENTED_1'])
148     flow.label(fpx_str['LABEL_NAME_NOT_IMPLEMENTED_2'])
149
150 ###############################################################################
151 class FptEmptyItemProperties(PropertyGroup):
152     prop = StringProperty(
153             default="",
154             #options={'HIDDEN', },
155             )
156     model = StringProperty(
157             default="",
158             #options={'HIDDEN', },
159             )
160
161 class FptEmptyProperties(PropertyGroup):
162     name = StringProperty(
163             name=fpx_str['PROP_NAME_EMPTY_PROP_NAME'],
164             description=fpx_str['PROP_DESC_EMPTY_PROP_NAME'],
165             default="",
166             #options={'HIDDEN', },
167             )
168
169     id = StringProperty(
170             name=fpx_str['PROP_NAME_EMPTY_PROP_ID'],
171             description=fpx_str['PROP_DESC_EMPTY_PROP_ID'],
172             default="",
173             #options={'HIDDEN', },
174             )
175
176     models = CollectionProperty(
177             type=FptEmptyItemProperties,
178             #options={'HIDDEN', },
179             )
180
181     selected_model_index = IntProperty(
182             default=-1,
183             min=-1,
184             options={'HIDDEN', 'SKIP_SAVE', },
185             )
186
187     def add_model(self, prop, model):
188         selected_model_index = len(self.models)
189         item = self.models.add()
190         item.prop = prop
191         item.model = model
192
193
194 class FptEmptyUILise(UIList):
195     def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
196         if self.layout_type in {'DEFAULT', 'COMPACT', }:
197             layout.label(text=item.model, icon_value=icon)
198         elif self.layout_type in {'GRID', }:
199             layout.alignment = 'CENTER'
200             layout.label(text="", icon_value=icon)
201
202 class FptEmptyPanel(Panel):
203     bl_label = fpx_str['LABEL_EMPTY_PANEL']
204     bl_space_type = 'PROPERTIES'
205     bl_region_type = 'WINDOW'
206     bl_context = 'data'
207
208     @classmethod
209     def poll(cls, blender_context):
210         return (blender_context
211                 and blender_context.object.type in {'EMPTY', }
212                 and blender_context.object.fpt is not None
213                 and blender_context.object.fpt.name
214                 )
215
216     def draw_header(self, blender_context):
217         layout = self.layout
218         layout.label(icon='PLUGIN')
219
220     def draw(self, blender_context):
221         import bpy
222         layout = self.layout
223         custom_data = blender_context.object.fpt
224
225         col = layout.column()
226         col.prop(custom_data, 'name', icon='SCENE_DATA', text="")
227         col.prop(custom_data, 'id', icon='OBJECT_DATA', text="")
228         col.template_list(
229                 listtype_name='FptEmptyUILise',
230                 dataptr=custom_data,
231                 propname='models',
232                 active_dataptr=custom_data,
233                 active_propname='selected_model_index',
234                 rows=2,
235                 type='DEFAULT',
236                 )
237         layout.enabled = False
238
239
240
241 ###############################################################################
242 class FpmImportOperator(Operator, ImportHelper):
243     """ Load a Future Pinball Model FPM File """
244     bl_idname = 'import_scene.fpm'
245     bl_label = fpx_str['BL_LABEL_IMPORTER_FPM']
246     bl_description = fpx_str['BL_DESCRIPTION_IMPORTER_FPM']
247     bl_options = {'PRESET', }
248     bl_space_type = 'PROPERTIES'
249     bl_region_type = 'WINDOW'
250
251     filepath = StringProperty(
252             subtype='FILE_PATH',
253             options={'HIDDEN', }
254             )
255
256
257     verbose = EnumProperty(
258             name=fpx_str['PROP_NAME_VERBOSE'],
259             description=fpx_str['PROP_DESC_VERBOSE'],
260             items=( (FpxUI.VERBOSE_MODE_NONE,
261                             fpx_str['ENUM_VERBOSE_NONE_1'],
262                             fpx_str['ENUM_VERBOSE_NONE_2'],
263                             ),
264                     (FpxUI.VERBOSE_MODE_NORMAL,
265                             fpx_str['ENUM_VERBOSE_NORMAL_1'],
266                             fpx_str['ENUM_VERBOSE_NORMAL_2'],
267                             ),
268                     (FpxUI.VERBOSE_MODE_MAXIMAL,
269                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_1'],
270                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_2'],
271                             ),
272                     ),
273             default=FpxUI.PROP_DEFAULT_VERBOSE,
274             )
275
276     keep_temp = BoolProperty(
277             name=fpx_str['PROP_NAME_KEEP_TEMP'],
278             description=fpx_str['PROP_DESC_KEEP_TEMP'],
279             default=FpxUI.PROP_DEFAULT_KEEP_TEMP,
280             )
281
282
283     use_all_models_of_folder = BoolProperty(
284             name=fpx_str['PROP_NAME_ALL_MODELS'],
285             description=fpx_str['PROP_DESC_ALL_MODELS'],
286             default=FpxUI.PROP_DEFAULT_ALL_MODELS,
287             )
288
289     use_scene_per_model = BoolProperty(
290             name=fpx_str['PROP_NAME_SCENE'],
291             description=fpx_str['PROP_DESC_SCENE'],
292             default=FpxUI.PROP_DEFAULT_SCENE,
293             )
294
295     name_extra = StringProperty(
296             #options={'HIDDEN', },
297             )
298
299
300     use_model_filter = EnumProperty(
301             name=fpx_str['PROP_NAME_USE_MODEL_FILTER'],
302             description=fpx_str['PROP_DESC_USE_MODEL_FILTER'],
303             items=(
304                     (FpxUI.USE_MODEL_FILTER_SECONDARY,
305                             fpx_str['PROP_NAME_MODEL_SECONDARY'],
306                             fpx_str['PROP_DESC_MODEL_SECONDARY'],
307                             'MESH_CUBE',
308                             1,
309                             ),
310                     (FpxUI.USE_MODEL_FILTER_REFLECTION,
311                             fpx_str['PROP_NAME_MODEL_REFLECTION'],
312                             fpx_str['PROP_DESC_MODEL_REFLECTION'],
313                             'MOD_MIRROR',
314                             2,
315                             ),
316                     (FpxUI.USE_MODEL_FILTER_MASK,
317                             fpx_str['PROP_NAME_MODEL_MASK'],
318                             fpx_str['PROP_DESC_MODEL_MASK'],
319                             'MOD_MASK',
320                             4,
321                             ),
322                     (FpxUI.USE_MODEL_FILTER_COLLISION,
323                             fpx_str['PROP_NAME_MODEL_COLLISION'],
324                             fpx_str['PROP_DESC_MODEL_COLLISION'],
325                             'MOD_PHYSICS',
326                             8,
327                             ),
328                     ),
329             default=FpxUI.PROP_DEFAULT_USE_MODEL_FILTER,
330             options={'ENUM_FLAG', },
331             )
332
333     use_model_adjustment = BoolProperty(
334             name=fpx_str['PROP_NAME_MODEL_ADJUST'],
335             description=fpx_str['PROP_DESC_MODEL_ADJUST'],
336             default=FpxUI.PROP_DEFAULT_MODEL_ADJUST_FPM,
337             )
338
339
340     filename_ext = fpx_str['FILE_EXT_FPM']
341
342     filter_glob = StringProperty(
343             default=fpx_str['FILE_FILTER_FPM'],
344             options={'HIDDEN', }
345             )
346
347     # check add-on dependency
348     @classmethod
349     def poll(cls, blender_context):
350         loaded_default, loaded_state = check("io_scene_ms3d")
351         return loaded_state
352
353     # draw the option panel
354     def draw(self, blender_context):
355         layout = self.layout
356
357         box = layout.box()
358         box.label(fpx_str['LABEL_NAME_OPTIONS'], icon=FpxUI.ICON_OPTIONS)
359         flow = box.column_flow()
360         flow.prop(self, 'verbose', icon='SPEAKER')
361         flow = box.column_flow()
362         flow.prop(self, 'keep_temp', icon='GHOST')
363         flow.prop(self, 'use_all_models_of_folder', icon='FILE_FOLDER')
364         flow.prop(self, 'use_scene_per_model', icon='SCENE_DATA')
365         flow.prop(self, 'name_extra', icon='TEXT', text="")
366
367         FpmImportOperator.draw_model_options(self, layout)
368
369     # entrypoint for FPM -> blender
370     def execute(self, blender_context):
371         """ start executing """
372
373         FpxUtilities.set_scene_to_default(blender_context.scene)
374
375         from io_scene_fpx.fpx_import import (FpmImporter, )
376         FpmImporter(
377                 report=self.report,
378                 verbose=self.verbose,
379                 keep_temp=self.keep_temp,
380                 use_all_models_of_folder=self.use_all_models_of_folder,
381                 use_scene_per_model=self.use_scene_per_model,
382                 name_extra=self.name_extra,
383                 use_model_filter=self.use_model_filter,
384                 use_model_adjustment=self.use_model_adjustment,
385                 ).read(
386                         blender_context,
387                         self.filepath,
388                         )
389
390         FpxUtilities.set_scene_to_metric(blender_context)
391
392         for scene in blender_context.blend_data.scenes:
393             scene.layers = (True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)
394             scene.update()
395
396         return {"FINISHED"}
397
398     def invoke(self, blender_context, event):
399         blender_context.window_manager.fileselect_add(self)
400         return {'RUNNING_MODAL', }
401
402     @staticmethod
403     def menu_func(cls, blender_context):
404         cls.layout.operator(
405                 FpmImportOperator.bl_idname,
406                 text=fpx_str['TEXT_OPERATOR_FPM'],
407                 )
408
409     @staticmethod
410     def draw_model_options(cls, layout):
411         box = layout.box()
412         box.label(fpx_str['LABEL_NAME_MODEL_OPTIONS'], icon=FpxUI.ICON_MODEL)
413         if FpxUI.USE_MODEL_FILTER_COLLISION in cls.use_model_filter:
414             NotImplemented(box)
415         flow = box.column_flow()
416         flow.prop(cls, 'use_model_filter', icon='FILTER')
417         flow = box.column_flow()
418         flow.prop(cls, 'use_model_adjustment', icon='MODIFIER')
419
420 ###############################################################################
421 class FplImportOperator(Operator, ImportHelper):
422     """ Load a Future Pinball Library FPL File """
423     bl_idname = 'import_scene.fpl'
424     bl_label = fpx_str['BL_LABEL_IMPORTER_FPL']
425     bl_description = fpx_str['BL_DESCRIPTION_IMPORTER_FPL']
426     bl_options = {'PRESET', }
427     bl_space_type = 'PROPERTIES'
428     bl_region_type = 'WINDOW'
429
430     filepath = StringProperty(
431             subtype='FILE_PATH',
432             options={'HIDDEN', }
433             )
434
435
436     verbose = EnumProperty(
437             name=fpx_str['PROP_NAME_VERBOSE'],
438             description=fpx_str['PROP_DESC_VERBOSE'],
439             items=( (FpxUI.VERBOSE_MODE_NONE,
440                             fpx_str['ENUM_VERBOSE_NONE_1'],
441                             fpx_str['ENUM_VERBOSE_NONE_2'],
442                             ),
443                     (FpxUI.VERBOSE_MODE_NORMAL,
444                             fpx_str['ENUM_VERBOSE_NORMAL_1'],
445                             fpx_str['ENUM_VERBOSE_NORMAL_2'],
446                             ),
447                     (FpxUI.VERBOSE_MODE_MAXIMAL,
448                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_1'],
449                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_2'],
450                             ),
451                     ),
452             default=FpxUI.PROP_DEFAULT_VERBOSE,
453             )
454
455     keep_temp = BoolProperty(
456             name=fpx_str['PROP_NAME_KEEP_TEMP'],
457             description=fpx_str['PROP_DESC_KEEP_TEMP'],
458             default=FpxUI.PROP_DEFAULT_KEEP_TEMP,
459             )
460
461
462     use_all_libraries_of_folder = BoolProperty(
463             name=fpx_str['PROP_NAME_ALL_LIBRARIES'],
464             description=fpx_str['PROP_DESC_ALL_LIBRARIES'],
465             default=FpxUI.PROP_DEFAULT_ALL_LIBRARIES,
466             )
467
468     use_library_filter = EnumProperty(
469             name=fpx_str['PROP_NAME_USE_LIBRARY_FILTER'],
470             description=fpx_str['PROP_DESC_USE_LIBRARY_FILTER'],
471             items=(
472                     (FpxUI.USE_LIBRARY_FILTER_MODEL,
473                             fpx_str['ENUM_USE_LIBRARY_FILTER_MODEL_1'],
474                             fpx_str['ENUM_USE_LIBRARY_FILTER_MODEL_2'],
475                             'FILE_BLEND',
476                             1,
477                             ),
478                     (FpxUI.USE_LIBRARY_FILTER_GRAPHIC,
479                             fpx_str['ENUM_USE_LIBRARY_FILTER_GRAPHIC_1'],
480                             fpx_str['ENUM_USE_LIBRARY_FILTER_GRAPHIC_2'],
481                             'FILE_IMAGE',
482                             2,
483                             ),
484                     (FpxUI.USE_LIBRARY_FILTER_DMDFONT,
485                             fpx_str['ENUM_USE_LIBRARY_FILTER_DMDFONT_1'],
486                             fpx_str['ENUM_USE_LIBRARY_FILTER_DMDFONT_2'],
487                             'FILE_FONT',
488                             4,
489                             ),
490                     (FpxUI.USE_LIBRARY_FILTER_SOUND,
491                             fpx_str['ENUM_USE_LIBRARY_FILTER_SOUND_1'],
492                             fpx_str['ENUM_USE_LIBRARY_FILTER_SOUND_2'],
493                             'FILE_SOUND',
494                             8,
495                             ),
496                     (FpxUI.USE_LIBRARY_FILTER_MUSIC,
497                             fpx_str['ENUM_USE_LIBRARY_FILTER_MUSIC_1'],
498                             fpx_str['ENUM_USE_LIBRARY_FILTER_MUSIC_2'],
499                             'FILE_MOVIE',
500                             16,
501                             ),
502                     (FpxUI.USE_LIBRARY_FILTER_SCRIPT,
503                             fpx_str['ENUM_USE_LIBRARY_FILTER_SCRIPT_1'],
504                             fpx_str['ENUM_USE_LIBRARY_FILTER_SCRIPT_2'],
505                             'FILE_SCRIPT',
506                             32,
507                             ),
508                     ),
509             default=FpxUI.PROP_DEFAULT_USE_LIBRARY_FILTER,
510             options={'ENUM_FLAG', },
511             )
512
513     use_model_filter = EnumProperty(
514             name=fpx_str['PROP_NAME_USE_MODEL_FILTER'],
515             description=fpx_str['PROP_DESC_USE_MODEL_FILTER'],
516             items=(
517                     (FpxUI.USE_MODEL_FILTER_SECONDARY,
518                             fpx_str['PROP_NAME_MODEL_SECONDARY'],
519                             fpx_str['PROP_DESC_MODEL_SECONDARY'],
520                             'MESH_CUBE',
521                             1,
522                             ),
523                     (FpxUI.USE_MODEL_FILTER_REFLECTION,
524                             fpx_str['PROP_NAME_MODEL_REFLECTION'],
525                             fpx_str['PROP_DESC_MODEL_REFLECTION'],
526                             'MOD_MIRROR',
527                             2,
528                             ),
529                     (FpxUI.USE_MODEL_FILTER_MASK,
530                             fpx_str['PROP_NAME_MODEL_MASK'],
531                             fpx_str['PROP_DESC_MODEL_MASK'],
532                             'MOD_MASK',
533                             4,
534                             ),
535                     (FpxUI.USE_MODEL_FILTER_COLLISION,
536                             fpx_str['PROP_NAME_MODEL_COLLISION'],
537                             fpx_str['PROP_DESC_MODEL_COLLISION'],
538                             'MOD_PHYSICS',
539                             8,
540                             ),
541                     ),
542             default=FpxUI.PROP_DEFAULT_USE_MODEL_FILTER,
543             options={'ENUM_FLAG', },
544             )
545
546     use_model_adjustment = BoolProperty(
547             name=fpx_str['PROP_NAME_MODEL_ADJUST'],
548             description=fpx_str['PROP_DESC_MODEL_ADJUST'],
549             default=FpxUI.PROP_DEFAULT_MODEL_ADJUST_FPL,
550             )
551
552
553     filename_ext = fpx_str['FILE_EXT_FPL']
554
555     filter_glob = StringProperty(
556             default=fpx_str['FILE_FILTER_FPL'],
557             options={'HIDDEN', }
558             )
559
560     # check add-on dependency
561     @classmethod
562     def poll(cls, blender_context):
563         loaded_default, loaded_state = check("io_scene_ms3d")
564         return loaded_state
565
566     # draw the option panel
567     def draw(self, blender_context):
568         layout = self.layout
569
570         box = layout.box()
571         box.label(fpx_str['LABEL_NAME_OPTIONS'], icon=FpxUI.ICON_OPTIONS)
572         flow = box.column_flow()
573         flow.prop(self, 'verbose', icon='SPEAKER')
574         flow = box.column_flow()
575         flow.prop(self, 'keep_temp', icon='GHOST')
576         flow.prop(self, 'use_all_libraries_of_folder', icon='FILE_FOLDER')
577
578         FplImportOperator.draw_library_options(self, layout)
579         FpmImportOperator.draw_model_options(self, layout)
580
581     # entrypoint for FPL -> blender
582     def execute(self, blender_context):
583         """ start executing """
584
585         FpxUtilities.set_scene_to_default(blender_context.scene)
586
587         from io_scene_fpx.fpx_import import (FplImporter, )
588         FplImporter(
589                 report=self.report,
590                 verbose=self.verbose,
591                 keep_temp=self.keep_temp,
592                 use_all_libraries_of_folder=self.use_all_libraries_of_folder,
593                 use_library_filter=self.use_library_filter,
594                 use_model_filter=self.use_model_filter,
595                 use_model_adjustment=self.use_model_adjustment,
596                 ).read(
597                         blender_context,
598                         self.filepath,
599                         )
600
601         FpxUtilities.set_scene_to_metric(blender_context)
602
603         for scene in blender_context.blend_data.scenes:
604             scene.layers = (True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)
605             scene.update()
606
607         return {"FINISHED"}
608
609     def invoke(self, blender_context, event):
610         blender_context.window_manager.fileselect_add(self)
611         return {'RUNNING_MODAL', }
612
613     @staticmethod
614     def menu_func(cls, blender_context):
615         cls.layout.operator(
616                 FplImportOperator.bl_idname,
617                 text=fpx_str['TEXT_OPERATOR_FPL'],
618                 )
619
620     @staticmethod
621     def draw_library_options(cls, layout):
622         box = layout.box()
623         box.label(fpx_str['LABEL_NAME_LIBRARYL_OPTIONS'], icon='IMPORT')
624         if FpxUI.USE_LIBRARY_FILTER_DMDFONT in cls.use_library_filter \
625                 or FpxUI.USE_LIBRARY_FILTER_SOUND in cls.use_library_filter \
626                 or FpxUI.USE_LIBRARY_FILTER_MUSIC in cls.use_library_filter \
627                 or FpxUI.USE_LIBRARY_FILTER_SCRIPT in cls.use_library_filter:
628             NotImplemented(box)
629         flow = box.column_flow()
630         flow.prop(cls, 'use_library_filter', icon='FILTER')
631
632
633 ###############################################################################
634 class FptImportOperator(Operator, ImportHelper):
635     """ Load a Future Pinball Table FPT File """
636     bl_idname = 'import_scene.fpt'
637     bl_label = fpx_str['BL_LABEL_IMPORTER_FPT']
638     bl_description = fpx_str['BL_DESCRIPTION_IMPORTER_FPT']
639     bl_options = {'PRESET', }
640     bl_space_type = 'PROPERTIES'
641     bl_region_type = 'WINDOW'
642
643     filepath = StringProperty(
644             subtype='FILE_PATH',
645             options={'HIDDEN', }
646             )
647
648
649     verbose = EnumProperty(
650             name=fpx_str['PROP_NAME_VERBOSE'],
651             description=fpx_str['PROP_DESC_VERBOSE'],
652             items=( (FpxUI.VERBOSE_MODE_NONE,
653                             fpx_str['ENUM_VERBOSE_NONE_1'],
654                             fpx_str['ENUM_VERBOSE_NONE_2'],
655                             ),
656                     (FpxUI.VERBOSE_MODE_NORMAL,
657                             fpx_str['ENUM_VERBOSE_NORMAL_1'],
658                             fpx_str['ENUM_VERBOSE_NORMAL_2'],
659                             ),
660                     (FpxUI.VERBOSE_MODE_MAXIMAL,
661                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_1'],
662                             fpx_str['ENUM_VERBOSE_MAXIMALIMAL_2'],
663                             ),
664                     ),
665             default=FpxUI.PROP_DEFAULT_VERBOSE,
666             )
667
668     keep_temp = BoolProperty(
669             name=fpx_str['PROP_NAME_KEEP_TEMP'],
670             description=fpx_str['PROP_DESC_KEEP_TEMP'],
671             default=FpxUI.PROP_DEFAULT_KEEP_TEMP,
672             )
673
674
675     path_libraries = StringProperty(
676             name=fpx_str['PROP_NAME_LIBRARIES_PATH'],
677             description=fpx_str['PROP_DESC_LIBRARIES_PATH'],
678             default=FpxUI.PROP_DEFAULT_LIBRARIES_PATH,
679             #subtype = 'DIR_PATH',
680             #options={'HIDDEN', },
681             )
682
683     path_dmdfonts = StringProperty(
684             name=fpx_str['PROP_NAME_DMDFONTS_PATH'],
685             description=fpx_str['PROP_DESC_DMDFONTS_PATH'],
686             default=FpxUI.PROP_DEFAULT_DMDFONTS_PATH,
687             #subtype = 'DIR_PATH',
688             #options={'HIDDEN', },
689             )
690
691     path_tables = StringProperty(
692             name=fpx_str['PROP_NAME_TABLES_PATH'],
693             description=fpx_str['PROP_DESC_TABLES_PATH'],
694             default=FpxUI.PROP_DEFAULT_TABLES_PATH,
695             #subtype = 'DIR_PATH',
696             #options={'HIDDEN', },
697             )
698
699
700     convert_to_mesh = BoolProperty(
701             name=fpx_str['PROP_NAME_CONVERT_TO_MESH'],
702             description=fpx_str['PROP_DESC_CONVERT_TO_MESH'],
703             default=FpxUI.PROP_DEFAULT_CONVERT_TO_MESH,
704             )
705
706     resolution_wire_bevel = IntProperty(
707             name=fpx_str['PROP_NAME_RESOLUTION_WIRE_BEVEL'],
708             description=fpx_str['PROP_DESC_RESOLUTION_WIRE_BEVEL'],
709             default=FpxUI.PROP_DEFAULT_RESOLUTION_WIRE_BEVEL,
710             min=2,
711             max=16,
712             )
713
714     resolution_wire = IntProperty(
715             name=fpx_str['PROP_NAME_RESOLUTION_WIRE'],
716             description=fpx_str['PROP_DESC_RESOLUTION_WIRE'],
717             default=FpxUI.PROP_DEFAULT_RESOLUTION_WIRE,
718             min=2,
719             max=16,
720             )
721
722     resolution_rubber_bevel = IntProperty(
723             name=fpx_str['PROP_NAME_RESOLUTION_RUBBER_BEVEL'],
724             description=fpx_str['PROP_DESC_RESOLUTION_RUBBER_BEVEL'],
725             default=FpxUI.PROP_DEFAULT_RESOLUTION_RUBBER_BEVEL,
726             min=2,
727             max=16,
728             )
729
730     resolution_rubber = IntProperty(
731             name=fpx_str['PROP_NAME_RESOLUTION_RUBBER'],
732             description=fpx_str['PROP_DESC_RESOLUTION_RUBBER'],
733             default=FpxUI.PROP_DEFAULT_RESOLUTION_RUBBER,
734             min=2,
735             max=16,
736             )
737
738     resolution_shape = IntProperty(
739             name=fpx_str['PROP_NAME_RESOLUTION_SHAPE'],
740             description=fpx_str['PROP_DESC_RESOLUTION_SHAPE'],
741             default=FpxUI.PROP_DEFAULT_RESOLUTION_SHAPE,
742             min=2,
743             max=16,
744             )
745
746     use_hermite_handle = BoolProperty(
747             name=fpx_str['PROP_NAME_USE_HERMITE_HANDLE'],
748             description=fpx_str['PROP_DESC_USE_HERMITE_HANDLE'],
749             default=FpxUI.PROP_DEFAULT_USE_HERMITE_HANDLE,
750             )
751
752
753     use_library_filter = EnumProperty(
754             name=fpx_str['PROP_NAME_USE_LIBRARY_FILTER'],
755             description=fpx_str['PROP_DESC_USE_LIBRARY_FILTER'],
756             items=(
757                     (FpxUI.USE_LIBRARY_FILTER_MODEL,
758                             fpx_str['ENUM_USE_LIBRARY_FILTER_MODEL_1'],
759                             fpx_str['ENUM_USE_LIBRARY_FILTER_MODEL_2'],
760                             'FILE_BLEND',
761                             1,
762                             ),
763                     (FpxUI.USE_LIBRARY_FILTER_GRAPHIC,
764                             fpx_str['ENUM_USE_LIBRARY_FILTER_GRAPHIC_1'],
765                             fpx_str['ENUM_USE_LIBRARY_FILTER_GRAPHIC_2'],
766                             'FILE_IMAGE',
767                             2,
768                             ),
769                     (FpxUI.USE_LIBRARY_FILTER_DMDFONT,
770                             fpx_str['ENUM_USE_LIBRARY_FILTER_DMDFONT_1'],
771                             fpx_str['ENUM_USE_LIBRARY_FILTER_DMDFONT_2'],
772                             'FILE_FONT',
773                             4,
774                             ),
775                     (FpxUI.USE_LIBRARY_FILTER_SOUND,
776                             fpx_str['ENUM_USE_LIBRARY_FILTER_SOUND_1'],
777                             fpx_str['ENUM_USE_LIBRARY_FILTER_SOUND_2'],
778                             'FILE_SOUND',
779                             8,
780                             ),
781                     (FpxUI.USE_LIBRARY_FILTER_MUSIC,
782                             fpx_str['ENUM_USE_LIBRARY_FILTER_MUSIC_1'],
783                             fpx_str['ENUM_USE_LIBRARY_FILTER_MUSIC_2'],
784                             'FILE_MOVIE',
785                             16,
786                             ),
787                     (FpxUI.USE_LIBRARY_FILTER_SCRIPT,
788                             fpx_str['ENUM_USE_LIBRARY_FILTER_SCRIPT_1'],
789                             fpx_str['ENUM_USE_LIBRARY_FILTER_SCRIPT_2'],
790                             'FILE_SCRIPT',
791                             32,
792                             ),
793                     ),
794             default=FpxUI.PROP_DEFAULT_USE_LIBRARY_FILTER,
795             options={'ENUM_FLAG', },
796             )
797
798     use_model_filter = EnumProperty(
799             name=fpx_str['PROP_NAME_USE_MODEL_FILTER'],
800             description=fpx_str['PROP_DESC_USE_MODEL_FILTER'],
801             items=(
802                     (FpxUI.USE_MODEL_FILTER_SECONDARY,
803                             fpx_str['PROP_NAME_MODEL_SECONDARY'],
804                             fpx_str['PROP_DESC_MODEL_SECONDARY'],
805                             'MESH_CUBE',
806                             1,
807                             ),
808                     (FpxUI.USE_MODEL_FILTER_REFLECTION,
809                             fpx_str['PROP_NAME_MODEL_REFLECTION'],
810                             fpx_str['PROP_DESC_MODEL_REFLECTION'],
811                             'MOD_MIRROR',
812                             2,
813                             ),
814                     (FpxUI.USE_MODEL_FILTER_MASK,
815                             fpx_str['PROP_NAME_MODEL_MASK'],
816                             fpx_str['PROP_DESC_MODEL_MASK'],
817                             'MOD_MASK',
818                             4,
819                             ),
820                     (FpxUI.USE_MODEL_FILTER_COLLISION,
821                             fpx_str['PROP_NAME_MODEL_COLLISION'],
822                             fpx_str['PROP_DESC_MODEL_COLLISION'],
823                             'MOD_PHYSICS',
824                             8,
825                             ),
826                     ),
827             default=FpxUI.PROP_DEFAULT_USE_MODEL_FILTER,
828             options={'ENUM_FLAG', },
829             )
830
831     use_model_adjustment = BoolProperty(
832             name=fpx_str['PROP_NAME_MODEL_ADJUST'],
833             description=fpx_str['PROP_DESC_MODEL_ADJUST'],
834             default=FpxUI.PROP_DEFAULT_MODEL_ADJUST_FPT,
835             )
836
837
838     filename_ext = fpx_str['FILE_EXT_FPT']
839
840     filter_glob = StringProperty(
841             default=fpx_str['FILE_FILTER_FPT'],
842             options={'HIDDEN', }
843             )
844
845     # check add-on dependency
846     @classmethod
847     def poll(cls, blender_context):
848         loaded_default, loaded_state = check("io_scene_ms3d")
849         return loaded_state
850
851     # draw the option panel
852     def draw(self, blender_context):
853         layout = self.layout
854
855         box = layout.box()
856         box.label(fpx_str['LABEL_NAME_OPTIONS'], icon=FpxUI.ICON_OPTIONS)
857         flow = box.column_flow()
858         flow.prop(self, 'verbose', icon='SPEAKER')
859         flow = box.column_flow()
860         flow.prop(self, 'keep_temp', icon='GHOST')
861
862         box.label(fpx_str['LABEL_NAME_EXTERNAL_DATA'], icon=FpxUI.ICON_EXTERNAL_DATA)
863         flow = box.column_flow()
864         flow.prop(self, 'path_libraries', icon='FILESEL', text="")
865         flow.prop(self, 'path_dmdfonts', icon='IMASEL', text="")
866         flow.prop(self, 'path_tables', icon='FILE_FOLDER', text="")
867
868         box = layout.box()
869         box.label(fpx_str['LABEL_NAME_TABLE_OPTIONS'], icon=FpxUI.ICON_MODEL)
870         #if self.convert_to_mesh:
871         #    NotImplemented(box)
872         flow = box.column_flow()
873         flow.prop(self, 'convert_to_mesh', icon='MOD_TRIANGULATE')
874         flow = box.column_flow()
875         flow.prop(self, 'resolution_wire_bevel', icon='MOD_REMESH')
876         flow.prop(self, 'resolution_wire', icon='MOD_REMESH')
877         flow.prop(self, 'resolution_rubber_bevel', icon='MOD_REMESH')
878         flow.prop(self, 'resolution_rubber', icon='MOD_REMESH')
879         flow.prop(self, 'resolution_shape', icon='MOD_REMESH')
880         flow = box.column_flow()
881         flow.prop(self, 'use_hermite_handle', icon='CURVE_BEZCURVE')
882
883         FplImportOperator.draw_library_options(self, layout)
884         FpmImportOperator.draw_model_options(self, layout)
885
886     # entrypoint for FPT -> blender
887     def execute(self, blender_context):
888         """ start executing """
889
890         FpxUtilities.set_scene_to_default(blender_context.scene)
891
892         from io_scene_fpx.fpx_import import (FptImporter, )
893         FptImporter(
894                 report = self.report,
895                 verbose = self.verbose,
896                 keep_temp = self.keep_temp,
897                 path_libraries = self.path_libraries,
898                 convert_to_mesh = self.convert_to_mesh,
899                 resolution_wire_bevel = self.resolution_wire_bevel,
900                 resolution_wire = self.resolution_wire,
901                 resolution_rubber_bevel = self.resolution_rubber_bevel,
902                 resolution_rubber = self.resolution_rubber,
903                 resolution_shape = self.resolution_shape,
904                 use_hermite_handle = self.use_hermite_handle,
905                 use_library_filter = self.use_library_filter,
906                 use_model_filter = self.use_model_filter,
907                 use_model_adjustment = self.use_model_adjustment,
908                 ).read(
909                         blender_context,
910                         self.filepath,
911                         )
912
913         FpxUtilities.set_scene_to_metric(blender_context)
914
915         for scene in blender_context.blend_data.scenes:
916             scene.layers = (True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False)
917             scene.update()
918
919         return {"FINISHED"}
920
921     def invoke(self, blender_context, event):
922         blender_context.window_manager.fileselect_add(self)
923         return {'RUNNING_MODAL', }
924
925     @staticmethod
926     def menu_func(cls, blender_context):
927         cls.layout.operator(
928                 FptImportOperator.bl_idname,
929                 text=fpx_str['TEXT_OPERATOR_FPT'],
930                 )
931
932
933 ###############################################################################
934 class FpxSetSceneToMetricOperator(Operator):
935     """ . """
936     bl_idname = 'io_scene_fpx.set_scene_to_metric'
937     bl_label = fpx_str['BL_LABEL_SET_SCENE_TO_METRIC']
938     bl_description = fpx_str['BL_DESC_SET_SCENE_TO_METRIC']
939
940
941     #
942     @classmethod
943     def poll(cls, blender_context):
944         return True
945
946     # entrypoint for option
947     def execute(self, blender_context):
948         return self.set_scene_to_metric(blender_context)
949
950     # entrypoint for option via UI
951     def invoke(self, blender_context, event):
952         return blender_context.window_manager.invoke_props_dialog(self)
953
954
955     ###########################################################################
956     def set_scene_to_metric(self, blender_context):
957         FpxUtilities.set_scene_to_metric(blender_context)
958         return {"FINISHED"}
959
960
961 ###############################################################################
962 def register():
963     register_class(FpxSetSceneToMetricOperator)
964     register_class(FptEmptyItemProperties)
965     register_class(FptEmptyProperties)
966     inject_properties()
967
968 def unregister():
969     delete_properties()
970     unregister_class(FptEmptyProperties)
971     unregister_class(FptEmptyItemProperties)
972     unregister_class(FpxSetSceneToMetricOperator)
973
974 def inject_properties():
975     Object.fpt = PointerProperty(type=FptEmptyProperties)
976
977 def delete_properties():
978     del Object.fpt
979
980 ###############################################################################
981
982
983 ###############################################################################
984 #234567890123456789012345678901234567890123456789012345678901234567890123456789
985 #--------1---------2---------3---------4---------5---------6---------7---------
986 # ##### END OF FILE #####