1# Copyright (c) 2019-2020 Manfred Moitzi
2# License: MIT License
3import pytest
4import ezdxf
5from ezdxf.entities.mesh import Mesh
6from ezdxf.lldxf.tagwriter import TagCollector, basic_tags_from_text
7from ezdxf.math import Vec3, Matrix44
8
9MESH = """0
10MESH
115
120
13330
141F
15100
16AcDbEntity
178
180
19100
20AcDbSubDMesh
2171
222
2372
240
2591
260
2792
280
2993
300
3194
320
3395
340
3590
360
37"""
38
39@pytest.fixture
40def entity():
41    return Mesh.from_text(MESH)
42
43
44def test_registered():
45    from ezdxf.entities.factory import ENTITY_CLASSES
46    assert 'MESH' in ENTITY_CLASSES
47
48
49def test_default_init():
50    entity = Mesh()
51    assert entity.dxftype() == 'MESH'
52    assert entity.dxf.handle is None
53    assert entity.dxf.owner is None
54
55
56def test_default_new():
57    entity = Mesh.new(handle='ABBA', owner='0', dxfattribs={
58        'color': 7,
59        'version': 3,
60        'blend_crease': 1,
61        'subdivision_levels': 2,
62    })
63    assert entity.dxf.layer == '0'
64    assert entity.dxf.color == 7
65    assert entity.dxf.version == 3
66    assert entity.dxf.blend_crease == 1
67    assert entity.dxf.subdivision_levels == 2
68
69
70def test_load_from_text(entity):
71    assert entity.dxf.layer == '0'
72    assert entity.dxf.color == 256, 'default color is 256 (by layer)'
73    assert entity.dxf.version == 2
74    assert entity.dxf.blend_crease == 0
75    assert entity.dxf.subdivision_levels == 0
76
77
78def test_write_dxf():
79    entity = Mesh.from_text(MESH)
80    result = TagCollector.dxftags(entity)
81    expected = basic_tags_from_text(MESH)
82    assert result == expected
83
84
85@pytest.fixture(scope='module')
86def doc():
87    return ezdxf.new('R2000')
88
89
90@pytest.fixture(scope='module')
91def msp(doc):
92    return doc.modelspace()
93
94
95@pytest.fixture
96def mesh(doc):
97    return Mesh.from_text(MESH2, doc)
98
99
100def test_mesh_properties(mesh):
101    assert 'MESH' == mesh.dxftype()
102    assert 256 == mesh.dxf.color
103    assert '0' == mesh.dxf.layer
104    assert 'BYLAYER' == mesh.dxf.linetype
105    assert mesh.dxf.paperspace == 0
106
107
108def test_mesh_dxf_attribs(mesh):
109    assert 2 == mesh.dxf.version
110    assert 0 == mesh.dxf.blend_crease
111    assert 3 == mesh.dxf.subdivision_levels
112
113
114def test_mesh_geometric_data(mesh):
115    with mesh.edit_data() as mesh_data:
116        assert 56 == len(mesh_data.vertices)
117        assert 54 == len(mesh_data.faces)
118        assert 108 == len(mesh_data.edges)
119        assert 108 == len(mesh_data.edge_crease_values)
120
121
122def test_create_empty_mesh(msp):
123    mesh = msp.add_mesh()
124    assert 2 == mesh.dxf.version
125    assert 0 == mesh.dxf.blend_crease
126    assert 0 == mesh.dxf.subdivision_levels
127
128
129def test_add_faces(msp):
130    mesh = msp.add_mesh()
131    with mesh.edit_data() as mesh_data:
132        mesh_data.add_face([(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)])
133        assert 4 == len(mesh_data.vertices)
134        assert 1 == len(mesh_data.faces)
135        assert [0, 1, 2, 3] == mesh_data.faces[0]
136
137
138def test_add_edges(msp):
139    mesh = msp.add_mesh()
140    with mesh.edit_data() as mesh_data:
141        mesh_data.add_edge([(0, 0, 0), (1, 0, 0)])
142        assert 2 == len(mesh_data.vertices)
143        assert 1 == len(mesh_data.edges)
144        assert [0, 1] == mesh_data.edges[0]
145
146
147def test_vertex_format(msp):
148    mesh = msp.add_mesh()
149    with mesh.edit_data() as mesh_data:
150        with pytest.raises(ezdxf.DXFValueError):
151            mesh_data.add_vertex((0, 0))  # only (x, y, z) vertices allowed
152
153
154def test_optimize(msp):
155    vertices = [
156        (0, 0, 0),
157        (1, 0, 0),
158        (1, 1, 0),
159        (0, 1, 0),
160        (0, 0, 1),
161        (1, 0, 1),
162        (1, 1, 1),
163        (0, 1, 1),
164    ]
165
166    # 6 cube faces
167    cube_faces = [
168        [0, 1, 2, 3],
169        [4, 5, 6, 7],
170        [0, 1, 5, 4],
171        [1, 2, 6, 5],
172        [3, 2, 6, 7],
173        [0, 3, 7, 4]
174    ]
175    mesh = msp.add_mesh()
176    with mesh.edit_data() as mesh_data:
177        for face in cube_faces:
178            mesh_data.add_face([vertices[index] for index in face])
179        assert 24 == len(mesh_data.vertices)
180        assert 6 == len(mesh_data.faces)
181        mesh_data.optimize()
182        assert 8 == len(mesh_data.vertices), "Doublettes not removed"
183        assert 6 == len(mesh_data.faces)
184        assert 0 == len(mesh_data.edges)
185
186
187def test_mesh_transform_interface():
188    mesh = Mesh()
189    mesh.vertices.append(Vec3(1, 2, 3))
190    mesh.transform(Matrix44.translate(1, 1, 1))
191    assert mesh.vertices[0] == (2, 3, 4)
192
193
194MESH2 = """  0
195MESH
1965
1972E2
198330
1991F
200100
201AcDbEntity
2028
2030
204100
205AcDbSubDMesh
20671
2072
20872
2090
21091
2113
21292
21356
21410
215284.7875769672455
21620
217754.2780370501814
21830
21964.23540699023241
22010
221284.7875769672455
22220
223754.2780370501814
22430
2250.0
22610
227284.7875769672455
22820
229616.8856749189314
23030
23164.23540699023241
23210
233284.7875769672455
23420
235616.8856749189314
23630
2370.0
23810
239284.7875769672455
24020
241360.4098446797661
24230
243193.4439639884759
24410
245284.7875769672455
24620
247479.4933127876815
24830
2490.0
25010
251284.7875769672455
25220
253463.228394722746
25430
255102.3121531918951
25610
257284.7875769672455
25820
259342.1009506564315
26030
2610.0
26210
263427.8287432817834
26420
265754.2780370501814
26630
26764.23540699023241
26810
269427.8287432817834
27020
271754.2780370501814
27230
2730.0
27410
275427.8287432817834
27620
277616.8856749189314
27830
27964.23540699023241
28010
281427.8287432817834
28220
283616.8856749189314
28430
2850.0
28610
287427.8287432817834
28820
289360.4098446797661
29030
291193.4439639884759
29210
293427.8287432817834
29420
295479.4933127876815
29630
2970.0
29810
299427.8287432817834
30020
301463.228394722746
30230
303102.3121531918951
30410
305427.8287432817834
30620
307342.1009506564315
30830
3090.0
31010
311570.8699095963213
31220
313754.2780370501814
31430
31564.23540699023241
31610
317570.8699095963213
31820
319754.2780370501814
32030
3210.0
32210
323570.8699095963213
32420
325616.8856749189314
32630
32764.23540699023241
32810
329570.8699095963213
33020
331616.8856749189314
33230
3330.0
33410
335570.8699095963213
33620
337360.4098446797661
33830
339193.4439639884759
34010
341570.8699095963213
34220
343479.4933127876815
34430
3450.0
34610
347570.8699095963213
34820
349463.228394722746
35030
351102.3121531918951
35210
353570.8699095963213
35420
355342.1009506564315
35630
3570.0
35810
359713.9110759108594
36020
361754.2780370501814
36230
36364.23540699023241
36410
365713.9110759108594
36620
367754.2780370501814
36830
3690.0
37010
371713.9110759108594
37220
373616.8856749189314
37430
37564.23540699023241
37610
377713.9110759108594
37820
379616.8856749189314
38030
3810.0
38210
383713.9110759108594
38420
385360.4098446797661
38630
387193.4439639884759
38810
389713.9110759108594
39020
391479.4933127876815
39230
3930.0
39410
395713.9110759108594
39620
397463.228394722746
39830
399102.3121531918951
40010
401713.9110759108594
40220
403342.1009506564315
40430
4050.0
40610
407427.8287432817834
40820
409342.1009506564315
41030
41121.41180233007747
41210
413427.8287432817834
41420
415754.2780370501814
41630
41721.41180233007747
41810
419427.8287432817834
42020
421342.1009506564315
42230
42342.82360466015493
42410
425427.8287432817834
42620
427754.2780370501814
42830
42942.82360466015493
43010
431570.8699095963213
43220
433342.1009506564315
43430
43521.41180233007747
43610
437570.8699095963213
43820
439754.2780370501814
44030
44121.41180233007747
44210
443570.8699095963213
44420
445342.1009506564315
44630
44742.82360466015493
44810
449570.8699095963213
45020
451754.2780370501814
45230
45342.82360466015493
45410
455713.9110759108594
45620
457616.8856749189314
45830
45921.41180233007747
46010
461284.7875769672455
46220
463616.8856749189314
46430
46521.41180233007747
46610
467713.9110759108594
46820
469616.8856749189314
47030
47142.82360466015493
47210
473284.7875769672455
47420
475616.8856749189314
47630
47742.82360466015493
47810
479713.9110759108594
48020
481479.4933127876815
48230
48321.41180233007747
48410
485284.7875769672455
48620
487479.4933127876815
48830
48921.41180233007747
49010
491713.9110759108594
49220
493479.4933127876815
49430
49542.82360466015493
49610
497284.7875769672455
49820
499479.4933127876815
50030
50142.82360466015493
50210
503284.7875769672455
50420
505754.2780370501814
50630
50721.41180233007747
50810
509284.7875769672455
51020
511342.1009506564315
51230
51321.41180233007747
51410
515713.9110759108594
51620
517754.2780370501814
51830
51921.41180233007747
52010
521713.9110759108594
52220
523342.1009506564315
52430
52521.41180233007747
52610
527284.7875769672455
52820
529754.2780370501814
53030
53142.82360466015493
53210
533284.7875769672455
53420
535342.1009506564315
53630
53742.82360466015493
53810
539713.9110759108594
54020
541754.2780370501814
54230
54342.82360466015493
54410
545713.9110759108594
54620
547342.1009506564315
54830
54942.82360466015493
55093
551270
55290
5534
55490
5552
55690
55710
55890
5598
56090
5610
56290
5634
56490
5654
56690
56712
56890
56910
57090
5712
57290
5734
57490
5756
57690
57714
57890
57912
58090
5814
58290
5834
58490
58510
58690
58718
58890
58916
59090
5918
59290
5934
59490
59512
59690
59720
59890
59918
60090
60110
60290
6034
60490
60514
60690
60722
60890
60920
61090
61112
61290
6134
61490
61518
61690
61726
61890
61924
62090
62116
62290
6234
62490
62520
62690
62728
62890
62926
63090
63118
63290
6334
63490
63522
63690
63730
63890
63928
64090
64120
64290
6434
64490
6451
64690
6479
64890
64911
65090
6513
65290
6534
65490
6553
65690
65711
65890
65913
66090
6615
66290
6634
66490
6655
66690
66713
66890
66915
67090
6717
67290
6734
67490
6759
67690
67717
67890
67919
68090
68111
68290
6834
68490
68511
68690
68719
68890
68921
69090
69113
69290
6934
69490
69513
69690
69721
69890
69923
70090
70115
70290
7034
70490
70517
70690
70725
70890
70927
71090
71119
71290
7134
71490
71519
71690
71727
71890
71929
72090
72121
72290
7234
72490
72521
72690
72729
72890
72931
73090
73123
73290
7334
73490
73515
73690
73732
73890
73949
74090
7417
74290
7434
74490
74532
74690
74734
74890
74953
75090
75149
75290
7534
75490
75534
75690
75714
75890
7596
76090
76153
76290
7634
76490
76523
76690
76736
76890
76932
77090
77115
77290
7734
77490
77536
77690
77738
77890
77934
78090
78132
78290
7834
78490
78538
78690
78722
78890
78914
79090
79134
79290
7934
79490
79531
79690
79751
79890
79936
80090
80123
80290
8034
80490
80551
80690
80755
80890
80938
81090
81136
81290
8134
81490
81555
81690
81730
81890
81922
82090
82138
82290
8234
82490
82548
82690
82733
82890
8299
83090
8311
83290
8334
83490
83552
83690
83735
83890
83933
84090
84148
84290
8434
84490
8450
84690
8478
84890
84935
85090
85152
85290
8534
85490
85533
85690
85737
85890
85917
86090
8619
86290
8634
86490
86535
86690
86739
86890
86937
87090
87133
87290
8734
87490
8758
87690
87716
87890
87939
88090
88135
88290
8834
88490
88537
88690
88750
88890
88925
89090
89117
89290
8934
89490
89539
89690
89754
89890
89950
90090
90137
90290
9034
90490
90516
90690
90724
90890
90954
91090
91139
91290
9134
91490
91550
91690
91740
91890
91927
92090
92125
92290
9234
92490
92554
92690
92742
92890
92940
93090
93150
93290
9334
93490
93524
93690
93726
93890
93942
94090
94154
94290
9434
94490
94540
94690
94744
94890
94929
95090
95127
95290
9534
95490
95542
95690
95746
95890
95944
96090
96140
96290
9634
96490
96526
96690
96728
96890
96946
97090
97142
97290
9734
97490
97544
97690
97751
97890
97931
98090
98129
98290
9834
98490
98546
98690
98755
98890
98951
99090
99144
99290
9934
99490
99528
99690
99730
99890
99955
100090
100146
100290
10034
100490
10051
100690
10073
100890
100941
101090
101148
101290
10134
101490
101548
101690
101741
101890
101943
102090
102152
102290
10234
102490
102552
102690
102743
102890
10292
103090
10310
103290
10334
103490
10353
103690
10375
103890
103945
104090
104141
104290
10434
104490
104541
104690
104745
104890
104947
105090
105143
105290
10534
105490
105543
105690
105747
105890
10594
106090
10612
106290
10634
106490
10655
106690
10677
106890
106949
107090
107145
107290
10734
107490
107545
107690
107749
107890
107953
108090
108147
108290
10834
108490
108547
108690
108753
108890
10896
109090
10914
109294
1093108
109490
10952
109690
109710
109890
10998
110090
110110
110290
11030
110490
11058
110690
11070
110890
11092
111090
11114
111290
111312
111490
111510
111690
111712
111890
11192
112090
11214
112290
11236
112490
112514
112690
112712
112890
112914
113090
11314
113290
11336
113490
113510
113690
113718
113890
113916
114090
114118
114290
11438
114490
114516
114690
114712
114890
114920
115090
115118
115290
115320
115490
115514
115690
115722
115890
115920
116090
116122
116290
116318
116490
116526
116690
116724
116890
116926
117090
117116
117290
117324
117490
117520
117690
117728
117890
117926
118090
118128
118290
118322
118490
118530
118690
118728
118890
118930
119090
11911
119290
11939
119490
11959
119690
119711
119890
11993
120090
120111
120290
12031
120490
12053
120690
120711
120890
120913
121090
12115
121290
121313
121490
12153
121690
12175
121890
121913
122090
122115
122290
12237
122490
122515
122690
12275
122890
12297
123090
12319
123290
123317
123490
123517
123690
123719
123890
123911
124090
124119
124290
124319
124490
124521
124690
124713
124890
124921
125090
125121
125290
125323
125490
125515
125690
125723
125890
125917
126090
126125
126290
126325
126490
126527
126690
126719
126890
126927
127090
127127
127290
127329
127490
127521
127690
127729
127890
127929
128090
128131
128290
128323
128490
128531
128690
128715
128890
128932
129090
129132
129290
129349
129490
12957
129690
129749
129890
129932
130090
130134
130290
130334
130490
130553
130690
130749
130890
130953
131090
131114
131290
131334
131490
13156
131690
131753
131890
131923
132090
132136
132290
132332
132490
132536
132690
132736
132890
132938
133090
133134
133290
133338
133490
133522
133690
133738
133890
133931
134090
134151
134290
134336
134490
134551
134690
134751
134890
134955
135090
135138
135290
135355
135490
135530
135690
135755
135890
135933
136090
136148
136290
13639
136490
136533
136690
13671
136890
136948
137090
137135
137290
137352
137490
137533
137690
137735
137890
137948
138090
138152
138290
13838
138490
138535
138690
13870
138890
138952
139090
139133
139290
139337
139490
139517
139690
139737
139890
139935
140090
140139
140290
140337
140490
140539
140690
140716
140890
140939
141090
141137
141290
141350
141490
141525
141690
141750
141890
141939
142090
142154
142290
142350
142490
142554
142690
142724
142890
142954
143090
143140
143290
143350
143490
143527
143690
143740
143890
143942
144090
144154
144290
144340
144490
144542
144690
144726
144890
144942
145090
145140
145290
145344
145490
145529
145690
145744
145890
145942
146090
146146
146290
146344
146490
146546
146690
146728
146890
146946
147090
147144
147290
147351
147490
147546
147690
147755
147890
14793
148090
148141
148290
148341
148490
148548
148690
148741
148890
148943
149090
149143
149290
149352
149490
14952
149690
149743
149890
14995
150090
150145
150290
150341
150490
150545
150690
150745
150890
150947
151090
151143
151290
151347
151490
15154
151690
151747
151890
151945
152090
152149
152290
152347
152490
152553
152695
1527108
1528140
15290.0
1530140
15310.0
1532140
15330.0
1534140
15350.0
1536140
15370.0
1538140
15390.0
1540140
15410.0
1542140
15430.0
1544140
15450.0
1546140
15470.0
1548140
15490.0
1550140
15510.0
1552140
15530.0
1554140
15550.0
1556140
15570.0
1558140
15590.0
1560140
15610.0
1562140
15630.0
1564140
15650.0
1566140
15670.0
1568140
15690.0
1570140
15710.0
1572140
15730.0
1574140
15750.0
1576140
15770.0
1578140
15790.0
1580140
15810.0
1582140
15830.0
1584140
15850.0
1586140
15870.0
1588140
15890.0
1590140
15910.0
1592140
15930.0
1594140
15950.0
1596140
15970.0
1598140
15990.0
1600140
16010.0
1602140
16030.0
1604140
16050.0
1606140
16070.0
1608140
16090.0
1610140
16110.0
1612140
16130.0
1614140
16150.0
1616140
16170.0
1618140
16190.0
1620140
16210.0
1622140
16230.0
1624140
16250.0
1626140
16270.0
1628140
16290.0
1630140
16310.0
1632140
16330.0
1634140
16350.0
1636140
16370.0
1638140
16390.0
1640140
16410.0
1642140
16430.0
1644140
16450.0
1646140
16470.0
1648140
16490.0
1650140
16510.0
1652140
16530.0
1654140
16550.0
1656140
16570.0
1658140
16590.0
1660140
16610.0
1662140
16630.0
1664140
16650.0
1666140
16670.0
1668140
16690.0
1670140
16710.0
1672140
16730.0
1674140
16750.0
1676140
16770.0
1678140
16790.0
1680140
16810.0
1682140
16830.0
1684140
16850.0
1686140
16870.0
1688140
16890.0
1690140
16910.0
1692140
16930.0
1694140
16950.0
1696140
16970.0
1698140
16990.0
1700140
17010.0
1702140
17030.0
1704140
17050.0
1706140
17070.0
1708140
17090.0
1710140
17110.0
1712140
17130.0
1714140
17150.0
1716140
17170.0
1718140
17190.0
1720140
17210.0
1722140
17230.0
1724140
17250.0
1726140
17270.0
1728140
17290.0
1730140
17310.0
1732140
17330.0
1734140
17350.0
1736140
17370.0
1738140
17390.0
1740140
17410.0
1742140
17430.0
174490
17450
1746"""
1747