1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
2# Copyright (C) 2016-2019 German Aerospace Center (DLR) and others.
3# SUMOPy module
4# Copyright (C) 2012-2017 University of Bologna - DICAM
5# This program and the accompanying materials
6# are made available under the terms of the Eclipse Public License v2.0
7# which accompanies this distribution, and is available at
8# http://www.eclipse.org/legal/epl-v20.html
9# SPDX-License-Identifier: EPL-2.0
10
11# @file    test_classman_classes.py
12# @author  Joerg Schweizer
13# @date
14# @version $Id$
15
16"""
17Test for callsman
18Provides test classes and some test functions for plugin.
19"""
20
21from classman import *
22from arrayman import *
23import xmlman as xm
24
25
26def on_event_delattr(attrconfig):
27    print 'EVENT: Attribute', attrconfig.attrname, 'will be deleted!!'
28
29
30def on_event_setattr(attrconfig):
31    print 'EVENT: Attribute', attrconfig.attrname, 'has been set to a new value', attrconfig.format_value()
32
33
34def on_event_getattr(attrconfig):
35    print 'EVENT: Attribute', attrconfig.attrname, 'has been retrieved the value', attrconfig.format_value()
36
37
38def on_event_additem(attrconfig, keys):
39    print 'EVENT: Attribute', attrconfig.attrname, ':added keys:', keys
40
41
42def on_event_delitem(attrconfig, keys):
43    print 'EVENT: Attribute', attrconfig.attrname, ':delete keys:', keys
44
45
46def on_event_setitem(attrconfig, keys):
47    print 'EVENT: Attribute', attrconfig.attrname, ':set keys:', keys
48
49
50def on_event_getitem(attrconfig, keys):
51    print 'EVENT: Attribute', attrconfig.attrname, ':get keys:', keys
52
53
54class Segments(ArrayObjman):
55
56    def __init__(self, ident='segments',  parent=None,  **kwargs):
57
58        self._init_objman(ident, parent=parent, xmltag=('segments', 'segment', 'ids_ref'), **kwargs)
59
60        self.add_col(ArrayConf('ids_ref', '',
61                               dtype='object',
62                               perm='r',
63                               is_index=True,
64                               name='ID Ref',
65                               info='Ref ID',
66                               xmltag='id_ref',
67                               ))
68
69        self.add_col(ArrayConf('vertices',  np.zeros((2, 3), float),
70                               groupnames=['internal'],
71                               perm='rw',
72                               name='Vertex',
73                               is_save=True,
74                               info='Vertex coordinate vectors of points. with format [[[x11,y11,z11],[x12,y12,z12]],[[x21,y21,z21],[x22,y22,z122]],...]',
75                               xmltag='vertex',
76                               ))
77
78        self.add_col(IdsArrayConf('ids_parent', parent,
79                                  groupnames=['state'],
80                                  is_save=True,
81                                  name='ID '+parent.get_ident(),
82                                  info='ID of '+parent.get_name()+' object.',
83                                  xmltag='id_poly',
84                                  ))
85
86
87class Polylines (ArrayObjman):
88    def __init__(self, ident='polyline',  parent=None, name='Polyline',
89                 info='Polyline [ segid11, segid12,...]', **kwargs):
90        self._init_objman(ident, parent=parent, xmltag=('polylines', 'polyline', 'ids_osm'), **kwargs)
91        # print '__init__',self.get_name(),self.format_ident()
92
93        self.add_col(ArrayConf('ids_osm', '',
94                               dtype='object',
95                               perm='r',
96                               is_index=True,
97                               name='ID OSM',
98                               info='Edge ID of OSM',
99                               xmltag='id_osm',
100                               ))
101
102        # initialize line segments
103        segments = Segments(parent=self)
104        self.add(ObjConf(segments, groupnames=['drawobjects']))
105
106        # print '   segments',segments
107        # print '   self.segments',self.segments,type(self.segments)
108        # create table with id lists to  segments
109        self.add_col(IdlistsArrayConf('ids_segments', segments,
110                                      groupnames=['elements'],
111                                      is_save=True,
112                                      name='IDs Segs',
113                                      info='List with IDs to Line segments.',
114                                      xmltag='segments',
115                                      ))
116
117    def draw(self, pointvertices, id_osm):
118        """
119        pointvertices = [
120                [0.0,0.0,0.0],
121                [0.2,0.0,0.0],
122                ]
123        """
124        vertices = []
125        print 'draw', self.ident
126        for i in xrange(1, len(pointvertices)):
127            vertices.append([pointvertices[i-1], pointvertices[i]])
128        n_vert = len(vertices)
129        _id = self.add_row(ids_osm=id_osm)
130        cod = []
131        #import string
132        clist = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'], np.object)
133        print '  ', len(vertices), clist[:len(vertices)]
134        ids = self.segments.value.suggest_ids(len(vertices))
135        ids_segs = self.segments.value.add_rows(ids=ids, vertices=vertices, ids_parent=n_vert*[_id], ids_ref=clist[ids])
136        self.ids_segments[_id] = list(ids_segs)  # put here list, otherwise numpy thinks it is a numeric array
137        return _id
138
139
140class Lines(ArrayObjman):
141
142    def __init__(self, ident,  parent=None,  **kwargs):
143
144        self._init_objman(ident, parent=parent, **kwargs)
145
146        self.add_col(ArrayConf('vertices',  np.zeros((2, 3), float),
147                               groupnames=['internal'],
148                               perm='rw',
149                               name='Vertex',
150                               is_save=True,
151                               info='Vertex coordinate vectors of points. with format [[[x11,y11,z11],[x12,y12,z12]],[[x21,y21,z21],[x22,y22,z122]],...]',
152                               ))
153
154        self.add_col(ArrayConf('ids_sumo', '',
155                               dtype='object',
156                               perm='r',
157                               is_index=True,
158                               name='ID SUMO',
159                               info='Edge ID of SUMO network',
160                               ))
161
162
163class Selection(ArrayObjman):
164    def __init__(self, ident,  parent=None,  **kwargs):
165        self._init_objman(ident, parent=parent, **kwargs)
166        self.add_col(TabIdsArrayConf('obj_ids',
167                                     name='Object[id]',
168                                     info='Draw obj and ids',
169                                     ))
170
171
172class Collection(ArrayObjman):
173    def __init__(self, ident,  parent=None,  **kwargs):
174        self._init_objman(ident, parent=parent, **kwargs)
175        self.add_col(TabIdListArrayConf('tab_id_lists',
176                                        name='[Tab1[id1],Tab2[id1],...]',
177                                        info='Collection of different items from different tables.',
178                                        ))
179
180
181class TestClass(BaseObjman):
182    def __init__(self, ident='testobj',  parent=None, name='Test Object'):
183        self._init_objman(ident, parent=parent, name=name, xmltag=ident)
184        attrsman = self.set_attrsman(Attrsman(self))
185
186        self.netfilepath = attrsman.add(AttrConf('netfilepath', 'pathtofile',
187                                                 groupnames=['state'],
188                                                 perm='rw',
189                                                 is_save=True,
190                                                 name='Network file',
191                                                 metatype='filepath',
192                                                 info='Network file path',
193                                                 xmltag='netfilepath',
194                                                 ))
195
196        self.workdirpath = attrsman.add(AttrConf('workdirpath', 'pathtodir',
197                                                 groupnames=['state'],
198                                                 perm='rw',
199                                                 is_save=True,
200                                                 name='Workdir',
201                                                 metatype='dirpath',
202                                                 info='Working directory.',
203                                                 xmltag='workdirpath',
204                                                 ))
205
206        self.access = attrsman.add(AttrConf('access', ['bus', 'bike', 'tram'],
207                                            groupnames=['state'],
208                                            perm='rw',
209                                            is_save=True,
210                                            name='Access list',
211                                            info='List with vehicle classes that have access',
212                                            xmltag='access',
213                                            ))
214
215        self.allowed = attrsman.add(AttrConf('allowed', 0, choices={'bus': 0, 'bike': 1, 'tram': 2},
216                                             groupnames=['state'],
217                                             perm='rw',
218                                             is_save=True,
219                                             name='Access list',
220                                             info='List with vehicle classes that have access',
221                                             xmltag='allowed',
222                                             ))
223
224        self.emissiontype = attrsman.add(AttrConf('emissiontype', 'Euro 0',
225                                                  groupnames=['state'],
226                                                  perm='rw',
227                                                  is_save=True,
228                                                  name='Emission type',
229                                                  info='Emission type of vehicle',
230                                                  xmltag='emissiontype',
231                                                  ))
232
233        self.x = attrsman.add(NumConf('x', 1.0,
234                                      digits_integer=None, digits_fraction=4,
235                                      minval=0.0, maxval=None,
236                                      groupnames=['state'],
237                                      perm='rw',
238                                      is_save=True,
239                                      unit='m',
240                                      is_plugin=True,
241                                      name='position',
242                                      info='Test object x position',
243                                      xmltag='x',
244                                      ))
245
246        self.x_thresh = attrsman.add(NumConf('x_thresh', 0.0,
247                                             digits_integer=None, digits_fraction=4,
248                                             minval=0.0, maxval=None,
249                                             groupnames=['state'],
250                                             perm='rw',
251                                             is_save=True,
252                                             unit='m',
253                                             is_plugin=True,
254                                             name='position threshold',
255                                             info='Test object x position threshold',
256                                             xmltag='x_thesh',
257                                             ))
258
259        self.is_pos_ok = attrsman.add(FuncConf('is_pos_ok', 'on_is_pos_ok', False,
260                                               groupnames=['state'],
261                                               name='Pos OK',
262                                               info='True if position greater than thhreshold.',
263                                               ))
264
265        attrsman.print_attrs()
266
267    def on_is_pos_ok(self):
268        """
269        True if position greater than thhreshold.
270        """
271        print 'on_is_pos_ok', self.x > self.x_thresh
272        return self.x > self.x_thresh
273
274
275class TestClass3(BaseObjman):
276    def __init__(self, ident='testobj3',  parent=None, name='Test Object3'):
277        self._init_objman(ident=ident,  parent=parent, name=name, xmltag='testobj3')
278        attrsman = self.set_attrsman(Attrsman(self))
279
280        self.child1 = attrsman.add(ObjConf(parent.child1, is_child=False))
281
282        self.y = attrsman.add(AttrConf('y', 0.0,
283                                       groupnames=['state'],
284                                       perm='r',
285                                       is_save=True,
286                                       unit='m',
287                                       metatype='length',
288                                       is_plugin=True,
289                                       name='position',
290                                       info='Test object  y position',
291                                       ))
292
293
294class TestClass2(BaseObjman):
295    def __init__(self, ident='testobj2',  parent=None, name='Test Object2', xmltag='testobj2'):
296        self._init_objman(ident, parent=parent, name=name, xmltag=xmltag)
297        attrsman = self.set_attrsman(Attrsman(self))
298
299        self.child1 = attrsman.add(ObjConf(TestClass('child1', self))
300                                   )
301
302        print 'TestClass2.child1', self.child1
303
304        self.child3 = attrsman.add(ObjConf(TestClass3('child3', self))
305                                   )
306
307
308class TestTabman(BaseObjman):
309    def __init__(self, ident='test_tabman',  parent=None, name='Test Table manage'):
310        self._init_objman(ident, parent=parent, name=name)
311        tm = Tabman(obj=self)
312        self.set_attrsman(tm)
313        self.surname = attrsman.add_col(ColConf('surname', 'xx',
314                                                groupnames=['state'],
315                                                perm='rw',
316                                                is_save=True,
317                                                name='Family name',
318                                                info='Name of Family',
319                                                ))
320
321        self.streetname = attrsman.add_col(ColConf('streetname', 'via della...',
322                                                   groupnames=['state'],
323                                                   perm='rw',
324                                                   is_save=False,
325                                                   name='Street name',
326                                                   info='Name of the street',
327                                                   ))
328
329        #_id = attrsman.suggest_id()
330        # print '_id =',_id
331        # self.attrman.add(_id)
332
333        # print 'self.streetname',self.streetname,type(self.streetname)
334        # self.streetname[1]='yyy'
335        # print 'self.streetname',self.streetname,type(self.streetname)
336        attrsman.add_rows(5)
337        attrsman.streetname[3] = 'ssss'
338        attrsman.streetname[[1, 2]] = ['aa', 55]
339        print 'test get', attrsman.streetname[[1, 2]]
340        # self.streetname[1]+='zzz'
341        attrsman.del_rows([1, 3])
342        attrsman.del_row(5)
343        # attrsman.delete('streetname')
344
345
346class TestTableObjMan(TableObjman):
347    def __init__(self, ident='test_tableobjman_simple',  parent=None, name='Test Table Object Manager'):
348        self._init_objman(ident, parent=parent, name=name, xmltag=('testtab', 'row', None))
349
350        # ATTENTION!!
351        # do not use x = self.add(...) or self.add_col(...)
352        # This would overwrite the configuration with the value
353        # because  the attribute is the configuration, which is set by Attrman
354        # While the add method is returning the value
355        self.add(AttrConf('x', 0.0,
356                          groupnames=['state'],
357                          perm='r',
358                          is_save=True,
359                          unit='m',
360                          metatype='length',
361                          is_plugin=False,
362                          name='position',
363                          info='Test object x position',
364                          xmltag='pos',
365                          ))
366
367        self.add(AttrConf('is_pos_ok', False,
368                          groupnames=['state'],
369                          perm='rw',
370                          is_save=True,
371                          name='Pos OK',
372                          info='True if position is OK',
373                          xmltag='pos_ok',
374                          ))
375
376        self.add_col(ColConf('surname', 'xx',
377                             groupnames=['state'],
378                             perm='r',
379                             is_save=True,
380                             name='Family name',
381                             info='Name of Family',
382                             xmltag='surname',
383                             ))
384
385        self.add_col(ColConf('streetname', 'via della...',
386                             groupnames=['state'],
387                             perm='rw',
388                             is_save=True,
389                             name='Street name',
390                             info='Name of the street',
391                             xmltag='streetname',
392                             ))
393
394        fruits = ['allpes', 'bananas', 'oranges']
395        self.add_col(ColConf('fruits', fruits[0],
396                             groupnames=['state'],
397                             choices=fruits,
398                             perm='rw',
399                             is_save=False,
400                             name='Fruits',
401                             info='Choose a fruit.',
402                             ))
403
404        self.add_col(NumcolConf('distances', 0.0,
405                                digits_integer=None, digits_fraction=4,
406                                minval=0.0, maxval=None,
407                                groupnames=['state'],
408                                perm='rw',
409                                is_save=True,
410                                name='Distance',
411                                unit='m',
412                                info='Distance of the street',
413                                xmltag='distances',
414                                ))
415
416        self.add(FuncConf('new_row', 'on_new_row', None,
417                          groupnames=['rowfunctions', '_private'],
418                          name='New row',
419                          info='Add a new row.',
420                          ))
421        self.add(FuncConf('delete_row', 'on_del_row', None,
422                          groupnames=['rowfunctions', '_private'],
423                          name='Del row',
424                          #info = 'Delete a row.',
425                          ))
426
427        #_id = attrsman.suggest_id()
428        # print '_id =',_id
429        # self.attrman.add(_id)
430
431        # print 'self.streetname',self.streetname,type(self.streetname)
432        # self.streetname[1]='yyy'
433        # print 'self.streetname',self.streetname,type(self.streetname)
434        self.add_rows(5)
435        self.streetname[3] = 'ssss'
436        self.surname[[1, 2, 3, 4]] = ['a', 'bb', 'ccc', 'dddd']
437        self.streetname[[1, 2]] = ['vv', 'dd']
438        # print '\n\ntest get',self.streetname[[1,2,3]]
439        # self.streetname[1]+='zzz'
440        # self.del_rows([1,3])
441        # self.del_row(5)
442        # self.delete('streetname')
443        # self.delete('is_pos_ok')
444        # print 'dir',dir(self)
445
446    def on_new_row(self, ids):
447        """
448        True if position greater than thhreshold.
449        """
450        self.add_row()
451
452    def on_del_row(self, id_row):
453        """
454        True if position greater than thhreshold.
455        """
456        print 'on_del_row', id_row
457        self.del_row(id_row)
458        print '  ids after del', self.get_ids()
459
460
461class TestTableObjManNocols(TableObjman):
462    """
463    Table manager without columns...for test purposes
464    """
465
466    def __init__(self, ident='test_tableobjman_simple_nocols',  parent=None, name='Test Table Object Manager'):
467        self._init_objman(ident, parent=parent, name=name)
468
469        # ATTENTION!!
470        # do not use x = self.add(...) or c=self.add_col(...)
471        # This would overwrite the configuration with the value
472        # because  the attribute is the configuration, which is set by Attrman
473        # While the add method is returning the value
474        self.add(AttrConf('x', 0.0,
475                          groupnames=['state'],
476                          perm='r',
477                          is_save=True,
478                          unit='m',
479                          metatype='length',
480                          is_plugin=False,
481                          name='position',
482                          info='Test object x position',
483                          ))
484
485        self.add(AttrConf('is_pos_ok', False,
486                          groupnames=['state'],
487                          perm='rw',
488                          is_save=True,
489                          name='Pos OK',
490                          info='True if position is OK',
491                          ))
492
493
494class ZonesTab(ArrayObjman):
495    def __init__(self, ident,  parent=None, **kwargs):
496        self._init_objman(ident, parent=parent, **kwargs)
497
498        self.add_col(ColConf('zonetypes', 0,
499                             choices={
500                                 "priority": 0,
501                                 "traffic_light": 1,
502                                 "right_before_left": 2,
503                                 "unregulated": 3,
504                                 "priority_stop": 4,
505                                 "traffic_light_unregulated": 5,
506                                 "allway_stop": 6,
507                                 "rail_signal": 7,
508                                 "zipper": 8,
509                                 "traffic_light_right_on_red": 9,
510                                 "rail_crossing": 10,
511                             },
512                             is_plugin=True,
513                             #dtype = np.int32,
514                             perm='rw',
515                             #is_index = True,
516                             name='Type',
517                             info='Zone type.',
518                             ))
519
520        self.add_col(NumcolConf('shapes', [],
521                                groupnames=['state'],
522                                perm='rw',
523                                is_plugin=True,
524                                is_save=True,
525                                name='Shape',
526                                info='Shape of zone which is a list of (x,y) coordinates',
527                                ))
528
529
530class OdTripsTab(ArrayObjman):
531    def __init__(self, ident,  parent, zones, **kwargs):
532        self._init_objman(ident, parent=parent, **kwargs)
533
534        self.add_col(IdsArrayConf('ids_orig', zones,
535                                  groupnames=['state'],
536                                  is_save=True,
537                                  name='ID Orig',
538                                  info='ID of traffic assignment zone of origin of trip.',
539                                  ))
540
541        self.add_col(IdsConf('ids_dest', zones,
542                             groupnames=['state'],
543                             is_save=True,
544                             name='ID Dest',
545                             info='ID of traffic assignment zone of destination of trip.',
546                             ))
547
548        self.add_col(NumArrayConf('tripnumbers', 0,
549                                  groupnames=['state'],
550                                  perm='rw',
551                                  is_save=True,
552                                  name='Trip number',
553                                  info='Number of trips from zone with ID Orig to zone with ID Dest.',
554                                  ))
555
556
557class OdModesTab(ArrayObjman):
558    def __init__(self, ident,  parent=None, **kwargs):
559        self._init_objman(ident, parent=parent, **kwargs)
560
561        self.add_col(ObjsConf('odtrips',
562                              groupnames=['state'],
563                              is_save=True,
564                              name='OD matrix',
565                              info='Matrix with trips from origin to destintion',
566                              ))
567
568
569class OdIntervalsTab(ArrayObjman):
570    def __init__(self, ident,  parent=None, **kwargs):
571        self._init_objman(ident, parent=parent, **kwargs)
572
573        self.add_col(NumArrayConf('t_start', 0.0,
574                                  groupnames=['state'],
575                                  perm='rw',
576                                  is_save=True,
577                                  name='Start time',
578                                  unit='s',
579                                  info='Start time of interval',
580                                  ))
581
582        self.add_col(NumArrayConf('t_end', 3600.0,
583                                  groupnames=['state'],
584                                  perm='rw',
585                                  is_save=True,
586                                  name='End time',
587                                  unit='s',
588                                  info='End time of interval',
589                                  ))
590
591        self.add_col(ObjsConf('odmodes',
592                              groupnames=['state'],
593                              is_save=True,
594                              name='Modes',
595                              info='Transport mode',
596                              ))
597
598###########################################################################
599# Instance creation
600
601
602demand = BaseObjman('demand')
603
604zones = ZonesTab('zones', parent=demand)
605demand.zones = demand.get_attrsman().add(ObjConf(zones))
606EVTDELITEM = 20  # delete attribute
607EVTSETITEM = 21  # set attribute
608EVTGETITEM = 22  # get attribute
609EVTADDITEM = 23  # add/create attribute
610zones.shapes.plugin.add_event(EVTADDITEM, on_event_additem)
611shapes = [[(0.0, 10.0), (10.0, 10.0), (10.0, 0.0)],
612          [(10.0, 20.0), (20.0, 20.0), (20.0, 10.0)],
613          [(20.0, 30.0), (30.0, 20.0), (30.0, 20.0)],
614          ]
615zones.add_rows(3, shapes=shapes)
616
617odintervals = OdIntervalsTab('odintervals', parent=demand, info='OD data for different time intervals')
618demand.odintervals = demand.get_attrsman().add(ObjConf(odintervals))
619odintervals.add_rows(2, t_start=[0, 3600], t_end=[3600, 7200])
620for id_odmodes in odintervals.get_ids():
621    odmodes = OdModesTab((odintervals.odmodes.attrname, id_odmodes), parent=odintervals)
622    odintervals.odmodes[id_odmodes] = odmodes
623
624    odmodes.add_rows(2)
625    for id_odtrips in odmodes.get_ids():
626        odtrips = OdTripsTab((odmodes.odtrips.attrname, id_odtrips), odmodes, zones)
627        odtrips.add_rows(3, ids_orig=[3, 2, 1], ids_dest=[3, 3, 3], tripnumbers=[10, 200, 555])
628        odmodes.odtrips[id_odtrips] = odtrips
629
630# demand.attrsman.print_attrs()
631# odintervals.print_attrs()
632
633# -------------------------------------------------------------------------------
634
635
636# vertices = [  [0.0,10.0,10.0,10.0,10.0,0.0],
637#            [10.0,20.0,20.0,20.0,20.0,10.0],
638#            [20.0,30.0,30.0,20.0,30.0,20.0],
639#            ]
640
641# vertices = [  [(0.0,10.0),(10.0,10.0)],
642#            [(10.0,20.0),(20.0,20.0)],
643#            [(20.0,30.0),(30.0,20.0)],
644#            ]
645vertices = [
646    [[0.0, 0.0, 0.0], [0.2, 0.0, 0.0]],  # 0
647    [[0.3, 0.0, 0.0], [0.9, 0.0, 0.0]],  # 1
648    [[0.5, 0.0, 0.1], [1.9, 0.0, 0.0]],  # 2
649]
650polygons = [
651    np.array([[0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.2, 0.0, 0.1], [0.3, 0.3, 0.3]]),  # 0
652    np.array([[0.3, 0.0, 0.0], [0.9, 0.0, 0.0]]),  # 1
653    np.array([[0.5, 0.0, 0.1], [1.9, 0.0, 0.0], [0.2, 0.2, 0.2]]),  # 2
654]
655ids_sumo = ['aa10', 'bb22', 'cc333']
656# lines.add_rows(3)
657drawing = BaseObjman('drawing')
658
659lines = Lines('lines', parent=drawing)
660drawing.lines = drawing.get_attrsman().add(ObjConf(lines))
661lines.add_rows(3, vertices=vertices, polygons=polygons, ids_sumo=ids_sumo)
662
663triangles = Lines('triangles', parent=drawing)
664drawing.triangles = drawing.get_attrsman().add(ObjConf(triangles))
665triangles.add_rows(3, vertices=2*vertices, polygons=polygons, ids_sumo=['xxx10', 'xx22', 'xx333'])
666
667selection = Selection('selection', parent=drawing)
668drawing.selection = drawing.get_attrsman().add(ObjConf(selection))
669selection.add_rows(2, obj_ids=[(lines, 2), (triangles, 1)])
670
671collections = Collection('collections', parent=drawing)
672drawing.collections = drawing.get_attrsman().add(ObjConf(collections))
673collections.add_rows(2, tab_id_lists=[[(lines, 2), (triangles, 1)],
674                                      [(lines, 2), (triangles, 1), (lines, 1)]]
675                     )
676
677# -------------------------------------------------------------------------------
678
679pointvertices = [
680                [0.0, 0.0, 0.0],
681                [0.2, 0.0, 0.0],
682                [0.3, 0.5, 0.0],
683                [0.2, 0.5, 0.0],
684                [0.0, 0.5, 0.1],
685                [-1.5, -0.5, 0.0],
686]
687
688pointvertices2 = [
689    [0.0, 0.3, 0.0],
690    [0.2, 0.3, 0.0],
691    [0.3, 0.8, 0.0],
692    [0.2, 0.8, 0.0],
693    [0.0, 0.8, 0.1],
694    [-1.5, -0.8, 0.0],
695]
696
697pointvertices3 = [
698    [0.5, 0.3, 0.0],
699    [-1.5, -0.8, 0.0],
700]
701
702
703polylines = Polylines()
704polylines.draw(pointvertices, 'aa10&1')
705polylines.draw(pointvertices2, 'bb2210&1')
706polylines.draw(pointvertices3, '5b2310&1')
707polylines.print_attrs()
708xm.write_obj_to_xml(polylines, 'test_polylines.xml')
709