forked from gilbo/cork
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest.py
112 lines (90 loc) · 3.87 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
"""
This file is part of the Cork library.
Cork is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Cork is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy
of the GNU Lesser General Public License
along with Cork. If not, see <http://www.gnu.org/licenses/>.
"""
"""
Test that the python bindings produce the same answer as the c program
on the sample input.
For this to work, you must edit src/util/prelude.h and change initRand
to have an srand(0) in it, so we can get the same results from both
runs.
@author Stephen Dawson-Haggerty <[email protected]>
"""
import os
import unittest
import subprocess
import numpy as np
import ctypes
import ctypes.util
import _cork
class TestPythonBindings(unittest.TestCase):
"""Compare the output of the cork binary to the python library
"""
BALL_A = os.path.join(os.path.dirname(__file__),
"../samples/ballA.off")
BALL_B = os.path.join(os.path.dirname(__file__),
"../samples/ballB.off")
@staticmethod
def read_mesh(f):
fp = open(f, "r")
fp.readline()
dims = map(int, fp.readline().split(" "))
triangles, vertices = [], []
for i in xrange(0, dims[0]):
vertices.append(map(float, fp.readline().split(" ") ))
for i in xrange(0, dims[1]):
triangles.append(map(float, fp.readline().split(" ")[1:] ))
return triangles, vertices
def call_cork(self, method):
args = [os.path.join(os.path.dirname(__file__), '../bin/cork'),
'-' + method,
self.BALL_A, self.BALL_B, '/tmp/_temp_mesh.off']
subprocess.check_call(args)
return self.read_mesh('/tmp/_temp_mesh.off')
def assertTriMeshEquals(self, a, b):
t1, v1 = a
t2, v2 = b
# assert these are close
self.assertTrue((np.sum(np.abs(v1 - v2)) / np.sum(np.abs(v1))) < 1e-6)
# these should be equal since they're integers to begin with
self.assertEqual(np.sum(np.abs(t1 - t2)), 0)
def setUp(self):
self.ballA = self.read_mesh(self.BALL_A)
self.ballB = self.read_mesh(self.BALL_B)
# are we having fun yet? cork uses srand to seed the crappy
# PRNG, but doesn't have a way to reset it. This way we can
# call it between runs so we get the same answer every time.
libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
libc.srand(0)
def testIsSolid(self):
"""Both demo objects are solid
"""
self.assertTrue(_cork.isSolid(self.ballA))
self.assertTrue(_cork.isSolid(self.ballB))
def testUnion(self):
self.assertTriMeshEquals(_cork.computeUnion(self.ballA, self.ballB),
self.call_cork('union'))
def testDifference(self):
self.assertTriMeshEquals(_cork.computeDifference(self.ballA, self.ballB),
self.call_cork('diff'))
def testIntersection(self):
self.assertTriMeshEquals(_cork.computeIntersection(self.ballA, self.ballB),
self.call_cork('isct'))
def testSymmetricDifference(self):
self.assertTriMeshEquals(_cork.computeSymmetricDifference(self.ballA, self.ballB),
self.call_cork('xor'))
def testResolve(self):
self.assertTriMeshEquals(_cork.resolveIntersections(self.ballA, self.ballB),
self.call_cork('resolve'))
if __name__ == '__main__':
unittest.main()