10
import FreeCAD, unittest, Mesh
12
from FreeCAD import Base
13
import time, tempfile, math
17
import _thread as thread
21
from os.path import join
28
class MeshTopoTestCases(unittest.TestCase):
34
self.planarMesh.append([0.0 + x, 0.0 + y, 0.0000])
35
self.planarMesh.append([1.0 + x, 1.0 + y, 0.0000])
36
self.planarMesh.append([0.0 + x, 1.0 + y, 0.0000])
37
self.planarMesh.append([0.0 + x, 0.0 + y, 0.0000])
38
self.planarMesh.append([1.0 + x, 0.0 + y, 0.0000])
39
self.planarMesh.append([1.0 + x, 1.0 + y, 0.0000])
41
def testCollapseFacetsSingle(self):
43
planarMeshObject = Mesh.Mesh(self.planarMesh)
44
planarMeshObject.collapseFacets([i])
46
def testCollapseFacetsMultible(self):
47
planarMeshObject = Mesh.Mesh(self.planarMesh)
48
planarMeshObject.collapseFacets(range(7))
50
def testCollapseFacetsAll(self):
51
planarMeshObject = Mesh.Mesh(self.planarMesh)
52
planarMeshObject.collapseFacets(range(18))
55
def testCorruptedFacet(self):
59
v(1.0e1, -1.0e1, 1.0e1),
60
v(1.0e1, +1.0e1, 1.0e1),
61
v(0.0e0, 0.0e0, 1.0e1))
64
v(-1.0e1, -1.0e1, 1.0e1),
65
v(-1.0e1, +1.0e1, 1.0e1),
69
v(+1.0e1, +1.0e1, 1.0e1),
70
v(-1.0e1, +1.0e1, 1.0e1),
71
v(.0e0, 0.0e0, 1.0e1))
74
v(+1.0e1, -1.0e1, 1.0e1),
75
v(-1.0e1, -1.0e1, 1.0e1),
76
v(.0e0, 0.0e0, 1.0e1))
79
v(-1.0e1, +1.0e1, 1.0e1),
80
v(+1.0e1, +1.0e1, 1.0e1),
81
v(+1.0e1, +1.0e1, 1.0e1))
84
v(+1.0e1, +1.0e1, 1.0e1),
85
v(+1.0e1, 00.0e1, 1.0e1),
86
v(+1.0e1, -1.0e1, 1.0e1))
88
self.assertEqual(mesh.CountFacets, 6)
90
self.assertEqual(mesh.CountFacets, 5)
96
class MeshSplitTestCases(unittest.TestCase):
98
self.mesh = Mesh.createBox(1.0, 1.0, 1.0)
100
def testSplitFacetOnOneEdge(self):
101
p1 = self.mesh.Points[0].Vector
102
p2 = self.mesh.Points[1].Vector
103
p3 = self.mesh.Points[2].Vector
104
self.mesh.splitFacet(0, p1, (p2 + p3) / 2)
105
self.assertFalse(self.mesh.hasNonManifolds())
106
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
107
self.assertFalse(self.mesh.hasPointsOutOfRange())
108
self.assertFalse(self.mesh.hasFacetsOutOfRange())
109
self.assertFalse(self.mesh.hasCorruptedFacets())
110
self.assertTrue(self.mesh.isSolid())
112
def testSplitFacetOnTwoEdges_21(self):
113
p1 = self.mesh.Points[0].Vector
114
p2 = self.mesh.Points[1].Vector
115
p3 = self.mesh.Points[2].Vector
116
self.mesh.splitFacet(0, (p1 + p3) / 2, (p2 + p3) / 2)
117
self.assertFalse(self.mesh.hasNonManifolds())
118
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
119
self.assertFalse(self.mesh.hasPointsOutOfRange())
120
self.assertFalse(self.mesh.hasFacetsOutOfRange())
121
self.assertFalse(self.mesh.hasCorruptedFacets())
122
self.assertTrue(self.mesh.isSolid())
124
def testSplitFacetOnTwoEdges_12(self):
125
p1 = self.mesh.Points[0].Vector
126
p2 = self.mesh.Points[1].Vector
127
p3 = self.mesh.Points[2].Vector
128
self.mesh.splitFacet(0, (p2 + p3) / 2, (p1 + p3) / 2)
129
self.assertFalse(self.mesh.hasNonManifolds())
130
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
131
self.assertFalse(self.mesh.hasPointsOutOfRange())
132
self.assertFalse(self.mesh.hasFacetsOutOfRange())
133
self.assertFalse(self.mesh.hasCorruptedFacets())
134
self.assertTrue(self.mesh.isSolid())
136
def testSplitFacetOnTwoEdges_01(self):
137
p1 = self.mesh.Points[0].Vector
138
p2 = self.mesh.Points[1].Vector
139
p3 = self.mesh.Points[2].Vector
140
self.mesh.splitFacet(0, (p1 + p2) / 2, (p2 + p3) / 2)
141
self.assertFalse(self.mesh.hasNonManifolds())
142
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
143
self.assertFalse(self.mesh.hasPointsOutOfRange())
144
self.assertFalse(self.mesh.hasFacetsOutOfRange())
145
self.assertFalse(self.mesh.hasCorruptedFacets())
146
self.assertTrue(self.mesh.isSolid())
148
def testSplitFacetOnTwoEdges_10(self):
149
p1 = self.mesh.Points[0].Vector
150
p2 = self.mesh.Points[1].Vector
151
p3 = self.mesh.Points[2].Vector
152
self.mesh.splitFacet(0, (p2 + p3) / 2, (p1 + p2) / 2)
153
self.assertFalse(self.mesh.hasNonManifolds())
154
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
155
self.assertFalse(self.mesh.hasPointsOutOfRange())
156
self.assertFalse(self.mesh.hasFacetsOutOfRange())
157
self.assertFalse(self.mesh.hasCorruptedFacets())
158
self.assertTrue(self.mesh.isSolid())
160
def testSplitFacetOnTwoEdges_02(self):
161
p1 = self.mesh.Points[0].Vector
162
p2 = self.mesh.Points[1].Vector
163
p3 = self.mesh.Points[2].Vector
164
self.mesh.splitFacet(0, (p1 + p2) / 2, (p1 + p3) / 2)
165
self.assertFalse(self.mesh.hasNonManifolds())
166
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
167
self.assertFalse(self.mesh.hasPointsOutOfRange())
168
self.assertFalse(self.mesh.hasFacetsOutOfRange())
169
self.assertFalse(self.mesh.hasCorruptedFacets())
170
self.assertTrue(self.mesh.isSolid())
172
def testSplitFacetOnTwoEdges_20(self):
173
p1 = self.mesh.Points[0].Vector
174
p2 = self.mesh.Points[1].Vector
175
p3 = self.mesh.Points[2].Vector
176
self.mesh.splitFacet(0, (p1 + p3) / 2, (p1 + p2) / 2)
177
self.assertFalse(self.mesh.hasNonManifolds())
178
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
179
self.assertFalse(self.mesh.hasPointsOutOfRange())
180
self.assertFalse(self.mesh.hasFacetsOutOfRange())
181
self.assertFalse(self.mesh.hasCorruptedFacets())
182
self.assertTrue(self.mesh.isSolid())
184
def testSplitFacetOnTwoEdges_5teps(self):
185
Vec3d = FreeCAD.Vector
187
f = self.mesh.Facets[0]
188
p1 = Vec3d(f.Points[0])
189
p2 = Vec3d(f.Points[1])
190
p3 = Vec3d(f.Points[2])
191
self.mesh.splitFacet(0, (p1 + p3) / 2, (p2 + p3) / 2)
193
self.assertFalse(self.mesh.hasNonManifolds())
194
self.assertFalse(self.mesh.hasInvalidNeighbourhood())
195
self.assertFalse(self.mesh.hasPointsOutOfRange())
196
self.assertFalse(self.mesh.hasFacetsOutOfRange())
197
self.assertFalse(self.mesh.hasCorruptedFacets())
198
self.assertTrue(self.mesh.isSolid())
200
def testFindNearest(self):
201
self.assertEqual(len(self.mesh.nearestFacetOnRay((-2, 2, -6), (0, 0, 1))), 0)
202
self.assertEqual(len(self.mesh.nearestFacetOnRay((0.5, 0.5, 0.5), (0, 0, 1))), 1)
204
len(self.mesh.nearestFacetOnRay((0.5, 0.5, 0.5), (0, 0, 1), -math.pi / 2)), 0
207
len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, 1))),
208
len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, -1))),
211
len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, 1), math.pi / 2)),
212
len(self.mesh.nearestFacetOnRay((0.2, 0.1, 0.2), (0, 0, -1), math.pi / 2)),
215
plm = Base.Placement(Base.Vector(1, 2, 3), Base.Rotation(1, 1, 1, 1))
216
pnt = Base.Vector(0.5, 0.5, 0.5)
217
vec = Base.Vector(0.0, 0.0, 1.0)
219
self.mesh.Placement = plm
220
self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt, vec)), 0)
223
pnt = plm.multVec(pnt)
224
vec = plm.Rotation.multVec(vec)
225
self.assertEqual(len(self.mesh.nearestFacetOnRay(pnt, vec)), 1)
227
def testForaminate(self):
229
def __init__(self, mesh, vec, limit):
234
def check_angle(self, item):
235
angle = self.myMesh.Facets[item].Normal.getAngle(self.vec)
236
return angle < self.limit
238
results = self.mesh.foraminate((0.0, 0.0, 0.0), (0, 1, 1))
239
filtered_result = list(
241
FilterAngle(self.mesh, FreeCAD.Vector(0, 1, 1), math.pi / 2).check_angle,
247
filtered_result, list(self.mesh.foraminate((0.0, 0.0, 0.0), (0, 1, 1), math.pi / 2))
250
def testForaminatePlacement(self):
251
pnt = Base.Vector(0.0, 0.0, 0.0)
252
vec = Base.Vector(0.0, 1.0, 1.0)
253
results = self.mesh.foraminate(pnt, vec)
254
self.assertEqual(len(results), 4)
257
plm = Base.Placement(Base.Vector(1, 2, 3), Base.Rotation(1, 1, 1, 1))
258
self.mesh.Placement = plm
259
self.assertEqual(len(self.mesh.foraminate(pnt, vec)), 0)
262
pnt = plm.multVec(pnt)
263
vec = plm.Rotation.multVec(vec)
264
results2 = self.mesh.foraminate(pnt, vec)
265
self.assertEqual(len(results2), 4)
266
self.assertEqual(list(results), list(results2))
269
class MeshGeoTestCases(unittest.TestCase):
274
def testIntersection(self):
275
self.planarMesh.append([0.9961, 1.5413, 4.3943])
276
self.planarMesh.append([9.4796, 10.024, -3.0937])
277
self.planarMesh.append([1.4308, 11.3841, 2.6829])
278
self.planarMesh.append([2.6493, 2.2536, 3.0679])
279
self.planarMesh.append([13.1126, 0.4857, -4.4417])
280
self.planarMesh.append([10.2410, 8.9040, -3.5002])
281
planarMeshObject = Mesh.Mesh(self.planarMesh)
282
f1 = planarMeshObject.Facets[0]
283
f2 = planarMeshObject.Facets[1]
284
res = f1.intersect(f2)
285
self.assertTrue(len(res) == 0)
287
def testIntersection2(self):
288
self.planarMesh.append([-16.097176, -29.891157, 15.987688])
289
self.planarMesh.append([-16.176304, -29.859991, 15.947966])
290
self.planarMesh.append([-16.071451, -29.900553, 15.912505])
291
self.planarMesh.append([-16.092241, -29.893408, 16.020439])
292
self.planarMesh.append([-16.007210, -29.926180, 15.967641])
293
self.planarMesh.append([-16.064457, -29.904951, 16.090832])
294
planarMeshObject = Mesh.Mesh(self.planarMesh)
295
f1 = planarMeshObject.Facets[0]
296
f2 = planarMeshObject.Facets[1]
298
res = f1.intersect(f2)
299
self.assertTrue(len(res) == 0)
301
def testIntersectionOfTransformedMesh(self):
302
self.planarMesh.append([0.0, 10.0, 10.0])
303
self.planarMesh.append([10.0, 0.0, 10.0])
304
self.planarMesh.append([10.0, 10.0, 10.0])
305
self.planarMesh.append([6.0, 8.0, 10.0])
306
self.planarMesh.append([16.0, 8.0, 10.0])
307
self.planarMesh.append([6.0, 18.0, 10.0])
308
planarMeshObject = Mesh.Mesh(self.planarMesh)
314
planarMeshObject.transformGeometry(mat)
316
f1 = planarMeshObject.Facets[0]
317
f2 = planarMeshObject.Facets[1]
318
res = f1.intersect(f2)
319
self.assertEqual(len(res), 2)
321
def testIntersectionOfParallelTriangles(self):
322
self.planarMesh.append([0.0, 10.0, 10.0])
323
self.planarMesh.append([10.0, 0.0, 10.0])
324
self.planarMesh.append([10.0, 10.0, 10.0])
325
self.planarMesh.append([6.0, 8.0, 10.1])
326
self.planarMesh.append([16.0, 8.0, 10.1])
327
self.planarMesh.append([6.0, 18.0, 10.1])
328
planarMeshObject = Mesh.Mesh(self.planarMesh)
334
planarMeshObject.transformGeometry(mat)
336
f1 = planarMeshObject.Facets[0]
337
f2 = planarMeshObject.Facets[1]
338
res = f1.intersect(f2)
339
self.assertTrue(len(res) == 0)
341
def testIntersectionOnEdge(self):
342
self.planarMesh.append([5.0, -1.9371663331985474, 0.49737977981567383])
343
self.planarMesh.append([4.0, -1.9371663331985474, 0.49737977981567383])
344
self.planarMesh.append([5.0, -1.9842294454574585, 0.25066646933555603])
345
self.planarMesh.append([4.6488823890686035, -1.7827962636947632, 0.4577442705631256])
346
self.planarMesh.append([4.524135112762451, -2.0620131492614746, 0.5294350385665894])
347
self.planarMesh.append([4.6488823890686035, -1.8261089324951172, 0.23069120943546295])
348
planarMeshObject = Mesh.Mesh(self.planarMesh)
349
f1 = planarMeshObject.Facets[0]
350
f2 = planarMeshObject.Facets[1]
351
res = f1.intersect(f2)
352
self.assertEqual(len(res), 2)
354
def testIntersectionCoplanar(self):
355
self.planarMesh.append([0.0, 10.0, 10.0])
356
self.planarMesh.append([10.0, 0.0, 10.0])
357
self.planarMesh.append([10.0, 10.0, 10.0])
358
self.planarMesh.append([6.0, 8.0, 10.0])
359
self.planarMesh.append([16.0, 8.0, 10.0])
360
self.planarMesh.append([6.0, 18.0, 10.0])
361
planarMeshObject = Mesh.Mesh(self.planarMesh)
362
f1 = planarMeshObject.Facets[0]
363
f2 = planarMeshObject.Facets[1]
364
res = f1.intersect(f2)
365
self.assertTrue(len(res) == 2)
367
def testIntersectionOverlap(self):
368
self.planarMesh.append([0.0, 0.0, 0.0])
369
self.planarMesh.append([5.0, 0.0, 0.0])
370
self.planarMesh.append([8.0, 5.0, 0.0])
371
self.planarMesh.append([4.0, 0.0, 0.0])
372
self.planarMesh.append([10.0, 0.0, 0.0])
373
self.planarMesh.append([9.0, 5.0, 0.0])
374
planarMeshObject = Mesh.Mesh(self.planarMesh)
375
f1 = planarMeshObject.Facets[0]
376
f2 = planarMeshObject.Facets[1]
377
res = f1.intersect(f2)
378
self.assertTrue(len(res) == 2)
380
def testIntersectionOfIntersectingEdges(self):
381
self.planarMesh.append([0.0, 10.0, 10.0])
382
self.planarMesh.append([10.0, 0.0, 10.0])
383
self.planarMesh.append([10.0, 10.0, 10.0])
384
self.planarMesh.append([6.0, 8.0, 10.0])
385
self.planarMesh.append([16.0, 8.0, 10.0])
386
self.planarMesh.append([6.0, 18.0, 10.0])
387
planarMeshObject = Mesh.Mesh(self.planarMesh)
389
edge1 = planarMeshObject.Facets[0].getEdge(2)
390
edge2 = planarMeshObject.Facets[1].getEdge(2)
391
res = edge1.intersectWithEdge(edge2)
392
self.assertTrue(len(res) == 1)
393
self.assertEqual(res[0][0], 6.0)
394
self.assertEqual(res[0][1], 10.0)
395
self.assertEqual(res[0][2], 10.0)
397
def testIntersectionOfParallelEdges(self):
398
self.planarMesh.append([0.0, 10.0, 10.0])
399
self.planarMesh.append([10.0, 0.0, 10.0])
400
self.planarMesh.append([10.0, 10.0, 10.0])
401
self.planarMesh.append([6.0, 8.0, 10.0])
402
self.planarMesh.append([16.0, 8.0, 10.0])
403
self.planarMesh.append([6.0, 18.0, 10.0])
404
planarMeshObject = Mesh.Mesh(self.planarMesh)
406
edge1 = planarMeshObject.Facets[0].getEdge(2)
407
edge2 = planarMeshObject.Facets[1].getEdge(0)
408
res = edge1.intersectWithEdge(edge2)
409
self.assertTrue(len(res) == 0)
411
def testIntersectionOfCollinearEdges(self):
412
self.planarMesh.append([0.0, 0.0, 0.0])
413
self.planarMesh.append([6.0, 0.0, 0.0])
414
self.planarMesh.append([3.0, 4.0, 0.0])
415
self.planarMesh.append([7.0, 0.0, 0.0])
416
self.planarMesh.append([13.0, 0.0, 0.0])
417
self.planarMesh.append([10.0, 4.0, 0.0])
418
planarMeshObject = Mesh.Mesh(self.planarMesh)
420
edge1 = planarMeshObject.Facets[0].getEdge(0)
421
edge2 = planarMeshObject.Facets[1].getEdge(0)
422
res = edge1.intersectWithEdge(edge2)
423
self.assertTrue(len(res) == 0)
425
def testIntersectionOfWarpedEdges(self):
426
self.planarMesh.append([0.0, 0.0, 0.0])
427
self.planarMesh.append([6.0, 0.0, 0.0])
428
self.planarMesh.append([3.0, 4.0, 0.0])
429
self.planarMesh.append([2.0, 2.0, 1.0])
430
self.planarMesh.append([8.0, 2.0, 1.0])
431
self.planarMesh.append([5.0, 6.0, 1.0])
432
planarMeshObject = Mesh.Mesh(self.planarMesh)
434
edge1 = planarMeshObject.Facets[0].getEdge(1)
435
edge2 = planarMeshObject.Facets[1].getEdge(0)
436
res = edge1.intersectWithEdge(edge2)
437
self.assertTrue(len(res) == 0)
439
def testSelfIntersection(self):
441
facet normal 0.0e0 0.0e0 1.0e1
443
vertex 0.0e1 0.0e1 1.0e1
444
vertex 0.0e1 +1.0e1 1.0e1
445
vertex +1.0e1 0.0e1 1.0e1
448
facet normal 0.0e0 0.0e0 1.0e1
450
vertex 0.0e1 +1.0e1 1.0e1
451
vertex +1.0e1 0.0e1 1.0e1
452
vertex 1.0e1 1.0e1 1.0e1
455
facet normal 0.0e0 0.0e0 1.0e1
457
vertex 0.0e1 0.0e1 1.0e1
458
vertex 0.0e1 +1.0e1 1.0e1
459
vertex -1.0e1 1.0e1 1.0e1
462
facet normal 0.0e0 0.0e0 1.0e1
464
vertex 0.0e1 0.0e1 1.0e1
465
vertex +1.0e1 0.0e1 1.0e1
466
vertex +1.0e1 -1.0e1 1.0e1
469
facet normal 0.0e0 0.0e0 1.0e1
471
vertex 0.6e1 0.8e1 1.0e1
472
vertex +1.6e1 0.8e1 1.0e1
473
vertex +0.6e1 1.8e1 1.0e1
479
mesh.read(Stream=data, Format="AST")
480
self.assertTrue(mesh.hasSelfIntersections())
483
class PivyTestCases(unittest.TestCase):
487
FreeCAD.newDocument("MeshTest")
489
def testRayPick(self):
490
if not FreeCAD.GuiUp:
492
self.planarMesh.append([-16.097176, -29.891157, 15.987688])
493
self.planarMesh.append([-16.176304, -29.859991, 15.947966])
494
self.planarMesh.append([-16.071451, -29.900553, 15.912505])
495
self.planarMesh.append([-16.092241, -29.893408, 16.020439])
496
self.planarMesh.append([-16.007210, -29.926180, 15.967641])
497
self.planarMesh.append([-16.064457, -29.904951, 16.090832])
498
planarMeshObject = Mesh.Mesh(self.planarMesh)
500
from pivy import coin
503
Mesh.show(planarMeshObject)
504
view = FreeCADGui.ActiveDocument.ActiveView.getViewer()
505
rp = coin.SoRayPickAction(view.getSoRenderManager().getViewportRegion())
506
rp.setRay(coin.SbVec3f(-16.05, 16.0, 16.0), coin.SbVec3f(0, -1, 0))
507
rp.apply(view.getSoRenderManager().getSceneGraph())
508
pp = rp.getPickedPoint()
509
self.assertTrue(pp is not None)
511
self.assertTrue(det.getTypeId() == coin.SoFaceDetail.getClassTypeId())
512
det = coin.cast(det, det.getTypeId().getName().getString())
513
self.assertTrue(det.getFaceIndex() == 1)
515
def testPrimitiveCount(self):
516
if not FreeCAD.GuiUp:
518
self.planarMesh.append([-16.097176, -29.891157, 15.987688])
519
self.planarMesh.append([-16.176304, -29.859991, 15.947966])
520
self.planarMesh.append([-16.071451, -29.900553, 15.912505])
521
self.planarMesh.append([-16.092241, -29.893408, 16.020439])
522
self.planarMesh.append([-16.007210, -29.926180, 15.967641])
523
self.planarMesh.append([-16.064457, -29.904951, 16.090832])
524
planarMeshObject = Mesh.Mesh(self.planarMesh)
526
from pivy import coin
529
Mesh.show(planarMeshObject)
530
view = FreeCADGui.ActiveDocument.ActiveView
531
view.setAxisCross(False)
532
pc = coin.SoGetPrimitiveCountAction()
533
pc.apply(view.getSceneGraph())
534
self.assertTrue(pc.getTriangleCount() == 2)
539
FreeCAD.closeDocument("MeshTest")
556
mesh = Mesh.createSphere(r, s)
560
class LoadMeshInThreadsCases(unittest.TestCase):
564
def testSphereMesh(self):
565
for i in range(6, 8):
566
thread.start_new(createMesh, (10.0, (i + 1) * 20))
569
def testLoadMesh(self):
570
mesh = Mesh.createSphere(10.0, 100)
571
name = tempfile.gettempdir() + os.sep + "mesh.stl"
576
thread.start_new(loadFile, (name,))
583
class PolynomialFitCases(unittest.TestCase):
587
def testFitGood(self):
590
v.append(FreeCAD.Vector(0, 0, 0.0))
591
v.append(FreeCAD.Vector(1, 0, 0.5))
592
v.append(FreeCAD.Vector(2, 0, 0.0))
593
v.append(FreeCAD.Vector(0, 1, 0.5))
594
v.append(FreeCAD.Vector(1, 1, 1.0))
595
v.append(FreeCAD.Vector(2, 1, 0.5))
596
v.append(FreeCAD.Vector(0, 2, 0.0))
597
v.append(FreeCAD.Vector(1, 2, 0.5))
598
v.append(FreeCAD.Vector(2, 2, 0.0))
599
d = Mesh.polynomialFit(v)
600
c = d["Coefficients"]
602
for i in d["Residuals"]:
603
self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i))
605
def testFitExact(self):
608
v.append(FreeCAD.Vector(0, 0, 0.0))
609
v.append(FreeCAD.Vector(1, 0, 0.0))
610
v.append(FreeCAD.Vector(2, 0, 0.0))
611
v.append(FreeCAD.Vector(0, 1, 0.0))
612
v.append(FreeCAD.Vector(1, 1, 1.0))
613
v.append(FreeCAD.Vector(2, 1, 0.0))
614
d = Mesh.polynomialFit(v)
615
c = d["Coefficients"]
617
for i in d["Residuals"]:
618
self.assertTrue(math.fabs(i) < 0.0001, "Too high residual %f" % math.fabs(i))
620
def testFitBad(self):
623
v.append(FreeCAD.Vector(0, 0, 0.0))
624
v.append(FreeCAD.Vector(1, 0, 0.0))
625
v.append(FreeCAD.Vector(2, 0, 0.0))
626
v.append(FreeCAD.Vector(0, 1, 0.0))
627
v.append(FreeCAD.Vector(1, 1, 1.0))
628
v.append(FreeCAD.Vector(2, 1, 0.0))
629
v.append(FreeCAD.Vector(0, 2, 0.0))
630
v.append(FreeCAD.Vector(1, 2, 0.0))
631
v.append(FreeCAD.Vector(2, 2, 0.0))
632
d = Mesh.polynomialFit(v)
633
c = d["Coefficients"]
635
for i in d["Residuals"]:
636
self.assertFalse(math.fabs(i) < 0.0001, "Residual %f must be higher" % math.fabs(i))
642
class NastranReader(unittest.TestCase):
644
self.test_dir = join(FreeCAD.getHomePath(), "Mod", "Mesh", "App", "TestData")
646
def testEightCharGRIDElement(self):
647
m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRID_CQUAD4.bdf")
648
self.assertEqual(m.CountPoints, 10)
649
self.assertEqual(m.CountFacets, 8)
651
def testDelimitedGRIDElement(self):
652
m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_Delimited_GRID_CQUAD4.bdf")
653
self.assertEqual(m.CountPoints, 10)
654
self.assertEqual(m.CountFacets, 8)
656
def testSixteenCharGRIDElement(self):
657
m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRIDSTAR_CQUAD4.bdf")
658
self.assertEqual(m.CountPoints, 4)
659
self.assertEqual(m.CountFacets, 2)
661
def testCTRIA3Element(self):
662
m = Mesh.read(f"{self.test_dir}/NASTRAN_Test_GRID_CTRIA3.bdf")
663
self.assertEqual(m.CountPoints, 3)
664
self.assertEqual(m.CountFacets, 1)
670
class MeshSubElement(unittest.TestCase):
672
self.mesh = Mesh.createBox(1.0, 1.0, 1.0)
674
def testCenterOfGravity(self):
675
c = self.mesh.CenterOfGravity
676
self.assertEqual(c, Base.Vector(0.0, 0.0, 0.0))
678
def testSubElements(self):
679
types = self.mesh.getElementTypes()
680
self.assertIn("Mesh", types)
681
self.assertIn("Segment", types)
683
def testCountSubElements(self):
684
self.assertEqual(self.mesh.countSubElements("Mesh"), 1)
685
self.assertEqual(self.mesh.countSubElements("Segment"), 0)
687
def testFacesFromSubElement(self):
688
element = self.mesh.getFacesFromSubElement("Mesh", 0)
689
self.assertIsInstance(element, tuple)
690
self.assertEqual(len(element), 2)
691
self.assertEqual(len(element[0]), 8)
692
self.assertEqual(len(element[1]), 12)
694
def testSegmentSubElement(self):
695
self.mesh.addSegment([0, 2, 4, 6, 8])
696
self.assertEqual(self.mesh.countSegments(), 1)
697
self.assertEqual(self.mesh.countSubElements("Segment"), 1)
698
element = self.mesh.getFacesFromSubElement("Segment", 0)
699
self.assertIsInstance(element, tuple)
700
self.assertEqual(len(element), 2)
701
self.assertEqual(len(element[0]), 7)
702
self.assertEqual(len(element[1]), 5)
703
segment = self.mesh.meshFromSegment(self.mesh.getSegment(0))
704
self.assertEqual(segment.CountPoints, 7)
705
self.assertEqual(segment.CountFacets, 5)
711
class MeshProperty(unittest.TestCase):
713
self.doc = FreeCAD.newDocument("MeshTest")
716
FreeCAD.closeDocument(self.doc.Name)
718
def testMaterial(self):
719
mesh = self.doc.addObject("Mesh::Feature", "Sphere")
720
mesh.Mesh = Mesh.createBox(1.0, 1.0, 1.0)
721
len1 = int(mesh.Mesh.CountFacets / 2)
722
len2 = int(mesh.Mesh.CountFacets - len1)
723
material = {"transparency": [0.2] * len1 + [0.8] * len2}
724
material["binding"] = MeshEnums.Binding.PER_FACE
725
material["ambientColor"] = [(1, 0, 0)] * (len1 + len2)
726
material["diffuseColor"] = [(0, 1, 0)] * (len1 + len2)
727
material["specularColor"] = [(0, 0, 1)] * (len1 + len2)
728
material["emissiveColor"] = [(1, 1, 1)] * (len1 + len2)
729
material["shininess"] = [0.3] * (len1 + len2)
731
mesh.addProperty("Mesh::PropertyMaterial", "Material")
732
mesh.Material = material
734
TempPath = tempfile.gettempdir()
735
SaveName = TempPath + os.sep + "mesh_with_material.FCStd"
736
self.doc.saveAs(SaveName)
737
FreeCAD.closeDocument(self.doc.Name)
739
self.doc = FreeCAD.openDocument(SaveName)
740
mesh2 = self.doc.Sphere
741
material2 = mesh2.Material
743
self.assertEqual(int(material2["binding"]), int(MeshEnums.Binding.PER_FACE))
744
self.assertEqual(len(material2["ambientColor"]), len1 + len2)
745
self.assertEqual(len(material2["diffuseColor"]), len1 + len2)
746
self.assertEqual(len(material2["specularColor"]), len1 + len2)
747
self.assertEqual(len(material2["emissiveColor"]), len1 + len2)
748
self.assertEqual(len(material2["shininess"]), len1 + len2)
749
self.assertEqual(len(material2["transparency"]), len1 + len2)