1#!@PYTHON@
2
3#
4# SPDX-License-Identifier: BSD-3-Clause
5# Copyright Contributors to the OpenEXR Project.
6#
7
8from imath import *
9from math import sqrt, pi, sin, cos
10import math
11import string, traceback, sys
12import random
13
14testList = []
15
16# -----------------------------------------------------------------
17# Test helper functions
18# -----------------------------------------------------------------
19
20ArrayBaseType = {}
21ArrayBaseType[V2sArray] = V2s
22ArrayBaseType[V2iArray] = V2i
23ArrayBaseType[V2fArray] = V2f
24ArrayBaseType[V2dArray] = V2d
25ArrayBaseType[V3sArray] = V3s
26ArrayBaseType[V3iArray] = V3i
27ArrayBaseType[V3fArray] = V3f
28ArrayBaseType[V3dArray] = V3d
29
30VecBaseType = {}
31VecBaseType[V2s] = int
32VecBaseType[V2i] = int
33VecBaseType[V2f] = float
34VecBaseType[V2d] = float
35VecBaseType[V3s] = int
36VecBaseType[V3i] = int
37VecBaseType[V3f] = float
38VecBaseType[V3d] = float
39
40eps = 10*FLT_EPS
41
42def dimensions(baseType):
43    if hasattr(baseType, 'dimensions'):
44        return baseType.dimensions()
45    else:
46        return 1
47
48def numNonZeroMaskEntries(mask):
49    count = 0
50    for i in range(0, len(mask)):
51        if mask[i]:
52            count += 1
53    return count
54
55def equalWithAbsErrorScalar(x1, x2, e):
56    return abs(x1 - x2) < e
57
58def make_range(start, end):
59    num = end-start
60    increment = 1
61    if num < 0:
62        num = -num;
63        increment = -1
64
65    retval = IntArray(num)
66    val = start
67    for i in range(0, num):
68        retval[i] = val
69        val += increment
70
71    return retval
72
73# We want to be able to use the test helper
74# functions generically with different array types
75# so we use hasattr to check if the arguments support
76# [] operator.  This is sufficient to distinguish
77# between vector and scalar types for our purposes here
78
79def equalWithAbsError(x1, x2, e):
80    if hasattr(x1, '__len__') and hasattr(x1, '__getitem__') and hasattr(x2, '__len__') and hasattr(x2, '__getitem__'):
81        assert(len(x1) == len(x2))
82        for i in range(0, len(x1)):
83            if not equalWithAbsErrorScalar(x1[i], x2[i], e):
84                return False
85        return True
86    else:
87        return equalWithAbsErrorScalar(x1, x2, e)
88
89def equalWithRelErrorScalar(x1, x2, e):
90    return abs(x1 - x2) <= e * abs(x1)
91
92def equalWithRelError(x1, x2, e):
93    if hasattr(x1, '__len__') and hasattr(x1, '__getitem__') and hasattr(x2, '__len__') and hasattr(x2, '__getitem__'):
94        assert(len(x1) == len(x2))
95        for i in range(0, len(x1)):
96            if not equalWithRelErrorScalar(x1[i], x2[i], e):
97                return False
98        return True
99    else:
100        return equalWithRelErrorScalar(x1, x2, e)
101
102def testVectorVectorArithmeticOps(f1, f2):
103    f = f1 + f2
104    assert(len(f) == len(f1))
105    for i in range(0, len(f)):
106        assert(f[i] == f1[i] + f2[i])
107
108    f = f1 - f2
109    assert(len(f) == len(f1))
110    for i in range(0, len(f)):
111        assert(f[i] == f1[i] - f2[i])
112
113    f = f1 * f2
114    assert(len(f) == len(f1))
115    for i in range(0, len(f)):
116        assert(f[i] == f1[i] * f2[i])
117
118    f = f1 / f2
119    assert(len(f) == len(f1))
120
121    if isinstance(f,IntArray) or isinstance(f,ShortArray):
122        op = lambda a,b : a // b
123    else:
124        op = lambda a,b : a / b
125    for i in range(0, len(f)):
126        assert(equalWithAbsError(f[i], op(f1[i],f2[i]), eps))
127
128    f = -f1
129    assert(len(f) == len(f1))
130    for i in range(0, len(f)):
131        assert(f[i] == -f1[i])
132
133def testVectorScalarArithmeticOps(f1, v):
134    f = f1 + v
135    assert(len(f) == len(f1))
136    for i in range(0, len(f)):
137        assert(f[i] == f1[i] + v)
138
139    f = v + f1
140    assert(len(f) == len(f1))
141    for i in range(0, len(f)):
142        assert(f[i] == v + f1[i])
143
144    f = f1 - v
145    assert(len(f) == len(f1))
146    for i in range(0, len(f)):
147        assert(f[i] == f1[i] - v)
148
149    f = v - f1
150    assert(len(f) == len(f1))
151    for i in range(0, len(f)):
152        if f[i] != v - f1[i]:
153            assert(f[i] == v - f1[i])
154
155    f = f1 * v
156    assert(len(f) == len(f1))
157    for i in range(0, len(f)):
158        assert(f[i] == f1[i] * v)
159
160    f = v * f1
161    assert(len(f) == len(f1))
162    for i in range(0, len(f)):
163        assert(f[i] == v * f1[i])
164
165    f = f1 / v
166    assert(len(f) == len(f1))
167    if isinstance(f,IntArray) or isinstance(f,ShortArray):
168        op = lambda a,b : a // b
169    else:
170        op = lambda a,b : a / b
171    for i in range(0, len(f)):
172        assert(equalWithAbsError(f[i], op(f1[i],v), eps))
173
174
175def testVectorVectorInPlaceArithmeticOps(f1, f2):
176    f = f1[:]
177    f += f2
178
179    assert(len(f) == len(f1))
180    for i in range(0, len(f)):
181        assert(f[i] == f1[i] + f2[i])
182
183    f = f1[:]
184    f -= f2
185    assert(len(f) == len(f1))
186    for i in range(0, len(f)):
187        assert(f[i] == f1[i] - f2[i])
188
189    f = f1[:]
190    f *= f2
191    assert(len(f) == len(f1))
192    for i in range(0, len(f)):
193        assert(f[i] == f1[i] * f2[i])
194
195    f = f1[:]
196    f /= f2
197    assert(len(f) == len(f1))
198    if isinstance(f,IntArray) or isinstance(f,ShortArray):
199        op = lambda a,b : a // b
200    else:
201        op = lambda a,b : a / b
202    for i in range(0, len(f)):
203        assert(equalWithAbsError(f[i], op(f1[i],f2[i]), eps))
204
205    f = f1[:]
206    f = -f;
207    assert(len(f) == len(f1))
208    for i in range(0, len(f)):
209        assert(f[i] == -f1[i])
210
211def testVectorScalarInPlaceArithmeticOps(f1, v):
212    f = f1[:]
213    f += v
214    assert(len(f) == len(f1))
215    for i in range(0, len(f)):
216        assert(f[i] == f1[i] + v)
217
218    f = f1[:]
219    f -= v
220    assert(len(f) == len(f1))
221    for i in range(0, len(f)):
222        assert(f[i] == f1[i] - v)
223
224    f = f1[:]
225    f *= v
226    assert(len(f) == len(f1))
227    for i in range(0, len(f)):
228        assert(f[i] == f1[i] * v)
229
230    f = f1[:]
231    f /= v
232    assert(len(f) == len(f1))
233    if isinstance(f,IntArray) or isinstance(f,ShortArray):
234        op = lambda a,b : a // b
235    else:
236        op = lambda a,b : a / b
237    for i in range(0, len(f)):
238        assert(equalWithAbsError(f[i], op(f1[i],v), eps))
239
240def testPowFunctions(f1, f2):
241    # vector-vector pow
242    assert(len(f1) == len(f2))
243    f = pow(f1, f2)
244    assert(len(f) == len(f1))
245    for i in range(0, len(f)):
246        assert(equalWithRelError(f[i], pow(f1[i], f2[i]), eps))
247
248    f  = f1 ** f2
249    assert(len(f) == len(f1))
250    for i in range(0, len(f)):
251        assert(equalWithRelError(f[i], f1[i] ** f2[i], eps))
252
253    # vector-scalar pow
254    v = f2[0]
255    f = pow(f1, v)
256    assert(len(f) == len(f1))
257    for i in range(0, len(f)):
258        assert(equalWithRelError(f[i], pow(f1[i], v), eps))
259
260    # in-place vector-vector pow
261    f = f1[:]
262    f **= f2
263    assert(len(f) == len(f1))
264    for i in range(0, len(f)):
265        assert(equalWithRelError(f[i], pow(f1[i], f2[i]), eps))
266
267    # in-place vector-scalar pow
268    f = f1[:]
269    v = f2[0]
270    f **= v
271    assert(len(f) == len(f1))
272    for i in range(0, len(f)):
273        assert(equalWithRelError(f[i], f1[i] ** v, eps))
274
275def testModOps(f1, f2):
276    f = f1 % f2
277    assert(len(f) == len(f1))
278    for i in range(0, len(f)):
279        assert(f[i] == f1[i] % f2[i])
280
281    v = f2[0]
282    f = f1 % v
283    assert(len(f) == len(f1))
284    for i in range(0, len(f)):
285        assert(f[i] == f1[i] %v)
286
287    f = f1[:]
288    f %= f2
289    assert(len(f) == len(f1))
290    for i in range(0, len(f)):
291        assert(f[i] == f1[i] % f2[i])
292
293
294def testVectorVectorComparisonOps(f1, f2):
295    f = f1 == f2
296    assert(len(f) == len(f1))
297    for i in range(0, len(f)):
298        if (f1[i] == f2[i]):
299            assert(f[i] == 1)
300        else:
301            assert(f[i] == 0)
302
303    f = f1 != f2
304    assert(len(f) == len(f1))
305    for i in range(0, len(f)):
306        if (f1[i] != f2[i]):
307            assert(f[i] == 1)
308        else:
309            assert(f[i] == 0)
310
311def testVectorVectorInequalityOps(f1, f2):
312    f = f1 < f2
313    assert(len(f) == len(f1))
314    for i in range(0, len(f)):
315        if (f1[i] < f2[i]):
316            assert(f[i] == 1)
317        else:
318            assert(f[i] == 0)
319
320    f = f1 > f2
321    assert(len(f) == len(f1))
322    for i in range(0, len(f)):
323        if (f1[i] > f2[i]):
324            assert(f[i] == 1)
325        else:
326            assert(f[i] == 0)
327
328    f = f1 <= f2
329    for i in range(0, len(f)):
330        if (f1[i] <= f2[i]):
331            assert(f[i] == 1)
332        else:
333            assert(f[i] == 0)
334
335    f = f1 >= f2
336    for i in range(0, len(f)):
337        if (f1[i] >= f2[i]):
338            assert(f[i] == 1)
339        else:
340            assert(f[i] == 0)
341
342def testVectorScalarComparisonOps(f1, v):
343    f = f1 == v
344    assert(len(f) == len(f1))
345    for i in range(0, len(f)):
346        if (f1[i] == v):
347            assert(f[i] == 1)
348        else:
349            assert(f[i] == 0)
350
351    f = v == f1
352    assert(len(f) == len(f1))
353    for i in range(0, len(f)):
354        if (v == f1[i]):
355            assert(f[i] == 1)
356        else:
357            assert(f[i] == 0)
358
359    f = f1 != v
360    assert(len(f) == len(f1))
361    for i in range(0, len(f)):
362        if (f1[i] != v):
363            assert(f[i] == 1)
364        else:
365            assert(f[i] == 0)
366
367    f = v != f1
368    assert(len(f) == len(f1))
369    for i in range(0, len(f)):
370        if (v != f1[i]):
371            assert(f[i] == 1)
372        else:
373            assert(f[i] == 0)
374
375def testVectorScalarInequalityOps(f1, v):
376    f = f1 < v
377    assert(len(f) == len(f1))
378    for i in range(0, len(f)):
379        if (f1[i] < v):
380            assert(f[i] == 1)
381        else:
382            assert(f[i] == 0)
383
384    f = v < f1
385    assert(len(f) == len(f1))
386    for i in range(0, len(f)):
387        if (v < f1[i]):
388            assert(f[i] == 1)
389        else:
390            assert(f[i] == 0)
391
392    f = f1 > v
393    assert(len(f) == len(f1))
394    for i in range(0, len(f)):
395        if (f1[i] > v):
396            assert(f[i] == 1)
397        else:
398            assert(f[i] == 0)
399
400    f = v > f1
401    assert(len(f) == len(f1))
402    for i in range(0, len(f)):
403        if (v > f1[i]):
404            assert(f[i] == 1)
405        else:
406            assert(f[i] == 0)
407
408    f = f1 <= v
409    for i in range(0, len(f)):
410        if (f1[i] <= v):
411            assert(f[i] == 1)
412        else:
413            assert(f[i] == 0)
414
415    f = v <= f1
416    for i in range(0, len(f)):
417        if (v <= f1[i]):
418            assert(f[i] == 1)
419        else:
420            assert(f[i] == 0)
421
422    f = f1 >= v
423    for i in range(0, len(f)):
424        if (f1[i] >= v):
425            assert(f[i] == 1)
426        else:
427            assert(f[i] == 0)
428
429    f = v >= f1
430    for i in range(0, len(f)):
431        if (v >= f1[i]):
432            assert(f[i] == 1)
433        else:
434            assert(f[i] == 0)
435
436
437# f1 and f2 are assumed to be unmasked arrays of the same length
438def testVectorVectorMaskedInPlaceArithmeticOps(f1, f2, m):
439    assert(len(f1) == len(f2))
440
441    f = f1[:]
442    f[m] += f2
443    for i in range(0, len(m)):
444        if m[i]: assert(f[i] == f1[i] + f2[i])
445
446    f = f1[:]
447    f[m] -= f2
448    for i in range(0, len(m)):
449        if m[i]: assert(f[i] == f1[i] - f2[i])
450
451    f = f1[:]
452    f[m] *= f2
453    for i in range(0, len(m)):
454        if m[i]: assert(f[i] == f1[i] * f2[i])
455
456    f = f1[:]
457    f[m] /= f2
458    if isinstance(f,IntArray) or isinstance(f,ShortArray):
459        op = lambda a,b : a // b
460    else:
461        op = lambda a,b : a / b
462    for i in range(0, len(m)):
463        if m[i]: assert(equalWithAbsError(f[i], op(f1[i],f2[i]), eps))
464
465    f = f1[:]
466    f[m] = -f
467    for i in range(0, len(m)):
468        if m[i]: assert(f[i] == -f1[i])
469
470# f1 is assumed to be an unmasked array and f2 is a masked
471# or unmasked array such that len(f2) == len(f1[m])
472def testVectorVectorMaskedInPlaceArithmeticOps2(f1, f2, m):
473    assert(len(f1[m]) == len(f2))
474    f = f1[:]
475    f1m = f1[m]
476    f[m] += f2
477    fm = f[m]
478
479    for i in range(0, len(fm)):
480        assert(fm[i] == f1m[i] + f2[i])
481
482    for i in range(0, len(m)):
483        if m[i] == 0:
484            assert(f[i] == f1[i])
485
486    f = f1[:]
487    f[m] -= f2
488    fm = f[m]
489
490    for i in range(0, len(fm)):
491        assert(fm[i] == f1m[i] - f2[i])
492
493    for i in range(0, len(m)):
494        if m[i] == 0:
495            assert(f[i] == f1[i])
496
497    f = f1[:]
498    f[m] *= f2
499    fm = f[m]
500
501    for i in range(0, len(fm)):
502        assert(fm[i] == f1m[i] * f2[i])
503
504    for i in range(0, len(m)):
505        if m[i] == 0:
506            assert(f[i] == f1[i])
507
508    f = f1[:]
509    f[m] /= f2
510    fm = f[m]
511
512    if isinstance(f,IntArray) or isinstance(f,ShortArray):
513        op = lambda a,b : a // b
514    else:
515        op = lambda a,b : a / b
516    for i in range(0, len(fm)):
517        assert(equalWithAbsError(fm[i], op(f1m[i],f2[i]), eps))
518
519    for i in range(0, len(m)):
520        if m[i] == 0:
521            assert(f[i] == f1[i])
522
523def testVectorVectorMaskedArithmeticOps(f1, f2, f3, m):
524    f = f3[:]
525    f[m] = f1[m] + f2[m]
526    for i in range(0, len(m)):
527        if m[i]: assert(f[i] == f1[i] + f2[i])
528        else:    assert(f[i] == f3[i])
529
530    f = f3[:]
531    f[m] = f1[m] - f2[m]
532    for i in range(0, len(m)):
533        if m[i]: assert(f[i] == f1[i] - f2[i])
534        else:    assert(f[i] == f3[i])
535
536    f = f3[:]
537    f[m] = f1[m] * f2[m]
538    for i in range(0, len(m)):
539        if m[i]: assert(f[i] == f1[i] * f2[i])
540        else:    assert(f[i] == f3[i])
541
542    f = f3[:]
543    f[m] = f1[m] / f2[m]
544    if isinstance(f,IntArray) or isinstance(f,ShortArray):
545        op = lambda a,b : a // b
546    else:
547        op = lambda a,b : a / b
548    for i in range(0, len(m)):
549        if m[i]: assert(equalWithRelError(f[i], op(f1[i],f2[i]), eps))
550        else:    assert(f[i] == f3[i])
551
552
553def testUnaryVecMethods(f):
554    g = f.length2()
555    assert(len(g) == len(f))
556    for i in range(0, len(f)):
557        assert(g[i] == f[i].length2())
558
559    # Normalization and length only makes sense for these types
560    if type(f) in [V2fArray, V2dArray, V3fArray, V3dArray]:
561        g = f.length()
562        assert(len(g) == len(f))
563        for i in range(0, len(f)):
564            assert(equalWithRelError(g[i], f[i].length(), eps))
565
566        g = f[:]
567        g.normalize()
568        assert(len(g) == len(f))
569        for i in range(0, len(f)):
570            assert(g[i] == f[i].normalized())
571
572        g = f.normalized()
573        assert(len(g) == len(f))
574        for i in range(0, len(f)):
575            assert(g[i] == f[i].normalized())
576
577
578def testBinaryVecMethods(f1, f2):
579    f = f1.dot(f2)
580    assert(len(f) == len(f1))
581    for i in range(0, len(f)):
582        assert(f[i] == f1[i].dot(f2[i]))
583
584    assert(f1.dot(f2) == f2.dot(f1))
585
586    f = f1.cross(f2)
587    assert(len(f) == len(f1))
588    for i in range(0, len(f)):
589        assert(equalWithAbsError(f[i], f1[i].cross(f2[i]), eps))
590
591    assert(f1.cross(f2) == -f2.cross(f1))
592
593    v = f2[0]
594    f = f1.dot(v)
595    assert(len(f) == len(f1))
596    for i in range(0, len(f)):
597        assert(f[i] == f1[i].dot(v))
598
599    assert(f1.dot(v) == v.dot(f1))
600
601    f = f1.cross(v)
602    assert(len(f) == len(f1))
603    for i in range(0, len(f)):
604        assert(equalWithAbsError(f[i], f1[i].cross(v), eps))
605
606    assert(f1.cross(v) == -v.cross(f1))
607
608
609def assertVectorVectorArithmeticOpFailures(f1, f2):
610    try:
611        f = f1 + f2
612    except:
613        pass
614    else:
615        assert(False)
616
617    try:
618        f = f1 - f2
619    except:
620        pass
621    else:
622        assert(False)
623
624    try:
625        f = f1 * f2
626    except:
627        pass
628    else:
629        assert(False)
630
631    try:
632        f = f1 / f2
633    except:
634        pass
635    else:
636        assert(False)
637
638def assertVectorVectorInPlaceArithmeticOpFailures(f1, f2):
639    try:
640        f1 += f2
641    except:
642        pass
643    else:
644        assert(False)
645
646    try:
647        f1 -= f2
648    except:
649        pass
650    else:
651        assert(False)
652
653    try:
654        f1 *= f2
655    except:
656        pass
657    else:
658        assert(False)
659
660    try:
661        f1 /= f2
662    except:
663        pass
664    else:
665        assert(False)
666
667def assertVectorVectorComparisonOpFailures(f1, f2):
668    try:
669        f1 == f2
670    except:
671        pass
672    else:
673        assert(False)
674
675    try:
676        f1 != f2
677    except:
678        pass
679    else:
680        assert(False)
681
682    try:
683        f1 < f2
684    except:
685        pass
686    else:
687        assert(False)
688
689    try:
690        f1 > f2
691    except:
692        pass
693    else:
694        assert(False)
695
696    try:
697        f1 <= f2
698    except:
699        pass
700    else:
701        assert(False)
702
703    try:
704        f1 >= f2
705    except:
706        pass
707    else:
708        assert(False)
709
710def assertPowFunctionFailures(f1, f2):
711    try:
712        f1 ** f2
713    except:
714        pass
715    else:
716        assert(False)
717
718    try:
719        f1 **= f2
720    except:
721        pass
722    else:
723        assert(False)
724
725def assertModOpFailures(f1, f2):
726    try:
727        f1 % f2
728    except:
729        pass
730    else:
731        assert(False)
732
733    try:
734        f1 %= f2
735    except:
736        pass
737    else:
738        assert(False)
739
740def testArrayArrayEquality(a1,a2):
741    assert len(a1) == len(a2)
742    for i in range(0, len(a1)):
743        assert a1[i] == a2[i]
744
745# -----------------------------------------------------------------
746# Begin main test definitions
747# -----------------------------------------------------------------
748
749def testSlicesOnArrayImpl(Array, BaseTypeConstructor):
750
751    # Test the slicing operators on array types.
752    # We use a python list as a reference here.
753
754    size = 4
755
756    a = Array(size)
757    l = []
758
759    for i in range(0,size):
760        n = BaseTypeConstructor(i)
761        a[i] = n
762        l.append(n)
763
764    # Test extraction using slices
765
766    a1 = a[::2]
767    l1 = l[::2]
768    testArrayArrayEquality(a1, l1)
769
770    a2 = a[::-1]
771    l2 = l[::-1]
772    testArrayArrayEquality(a2, l2)
773
774    a3 = a[1:size]
775    l3 = l[1:size]
776    testArrayArrayEquality(a3, l3)
777
778    a4 = a[:size]
779    l4 = l[:size]
780    testArrayArrayEquality(a4, l4)
781
782    a5 = a[:-1]
783    l5 = l[:-1]
784    testArrayArrayEquality(a5, l5)
785
786    a6 = a[1:]
787    l6 = l[1:]
788    testArrayArrayEquality(a6, l6)
789
790    testArrayArrayEquality(a,a[:])
791
792    # Test assignment using slices
793
794    a8 = a
795    l8 = l
796    a8[::2] = a8[::-2]
797    l8[::2] = a8[::-2]
798
799    testArrayArrayEquality(a8,l8)
800
801    try:
802        a9 = a
803        a9[::1] = a9[::2]
804    except:
805        pass
806    else:
807        assert(False)
808
809    # Test that a sliced array does not share
810    # the same internal data
811    a10 = a[:]
812    a10[0] = BaseTypeConstructor(size)
813
814    assert a10[0] != a[0]
815
816def testSlicesOnArray():
817
818    # All fixed arrays except StringArray shares
819    # the same implementation. We just choose
820    # a few samples for testing.
821    testSlicesOnArrayImpl(IntArray, int)
822    testSlicesOnArrayImpl(V3fArray, V3f)
823    testSlicesOnArrayImpl(FloatArray, float)
824    testSlicesOnArrayImpl(StringArray, str)
825
826    print ("ok")
827
828testList.append (('testSlicesOnArray',testSlicesOnArray))
829
830def testNonMaskedFloatTypeArray(FloatTypeArray):
831    f1 = FloatTypeArray(5)
832    assert (len(f1) == 5)
833
834    # Check for correct initialization
835    for i in range(0, len(f1)):
836        assert(f1[i] == 0)
837
838    f1 = FloatTypeArray(1.25, 10)
839    assert(len(f1) == 10)
840    for i in range(0, len(f1)):
841        assert(f1[i] == 1.25)
842
843    # Ensure that an exception is thrown when
844    # we exceed the bounds of the array
845    try:
846        print (f1[10])
847    except:
848        pass
849    else:
850        assert(False)
851
852    # Check element assignment
853    f1[0] = 1.5
854    f1[1] = 2.0
855
856    assert(f1[0] == 1.5)
857    assert(f1[1] == 2.0)
858
859    # Test copy construction
860    f2 = FloatTypeArray(f1)
861    assert(len(f2) == len(f1))
862    for i in range(0, len(f1)):
863        assert f1[i] == f2[i]
864
865    # The same internal data is referenced by both arrays
866    f2[3] = 4.5
867    assert(f2[3] == 4.5)
868    assert(f1[3] == 4.5)
869    f1[4] = 5.5
870    assert(f1[4] == 5.5)
871    assert(f2[4] == 5.5)
872
873    # Test negative indices
874    assert(f2[-1] == f2[len(f2)-1])
875    assert(f2[-2] == f2[len(f2)-2])
876
877    # Test slice operations
878
879    # Copy contents of f1
880    f3 = f1[:]
881    assert(len(f3) == len(f1))
882
883    for i in range(0, len(f1)):
884        assert(f3[i] == f1[i])
885
886    f3[0] = 0.25
887    assert(f3[0] != f1[0])
888
889    f3 = f1[2:4]
890    assert(len(f3) == 2)
891    assert(f3[0] == f1[2] and f3[1] == f1[3])
892
893    # Test array-array operations
894    f1 = FloatTypeArray(5)
895    f2 = FloatTypeArray(5)
896
897    # These values were chosen to allow division operations
898    # to return exact values that can be compared with '=='
899
900    f1[0] = 1.25
901    f1[1] = 2.0
902    f1[2] = 3.0
903    f1[3] = 1.0
904    f1[4] = 3.75
905
906    f2[0] = 5.0
907    f2[1] = 2.0
908    f2[2] = 1.5
909    f2[3] = 2.0
910    f2[4] = 10.0
911
912    testVectorVectorArithmeticOps(f1, f2)
913    testVectorVectorInPlaceArithmeticOps(f1, f2)
914
915    # Test operations for arrays with scalars
916    testVectorScalarArithmeticOps(f1, 1.75)
917    testVectorScalarInPlaceArithmeticOps(f1, 0.25)
918    testVectorScalarComparisonOps(f1, 3.5)
919    testVectorScalarInequalityOps(f1, 3.5)
920
921    # Make sure that operations fail when performed on arrays
922    # of differing lengths
923    f3 = FloatTypeArray(6)
924
925    assertVectorVectorArithmeticOpFailures(f1, f3)
926    assertVectorVectorInPlaceArithmeticOpFailures(f1, f3)
927    assertVectorVectorComparisonOpFailures(f1, f3)
928    assertPowFunctionFailures(f1, f3)
929
930    testPowFunctions(f1, f2)
931
932    print ("ok")
933
934testList.append(('testNonMaskedFloatArray', lambda : testNonMaskedFloatTypeArray(FloatArray)))
935testList.append(('testNonMaskedDoubleArray', lambda : testNonMaskedFloatTypeArray(DoubleArray)))
936
937def testNonMaskedIntTypeArray(IntTypeArray):
938    f1 = IntTypeArray(5)
939    assert (len(f1) == 5)
940
941    # Check for correct initialization
942    for i in range(0, len(f1)):
943        assert(f1[i] == 0)
944
945    f1 = IntTypeArray(3, 10)
946    assert(len(f1) == 10)
947    for i in range(0, len(f1)):
948        assert(f1[i] == 3)
949
950    # Ensure that an exception is thrown when
951    # we exceed the bounds of the array
952    try:
953        print (f1[10])
954    except:
955        pass
956    else:
957        assert(false)
958
959    # Check element assignment
960    f1[0] = 1
961    f1[1] = 2
962
963    assert(f1[0] == 1)
964    assert(f1[1] == 2)
965
966    # Test copy construction
967    f2 = IntTypeArray(f1)
968    assert(len(f2) == len(f1))
969    for i in range(0, len(f1)):
970        assert f1[i] == f2[i]
971
972    # The same internal data is referenced by both arrays
973    f2[3] = 4
974    assert(f2[3] == 4)
975    assert(f1[3] == 4)
976    f1[4] = 5
977    assert(f1[4] == 5)
978    assert(f2[4] == 5)
979
980    # Test negative indices
981    assert(f2[-1] == f2[len(f2)-1])
982    assert(f2[-2] == f2[len(f2)-2])
983
984    # Test slice operations
985
986    # Copy contents of f1
987    f3 = f1[:]
988    assert(len(f3) == len(f1))
989
990    for i in range(0, len(f1)):
991        assert(f3[i] == f1[i])
992
993    f3[0] = 4
994    assert(f3[0] != f1[0])
995
996    f3 = f1[2:4]
997    assert(len(f3) == 2)
998    assert(f3[0] == f1[2] and f3[1] == f1[3])
999
1000    # Test array-array operations
1001    f1 = IntTypeArray(5)
1002    f2 = IntTypeArray(5)
1003
1004    # These values were chosen to allow division operations
1005    # to return exact values that can be compared with '=='
1006
1007    f1[0] = 1
1008    f1[1] = 2
1009    f1[2] = 3
1010    f1[3] = 1
1011    f1[4] = 7
1012
1013    f2[0] = 5
1014    f2[1] = 2
1015    f2[2] = 1
1016    f2[3] = 2
1017    f2[4] = 10
1018
1019    testVectorVectorArithmeticOps(f1, f2)
1020    testVectorVectorInPlaceArithmeticOps(f1, f2)
1021    testVectorVectorComparisonOps(f1, f2)
1022    testVectorVectorInequalityOps(f1, f2)
1023
1024    # Test operations for arrays with scalars
1025    testVectorScalarArithmeticOps(f1, 2)
1026    testVectorScalarInPlaceArithmeticOps(f1, 4)
1027    testVectorScalarComparisonOps(f1, 7)
1028    testVectorScalarInequalityOps(f1, 7)
1029
1030    testModOps(f1, f2)
1031
1032    # Make sure that operations fail when performed on arrays
1033    # of differing lengths
1034    f3 = IntTypeArray(6)
1035
1036    assertVectorVectorArithmeticOpFailures(f1, f3)
1037    assertVectorVectorInPlaceArithmeticOpFailures(f1, f3)
1038    assertVectorVectorComparisonOpFailures(f1, f3)
1039    assertModOpFailures(f1, f3)
1040
1041    print ("ok")
1042
1043testList.append(('testNonMaskedIntArray', lambda : testNonMaskedIntTypeArray(IntArray)))
1044testList.append(('testNonMaskedShortArray', lambda : testNonMaskedIntTypeArray(ShortArray)))
1045#testList.append(('testNonMaskedUnsignedCharArray', lambda : testNonMaskedIntTypeArray(UnsignedCharArray))) # arithmetic tests will fail this
1046
1047def testMaskedFloatTypeArray(FloatTypeArray):
1048    f = FloatTypeArray(10)
1049
1050    f[0] = 1.25
1051    f[1] = 2.5
1052    f[2] = 1.0
1053    f[3] = 1.75
1054    f[4] = 5.25
1055    f[5] = 7.0
1056    f[6] = 4.25
1057    f[7] = 1.0
1058    f[8] = 0.5
1059    f[9] = 3.5
1060
1061    # Ensure we can't create a masked array if the indices don't match
1062    m1 = IntArray(9)
1063    try:
1064        mf = f[m1]
1065    except:
1066        pass
1067    else:
1068        assert(false)
1069
1070    m1 = IntArray(len(f))
1071    m1[0] = 1
1072    m1[1] = 0
1073    m1[2] = 0
1074    m1[3] = 1
1075    m1[4] = 1
1076    m1[5] = 0
1077    m1[6] = 0
1078    m1[7] = 1
1079    m1[8] = 0
1080    m1[9] = 1
1081
1082    # Ensure the masked array reports the correct reduced length
1083    mf = f[m1]
1084    assert(len(mf) == numNonZeroMaskEntries(m1))
1085
1086    # Ensure the masked array holds the correct values
1087    assert(mf[0] == 1.25)
1088    assert(mf[1] == 1.75)
1089    assert(mf[2] == 5.25)
1090    assert(mf[3] == 1.0)
1091    assert(mf[4] == 3.5)
1092
1093    # Masked arrays reference the same internal data
1094    f[9] = 1.75
1095    assert(mf[4] == 1.75)
1096    mf[3] = 10.5
1097    assert(f[7] == 10.5)
1098
1099    # Test copy construction of masked references
1100    g = FloatTypeArray(mf)
1101
1102    # Check slices of masks
1103    s = mf[1:3]
1104    assert(len(s) == 2)
1105    assert(s[0] == mf[1])
1106    assert(s[1] == mf[2])
1107
1108    assert(mf[-1] == mf[len(mf)-1])
1109    assert(mf[-2] == mf[len(mf)-2])
1110
1111    # Check that slices copy (not reference) array data
1112    s = mf[:]
1113    assert(len(s) == len(mf))
1114    for i in range(0, len(mf)):
1115        assert(s[i] == mf[i])
1116
1117    s[0] = 0
1118    assert(s[0] != mf[0])
1119
1120    # Test operations with masked arrays
1121    # Masked arrays should behave exactly as ordinary arrays
1122
1123    m2 = IntArray(len(f))
1124    m2[0] = 1
1125    m2[1] = 0
1126    m2[2] = 1
1127    m2[3] = 0
1128    m2[4] = 1
1129    m2[5] = 1
1130    m2[6] = 0
1131    m2[7] = 0
1132    m2[8] = 1
1133    m2[9] = 1
1134
1135    # m1 and m2 differ in the number of non-zero entries.
1136    # Ensure that arithmetic operations with masked arrays
1137    # cannot proceed if they have differing lengths
1138
1139    mf1 = f[m1]
1140    mf2 = f[m2]
1141
1142    assertVectorVectorInPlaceArithmeticOpFailures(mf1, mf2)
1143
1144    # Test that the operations still fail when the number
1145    # of non-zero mask entries is the same
1146
1147    m2[9] = 0
1148
1149    assert(numNonZeroMaskEntries(m1) == numNonZeroMaskEntries(m2))
1150
1151    mf2 = f[m2]
1152
1153    # Aritmetic operations and comparison ops are supported
1154    testVectorVectorArithmeticOps(mf1, mf2)
1155    testVectorVectorComparisonOps(mf1, mf2)
1156    testVectorVectorInequalityOps(mf1, mf2)
1157
1158    # Test operations between masked arrays and non-masked arrays
1159    assert(len(mf1) == 5);
1160    g = FloatTypeArray(5)
1161    g[0] = 0.25
1162    g[1] = 1.75
1163    g[2] = 3.0
1164    g[3] = 4.25
1165    g[4] = 5.75
1166
1167    testVectorVectorArithmeticOps(g, mf1)
1168    testVectorVectorComparisonOps(g, mf1)
1169    testVectorVectorInequalityOps(g, mf1)
1170
1171    assert(len(f) == 10)
1172    g = FloatTypeArray(10)
1173    g[0] = 0.75
1174    g[1] = 1.25
1175    g[2] = 6.0
1176    g[3] = 4.25
1177    g[4] = 1.5
1178    g[5] = 8.0
1179    g[6] = 3.5
1180    g[7] = 2.0
1181    g[8] = 1.75
1182    g[9] = 6.5
1183
1184    testVectorVectorMaskedInPlaceArithmeticOps(f, g, m1)
1185    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m1], m1)
1186    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m2][:], m1)
1187    testVectorVectorMaskedArithmeticOps(f, g, f / 2.0, m1)
1188
1189    print ("ok")
1190
1191testList.append(('testMaskedFloatArray', lambda : testMaskedFloatTypeArray(FloatArray)))
1192testList.append(('testMaskedDoubleArray', lambda : testMaskedFloatTypeArray(DoubleArray)))
1193
1194
1195def testMaskedIntTypeArray(IntTypeArray):
1196    f = IntTypeArray(10)
1197
1198    f[0] = 1
1199    f[1] = 2
1200    f[2] = 9
1201    f[3] = 1
1202    f[4] = 5
1203    f[5] = 7
1204    f[6] = 4
1205    f[7] = 1
1206    f[8] = 6
1207    f[9] = 3
1208
1209    # Ensure we can't create a masked array if the indices don't match
1210    m1 = IntArray(9)
1211    try:
1212        mf = f[m1]
1213    except:
1214        pass
1215    else:
1216        assert(false)
1217
1218    m1 = IntArray(len(f))
1219    m1[0] = 1
1220    m1[1] = 0
1221    m1[2] = 0
1222    m1[3] = 1
1223    m1[4] = 1
1224    m1[5] = 0
1225    m1[6] = 0
1226    m1[7] = 1
1227    m1[8] = 0
1228    m1[9] = 1
1229
1230    # Ensure the masked array reports the correct reduced length
1231    mf = f[m1]
1232    assert(len(mf) == numNonZeroMaskEntries(m1))
1233
1234    # Ensure the masked array holds the correct values
1235    assert(mf[0] == 1)
1236    assert(mf[1] == 1)
1237    assert(mf[2] == 5)
1238    assert(mf[3] == 1)
1239    assert(mf[4] == 3)
1240
1241    # Masked arrays reference the same internal data
1242    f[9] = 4
1243    assert(mf[4] == 4)
1244    mf[3] = 5
1245    assert(f[7] == 5)
1246
1247    # Test copy construction of masked references
1248    g = IntTypeArray(mf)
1249
1250    # Check slices of masks
1251    s = mf[1:3]
1252    assert(len(s) == 2)
1253    assert(s[0] == mf[1])
1254    assert(s[1] == mf[2])
1255
1256    assert(mf[-1] == mf[len(mf)-1])
1257    assert(mf[-2] == mf[len(mf)-2])
1258
1259    # Check that slices copy (not reference) array data
1260    s = mf[:]
1261    assert(len(s) == len(mf))
1262    for i in range(0, len(mf)):
1263        assert(s[i] == mf[i])
1264
1265    s[0] = 0
1266    assert(s[0] != mf[0])
1267
1268    # Test operations with masked arrays
1269    # Masked arrays should behave exactly as ordinary arrays
1270
1271    m2 = IntArray(len(f))
1272    m2[0] = 1
1273    m2[1] = 0
1274    m2[2] = 1
1275    m2[3] = 0
1276    m2[4] = 1
1277    m2[5] = 1
1278    m2[6] = 0
1279    m2[7] = 0
1280    m2[8] = 1
1281    m2[9] = 1
1282
1283    # m1 and m2 differ in the number of non-zero entries.
1284    # Ensure that arithmetic operations with masked arrays
1285    # cannot proceed if they have differing lengths
1286
1287    mf1 = f[m1]
1288    mf2 = f[m2]
1289
1290    assertVectorVectorInPlaceArithmeticOpFailures(mf1, mf2)
1291
1292    # Test that the operations still fail when the number
1293    # of non-zero mask entries is the same
1294
1295    m2[9] = 0
1296
1297    assert(numNonZeroMaskEntries(m1) == numNonZeroMaskEntries(m2))
1298
1299    mf2 = f[m2]
1300
1301    #assertVectorVectorInPlaceArithmeticOpFailures(mf1, mf2)
1302
1303    # Aritmetic operations and comparison ops are supported
1304    testVectorVectorArithmeticOps(mf1, mf2)
1305    testVectorVectorComparisonOps(mf1, mf2)
1306    testVectorVectorInequalityOps(mf1, mf2)
1307
1308    # Test operations between masked arrays and non-masked arrays
1309    assert(len(mf1) == 5);
1310    g = IntTypeArray(5)
1311    g[0] = 2
1312    g[1] = 1
1313    g[2] = 5
1314    g[3] = 4
1315    g[4] = 8
1316
1317    testVectorVectorArithmeticOps(g, mf1)
1318    testVectorVectorComparisonOps(g, mf1)
1319    testVectorVectorInequalityOps(g, mf1)
1320
1321    assert(len(f) == 10)
1322    g = IntTypeArray(10)
1323    g[0] = 5
1324    g[1] = 11
1325    g[2] = 3
1326    g[3] = 4
1327    g[4] = 1
1328    g[5] = 8
1329    g[6] = 6
1330    g[7] = 2
1331    g[8] = 1
1332    g[9] = 7
1333
1334    testVectorVectorMaskedInPlaceArithmeticOps(f, g, m1)
1335    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m1], m1)
1336    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m2][:], m1)
1337    testVectorVectorMaskedArithmeticOps(f, g, f / 2, m1)
1338
1339    print ("ok")
1340
1341testList.append(('testMaskedIntArray', lambda : testMaskedIntTypeArray(IntArray)))
1342testList.append(('testMaskedShortArray', lambda : testMaskedIntTypeArray(ShortArray)))
1343
1344def testNonMaskedVecTypeArray(VecTypeArray):
1345    base_type = ArrayBaseType[VecTypeArray]
1346    vec_base_type = VecBaseType[base_type]
1347
1348    f1 = VecTypeArray(5)
1349    assert (len(f1) == 5)
1350
1351    # Check for correct initialization
1352    for i in range(0, len(f1)):
1353        assert(f1[i] == base_type(0))
1354
1355    v = None
1356    if dimensions(base_type) == 2:
1357        v = base_type(1.25, 3.75)
1358    elif base_type.dimensions() == 3:
1359        v = base_type(1.25, 3.75, 2.0)
1360    else:
1361        assert(False)
1362
1363    f1 = VecTypeArray(v, 10)
1364    assert(len(f1) == 10)
1365    for i in range(0, len(f1)):
1366        assert(f1[i] == v)
1367
1368    # Ensure that an exception is thrown when
1369    # we exceed the bounds of the array
1370    try:
1371        print (f1[10])
1372    except:
1373        pass
1374    else:
1375        assert(False)
1376
1377    # Check element assignment
1378
1379    v1 = None
1380    v2 = None
1381
1382    if dimensions(base_type) == 2:
1383        v1 = base_type(1.5, 0.75)
1384        v2 = base_type(4.25, 7.5)
1385    elif dimensions(base_type) == 3:
1386        v1 = base_type(1.5, 0.75, 5.0)
1387        v2 = base_type(4.25, 7.5, 2.25)
1388    else:
1389        assert(False)
1390
1391    f1[0] = v1
1392    f1[1] = v2
1393
1394    assert(f1[0] == v1)
1395    assert(f1[1] == v2)
1396
1397    # Test copy construction
1398    f2 = VecTypeArray(f1)
1399    assert(len(f2) == len(f1))
1400    for i in range(0, len(f1)):
1401        assert f1[i] == f2[i]
1402
1403    # The same internal data is referenced by both arrays
1404    v = None
1405    if dimensions(base_type) == 2:
1406        v = base_type(4.5, 1.75)
1407    elif base_type.dimensions() == 3:
1408        v = base_type(4.5, 1.75, 6.0)
1409    else:
1410        assert(False)
1411
1412    f2[3] = v
1413    assert(f2[3] == v)
1414    assert(f1[3] == v)
1415
1416    f1[4] = 2*v
1417    assert(f1[4] == 2*v)
1418    assert(f2[4] == 2*v)
1419
1420    # Test negative indices
1421    assert(f2[-1] == f2[len(f2)-1])
1422    assert(f2[-2] == f2[len(f2)-2])
1423
1424    # Test slice operations
1425
1426    # Copy contents of f1
1427    f3 = f1[:]
1428    assert(len(f3) == len(f1))
1429
1430    for i in range(0, len(f1)):
1431        assert(f3[i] == f1[i])
1432
1433    v = None
1434    if dimensions(base_type) == 2:
1435        v = base_type(0.25, 5.25)
1436    elif base_type.dimensions() == 3:
1437        v = base_type(0.25, 5.25, 1.0)
1438
1439    assert(v is not None)
1440
1441    f3[0] = v
1442    assert(f3[0] != f1[0])
1443
1444    f3 = f1[2:4]
1445    assert(len(f3) == 2)
1446    assert(f3[0] == f1[2] and f3[1] == f1[3])
1447
1448    # Test array-array operations
1449    f1 = VecTypeArray(5)
1450    f2 = VecTypeArray(5)
1451
1452    # These values were chosen to allow division operations
1453    # to return exact values that can be compared with '=='
1454
1455    if dimensions(base_type) == 2:
1456        f1[0] = base_type(1.25, 2.5)
1457        f1[1] = base_type(2.0, 7.25)
1458        f1[2] = base_type(3.0, 9.0)
1459        f1[3] = base_type(1.0, 8.5)
1460        f1[4] = base_type(3.75, 3.25)
1461
1462        f2[0] = base_type(5.0, 4.25)
1463        f2[1] = base_type(2.0, 3.5)
1464        f2[2] = base_type(1.5, 6.0)
1465        f2[3] = base_type(2.0, 7.25)
1466        f2[4] = base_type(10.0, 11.0)
1467
1468    elif dimensions(base_type) == 3:
1469        f1[0] = base_type(1.25, 2.5, 11.75)
1470        f1[1] = base_type(2.0, 7.25, 4.0)
1471        f1[2] = base_type(3.0, 9.0, 12.25)
1472        f1[3] = base_type(1.0, 8.5, 6.5)
1473        f1[4] = base_type(3.75, 0.25, 5.25)
1474
1475        f2[0] = base_type(5.0, 4.25, 5.75)
1476        f2[1] = base_type(2.0, 3.5, 8.0)
1477        f2[2] = base_type(1.5, 6.0, 12.5)
1478        f2[3] = base_type(2.0, 7.25, 15.0)
1479        f2[4] = base_type(10.0, 11.0, 1.25)
1480
1481    testVectorVectorArithmeticOps(f1, f2)
1482    testVectorVectorInPlaceArithmeticOps(f1, f2)
1483    testUnaryVecMethods(f1)
1484    testBinaryVecMethods(f1, f2)
1485
1486    if dimensions(base_type) == 2:
1487        v = base_type(1.25, 5.25)
1488    elif dimensions(base_type) == 3:
1489        v = base_type(1.25, 5.25, 1.0)
1490    else:
1491        assert(False)
1492
1493    assert(v is not None)
1494
1495    # Test operations for arrays with scalars
1496    testVectorScalarArithmeticOps(f1, v)
1497    testVectorScalarInPlaceArithmeticOps(f1, v)
1498    testVectorScalarComparisonOps(f1, v)
1499
1500    # Test multiplication and division by vector base types
1501    v = vec_base_type(4.25)
1502
1503    f = f1 * v
1504    assert(len(f) == len(f1))
1505    for i in range(0, len(f)):
1506        assert(f[i] == f1[i] * v)
1507
1508    f = v * f1
1509    assert(len(f) == len(f1))
1510    for i in range(0, len(f)):
1511        assert(f[i] == v * f1[i])
1512
1513    f = f1 / v
1514    assert(len(f) == len(f1))
1515    for i in range(0, len(f)):
1516        assert(equalWithAbsError(f[i], f1[i] / v, eps))
1517
1518
1519    # Make sure that operations fail when performed on arrays
1520    # of differing lengths
1521    f3 = VecTypeArray(6)
1522
1523    assertVectorVectorArithmeticOpFailures(f1, f3)
1524    assertVectorVectorInPlaceArithmeticOpFailures(f1, f3)
1525
1526    print ("ok")
1527
1528testList.append(('testNonMaskedV2sArray', lambda : testNonMaskedVecTypeArray(V2sArray)))
1529testList.append(('testNonMaskedV2iArray', lambda : testNonMaskedVecTypeArray(V2iArray)))
1530testList.append(('testNonMaskedV2fArray', lambda : testNonMaskedVecTypeArray(V2fArray)))
1531testList.append(('testNonMaskedV2dArray', lambda : testNonMaskedVecTypeArray(V2dArray)))
1532testList.append(('testNonMaskedV3sArray', lambda : testNonMaskedVecTypeArray(V3sArray)))
1533testList.append(('testNonMaskedV3iArray', lambda : testNonMaskedVecTypeArray(V3iArray)))
1534testList.append(('testNonMaskedV3fArray', lambda : testNonMaskedVecTypeArray(V3fArray)))
1535testList.append(('testNonMaskedV3dArray', lambda : testNonMaskedVecTypeArray(V3dArray)))
1536
1537
1538def testMaskedVecTypeArray(VecTypeArray):
1539    base_type = ArrayBaseType[VecTypeArray]
1540    vec_base_type = VecBaseType[base_type]
1541
1542    f = VecTypeArray(10)
1543
1544    if dimensions(base_type) == 2:
1545        f[0] = base_type(1.25, 5.25)
1546        f[1] = base_type(2.5, 6.0)
1547        f[2] = base_type(1.0, 3.75)
1548        f[3] = base_type(1.75, 11.25)
1549        f[4] = base_type(5.25, 12.0)
1550        f[5] = base_type(7.0, 4.5)
1551        f[6] = base_type(4.25, 6.5)
1552        f[7] = base_type(1.0, 2.25)
1553        f[8] = base_type(1.5, 1.75)
1554        f[9] = base_type(3.5, 4.0)
1555    elif dimensions(base_type) == 3:
1556        f[0] = base_type(1.25, 5.25, 8.5)
1557        f[1] = base_type(2.5, 6.0, 7.25)
1558        f[2] = base_type(1.0, 3.75, 15.5)
1559        f[3] = base_type(1.75, 11.25, 10.0)
1560        f[4] = base_type(5.25, 12.0, 16.5)
1561        f[5] = base_type(7.0, 4.5, 1.25)
1562        f[6] = base_type(4.25, 6.5, 9.25)
1563        f[7] = base_type(1.0, 2.25, 5.0)
1564        f[8] = base_type(1.5, 1.75, 7.5)
1565        f[9] = base_type(3.5, 4.0, 5.75)
1566
1567    # Ensure we can't create a masked array if the indices don't match
1568    m1 = IntArray(9)
1569    try:
1570        mf = f[m1]
1571    except:
1572        pass
1573    else:
1574        assert(false)
1575
1576    m1 = IntArray(len(f))
1577    m1[0] = 1
1578    m1[1] = 0
1579    m1[2] = 0
1580    m1[3] = 1
1581    m1[4] = 1
1582    m1[5] = 0
1583    m1[6] = 0
1584    m1[7] = 1
1585    m1[8] = 0
1586    m1[9] = 1
1587
1588    # Ensure the masked array reports the correct reduced length
1589    mf = f[m1]
1590    assert(len(mf) == numNonZeroMaskEntries(m1))
1591
1592    # Ensure the masked array holds the correct values
1593    assert(mf[0] == f[0])
1594    assert(mf[1] == f[3])
1595    assert(mf[2] == f[4])
1596    assert(mf[3] == f[7])
1597    assert(mf[4] == f[9])
1598
1599    # Masked arrays reference the same internal data
1600    v = None
1601    if dimensions(base_type) == 2:
1602        v = base_type(1.75, 2.5)
1603    elif dimensions(base_type) == 3:
1604        v = base_type(1.75, 2.5, 9.25)
1605    else:
1606        assert(False)
1607
1608    f[9] = v
1609    assert(mf[4] == v)
1610
1611    mf[3] = 2*v
1612    assert(f[7] == 2*v)
1613
1614    # Test copy construction of masked references
1615    g = VecTypeArray(mf)
1616
1617    # Check slices of masks
1618    s = mf[1:3]
1619    assert(len(s) == 2)
1620    assert(s[0] == mf[1])
1621    assert(s[1] == mf[2])
1622
1623    assert(mf[-1] == mf[len(mf)-1])
1624    assert(mf[-2] == mf[len(mf)-2])
1625
1626    # Check that slices copy (not reference) array data
1627    s = mf[:]
1628    assert(len(s) == len(mf))
1629    for i in range(0, len(mf)):
1630        assert(s[i] == mf[i])
1631
1632    s[0] = base_type(0)
1633    assert(s[0] != mf[0])
1634
1635    # Test operations with masked arrays
1636    # Masked arrays should behave exactly as ordinary arrays
1637
1638    m2 = IntArray(len(f))
1639    m2[0] = 1
1640    m2[1] = 0
1641    m2[2] = 1
1642    m2[3] = 0
1643    m2[4] = 1
1644    m2[5] = 1
1645    m2[6] = 0
1646    m2[7] = 0
1647    m2[8] = 1
1648    m2[9] = 1
1649
1650    # m1 and m2 differ in the number of non-zero entries.
1651    # Ensure that arithmetic operations with masked arrays
1652    # cannot proceed if they have differing lengths
1653
1654    mf1 = f[m1]
1655    mf2 = f[m2]
1656
1657    assertVectorVectorInPlaceArithmeticOpFailures(mf1, mf2)
1658
1659    # Test that the operations still fail when the number
1660    # of non-zero mask entries is the same
1661
1662    m2[9] = 0
1663
1664    assert(numNonZeroMaskEntries(m1) == numNonZeroMaskEntries(m2))
1665
1666    mf2 = f[m2]
1667
1668    # Aritmetic operations and comparison ops are supported
1669    testVectorVectorArithmeticOps(mf1, mf2)
1670    testVectorVectorComparisonOps(mf1, mf2)
1671
1672    # Test operations between masked arrays and non-masked arrays
1673    assert(len(mf1) == 5);
1674    g = VecTypeArray(5)
1675
1676    if dimensions(base_type) == 2:
1677        g[0] = base_type(5.25, 2.75)
1678        g[1] = base_type(1.75, 11.5)
1679        g[2] = base_type(3.0, 8.25)
1680        g[3] = base_type(4.25, 6.75)
1681        g[4] = base_type(5.75, 12.0)
1682    elif dimensions(base_type) == 3:
1683        g[0] = base_type(5.25, 2.75, 1.0)
1684        g[1] = base_type(1.75, 11.5, 15.25)
1685        g[2] = base_type(3.0, 8.25, 9.0)
1686        g[3] = base_type(4.25, 6.75, 1.25)
1687        g[4] = base_type(5.75, 12.0, 7.5)
1688    else:
1689        assert(False)
1690
1691    testVectorVectorArithmeticOps(g, mf1)
1692    testVectorVectorComparisonOps(g, mf1)
1693
1694    testUnaryVecMethods(g)
1695    testBinaryVecMethods(g, mf1)
1696    testBinaryVecMethods(mf1, mf2)
1697
1698    assert(len(f) == 10)
1699    g = VecTypeArray(10)
1700
1701    if dimensions(base_type) == 2:
1702        g[0] = base_type(5.25, 2.75)
1703        g[1] = base_type(1.75, 11.5)
1704        g[2] = base_type(3.0, 8.25)
1705        g[3] = base_type(4.25, 6.75)
1706        g[4] = base_type(5.75, 12.0)
1707        g[5] = base_type(8.0, 5.25)
1708        g[6] = base_type(3.5, 4.0)
1709        g[7] = base_type(2.0, 12.5)
1710        g[8] = base_type(1.75, 6.75)
1711        g[9] = base_type(6.5, 8.0)
1712    elif dimensions(base_type) == 3:
1713        g[0] = base_type(5.25, 2.75, 1.0)
1714        g[1] = base_type(1.75, 11.5, 15.25)
1715        g[2] = base_type(3.0, 8.25, 9.0)
1716        g[3] = base_type(4.25, 6.75, 1.25)
1717        g[4] = base_type(5.75, 12.0, 7.5)
1718        g[5] = base_type(8.0, 5.25, 12.25)
1719        g[6] = base_type(3.5, 4.0, 6.0)
1720        g[7] = base_type(2.0, 12.5, 16.5)
1721        g[8] = base_type(1.75, 6.75, 4.25)
1722        g[9] = base_type(6.5, 8.0, 7.75)
1723    else:
1724        assert(False)
1725
1726    testVectorVectorMaskedInPlaceArithmeticOps(f, g, m1)
1727    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m1], m1)
1728    testVectorVectorMaskedInPlaceArithmeticOps2(f, g[m2][:], m1)
1729
1730    v = None
1731    if dimensions(base_type) == 2:
1732        v = base_type(1.25, 3.75)
1733    elif base_type.dimensions() == 3:
1734        v = base_type(1.25, 3.75, 2.0)
1735    else:
1736        assert(False)
1737
1738    assert(v is not None)
1739
1740    # Test operations for arrays with scalars
1741    testVectorScalarArithmeticOps(g, v)
1742    testVectorScalarInPlaceArithmeticOps(g, v)
1743    testVectorScalarComparisonOps(g, v)
1744
1745    testVectorVectorMaskedArithmeticOps(f, f, f, m1)
1746
1747    # Test multiplication and division by vector base types
1748    v = vec_base_type(4.25)
1749
1750    f = g * v
1751    assert(len(f) == len(g))
1752    for i in range(0, len(f)):
1753        assert(f[i] == g[i] * v)
1754
1755    f = v * g
1756    assert(len(f) == len(g))
1757    for i in range(0, len(f)):
1758        assert(f[i] == v * g[i])
1759
1760    f = g / v
1761    assert(len(f) == len(g))
1762    for i in range(0, len(f)):
1763        assert(equalWithAbsError(f[i], g[i] / v, eps))
1764
1765    testVectorVectorMaskedArithmeticOps
1766
1767    print ("ok")
1768
1769testList.append(('testMaskedV2sArray', lambda : testMaskedVecTypeArray(V2sArray)))
1770testList.append(('testMaskedV2iArray', lambda : testMaskedVecTypeArray(V2iArray)))
1771testList.append(('testMaskedV2fArray', lambda : testMaskedVecTypeArray(V2fArray)))
1772testList.append(('testMaskedV2dArray', lambda : testMaskedVecTypeArray(V2dArray)))
1773testList.append(('testMaskedV3fArray', lambda : testMaskedVecTypeArray(V3fArray)))
1774testList.append(('testMaskedV3dArray', lambda : testMaskedVecTypeArray(V3dArray)))
1775
1776
1777# -------------------------------------------------------------------------
1778# Tests for functions
1779
1780def testFun ():
1781
1782    assert sign(5)    ==  1
1783    assert sign(5.0)  ==  1
1784    assert sign(-5)   == -1
1785    assert sign(-5.0) == -1
1786
1787    assert log(math.e) ==  1
1788    assert log(1)      ==  0
1789
1790    assert log10(10)   ==  1
1791    assert log10(1)    ==  0
1792
1793    assert lerp(1, 2, 0.5)     == 1.5
1794    assert lerp(1.0, 2.0, 0.5) == 1.5
1795    assert lerp(2, 1, 0.5)     == 1.5
1796    assert lerp(2.0, 1.0, 0.5) == 1.5
1797
1798    assert lerpfactor(1.5, 1, 2)     == 0.5
1799    assert lerpfactor(1.5, 1.0, 2.0) == 0.5
1800
1801    assert clamp(0, 1, 2)       == 1
1802    assert clamp(3, 1, 2)       == 2
1803    assert clamp(0.0, 1.0, 2.0) == 1
1804    assert clamp(3.0, 1.0, 2.0) == 2
1805
1806    assert cmp(1, 2)     == -1
1807    assert cmp(2, 2)     ==  0
1808    assert cmp(3, 2)     ==  1
1809    assert cmp(1.0, 2.0) == -1
1810    assert cmp(2.0, 2.0) ==  0
1811    assert cmp(3.0, 2.0) ==  1
1812
1813    assert cmpt(1.0, 1.5, 0.1) == -1
1814    assert cmpt(1.5, 1.5, 0.1) ==  0
1815    assert cmpt(2.0, 1.5, 0.1) ==  1
1816    assert cmpt(1.0, 1.5, 0.6) ==  0
1817    assert cmpt(1.5, 1.5, 0.6) ==  0
1818    assert cmpt(2.0, 1.5, 0.6) ==  0
1819
1820    assert iszero(0, 0)        == 1
1821    assert iszero(0, 0.1)      == 1
1822    assert iszero(0.01, 0.1)   == 1
1823    assert iszero(0.01, 0.001) == 0
1824
1825    assert equal(5, 5, 0)        == 1
1826    assert equal(5, 6, 0)        == 0
1827    assert equal(5, 5.01, 0.1)   == 1
1828    assert equal(5, 5.01, 0.001) == 0
1829
1830    assert trunc(1.1)  ==  1
1831    assert trunc(-1.1) == -1
1832    assert trunc(1)    ==  1
1833
1834    assert divs( 4,  2) ==  2
1835    assert divs(-4,  2) == -2
1836    assert divs( 4, -2) == -2
1837    assert divs(-4, -2) ==  2
1838    assert mods( 3,  2) ==  1
1839    assert mods(-3,  2) == -1
1840    assert mods( 3, -2) ==  1
1841    assert mods(-3, -2) == -1
1842
1843    assert divp( 4,  2) ==  2
1844    assert divp(-4,  2) == -2
1845    assert divp( 4, -2) == -2
1846    assert divp(-4, -2) ==  2
1847    assert modp( 3,  2) ==  1
1848    assert modp(-3,  2) ==  1
1849    assert modp( 3, -2) ==  1
1850    assert modp(-3, -2) ==  1
1851
1852    print ("ok")
1853
1854    return
1855
1856testList.append (('testFun',testFun))
1857
1858
1859# -------------------------------------------------------------------------
1860# Tests for V2x
1861
1862def testV2x (Vec):
1863
1864    # Constructors (and element access).
1865
1866    v = Vec()
1867    assert v[0] == 0 and v[1] == 0
1868
1869    v = Vec(1)
1870    assert v[0] == 1 and v[1] == 1
1871
1872    v = Vec(0, 1)
1873    assert v[0] == 0 and v[1] == 1
1874
1875    v = Vec((0, 1))
1876    assert v[0] == 0 and v[1] == 1
1877
1878    v = Vec([0, 1])
1879    assert v[0] == 0 and v[1] == 1
1880
1881    v = Vec()
1882    v.setValue(0, 1)
1883    assert v[0] == 0 and v[1] == 1
1884
1885    # Repr.
1886
1887    v = Vec(1/9., 2/9.)
1888    assert v == eval(repr(v))
1889
1890    # Sequence length.
1891
1892    v = Vec()
1893    assert len(v) == 2
1894
1895    # Element setting.
1896
1897    v = Vec()
1898    v[0] = 10
1899    v[1] = 11
1900    assert v[0] == 10 and v[1] == 11
1901
1902    try:
1903        v[-3] = 0  # This should raise an exception.
1904    except:
1905        pass
1906    else:
1907        assert 0   # We shouldn't get here.
1908
1909    try:
1910        v[3] = 0   # This should raise an exception.
1911    except:
1912        pass
1913    else:
1914        assert 0   # We shouldn't get here.
1915
1916    try:
1917        v[1] = "a" # This should raise an exception.
1918    except:
1919        pass
1920    else:
1921        assert 0   # We shouldn't get here.
1922
1923    # Assignment.
1924
1925    v1 = Vec(1)
1926
1927    v2 = v1
1928    assert v2[0] == 1 and v2[1] == 1
1929    v1[0] = 2
1930    assert v2[0] == 2 and v2[1] == 1
1931
1932    # Comparison operators.
1933
1934    v1 = Vec(20, 20)
1935    v2 = Vec(20, 20)
1936    v3 = Vec(20, 21)
1937
1938    assert v1 == v2
1939    assert v1 != v3
1940    assert not (v1 < v2)
1941    assert v1 < v3
1942    assert v1 <= v2
1943    assert v1 <= v3
1944    assert not (v3 <= v1)
1945    assert not (v2 > v1)
1946    assert v3 > v1
1947    assert v2 >= v1
1948    assert v3 >= v1
1949    assert not (v1 >= v3)
1950
1951    # Epsilon equality.
1952
1953    e = 0.005
1954    v1 = Vec(1)
1955    v2 = Vec(1 + e)
1956
1957    assert v1.equalWithAbsError(v2, e)
1958    assert v2.equalWithAbsError(v1, e)
1959
1960    e = 0.003
1961    v1 = Vec(10)
1962    v2 = Vec(10 + 10 * e)
1963
1964    assert v1.equalWithRelError(v2, e)
1965    assert v2.equalWithRelError(v1, e)
1966
1967    # Dot products.
1968
1969    v1 = Vec(0, 1)
1970    v2 = Vec(1, 0)
1971    v3 = Vec(1, 1)
1972
1973    assert v1.dot(v2) == 0
1974    assert v1.dot(v3) == 1
1975    assert v1 ^ v2 == v1.dot(v2)
1976    assert v1 ^ v3 == v1.dot(v3)
1977
1978    # Cross products.
1979
1980    v1 = Vec(1, 0)
1981    v2 = Vec(0, 1)
1982
1983    assert v1.cross(v2) == 1
1984    assert v2.cross(v1) == -1
1985    assert v1 % v2 == v1.cross(v2)
1986    assert v2 % v1 == v2.cross(v1)
1987
1988    # Addition.
1989
1990    v1 = Vec(10, 20)
1991    v2 = Vec(30, 40)
1992
1993    assert v1 + v2 == Vec(40, 60)
1994    assert v2 + v1 == v1 + v2
1995    assert v1 + 1 == Vec(11, 21)
1996    assert 1 + v1 == v1 + 1
1997
1998    # (with the switch to python2, we now allow ops between vectors and tuples)
1999    assert v1 + (1, 2) == Vec(11, 22)
2000    assert (1, 2) + v1 == v1 + (1, 2)
2001
2002    # Subtraction and negation.
2003
2004    v1 = Vec(10, 20)
2005    v2 = Vec(30, 40)
2006
2007    assert v2 - v1 == Vec(20, 20)
2008    assert v1 - 1 == Vec(9, 19)
2009    assert 1 - v1 == - (v1 - 1)
2010
2011    # (with the switch to python2, we now allow ops between vectors and tuples)
2012    assert v1 - (1, 2) == Vec(9, 18)
2013    assert (1, 2) - v1 == - (v1 - (1, 2))
2014
2015    assert v1.negate() == Vec(-10, -20)
2016
2017    # Multiplication.
2018
2019    v1 = Vec(1, 2)
2020    v2 = Vec(3, 4)
2021
2022    assert v1 * v2 == Vec(3, 8)
2023    assert v2 * v1 == v1 * v2
2024    assert 2 * v1 == Vec(2, 4)
2025    assert v1 * 2 == 2 * v1
2026
2027    assert v1 * V2i(3, 4) == Vec(3, 8)
2028    assert v1 * V2f(3, 4) == Vec(3, 8)
2029    assert v1 * V2d(3, 4) == Vec(3, 8)
2030
2031    v1 *= 2
2032    assert v1 == Vec(2, 4)
2033    v1 = Vec(1, 2)
2034
2035    # (with the switch to python2, we now allow ops between vectors and tuples)
2036    assert v1 * (1, 2) == Vec(1, 4)
2037    assert (1, 2) * v1 == v1 * (1, 2)
2038
2039    # Division.
2040
2041    v1 = Vec(10, 20)
2042    v2 = Vec(2, 4)
2043
2044    assert v1 / v2 == Vec(10/2, 20/4)
2045    assert v1 / 2 == Vec(10/2, 20/2)
2046    assert Vec(40) / v1 == Vec(40/10, 40/20)
2047
2048    # (with the switch to python2, we now allow ops between vectors and tuples)
2049    assert v1 / (1, 2) == Vec(10/1, 20/2)
2050    assert Vec(30, 40) / v1 == Vec(30/10, 40/20)
2051
2052    assert v1 / V2i (2, 4) == Vec(10/2, 20/4)
2053    assert v1 / V2f (2, 4) == Vec(10/2, 20/4)
2054    assert v1 / V2d (2, 4) == Vec(10/2, 20/4)
2055    assert v1 / (2, 4) == Vec(10/2, 20/4)
2056    assert v1 / [2, 4] == Vec(10/2, 20/4)
2057
2058    v1 = Vec(10, 20)
2059    v1 /= 2
2060    assert v1 == Vec(10/2, 20/2)
2061
2062    v1 = Vec(10, 20)
2063    v1 /= V2i (2, 4)
2064    assert v1 == Vec(10/2, 20/4)
2065
2066    v1 = Vec(10, 20)
2067    v1 /= V2f (2, 4)
2068    assert v1 == Vec(10/2, 20/4)
2069
2070    v1 = Vec(10, 20)
2071    v1 /= V2d (2, 4)
2072    assert v1 == Vec(10/2, 20/4)
2073
2074    v1 = Vec(10, 20)
2075    v1 /= (2, 4)
2076    assert v1 == Vec(10/2, 20/4)
2077
2078    v1 = Vec(10, 20)
2079    v1 /= [2, 4]
2080    assert v1 == Vec(10/2, 20/4)
2081
2082    # Length.
2083
2084    if (Vec != V2i):
2085       v = Vec(1, 2)
2086       assert equal(v.length(), sqrt(1*1 + 2*2), v.baseTypeEpsilon())
2087
2088    v = Vec(1, 2)
2089    assert v.length2() == 1*1 + 2*2
2090
2091    # Normalizing.
2092
2093    if (Vec != V2i):
2094       v = Vec(1, 2)
2095       v.normalize()
2096       assert equal(v.length(), 1, v.baseTypeEpsilon())
2097
2098       v = Vec(1, 2)
2099       v.normalizeExc()
2100       assert equal(v.length(), 1, v.baseTypeEpsilon())
2101       v = Vec(0)
2102       try:
2103           v.normalizeExc()        # This should raise an exception.
2104       except:
2105           pass
2106       else:
2107           assert 0                # We shouldn't get here.
2108
2109       v = Vec(1, 2)
2110       v.normalizeNonNull()
2111       assert equal(v.length(), 1, v.baseTypeEpsilon())
2112
2113       v = Vec(1, 2)
2114       assert equal(v.normalized().length(), 1, v.baseTypeEpsilon())
2115
2116       v = Vec(1, 2)
2117       assert equal(v.normalizedExc().length(), 1, v.baseTypeEpsilon())
2118       v = Vec(0)
2119       try:
2120           v.normalizedExc()        # This should raise an exception.
2121       except:
2122           pass
2123       else:
2124           assert 0                # We shouldn't get here.
2125
2126       v = Vec(1, 2)
2127       assert equal(v.normalizedNonNull().length(), 1, v.baseTypeEpsilon())
2128
2129
2130    # Projection.
2131
2132    if (Vec != V2i):
2133        s = Vec(2, 0)
2134        t = Vec(1, 1)
2135        assert t.project(s) == Vec(1, 0)
2136
2137    # Orthogonal.
2138
2139    if (Vec != V2i):
2140        s = Vec(2, 0)
2141        t = Vec(1, 1)
2142        o = s.orthogonal(t)
2143        assert iszero(o ^ s, s.baseTypeEpsilon())
2144
2145    # Reflect.
2146
2147    if (Vec != V2i):
2148        s = Vec(1, 1)
2149        t = Vec(2, 0)
2150        r = s.reflect(t)
2151        assert equal(abs(s ^ t), abs(r ^ t), s.baseTypeEpsilon())
2152
2153    # Closest vertex.
2154
2155    v0 = Vec(0, 0)
2156    v1 = Vec(5, 0)
2157    v2 = Vec(0, 5)
2158
2159    p = Vec(1, 1)
2160    assert p.closestVertex(v0, v1, v2) == v0
2161
2162    p = Vec(4, 1)
2163    assert p.closestVertex(v0, v1, v2) == v1
2164
2165    p = Vec(1, 4)
2166    assert p.closestVertex(v0, v1, v2) == v2
2167
2168
2169    print ("ok")
2170
2171    return
2172
2173def testV2 ():
2174
2175    print ("V2i")
2176    testV2x (V2i)
2177    print ("V2f")
2178    testV2x (V2f)
2179    print ("V2d")
2180    testV2x (V2d)
2181
2182testList.append (('testV2',testV2))
2183
2184
2185# -------------------------------------------------------------------------
2186# Tests for V2xArray
2187
2188def testV2xArray (Array, Vec, Arrayx):
2189
2190    # Constructors (and element access).
2191
2192    a = Array (3)
2193
2194    a[0] = Vec(0)
2195    a[1] = Vec(1)
2196    a[2] = Vec(2)
2197
2198    assert a[0] == Vec(0)
2199    assert a[1] == Vec(1)
2200    assert a[2] == Vec(2)
2201
2202    a[0].setValue(10,10)
2203    a[1].setValue(11,11)
2204    a[2].setValue(12,12)
2205
2206    assert a[0] == Vec(10)
2207    assert a[1] == Vec(11)
2208    assert a[2] == Vec(12)
2209
2210    # Element setting.
2211
2212    a = Array(2)
2213
2214    try:
2215        a[-3] = Vec(0)        # This should raise an exception.
2216    except:
2217        pass
2218    else:
2219        assert 0           # We shouldn't get here.
2220
2221    try:
2222        a[3] = Vec(0)   # This should raise an exception.
2223    except:
2224        pass
2225    else:
2226        assert 0           # We shouldn't get here.
2227
2228    try:
2229        a[1] = "a"         # This should raise an exception.
2230    except:
2231        pass
2232    else:
2233        assert 0           # We shouldn't get here.
2234
2235    # Assignment.
2236
2237    a = Array(2)
2238    a[0] = Vec(0)
2239    a[1] = Vec(1)
2240
2241    b = Array(2)
2242    b[0] = Vec(0)
2243    b[1] = Vec(1)
2244
2245    c = Array(2)
2246    c[0] = Vec(10)
2247    c[1] = Vec(11)
2248
2249    # TODO: make equality work correctly.
2250    #assert a == b
2251    assert a != c
2252
2253    # Dot products.
2254
2255    a = Array(2)
2256    a[0] = Vec(1, 2)
2257    a[1] = Vec(3, 4)
2258
2259    b = Array(2)
2260    b[0] = Vec(5, 6)
2261    b[1] = Vec(7, 8)
2262
2263    r = a.dot(b)
2264    assert r[0] == 1*5 + 2*6
2265    assert r[1] == 3*7 + 4*8
2266
2267    c = Vec(5, 6)
2268    r = a.dot(c)
2269    assert r[0] == 1*5 + 2*6
2270    assert r[1] == 3*5 + 4*6
2271
2272    d = Array(3)
2273    try:
2274        a.dot(d)        # This should raise an exception.
2275    except:
2276        pass
2277    else:
2278        assert 0           # We shouldn't get here.
2279
2280
2281    # Cross products.
2282
2283    a = Array(2)
2284    a[0] = Vec(1, 2)
2285    a[1] = Vec(3, 4)
2286
2287    b = Array(2)
2288    b[0] = Vec(5, 6)
2289    b[1] = Vec(7, 8)
2290
2291    r = a.cross(b)
2292    assert r[0] == 1*6 - 2*5
2293    assert r[1] == 3*8 - 4*7
2294
2295    c = Vec(5, 6)
2296    r = a.cross(c)
2297    assert r[0] == 1*6 - 2*5
2298    assert r[1] == 3*6 - 4*5
2299
2300    d = Array(3)
2301    try:
2302        a.cross(d)        # This should raise an exception.
2303    except:
2304        pass
2305    else:
2306        assert 0           # We shouldn't get here.
2307
2308    # Addition.
2309
2310    a = Array(2)
2311    a[0] = Vec(1, 2)
2312    a[1] = Vec(3, 4)
2313
2314    b = Array(2)
2315    b[0] = Vec(5, 6)
2316    b[1] = Vec(7, 8)
2317
2318    r = a + b
2319    assert r[0] == Vec(1+5, 2+6)
2320    assert r[1] == Vec(3+7, 4+8)
2321
2322    r = a + Vec(10)
2323    assert r[0] == Vec(1+10, 2+10)
2324    assert r[1] == Vec(3+10, 4+10)
2325
2326    v = Vec(11)
2327    r = v + a
2328    assert r[0] == Vec(11+1, 11+2)
2329    assert r[1] == Vec(11+3, 11+4)
2330
2331    a += b
2332    assert a[0] == Vec(1+5, 2+6)
2333    assert a[1] == Vec(3+7, 4+8)
2334
2335    a[0] = Vec(1, 2)
2336    a[1] = Vec(3, 4)
2337
2338    a += Vec(10)
2339    assert a[0] == Vec(1+10, 2+10)
2340    assert a[1] == Vec(3+10, 4+10)
2341
2342    c = Array(3)
2343
2344    try:
2345        a + c                # This should raise an exception.
2346    except:
2347        pass
2348    else:
2349        assert 0           # We shouldn't get here.
2350
2351    try:
2352        a += c                # This should raise an exception.
2353    except:
2354        pass
2355    else:
2356        assert 0           # We shouldn't get here.
2357
2358    # Subtraction.
2359
2360    a = Array(2)
2361    a[0] = Vec(1, 2)
2362    a[1] = Vec(3, 4)
2363
2364    b = Array(2)
2365    b[0] = Vec(5, 6)
2366    b[1] = Vec(7, 8)
2367
2368    r = a - b
2369    assert r[0] == Vec(1-5, 2-6)
2370    assert r[1] == Vec(3-7, 4-8)
2371
2372    r = a - Vec(10)
2373    assert r[0] == Vec(1-10, 2-10)
2374    assert r[1] == Vec(3-10, 4-10)
2375
2376    r = Vec(10) - a
2377    assert r[0] == Vec(10-1, 10-2)
2378    assert r[1] == Vec(10-3, 10-4)
2379
2380    v = Vec(11)
2381    r = v - a
2382    assert r[0] == Vec(11-1, 11-2)
2383    assert r[1] == Vec(11-3, 11-4)
2384
2385    a -= b
2386    assert a[0] == Vec(1-5, 2-6)
2387    assert a[1] == Vec(3-7, 4-8)
2388
2389    a[0] = Vec(1, 2)
2390    a[1] = Vec(3, 4)
2391
2392    a -= Vec(10)
2393    assert a[0] == Vec(1-10, 2-10)
2394    assert a[1] == Vec(3-10, 4-10)
2395
2396    c = Array(3)
2397
2398    try:
2399        a - c                # This should raise an exception.
2400    except:
2401        pass
2402    else:
2403        assert 0           # We shouldn't get here.
2404
2405    try:
2406        a -= c                # This should raise an exception.
2407    except:
2408        pass
2409    else:
2410        assert 0           # We shouldn't get here.
2411
2412    # Negation.
2413
2414    a = Array(2)
2415    a[0] = Vec(1, 2)
2416    a[1] = Vec(3, 4)
2417
2418    r = -a
2419    assert r[0] == Vec(-1, -2)
2420    assert r[1] == Vec(-3, -4)
2421
2422    # Multiplication.
2423
2424    a = Array(2)
2425    a[0] = Vec(1, 2)
2426    a[1] = Vec(3, 4)
2427
2428    r = a * 10
2429    assert r[0] == Vec(1, 2) * 10
2430    assert r[1] == Vec(3, 4) * 10
2431
2432    b = Arrayx(2)
2433    b[0] = 10
2434    b[1] = 11
2435
2436    r = a * b
2437    assert r[0] == Vec(1, 2) * 10
2438    assert r[1] == Vec(3, 4) * 11
2439
2440    a *= 10
2441    assert a[0] == Vec(1, 2) * 10
2442    assert a[1] == Vec(3, 4) * 10
2443
2444    a[0] = Vec(1, 2)
2445    a[1] = Vec(3, 4)
2446
2447    a *= b
2448    assert a[0] == Vec(1, 2) * 10
2449    assert a[1] == Vec(3, 4) * 11
2450
2451    a[0] = Vec(1, 2)
2452    a[1] = Vec(3, 4)
2453
2454    b = Array(2)
2455    b[0] = Vec(5, 6)
2456    b[1] = Vec(7, 8)
2457
2458    r = a * b
2459    assert r[0] == Vec(1*5, 2*6)
2460    assert r[1] == Vec(3*7, 4*8)
2461
2462    v = Vec(9, 10)
2463
2464    r = a * v
2465    assert r[0] == Vec(1*9, 2*10)
2466    assert r[1] == Vec(3*9, 4*10)
2467
2468    r = v * a
2469    assert r[0] == Vec(1*9, 2*10)
2470    assert r[1] == Vec(3*9, 4*10)
2471
2472    a *= b
2473    assert a[0] == Vec(1*5, 2*6)
2474    assert a[1] == Vec(3*7, 4*8)
2475
2476    a[0] = Vec(1, 2)
2477    a[1] = Vec(3, 4)
2478
2479    a *= v
2480    assert a[0] == Vec(1*9, 2*10)
2481    assert a[1] == Vec(3*9, 4*10)
2482
2483    d = Array(3)
2484    try:
2485        a * d                # This should raise an exception.
2486    except:
2487        pass
2488    else:
2489        assert 0           # We shouldn't get here.
2490
2491    try:
2492        a *= d                # This should raise an exception.
2493    except:
2494        pass
2495    else:
2496        assert 0           # We shouldn't get here.
2497
2498    # Division.
2499
2500    a = Array(2)
2501    a[0] = Vec(1.0, 2.0)
2502    a[1] = Vec(3.0, 4.0)
2503
2504    r = a / 10
2505    assert r[0] == Vec(1.0, 2.0) / 10
2506    assert r[1] == Vec(3.0, 4.0) / 10
2507
2508    b = Arrayx(2)
2509    b[0] = 10
2510    b[1] = 11
2511
2512    r = a / b
2513    assert r[0] == Vec(1.0, 2.0) / 10
2514    assert r[1] == Vec(3.0, 4.0) / 11
2515
2516    a /= 10
2517    assert a[0] == Vec(1.0, 2.0) / 10
2518    assert a[1] == Vec(3.0, 4.0) / 10
2519
2520    a[0] = Vec(1.0, 2.0)
2521    a[1] = Vec(3.0, 4.0)
2522
2523    a /= b
2524    assert a[0] == Vec(1.0, 2.0) / 10
2525    assert a[1] == Vec(3.0, 4.0) / 11
2526
2527    a[0] = Vec(1.0, 2.0)
2528    a[1] = Vec(3.0, 4.0)
2529
2530    b = Array(2)
2531    b[0] = Vec(5, 6)
2532    b[1] = Vec(7, 8)
2533
2534    r = a / b
2535    assert r[0] == Vec(1.0/5, 2.0/6)
2536    assert r[1] == Vec(3.0/7, 4.0/8)
2537
2538    v = Vec(9, 10)
2539
2540    r = a / v
2541    assert r[0] == Vec(1.0/9, 2.0/10)
2542    assert r[1] == Vec(3.0/9, 4.0/10)
2543
2544    # TODO: Figure out why "v / a" is illegal, even though the
2545    # add_arithmetic_math_functions() routine in PyImathFixedArray.h
2546    # should make it possible.
2547    #r = v / a
2548    #assert r[0] == Vec(1.0/9, 2.0/10)
2549    #assert r[1] == Vec(3.0/9, 4.0/10)
2550
2551    a /= b
2552    assert a[0] == Vec(1.0/5, 2.0/6)
2553    assert a[1] == Vec(3.0/7, 4.0/8)
2554
2555    a[0] = Vec(1.0, 2.0)
2556    a[1] = Vec(3.0, 4.0)
2557
2558    a /= v
2559    assert a[0] == Vec(1.0/9, 2.0/10)
2560    assert a[1] == Vec(3.0/9, 4.0/10)
2561
2562    d = Array(3)
2563    try:
2564        a / d                # This should raise an exception.
2565    except:
2566        pass
2567    else:
2568        assert 0           # We shouldn't get here.
2569
2570    try:
2571        a /= d                # This should raise an exception.
2572    except:
2573        pass
2574    else:
2575        assert 0           # We shouldn't get here.
2576
2577    # Length.
2578
2579    if (Vec != V2i):
2580        v0 = Vec(1, 2)
2581        v1 = Vec(3, 4)
2582
2583        a = Array(2)
2584        a[0] = v0
2585        a[1] = v1
2586
2587        l = a.length()
2588        assert (l[0] == v0.length())
2589        assert (l[1] == v1.length())
2590
2591        l = a.length2()
2592        assert (l[0] == v0.length2())
2593        assert (l[1] == v1.length2())
2594
2595    # Normalizing.
2596
2597    if (Vec != V2i):
2598
2599        a[0] = Vec(1, 2)
2600        a[1] = Vec(3, 4)
2601
2602        r = a.normalized();
2603        assert r[0] == Vec(1, 2).normalized()
2604        assert r[1] == Vec(3, 4).normalized()
2605
2606        a.normalize();
2607        assert a[0] == Vec(1, 2).normalized()
2608        assert a[1] == Vec(3, 4).normalized()
2609
2610    print ("ok")
2611
2612    return
2613
2614def testV2Array ():
2615
2616    print ("V2iArray")
2617    testV2xArray (V2iArray, V2i, IntArray)
2618    print ("V2fArray")
2619    testV2xArray (V2fArray, V2f, FloatArray)
2620    print ("V2dArray")
2621    testV2xArray (V2dArray, V2d, DoubleArray)
2622
2623testList.append (('testV2Array',testV2Array))
2624
2625
2626# -------------------------------------------------------------------------
2627# Tests for V3x
2628
2629def testV3x (Vec):
2630
2631    # Constructors (and element access).
2632
2633    v = Vec()
2634    assert v[0] == 0 and v[1] == 0 and v[2] == 0
2635
2636    v = Vec(1)
2637    assert v[0] == 1 and v[1] == 1 and v[2] == 1
2638
2639    v = Vec(0, 1, 2)
2640    assert v[0] == 0 and v[1] == 1 and v[2] == 2
2641
2642    v = Vec((0, 1, 2))
2643    assert v[0] == 0 and v[1] == 1 and v[2] == 2
2644
2645    v = Vec([0, 1, 2])
2646    assert v[0] == 0 and v[1] == 1 and v[2] == 2
2647
2648    v = Vec()
2649    v.setValue(0, 1, 2)
2650    assert v[0] == 0 and v[1] == 1 and v[2] == 2
2651
2652    # Repr.
2653
2654    v = Vec(1/9., 2/9., 3/9.)
2655    assert v == eval(repr(v))
2656
2657    # Sequence length.
2658
2659    v = Vec()
2660    assert len(v) == 3
2661
2662    # Element setting.
2663
2664    v = Vec()
2665    v[0] = 10
2666    v[1] = 11
2667    v[2] = 12
2668    assert v[0] == 10 and v[1] == 11 and v[2] == 12
2669
2670    try:
2671        v[-4] = 0           # This should raise an exception.
2672    except:
2673        pass
2674    else:
2675        assert 0           # We shouldn't get here.
2676
2677    try:
2678        v[3] = 0           # This should raise an exception.
2679    except:
2680        pass
2681    else:
2682        assert 0           # We shouldn't get here.
2683
2684    try:
2685        v[1] = "a"           # This should raise an exception.
2686    except:
2687        pass
2688    else:
2689        assert 0           # We shouldn't get here.
2690
2691    # Assignment.
2692
2693    v1 = Vec(1)
2694
2695    v2 = v1
2696    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1
2697    v1[0] = 2
2698    assert v2[0] == 2 and v2[1] == 1 and v2[2] == 1
2699
2700    # Comparison operators.
2701
2702    v1 = Vec(20, 20, 0)
2703    v2 = Vec(20, 20, 0)
2704    v3 = Vec(20, 21, 0)
2705
2706    assert v1 == v2
2707    assert v1 != v3
2708    assert not (v1 < v2)
2709    assert v1 < v3
2710    assert v1 <= v2
2711    assert v1 <= v3
2712    assert not (v3 <= v1)
2713    assert not (v2 > v1)
2714    assert v3 > v1
2715    assert v2 >= v1
2716    assert v3 >= v1
2717    assert not (v1 >= v3)
2718
2719    # Epsilon equality.
2720
2721    e = 0.005
2722    v1 = Vec(1)
2723    v2 = Vec(1 + e)
2724
2725    assert v1.equalWithAbsError(v2, e)
2726    assert v2.equalWithAbsError(v1, e)
2727
2728    e = 0.003
2729    v1 = Vec(10)
2730    v2 = Vec(10 + 10 * e)
2731
2732    assert v1.equalWithRelError(v2, e)
2733    assert v2.equalWithRelError(v1, e)
2734
2735    # Dot products.
2736
2737    v1 = Vec(0, 1, 0)
2738    v2 = Vec(1, 0, 0)
2739    v3 = Vec(1, 1, 0)
2740
2741    assert v1.dot(v2) == 0
2742    assert v1.dot(v3) == 1
2743    assert v1 ^ v2 == v1.dot(v2)
2744    assert v1 ^ v3 == v1.dot(v3)
2745
2746    # Cross products.
2747
2748    v1 = Vec(1, 0, 0)
2749    v2 = Vec(0, 1, 0)
2750
2751    assert v1.cross(v2) == Vec(0, 0, 1)
2752    assert v2.cross(v1) == Vec(0, 0, -1)
2753    assert v1 % v2 == v1.cross(v2)
2754    assert v2 % v1 == v2.cross(v1)
2755
2756    # Addition.
2757
2758    v1 = Vec(10, 20, 30)
2759    v2 = Vec(30, 40, 50)
2760
2761    assert v1 + v2 == Vec(40, 60, 80)
2762    assert v2 + v1 == v1 + v2
2763    assert v1 + 1 == Vec(11, 21, 31)
2764    assert 1 + v1 == v1 + 1
2765
2766    # (with the switch to python2, we now allow ops between vectors and tuples)
2767    assert v1 + (1, 2, 3) == Vec(11, 22, 33)
2768    assert (1, 2, 3) + v1 == v1 + (1, 2, 3)
2769
2770    # Subtraction and negation.
2771
2772    v1 = Vec(10, 20, 30)
2773    v2 = Vec(30, 40, 50)
2774
2775    assert v2 - v1 == Vec(20, 20, 20)
2776    assert v1 - 1 == Vec(9, 19, 29)
2777    assert 1 - v1 == - (v1 - 1)
2778
2779    # (with the switch to python2, we now allow ops between vectors and tuples)
2780    assert v1 - (1, 2, 3) == Vec(9, 18, 27)
2781    assert (1, 2, 3) - v1 == - (v1 - (1, 2, 3))
2782
2783    assert v1.negate() == Vec(-10, -20, -30)
2784
2785    # Multiplication.
2786
2787    v1 = Vec(1, 2, 3)
2788    v2 = Vec(3, 4, 5)
2789
2790    assert v1 * v2 == Vec(3, 8, 15)
2791    assert v2 * v1 == v1 * v2
2792    assert 2 * v1 == Vec(2, 4, 6)
2793    assert v1 * 2 == 2 * v1
2794
2795    assert v1 * V3i(3, 4, 5) == Vec(3, 8, 15)
2796    assert v1 * V3f(3, 4, 5) == Vec(3, 8, 15)
2797    assert v1 * V3d(3, 4, 5) == Vec(3, 8, 15)
2798
2799    v1 *= 2
2800    assert v1 == Vec(2, 4, 6)
2801    v1 = Vec(1, 2, 3)
2802
2803    # (with the switch to python2, we now allow ops between vectors and tuples)
2804    assert v1 * (1, 2, 3) == Vec(1, 4, 9)
2805    assert (1, 2, 3) * v1 == v1 * (1, 2, 3)
2806
2807    # Division.
2808
2809    v1 = Vec(10, 20, 40)
2810    v2 = Vec(2, 4, 8)
2811
2812    assert v1 / v2 == Vec(10/2, 20/4, 40/8)
2813    assert v1 / 2 == Vec(10/2, 20/2, 40/2)
2814    assert Vec(40) / v1 == Vec(40/10, 40/20, 40/40)
2815
2816    # (with the switch to python2, we now allow ops between vectors and tuples)
2817    assert v1 / (1, 2, 4) == Vec(10, 10, 10)
2818    assert Vec(50, 40, 80) / v1 == Vec(5, 2, 2)
2819
2820    assert v1 / V3i (2, 4, 8) == Vec(10/2, 20/4, 40/8)
2821    assert v1 / V3f (2, 4, 8) == Vec(10/2, 20/4, 40/8)
2822    assert v1 / V3d (2, 4, 8) == Vec(10/2, 20/4, 40/8)
2823    assert v1 / (2, 4, 8) == Vec(10/2, 20/4, 40/8)
2824    assert v1 / [2, 4, 8] == Vec(10/2, 20/4, 40/8)
2825
2826    v1 = Vec(10, 20, 40)
2827    v1 /= 2
2828    assert v1 == Vec(10/2, 20/2, 40/2)
2829
2830    v1 = Vec(10, 20, 40)
2831    v1 /= V3i (2, 4, 8)
2832    assert v1 == Vec(10/2, 20/4, 40/8)
2833
2834    v1 = Vec(10, 20, 40)
2835    v1 /= V3f (2, 4, 8)
2836    assert v1 == Vec(10/2, 20/4, 40/8)
2837
2838    v1 = Vec(10, 20, 40)
2839    v1 /= V3d (2, 4, 8)
2840    assert v1 == Vec(10/2, 20/4, 40/8)
2841
2842    v1 = Vec(10, 20, 40)
2843    v1 /= (2, 4, 8)
2844    assert v1 == Vec(10/2, 20/4, 40/8)
2845
2846    v1 = Vec(10, 20, 40)
2847    v1 /= [2, 4, 8]
2848    assert v1 == Vec(10/2, 20/4, 40/8)
2849
2850    # Length.
2851
2852    if (Vec != V3i):
2853       v = Vec(1, 2, 3)
2854       assert equal(v.length(), sqrt(1*1 + 2*2 + 3*3), v.baseTypeEpsilon())
2855
2856    v = Vec(1, 2, 3)
2857    assert v.length2() == 1*1 + 2*2 + 3*3
2858
2859    # Normalizing.
2860
2861    if (Vec != V3i):
2862       v = Vec(1, 2, 3)
2863       v.normalize()
2864       assert equal(v.length(), 1, v.baseTypeEpsilon())
2865
2866       v = Vec(1, 2, 3)
2867       v.normalizeExc()
2868       assert equal(v.length(), 1, v.baseTypeEpsilon())
2869       v = Vec(0)
2870       try:
2871           v.normalizeExc()        # This should raise an exception.
2872       except:
2873           pass
2874       else:
2875           assert 0                # We shouldn't get here.
2876
2877       v = Vec(1, 2, 3)
2878       v.normalizeNonNull()
2879       assert equal(v.length(), 1, v.baseTypeEpsilon())
2880
2881       v = Vec(1, 2, 3)
2882       assert equal(v.normalized().length(), 1, v.baseTypeEpsilon())
2883
2884       v = Vec(1, 2, 3)
2885       assert equal(v.normalizedExc().length(), 1, v.baseTypeEpsilon())
2886       v = Vec(0)
2887       try:
2888           v.normalizedExc()  # This should raise an exception.
2889       except:
2890           pass
2891       else:
2892           assert 0              # We shouldn't get here.
2893
2894       v = Vec(1, 2, 3)
2895       assert equal(v.normalizedNonNull().length(), 1, v.baseTypeEpsilon())
2896
2897    # Projection.
2898
2899    if (Vec != V3i):
2900        s = Vec(2, 0, 0)
2901        t = Vec(1, 1, 0)
2902        assert t.project(s) == Vec(1, 0, 0)
2903
2904    # Orthogonal.
2905
2906    if (Vec != V3i):
2907        s = Vec(2, 0, 0)
2908        t = Vec(1, 1, 0)
2909        o = s.orthogonal(t)
2910        assert iszero(o ^ s, s.baseTypeEpsilon())
2911
2912    # Reflect.
2913
2914    if (Vec != V3i):
2915        s = Vec(1, 1, 0)
2916        t = Vec(2, 0, 0)
2917        r = s.reflect(t)
2918        assert equal(abs(s ^ t), abs(r ^ t), s.baseTypeEpsilon())
2919
2920    # Closest vertex.
2921
2922    v0 = Vec(0, 0, 0)
2923    v1 = Vec(5, 0, 0)
2924    v2 = Vec(0, 5, 0)
2925
2926    p = Vec(1, 1, 0)
2927    assert p.closestVertex(v0, v1, v2) == v0
2928
2929    p = Vec(4, 1, 0)
2930    assert p.closestVertex(v0, v1, v2) == v1
2931
2932    p = Vec(1, 4, 0)
2933    assert p.closestVertex(v0, v1, v2) == v2
2934
2935
2936    print ("ok")
2937
2938    return
2939
2940def testV3 ():
2941
2942    print ("V3i")
2943    testV3x (V3i)
2944    print ("V3f")
2945    testV3x (V3f)
2946    print ("V3d")
2947    testV3x (V3d)
2948
2949testList.append (('testV3',testV3))
2950
2951
2952# -------------------------------------------------------------------------
2953# Tests for V3xArray
2954
2955def testV3xArray (Array, Vec, Arrayx):
2956
2957    # Constructors (and element access).
2958
2959    a = Array (3)
2960
2961    a[0] = Vec(0)
2962    a[1] = Vec(1)
2963    a[2] = Vec(2)
2964
2965    assert a[0] == Vec(0)
2966    assert a[1] == Vec(1)
2967    assert a[2] == Vec(2)
2968
2969    a[0].setValue(10,10,10)
2970    a[1].setValue(11,11,11)
2971    a[2].setValue(12,12,12)
2972
2973    assert a[0] == Vec(10)
2974    assert a[1] == Vec(11)
2975    assert a[2] == Vec(12)
2976
2977    # explicit constructors across types
2978    af = V3fArray(a)
2979    assert a[0] == Vec(af[0])
2980    assert a[1] == Vec(af[1])
2981    assert a[2] == Vec(af[2])
2982    ad = V3dArray(a)
2983    assert a[0] == Vec(ad[0])
2984    assert a[1] == Vec(ad[1])
2985    assert a[2] == Vec(ad[2])
2986    ai = V3iArray(a)
2987    assert a[0] == Vec(ai[0])
2988    assert a[1] == Vec(ai[1])
2989    assert a[2] == Vec(ai[2])
2990
2991
2992    # Element setting.
2993
2994    a = Array(2)
2995
2996    try:
2997        a[-3] = Vec(0)        # This should raise an exception.
2998    except:
2999        pass
3000    else:
3001        assert 0           # We shouldn't get here.
3002
3003    try:
3004        a[3] = Vec(0)   # This should raise an exception.
3005    except:
3006        pass
3007    else:
3008        assert 0           # We shouldn't get here.
3009
3010    try:
3011        a[1] = "a"         # This should raise an exception.
3012    except:
3013        pass
3014    else:
3015        assert 0           # We shouldn't get here.
3016
3017    # Assignment.
3018
3019    a = Array(2)
3020    a[0] = Vec(0)
3021    a[1] = Vec(1)
3022
3023    b = Array(2)
3024    b[0] = Vec(0)
3025    b[1] = Vec(1)
3026
3027    c = Array(2)
3028    c[0] = Vec(10)
3029    c[1] = Vec(11)
3030
3031    # TODO: make equality work correctly.
3032    #assert a == b
3033    assert a != c
3034
3035    # Dot products.
3036
3037    a = Array(2)
3038    a[0] = Vec(1, 2, 3)
3039    a[1] = Vec(4, 5, 6)
3040
3041    b = Array(2)
3042    b[0] = Vec(7, 8, 9)
3043    b[1] = Vec(10, 11, 12)
3044
3045    r = a.dot(b)
3046    assert r[0] == 1*7 + 2*8 + 3*9
3047    assert r[1] == 4*10 + 5*11 + 6*12
3048
3049    c = Vec(13, 14, 15)
3050    r = a.dot(c)
3051    assert r[0] == 1*13 + 2*14 + 3*15
3052    assert r[1] == 4*13 + 5*14 + 6*15
3053
3054    d = Array(3)
3055    try:
3056        a.dot(d)        # This should raise an exception.
3057    except:
3058        pass
3059    else:
3060        assert 0           # We shouldn't get here.
3061
3062
3063    # Cross products.
3064
3065    a = Array(2)
3066    a[0] = Vec(1, 2, 3)
3067    a[1] = Vec(4, 5, 6)
3068
3069    b = Array(2)
3070    b[0] = Vec(7, 8, 9)
3071    b[1] = Vec(10, 11, 12)
3072
3073    r = a.cross(b)
3074    assert r[0] == Vec(1, 2, 3) % Vec(7, 8, 9)
3075    assert r[1] == Vec(4, 5, 6) % Vec(10, 11, 12)
3076
3077    c = Vec(13, 14, 15)
3078    r = a.cross(c)
3079    assert r[0] == Vec(1, 2, 3) % Vec(13, 14, 15)
3080    assert r[1] == Vec(4, 5, 6) % Vec(13, 14, 15)
3081
3082    d = Array(3)
3083    try:
3084        a.cross(d)        # This should raise an exception.
3085    except:
3086        pass
3087    else:
3088        assert 0           # We shouldn't get here.
3089
3090    # Addition.
3091
3092    a = Array(2)
3093    a[0] = Vec(1, 2, 3)
3094    a[1] = Vec(4, 5, 6)
3095
3096    b = Array(2)
3097    b[0] = Vec(7, 8, 9)
3098    b[1] = Vec(10, 11, 12)
3099
3100    r = a + b
3101    assert r[0] == Vec(1+7, 2+8, 3+9)
3102    assert r[1] == Vec(4+10, 5+11, 6+12)
3103
3104    r = a + Vec(10)
3105    assert r[0] == Vec(1+10, 2+10, 3+10)
3106    assert r[1] == Vec(4+10, 5+10, 6+10)
3107
3108    v = Vec(11)
3109    r = v + a
3110    assert r[0] == Vec(11+1, 11+2, 11+3)
3111    assert r[1] == Vec(11+4, 11+5, 11+6)
3112
3113    a += b
3114    assert a[0] == Vec(1+7, 2+8, 3+9)
3115    assert a[1] == Vec(4+10, 5+11, 6+12)
3116
3117    a[0] = Vec(1, 2, 3)
3118    a[1] = Vec(4, 5, 6)
3119
3120    a += Vec(10)
3121    assert a[0] == Vec(1+10, 2+10, 3+10)
3122    assert a[1] == Vec(4+10, 5+10, 6+10)
3123
3124    c = Array(3)
3125
3126    try:
3127        a + c                # This should raise an exception.
3128    except:
3129        pass
3130    else:
3131        assert 0           # We shouldn't get here.
3132
3133    try:
3134        a += c                # This should raise an exception.
3135    except:
3136        pass
3137    else:
3138        assert 0           # We shouldn't get here.
3139
3140    # Subtraction.
3141
3142    a = Array(2)
3143    a[0] = Vec(1, 2, 3)
3144    a[1] = Vec(4, 5, 6)
3145
3146    b = Array(2)
3147    b[0] = Vec(7, 8, 9)
3148    b[1] = Vec(10, 11, 12)
3149
3150    r = a - b
3151    assert r[0] == Vec(1-7, 2-8, 3-9)
3152    assert r[1] == Vec(4-10, 5-11, 6-12)
3153
3154    r = a - Vec(10)
3155    assert r[0] == Vec(1-10, 2-10, 3-10)
3156    assert r[1] == Vec(4-10, 5-10, 6-10)
3157
3158    v = Vec(11)
3159    r = v - a
3160    assert r[0] == Vec(11-1, 11-2, 11-3)
3161    assert r[1] == Vec(11-4, 11-5, 11-6)
3162
3163    a -= b
3164    assert a[0] == Vec(1-7, 2-8, 3-9)
3165    assert a[1] == Vec(4-10, 5-11, 6-12)
3166
3167    a[0] = Vec(1, 2, 3)
3168    a[1] = Vec(4, 5, 6)
3169
3170    a -= Vec(10)
3171    assert a[0] == Vec(1-10, 2-10, 3-10)
3172    assert a[1] == Vec(4-10, 5-10, 6-10)
3173
3174    c = Array(3)
3175
3176    try:
3177        a - c                # This should raise an exception.
3178    except:
3179        pass
3180    else:
3181        assert 0           # We shouldn't get here.
3182
3183    try:
3184        a -= c                # This should raise an exception.
3185    except:
3186        pass
3187    else:
3188        assert 0           # We shouldn't get here.
3189
3190    # Negation.
3191
3192    a = Array(2)
3193    a[0] = Vec(1, 2, 3)
3194    a[1] = Vec(4, 5, 6)
3195
3196    r = -a
3197    assert r[0] == Vec(-1, -2, -3)
3198    assert r[1] == Vec(-4, -5, -6)
3199
3200    # Multiplication.
3201
3202    a = Array(2)
3203    a[0] = Vec(1, 2, 3)
3204    a[1] = Vec(4, 5, 6)
3205
3206    r = a * 10
3207    assert r[0] == Vec(1, 2, 3) * 10
3208    assert r[1] == Vec(4, 5, 6) * 10
3209
3210    b = Arrayx(2)
3211    b[0] = 10
3212    b[1] = 11
3213
3214    r = a * b
3215    assert r[0] == Vec(1, 2, 3) * 10
3216    assert r[1] == Vec(4, 5, 6) * 11
3217
3218    a *= 10
3219    assert a[0] == Vec(1, 2, 3) * 10
3220    assert a[1] == Vec(4, 5, 6) * 10
3221
3222    a[0] = Vec(1, 2, 3)
3223    a[1] = Vec(4, 5, 6)
3224
3225    a *= b
3226    assert a[0] == Vec(1, 2, 3) * 10
3227    assert a[1] == Vec(4, 5, 6) * 11
3228
3229    a[0] = Vec(1, 2, 3)
3230    a[1] = Vec(4, 5, 6)
3231
3232    b = Array(2)
3233    b[0] = Vec(7, 8, 9)
3234    b[1] = Vec(10, 11, 12)
3235
3236    r = a * b
3237    assert r[0] == Vec(1*7, 2*8, 3*9)
3238    assert r[1] == Vec(4*10, 5*11, 6*12)
3239
3240    v = Vec(13, 14, 15)
3241
3242    r = a * v
3243    assert r[0] == Vec(1*13, 2*14, 3*15)
3244    assert r[1] == Vec(4*13, 5*14, 6*15)
3245
3246    r = v * a
3247    assert r[0] == Vec(1*13, 2*14, 3*15)
3248    assert r[1] == Vec(4*13, 5*14, 6*15)
3249
3250    a *= b
3251    assert a[0] == Vec(1*7, 2*8, 3*9)
3252    assert a[1] == Vec(4*10, 5*11, 6*12)
3253
3254    a[0] = Vec(1, 2, 3)
3255    a[1] = Vec(4, 5, 6)
3256
3257    a *= v
3258    assert a[0] == Vec(1*13, 2*14, 3*15)
3259    assert a[1] == Vec(4*13, 5*14, 6*15)
3260
3261    d = Array(3)
3262    try:
3263        a * d                # This should raise an exception.
3264    except:
3265        pass
3266    else:
3267        assert 0           # We shouldn't get here.
3268
3269    try:
3270        a *= d                # This should raise an exception.
3271    except:
3272        pass
3273    else:
3274        assert 0           # We shouldn't get here.
3275
3276    # Division.
3277
3278    a = Array(2)
3279    a[0] = Vec(1.0, 2.0, 3.0)
3280    a[1] = Vec(4.0, 5.0, 6.0)
3281
3282    r = a / 10
3283    assert r[0] == Vec(1.0, 2.0, 3.0) / 10
3284    assert r[1] == Vec(4.0, 5.0, 6.0) / 10
3285
3286    b = Arrayx(2)
3287    b[0] = 10
3288    b[1] = 11
3289
3290    r = a / b
3291    assert r[0] == Vec(1.0, 2.0, 3.0) / 10
3292    assert r[1] == Vec(4.0, 5.0, 6.0) / 11
3293
3294    a /= 10
3295    assert a[0] == Vec(1.0, 2.0, 3.0) / 10
3296    assert a[1] == Vec(4.0, 5.0, 6.0) / 10
3297
3298    a[0] = Vec(1.0, 2.0, 3.0)
3299    a[1] = Vec(4.0, 5.0, 6.0)
3300
3301    a /= b
3302    assert a[0] == Vec(1.0, 2.0, 3.0) / 10
3303    assert a[1] == Vec(4.0, 5.0, 6.0) / 11
3304
3305    a[0] = Vec(1.0, 2.0, 3.0)
3306    a[1] = Vec(4.0, 5.0, 6.0)
3307
3308    b = Array(2)
3309    b[0] = Vec(7.0, 8.0, 9.0)
3310    b[1] = Vec(10.0, 11.0, 12.0)
3311
3312    r = a / b
3313    assert r[0] == Vec(1.0/7, 2.0/8, 3.0/9)
3314    assert r[1] == Vec(4.0/10, 5.0/11, 6.0/12)
3315
3316    v = Vec(13.0, 14.0, 15.0)
3317
3318    r = a / v
3319    assert r[0] == Vec(1.0/13, 2.0/14, 3.0/15)
3320    assert r[1] == Vec(4.0/13, 5.0/14, 6.0/15)
3321
3322    # TODO: Figure out why "v / a" is illegal, even though the
3323    # add_arithmetic_math_functions() routine in PyImathFixedArray.h
3324    # should make it possible.
3325    #r = v / a
3326    #assert r[0] == Vec(1.0/13, 2.0/14, 3.0/15)
3327    #assert r[1] == Vec(4.0/13, 5.0/14, 6.0/15)
3328
3329    a /= b
3330    assert a[0] == Vec(1.0/7, 2.0/8, 3.0/9)
3331    assert a[1] == Vec(4.0/10, 5.0/11, 6.0/12)
3332
3333    a[0] = Vec(1.0, 2.0, 3.0)
3334    a[1] = Vec(4.0, 5.0, 6.0)
3335
3336    a /= v
3337    assert a[0] == Vec(1.0/13, 2.0/14, 3.0/15)
3338    assert a[1] == Vec(4.0/13, 5.0/14, 6.0/15)
3339
3340    d = Array(3)
3341    try:
3342        a / d                # This should raise an exception.
3343    except:
3344        pass
3345    else:
3346        assert 0           # We shouldn't get here.
3347
3348    try:
3349        a /= d                # This should raise an exception.
3350    except:
3351        pass
3352    else:
3353        assert 0           # We shouldn't get here.
3354
3355    # Length.
3356
3357    v0 = Vec(1, 2, 3)
3358    v1 = Vec(4, 5, 6)
3359
3360    a = Array(2)
3361    a[0] = v0
3362    a[1] = v1
3363
3364    if (Vec != V3i):
3365        l = a.length()
3366        assert (l[0] == v0.length())
3367        assert (l[1] == v1.length())
3368
3369    l = a.length2()
3370    assert (l[0] == v0.length2())
3371    assert (l[1] == v1.length2())
3372
3373    # Normalizing.
3374
3375    if (Vec != V3i):
3376
3377        a[0] = Vec(1, 2, 3)
3378        a[1] = Vec(4, 5, 6)
3379
3380        r = a.normalized();
3381        assert r[0] == Vec(1, 2, 3).normalized()
3382        assert r[1] == Vec(4, 5, 6).normalized()
3383
3384        a.normalize();
3385        assert a[0] == Vec(1, 2, 3).normalized()
3386        assert a[1] == Vec(4, 5, 6).normalized()
3387
3388    print ("ok")
3389
3390    return
3391
3392def testV3Array ():
3393
3394    print ("V3iArray")
3395    testV3xArray (V3iArray, V3i, IntArray)
3396    print ("V3fArray")
3397    testV3xArray (V3fArray, V3f, FloatArray)
3398    print ("V3dArray")
3399    testV3xArray (V3dArray, V3d, DoubleArray)
3400
3401testList.append (('testV3Array',testV3Array))
3402
3403
3404# -------------------------------------------------------------------------
3405# Tests for Vec --> Vec conversions
3406
3407def testV2xConversions (Vec):
3408
3409    # Assignment
3410
3411    v1 = Vec(0, 1)
3412
3413    v2 = V2i (v1)
3414    assert v2[0] == 0 and v2[1] == 1
3415
3416    v2 = V2f (v1)
3417    assert v2[0] == 0 and v2[1] == 1
3418
3419    v2 = V2d (v1)
3420    assert v2[0] == 0 and v2[1] == 1
3421
3422    # The += operator
3423
3424    v2 = Vec (1, 2)
3425    v2 += V2i (v1)
3426    assert v2[0] == 1 and v2[1] == 3
3427
3428    v2 = Vec (1, 2)
3429    v2 += V2f (v1)
3430    assert v2[0] == 1 and v2[1] == 3
3431
3432    v2 = Vec (1, 2)
3433    v2 += V2d (v1)
3434    assert v2[0] == 1 and v2[1] == 3
3435
3436    # The -= operator
3437
3438    v2 = Vec (1, 2)
3439    v2 -= V2i (v1)
3440    assert v2[0] == 1 and v2[1] == 1
3441
3442    v2 = Vec (1, 2)
3443    v2 -= V2f (v1)
3444    assert v2[0] == 1 and v2[1] == 1
3445
3446    v2 = Vec (1, 2)
3447    v2 -= V2d (v1)
3448    assert v2[0] == 1 and v2[1] == 1
3449
3450    # The *= operator
3451
3452    v2 = Vec (1, 2)
3453    v2 *= V2i (v1)
3454    assert v2[0] == 0 and v2[1] == 2
3455
3456    v2 = Vec (1, 2)
3457    v2 *= V2f (v1)
3458    assert v2[0] == 0 and v2[1] == 2
3459
3460    v2 = Vec (1, 2)
3461    v2 *= V2d (v1)
3462    assert v2[0] == 0 and v2[1] == 2
3463
3464    print ("ok")
3465    return
3466
3467
3468def testV3xConversions (Vec):
3469
3470    # Assignment
3471
3472    v1 = Vec(0, 1, 2)
3473
3474    v2 = V3i (v1)
3475    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2
3476
3477    v2 = V3f (v1)
3478    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2
3479
3480    v2 = V3d (v1)
3481    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2
3482
3483    # The += operator
3484
3485    v2 = Vec (1, 2, 3)
3486    v2 += V3i (v1)
3487    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5
3488
3489    v2 = Vec (1, 2, 3)
3490    v2 += V3f (v1)
3491    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5
3492
3493    v2 = Vec (1, 2, 3)
3494    v2 += V3d (v1)
3495    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5
3496
3497    # The -= operator
3498
3499    v2 = Vec (1, 2, 3)
3500    v2 -= V3i (v1)
3501    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1
3502
3503    v2 = Vec (1, 2, 3)
3504    v2 -= V3f (v1)
3505    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1
3506
3507    v2 = Vec (1, 2, 3)
3508    v2 -= V3d (v1)
3509    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1
3510
3511    # The *= operator
3512
3513    v2 = Vec (1, 2, 3)
3514    v2 *= V3i (v1)
3515    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6
3516
3517    v2 = Vec (1, 2, 3)
3518    v2 *= V3f (v1)
3519    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6
3520
3521    v2 = Vec (1, 2, 3)
3522    v2 *= V3d (v1)
3523    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6
3524
3525    print ("ok")
3526    return
3527
3528# -------------------------------------------------------------------------
3529# Tests for V4x
3530
3531def testV4x (Vec):
3532
3533    # Constructors (and element access).
3534
3535    v = Vec()
3536    assert v[0] == 0 and v[1] == 0 and v[2] == 0 and v[3] == 0
3537
3538    v = Vec(1)
3539    assert v[0] == 1 and v[1] == 1 and v[2] == 1 and v[3] == 1
3540
3541    v = Vec(0, 1, 2, 3)
3542    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
3543
3544    v = Vec((0, 1, 2, 3))
3545    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
3546
3547    v = Vec([0, 1, 2, 3])
3548    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
3549
3550    v = Vec()
3551    v.setValue(0, 1, 2, 3)
3552    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
3553
3554    # Repr.
3555
3556    v = Vec(1/9., 2/9., 3/9., 4./9.)
3557    assert v == eval(repr(v))
3558
3559    # Sequence length.
3560
3561    v = Vec()
3562    assert len(v) == 4
3563
3564    # Element setting.
3565
3566    v = Vec()
3567    v[0] = 10
3568    v[1] = 11
3569    v[2] = 12
3570    v[3] = 13
3571    assert v[0] == 10 and v[1] == 11 and v[2] == 12 and v[3] == 13
3572
3573    try:
3574        # TODO why does this have to be -5 and not -4?
3575        v[-5] = 0           # This should raise an exception.
3576    except:
3577        pass
3578    else:
3579        assert 0           # We shouldn't get here.
3580
3581    try:
3582        v[4] = 0           # This should raise an exception.
3583    except:
3584        pass
3585    else:
3586        assert 0           # We shouldn't get here.
3587
3588    try:
3589        v[1] = "a"           # This should raise an exception.
3590    except:
3591        pass
3592    else:
3593        assert 0           # We shouldn't get here.
3594
3595    # Assignment.
3596
3597    v1 = Vec(1)
3598
3599    v2 = v1
3600    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
3601    v1[0] = 2
3602    assert v2[0] == 2 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
3603
3604    # Comparison operators.
3605
3606    v1 = Vec(20, 20, 20, 20)
3607    v2 = Vec(20, 20, 20, 20)
3608    v3 = Vec(20, 20, 20, 21)
3609
3610    assert v1 == v2
3611    assert v1 != v3
3612    assert not (v1 < v2)
3613    assert v1 < v3
3614    assert v1 <= v2
3615    assert v1 <= v3
3616    assert not (v3 <= v1)
3617    assert not (v2 > v1)
3618    assert v3 > v1
3619    assert v2 >= v1
3620    assert v3 >= v1
3621    assert not (v1 >= v3)
3622
3623    # Epsilon equality.
3624
3625    e = 0.005
3626    v1 = Vec(1)
3627    v2 = Vec(1 + e)
3628
3629    assert v1.equalWithAbsError(v2, e)
3630    assert v2.equalWithAbsError(v1, e)
3631
3632    e = 0.003
3633    v1 = Vec(10)
3634    v2 = Vec(10 + 10 * e)
3635
3636    assert v1.equalWithRelError(v2, e)
3637    assert v2.equalWithRelError(v1, e)
3638
3639    # Dot products.
3640
3641    v1 = Vec(0, 1, 0, 1)
3642    v2 = Vec(1, 0, 0, 0)
3643    v3 = Vec(1, 1, 1, 1)
3644
3645    assert v1.dot(v2) == 0
3646    assert v1.dot(v3) == 2
3647    assert v1 ^ v2 == v1.dot(v2)
3648    assert v1 ^ v3 == v1.dot(v3)
3649
3650    # Addition.
3651
3652    v1 = Vec(10, 20, 30, 40)
3653    v2 = Vec(30, 40, 50, 60)
3654
3655    assert v1 + v2 == Vec(40, 60, 80, 100)
3656    assert v2 + v1 == v1 + v2
3657    assert v1 + 1 == Vec(11, 21, 31, 41)
3658    assert 1 + v1 == v1 + 1
3659
3660    # (with the switch to python2, we now allow ops between vectors and tuples)
3661    assert v1 + (1, 2, 3, 4) == Vec(11, 22, 33, 44)
3662    assert (1, 2, 3, 4) + v1 == v1 + (1, 2, 3, 4)
3663
3664    # Subtraction and negation.
3665
3666    v1 = Vec(10, 20, 30, 40)
3667    v2 = Vec(30, 40, 50, 60)
3668
3669    assert v2 - v1 == Vec(20, 20, 20, 20)
3670    assert v1 - 1 == Vec(9, 19, 29, 39)
3671    assert 1 - v1 == - (v1 - 1)
3672
3673    # (with the switch to python2, we now allow ops between vectors and tuples)
3674    assert v1 - (1, 2, 3, 4) == Vec(9, 18, 27, 36)
3675    assert (1, 2, 3, 4) - v1 == - (v1 - (1, 2, 3, 4))
3676
3677    assert v1.negate() == Vec(-10, -20, -30, -40)
3678
3679    # Multiplication.
3680
3681    v1 = Vec(1, 2, 3, 4)
3682    v2 = Vec(3, 4, 5, 6)
3683
3684    assert v1 * v2 == Vec(3, 8, 15, 24)
3685    assert v2 * v1 == v1 * v2
3686    assert 2 * v1 == Vec(2, 4, 6, 8)
3687    assert v1 * 2 == 2 * v1
3688
3689    assert v1 * V4i(3, 4, 5, 6) == Vec(3, 8, 15, 24)
3690    assert v1 * V4f(3, 4, 5, 6) == Vec(3, 8, 15, 24)
3691    assert v1 * V4d(3, 4, 5, 6) == Vec(3, 8, 15, 24)
3692
3693    v1 *= 2
3694    assert v1 == Vec(2, 4, 6, 8)
3695    v1 = Vec(1, 2, 3, 4)
3696
3697    # (with the switch to python2, we now allow ops between vectors and tuples)
3698    assert v1 * (1, 2, 3, 4) == Vec(1, 4, 9, 16)
3699    assert (1, 2, 3, 4) * v1 == v1 * (1, 2, 3, 4)
3700
3701    # Division.
3702
3703    v1 = Vec(10, 20, 40, 80)
3704    v2 = Vec(2, 4, 8, 10)
3705
3706    assert v1 / v2 == Vec(10/2, 20/4, 40/8, 80/10)
3707    assert v1 / 2 == Vec(10/2, 20/2, 40/2, 80/2)
3708    assert Vec(80) / v1 == Vec(80/10, 80/20, 80/40, 80/80)
3709
3710    # (with the switch to python2, we now allow ops between vectors and tuples)
3711    assert v1 / (1, 2, 4, 8) == Vec(10, 10, 10, 10)
3712    assert Vec(50, 40, 80, 160) / v1 == Vec(5, 2, 2, 2)
3713
3714    assert v1 / V4i (2, 4, 8, 10) == Vec(10/2, 20/4, 40/8, 80/10)
3715    assert v1 / V4f (2, 4, 8, 10) == Vec(10/2, 20/4, 40/8, 80/10)
3716    assert v1 / V4d (2, 4, 8, 10) == Vec(10/2, 20/4, 40/8, 80/10)
3717    assert v1 / (2, 4, 8, 10) == Vec(10/2, 20/4, 40/8, 80/10)
3718    assert v1 / [2, 4, 8, 10] == Vec(10/2, 20/4, 40/8, 80/10)
3719
3720    v1 = Vec(10, 20, 40, 80)
3721    v1 /= 2
3722    assert v1 == Vec(10/2, 20/2, 40/2, 80/2)
3723
3724    v1 = Vec(10, 20, 40, 80)
3725    v1 /= V4i (2, 4, 8, 10)
3726    assert v1 == Vec(10/2, 20/4, 40/8, 80/10)
3727
3728    v1 = Vec(10, 20, 40, 80)
3729    v1 /= V4f (2, 4, 8, 10)
3730    assert v1 == Vec(10/2, 20/4, 40/8, 80/10)
3731
3732    v1 = Vec(10, 20, 40, 80)
3733    v1 /= V4d (2, 4, 8, 10)
3734    assert v1 == Vec(10/2, 20/4, 40/8, 80/10)
3735
3736    v1 = Vec(10, 20, 40, 80)
3737    v1 /= (2, 4, 8, 10)
3738    assert v1 == Vec(10/2, 20/4, 40/8, 80/10)
3739
3740    v1 = Vec(10, 20, 40, 80)
3741    v1 /= [2, 4, 8, 10]
3742    assert v1 == Vec(10/2, 20/4, 40/8, 80/10)
3743
3744    # Length.
3745
3746    if (Vec != V4i):
3747       v = Vec(1, 2, 3, 4)
3748       assert equal(v.length(), sqrt(1*1 + 2*2 + 3*3 + 4*4), 10.0*v.baseTypeEpsilon())
3749
3750    v = Vec(1, 2, 3, 4)
3751    assert v.length2() == 1*1 + 2*2 + 3*3 + 4*4
3752
3753    # Normalizing.
3754
3755    if (Vec != V4i):
3756       v = Vec(1, 2, 3, 4)
3757       v.normalize()
3758       assert equal(v.length(), 1, v.baseTypeEpsilon())
3759
3760       v = Vec(1, 2, 3, 4)
3761       v.normalizeExc()
3762       assert equal(v.length(), 1, v.baseTypeEpsilon())
3763       v = Vec(0)
3764       try:
3765           v.normalizeExc()        # This should raise an exception.
3766       except:
3767           pass
3768       else:
3769           assert 0                # We shouldn't get here.
3770
3771       v = Vec(1, 2, 3, 4)
3772       v.normalizeNonNull()
3773       assert equal(v.length(), 1, v.baseTypeEpsilon())
3774
3775       v = Vec(1, 2, 3, 4)
3776       assert equal(v.normalized().length(), 1, v.baseTypeEpsilon())
3777
3778       v = Vec(1, 2, 3, 4)
3779       assert equal(v.normalizedExc().length(), 1, v.baseTypeEpsilon())
3780       v = Vec(0)
3781       try:
3782           v.normalizedExc()  # This should raise an exception.
3783       except:
3784           pass
3785       else:
3786           assert 0              # We shouldn't get here.
3787
3788       v = Vec(1, 2, 3, 4)
3789       assert equal(v.normalizedNonNull().length(), 1, v.baseTypeEpsilon())
3790
3791    # Projection.
3792
3793    if (Vec != V4i):
3794        s = Vec(0, 0, 0, 2)
3795        t = Vec(1, 1, 1, 1)
3796        assert t.project(s) == Vec(0, 0, 0, 1)
3797
3798    # Orthogonal.
3799
3800    if (Vec != V4i):
3801        s = Vec(0, 0, 0, 2)
3802        t = Vec(1, 1, 1, 1)
3803        o = s.orthogonal(t)
3804        assert iszero(o ^ s, s.baseTypeEpsilon())
3805
3806    # Reflect.
3807
3808    if (Vec != V4i):
3809        s = Vec(1, 1, 1, 1)
3810        t = Vec(0, 0, 0, 2)
3811        r = s.reflect(t)
3812        assert equal(abs(s ^ t), abs(r ^ t), s.baseTypeEpsilon())
3813
3814    print ("ok")
3815
3816    return
3817
3818def testV4 ():
3819
3820    print ("V4i")
3821    testV4x (V4i)
3822    print ("V4f")
3823    testV4x (V4f)
3824    print ("V4d")
3825    testV4x (V4d)
3826
3827testList.append (('testV4',testV4))
3828
3829
3830# -------------------------------------------------------------------------
3831# Tests for V4xArray
3832
3833def testV4xArray (Array, Vec, Arrayx):
3834
3835    # Constructors (and element access).
3836
3837    a = Array (4)
3838
3839    a[0] = Vec(0)
3840    a[1] = Vec(1)
3841    a[2] = Vec(2)
3842    a[3] = Vec(3)
3843
3844    assert a[0] == Vec(0)
3845    assert a[1] == Vec(1)
3846    assert a[2] == Vec(2)
3847    assert a[3] == Vec(3)
3848
3849    a[0].setValue(10,10,10,10)
3850    a[1].setValue(11,11,11,11)
3851    a[2].setValue(12,12,12,12)
3852    a[3].setValue(13,13,13,13)
3853
3854    assert a[0] == Vec(10)
3855    assert a[1] == Vec(11)
3856    assert a[2] == Vec(12)
3857    assert a[3] == Vec(13)
3858
3859    # Element setting.
3860
3861    a = Array(2)
3862
3863    try:
3864        a[-3] = Vec(0)        # This should raise an exception.
3865    except:
3866        pass
3867    else:
3868        assert 0           # We shouldn't get here.
3869
3870    try:
3871        a[4] = Vec(0)   # This should raise an exception.
3872    except:
3873        pass
3874    else:
3875        assert 0           # We shouldn't get here.
3876
3877    try:
3878        a[1] = "a"         # This should raise an exception.
3879    except:
3880        pass
3881    else:
3882        assert 0           # We shouldn't get here.
3883
3884    # Assignment.
3885
3886    a = Array(2)
3887    a[0] = Vec(0)
3888    a[1] = Vec(1)
3889
3890    b = Array(2)
3891    b[0] = Vec(0)
3892    b[1] = Vec(1)
3893
3894    c = Array(2)
3895    c[0] = Vec(10)
3896    c[1] = Vec(11)
3897
3898    # TODO: make equality work correctly.
3899    #assert a == b
3900    assert a != c
3901
3902    # Dot products.
3903
3904    a = Array(2)
3905    a[0] = Vec(1, 2, 3, 4)
3906    a[1] = Vec(4, 5, 6, 7)
3907
3908    b = Array(2)
3909    b[0] = Vec(7, 8, 9, 10)
3910    b[1] = Vec(10, 11, 12, 13)
3911
3912    r = a.dot(b)
3913    assert r[0] == 1*7 + 2*8 + 3*9 + 4*10
3914    assert r[1] == 4*10 + 5*11 + 6*12 + 7*13
3915
3916    c = Vec(13, 14, 15, 16)
3917    r = a.dot(c)
3918    assert r[0] == 1*13 + 2*14 + 3*15 + 4*16
3919    assert r[1] == 4*13 + 5*14 + 6*15 + 7*16
3920
3921    d = Array(3)
3922    try:
3923        a.dot(d)        # This should raise an exception.
3924    except:
3925        pass
3926    else:
3927        assert 0           # We shouldn't get here.
3928
3929    # Addition.
3930
3931    a = Array(2)
3932    a[0] = Vec(1, 2, 3, 4)
3933    a[1] = Vec(4, 5, 6, 7)
3934
3935    b = Array(2)
3936    b[0] = Vec(7, 8, 9, 10)
3937    b[1] = Vec(10, 11, 12, 13)
3938
3939    r = a + b
3940    assert r[0] == Vec(1+7, 2+8, 3+9, 4+10)
3941    assert r[1] == Vec(4+10, 5+11, 6+12, 7+13)
3942
3943    r = a + Vec(10)
3944    assert r[0] == Vec(1+10, 2+10, 3+10, 4+10)
3945    assert r[1] == Vec(4+10, 5+10, 6+10, 7+10)
3946
3947    v = Vec(11)
3948    r = v + a
3949    assert r[0] == Vec(11+1, 11+2, 11+3, 11+4)
3950    assert r[1] == Vec(11+4, 11+5, 11+6, 11+7)
3951
3952    a += b
3953    assert a[0] == Vec(1+7, 2+8, 3+9, 4+10)
3954    assert a[1] == Vec(4+10, 5+11, 6+12, 7+13)
3955
3956    a[0] = Vec(1, 2, 3, 4)
3957    a[1] = Vec(4, 5, 6, 7)
3958
3959    a += Vec(10)
3960    assert a[0] == Vec(1+10, 2+10, 3+10, 4+10)
3961    assert a[1] == Vec(4+10, 5+10, 6+10, 7+10)
3962
3963    c = Array(3)
3964
3965    try:
3966        a + c                # This should raise an exception.
3967    except:
3968        pass
3969    else:
3970        assert 0           # We shouldn't get here.
3971
3972    try:
3973        a += c                # This should raise an exception.
3974    except:
3975        pass
3976    else:
3977        assert 0           # We shouldn't get here.
3978
3979    # Subtraction.
3980
3981    a = Array(2)
3982    a[0] = Vec(1, 2, 3, 4)
3983    a[1] = Vec(4, 5, 6, 7)
3984
3985    b = Array(2)
3986    b[0] = Vec(7, 8, 9, 10)
3987    b[1] = Vec(10, 11, 12, 13)
3988
3989    r = a - b
3990    assert r[0] == Vec(1-7, 2-8, 3-9, 4-10)
3991    assert r[1] == Vec(4-10, 5-11, 6-12, 7-13)
3992
3993    r = a - Vec(10)
3994    assert r[0] == Vec(1-10, 2-10, 3-10, 4-10)
3995    assert r[1] == Vec(4-10, 5-10, 6-10, 7-10)
3996
3997    v = Vec(11)
3998    r = v - a
3999    assert r[0] == Vec(11-1, 11-2, 11-3, 11-4)
4000    assert r[1] == Vec(11-4, 11-5, 11-6, 11-7)
4001
4002    a -= b
4003    assert a[0] == Vec(1-7, 2-8, 3-9, 4-10)
4004    assert a[1] == Vec(4-10, 5-11, 6-12, 7-13)
4005
4006    a[0] = Vec(1, 2, 3, 4)
4007    a[1] = Vec(4, 5, 6, 7)
4008
4009    a -= Vec(10)
4010    assert a[0] == Vec(1-10, 2-10, 3-10, 4-10)
4011    assert a[1] == Vec(4-10, 5-10, 6-10, 7-10)
4012
4013    c = Array(3)
4014
4015    try:
4016        a - c                # This should raise an exception.
4017    except:
4018        pass
4019    else:
4020        assert 0           # We shouldn't get here.
4021
4022    try:
4023        a -= c                # This should raise an exception.
4024    except:
4025        pass
4026    else:
4027        assert 0           # We shouldn't get here.
4028
4029    # Negation.
4030
4031    a = Array(2)
4032    a[0] = Vec(1, 2, 3, 4)
4033    a[1] = Vec(4, 5, 6, 7)
4034
4035    r = -a
4036    assert r[0] == Vec(-1, -2, -3, -4)
4037    assert r[1] == Vec(-4, -5, -6, -7)
4038
4039    # Multiplication.
4040
4041    a = Array(2)
4042    a[0] = Vec(1, 2, 3, 4)
4043    a[1] = Vec(4, 5, 6, 7)
4044
4045    r = a * 10
4046    assert r[0] == Vec(1, 2, 3, 4) * 10
4047    assert r[1] == Vec(4, 5, 6, 7) * 10
4048
4049    b = Arrayx(2)
4050    b[0] = 10
4051    b[1] = 11
4052
4053    r = a * b
4054    assert r[0] == Vec(1, 2, 3, 4) * 10
4055    assert r[1] == Vec(4, 5, 6, 7) * 11
4056
4057    a *= 10
4058    assert a[0] == Vec(1, 2, 3, 4) * 10
4059    assert a[1] == Vec(4, 5, 6, 7) * 10
4060
4061    a[0] = Vec(1, 2, 3, 4)
4062    a[1] = Vec(4, 5, 6, 7)
4063
4064    a *= b
4065    assert a[0] == Vec(1, 2, 3, 4) * 10
4066    assert a[1] == Vec(4, 5, 6, 7) * 11
4067
4068    a[0] = Vec(1, 2, 3, 4)
4069    a[1] = Vec(4, 5, 6, 7)
4070
4071    b = Array(2)
4072    b[0] = Vec(7, 8, 9, 10)
4073    b[1] = Vec(10, 11, 12, 13)
4074
4075    r = a * b
4076    assert r[0] == Vec(1*7, 2*8, 3*9, 4*10)
4077    assert r[1] == Vec(4*10, 5*11, 6*12, 7*13)
4078
4079    v = Vec(13, 14, 15, 16)
4080
4081    r = a * v
4082    assert r[0] == Vec(1*13, 2*14, 3*15, 4*16)
4083    assert r[1] == Vec(4*13, 5*14, 6*15, 7*16)
4084
4085    r = v * a
4086    assert r[0] == Vec(1*13, 2*14, 3*15, 4*16)
4087    assert r[1] == Vec(4*13, 5*14, 6*15, 7*16)
4088
4089    a *= b
4090    assert a[0] == Vec(1*7, 2*8, 3*9, 4*10)
4091    assert a[1] == Vec(4*10, 5*11, 6*12, 7*13)
4092
4093    a[0] = Vec(1, 2, 3, 4)
4094    a[1] = Vec(4, 5, 6, 7)
4095
4096    a *= v
4097    assert a[0] == Vec(1*13, 2*14, 3*15, 4*16)
4098    assert a[1] == Vec(4*13, 5*14, 6*15, 7*16)
4099
4100    d = Array(3)
4101    try:
4102        a * d                # This should raise an exception.
4103    except:
4104        pass
4105    else:
4106        assert 0           # We shouldn't get here.
4107
4108    try:
4109        a *= d                # This should raise an exception.
4110    except:
4111        pass
4112    else:
4113        assert 0           # We shouldn't get here.
4114
4115    # Division.
4116
4117    a = Array(2)
4118    a[0] = Vec(1.0, 2.0, 3.0, 4.0)
4119    a[1] = Vec(4.0, 5.0, 6.0, 7.0)
4120
4121    r = a / 10
4122    assert r[0] == Vec(1.0, 2.0, 3.0, 4.0) / 10
4123    assert r[1] == Vec(4.0, 5.0, 6.0, 7.0) / 10
4124
4125    b = Arrayx(2)
4126    b[0] = 10
4127    b[1] = 11
4128
4129    r = a / b
4130    assert r[0] == Vec(1.0, 2.0, 3.0, 4.0) / 10
4131    assert r[1] == Vec(4.0, 5.0, 6.0, 7.0) / 11
4132
4133    a /= 10
4134    assert a[0] == Vec(1.0, 2.0, 3.0, 4.0) / 10
4135    assert a[1] == Vec(4.0, 5.0, 6.0, 7.0) / 10
4136
4137    a[0] = Vec(1.0, 2.0, 3.0, 4.0)
4138    a[1] = Vec(4.0, 5.0, 6.0, 7.0)
4139
4140    a /= b
4141    assert a[0] == Vec(1.0, 2.0, 3.0, 4.0) / 10
4142    assert a[1] == Vec(4.0, 5.0, 6.0, 7.0) / 11
4143
4144    a[0] = Vec(1.0, 2.0, 3.0, 4.0)
4145    a[1] = Vec(4.0, 5.0, 6.0, 7.0)
4146
4147    b = Array(2)
4148    b[0] = Vec(7.0, 8.0, 9.0, 10.0)
4149    b[1] = Vec(10.0, 11.0, 12.0, 13.0)
4150
4151    r = a / b
4152    assert r[0] == Vec(1.0/7, 2.0/8, 3.0/9, 4.0/10)
4153    assert r[1] == Vec(4.0/10, 5.0/11, 6.0/12, 7.0/13)
4154
4155    v = Vec(13.0, 14.0, 15.0, 16)
4156
4157    r = a / v
4158    assert r[0] == Vec(1.0/13, 2.0/14, 3.0/15, 4.0/16)
4159    assert r[1] == Vec(4.0/13, 5.0/14, 6.0/15, 7.0/16)
4160
4161    # TODO: Figure out why "v / a" is illegal, even though the
4162    # add_arithmetic_math_functions() routine in PyImathFixedArray.h
4163    # should make it possible.
4164    #r = v / a
4165    #assert r[0] == Vec(1.0/13, 2.0/14, 3.0/15)
4166    #assert r[1] == Vec(4.0/13, 5.0/14, 6.0/15)
4167
4168    a /= b
4169    assert a[0] == Vec(1.0/7, 2.0/8, 3.0/9, 4.0/10)
4170    assert a[1] == Vec(4.0/10, 5.0/11, 6.0/12, 7.0/13)
4171
4172    a[0] = Vec(1.0, 2.0, 3.0, 4.0)
4173    a[1] = Vec(4.0, 5.0, 6.0, 7.0)
4174
4175    a /= v
4176    assert a[0] == Vec(1.0/13, 2.0/14, 3.0/15, 4.0/16)
4177    assert a[1] == Vec(4.0/13, 5.0/14, 6.0/15, 7.0/16)
4178
4179    d = Array(3)
4180    try:
4181        a / d                # This should raise an exception.
4182    except:
4183        pass
4184    else:
4185        assert 0           # We shouldn't get here.
4186
4187    try:
4188        a /= d                # This should raise an exception.
4189    except:
4190        pass
4191    else:
4192        assert 0           # We shouldn't get here.
4193
4194    # Length.
4195
4196    v0 = Vec(1, 2, 3, 4)
4197    v1 = Vec(4, 5, 6, 7)
4198
4199    a = Array(2)
4200    a[0] = v0
4201    a[1] = v1
4202
4203    if (Vec != V4i):
4204        l = a.length()
4205        assert (l[0] == v0.length())
4206        assert (l[1] == v1.length())
4207
4208    l = a.length2()
4209    assert (l[0] == v0.length2())
4210    assert (l[1] == v1.length2())
4211
4212    # Normalizing.
4213
4214    if (Vec != V4i):
4215
4216        a[0] = Vec(1, 2, 3, 4)
4217        a[1] = Vec(4, 5, 6, 7)
4218
4219        r = a.normalized();
4220        assert r[0] == Vec(1, 2, 3, 4).normalized()
4221        assert r[1] == Vec(4, 5, 6, 7).normalized()
4222
4223        a.normalize();
4224        assert a[0] == Vec(1, 2, 3, 4).normalized()
4225        assert a[1] == Vec(4, 5, 6, 7).normalized()
4226
4227    print ("ok")
4228
4229    return
4230
4231def testV4Array ():
4232
4233    print ("V4iArray")
4234    testV4xArray (V4iArray, V4i, IntArray)
4235    print ("V4fArray")
4236    testV4xArray (V4fArray, V4f, FloatArray)
4237    print ("V4dArray")
4238    testV4xArray (V4dArray, V4d, DoubleArray)
4239
4240testList.append (('testV4Array',testV4Array))
4241
4242def testV4xConversions (Vec):
4243
4244    # Assignment
4245
4246    v1 = Vec(0, 1, 2, 3)
4247
4248    v2 = V4i (v1)
4249    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2 and v2[3] == 3
4250
4251    v2 = V4f (v1)
4252    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2 and v2[3] == 3
4253
4254    v2 = V4d (v1)
4255    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2 and v2[3] == 3
4256
4257    # The += operator
4258
4259    v2 = Vec (1, 2, 3, 4)
4260    v2 += V4i (v1)
4261    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5 and v2[3] == 7
4262
4263    v2 = Vec (1, 2, 3, 4)
4264    v2 += V4f (v1)
4265    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5  and v2[3] == 7
4266
4267    v2 = Vec (1, 2, 3, 4)
4268    v2 += V4d (v1)
4269    assert v2[0] == 1 and v2[1] == 3 and v2[2] == 5  and v2[3] == 7
4270
4271    # The -= operator
4272
4273    v2 = Vec (1, 2, 3, 4)
4274    v2 -= V4i (v1)
4275    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
4276
4277    v2 = Vec (1, 2, 3, 4)
4278    v2 -= V4f (v1)
4279    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
4280
4281    v2 = Vec (1, 2, 3, 4)
4282    v2 -= V4d (v1)
4283    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
4284
4285    # The *= operator
4286
4287    v2 = Vec (1, 2, 3, 4)
4288    v2 *= V4i (v1)
4289    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6 and v2[3] == 12
4290
4291    v2 = Vec (1, 2, 3, 4)
4292    v2 *= V4f (v1)
4293    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6 and v2[3] == 12
4294
4295    v2 = Vec (1, 2, 3, 4)
4296    v2 *= V4d (v1)
4297    assert v2[0] == 0 and v2[1] == 2 and v2[2] == 6 and v2[3] == 12
4298
4299    print ("ok")
4300    return
4301
4302
4303def testV2xV3xConversion (VecA, VecB):
4304
4305    try:
4306        v = VecA();
4307        v1 = VecB (v);           # This should raise an exception.
4308    except:
4309        pass
4310    else:
4311        assert 0           # We shouldn't get here.
4312
4313
4314def testVecConversions ():
4315
4316    print ("V2i")
4317    testV2xConversions (V2i)
4318    print ("V2f")
4319    testV2xConversions (V2f)
4320    print ("V2d")
4321    testV2xConversions (V2d)
4322
4323    print ("V3i")
4324    testV3xConversions (V3i)
4325    print ("V3f")
4326    testV3xConversions (V3f)
4327    print ("V3d")
4328    testV3xConversions (V3d)
4329
4330    print ("V4i")
4331    testV4xConversions (V4i)
4332    print ("V4f")
4333    testV4xConversions (V4f)
4334    print ("V4d")
4335    testV4xConversions (V4d)
4336
4337
4338    print ("invalid conversions")
4339    # Deliberatly not exhaustive, just representative.
4340    testV2xV3xConversion (V2i, V3f)
4341    testV2xV3xConversion (V3f, V2d)
4342
4343    print ("ok")
4344    return
4345
4346
4347testList.append (('testVecConversions',testVecConversions))
4348
4349
4350
4351# -------------------------------------------------------------------------
4352# Tests for Shear6x
4353
4354def testShear6x (Shear):
4355
4356    # Constructors (and element access).
4357
4358    h = Shear()
4359    assert h[0] == 0 and h[1] == 0 and h[2] == 0 and \
4360           h[3] == 0 and h[4] == 0 and h[5] == 0
4361
4362    h = Shear(1)
4363    assert h[0] == 1 and h[1] == 1 and h[2] == 1 and \
4364           h[3] == 1 and h[4] == 1 and h[5] == 1
4365
4366    h = Shear(0, 1, 2)
4367    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4368           h[3] == 0 and h[4] == 0 and h[5] == 0
4369
4370    h = Shear((0, 1, 2))
4371    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4372           h[3] == 0 and h[4] == 0 and h[5] == 0
4373
4374    h = Shear(0, 1, 2, 3, 4, 5)
4375    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4376           h[3] == 3 and h[4] == 4 and h[5] == 5
4377
4378    h = Shear((0, 1, 2, 3, 4, 5))
4379    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4380           h[3] == 3 and h[4] == 4 and h[5] == 5
4381
4382    h = Shear()
4383    h.setValue(0, 1, 2, 3, 4, 5)
4384    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4385           h[3] == 3 and h[4] == 4 and h[5] == 5
4386
4387    # Repr.
4388
4389    h = Shear(1/9., 2/9., 3/9., 4/9., 5/9., 6/9.)
4390    assert h == eval(repr(h))
4391
4392    # Sequence length.
4393
4394    h = Shear()
4395    assert len(h) == 6
4396
4397    # Element setting.
4398
4399    h = Shear()
4400    h[0] = 10
4401    h[1] = 11
4402    h[2] = 12
4403    h[3] = 13
4404    h[4] = 14
4405    h[5] = 15
4406    assert h[0] == 10 and h[1] == 11 and h[2] == 12 and \
4407           h[3] == 13 and h[4] == 14 and h[5] == 15
4408
4409    try:
4410        h[-7] = 0           # This should raise an exception.
4411    except:
4412        pass
4413    else:
4414        assert 0           # We shouldn't get here.
4415
4416    try:
4417        h[6] = 0           # This should raise an exception.
4418    except:
4419        pass
4420    else:
4421        assert 0           # We shouldn't get here.
4422
4423    try:
4424        h[1] = "a"           # This should raise an exception.
4425    except:
4426        pass
4427    else:
4428        assert 0           # We shouldn't get here.
4429
4430    # Assignment.
4431
4432    h1 = Shear(1)
4433
4434    h2 = h1
4435    assert h2[0] == 1 and h2[1] == 1 and h2[2] == 1 and \
4436           h2[3] == 1 and h2[4] == 1 and h2[5] == 1
4437    h1[0] = 2
4438    assert h2[0] == 2 and h2[1] == 1 and h2[2] == 1 and \
4439           h2[3] == 1 and h2[4] == 1 and h2[5] == 1
4440
4441    # Comparison operators.
4442
4443    h1 = Shear(20, 20, 20, 20, 20, 0)
4444    h2 = Shear(20, 20, 20, 20, 20, 0)
4445    h3 = Shear(20, 20, 20, 20, 21, 0)
4446
4447    assert h1 == h2
4448    assert h1 != h3
4449    assert not (h1 < h2)
4450    assert h1 < h3
4451    assert h1 <= h2
4452    assert h1 <= h3
4453    assert not (h3 <= h1)
4454    assert not (h2 > h1)
4455    assert h3 > h1
4456    assert h2 >= h1
4457    assert h3 >= h1
4458    assert not (h1 >= h3)
4459
4460    # Epsilon equality.
4461
4462    e = 0.005
4463    h1 = Shear(1)
4464    h2 = Shear(1 + e)
4465
4466    assert h1.equalWithAbsError(h2, e)
4467    assert h2.equalWithAbsError(h1, e)
4468
4469    e = 0.003
4470    h1 = Shear(10)
4471    h2 = Shear(10 + 10 * e)
4472
4473    assert h1.equalWithRelError(h2, e)
4474    assert h2.equalWithRelError(h1, e)
4475
4476    # Addition.
4477
4478    h1 = Shear(10, 20, 30, -10, -20, -30)
4479    h2 = Shear(30, 40, 50, -30, -40, -50)
4480
4481    assert h1 + h2 == Shear(40, 60, 80, -40, -60, -80)
4482    assert h2 + h1 == h1 + h2
4483    assert h1 + 1 == Shear(11, 21, 31, -9, -19, -29)
4484    assert 1 + h1 == h1 + 1
4485
4486    # (with the switch to python2, we now allow ops between vectors and tuples)
4487    assert h1 + (1, 2, 3, 4, 5, 6) == Shear(11, 22, 33, -6, -15, -24)
4488    assert (1, 2, 3, 4, 5, 6) + h1 == h1 + (1, 2, 3, 4, 5, 6)
4489
4490    # Subtraction and negation.
4491
4492    h1 = Shear(10, 20, 30, -10, -20, -30)
4493    h2 = Shear(30, 40, 50, -30, -40, -50)
4494
4495    assert h2 - h1 == Shear(20, 20, 20, -20, -20, -20)
4496    assert h1 - 1 == Shear(9, 19, 29, -11, -21, -31)
4497    assert 1 - h1 == - (h1 - 1)
4498
4499    # (with the switch to python2, we now allow ops between vectors and tuples)
4500    assert h1 - (1, 2, 3, 4, 5, 6) == Shear(9, 18, 27, -14, -25, -36)
4501    assert (1, 2, 3, 4, 5, 6) - h1 == - (h1 - (1, 2, 3, 4, 5, 6))
4502
4503    assert h1.negate() == Shear(-10, -20, -30, 10, 20, 30)
4504
4505    # Multiplication.
4506
4507    h1 = Shear(1, 2, 3, -1, -2, -3)
4508    h2 = Shear(3, 4, 5, -3, -4, -5)
4509
4510    assert h1 * h2 == Shear(3, 8, 15, 3, 8, 15)
4511    assert h2 * h1 == h1 * h2
4512    assert 2 * h1 == Shear(2, 4, 6, -2, -4, -6)
4513    assert h1 * 2 == 2 * h1
4514
4515    # (with the switch to python2, we now allow ops between vectors and tuples)
4516    assert h1 * (1, 2, 3, 4, 5, 6) == Shear(1, 4, 9, -4, -10, -18)
4517    assert (1, 2, 3, 4, 5, 6) * h1 == h1 * (1, 2, 3, 4, 5, 6)
4518
4519    # Division.
4520
4521    h1 = Shear(10, 20, 40, -10, -20, -40)
4522    h2 = Shear(2, 4, 8, -2, -4, -8)
4523
4524    assert h1 / h2 == Shear(10/2, 20/4, 40/8, -10/-2, -20/-4, -40/-8)
4525    assert h1 / 2 == Shear(10/2, 20/2, 40/2, -10/2, -20/2, -40/2)
4526    assert Shear(40) / h1 == Shear(40/10, 40/20, 40/40, 40/-10, 40/-20, 40/-40)
4527
4528    # (with the switch to python2, we now allow ops between vectors and tuples)
4529    assert h1 / (1, 2, 4, -1, -2, -4) == Shear(10, 10, 10, 10, 10, 10)
4530    assert Shear(50, 40, 80, -50, -40, -80) / h1 == Shear(5, 2, 2, 5, 2, 2)
4531
4532    print ("ok")
4533
4534    return
4535
4536def testShear6 ():
4537
4538    print ("Shear6f")
4539    testShear6x (Shear6f)
4540    print ("Shear6d")
4541    testShear6x (Shear6d)
4542
4543testList.append (('testShear6',testShear6))
4544
4545
4546# -------------------------------------------------------------------------
4547# Tests for Shear --> Shear conversions
4548
4549def testShearV3xConversions (Vec):
4550
4551    v = Vec (0, 1, 2)
4552
4553    h = Shear6f (v)
4554    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4555           h[3] == 0 and h[4] == 0 and h[5] == 0
4556
4557    h = Shear6d (v)
4558    assert h[0] == 0 and h[1] == 1 and h[2] == 2 and \
4559           h[3] == 0 and h[4] == 0 and h[5] == 0
4560
4561    print ("ok")
4562    return
4563
4564
4565def testShear6xConversions (Shear):
4566
4567    h1 = Shear(0, 1, 2, 3, 4, 5)
4568
4569    h2 = Shear6f (h1)
4570    assert h2[0] == 0 and h2[1] == 1 and h2[2] == 2 and \
4571           h2[3] == 3 and h2[4] == 4 and h2[5] == 5
4572
4573    h2 = Shear6d (h1)
4574    assert h2[0] == 0 and h2[1] == 1 and h2[2] == 2 and \
4575           h2[3] == 3 and h2[4] == 4 and h2[5] == 5
4576
4577    print ("ok")
4578    return
4579
4580
4581def testShearConversions ():
4582
4583    print ("V3f")
4584    testShearV3xConversions (V3f)
4585    print ("V3d")
4586    testShearV3xConversions (V3d)
4587
4588    print ("Shear6f")
4589    testShear6xConversions (Shear6f)
4590    print ("Shear6d")
4591    testShear6xConversions (Shear6d)
4592
4593    print ("ok")
4594    return
4595
4596
4597testList.append (('testShearConversions',testShearConversions))
4598
4599
4600# -------------------------------------------------------------------------
4601# Tests for M22x
4602
4603def testM22x (Mat, Vec):
4604
4605    # Constructors (and element access).
4606
4607    m = Mat()
4608    assert m[0][0] == 1 and m[0][1] == 0 and \
4609           m[1][0] == 0 and m[1][1] == 1
4610
4611    m = Mat(1)
4612    assert m[0][0] == 1 and m[0][1] == 1 and \
4613           m[1][0] == 1 and m[1][1] == 1
4614
4615    m = Mat((0, 1), (2, 3))
4616    assert m[0][0] == 0 and m[0][1] == 1 and \
4617           m[1][0] == 2 and m[1][1] == 3
4618
4619
4620    m = Mat(0, 1, 2, 3)
4621    assert m[0][0] == 0 and m[0][1] == 1 and \
4622           m[1][0] == 2 and m[1][1] == 3
4623
4624    # Repr.
4625
4626    m = Mat(0/9., 1/9., 2/9., 3/9.)
4627    assert m == eval(repr(m))
4628
4629    # Sequence length.
4630
4631    m = Mat()
4632    assert len(m) == 2
4633
4634    # Element setting.
4635
4636    m = Mat()
4637    m[0][0] = 10
4638    m[1][1] = 11
4639    assert m[0][0] == 10 and m[1][1] == 11
4640
4641    try:
4642        m[-4][0] = 0           # This should raise an exception.
4643    except:
4644        pass
4645    else:
4646        assert 0           # We shouldn't get here.
4647
4648    try:
4649        v[3][0] = 0           # This should raise an exception.
4650    except:
4651        pass
4652    else:
4653        assert 0           # We shouldn't get here.
4654
4655    try:
4656        m[0][-4] = 0           # This should raise an exception.
4657    except:
4658        pass
4659    else:
4660        assert 0           # We shouldn't get here.
4661
4662    try:
4663        v[0][3] = 0           # This should raise an exception.
4664    except:
4665        pass
4666    else:
4667        assert 0           # We shouldn't get here.
4668
4669    try:
4670        v[1] = (1,2,3)           # This should raise an exception.
4671    except:
4672        pass
4673    else:
4674        assert 0           # We shouldn't get here.
4675
4676    # Assignment.
4677
4678    m1 = Mat(1)
4679
4680    m2 = m1
4681    assert m2[0][0] == 1 and m2[0][1] == 1 and \
4682           m2[1][0] == 1 and m2[1][1] == 1
4683
4684    m1[0][0] = 2
4685    assert m2[0][0] == 2 and m2[0][1] == 1 and \
4686           m2[1][0] == 1 and m2[1][1] == 1
4687
4688    # Identity.
4689
4690    m = Mat(2)
4691
4692    m.makeIdentity()
4693    assert m[0][0] == 1 and m[0][1] == 0 and \
4694           m[1][0] == 0 and m[1][1] == 1
4695
4696    # Comparison operators.
4697
4698    m1 = Mat()
4699    m1[1][1] = 2
4700    m2 = Mat()
4701    m2[1][1] = 2
4702    m3 = Mat()
4703    m3[1][1] = 3
4704
4705    assert m1 == m2
4706    assert m1 != m3
4707    assert not (m1 < m2)
4708    assert m1 < m3
4709    assert m1 <= m2
4710    assert m1 <= m3
4711    assert not (m3 <= m1)
4712    assert not (m2 > m1)
4713    assert m3 > m1
4714    assert m2 >= m1
4715    assert m3 >= m1
4716    assert not (m1 >= m3)
4717
4718    # Epsilon equality.
4719
4720    e = 0.005
4721    m1 = Mat(1)
4722    m2 = Mat(1 + e)
4723
4724    assert m1.equalWithAbsError(m2, e)
4725    assert m2.equalWithAbsError(m1, e)
4726
4727    e = 0.003
4728    m1 = Mat(10)
4729    m2 = Mat(10 + 10 * e)
4730
4731    assert m1.equalWithRelError(m2, e)
4732    assert m2.equalWithRelError(m1, e)
4733
4734    # Addition.
4735
4736    m1 = Mat(1)
4737    m2 = Mat(2)
4738
4739    assert m1 + m2 == Mat(3)
4740    assert m2 + m1 == m1 + m2
4741    assert m1 + 1 == Mat(2)
4742    assert 1 + m1 == m1 + 1
4743
4744    # Subtraction and negation.
4745
4746    m1 = Mat(2)
4747    m2 = Mat(3)
4748
4749    assert m2 - m1 == Mat(1)
4750    assert m1 - 1 == Mat(1)
4751    assert 1 - m1 == - (m1 - 1)
4752    assert m1.negate() == Mat(-2)
4753
4754    # Multiplication.
4755
4756    m1 = Mat(1)
4757    # (Scales by (3, 4).)
4758    m2 = Mat()
4759    m2[0][0] = 3
4760    m2[1][1] = 4
4761    v = Vec(1, 2)
4762
4763    assert m1 * 2 == Mat(2)
4764    assert m1 * 2 == 2 * m1
4765    assert m1 * m2 == Mat((3,4),(3,4))
4766    assert v * m2 == Vec(3, 8)
4767    try:
4768        m1 * v                   # This should raise an exception.
4769    except:
4770        pass
4771    else:
4772        assert 0           # We shouldn't get here.
4773
4774    m2f = M22f()
4775    m2f[0][0] = 1
4776    m2f[1][1] = 2
4777    v = Vec(1, 2)
4778    v *= m2f
4779    assert v == Vec(1, 4)
4780
4781    m2d = M22d()
4782    m2d[0][0] = 1
4783    m2d[1][1] = 2
4784    v = Vec(1, 2)
4785    v *= m2d
4786    assert v == Vec(1, 4)
4787
4788    # (Rotates by 45 degrees.)
4789    m3 = Mat()
4790    m3[0][0] = 0
4791    m3[0][1] = 1
4792    m3[1][0] = -1
4793    m3[1][1] = 0
4794    m4 = m3 * Mat()
4795    v1 = Vec(1, 0)
4796    v2 = Vec()
4797
4798    m4.multDirMatrix(v1,v2)
4799    assert v2.equalWithAbsError((0, 1), v2.baseTypeEpsilon())
4800    v2 = m4.multDirMatrix(v1)
4801    assert v2.equalWithAbsError((0, 1), v2.baseTypeEpsilon())
4802    v1a = V2fArray(1)
4803    v1a[:] = V2f(v1)
4804    v2a = m4.multDirMatrix(v1a)
4805    assert v2a[0].equalWithAbsError((0, 1), v2a[0].baseTypeEpsilon())
4806    v1a = V2dArray(1)
4807    v1a[:] = V2d(v1)
4808    v2a = m4.multDirMatrix(v1a)
4809    assert v2a[0].equalWithAbsError((0, 1), v2a[0].baseTypeEpsilon())
4810
4811    # Division.
4812
4813    m = Mat(4)
4814
4815    assert m / 2 == Mat(2)
4816    try:
4817        4 / m                   # This should raise an exception.
4818    except:
4819        pass
4820    else:
4821        assert 0           # We shouldn't get here.
4822
4823    # Transpose.
4824
4825    m = Mat(1, 2, 3, 4)
4826
4827    assert m.transpose() == Mat(1, 3, 2, 4)
4828    m.transposed()
4829    assert m == Mat(1, 3, 2, 4)
4830
4831    # Invert.
4832
4833    m1 = Mat()
4834    m1[0][0] = 1
4835    m1[1][1] = 2
4836
4837    m1I = m1.inverse()
4838    assert m1 * m1I == Mat()
4839
4840    m2 = Mat(m1)
4841    m2.invert()
4842    assert m1 * m2 == Mat()
4843
4844    # Rotation (in radians).
4845
4846    v1 = Vec(1, 0)
4847
4848    m = Mat()
4849    m.setRotation(-pi / 2)
4850
4851    v2 = v1 * m
4852    assert v2.equalWithAbsError((0, -1), v2.baseTypeEpsilon())
4853
4854    m.rotate(-pi / 2)
4855
4856    v2 = v1 * m
4857    assert v2.equalWithAbsError((-1, 0), v2.baseTypeEpsilon())
4858
4859    # Scaling.
4860
4861    v1 = Vec(1, 2)
4862
4863    m = Mat()
4864    m.setScale(2)
4865
4866    v2 = v1 * m
4867    assert v2.equalWithAbsError((2, 4), v2.baseTypeEpsilon())
4868
4869    m.scale(3)
4870
4871    v2 = v1 * m
4872    assert v2.equalWithAbsError((6, 12), v2.baseTypeEpsilon())
4873
4874    m = Mat()
4875    m.setScale((1, 2))
4876
4877    v2 = v1 * m
4878    assert v2.equalWithAbsError((1, 4), v2.baseTypeEpsilon())
4879
4880    m.scale((2, 3))
4881
4882    v2 = v1 * m
4883    assert v2.equalWithAbsError((2, 12), v2.baseTypeEpsilon())
4884
4885    # It is not essential for correctness that the following exceptions
4886    # occur.  Instead, these tests merely document the way the Python
4887    # wrappings currently work.
4888    try:
4889        m.setScale(1, 2)        # This should raise an exception.
4890    except:
4891        pass
4892    else:
4893        assert 0                   # We shouldn't get here.
4894
4895    m = Mat()
4896    a = pi/4
4897    # (Rotation by -a around Z axis.)
4898    m[0][0] = cos(a)
4899    m[0][1] = -sin(a)
4900    m[1][0] = sin(a)
4901    m[1][1] = cos(a)
4902    v = Vec()
4903
4904    m.extractEuler(v)
4905    assert v.equalWithAbsError((-a, 0), v.baseTypeEpsilon())
4906
4907    # Determinants (by building a random singular value decomposition)
4908
4909    u = Mat()
4910    v = Mat()
4911    s = Mat()
4912
4913    u.setRotation( random.random() )
4914    v.setRotation( random.random() )
4915    s[0][0] = random.random()
4916    s[1][1] = random.random()
4917
4918    c = u * s * v.transpose()
4919    assert abs(c.determinant() - s[0][0]*s[1][1]) <= u.baseTypeEpsilon()
4920
4921
4922    print ("ok")
4923    return
4924
4925def testM22 ():
4926
4927    print ("M22f")
4928    testM22x (M22f, V2f)
4929    print ("M22d")
4930    testM22x (M22d, V2d)
4931
4932#testList.append (('testM22',testM22))
4933
4934
4935# -------------------------------------------------------------------------
4936# Tests for M33x
4937
4938def testM33x (Mat, Vec, Vec3):
4939
4940    # Constructors (and element access).
4941
4942    m = Mat()
4943    assert m[0][0] == 1 and m[0][1] == 0 and m[0][2] == 0 and \
4944           m[1][0] == 0 and m[1][1] == 1 and m[1][2] == 0 and \
4945           m[2][0] == 0 and m[2][1] == 0 and m[2][2] == 1
4946
4947    m = Mat(1)
4948    assert m[0][0] == 1 and m[0][1] == 1 and m[0][2] == 1 and \
4949           m[1][0] == 1 and m[1][1] == 1 and m[1][2] == 1 and \
4950           m[2][0] == 1 and m[2][1] == 1 and m[2][2] == 1
4951
4952    m = Mat((0, 1, 2), (3, 4, 5), (6, 7, 8))
4953    assert m[0][0] == 0 and m[0][1] == 1 and m[0][2] == 2 and \
4954           m[1][0] == 3 and m[1][1] == 4 and m[1][2] == 5 and \
4955           m[2][0] == 6 and m[2][1] == 7 and m[2][2] == 8
4956
4957
4958    m = Mat(0, 1, 2, 3, 4, 5, 6, 7, 8)
4959    assert m[0][0] == 0 and m[0][1] == 1 and m[0][2] == 2 and \
4960           m[1][0] == 3 and m[1][1] == 4 and m[1][2] == 5 and \
4961           m[2][0] == 6 and m[2][1] == 7 and m[2][2] == 8
4962
4963    # Repr.
4964
4965    m = Mat(0/9., 1/9., 2/9., 3/9., 4/9., 5/9., 6/9., 7/9., 8/9.)
4966    assert m == eval(repr(m))
4967
4968    # Sequence length.
4969
4970    m = Mat()
4971    assert len(m) == 3
4972
4973    # Element setting.
4974
4975    m = Mat()
4976    m[0][0] = 10
4977    m[1][2] = 11
4978    assert m[0][0] == 10 and m[1][2] == 11
4979
4980    try:
4981        m[-4][0] = 0           # This should raise an exception.
4982    except:
4983        pass
4984    else:
4985        assert 0           # We shouldn't get here.
4986
4987    try:
4988        v[3][0] = 0           # This should raise an exception.
4989    except:
4990        pass
4991    else:
4992        assert 0           # We shouldn't get here.
4993
4994    try:
4995        m[0][-4] = 0           # This should raise an exception.
4996    except:
4997        pass
4998    else:
4999        assert 0           # We shouldn't get here.
5000
5001    try:
5002        v[0][3] = 0           # This should raise an exception.
5003    except:
5004        pass
5005    else:
5006        assert 0           # We shouldn't get here.
5007
5008    try:
5009        v[1] = (1,2,3)           # This should raise an exception.
5010    except:
5011        pass
5012    else:
5013        assert 0           # We shouldn't get here.
5014
5015    # Assignment.
5016
5017    m1 = Mat(1)
5018
5019    m2 = m1
5020    assert m2[0][0] == 1 and m2[0][1] == 1 and m2[0][2] == 1 and \
5021           m2[1][0] == 1 and m2[1][1] == 1 and m2[1][2] == 1 and \
5022           m2[2][0] == 1 and m2[2][1] == 1 and m2[2][2] == 1
5023    m1[0][0] = 2
5024    assert m2[0][0] == 2 and m2[0][1] == 1 and m2[0][2] == 1 and \
5025           m2[1][0] == 1 and m2[1][1] == 1 and m2[1][2] == 1 and \
5026           m2[2][0] == 1 and m2[2][1] == 1 and m2[2][2] == 1
5027
5028    # Identity.
5029
5030    m = Mat(2)
5031
5032    m.makeIdentity()
5033    assert m[0][0] == 1 and m[0][1] == 0 and m[0][2] == 0 and \
5034           m[1][0] == 0 and m[1][1] == 1 and m[1][2] == 0 and \
5035           m[2][0] == 0 and m[2][1] == 0 and m[2][2] == 1
5036
5037    # Comparison operators.
5038
5039    m1 = Mat()
5040    m1[1][1] = 2
5041    m2 = Mat()
5042    m2[1][1] = 2
5043    m3 = Mat()
5044    m3[1][1] = 3
5045
5046    assert m1 == m2
5047    assert m1 != m3
5048    assert not (m1 < m2)
5049    assert m1 < m3
5050    assert m1 <= m2
5051    assert m1 <= m3
5052    assert not (m3 <= m1)
5053    assert not (m2 > m1)
5054    assert m3 > m1
5055    assert m2 >= m1
5056    assert m3 >= m1
5057    assert not (m1 >= m3)
5058
5059    # Epsilon equality.
5060
5061    e = 0.005
5062    m1 = Mat(1)
5063    m2 = Mat(1 + e)
5064
5065    assert m1.equalWithAbsError(m2, e)
5066    assert m2.equalWithAbsError(m1, e)
5067
5068    e = 0.003
5069    m1 = Mat(10)
5070    m2 = Mat(10 + 10 * e)
5071
5072    assert m1.equalWithRelError(m2, e)
5073    assert m2.equalWithRelError(m1, e)
5074
5075    # Addition.
5076
5077    m1 = Mat(1)
5078    m2 = Mat(2)
5079
5080    assert m1 + m2 == Mat(3)
5081    assert m2 + m1 == m1 + m2
5082    assert m1 + 1 == Mat(2)
5083    assert 1 + m1 == m1 + 1
5084
5085    # Subtraction and negation.
5086
5087    m1 = Mat(2)
5088    m2 = Mat(3)
5089
5090    assert m2 - m1 == Mat(1)
5091    assert m1 - 1 == Mat(1)
5092    assert 1 - m1 == - (m1 - 1)
5093    assert m1.negate() == Mat(-2)
5094
5095    # Multiplication.
5096
5097    m1 = Mat(1)
5098    # (Translates by (1,2).)
5099    m2 = Mat()
5100    m2[2][0] = 1
5101    m2[2][1] = 2
5102    # (Scales by (3, 4).)
5103    m3 = Mat()
5104    m3[0][0] = 3
5105    m3[1][1] = 4
5106    v = Vec(1, 2)
5107
5108    assert m1 * 2 == Mat(2)
5109    assert m1 * 2 == 2 * m1
5110    assert m2 * m3 == Mat((3,0,0),(0,4,0),(3,8,1))
5111    assert m3 * m2 == Mat((3,0,0),(0,4,0),(1,2,1))
5112    assert v * m2 == Vec(2, 4)
5113    try:
5114        m1 * v                   # This should raise an exception.
5115    except:
5116        pass
5117    else:
5118        assert 0           # We shouldn't get here.
5119
5120    m2f = M33f()
5121    m2f[2][0] = 1
5122    m2f[2][1] = 2
5123    v = Vec(1, 2)
5124    v *= m2f
5125    assert v == Vec(2, 4)
5126
5127    m2d = M33d()
5128    m2d[2][0] = 1
5129    m2d[2][1] = 2
5130    v = Vec(1, 2)
5131    v *= m2d
5132    assert v == Vec(2, 4)
5133
5134    # (Rotates by 45 degrees, then translates by (1,2).)
5135    m3 = Mat()
5136    m3[0][0] = 0
5137    m3[0][1] = 1
5138    m3[1][0] = -1
5139    m3[1][1] = 0
5140    m4 = m3 * m2
5141    v1 = Vec(1, 0)
5142    v2 = Vec()
5143
5144    m4.multVecMatrix(v1,v2)
5145    assert v2.equalWithAbsError((1, 3), v2.baseTypeEpsilon())
5146    v2 = m4.multVecMatrix(v1)
5147    assert v2.equalWithAbsError((1, 3), v2.baseTypeEpsilon())
5148    v1a = V2fArray(1)
5149    v1a[:] = V2f(v1)
5150    v2a = m4.multVecMatrix(v1a)
5151    assert v2a[0].equalWithAbsError((1, 3), v2a[0].baseTypeEpsilon())
5152    v1a = V2dArray(1)
5153    v1a[:] = V2d(v1)
5154    v2a = m4.multVecMatrix(v1a)
5155    assert v2a[0].equalWithAbsError((1, 3), v2a[0].baseTypeEpsilon())
5156
5157
5158    m4.multDirMatrix(v1,v2)
5159    assert v2.equalWithAbsError((0, 1), v2.baseTypeEpsilon())
5160    v2 = m4.multDirMatrix(v1)
5161    assert v2.equalWithAbsError((0, 1), v2.baseTypeEpsilon())
5162    v1a = V2fArray(1)
5163    v1a[:] = V2f(v1)
5164    v2a = m4.multDirMatrix(v1a)
5165    assert v2a[0].equalWithAbsError((0, 1), v2a[0].baseTypeEpsilon())
5166    v1a = V2dArray(1)
5167    v1a[:] = V2d(v1)
5168    v2a = m4.multDirMatrix(v1a)
5169    assert v2a[0].equalWithAbsError((0, 1), v2a[0].baseTypeEpsilon())
5170
5171    # Division.
5172
5173    m = Mat(4)
5174
5175    assert m / 2 == Mat(2)
5176    try:
5177        4 / m                   # This should raise an exception.
5178    except:
5179        pass
5180    else:
5181        assert 0           # We shouldn't get here.
5182
5183    # Transpose.
5184
5185    m = Mat(1, 2, 3, 4, 5, 6, 7, 8, 9)
5186
5187    assert m.transpose() == Mat(1, 4, 7, 2, 5, 8, 3, 6, 9)
5188    m.transposed()
5189    assert m == Mat(1, 4, 7, 2, 5, 8, 3, 6, 9)
5190
5191    # Invert.
5192
5193    # (Translates by (1,2).)
5194    m1 = Mat()
5195    m1[2][0] = 1
5196    m1[2][1] = 2
5197
5198    m1I = m1.inverse()
5199    assert m1 * m1I == Mat()
5200    m1I = m1.gjInverse()
5201    assert m1 * m1I == Mat()
5202
5203    m2 = Mat(m1)
5204    m2.invert()
5205    assert m1 * m2 == Mat()
5206    m2 = Mat(m1)
5207    m2.gjInvert()
5208    assert m1 * m2 == Mat()
5209
5210    # Rotation (in radians).
5211
5212    v1 = Vec(1, 0)
5213
5214    m = Mat()
5215    m.setRotation(-pi / 2)
5216
5217    v2 = v1 * m
5218    assert v2.equalWithAbsError((0, -1), v2.baseTypeEpsilon())
5219
5220    m.rotate(-pi / 2)
5221
5222    v2 = v1 * m
5223    assert v2.equalWithAbsError((-1, 0), v2.baseTypeEpsilon())
5224
5225    # Scaling.
5226
5227    v1 = Vec(1, 2)
5228
5229    m = Mat()
5230    m.setScale(2)
5231
5232    v2 = v1 * m
5233    assert v2.equalWithAbsError((2, 4), v2.baseTypeEpsilon())
5234
5235    m.scale(3)
5236
5237    v2 = v1 * m
5238    assert v2.equalWithAbsError((6, 12), v2.baseTypeEpsilon())
5239
5240    m = Mat()
5241    m.setScale((1, 2))
5242
5243    v2 = v1 * m
5244    assert v2.equalWithAbsError((1, 4), v2.baseTypeEpsilon())
5245
5246    m.scale((2, 3))
5247
5248    v2 = v1 * m
5249    assert v2.equalWithAbsError((2, 12), v2.baseTypeEpsilon())
5250
5251    # It is not essential for correctness that the following exceptions
5252    # occur.  Instead, these tests merely document the way the Python
5253    # wrappings currently work.
5254    try:
5255        m.setScale(1, 2)        # This should raise an exception.
5256    except:
5257        pass
5258    else:
5259        assert 0                   # We shouldn't get here.
5260
5261    # Shearing.
5262
5263    v1 = Vec(1, 2)
5264
5265    m = Mat()
5266    m.setShear(2)
5267
5268    v2 = v1 * m
5269    assert v2.equalWithAbsError((5, 2), v2.baseTypeEpsilon())
5270
5271    m.shear(3)
5272
5273    v2 = v1 * m
5274    assert v2.equalWithAbsError((11, 2), v2.baseTypeEpsilon())
5275
5276    m = Mat()
5277    m.setShear((2, 1))
5278
5279    v2 = v1 * m
5280    assert v2.equalWithAbsError((5, 3), v2.baseTypeEpsilon())
5281
5282    m.shear((3, 2))
5283
5284    v2 = v1 * m
5285    assert v2.equalWithAbsError((15, 11), v2.baseTypeEpsilon())
5286
5287    m = Mat()
5288    m.setShear((1, 2))
5289
5290    v2 = v1 * m
5291    assert v2.equalWithAbsError((3, 4), v2.baseTypeEpsilon())
5292
5293    m.shear((2, 3))
5294
5295    v2 = v1 * m
5296    assert v2.equalWithAbsError((10, 15), v2.baseTypeEpsilon())
5297
5298    # It is not essential for correctness that the following exceptions
5299    # occur.  Instead, these tests merely document the way the Python
5300    # wrappings currently work.
5301    try:
5302        m.setShear(1, 2)        # This should raise an exception.
5303    except:
5304        pass
5305    else:
5306        assert 0                   # We shouldn't get here.
5307
5308    # Translation.
5309
5310    v1 = Vec(1, 0)
5311
5312    m = Mat()
5313    m.setTranslation((3, 2))
5314
5315    v2 = v1 * m
5316    assert v2.equalWithAbsError((4, 2), v2.baseTypeEpsilon())
5317
5318    m.translate((1, 2))
5319
5320    v2 = v1 * m
5321    assert v2.equalWithAbsError((5, 4), v2.baseTypeEpsilon())
5322
5323    v3 = m.translation()
5324    assert v3.equalWithAbsError((4, 4), v2.baseTypeEpsilon())
5325
5326    # Extract scaling.
5327
5328    m = Mat()
5329    s = Vec(4, 5)
5330    m.translate((1, 2))
5331    m.shear(7)
5332    m.scale(s)
5333
5334    sM = Vec()
5335    m.extractScaling(sM)
5336    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
5337
5338    # Sans scaling / Remove scaling.
5339
5340    m1 = Mat()
5341    m1.translate((1, 2))
5342    m1.shear(7)
5343    m1.scale((4, 5))
5344
5345    m2 = m1.sansScaling()
5346    assert m2[0][0] == 1 and m2[1][1] == 1 and \
5347           abs (m2[1][0] - 7) <= 4 * m2.baseTypeEpsilon () and \
5348           abs (m2[0][1])     <= 4 * m2.baseTypeEpsilon () and \
5349           m2[2][0] == 1 and m2[2][1] == 2
5350
5351    m1 = Mat()
5352    m1.translate((1, 2))
5353    m1.shear(7)
5354    m1.scale((0, 0))
5355
5356    try:
5357        m2 = m1.sansScaling()  # This should raise an exception.
5358    except:
5359        pass
5360    else:
5361        assert 0               # We shouldn't get here.
5362
5363    m1 = Mat()
5364    m1.translate((1, 2))
5365    m1.shear(7)
5366    m2 = Mat(m1)
5367    m1.scale((4, 5))
5368
5369    r = m1.removeScaling()
5370    assert r == 1 and m1.equalWithAbsError(m2, 4 * m1.baseTypeEpsilon())
5371
5372    m = Mat()
5373    m.translate((1, 2))
5374    m.shear(7)
5375    m.scale((0, 0))
5376
5377    try:
5378        r = m.removeScaling()  # This should raise an exception.
5379    except:
5380        pass
5381    else:
5382        assert 0               # We shouldn't get here.
5383
5384    m = Mat()
5385    m.translate((1, 2))
5386    m.shear(7)
5387    m.scale((0, 0))
5388
5389    r = m.removeScaling(0)
5390    assert r == 0
5391
5392    # Sans scaling and shear / Remove scaling and shear.
5393
5394    m1 = Mat()
5395    m1.translate((1, 2))
5396    m1.shear(7)
5397    m1.scale((4, 5))
5398
5399    m2 = m1.sansScalingAndShear()
5400    assert m2[0][0] == 1 and m2[1][1] == 1 and \
5401           m2[1][0] == 0 and m2[0][1] == 0 and \
5402           m2[2][0] == 1 and m2[2][1] == 2
5403
5404    m1 = Mat()
5405    m1.translate((1, 2))
5406    m1.shear(7)
5407    m1.scale((0, 0))
5408
5409    try:
5410        m2 = m1.sansScalingAndShear()  # This should raise an exception.
5411    except:
5412        pass
5413    else:
5414        assert 0               # We shouldn't get here.
5415
5416    m1 = Mat()
5417    m1.translate((1, 2))
5418    m2 = Mat(m1)
5419    m1.shear(7)
5420    m1.scale((4, 5))
5421
5422    r = m1.removeScalingAndShear()
5423    assert r == 1 and m1.equalWithAbsError(m2, m1.baseTypeEpsilon())
5424
5425    m = Mat()
5426    m.translate((1, 2))
5427    m.scale((0, 0))
5428
5429    try:
5430        r = m.removeScalingAndShear()  # This should raise an exception.
5431    except:
5432        pass
5433    else:
5434        assert 0               # We shouldn't get here.
5435
5436    m = Mat()
5437    m.translate((1, 2))
5438    m.shear(7)
5439    m.scale((0, 0))
5440
5441    r = m.removeScalingAndShear(0)
5442    assert r == 0
5443
5444    # Extract and remove scaling and shear.
5445
5446    m = Mat()
5447    s = Vec(4, 5)
5448    h = Vec(7, 0)
5449    m.translate((1, 2))
5450    m2 = Mat(m)
5451    m.shear(h)
5452    m.scale(s)
5453
5454    sM = Vec()
5455    hM = Vec()
5456    m.extractScalingAndShear(sM, hM)
5457    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
5458    assert hM.equalWithAbsError(h, 4 * h.baseTypeEpsilon())
5459
5460    sM = Vec()
5461    hM = Vec()
5462    m.extractAndRemoveScalingAndShear(sM, hM)
5463    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
5464    assert hM.equalWithAbsError(h, 4 * h.baseTypeEpsilon())
5465    assert m2.equalWithAbsError(m, m.baseTypeEpsilon())
5466
5467    # Extract Euler.
5468
5469    m = Mat()
5470    a = pi/4
5471    # (Rotation by -a around Z axis.)
5472    m[0][0] = cos(a)
5473    m[0][1] = -sin(a)
5474    m[1][0] = sin(a)
5475    m[1][1] = cos(a)
5476    v = Vec()
5477
5478    m.extractEuler(v)
5479    assert v.equalWithAbsError((-a, 0), v.baseTypeEpsilon())
5480
5481    # Extract scale, shear, rotation, translation.
5482
5483    s = Vec(1, 2)
5484    h = Vec(0.5, 0)
5485    a = pi/4
5486    t = Vec(4, 5)
5487
5488    mS = Mat()
5489    mS.scale(s)
5490    mH = Mat()
5491    # (Shear by XY, XZ, YZ shear factors.)
5492    mH.shear(h)
5493    mR = Mat()
5494    # (Rotation by -a around Z axis.)
5495    mR[0][0] = cos(a)
5496    mR[0][1] = -sin(a)
5497    mR[1][0] = sin(a)
5498    mR[1][1] = cos(a)
5499    mT = Mat()
5500    mT.translate(t)
5501    m = mS * mH * mR * mT
5502
5503    sInq = Vec()
5504    hInq = Vec()
5505    rInq = Vec()
5506    tInq = Vec()
5507
5508    b = m.extractSHRT(sInq, hInq, rInq, tInq)
5509
5510    assert sInq.equalWithAbsError(s, 2 * sInq.baseTypeEpsilon())
5511    assert hInq.equalWithAbsError(h, hInq.baseTypeEpsilon())
5512    assert rInq.equalWithAbsError((-a, 0), 2 * rInq.baseTypeEpsilon())
5513    assert tInq.equalWithAbsError(t, tInq.baseTypeEpsilon())
5514
5515    # Matrix minors
5516
5517    a = Mat(1,2,3,4,5,6,7,8,9)
5518    assert a.minorOf(0,0) == a.fastMinor(1,2,1,2)
5519    assert a.minorOf(0,1) == a.fastMinor(1,2,0,2)
5520    assert a.minorOf(0,2) == a.fastMinor(1,2,0,1)
5521    assert a.minorOf(1,0) == a.fastMinor(0,2,1,2)
5522    assert a.minorOf(1,1) == a.fastMinor(0,2,0,2)
5523    assert a.minorOf(1,2) == a.fastMinor(0,2,0,1)
5524    assert a.minorOf(2,0) == a.fastMinor(0,1,1,2)
5525    assert a.minorOf(2,1) == a.fastMinor(0,1,0,2)
5526    assert a.minorOf(2,2) == a.fastMinor(0,1,0,1)
5527
5528    # Determinants (by building a random singular value decomposition)
5529
5530    u = Mat()
5531    v = Mat()
5532    s = Mat()
5533
5534    u.setRotation( random.random() )
5535    v.setRotation( random.random() )
5536    s[0][0] = random.random()
5537    s[1][1] = random.random()
5538    s[2][2] = random.random()
5539
5540    c = u * s * v.transpose()
5541    assert abs(c.determinant() - s[0][0]*s[1][1]*s[2][2]) <= u.baseTypeEpsilon()
5542
5543    # Outer product of two 3D vectors
5544
5545    a = Vec3(1,2,3)
5546    b = Vec3(4,5,6)
5547    p = Mat()
5548
5549    p.outerProduct(a,b)
5550    for i in range(3):
5551        for j in range(3):
5552            assert p[i][j] == a[i]*b[j]
5553
5554    print ("ok")
5555    return
5556
5557def testM33 ():
5558
5559    print ("M33f")
5560    testM33x (M33f, V2f, V3f)
5561    print ("M33d")
5562    testM33x (M33d, V2d, V3d)
5563
5564testList.append (('testM33',testM33))
5565
5566
5567# -------------------------------------------------------------------------
5568# Tests for M44x
5569
5570def testM44x (Mat, Vec):
5571
5572    # Constructors (and element access).
5573
5574    m = Mat()
5575    assert \
5576      m[0][0] == 1 and m[0][1] == 0 and m[0][2] == 0 and m[0][3] == 0 and \
5577      m[1][0] == 0 and m[1][1] == 1 and m[1][2] == 0 and m[1][3] == 0 and \
5578      m[2][0] == 0 and m[2][1] == 0 and m[2][2] == 1 and m[2][3] == 0 and \
5579      m[3][0] == 0 and m[3][1] == 0 and m[3][2] == 0 and m[3][3] == 1
5580
5581    m = Mat(1)
5582    assert \
5583      m[0][0] == 1 and m[0][1] == 1 and m[0][2] == 1 and m[0][3] == 1 and \
5584      m[1][0] == 1 and m[1][1] == 1 and m[1][2] == 1 and m[1][3] == 1 and \
5585      m[2][0] == 1 and m[2][1] == 1 and m[2][2] == 1 and m[2][3] == 1 and \
5586      m[3][0] == 1 and m[3][1] == 1 and m[3][2] == 1 and m[3][3] == 1
5587
5588    m = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
5589    assert \
5590      m[0][0] == 0 and m[0][1] == 1 and m[0][2] == 2 and m[0][3] == 3 and \
5591      m[1][0] == 4 and m[1][1] == 5 and m[1][2] == 6 and m[1][3] == 7 and \
5592      m[2][0] == 8 and m[2][1] == 9 and m[2][2] ==10 and m[2][3] ==11 and \
5593      m[3][0] ==12 and m[3][1] ==13 and m[3][2] ==14 and m[3][3] ==15
5594
5595    # Repr.
5596
5597    m = Mat((0/9.,1/9.,2/9.,3/9.),
5598            (4/9.,5/9.,6/9.,7/9.),
5599            (8/9.,9/9.,10/9.,11/9.),
5600            (12/9.,13/9.,14/9.,15/9.))
5601    assert m == eval(repr(m))
5602
5603    # Sequence length.
5604
5605    m = Mat()
5606    assert len(m) == 4
5607
5608    # Element setting.
5609
5610    m = Mat()
5611    m[0][0] = 10
5612    m[1][2] = 11
5613    assert m[0][0] == 10 and m[1][2] == 11
5614
5615    try:
5616        m[-5][0] = 0           # This should raise an exception.
5617    except:
5618        pass
5619    else:
5620        assert 0           # We shouldn't get here.
5621
5622    try:
5623        m[4][0] = 0           # This should raise an exception.
5624    except:
5625        pass
5626    else:
5627        assert 0           # We shouldn't get here.
5628
5629    try:
5630        m[0][-5] = 0           # This should raise an exception.
5631    except:
5632        pass
5633    else:
5634        assert 0           # We shouldn't get here.
5635
5636    try:
5637        m[0][4] = 0           # This should raise an exception.
5638    except:
5639        pass
5640    else:
5641        assert 0           # We shouldn't get here.
5642
5643    try:
5644        m[1] = (1,2,3,4)   # This should raise an exception.
5645    except:
5646        pass
5647    else:
5648        assert 0           # We shouldn't get here.
5649
5650    # Assignment.
5651
5652    m1 = Mat(1)
5653
5654    m2 = m1
5655    assert \
5656      m2[0][0] ==1 and m2[0][1] ==1 and m2[0][2] ==1 and m2[0][3] ==1 and \
5657      m2[1][0] ==1 and m2[1][1] ==1 and m2[1][2] ==1 and m2[1][3] ==1 and \
5658      m2[2][0] ==1 and m2[2][1] ==1 and m2[2][2] ==1 and m2[2][3] ==1 and \
5659      m2[3][0] ==1 and m2[3][1] ==1 and m2[3][2] ==1 and m2[3][3] ==1
5660
5661    m1[0][0] = 2
5662    assert \
5663      m2[0][0] ==2 and m2[0][1] ==1 and m2[0][2] ==1 and m2[0][3] ==1 and \
5664      m2[1][0] ==1 and m2[1][1] ==1 and m2[1][2] ==1 and m2[1][3] ==1 and \
5665      m2[2][0] ==1 and m2[2][1] ==1 and m2[2][2] ==1 and m2[2][3] ==1 and \
5666      m2[3][0] ==1 and m2[3][1] ==1 and m2[3][2] ==1 and m2[3][3] ==1
5667
5668    # Identity.
5669
5670    m = Mat(2)
5671
5672    m.makeIdentity()
5673    assert \
5674      m[0][0] == 1 and m[0][1] == 0 and m[0][2] == 0 and m[0][3] == 0 and \
5675      m[1][0] == 0 and m[1][1] == 1 and m[1][2] == 0 and m[1][3] == 0 and \
5676      m[2][0] == 0 and m[2][1] == 0 and m[2][2] == 1 and m[2][3] == 0 and \
5677      m[3][0] == 0 and m[3][1] == 0 and m[3][2] == 0 and m[3][3] == 1
5678
5679    # Comparison operators.
5680
5681    m1 = Mat()
5682    m1[1][1] = 2
5683    m2 = Mat()
5684    m2[1][1] = 2
5685    m3 = Mat()
5686    m3[1][1] = 3
5687
5688    assert m1 == m2
5689    assert m1 != m3
5690    assert not (m1 < m2)
5691    assert m1 < m3
5692    assert m1 <= m2
5693    assert m1 <= m3
5694    assert not (m3 <= m1)
5695    assert not (m2 > m1)
5696    assert m3 > m1
5697    assert m2 >= m1
5698    assert m3 >= m1
5699    assert not (m1 >= m3)
5700
5701    # Epsilon equality.
5702
5703    e = 0.005
5704    m1 = Mat(1)
5705    m2 = Mat(1 + e)
5706
5707    assert m1.equalWithAbsError(m2, e)
5708    assert m2.equalWithAbsError(m1, e)
5709
5710    e = 0.003
5711    m1 = Mat(10)
5712    m2 = Mat(10 + 10 * e)
5713
5714    assert m1.equalWithRelError(m2, e)
5715    assert m2.equalWithRelError(m1, e)
5716
5717    # Addition.
5718
5719    m1 = Mat(1)
5720    m2 = Mat(2)
5721
5722    assert m1 + m2 == Mat(3)
5723    assert m2 + m1 == m1 + m2
5724    assert m1 + 1 == Mat(2)
5725    assert 1 + m1 == m1 + 1
5726
5727    # Subtraction and negation.
5728
5729    m1 = Mat(2)
5730    m2 = Mat(3)
5731
5732    assert m2 - m1 == Mat(1)
5733    assert m1 - 1 == Mat(1)
5734    assert 1 - m1 == - (m1 - 1)
5735    assert m1.negate() == Mat(-2)
5736
5737    # Multiplication.
5738
5739    m1 = Mat(1)
5740    # (Translates by (1, 2, 0).)
5741    m2 = Mat()
5742    m2[3][0] = 1
5743    m2[3][1] = 2
5744    # (Scales by (3, 4, 1).)
5745    m3 = Mat()
5746    m3[0][0] = 3
5747    m3[1][1] = 4
5748    v = Vec(1, 2, 0)
5749
5750    assert m1 * 2 == Mat(2)
5751    assert m1 * 2 == 2 * m1
5752    assert m2 * m3 == Mat((3,0,0,0),(0,4,0,0),(0,0,1,0),(3,8,0,1))
5753    assert m3 * m2 == Mat((3,0,0,0),(0,4,0,0),(0,0,1,0),(1,2,0,1))
5754    assert v * m2 == Vec(2, 4, 0)
5755    try:
5756        m1 * v                   # This should raise an exception.
5757    except:
5758        pass
5759    else:
5760        assert 0           # We shouldn't get here.
5761
5762    m2f = M44f()
5763    m2f[3][0] = 1
5764    m2f[3][1] = 2
5765    v = Vec(1, 2, 0)
5766    v *= m2f
5767    assert v == Vec(2, 4, 0)
5768
5769    m2d = M44d()
5770    m2d[3][0] = 1
5771    m2d[3][1] = 2
5772    v = Vec(1, 2, 0)
5773    v *= m2d
5774    assert v == Vec(2, 4, 0)
5775
5776    # (Rotates by 45 degrees around Z, then translates by (1, 2, 0).)
5777    m3 = Mat()
5778    m3[0][0] = 0
5779    m3[0][1] = 1
5780    m3[1][0] = -1
5781    m3[1][1] = 0
5782    m4 = m3 * m2
5783    v1 = Vec(1, 0, 0)
5784    v2 = Vec()
5785
5786    m4.multVecMatrix(v1,v2)
5787    assert v2.equalWithAbsError((1, 3, 0), v2.baseTypeEpsilon())
5788    v2 = m4.multVecMatrix(v1)
5789    assert v2.equalWithAbsError((1, 3, 0), v2.baseTypeEpsilon())
5790    v1a = V3fArray(1)
5791    v1a[:] = V3f(v1)
5792    v2a = m4.multVecMatrix(v1a)
5793    assert v2a[0].equalWithAbsError((1, 3, 0), v2a[0].baseTypeEpsilon())
5794    v1a = V3dArray(1)
5795    v1a[:] = V3d(v1)
5796    v2a = m4.multVecMatrix(v1a)
5797    assert v2a[0].equalWithAbsError((1, 3, 0), v2a[0].baseTypeEpsilon())
5798
5799    m4.multDirMatrix(v1,v2)
5800    assert v2.equalWithAbsError((0, 1, 0), v2.baseTypeEpsilon())
5801    v2 = m4.multDirMatrix(v1)
5802    assert v2.equalWithAbsError((0, 1, 0), v2.baseTypeEpsilon())
5803    v1a = V3fArray(1)
5804    v1a[:] = V3f(v1)
5805    v2a = m4.multDirMatrix(v1a)
5806    assert v2a[0].equalWithAbsError((0, 1, 0), v2a[0].baseTypeEpsilon())
5807    v1a = V3dArray(1)
5808    v1a[:] = V3d(v1)
5809    v2a = m4.multDirMatrix(v1a)
5810    assert v2a[0].equalWithAbsError((0, 1, 0), v2a[0].baseTypeEpsilon())
5811
5812    # Division.
5813
5814    m = Mat(4)
5815
5816    assert m / 2 == Mat(2)
5817    try:
5818        4 / m                   # This should raise an exception.
5819    except:
5820        pass
5821    else:
5822        assert 0           # We shouldn't get here.
5823
5824    # Transpose.
5825
5826    m = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
5827
5828    assert m.transpose() == Mat((0,4,8,12), (1,5,9,13), (2,6,10,14), (3,7,11,15))
5829    m.transposed()
5830    assert m == Mat((0,4,8,12), (1,5,9,13), (2,6,10,14), (3,7,11,15))
5831
5832    # Invert.
5833
5834    # (Translates by (1,2).)
5835    m1 = Mat()
5836    m1[3][0] = 1
5837    m1[3][1] = 2
5838
5839    m1I = m1.inverse()
5840    assert m1 * m1I == Mat()
5841    m1I = m1.gjInverse()
5842    assert m1 * m1I == Mat()
5843
5844    m2 = Mat(m1)
5845    m2.invert()
5846    assert m1 * m2 == Mat()
5847    m2 = Mat(m1)
5848    m2.gjInvert()
5849    assert m1 * m2 == Mat()
5850
5851    # Scaling.
5852
5853    v1 = Vec(1, 2, 0)
5854
5855    m = Mat()
5856    m.setScale(2)
5857
5858    v2 = v1 * m
5859    assert v2.equalWithAbsError((2, 4, 0), v2.baseTypeEpsilon())
5860
5861    m.scale(3)
5862
5863    v2 = v1 * m
5864    assert v2.equalWithAbsError((6, 12, 0), v2.baseTypeEpsilon())
5865
5866    m = Mat()
5867    m.setScale((1, 2, 1))
5868
5869    v2 = v1 * m
5870    assert v2.equalWithAbsError((1, 4, 0), v2.baseTypeEpsilon())
5871
5872    m.scale((2, 3, 1))
5873
5874    v2 = v1 * m
5875    assert v2.equalWithAbsError((2, 12, 0), v2.baseTypeEpsilon())
5876
5877    # It is not essential for correctness that the following exceptions
5878    # occur.  Instead, these tests merely document the way the Python
5879    # wrappings currently work.
5880    try:
5881        m.setScale(1, 2)        # This should raise an exception.
5882    except:
5883        pass
5884    else:
5885        assert 0                   # We shouldn't get here.
5886
5887    # Shearing.
5888
5889    v1 = Vec((1, 2, 3))
5890
5891    m = Mat()
5892    m.setShear((2, 3, 4))
5893
5894    v2 = v1 * m
5895    assert v2.equalWithAbsError((14, 14, 3), v2.baseTypeEpsilon())
5896
5897    m.shear((1, 2, 3))
5898
5899    v2 = v1 * m
5900    assert v2.equalWithAbsError((40, 23, 3), v2.baseTypeEpsilon())
5901
5902    m = Mat()
5903    m.setShear((4, 3, 2, -4, -3, -2))
5904
5905    v2 = v1 * m
5906    assert v2.equalWithAbsError((18, 4, -4), v2.baseTypeEpsilon())
5907
5908    m.shear((3, 2, 1, -3, -2, -1))
5909
5910    v2 = v1 * m
5911    assert v2.equalWithAbsError((18, -52, -44), v2.baseTypeEpsilon())
5912
5913    # It is not essential for correctness that the following exceptions
5914    # occur.  Instead, these tests merely document the way the Python
5915    # wrappings currently work.
5916    try:
5917        m.setShear(1, 2, 3)        # This should raise an exception.
5918    except:
5919        pass
5920    else:
5921        assert 0                   # We shouldn't get here.
5922
5923    # It is not essential for correctness that the following exceptions
5924    # occur.  Instead, these tests merely document the way the Python
5925    # wrappings currently work.
5926    try:
5927        m.shear(1, 2, 3, 4, 5, 6)        # This should raise an exception.
5928    except:
5929        pass
5930    else:
5931        assert 0                   # We shouldn't get here.
5932
5933    # Translation.
5934
5935    v1 = Vec(1, 0, 0)
5936
5937    m = Mat()
5938    m.setTranslation((3, 2, 0))
5939
5940    v2 = v1 * m
5941    assert v2.equalWithAbsError((4, 2, 0), v2.baseTypeEpsilon())
5942
5943    m.translate((1, 2, 0))
5944
5945    v2 = v1 * m
5946    assert v2.equalWithAbsError((5, 4, 0), v2.baseTypeEpsilon())
5947
5948    v3 = m.translation()
5949    assert v3.equalWithAbsError((4, 4, 0), v3.baseTypeEpsilon())
5950
5951    # Extract scaling.
5952
5953    m = Mat()
5954    s = Vec(4, 5, 6)
5955    m.translate((1, 2, 3))
5956    m.shear((7, 8, 9))
5957    m.scale(s)
5958
5959    sM = Vec()
5960    m.extractScaling(sM)
5961    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
5962
5963    # Sans scaling / Remove scaling.
5964
5965    m1 = Mat()
5966    m1.translate((1, 2, 3))
5967    m1.shear((7, 8, 9))
5968    m1.scale((4, 5, 6))
5969
5970    m2 = m1.sansScaling()
5971    assert m2[0][0] == 1 and m2[1][1] == 1 and m2[2][2] == 1 and \
5972           m2[1][0] == 7 and m2[2][0] == 8 and m2[2][1] == 9 and \
5973           m2[0][1] == 0 and m2[0][2] == 0 and m2[1][2] == 0 and \
5974           m2[3][0] == 1 and m2[3][1] == 2 and m2[3][2] == 3
5975
5976    m1 = Mat()
5977    m1.translate((1, 2, 3))
5978    m1.shear((7, 8, 9))
5979    m1.scale((0, 0, 0))
5980
5981    try:
5982        m2 = m1.sansScaling()  # This should raise an exception.
5983    except:
5984        pass
5985    else:
5986        assert 0               # We shouldn't get here.
5987
5988    m1 = Mat()
5989    m1.translate((1, 2, 3))
5990    m1.shear((7, 8, 9))
5991    m2 = Mat(m1)
5992    m1.scale((4, 5, 6))
5993
5994    r = m1.removeScaling()
5995    assert r == 1 and m1.equalWithAbsError(m2, m1.baseTypeEpsilon())
5996
5997    m = Mat()
5998    m.translate((1, 2, 3))
5999    m.shear((7, 8, 9))
6000    m.scale((0, 0, 0))
6001
6002    try:
6003        r = m.removeScaling()  # This should raise an exception.
6004    except:
6005        pass
6006    else:
6007        assert 0               # We shouldn't get here.
6008
6009    m = Mat()
6010    m.translate((1, 2, 3))
6011    m.shear((7, 8, 9))
6012    m.scale((0, 0, 0))
6013
6014    r = m.removeScaling(0)
6015    assert r == 0
6016
6017    # Sans scaling and shear / Remove scaling and shear.
6018
6019    m1 = Mat()
6020    m1.translate((1, 2, 3))
6021    m1.shear((7, 8, 9))
6022    m1.scale((4, 5, 6))
6023
6024    m2 = m1.sansScalingAndShear()
6025    assert m2[0][0] == 1 and m2[1][1] == 1 and m2[2][2] == 1 and \
6026           m2[1][0] == 0 and m2[2][0] == 0 and m2[2][1] == 0 and \
6027           m2[0][1] == 0 and m2[0][2] == 0 and m2[1][2] == 0 and \
6028           m2[3][0] == 1 and m2[3][1] == 2 and m2[3][2] == 3
6029
6030    m1 = Mat()
6031    m1.translate((1, 2, 3))
6032    m1.shear((7, 8, 9))
6033    m1.scale((0, 0, 0))
6034
6035    try:
6036        m2 = m1.sansScalingAndShear()  # This should raise an exception.
6037    except:
6038        pass
6039    else:
6040        assert 0               # We shouldn't get here.
6041
6042    m1 = Mat()
6043    m1.translate((1, 2, 3))
6044    m2 = Mat(m1)
6045    m1.shear((7, 8, 9))
6046    m1.scale((4, 5, 6))
6047
6048    r = m1.removeScalingAndShear()
6049    assert r == 1 and m1.equalWithAbsError(m2, m1.baseTypeEpsilon())
6050
6051    m = Mat()
6052    m.translate((1, 2, 3))
6053    m.scale((0, 0, 0))
6054
6055    try:
6056        r = m.removeScalingAndShear()  # This should raise an exception.
6057    except:
6058        pass
6059    else:
6060        assert 0               # We shouldn't get here.
6061
6062    m = Mat()
6063    m.translate((1, 2, 3))
6064    m.shear((7, 8, 9))
6065    m.scale((0, 0, 0))
6066
6067    r = m.removeScalingAndShear(0)
6068    assert r == 0
6069
6070    # Extract and remove scaling and shear.
6071
6072    m = Mat()
6073    s = Vec(4, 5, 6)
6074    h = Vec(7, 8, 9)
6075    m.translate((1, 2, 3))
6076    m2 = Mat(m)
6077    m.shear(h)
6078    m.scale(s)
6079
6080    sM = Vec()
6081    hM = Vec()
6082    m.extractScalingAndShear(sM, hM)
6083    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
6084    assert hM.equalWithAbsError(h, h.baseTypeEpsilon())
6085
6086    sM = Vec()
6087    hM = Vec()
6088    m.extractAndRemoveScalingAndShear(sM, hM)
6089    assert sM.equalWithAbsError(s, s.baseTypeEpsilon())
6090    assert hM.equalWithAbsError(h, h.baseTypeEpsilon())
6091    assert m2.equalWithAbsError(m, m.baseTypeEpsilon())
6092
6093    # Extract Euler.
6094
6095    m = Mat()
6096    a = pi/4
6097    # (Rotation by -a around Z axis.)
6098    m[0][0] = cos(a)
6099    m[0][1] = -sin(a)
6100    m[1][0] = sin(a)
6101    m[1][1] = cos(a)
6102    v = Vec()
6103
6104    m.extractEulerZYX(v)
6105    assert v.equalWithAbsError((-a, 0, 0), v.baseTypeEpsilon())
6106
6107    m.extractEulerXYZ(v)
6108    assert v.equalWithAbsError((0, 0, -a), v.baseTypeEpsilon())
6109
6110    # Extract scale, shear, rotation, translation.
6111
6112    s = Vec(1, 2, 3)
6113    h = Vec(0.5, 1, 0.75)
6114    a = pi/4
6115    t = Vec(4, 5, 6)
6116
6117    mS = Mat()
6118    mS.scale(s)
6119    mH = Mat()
6120    # (Shear by XY, XZ, YZ shear factors.)
6121    mH.shear(h)
6122    mR = Mat()
6123    # (Rotation by -a around Z axis.)
6124    mR[0][0] = cos(a)
6125    mR[0][1] = -sin(a)
6126    mR[1][0] = sin(a)
6127    mR[1][1] = cos(a)
6128    mT = Mat()
6129    mT.translate(t)
6130    m = mS * mH * mR * mT
6131
6132    sInq = Vec()
6133    hInq = Vec()
6134    rInq = Vec()
6135    tInq = Vec()
6136
6137    b = m.extractSHRT(sInq, hInq, rInq, tInq)
6138
6139    assert sInq.equalWithAbsError(s, sInq.baseTypeEpsilon())
6140    assert hInq.equalWithAbsError(h, hInq.baseTypeEpsilon())
6141    assert rInq.equalWithAbsError((0, 0, -a), 2 * rInq.baseTypeEpsilon())
6142    assert tInq.equalWithAbsError(t, tInq.baseTypeEpsilon())
6143
6144    # From-to rotation matrix.
6145
6146    fromDir = Vec(1, 1, 0)
6147    fromDir.normalize()
6148    toDir = Vec(0, 1, 1)
6149    toDir.normalize()
6150    m = Mat()
6151    m.rotationMatrix(fromDir, toDir)
6152
6153    v = fromDir * m
6154    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6155
6156    fromDirTup = (fromDir[0], fromDir[1], fromDir[2])
6157    toDirTup = (toDir[0], toDir[1], toDir[2])
6158
6159    m = Mat()
6160    m.rotationMatrix(fromDirTup, toDirTup)
6161
6162    v = fromDir * m
6163    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6164
6165    m = Mat()
6166    m.rotationMatrix(fromDir, toDirTup)
6167
6168    v = fromDir * m
6169    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6170
6171    m = Mat()
6172    m.rotationMatrix(fromDirTup, toDir)
6173
6174    v = fromDir * m
6175    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6176
6177    fromDir = V3f(1, 1, 0)
6178    fromDir.normalize()
6179    toDir = V3f(0, 1, 1)
6180    toDir.normalize()
6181    m = Mat()
6182    m.rotationMatrix(fromDir, toDir)
6183
6184    v = fromDir * m
6185    assert v.equalWithAbsError(toDir, 2 * V3f.baseTypeEpsilon())
6186
6187    fromDir = V3d(1, 1, 0)
6188    fromDir.normalize()
6189    toDir = V3d(0, 1, 1)
6190    toDir.normalize()
6191    m = Mat()
6192    m.rotationMatrix(fromDir, toDir)
6193
6194    v = fromDir * m
6195    assert v.equalWithAbsError(toDir, 2 * V3f.baseTypeEpsilon())
6196
6197    # From-to rotation matrix with up dir.
6198
6199    upDir = Vec(1, 0, 1)
6200    upDir.normalize()
6201    fromDir = Vec(1, 1, 0)
6202    fromDir.normalize()
6203    toDir = Vec(0, 1, 1)
6204    toDir.normalize()
6205    m = Mat()
6206    m.rotationMatrixWithUpDir(fromDir, toDir, upDir)
6207
6208    v = fromDir * m
6209    assert v.equalWithAbsError(toDir, v.baseTypeEpsilon())
6210
6211    fromDirTup = (fromDir[0], fromDir[1], fromDir[2])
6212    toDirTup = (toDir[0], toDir[1], toDir[2])
6213    upDirTup = (upDir[0], upDir[1], upDir[2])
6214
6215    m = Mat()
6216    m.rotationMatrixWithUpDir(fromDirTup, toDirTup, upDirTup)
6217
6218    v = fromDir * m
6219    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6220
6221    m = Mat()
6222    m.rotationMatrixWithUpDir(fromDir, toDirTup, upDirTup)
6223
6224    v = fromDir * m
6225    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6226
6227    m = Mat()
6228    m.rotationMatrixWithUpDir(fromDirTup, toDir, upDirTup)
6229
6230    v = fromDir * m
6231    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6232
6233    m = Mat()
6234    m.rotationMatrixWithUpDir(fromDirTup, toDirTup, upDir)
6235
6236    v = fromDir * m
6237    assert v.equalWithAbsError(toDir, 2 * v.baseTypeEpsilon())
6238
6239    upDir = V3f(1, 0, 1)
6240    upDir.normalize()
6241    fromDir = V3f(1, 1, 0)
6242    fromDir.normalize()
6243    toDir = V3f(0, 1, 1)
6244    toDir.normalize()
6245    m = Mat()
6246    m.rotationMatrixWithUpDir(fromDir, toDir, upDir)
6247
6248    v = fromDir * m
6249    assert v.equalWithAbsError(toDir, V3f.baseTypeEpsilon())
6250
6251    upDir = V3d(1, 0, 1)
6252    upDir.normalize()
6253    fromDir = V3d(1, 1, 0)
6254    fromDir.normalize()
6255    toDir = V3d(0, 1, 1)
6256    toDir.normalize()
6257    m = Mat()
6258    m.rotationMatrixWithUpDir(fromDir, toDir, upDir)
6259
6260    v = fromDir * m
6261    assert v.equalWithAbsError(toDir, V3f.baseTypeEpsilon())
6262
6263    # Determinants (by building a random singular value decomposition)
6264
6265    u = Mat()
6266    v = Mat()
6267    s = Mat()
6268
6269    u.rotationMatrix( V3f(random.random(),random.random(),random.random()).normalize(),
6270                      V3f(random.random(),random.random(),random.random()).normalize() )
6271    v.rotationMatrix( V3f(random.random(),random.random(),random.random()).normalize(),
6272                      V3f(random.random(),random.random(),random.random()).normalize() )
6273    s[0][0] = random.random()
6274    s[1][1] = random.random()
6275    s[2][2] = random.random()
6276    s[3][3] = random.random()
6277
6278    c = u * s * v.transpose()
6279    assert abs(c.determinant() - s[0][0]*s[1][1]*s[2][2]*s[3][3]) <= u.baseTypeEpsilon()
6280
6281    # Matrix minors
6282
6283    a = Mat(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
6284    assert a.minorOf(0,0) == a.fastMinor(1,2,3,1,2,3)
6285    assert a.minorOf(0,1) == a.fastMinor(1,2,3,0,2,3)
6286    assert a.minorOf(0,2) == a.fastMinor(1,2,3,0,1,3)
6287    assert a.minorOf(0,3) == a.fastMinor(1,2,3,0,1,2)
6288    assert a.minorOf(1,0) == a.fastMinor(0,2,3,1,2,3)
6289    assert a.minorOf(1,1) == a.fastMinor(0,2,3,0,2,3)
6290    assert a.minorOf(1,2) == a.fastMinor(0,2,3,0,1,3)
6291    assert a.minorOf(1,3) == a.fastMinor(0,2,3,0,1,2)
6292    assert a.minorOf(2,0) == a.fastMinor(0,1,3,1,2,3)
6293    assert a.minorOf(2,1) == a.fastMinor(0,1,3,0,2,3)
6294    assert a.minorOf(2,2) == a.fastMinor(0,1,3,0,1,3)
6295    assert a.minorOf(2,3) == a.fastMinor(0,1,3,0,1,2)
6296    assert a.minorOf(3,0) == a.fastMinor(0,1,2,1,2,3)
6297    assert a.minorOf(3,1) == a.fastMinor(0,1,2,0,2,3)
6298    assert a.minorOf(3,2) == a.fastMinor(0,1,2,0,1,3)
6299    assert a.minorOf(3,3) == a.fastMinor(0,1,2,0,1,2)
6300
6301    print ("ok")
6302    return
6303
6304def testM44 ():
6305
6306    print ("M44f")
6307    testM44x (M44f, V3f)
6308    print ("M44d")
6309    testM44x (M44d, V3d)
6310
6311testList.append (('testM44',testM44))
6312
6313
6314# -------------------------------------------------------------------------
6315# Tests for Mat --> Mat conversions
6316
6317def testM22xConversions (Mat):
6318
6319    # Assignment
6320
6321    m1 = Mat(0,1, 2,3)
6322
6323    m2 = M22f (m1)
6324    assert m2[0][0] == 0 and m2[0][1] == 1
6325
6326    m2 = M22d (m1)
6327    assert m2[0][0] == 0 and m2[0][1] == 1
6328
6329    # The += operator
6330
6331    m2 = Mat(0,1, 2,3)
6332    m2 += M22f (m1)
6333    assert m2[0][0] == 0 and m2[0][1] == 2
6334
6335    m2 = Mat(0,1, 2,3)
6336    m2 += M22d (m1)
6337    assert m2[0][0] == 0 and m2[0][1] == 2
6338
6339    # The -= operator
6340
6341    m2 = Mat(0,1, 2,3)
6342    m2 -= M22f (m1)
6343    assert m2[0][0] == 0 and m2[0][1] == 0
6344
6345    m2 = Mat(0,1, 2,3)
6346    m2 -= M22d (m1)
6347    assert m2[0][0] == 0 and m2[0][1] == 0
6348
6349    # The *= operator
6350
6351    m2 = Mat(0,1, 2,3)
6352    m2 *= M22f (m1)
6353    assert m2[0][0] == 0*0 + 1*2
6354    assert m2[0][1] == 0*1 + 1*3
6355
6356    m2 = Mat(0,1, 2,3)
6357    m2 *= M22d (m1)
6358    assert m2[0][0] == 0*0 + 1*2
6359    assert m2[0][1] == 0*1 + 1*3
6360
6361    print ("ok")
6362    return
6363
6364
6365def testM33xConversions (Mat):
6366
6367    # Assignment
6368
6369    m1 = Mat(0,1,2, 3,4,5, 6,7,8)
6370
6371    m2 = M33f (m1)
6372    assert m2[0][0] == 0 and m2[0][1] == 1
6373
6374    m2 = M33d (m1)
6375    assert m2[0][0] == 0 and m2[0][1] == 1
6376
6377    # The += operator
6378
6379    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6380    m2 += M33f (m1)
6381    assert m2[0][0] == 0 and m2[0][1] == 2
6382
6383    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6384    m2 += M33d (m1)
6385    assert m2[0][0] == 0 and m2[0][1] == 2
6386
6387    # The -= operator
6388
6389    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6390    m2 -= M33f (m1)
6391    assert m2[0][0] == 0 and m2[0][1] == 0
6392
6393    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6394    m2 -= M33d (m1)
6395    assert m2[0][0] == 0 and m2[0][1] == 0
6396
6397    # The *= operator
6398
6399    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6400    m2 *= M33f (m1)
6401    assert m2[0][0] == 0*0 + 1*3 + 2*6
6402    assert m2[0][1] == 0*1 + 1*4 + 2*7
6403
6404    m2 = Mat(0,1,2, 3,4,5, 6,7,8)
6405    m2 *= M33d (m1)
6406    assert m2[0][0] == 0*0 + 1*3 + 2*6
6407    assert m2[0][1] == 0*1 + 1*4 + 2*7
6408
6409    print ("ok")
6410    return
6411
6412
6413def testM44xConversions (Mat):
6414
6415    # Assignment
6416
6417    m1 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6418
6419    m2 = M44f (m1)
6420    assert m2[0][0] == 0 and m2[0][1] == 1 and m2[0][2] == 2
6421
6422    m2 = M44d (m1)
6423    assert m2[0][0] == 0 and m2[0][1] == 1 and m2[0][2] == 2
6424
6425    # The += operator
6426
6427    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6428    m2 += M44f (m1)
6429    assert m2[0][0] == 0 and m2[0][1] == 2
6430
6431    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6432    m2 += M44d (m1)
6433    assert m2[0][0] == 0 and m2[0][1] == 2
6434
6435    # The -= operator
6436
6437    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6438    m2 -= M44f (m1)
6439    assert m2[0][0] == 0 and m2[0][1] == 0
6440
6441    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6442    m2 -= M44d (m1)
6443    assert m2[0][0] == 0 and m2[0][1] == 0
6444
6445    # The *= operator
6446
6447    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6448    m2 *= M44f (m1)
6449    assert m2[0][0] == 0*0 + 1*4 + 2*8 + 3*12
6450    assert m2[0][1] == 0*1 + 1*5 + 2*9 + 3*13
6451
6452    m2 = Mat((0,1,2,3), (4,5,6,7), (8,9,10,11), (12,13,14,15))
6453    m2 *= M44d (m1)
6454    assert m2[0][0] == 0*0 + 1*4 + 2*8 + 3*12
6455    assert m2[0][1] == 0*1 + 1*5 + 2*9 + 3*13
6456
6457    print ("ok")
6458    return
6459
6460
6461def testInvalidConversion (MatA, MatB):
6462    try:
6463        m = MatA();
6464        m1 = MatB (m);           # This should raise an exception.
6465    except:
6466        pass
6467    else:
6468        assert 0           # We shouldn't get here.
6469
6470
6471def testM33xM44xConversion (MatA, MatB):
6472    testInvalidConversion (MatA, MatB)
6473
6474
6475def testM22xM33xConversion (MatA, MatB):
6476    testInvalidConversion (MatA, MatB)
6477
6478
6479def testM22xM44xConversion (MatA, MatB):
6480    testInvalidConversion (MatA, MatB)
6481
6482
6483def testMatConversions ():
6484
6485    print ("M22f")
6486#    testM22xConversions (M22f)
6487    print ("M22d")
6488    testM22xConversions (M22d)
6489
6490    print ("M33f")
6491    testM33xConversions (M33f)
6492    print ("M33d")
6493    testM33xConversions (M33d)
6494
6495    print ("M44f")
6496    testM44xConversions (M44f)
6497    print ("M44d")
6498    testM44xConversions (M44d)
6499
6500    print ("invalid conversions")
6501    # Deliberatly not exhaustive, just representative.
6502
6503    testM22xM33xConversion (M22f, M33d)
6504    testM22xM33xConversion (M33f, M22d)
6505
6506    testM22xM44xConversion (M22f, M44d)
6507    testM22xM44xConversion (M44f, M22d)
6508
6509    testM33xM44xConversion (M33f, M44d)
6510    testM33xM44xConversion (M44f, M33d)
6511
6512    print ("ok")
6513    return
6514
6515
6516testList.append (('testMatConversions',testMatConversions))
6517
6518
6519# -------------------------------------------------------------------------
6520# Tests for Box2x
6521
6522def testBox2x (Box, Vec):
6523
6524    # constructors
6525
6526    b = Box()
6527    assert b.isEmpty() and (not b.hasVolume())
6528
6529    b = Box (Vec (1, 2))
6530    assert (not b.isEmpty()) and (not b.hasVolume())
6531    assert b.min() == Vec (1, 2) and b.max() == Vec (1, 2)
6532
6533    b = Box (Vec (4, 5), Vec (7, 8))
6534    assert (not b.isEmpty()) and b.hasVolume()
6535    assert b.min() == Vec (4, 5) and b.max() == Vec (7, 8)
6536
6537    b1 = Box (b)
6538    assert b1.min() == Vec (4, 5) and b1.max() == Vec (7, 8)
6539
6540    b = Box (((1, 2), (4, 5)))
6541    assert b.min() == Vec (1, 2) and b.max() == Vec (4, 5)
6542
6543    # setMin(), setMax()
6544
6545    b = Box()
6546    b.setMin (Vec (1, 2))
6547    b.setMax (Vec (3, 6))
6548    assert b.min() == Vec (1, 2) and b.max() == Vec (3, 6)
6549    assert b.size() == Vec (2, 4)
6550    assert b.center() == Vec (2, 4)
6551
6552    # makeEmpty()
6553
6554    b.makeEmpty()
6555    assert b.isEmpty()
6556
6557    # extendBy()
6558
6559    b.extendBy (Vec (1, 2))
6560    assert b.min() == Vec (1, 2) and b.max() == Vec (1, 2)
6561
6562    b.extendBy (Vec (0, 2))
6563    assert b.min() == Vec (0, 2) and b.max() == Vec (1, 2)
6564
6565    b.extendBy (Box (Vec (0, 0), Vec (4, 4)))
6566    assert b.min() == Vec (0, 0) and b.max() == Vec (4, 4)
6567
6568    # intersects()
6569
6570    b = Box (Vec (0, 0), Vec (4, 4))
6571    assert b.intersects (Vec (1, 2))
6572    assert not b.intersects (Vec (6, 7))
6573    assert b.intersects (Box (Vec (-2, -2), Vec (1, 1)))
6574    assert not b.intersects (Box (Vec (-2, -2), Vec (-1, -1)))
6575
6576    # majorAxis()
6577
6578    assert 0 == Box(Vec (0, 0), Vec (2, 1)).majorAxis()
6579    assert 1 == Box(Vec (0, 0), Vec (1, 2)).majorAxis()
6580
6581    # repr
6582
6583    b = Box (Vec (1/9., 2/9.), Vec (4/9., 5/9.))
6584    assert b == eval (repr (b))
6585
6586    print ("ok")
6587    return
6588
6589
6590def testBox2():
6591
6592    print ("Box2i")
6593    testBox2x (Box2i, V2i)
6594    print ("Box2i64")
6595    testBox2x (Box2i64, V2i64)
6596    print ("Box2f")
6597    testBox2x (Box2f, V2f)
6598    print ("Box2d")
6599    testBox2x (Box2d, V2d)
6600
6601
6602testList.append (('testBox2',testBox2))
6603
6604
6605# -------------------------------------------------------------------------
6606# Tests for Box3x
6607
6608def testBox3x (Box, Vec):
6609
6610    # constructors
6611
6612    b = Box()
6613    assert b.isEmpty() and (not b.hasVolume())
6614
6615    b = Box (Vec (1, 2, 3))
6616    assert (not b.isEmpty()) and (not b.hasVolume())
6617    assert b.min() == Vec (1, 2, 3) and b.max() == Vec (1, 2, 3)
6618
6619    b = Box (Vec (4, 5, 6), Vec (7, 8, 9))
6620    assert (not b.isEmpty()) and b.hasVolume()
6621    assert b.min() == Vec (4, 5, 6) and b.max() == Vec (7, 8, 9)
6622
6623    b1 = Box (b)
6624    assert b1.min() == Vec (4, 5, 6) and b1.max() == Vec (7, 8, 9)
6625
6626    b = Box (((1, 2, 3), (4, 5, 6)))
6627    assert b.min() == Vec (1, 2, 3) and b.max() == Vec (4, 5, 6)
6628
6629    # setMin(), setMax()
6630
6631    b = Box()
6632    b.setMin (Vec (1, 2, 3))
6633    b.setMax (Vec (3, 6, 11))
6634    assert b.min() == Vec (1, 2, 3) and b.max() == Vec (3, 6, 11)
6635    assert b.size() == Vec (2, 4, 8)
6636    assert b.center() == Vec (2, 4, 7)
6637
6638    # makeEmpty()
6639
6640    b.makeEmpty()
6641    assert b.isEmpty()
6642
6643    # extendBy()
6644
6645    b.extendBy (Vec (1, 2, 3))
6646    assert b.min() == Vec (1, 2, 3) and b.max() == Vec (1, 2, 3)
6647
6648    b.extendBy (Vec (0, 2, 4))
6649    assert b.min() == Vec (0, 2, 3) and b.max() == Vec (1, 2, 4)
6650
6651    b.extendBy (Box (Vec (0, 0, 0), Vec (4, 4, 4)))
6652    assert b.min() == Vec (0, 0, 0) and b.max() == Vec (4, 4, 4)
6653
6654    # intersects()
6655
6656    b = Box (Vec (0, 0, 0), Vec (4, 4, 4))
6657    assert b.intersects (Vec (1, 2, 3))
6658    assert not b.intersects (Vec (6, 7, 8))
6659    assert b.intersects (Box (Vec (-2, -2, -2), Vec (1, 1, 1)))
6660    assert not b.intersects (Box (Vec (-2, -2, -2), Vec (-1, -1, -1)))
6661
6662    # majorAxis()
6663
6664    assert 0 == Box(Vec (0, 0, 0), Vec (2, 1, 1)).majorAxis()
6665    assert 1 == Box(Vec (0, 0, 0), Vec (1, 2, 1)).majorAxis()
6666    assert 2 == Box(Vec (0, 0, 0), Vec (1, 1, 2)).majorAxis()
6667
6668    # repr
6669
6670    b = Box (Vec (1/9., 2/9., 3/9.), Vec (4/9., 5/9., 6/9.))
6671    assert b == eval (repr (b))
6672
6673    # tranform
6674
6675    b = Box (Vec (1, 1, 1), Vec (2, 2, 2))
6676
6677    mf = M44f ()
6678    mf.setTranslation (Vec (10, 11, 12))
6679
6680    b2 = b * mf
6681    assert b2.min() == Vec (11, 12, 13)
6682    assert b2.max() == Vec (12, 13, 14)
6683
6684    b *= mf
6685    assert b.min() == Vec (11, 12, 13)
6686    assert b.max() == Vec (12, 13, 14)
6687
6688    b = Box (Vec (1, 1, 1), Vec (2, 2, 2))
6689
6690    md = M44d ()
6691    md.setTranslation (Vec (10, 11, 12))
6692
6693    b2 = b * md
6694    assert b2.min() == Vec (11, 12, 13)
6695    assert b2.max() == Vec (12, 13, 14)
6696
6697    b *= md
6698    assert b.min() == Vec (11, 12, 13)
6699    assert b.max() == Vec (12, 13, 14)
6700
6701    print ("ok")
6702    return
6703
6704
6705def testBox3():
6706
6707    print ("Box3i")
6708    testBox3x (Box3i, V3i)
6709    print ("Box3i64")
6710    testBox3x (Box3i64, V3i64)
6711    print ("Box3f")
6712    testBox3x (Box3f, V3f)
6713    print ("Box3d")
6714    testBox3x (Box3d, V3d)
6715
6716
6717testList.append (('testBox3',testBox3))
6718
6719
6720# -------------------------------------------------------------------------
6721# Tests for Box --> Box conversions
6722
6723def testBox2Conversions (Box, Vec):
6724
6725    b1 = Box (Vec (1, 2), Vec (4, 5))
6726
6727    b2 = Box2i (b1)
6728    assert b2.min() == V2i (1, 2) and b2.max() == V2i (4, 5)
6729
6730    b2 = Box2f (b1)
6731    assert b2.min() == V2f (1, 2) and b2.max() == V2f (4, 5)
6732
6733    b2 = Box2d (b1)
6734    assert b2.min() == V2d (1, 2) and b2.max() == V2d (4, 5)
6735
6736    print ("ok")
6737    return
6738
6739
6740def testBox3Conversions (Box, Vec):
6741
6742    b1 = Box (Vec (1, 2, 3), Vec (4, 5, 6))
6743
6744    b2 = Box3i (b1)
6745    assert b2.min() == V3i (1, 2, 3) and b2.max() == V3i (4, 5, 6)
6746
6747    b2 = Box3f (b1)
6748    assert b2.min() == V3f (1, 2, 3) and b2.max() == V3f (4, 5, 6)
6749
6750    b2 = Box3d (b1)
6751    assert b2.min() == V3d (1, 2, 3) and b2.max() == V3d (4, 5, 6)
6752
6753    print ("ok")
6754    return
6755
6756
6757def testBox2Box3Conversion (Box1, Box2):
6758
6759    try:
6760        b = Box1();
6761        b1 = Box2 (b);           # This should raise an exception.
6762    except:
6763        pass
6764    else:
6765        assert 0           # We shouldn't get here.
6766
6767
6768def testBoxConversions ():
6769
6770    print ("Box2i")
6771    testBox2Conversions (Box2i, V2i)
6772    print ("Box2i64")
6773    testBox2Conversions (Box2i64, V2i64)
6774    print ("Box2f")
6775    testBox2Conversions (Box2f, V2f)
6776    print ("Box2d")
6777    testBox2Conversions (Box2d, V2d)
6778
6779    print ("Box3i")
6780    testBox3Conversions (Box3i, V3i)
6781    print ("Box3i64")
6782    testBox3Conversions (Box3i64, V3i64)
6783    print ("Box3f")
6784    testBox3Conversions (Box3f, V3f)
6785    print ("Box3d")
6786    testBox3Conversions (Box3d, V3d)
6787
6788    print ("invalid conversions")
6789    testBox2Box3Conversion (Box2i, Box3i)
6790    testBox2Box3Conversion (Box2i, Box3f)
6791    testBox2Box3Conversion (Box3d, Box2i)
6792    testBox2Box3Conversion (Box3f, Box2f)
6793
6794    print ("ok")
6795    return
6796
6797
6798testList.append (('testBoxConversions',testBoxConversions))
6799
6800
6801# -------------------------------------------------------------------------
6802# Tests for Quatx
6803
6804def testQuatx (Quat, Vec, M33, M44):
6805
6806    # constructors, r(), v()
6807    e = 4 * Vec.baseTypeEpsilon()
6808
6809    q = Quat()
6810    assert q.r() == 1 and q.v() == Vec (0, 0, 0)
6811
6812    q = Quat (2, 3, 4, 5)
6813    assert q.r() == 2 and q.v() == Vec (3, 4, 5)
6814
6815    q = Quat (6, Vec (7, 8, 9))
6816    assert q.r() == 6 and q.v() == Vec (7, 8, 9)
6817
6818    q1 = Quat (q)
6819    assert q1.r() == 6 and q1.v() == Vec (7, 8, 9)
6820
6821    # setR(), setV()
6822
6823    q.setR (1)
6824    q.setV (Vec (2, 3, 4))
6825    assert q.r() == 1 and q.v() == Vec (2, 3, 4)
6826
6827    # invert(), inverse()
6828
6829    q = Quat (1, 0, 0, 1)
6830    assert q.inverse() == Quat (0.5, 0, 0, -0.5)
6831    q.invert()
6832    assert q == Quat (0.5, 0, 0, -0.5)
6833
6834    # normalize(), normalized()
6835
6836    q = Quat (2, Vec (0, 0, 0))
6837    assert q.normalized() == Quat (1, 0, 0, 0)
6838    q.normalize()
6839    assert q == Quat (1, 0, 0, 0)
6840
6841    q = Quat (0, Vec (0, 2, 0))
6842    assert q.normalized() == Quat (0, 0, 1, 0)
6843    q.normalize()
6844    assert q == Quat (0, 0, 1, 0)
6845
6846    # length()
6847
6848    q = Quat (3, 0, 4, 0)
6849    assert q.length() == 5
6850
6851    # setAxisAngle(), angle(), axis()
6852
6853    q.setAxisAngle (Vec (0, 0, 1), pi/2)
6854    v = q.axis()
6855    a = q.angle()
6856    assert v.equalWithAbsError (Vec (0, 0, 1), e)
6857    assert equal(a, pi/2, e)
6858
6859    # setRotation()
6860
6861    q.setRotation (Vec (1, 0, 0), Vec (0, 1, 0))
6862    v = q.axis()
6863    a = q.angle()
6864    assert v.equalWithAbsError (Vec (0, 0, 1), e)
6865    assert equal(a, pi/2, e)
6866
6867    # slerp()
6868
6869    q = Quat()
6870    q.setAxisAngle (Vec (0, 0, 1), pi/2)
6871    p = Quat()
6872    p.setAxisAngle (Vec (1, 0, 0), pi/2)
6873
6874    r = q.slerp (p, 0)
6875
6876    assert equal (r.r(), sqrt(2) / 2, e)
6877
6878    assert r.v().equalWithAbsError (Vec (0, 0, sqrt(2) / 2), e)
6879    r = q.slerp (p, 1)
6880
6881    assert equal (r.r(), sqrt(2) / 2, e)
6882
6883    assert r.v().equalWithAbsError (Vec (sqrt(2) / 2, 0, 0), e)
6884
6885    # toMatrix33(), toMatrix44()
6886
6887    q.setRotation (Vec (1, 0, 0), Vec (0, 1, 0))
6888
6889    m = q.toMatrix33()
6890
6891    assert m.equalWithAbsError (M33 (0, 1, 0,
6892                                    -1, 0, 0,
6893                                     0, 0, 1),
6894                                m.baseTypeEpsilon())
6895    m = q.toMatrix44()
6896
6897    assert m.equalWithAbsError (M44 (( 0, 1, 0, 0),
6898                                     (-1, 0, 0, 0),
6899                                     ( 0, 0, 1, 0),
6900                                     ( 0, 0, 0, 1)),
6901                                m.baseTypeEpsilon())
6902
6903    # +, - (unary and binary), ~ *, /, ^
6904
6905    assert Quat (1, 2, 3, 4) + Quat (5, 6, 7, 8) == Quat (6, 8, 10, 12)
6906
6907    assert Quat (-1, -2, -3, -4) - Quat (5, 6, 7, 8) == Quat (-6, -8, -10, -12)
6908    assert -Quat (1, 2, 3, 4) == Quat (-1, -2, -3, -4)
6909
6910    assert ~Quat (1, 2, 3, 4) == Quat (1, -2, -3, -4)
6911
6912    assert 2 * Quat (1, 2, 3, 4) == Quat (2, 4, 6, 8)
6913    assert Quat (1, 2, 3, 4) * 2 == Quat (2, 4, 6, 8)
6914    assert Quat (1, 0, 0, 1) * Quat (1, 1, 0, 0) == Quat (1, 1, 1, 1)
6915    assert Quat (1, 1, 0, 0) * Quat (1, 0, 0, 1) == Quat (1, 1, -1, 1)
6916
6917    assert Quat (1, 0, 0, 1) / Quat (0.5, -0.5, 0, 0) == Quat (1, 1, 1, 1)
6918    assert Quat (2, 4, 6, 8) / 2 == Quat (1, 2, 3, 4)
6919
6920    assert Quat (1, 2, 3, 4) ^ Quat (2, 2, 2, 2) == 20
6921
6922    # repr
6923
6924    q = Quat (1/9., 2/9., 3/9., 4/9.)
6925    assert q == eval (repr (q))
6926
6927    # extract()
6928
6929    m1 = M44 ()
6930    vFrom = Vec (1, 0, 0)
6931    vTo = Vec (0, 1, 1)
6932    m1.rotationMatrix(vFrom, vTo)
6933    q = Quat ()
6934    q.extract(m1)
6935    m2 = q.toMatrix44()
6936    assert m2.equalWithAbsError(m1, 2*m1.baseTypeEpsilon())
6937
6938    print ("ok")
6939    return
6940
6941
6942def testQuatConversions ():
6943
6944    q = Quatf (1, V3f (2, 3, 4))
6945    q1 = Quatd (q)
6946    assert q1.r() == 1 and q1.v() == V3d (2, 3, 4)
6947
6948    q = Quatd (1, V3d (2, 3, 4))
6949    q1 = Quatf (q)
6950    assert q1.r() == 1 and q1.v() == V3f (2, 3, 4)
6951
6952    print ("ok")
6953    return
6954
6955
6956def testQuat():
6957
6958    print ("Quatf")
6959    testQuatx (Quatf, V3f, M33f, M44f)
6960    print ("Quatd")
6961    testQuatx (Quatd, V3d, M33d, M44d)
6962    print ("conversions")
6963    testQuatConversions()
6964
6965
6966testList.append (('testQuat',testQuat))
6967
6968
6969# -------------------------------------------------------------------------
6970# Tests for Eulerx
6971
6972def testEulerx (Euler, Vec, M33, M44):
6973
6974    # constructors, toXYZVector(), order()
6975
6976    e = Euler()
6977    assert e.toXYZVector() == Vec (0, 0, 0) and e.order() == EULER_XYZ
6978
6979    e = Euler (Vec (1, 2, 3))
6980    assert e.toXYZVector() == Vec (1, 2, 3) and e.order() == EULER_XYZ
6981
6982    e = Euler (Vec (1, 2, 3), EULER_ZYX)
6983    assert e.toXYZVector() == Vec (3, 2, 1) and e.order() == EULER_ZYX
6984
6985    e1 = Euler (e)
6986    assert e1.toXYZVector() == Vec (3, 2, 1) and e1.order() == EULER_ZYX
6987
6988    e = Euler (4, 5, 6)
6989    assert e.toXYZVector() == Vec (4, 5, 6) and e.order() == EULER_XYZ
6990
6991    e = Euler (4, 5, 6, EULER_ZXY)
6992    assert e.toXYZVector() == Vec (5, 6, 4) and e.order() == EULER_ZXY
6993
6994    e = Euler (M33())
6995    assert e.toXYZVector() == Vec (0, 0, 0) and e.order() == EULER_XYZ
6996
6997    e = Euler (M33(), EULER_ZYX)
6998    assert e.toXYZVector() == Vec (0, 0, 0) and e.order() == EULER_ZYX
6999
7000    e = Euler (M44())
7001    assert e.toXYZVector() == Vec (0, 0, 0) and e.order() == EULER_XYZ
7002
7003    e = Euler (M44(), EULER_ZYX)
7004    assert e.toXYZVector() == Vec (0, 0, 0) and e.order() == EULER_ZYX
7005
7006    # comparison
7007
7008    e = Euler (1, 2, 3, EULER_XYZ)
7009
7010    e1 = e
7011    assert e1 == e
7012
7013    e1 = Euler (1, 2, 3, EULER_XZY)
7014    assert e1 != e
7015
7016    e1 = Euler (1, 1, 3, EULER_XYZ)
7017    assert e1 != e
7018
7019    # setXYZVector(), setOrder()
7020
7021    e.setXYZVector (Vec (7, 8, 9))
7022
7023    e.setOrder (EULER_ZYX)
7024    assert e.order() == EULER_ZYX and e.toXYZVector() == Vec (9, 8, 7)
7025
7026    e.setOrder (EULER_XYZ)
7027    assert e.order() == EULER_XYZ and e.toXYZVector() == Vec (7, 8, 9)
7028
7029    # set(), frameStatic(), initialRepeated(), parityEven(), initialAxis()
7030
7031    e.set (EULER_X_AXIS, 0, 0, 1)
7032    assert e.order() == EULER_XZX
7033    assert e.frameStatic() == 1
7034    assert e.initialRepeated() == 1
7035    assert e.parityEven() == 0
7036    assert e.initialAxis() == EULER_X_AXIS
7037
7038    e.set (EULER_Y_AXIS, 1, 0, 1)
7039    assert e.order() == EULER_YZYr
7040    assert e.frameStatic() == 0
7041    assert e.initialRepeated() == 1
7042    assert e.parityEven() == 0
7043    assert e.initialAxis() == EULER_Y_AXIS
7044
7045    e.set (EULER_Z_AXIS, 1, 1, 1)
7046    assert e.order() == EULER_XZXr
7047    assert e.frameStatic() == 0
7048    assert e.initialRepeated() == 1
7049    assert e.parityEven() == 1
7050    assert e.initialAxis() == EULER_Z_AXIS
7051
7052    # extract()
7053
7054    e = Euler (EULER_XYZ);
7055
7056    m = M33 (( 0, 2, 0),        # 90-degree rotation around Z,
7057             (-2, 0, 0),        # scale by factor 2
7058             ( 0, 0, 2))
7059
7060    e.extract (m);
7061    v = e.toXYZVector();
7062
7063    assert v.equalWithAbsError (Vec (0, 0, pi/2), v.baseTypeEpsilon())
7064
7065    m = M44 (( 0, 2, 0, 0),        # 90-degree rotation around Z
7066             (-2, 0, 0, 0),        # scale by factor 2
7067             ( 0, 0, 2, 0),
7068             ( 0, 0, 0, 1))
7069
7070    e.extract (m);
7071    v = e.toXYZVector();
7072
7073    assert v.equalWithAbsError (Vec (0, 0, pi/2), v.baseTypeEpsilon())
7074
7075    # toMatrix33(), toMatrix44()
7076
7077    m = e.toMatrix33();
7078
7079    assert m.equalWithAbsError (M33 (0, 1, 0,
7080                                    -1, 0, 0,
7081                                     0, 0, 1),
7082                                m.baseTypeEpsilon())
7083    m = e.toMatrix44();
7084
7085    assert m.equalWithAbsError (M44 (( 0, 1, 0, 0),
7086                                     (-1, 0, 0, 0),
7087                                     ( 0, 0, 1, 0),
7088                                     ( 0, 0, 0, 1)),
7089                                m.baseTypeEpsilon())
7090    # toQuat()
7091
7092    q = e.toQuat();
7093
7094    assert equal (q.r(), sqrt(2) / 2, Vec().baseTypeEpsilon())
7095
7096    assert q.v().equalWithAbsError (Vec (0, 0, sqrt(2) / 2),
7097                                    Vec().baseTypeEpsilon())
7098
7099    # angleOrder()
7100
7101    e = Euler (EULER_XYZ)
7102    assert e.angleOrder() == (0, 1, 2)
7103
7104    e = Euler (EULER_XZY)
7105    assert e.angleOrder() == (0, 2, 1)
7106
7107    e = Euler (EULER_ZYX)
7108    assert e.angleOrder() == (2, 1, 0)
7109
7110    # makeNear()
7111
7112    e = Euler (0, 0, 0.1 + 2 * pi)
7113    e1 = Euler (0, 0, 0.1)
7114
7115    e.makeNear (e1)
7116    v = e.toXYZVector()
7117    assert v.equalWithAbsError (Vec (0, 0, 0.1), v.baseTypeEpsilon())
7118
7119    # repr
7120
7121    e = Euler (1/9., 2/9., 3/9., EULER_XYZ)
7122    assert e == eval (repr (e))
7123
7124    e = Euler (1/9., 2/9., 3/9., EULER_YXZ)
7125    assert e == eval (repr (e))
7126
7127    e = Euler (1/9., 2/9., 3/9., EULER_XZXr)
7128    assert e == eval (repr (e))
7129
7130    print ("ok")
7131    return
7132
7133
7134def testEulerConversions ():
7135
7136    e = Eulerf (V3f (1, 2, 3), EULER_XYZ)
7137    e1 = Eulerd (e)
7138    assert e1.toXYZVector() == V3d (1, 2, 3) and e1.order() == EULER_XYZ
7139
7140    e = Eulerd (V3d (1, 2, 3), EULER_XYZ)
7141    e1 = Eulerf (e)
7142    assert e1.toXYZVector() == V3f (1, 2, 3) and e1.order() == EULER_XYZ
7143
7144    print ("ok")
7145    return
7146
7147
7148def testEuler():
7149
7150    print ("Eulerf")
7151    testEulerx (Eulerf, V3f, M33f, M44f)
7152    print ("Eulerd")
7153    testEulerx (Eulerd, V3d, M33d, M44d)
7154    print ("conversions")
7155    testEulerConversions()
7156
7157
7158testList.append (('testEuler',testEuler))
7159
7160
7161# -------------------------------------------------------------------------
7162# Tests for Line3x
7163
7164def testLine3x (Line, Vec, Mat):
7165
7166    # constructors, pos(), dir()
7167
7168    l = Line()
7169    assert l.pos() == Vec (0, 0, 0) and l.dir() == Vec (1, 0, 0)
7170
7171    l = Line (Vec (1, 2, 3), Vec (1, 6, 3))
7172    assert l.pos() == Vec (1, 2, 3) and l.dir() == Vec (0, 1, 0)
7173
7174    l1 = Line (l)
7175    assert l1.pos() == Vec (1, 2, 3) and l1.dir() == Vec (0, 1, 0)
7176
7177    # comparison
7178
7179    l = Line (Vec (1, 1, 1), Vec (2, 2, 2))
7180    l1 = Line (l)
7181    assert l == l1
7182
7183    l = Line (Vec (1, 1, 1), Vec (2, 2, 3))
7184    assert l != l1
7185
7186    l = Line (Vec (1, 1, 2), Vec (2, 2, 2))
7187    assert l != l1
7188
7189    # setPos(), setDir(), set()
7190
7191    l.setPos (Vec (4, 5, 6))
7192    l.setDir (Vec (0, 0, 4))
7193    assert l.pos() == Vec (4, 5, 6) and l.dir() == Vec (0, 0, 1)
7194
7195    l.set (Vec (1, 2, 3), Vec (1, 6, 3))
7196    assert l.pos() == Vec (1, 2, 3) and l.dir() == Vec (0, 1, 0)
7197
7198    # pointAt()
7199
7200    l = Line (Vec (1, 2, 3), Vec (2, 2, 3))
7201    assert l.pointAt (2) == Vec (3, 2, 3)
7202
7203    # distanceTo()
7204
7205    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7206    assert l.distanceTo (Vec (2, 3, 0)) == 3
7207    assert l.distanceTo (Line (Vec (0, 2, -1), Vec (0, 2, 1))) == 2
7208
7209    # closestPointTo(), closestPoints()
7210
7211    l = Line (Vec (1, 0, 0), Vec (2, 0, 0))
7212    assert l.closestPointTo (Vec (0, 1, 0)) == Vec (0, 0, 0)
7213
7214    l1 = Line (Vec (0, 1, 1), Vec (0, 1, 2))
7215    assert l.closestPointTo (l1) == Vec (0, 0, 0)
7216
7217    p = l.closestPoints (l1)
7218    assert p[0] == Vec (0, 0, 0) and p[1] == Vec (0, 1, 0)
7219
7220    # closestTriangleVertex()
7221
7222    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7223    v = l.closestTriangleVertex (Vec (1, 1, 1), Vec (2, 0, 2), Vec (1, 2, 3))
7224    assert v == Vec (1, 1, 1)
7225
7226    # intersectWithTriangle()
7227
7228    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7229
7230    i = l.intersectWithTriangle (Vec (1, 1, 0), Vec (1, 2, 0), Vec (2, 2, 0))
7231
7232    assert i == None
7233
7234    i = l.intersectWithTriangle (Vec (4,-1,-1), Vec (4,-1, 2), Vec (4, 2,-1))
7235
7236    assert i[0] == Vec (4, 0, 0)
7237    assert i[1].equalWithAbsError (Vec (1) / 3, i[1].baseTypeEpsilon())
7238    assert i[2] == 0
7239
7240    # rotatePoint()
7241
7242    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7243    p = l.rotatePoint (Vec (2, 2, 0), pi/2)
7244
7245    assert p.equalWithAbsError (Vec (2, 0, -2), p.baseTypeEpsilon())
7246
7247    # line*matrix multiplication
7248
7249    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7250
7251    m = Mat (( 0, 1, 0, 0),
7252             (-1, 0, 0, 0),
7253             ( 0, 0, 1, 0),
7254             ( 0, 0, 0, 1))
7255
7256    l = l * m
7257    assert l.pos() == Vec (0, 0, 0) and l.dir() == Vec (0, 1, 0)
7258
7259    try:
7260        l = m * l        # should raise TypeError
7261    except TypeError:
7262        pass
7263    else:
7264        assert 0
7265
7266    # repr
7267
7268    e = Line (V3f (1/9., 2/9., 3/9.), V3f (1/9., 3/9., 3/9.))
7269    assert e == eval (repr (e))
7270
7271    print ("ok")
7272    return
7273
7274
7275def testLine3Conversions ():
7276
7277    l = Line3f (V3f (1, 2, 3), V3f (1, 3, 3))
7278    l1 = Line3d (l)
7279    assert l1.pos() == V3d (1, 2, 3) and l1.dir() == V3d (0, 1, 0)
7280
7281    l = Line3d (V3d (1, 2, 3), V3d (1, 3, 3))
7282    l1 = Line3f (l)
7283    assert l1.pos() == V3f (1, 2, 3) and l1.dir() == V3f (0, 1, 0)
7284
7285    print ("ok")
7286    return
7287
7288
7289def testLine3():
7290
7291    print ("Line3f")
7292    testLine3x (Line3f, V3f, M44f)
7293    print ("Line3d")
7294    testLine3x (Line3d, V3d, M44d)
7295    print ("conversions")
7296    testLine3Conversions()
7297
7298
7299testList.append (('testLine3',testLine3))
7300
7301
7302# -------------------------------------------------------------------------
7303# Tests for Plane3x
7304
7305def testPlane3x (Plane, Vec, Mat, Line):
7306
7307    # constructors, normal(), distance()
7308
7309    p = Plane()
7310    assert p.normal() == Vec (1, 0, 0) and p.distance() == 0
7311
7312    p = Plane (Vec (0, 4, 0), 3) # normal, distance
7313    assert p.normal() == Vec (0, 1, 0) and p.distance() == 3
7314
7315    p = Plane (Vec (0, 4, 0), Vec (0, 1, 0)) # point, normal
7316    assert p.normal() == Vec (0, 1, 0) and p.distance() == 4
7317
7318    p = Plane (Vec (0, 0, 1), Vec (2, 0, 1), Vec (0, 2, 1)) # three points
7319    assert p.normal() == Vec (0, 0, 1) and p.distance() == 1
7320
7321    p1 = Plane (p)
7322    assert p1.normal() == Vec (0, 0, 1) and p1.distance() == 1
7323
7324    # comparison
7325
7326    p = Plane (Vec (1, 1, 1), 2)
7327    p1 = Plane (p)
7328    assert p == p1
7329
7330    p = Plane (Vec (1, 1, 2), 2)
7331    assert p != p1
7332
7333    p = Plane (Vec (1, 1, 1), 1)
7334    assert p != p1
7335
7336    # setNormal(), setDistance()
7337
7338    p = Plane(Vec (1, 1, 1), 3)
7339    p.setNormal (Vec (0, 0, 4))
7340    p.setDistance (5)
7341    assert p.normal() == Vec (0, 0, 1) and p.distance() == 5
7342
7343    # set()
7344
7345    p.set (Vec (0, 1, 0), 2) # normal, distance
7346    assert p.normal() == Vec (0, 1, 0) and p.distance() == 2
7347
7348    p.set (Vec (0, 2, 0), Vec (0, 0, 1)) # point, normal
7349    assert p.normal() == Vec (0, 0, 1) and p.distance() == 0
7350
7351    p.set (Vec (1, 0, 2), Vec (1, 2, 0), Vec (1, 0, 0)) # three points
7352    assert p.normal() == Vec (-1, 0, 0) and p.distance() == -1
7353
7354    # intersect(), intersectT(), distanceTo(), reflectPoint(), reflectVector()
7355
7356    p = Plane (Vec (2, 0, 2), Vec (2, 2, 0), Vec (2, 0, 0)) # three points
7357
7358    l = Line (Vec (0, 0, 0), Vec (1, 0, 0))
7359    assert p.intersect(l) == Vec (2, 0, 0)
7360    assert p.intersectT(l) == 2
7361
7362    assert p.distanceTo (Vec (1, 2, 3)) ==  1
7363    assert p.distanceTo (Vec (3, 2, 3)) == -1
7364
7365    assert p.reflectPoint (Vec (1, 2, 3)) == Vec (3, 2, 3)
7366    assert p.reflectVector (Vec (1, 2, 3)) == Vec (1, -2, -3)
7367
7368    # plane*matrix multiplication
7369
7370    p = Plane (Vec (1, 0, 0), 4)
7371
7372    m = Mat (( 0, 1, 0, 0),
7373             (-1, 0, 0, 0),
7374             ( 0, 0, 1, 0),
7375             ( 0, 0, 0, 1))
7376
7377    p = p * m
7378    assert p.normal().equalWithAbsError (Vec (0, 1, 0), Vec().baseTypeEpsilon())
7379    assert equal (p.distance(), 4, Vec().baseTypeEpsilon())
7380
7381    try:
7382        p = m * p        # should raise TypeError
7383    except TypeError:
7384        pass
7385    else:
7386        assert 0
7387
7388    # unary minus operator
7389
7390    assert -Plane (Vec (0, 1, 0), 4) == Plane (Vec (0, -1, 0), -4)
7391
7392    # repr
7393
7394    e = Plane (Vec (0/9., 1/9., 0/9.), 3/9.)
7395    assert e == eval (repr (e))
7396
7397    print ("ok")
7398    return
7399
7400
7401def testPlane3Conversions ():
7402
7403    p = Plane3f (V3f (1, 0, 0), 3)
7404    p1 = Plane3d (p)
7405    assert p1.normal() == V3d (1, 0, 0) and p1.distance() == 3
7406
7407    p = Plane3d (V3d (1, 0, 0), 3)
7408    p1 = Plane3f (p)
7409    assert p1.normal() == V3f (1, 0, 0) and p1.distance() == 3
7410
7411    print ("ok")
7412    return
7413
7414
7415def testPlane3():
7416
7417    print ("Plane3f")
7418    testPlane3x (Plane3f, V3f, M44f, Line3f)
7419    print ("Plane3d with Line3f")
7420    testPlane3x (Plane3d, V3d, M44d, Line3f)
7421    print ("Plane3d with Line3d")
7422    testPlane3x (Plane3d, V3d, M44d, Line3d)
7423    print ("conversions")
7424    testPlane3Conversions()
7425
7426
7427testList.append (('testPlane3',testPlane3))
7428
7429
7430# -------------------------------------------------------------------------
7431# Tests for Color3x
7432
7433def testColor3x (Color, maxComp):
7434
7435    # Constructors (and element access).
7436
7437    v = Color()
7438    assert v[0] == 0 and v[1] == 0 and v[2] == 0
7439
7440    v = Color(1)
7441    assert v[0] == 1 and v[1] == 1 and v[2] == 1
7442
7443    v = Color(0, 1, 2)
7444    assert v[0] == 0 and v[1] == 1 and v[2] == 2
7445
7446    v = Color((0, 1, 2))
7447    assert v[0] == 0 and v[1] == 1 and v[2] == 2
7448
7449    v = Color([0, 1, 2])
7450    assert v[0] == 0 and v[1] == 1 and v[2] == 2
7451
7452    v = Color()
7453    v.setValue(0, 1, 2)
7454    assert v[0] == 0 and v[1] == 1 and v[2] == 2
7455
7456    # Repr.
7457
7458    v = Color(1/9., 2/9., 3/9.)
7459    assert v == eval(repr(v))
7460
7461    # Sequence length.
7462
7463    v = Color()
7464    assert len(v) == 3
7465
7466    # Element setting.
7467
7468    v = Color()
7469    v[0] = 10
7470    v[1] = 11
7471    v[2] = 12
7472    assert v[0] == 10 and v[1] == 11 and v[2] == 12
7473
7474    try:
7475        v[-4] = 0           # This should raise an exception.
7476    except:
7477        pass
7478    else:
7479        assert 0           # We shouldn't get here.
7480
7481    try:
7482        v[3] = 0           # This should raise an exception.
7483    except:
7484        pass
7485    else:
7486        assert 0           # We shouldn't get here.
7487
7488    try:
7489        v[1] = "a"           # This should raise an exception.
7490    except:
7491        pass
7492    else:
7493        assert 0           # We shouldn't get here.
7494
7495    # Assignment.
7496
7497    v1 = Color(1)
7498
7499    v2 = v1
7500    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1
7501    v1[0] = 2
7502    assert v2[0] == 2 and v2[1] == 1 and v2[2] == 1
7503
7504    # Comparison operators.
7505
7506    v1 = Color(20, 20, 0)
7507    v2 = Color(20, 20, 0)
7508    v3 = Color(20, 21, 0)
7509
7510    assert v1 == v2
7511    assert v1 != v3
7512    assert not (v1 < v2)
7513    assert v1 < v3
7514    assert v1 <= v2
7515    assert v1 <= v3
7516    assert not (v3 <= v1)
7517    assert not (v2 > v1)
7518    assert v3 > v1
7519    assert v2 >= v1
7520    assert v3 >= v1
7521    assert not (v1 >= v3)
7522
7523    # Addition.
7524
7525    v1 = Color(10, 20, 30)
7526    v2 = Color(30, 40, 50)
7527
7528    assert v1 + v2 == Color(40, 60, 80)
7529    assert v2 + v1 == v1 + v2
7530    assert v1 + 1 == Color(11, 21, 31)
7531    assert 1 + v1 == v1 + 1
7532
7533    # (with the switch to python2, we now allow ops between colors and tuples)
7534    assert v1 + (1, 2, 3) == Color(11, 22, 33)
7535    assert (1, 2, 3) + v1 == v1 + (1, 2, 3)
7536
7537    # Subtraction and negation.
7538
7539    v1 = Color(10, 20, 30)
7540    v2 = Color(30, 40, 50)
7541
7542    assert v2 - v1 == Color(20, 20, 20)
7543    assert v1 - 1 == Color(9, 19, 29)
7544    assert 1 - v1 == - (v1 - 1)
7545
7546    # (with the switch to python2, we now allow ops between colors and tuples)
7547    assert v1 - (1, 2, 3) == Color(9, 18, 27)
7548    assert (1, 2, 3) - v1 == - (v1 - (1, 2, 3))
7549
7550    assert v1.negate() == Color(-10, -20, -30)
7551
7552    # Multiplication.
7553
7554    v1 = Color(1, 2, 3)
7555    v2 = Color(3, 4, 5)
7556
7557    assert v1 * v2 == Color(3, 8, 15)
7558    assert v2 * v1 == v1 * v2
7559    assert 2 * v1 == Color(2, 4, 6)
7560    assert v1 * 2 == 2 * v1
7561
7562    # (with the switch to python2, we now allow ops between colors and tuples)
7563    assert v1 * (1, 2, 3) == Color(1, 4, 9)
7564    assert (1, 2, 3) * v1 == v1 * (1, 2, 3)
7565
7566    # Division.
7567
7568    v1 = Color(10, 20, 40)
7569    v2 = Color(2, 4, 8)
7570
7571    assert v1 / v2 == Color(10/2, 20/4, 40/8)
7572    assert v1 / 2 == Color(10/2, 20/2, 40/2)
7573    assert Color(40) / v1 == Color(40/10, 40/20, 40/40)
7574
7575    # (with the switch to python2, we now allow ops between colors and tuples)
7576    assert v1 / (1, 4, 20) == Color(10/1, 20/4, 40/20)
7577    assert Color(20, 60, 160) / v1 == Color(20/10, 60/20, 160/40)
7578
7579    # Color space conversion.
7580
7581    c1 = Color(maxComp, 0, 0)
7582
7583    c2 = c1.rgb2hsv()
7584    assert c2[0] == 0 and c2[1] == maxComp and c2[2] == maxComp
7585
7586    c3 = c2.hsv2rgb()
7587    assert c3[0] == maxComp and c3[1] == 0 and c3[2] == 0
7588
7589    print ("ok")
7590
7591    return
7592
7593def testColor3 ():
7594
7595    print ("Color3f")
7596    testColor3x (Color3f, 1.0)
7597    print ("Color3c")
7598    testColor3x (Color3c, 255)
7599
7600testList.append (('testColor3',testColor3))
7601
7602
7603# -------------------------------------------------------------------------
7604# Tests for Color4x
7605
7606def testColor4x (Color, maxComp):
7607
7608    # Constructors (and element access).
7609
7610    v = Color()
7611    assert v[0] == 0 and v[1] == 0 and v[2] == 0 and v[3] == 0
7612
7613    v = Color(1)
7614    assert v[0] == 1 and v[1] == 1 and v[2] == 1 and v[3] == 1
7615
7616    v = Color(0, 1, 2, 3)
7617    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
7618
7619    v = Color((0, 1, 2, 3))
7620    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
7621
7622    v = Color([0, 1, 2, 3])
7623    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
7624
7625    v = Color()
7626    v.setValue(0, 1, 2, 3)
7627    assert v[0] == 0 and v[1] == 1 and v[2] == 2 and v[3] == 3
7628
7629    # Repr.
7630
7631    v = Color(1/9., 2/9., 3/9., 4/9.)
7632    assert v == eval(repr(v))
7633
7634    # Sequence length.
7635
7636    v = Color()
7637    assert len(v) == 4
7638
7639    # Element setting.
7640
7641    v = Color()
7642    v[0] = 10
7643    v[1] = 11
7644    v[2] = 12
7645    v[3] = 13
7646    assert v[0] == 10 and v[1] == 11 and v[2] == 12 and v[3] == 13
7647
7648    try:
7649        v[-5] = 0           # This should raise an exception.
7650    except:
7651        pass
7652    else:
7653        assert 0           # We shouldn't get here.
7654
7655    try:
7656        v[4] = 0           # This should raise an exception.
7657    except:
7658        pass
7659    else:
7660        assert 0           # We shouldn't get here.
7661
7662    try:
7663        v[1] = "a"           # This should raise an exception.
7664    except:
7665        pass
7666    else:
7667        assert 0           # We shouldn't get here.
7668
7669    # Assignment.
7670
7671    v1 = Color(1)
7672
7673    v2 = v1
7674    assert v2[0] == 1 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
7675    v1[0] = 2
7676    assert v2[0] == 2 and v2[1] == 1 and v2[2] == 1 and v2[3] == 1
7677
7678    # Comparison operators.
7679
7680    v1 = Color(20, 20, 0, 0)
7681    v2 = Color(20, 20, 0, 0)
7682    v3 = Color(20, 21, 0, 0)
7683
7684    assert v1 == v2
7685    assert v1 != v3
7686    assert not (v1 < v2)
7687    assert v1 < v3
7688    assert v1 <= v2
7689    assert v1 <= v3
7690    assert not (v3 <= v1)
7691    assert not (v2 > v1)
7692    assert v3 > v1
7693    assert v2 >= v1
7694    assert v3 >= v1
7695    assert not (v1 >= v3)
7696
7697    # Addition.
7698
7699    v1 = Color(10, 20, 30, 0)
7700    v2 = Color(30, 40, 50, 0)
7701
7702    assert v1 + v2 == Color(40, 60, 80, 0)
7703    assert v2 + v1 == v1 + v2
7704    assert v1 + 1 == Color(11, 21, 31, 1)
7705    assert 1 + v1 == v1 + 1
7706
7707    # (with the switch to python2, we now allow ops between colors and tuples)
7708    assert v1 + (1, 2, 3, 4) == Color(11, 22, 33, 4)
7709    assert (1, 2, 3, 4) + v1 == v1 + (1, 2, 3, 4)
7710
7711    # Subtraction and negation.
7712
7713    v1 = Color(10, 20, 30, 0)
7714    v2 = Color(30, 40, 50, 0)
7715
7716    assert v2 - v1 == Color(20, 20, 20, 0)
7717    assert v1 - 1 == Color(9, 19, 29, -1)
7718    assert 1 - v1 == - (v1 - 1)
7719
7720    # (with the switch to python2, we now allow ops between colors and tuples)
7721    assert v1 - (1, 2, 3, 4) == Color(9, 18, 27, -4)
7722    assert (1, 2, 3, 4) - v1 == - (v1 - (1, 2, 3, 4))
7723
7724    assert v1.negate() == Color(-10, -20, -30, 0)
7725
7726    # Multiplication.
7727
7728    v1 = Color(1, 2, 3, 0)
7729    v2 = Color(3, 4, 5, 0)
7730
7731    assert v1 * v2 == Color(3, 8, 15, 0)
7732    assert v2 * v1 == v1 * v2
7733    assert 2 * v1 == Color(2, 4, 6, 0)
7734    assert v1 * 2 == 2 * v1
7735
7736    # (with the switch to python2, we now allow ops between colors and tuples)
7737    assert v1 * (1, 2, 3, 4) == Color(1, 4, 9, 0)
7738    assert (1, 2, 3, 4) * v1 == v1 * (1, 2, 3, 4)
7739
7740    # Division.
7741
7742    v1 = Color(10, 20, 40, 40)
7743    v2 = Color(2, 4, 8, 8)
7744
7745    assert v1 / v2 == Color(10/2, 20/4, 40/8, 40/8)
7746    assert v1 / 2 == Color(10/2, 20/2, 40/2, 40/2)
7747    assert Color(40) / v1 == Color(40/10, 40/20, 40/40, 40/40)
7748
7749    # (with the switch to python2, we now allow ops between colors and tuples)
7750    assert v1 / (1, 4, 8, 20) == Color(10/1, 20/4, 40/8, 40/20)
7751    assert Color(20, 60, 160, 40) / v1 == Color(20/10, 60/20, 160/40, 40/40)
7752
7753    # Color space conversion.
7754
7755    c1 = Color(maxComp, 0, 0, 0)
7756
7757    c2 = c1.rgb2hsv()
7758    assert c2[0] == 0 and c2[1] == maxComp and c2[2] == maxComp and c2[3] == 0
7759
7760    c3 = c2.hsv2rgb()
7761    assert c3[0] == maxComp and c3[1] == 0 and c3[2] == 0 and c3[3] == 0
7762
7763    print ("ok")
7764
7765    return
7766
7767def testColor4 ():
7768
7769    print ("Color4f")
7770    testColor4x (Color4f, 1.0)
7771    print ("Color4c")
7772    testColor4x (Color4c, 255)
7773
7774testList.append (('testColor4',testColor4))
7775
7776
7777# -------------------------------------------------------------------------
7778# Tests for Color --> Color conversions
7779
7780def testColor3xConversions (Color):
7781
7782    v1 = Color(0, 1, 2)
7783
7784    v2 = Color3c (v1)
7785    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2
7786
7787    v2 = Color3f (v1)
7788    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2
7789
7790    print ("ok")
7791    return
7792
7793
7794def testColor4xConversions (Color):
7795
7796    v1 = Color(0, 1, 2, 3)
7797
7798    v2 = Color4c (v1)
7799    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2 and v2[3] == 3
7800
7801    v2 = Color4f (v1)
7802    assert v2[0] == 0 and v2[1] == 1 and v2[2] == 2 and v2[3] == 3
7803
7804    print ("ok")
7805    return
7806
7807
7808def testColor3xColor4xConversion (ColorA, ColorB):
7809
7810    try:
7811        v = ColorA ();
7812        v1 = ColorB (v);   # This should raise an exception.
7813    except:
7814        pass
7815    else:
7816        assert 0           # We shouldn't get here.
7817
7818
7819def testColorConversions ():
7820
7821    print ("Color3c")
7822    testColor3xConversions (Color3c)
7823    print ("Color3f")
7824    testColor3xConversions (Color3f)
7825    print ("V3i")
7826    testColor3xConversions (V3i)
7827    print ("V3f")
7828    testColor3xConversions (V3f)
7829    print ("V3d")
7830    testColor3xConversions (V3d)
7831
7832    print ("Color4c")
7833    testColor4xConversions (Color4c)
7834    print ("Color4f")
7835    testColor4xConversions (Color4f)
7836
7837    print ("invalid conversions")
7838    # Deliberatly not exhaustive, just representative.
7839    testColor3xColor4xConversion (Color3c, Color4f)
7840    testColor3xColor4xConversion (Color4c, Color3f)
7841
7842    print ("ok")
7843    return
7844
7845
7846testList.append (('testColorConversions',testColorConversions))
7847
7848
7849# -------------------------------------------------------------------------
7850# Tests for Frustumx
7851
7852def testFrustumx (Frustum, Vec3, Mat):
7853
7854    # Constructors (and accessors).
7855
7856    f = Frustum()
7857
7858    nearPlane = 1
7859    farPlane = 1000
7860    left = -2
7861    right = 2
7862    top = 2
7863    bottom = -2
7864    ortho = 1
7865
7866    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7867    assert f.nearPlane() == nearPlane and f.farPlane() == farPlane and \
7868           f.left() == left and f.right() == right and \
7869           f.bottom() == bottom and f.top() == top and \
7870           f.orthographic() == ortho
7871
7872    # Repr.
7873
7874    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7875    assert f.nearPlane() == nearPlane and f.farPlane() == farPlane and \
7876           f.left() == left and f.right() == right and \
7877           f.bottom() == bottom and f.top() == top and \
7878           f.orthographic() == ortho
7879    assert f.near() == nearPlane and f.far() == farPlane
7880
7881    # Assignment.
7882
7883    f1 = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7884
7885    f2 = f1
7886    assert f2.nearPlane() == f1.nearPlane() and f2.farPlane() == f1.farPlane() and \
7887           f2.left() == f1.left() and f2.right() == f2.right() and \
7888           f2.bottom() == f1.bottom() and f2.top() == f1.top() and \
7889           f2.orthographic() == f1.orthographic()
7890    assert f2.near() == f1.nearPlane() and f2.far() == f1.farPlane()
7891
7892    # Planes.
7893
7894    nearPlane = 1
7895    farPlane = 2
7896    left = -1
7897    right = 1
7898    top = 1
7899    bottom = -1
7900    ortho = 0
7901    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7902
7903    p1 = f.planes();
7904
7905    topN    = Vec3( 0, 1, 1).normalized()
7906    rightN  = Vec3( 1, 0, 1).normalized()
7907    bottomN = Vec3( 0,-1, 1).normalized()
7908    leftN   = Vec3(-1, 0, 1).normalized()
7909    nearPlaneN   = Vec3( 0, 0, 1)
7910    farPlaneN    = Vec3( 0, 0,-1)
7911    assert p1[0].normal() == topN and p1[0].distance() == 0
7912    assert p1[1].normal() == rightN and p1[1].distance() == 0
7913    assert p1[2].normal() == bottomN and p1[2].distance() == 0
7914    assert p1[3].normal() == leftN and p1[3].distance() == 0
7915    assert p1[4].normal() == nearPlaneN and p1[4].distance() == -nearPlane
7916    assert p1[5].normal() == farPlaneN and p1[5].distance() == farPlane
7917
7918    m = Mat()
7919    m.rotationMatrix(Vec3(0, 0,-1), (-1, 0, 0))
7920    p2 = f.planes(m)
7921
7922    topN    = Vec3( 1, 1, 0).normalized()
7923    rightN  = Vec3( 1, 0,-1).normalized()
7924    bottomN = Vec3( 1,-1, 0).normalized()
7925    leftN   = Vec3( 1, 0, 1).normalized()
7926    nearPlaneN   = Vec3( 1, 0, 0)
7927    farPlaneN    = Vec3(-1, 0, 0)
7928    assert p2[0].normal().equalWithAbsError(topN, topN.baseTypeEpsilon())
7929    assert p2[0].distance() == 0
7930    assert p2[1].normal().equalWithAbsError(rightN, rightN.baseTypeEpsilon())
7931    assert p2[1].distance() == 0
7932    assert p2[2].normal().equalWithAbsError(bottomN, bottomN.baseTypeEpsilon())
7933    assert p2[2].distance() == 0
7934    assert p2[3].normal().equalWithAbsError(leftN, leftN.baseTypeEpsilon())
7935    assert p2[3].distance() == 0
7936    assert p2[4].normal().equalWithAbsError(nearPlaneN, nearPlaneN.baseTypeEpsilon())
7937    assert equal(p2[4].distance(), -nearPlane, 2 * nearPlaneN.baseTypeEpsilon())
7938    assert p2[5].normal().equalWithAbsError(farPlaneN, farPlaneN.baseTypeEpsilon())
7939    assert equal(p2[5].distance(), farPlane, 2 * farPlaneN.baseTypeEpsilon())
7940
7941    # Fovy, aspect, projection matrix.
7942
7943    nearPlane = 1
7944    farPlane = 2
7945    left = -1
7946    right = 1
7947    top = 1
7948    bottom = -1
7949    ortho = 0
7950    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7951
7952    assert equal(f.fovx(), pi / 2.0, Vec3().baseTypeEpsilon())
7953    assert equal(f.aspect(), 1, Vec3().baseTypeEpsilon())
7954
7955    m = f.projectionMatrix()
7956    C = -(farPlane + nearPlane) / (farPlane - nearPlane)
7957    D = (-2 * farPlane * nearPlane) / (farPlane - nearPlane)
7958    E = 2 * nearPlane / (right - left)
7959    F = 2 * nearPlane / (top - bottom)
7960    assert m[0][0] == E
7961    assert m[1][1] == F
7962    assert m[2][2] == C
7963    assert m[3][2] == D
7964
7965    # Window.
7966
7967    nearPlane = 2
7968    farPlane = 4
7969    left = -2
7970    right = 2
7971    top = 2
7972    bottom = -2
7973    ortho = 0
7974    f1 = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7975
7976    left2 = -0.5
7977    right2 = 0.5
7978    top2 = 0.25
7979    bottom2 = -0.25
7980    f2 = f1.window(left2, right2, top2, bottom2)
7981    assert f2.left() == -1 and f2.right() == 1
7982    assert f2.top() == 0.5 and f2.bottom() == -0.5
7983
7984    # Project screen to ray, point to screen.
7985
7986    nearPlane = 1
7987    farPlane = 2
7988    left = -1
7989    right = 1
7990    top = 1
7991    bottom = -1
7992    ortho = 0
7993    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
7994
7995    s = 0.5
7996    t = 0.5
7997    l = f.projectScreenToRay((s, t))
7998
7999    p3d = Vec3(left + (right - left) * (1 + s) / 2.0,
8000             bottom + (top - bottom) * (1 + t) / 2.0, -nearPlane)
8001    assert iszero(l.distanceTo(p3d), 2 * p3d.baseTypeEpsilon())
8002
8003    p2d = f.projectPointToScreen(p3d)
8004    assert p2d.equalWithAbsError((s, t), p2d.baseTypeEpsilon())
8005
8006    p3df = V3f (p3d)
8007    p2d = f.projectPointToScreen(p3df)
8008    assert p2d.equalWithAbsError((s, t), p2d.baseTypeEpsilon())
8009
8010    p3dd = V3d (p3d)
8011    p2d = f.projectPointToScreen(p3dd)
8012    assert p2d.equalWithAbsError((s, t), p2d.baseTypeEpsilon())
8013
8014    # Conversion between depth and Z.
8015
8016    f = Frustum()
8017    zMin = 1
8018    zMax = 100
8019
8020    assert round(f.ZToDepth(zMin, zMin, zMax)) == round(-f.nearPlane())
8021    assert round(f.ZToDepth(zMax, zMin, zMax)) == round(-f.farPlane())
8022    assert (f.near() == f.nearPlane())
8023    assert (f.far() == f.farPlane())
8024
8025    assert round(f.normalizedZToDepth(-1)) == round(-f.nearPlane())
8026    assert round(f.normalizedZToDepth(1)) == round(-f.farPlane())
8027
8028    assert f.DepthToZ(-f.nearPlane(), zMin, zMax) == zMin
8029    assert f.DepthToZ(-f.farPlane(), zMin, zMax) == zMax
8030
8031    # Screen and world radius conversion.
8032
8033    nearPlane = 1
8034    farPlane = 10
8035    left = -1
8036    right = 1
8037    top = 1
8038    bottom = -1
8039    ortho = 0
8040    f = Frustum(nearPlane, farPlane, left, right, top, bottom, ortho)
8041
8042    d = 4
8043    s = 0.75
8044    r1 = f.screenRadius((0, 0, -d), d * s)
8045    assert equal(r1, s, Vec3().baseTypeEpsilon())
8046
8047    r2 = f.worldRadius((0, 0, -d), r1)
8048    assert equal(r2, d * s, Vec3().baseTypeEpsilon())
8049
8050    print ("ok")
8051
8052    return
8053
8054def testFrustum ():
8055
8056    print ("Frustumf")
8057    testFrustumx (Frustumf, V3f, M44f)
8058
8059testList.append (('testFrustum',testFrustum))
8060
8061
8062# -------------------------------------------------------------------------
8063# Tests for random number generators
8064
8065def testRandomCompare (r1a, r1b, r1c, r2):
8066    n = 10
8067    nMatch1a1b = 0
8068    nMatch1a1c = 0
8069    nMatch1a2 = 0
8070    for i in range(n):
8071        a = r1a()
8072        b = r1b()
8073        c = r1c()
8074        d = r2()
8075        if (a == b): nMatch1a1b = nMatch1a1b + 1
8076        if (a == c): nMatch1a1c = nMatch1a1c + 1
8077        if (a == d): nMatch1a2 = nMatch1a2 + 1
8078    assert nMatch1a1b == n
8079    assert nMatch1a1c == n
8080    assert nMatch1a2 < n
8081
8082def testRandomCompareSphere (r1a, r1b, r1c, r2, type):
8083    n = 10
8084    nMatch1a1b = 0
8085    nMatch1a1c = 0
8086    nMatch1a2 = 0
8087    for i in range(n):
8088        a = r1a(type)
8089        b = r1b(type)
8090        c = r1c(type)
8091        d = r2(type)
8092        if (a == b): nMatch1a1b = nMatch1a1b + 1
8093        if (a == c): nMatch1a1c = nMatch1a1c + 1
8094        if (a == d): nMatch1a2 = nMatch1a2 + 1
8095    assert nMatch1a1b == n
8096    assert nMatch1a1c == n
8097    assert nMatch1a2 < n
8098
8099def testRandomx (Rand):
8100
8101    # Same/different seeds produces same/different sequences.
8102
8103    r1a = Rand(1)
8104    r1b = Rand(1)
8105    r1c = Rand(r1a)
8106    r2 = Rand(2)
8107
8108    testRandomCompare(r1a.nextb, r1b.nextb, r1c.nextb, r2.nextb)
8109    testRandomCompare(r1a.nexti, r1b.nexti, r1c.nexti, r2.nexti)
8110    testRandomCompare(r1a.nextf, r1b.nextf, r1c.nextf, r2.nextf)
8111    testRandomCompareSphere(r1a.nextSolidSphere, r1b.nextSolidSphere, \
8112                            r1c.nextSolidSphere, r2.nextSolidSphere, V2f())
8113    testRandomCompareSphere(r1a.nextSolidSphere, r1b.nextSolidSphere, \
8114                            r1c.nextSolidSphere, r2.nextSolidSphere, V2d())
8115    testRandomCompareSphere(r1a.nextSolidSphere, r1b.nextSolidSphere, \
8116                            r1c.nextSolidSphere, r2.nextSolidSphere, V3f())
8117    testRandomCompareSphere(r1a.nextSolidSphere, r1b.nextSolidSphere, \
8118                            r1c.nextSolidSphere, r2.nextSolidSphere, V3f())
8119    testRandomCompareSphere(r1a.nextHollowSphere, r1b.nextHollowSphere, \
8120                            r1c.nextHollowSphere, r2.nextHollowSphere, V2f())
8121    testRandomCompareSphere(r1a.nextHollowSphere, r1b.nextHollowSphere, \
8122                            r1c.nextHollowSphere, r2.nextHollowSphere, V2d())
8123    testRandomCompareSphere(r1a.nextHollowSphere, r1b.nextHollowSphere, \
8124                            r1c.nextHollowSphere, r2.nextHollowSphere, V3f())
8125    testRandomCompareSphere(r1a.nextHollowSphere, r1b.nextHollowSphere, \
8126                            r1c.nextHollowSphere, r2.nextHollowSphere, V3f())
8127    testRandomCompare(r1a.nextGauss, r1b.nextGauss, r1c.nextGauss, \
8128                      r2.nextGauss)
8129    testRandomCompareSphere(r1a.nextGaussSphere, r1b.nextGaussSphere, \
8130                            r1c.nextGaussSphere, r2.nextGaussSphere, V2f())
8131    testRandomCompareSphere(r1a.nextGaussSphere, r1b.nextGaussSphere, \
8132                            r1c.nextGaussSphere, r2.nextGaussSphere, V2d())
8133    testRandomCompareSphere(r1a.nextGaussSphere, r1b.nextGaussSphere, \
8134                            r1c.nextGaussSphere, r2.nextGaussSphere, V3f())
8135    testRandomCompareSphere(r1a.nextGaussSphere, r1b.nextGaussSphere, \
8136                            r1c.nextGaussSphere, r2.nextGaussSphere, V3f())
8137
8138    # Init (if it works for one type, it should work for all).
8139
8140    r = Rand(10)
8141    seq = []
8142    n = 10
8143    for i in range(n):
8144        seq.append(r.nextb())
8145    r.init(10)
8146    for i in range(n):
8147        assert r.nextb() == seq[i]
8148
8149    print ("ok")
8150
8151    return
8152
8153def testRandom ():
8154
8155    print ("Rand32")
8156    testRandomx (Rand32)
8157    print ("Rand48")
8158    testRandomx (Rand48)
8159
8160testList.append (('testRandom',testRandom))
8161
8162# -------------------------------------------------------------------------
8163# Tests C4xArrays
8164def testC4xArray(Array, Color, Arrayx):
8165    a = Array (3)
8166
8167    a[0] = Color(0)
8168    a[1] = Color(1)
8169    a[2] = Color(2)
8170
8171    assert a[0] == Color(0)
8172    assert a[1] == Color(1)
8173    assert a[2] == Color(2)
8174
8175    # Element setting.
8176
8177    a = Array(2)
8178
8179    try:
8180        a[-3] = Color(0) # This should raise an exception.
8181    except:
8182        pass
8183    else:
8184        assert 0            # We shouldn't get here.
8185
8186    try:
8187        a[3] = Color(0)   # This should raise an exception.
8188    except:
8189        pass
8190    else:
8191        assert 0           # We shouldn't get here.
8192
8193    try:
8194        a[1] = "a"         # This should raise an exception.
8195    except:
8196        pass
8197    else:
8198        assert 0           # We shouldn't get here.
8199
8200    # Assignment.
8201
8202    a = Array(2)
8203    a[0] = Color(0)
8204    a[1] = Color(1)
8205
8206    # Array Component access
8207
8208    ar = Arrayx(2)
8209    ag = Arrayx(2)
8210    ab = Arrayx(2)
8211    aa = Arrayx(2)
8212    ar[:] = a.r
8213    ag[:] = a.g
8214    ab[:] = a.b
8215    aa[:] = a.a
8216
8217    assert ar == a.r
8218    assert ag == a.g
8219    assert ab == a.b
8220    assert aa == a.a
8221
8222    a.r[0] = 1
8223    assert ar != a.r
8224
8225def testC4Array ():
8226    print ("C4fArray")
8227    testC4xArray (C4fArray, Color4f, FloatArray)
8228    print ("C4cArray")
8229    testC4xArray (C4cArray, Color4c, UnsignedCharArray)
8230
8231testList.append (('testC4Array',testC4Array))
8232
8233# -------------------------------------------------------------------------
8234# Tests C3xArrays
8235def testC3xArray(Array, Color, Arrayx):
8236    a = Array (3)
8237
8238    a[0] = Color(0)
8239    a[1] = Color(1)
8240    a[2] = Color(2)
8241
8242    assert a[0] == Color(0)
8243    assert a[1] == Color(1)
8244    assert a[2] == Color(2)
8245
8246    # Element setting.
8247
8248    a = Array(2)
8249
8250    try:
8251        a[-3] = Color(0) # This should raise an exception.
8252    except:
8253        pass
8254    else:
8255        assert 0         # We shouldn't get here.
8256
8257    try:
8258        a[3] = Color(0)   # This should raise an exception.
8259    except:
8260        pass
8261    else:
8262        assert 0        # We shouldn't get here.
8263
8264    try:
8265        a[1] = "a"      # This should raise an exception.
8266    except:
8267        pass
8268    else:
8269        assert 0        # We shouldn't get here.
8270
8271    # Assignment.
8272
8273    a = Array(2)
8274    a[0] = Color(0)
8275    a[1] = Color(1)
8276
8277    # Array Component access
8278
8279    ar = Arrayx(2)
8280    ag = Arrayx(2)
8281    ab = Arrayx(2)
8282    ar[:] = a.r
8283    ag[:] = a.g
8284    ab[:] = a.b
8285
8286    assert ar == a.r
8287    assert ag == a.g
8288    assert ab == a.b
8289
8290    a.r[0] = 1
8291    assert ar != a.r
8292
8293def testC3xExplicitConversion(Array):
8294
8295     # explicit constructors from Vec3 types
8296    af = V3fArray(3)
8297    af[0] = V3f(0)
8298    af[1] = V3f(1)
8299    af[2] = V3f(2)
8300    a = Array(af);
8301    assert af[0] == V3f(a[0])
8302    assert af[1] == V3f(a[1])
8303    assert af[2] == V3f(a[2])
8304
8305    ad = V3dArray(3)
8306    ad[0] = V3d(0)
8307    ad[1] = V3d(1)
8308    ad[2] = V3d(2)
8309    a = Array(ad);
8310    assert ad[0] == V3d(a[0])
8311    assert ad[1] == V3d(a[1])
8312    assert ad[2] == V3d(a[2])
8313
8314def testC3Array ():
8315    print ("C3fArray")
8316    testC3xArray (C3fArray, Color3f, FloatArray)
8317    testC3xExplicitConversion(C3fArray)
8318    print ("C3cArray")
8319    testC3xArray (C3cArray, Color3c, UnsignedCharArray)
8320
8321testList.append (('testC3Array',testC3Array))
8322
8323# -------------------------------------------------------------------------
8324# Verify that floating-point exceptions, both in Imath and in Python,
8325# raise Python exceptions rather than causing crashes.
8326
8327def testFpExceptions():
8328
8329    try:
8330        f = sqrt (-1)
8331        print (f)
8332    except ValueError:
8333        pass
8334    except OverflowError:
8335        pass
8336    else:
8337        assert 0
8338
8339    try:
8340        f = sqrt (-1)
8341        print (f)
8342    except ValueError:
8343        pass
8344    except OverflowError:
8345        pass
8346    else:
8347        assert 0
8348
8349    try:
8350        f = 1 / 0
8351        print (f)
8352    except ZeroDivisionError:
8353        pass
8354    else:
8355        assert 0
8356
8357    print ("ok")
8358    return
8359
8360testList.append (('testFpExceptions',testFpExceptions))
8361
8362def testProcrustes():
8363    m = M44d()
8364    m.translate (V3d(10, 5, 0))
8365
8366    r = Eulerd (pi, pi/4.0, 0)
8367    m = m * r.toMatrix44()
8368
8369    n = 8
8370    f = []
8371    t = []
8372    w = []
8373    for i in range (n):
8374        theta = 2.0 * pi * float(i)/float(n)
8375        fromVec = V3d(cos(theta), sin(theta), 0)
8376        w.append (1)
8377        f.append (fromVec)
8378        t.append (fromVec * m)
8379
8380    result = procrustesRotationAndTranslation (f, t, None, False)
8381    for i in range(n):
8382        res = f[i] * result
8383        assert ((res - t[i]).length2() < 1e-5)
8384
8385    # Test it with arrays:
8386    r = Rand48(145)
8387    f1 = V3dArray (n)
8388    t1 = V3dArray (n)
8389    for i in range(n):
8390        fromVec = V3d (r.nextf(), r.nextf(), r.nextf())
8391        f1[i] = fromVec
8392        t1[i] = fromVec * m
8393    result = procrustesRotationAndTranslation (f1, t1, None, False)
8394    for i in range(n):
8395        res = f1[i] * result
8396        assert ((res - t1[i]).length2() < 1e-5)
8397
8398    # Verify weights:
8399    f.append (V3d(0,0,0))
8400    t.append (V3d(10000,10000,100))
8401    w.append (0.0)
8402    result = procrustesRotationAndTranslation (f, t, w, False)
8403    for i in range(n):
8404        res = f[i] * result
8405        assert ((res - t[i]).length2() < 1e-5)
8406
8407testList.append (('testProcrustes',testProcrustes))
8408
8409def testSVD():
8410    # We'll just test the Python wrapper here; for comprehensive SVD tests,
8411    # please see ImathToolboxTest.
8412    # 4x4
8413    m = M44d()
8414    [U, S, V] = m.singularValueDecomposition(False)
8415
8416    eps = 1e-4
8417    def sameMatrix44 (m1, m2):
8418        for i in range(4):
8419            for j in range(4):
8420                if (abs(m1[i][j] - m2[i][j]) > eps):
8421                    return False
8422        return True
8423
8424    def sameVector4 (v1, v2):
8425        for i in range(4):
8426            if (abs(v1[i] - v2[i]) > eps):
8427                return False
8428        return True
8429
8430    assert (sameMatrix44(U, M44d()));
8431    assert (sameMatrix44(V, M44d()));
8432    assert (sameVector4(S, V4d(1,1,1,1)))
8433
8434    def checkSVD44(m):
8435        [U, S, V] = m.singularValueDecomposition(True)
8436        assert (sameMatrix44(U*U.transposed(), M44d()))
8437        assert (sameMatrix44(V*V.transposed(), M44d()))
8438        for i in range(3):
8439            assert S[i] >= 0
8440
8441        assert (U.determinant() > 0)
8442        assert (V.determinant() > 0)
8443
8444        sDiag = M44d()
8445        for i in range(4):
8446            sDiag[i][i] = S[i]
8447        assert (sameMatrix44(U*sDiag*V.transposed(), m))
8448
8449        [U2, S2, V2] = m.singularValueDecomposition(False)
8450        for i in range(4):
8451            assert (S2[i] >= 0)
8452        for i in range(3):
8453            assert (abs(S[i] - S2[i]) < eps)
8454        assert (abs(abs(S[3]) - S2[3]) < eps)
8455
8456    scaleMatrix = M44d()
8457    scaleMatrix.setScale (V3d(1, 2, 3))
8458    m = m * scaleMatrix
8459    checkSVD44(m)
8460
8461    e = Eulerd (20, 30, 40)
8462    m = m * e.toMatrix44()
8463    checkSVD44(m)
8464
8465    scaleMatrix.setScale (V3d(-3, 2, 3))
8466    m = m * e.toMatrix44()
8467    checkSVD44(m)
8468
8469    # 3x3
8470    m = M33d()
8471    [U, S, V] = m.singularValueDecomposition(False)
8472
8473    eps = 1e-4
8474    def sameMatrix33 (m1, m2):
8475        for i in range(3):
8476            for j in range(3):
8477                if (abs(m1[i][j] - m2[i][j]) > eps):
8478                    return False
8479        return True
8480
8481    def sameVector3 (v1, v2):
8482        for i in range(3):
8483            if (abs(v1[i] - v2[i]) > eps):
8484                return False
8485        return True
8486
8487    assert (sameMatrix33(U, M33d()));
8488    assert (sameMatrix33(V, M33d()));
8489    assert (sameVector3(S, V3d(1,1,1)))
8490
8491    def checkSVD33(m):
8492        [U, S, V] = m.singularValueDecomposition(True)
8493        assert (sameMatrix33(U*U.transposed(), M33d()))
8494        assert (sameMatrix33(V*V.transposed(), M33d()))
8495        for i in range(3):
8496            assert S[i] >= 0
8497
8498        assert (U.determinant() > 0)
8499        assert (V.determinant() > 0)
8500
8501        sDiag = M33d()
8502        for i in range(3):
8503            sDiag[i][i] = S[i]
8504        assert (sameMatrix33(U*sDiag*V.transposed(), m))
8505
8506        [U2, S2, V2] = m.singularValueDecomposition(False)
8507        for i in range(2):
8508            assert (S2[i] >= 0)
8509        for i in range(2):
8510            assert (abs(S[i] - S2[i]) < eps)
8511        assert (abs(abs(S[2]) - S2[2]) < eps)
8512
8513    scaleMatrix = M33d (1, 0, 0, 0, 2, 0, 0, 0, 3)
8514    m = m * scaleMatrix
8515    checkSVD33(m)
8516
8517    e = Eulerd (20, 30, 40)
8518    m = m * e.toMatrix33()
8519    checkSVD33(m)
8520
8521    scaleMatrix = M33d (-3, 0, 0, 0, 2, 0, 0, 0, 3)
8522    m = m * e.toMatrix33()
8523    checkSVD33(m)
8524
8525testList.append (('testSVD',testSVD))
8526
8527def testSymmetricEigensolve():
8528    # We'll just test the Python wrapper here; for comprehensive eigensolver tests,
8529    # please see ImathToolboxTest.
8530    # 4x4
8531
8532    eps = 1e-4
8533    def sameMatrix44 (m1, m2):
8534        for i in range(4):
8535            for j in range(4):
8536                if (abs(m1[i][j] - m2[i][j]) > eps):
8537                    return False
8538        return True
8539
8540    def sameVector4 (v1, v2):
8541        for i in range(4):
8542            if (abs(v1[i] - v2[i]) > eps):
8543                return False
8544        return True
8545
8546    m = M44d()
8547    [Q, S] = m.symmetricEigensolve()
8548    assert (sameMatrix44 (Q, M44d()))
8549    assert (sameVector4 (S, V4d(1,1,1,1)))
8550
8551    m = M44d(2, 4, 3,  6,
8552             4, 1, 9,  7,
8553             3, 9, 10, 13,
8554             6, 7, 13, 27);
8555    [Q, S] = m.symmetricEigensolve()
8556    assert (sameMatrix44(Q*Q.transposed(), M44d()))
8557
8558    sDiag = M44d()
8559    for i in range(4):
8560        sDiag[i][i] = S[i]
8561    assert (sameMatrix44 (Q * sDiag * Q.transposed(), m))
8562
8563    # Verify that it checks for symmetry:
8564    m[2][3] = 1000
8565    try:
8566        m.symmetricEigensolve()
8567    except ValueError:
8568        pass
8569    else:
8570        assert 0
8571
8572    def sameMatrix33 (m1, m2):
8573        for i in range(3):
8574            for j in range(3):
8575                if (abs(m1[i][j] - m2[i][j]) > eps):
8576                    return False
8577        return True
8578
8579    def sameVector3 (v1, v2):
8580        for i in range(3):
8581            if (abs(v1[i] - v2[i]) > eps):
8582                return False
8583        return True
8584
8585    m = M33d()
8586    [Q, S] = m.symmetricEigensolve()
8587    assert (sameMatrix33 (Q, M33d()))
8588    assert (sameVector3 (S, V3d(1,1,1)))
8589
8590    m = M33d(2, 4, 3,
8591             4, 1, 9,
8592             3, 9, 10)
8593    [Q, S] = m.symmetricEigensolve()
8594    assert (sameMatrix33(Q*Q.transposed(), M33d()))
8595
8596    sDiag = M33d()
8597    for i in range(3):
8598        sDiag[i][i] = S[i]
8599    assert (sameMatrix33 (Q * sDiag * Q.transposed(), m))
8600
8601    # Verify that it checks for symmetry:
8602    m[1][2] = 1000
8603    try:
8604        m.symmetricEigensolve()
8605    except ValueError:
8606        pass
8607    else:
8608        assert 0
8609
8610
8611
8612testList.append (('testSymmetricEigensolve',testSymmetricEigensolve))
8613
8614# -------------------------------------------------------------------------
8615# Tests MxArrays
8616def testMxArray(Array, Matrix):
8617    a = Array (3)
8618
8619    a[0] = Matrix(0)
8620    a[1] = Matrix(1)
8621    a[2] = Matrix(2)
8622
8623    assert a[0] == Matrix(0)
8624    assert a[1] == Matrix(1)
8625    assert a[2] == Matrix(2)
8626
8627    # Element setting.
8628
8629    a = Array(2)
8630
8631    try:
8632        a[-3] = Matrix(0) # This should raise an exception.
8633    except:
8634        pass
8635    else:
8636        assert 0            # We shouldn't get here.
8637
8638    try:
8639        a[3] = Matrix(0)   # This should raise an exception.
8640    except:
8641        pass
8642    else:
8643        assert 0           # We shouldn't get here.
8644
8645    try:
8646        a[1] = "a"         # This should raise an exception.
8647    except:
8648        pass
8649    else:
8650        assert 0           # We shouldn't get here.
8651
8652    # Assignment.
8653
8654    a = Array(2)
8655    a[0] = Matrix(0)
8656    a[1] = Matrix(1)
8657
8658    # Comparison.
8659
8660    m = Matrix(2)
8661    a1 = Array(m, 3)
8662    a2 = Array(m, 3)
8663
8664    testVectorVectorComparisonOps(a1, a2)
8665    testVectorScalarComparisonOps(a1, m)
8666
8667def testM4Array(Array, Matrix, Vec, VecArray):
8668
8669    a = Array(3)
8670    m0 = Matrix()
8671    m0.setTranslation (Vec(1,2,3))
8672    m1 = Matrix()
8673    m1.setScale (Vec(.3,.2,.1))
8674    m2 = Matrix()
8675    m2.rotate (Vec(.3,.1,.2))
8676
8677    a[0] = m0
8678    a[1] = m1
8679    a[2] = m2
8680
8681    n = a.inverse()
8682    assert n[0] == m0.inverse()
8683    assert n[1] == m1.inverse()
8684    assert n[2] == m2.inverse()
8685
8686    a.invert()
8687    testVectorVectorComparisonOps(a, n)
8688
8689    n0 = a[0]
8690    n1 = a[2]
8691    n2 = a[2]
8692    a.transpose()
8693    assert n[0].transposed() == a[0]
8694    assert n[1].transposed() == a[1]
8695    assert n[2].transposed() == a[2]
8696
8697    v = VecArray(3)
8698    v[0] = Vec(11,17,3).normalized()
8699    v[1] = Vec(7,19,31).normalized()
8700    v[2] = Vec(23,5,13).normalized()
8701
8702    V = a.multDirMatrix(v)
8703    assert a[0].multDirMatrix(v[0]) == V[0]
8704    assert a[1].multDirMatrix(v[1]) == V[1]
8705    assert a[2].multDirMatrix(v[2]) == V[2]
8706
8707    V = a.multVecMatrix(v)
8708    assert a[0].multVecMatrix(v[0]) == V[0]
8709    assert a[1].multVecMatrix(v[1]) == V[1]
8710    assert a[2].multVecMatrix(v[2]) == V[2]
8711
8712def testMatrixArray ():
8713    print ("M44fArray")
8714    testMxArray (M44fArray, M44f)
8715    testM4Array (M44fArray, M44f, V3f, V3fArray)
8716    print ("M44dArray")
8717    testMxArray (M44dArray, M44d)
8718    testM4Array (M44dArray, M44d, V3d, V3dArray)
8719    print ("M33fArray")
8720    testMxArray (M33fArray, M33f)
8721    print ("M33dArray")
8722    testMxArray (M33dArray, M33d)
8723    print ("M22fArray")
8724    testMxArray (M22fArray, M22f)
8725    print ("M22dArray")
8726    testMxArray (M22dArray, M22d)
8727
8728testList.append(("testMatrixArray",testMatrixArray))
8729
8730# -------------------------------------------------------------------------
8731# Tests BoxxArrays
8732def testBoxxArray(Array, Box, Vec):
8733
8734    b0 = Box(Vec(1), Vec(2))
8735    b1 = Box(Vec(2), Vec(3))
8736    b2 = Box(Vec(3), Vec(4))
8737
8738    a = Array (3)
8739
8740    a[0] = b0
8741    a[1] = b1
8742    a[2] = b2
8743
8744    assert a[0] == b0
8745    assert a[1] == b1
8746    assert a[2] == b2
8747
8748    # Element setting.
8749
8750    a = Array(2)
8751
8752    try:
8753        a[-3] = b0      # This should raise an exception.
8754    except:
8755        pass
8756    else:
8757        assert 0        # We shouldn't get here.
8758
8759    try:
8760        a[3] = b0       # This should raise an exception.
8761    except:
8762        pass
8763    else:
8764        assert 0        # We shouldn't get here.
8765
8766    try:
8767        a[1] = "a"      # This should raise an exception.
8768    except:
8769        pass
8770    else:
8771        assert 0        # We shouldn't get here.
8772
8773    # Assignment.
8774
8775    a = Array(2)
8776    a[0] = b0
8777    a[1] = b1
8778
8779    # Comparison.
8780
8781    a1 = Array(b2, 3)
8782    a2 = Array(b2, 3)
8783
8784    testVectorVectorComparisonOps(a1, a2)
8785    testVectorScalarComparisonOps(a1, b2)
8786
8787def testBoxArray ():
8788    print ("Box2iArray")
8789    testBoxxArray (Box2iArray, Box2i, V2i)
8790    print ("Box2sArray")
8791    testBoxxArray (Box2sArray, Box2s, V2s)
8792    print ("Box2fArray")
8793    testBoxxArray (Box2fArray, Box2f, V2f)
8794    print ("Box2dArray")
8795    testBoxxArray (Box2dArray, Box2d, V2d)
8796    print ("Box3iArray")
8797    testBoxxArray (Box3iArray, Box3i, V3i)
8798    print ("Box3sArray")
8799    testBoxxArray (Box3sArray, Box3s, V3s)
8800    print ("Box3fArray")
8801    testBoxxArray (Box3fArray, Box3f, V3f)
8802    print ("Box3dArray")
8803    testBoxxArray (Box3dArray, Box3d, V3d)
8804
8805testList.append(("testBoxArray",testBoxArray))
8806
8807def testStringArray():
8808
8809    num = 10
8810
8811    s = StringArray(num)
8812    s2 = StringArray(num)
8813
8814    assert((s != '').reduce() == 0)
8815    assert((s == '').reduce() == num)
8816
8817    assert(('' != s).reduce() == 0)
8818    assert(('' == s).reduce() == num)
8819
8820    assert((s != s2).reduce() == 0)
8821    assert((s == s2).reduce() == num)
8822
8823    id = IntArray(num)
8824    id[:] = make_range(0,num)
8825
8826    s = StringArray('foo', num)
8827    s2 = StringArray('a', num)
8828    s2[:] = 'foo'
8829
8830    assert((s != 'foo').reduce() == 0)
8831    assert((s == 'foo').reduce() == num)
8832
8833    assert(('foo' != s).reduce() == 0)
8834    assert(('foo' == s).reduce() == num)
8835    assert((s != s2).reduce() == 0)
8836    assert((s == s2).reduce() == num)
8837
8838    s[id < num//2] = 'bar'
8839
8840    assert((s != 'foo').reduce() == num//2)
8841    assert((s == 'foo').reduce() == num//2)
8842
8843    assert(('foo' != s).reduce() == num//2)
8844    assert(('foo' == s).reduce() == num//2)
8845
8846    assert((s != 'bar').reduce() == num//2)
8847    assert((s == 'bar').reduce() == num//2)
8848
8849    assert(('bar' != s).reduce() == num//2)
8850    assert(('bar' == s).reduce() == num//2)
8851
8852    assert((s != s2).reduce() == num//2)
8853    assert((s == s2).reduce() == num//2)
8854
8855    for i in range(0,num):
8856        s2[i] = str(i)
8857
8858    for i in range(0,num):
8859        assert(int(s2[i]) == i)
8860
8861    print ("should see {0} 'bar' and {1} 'foo'".format (num//2,num//2))
8862    for m in s:
8863        print (m)
8864    print ("should see '0' through '{}'".format(num-1))
8865    for m in s2:
8866        print (m)
8867
8868    print ("ok")
8869
8870testList.append(("testStringArray",testStringArray))
8871
8872
8873def testWstringArray():
8874
8875    num = 10
8876
8877    s = WstringArray(num)
8878    s2 = WstringArray(num)
8879
8880    assert((s != '').reduce() == 0)
8881    assert((s == '').reduce() == num)
8882
8883    assert(('' != s).reduce() == 0)
8884    assert(('' == s).reduce() == num)
8885
8886    assert((s != s2).reduce() == 0)
8887    assert((s == s2).reduce() == num)
8888
8889    id = IntArray(num)
8890    id[:] = make_range(0,num)
8891
8892    s = WstringArray(u'foo', num)
8893    s2 = WstringArray(u'a', num)
8894    s2[:] = u'foo'
8895
8896    assert((s != u'foo').reduce() == 0)
8897    assert((s == u'foo').reduce() == num)
8898
8899    assert((u'foo' != s).reduce() == 0)
8900    assert((u'foo' == s).reduce() == num)
8901    assert((s != s2).reduce() == 0)
8902    assert((s == s2).reduce() == num)
8903
8904    s[id < num//2] = u'bar'
8905
8906    assert((s != u'foo').reduce() == num//2)
8907    assert((s == u'foo').reduce() == num//2)
8908
8909    assert((u'foo' != s).reduce() == num//2)
8910    assert((u'foo' == s).reduce() == num//2)
8911
8912    assert((s != u'bar').reduce() == num//2)
8913    assert((s == u'bar').reduce() == num//2)
8914
8915    assert((u'bar' != s).reduce() == num//2)
8916    assert((u'bar' == s).reduce() == num//2)
8917
8918    assert((s != s2).reduce() == num//2)
8919    assert((s == s2).reduce() == num//2)
8920
8921    for i in range(0,num):
8922        s2[i] = str(i)
8923
8924    for i in range(0,num):
8925        assert(int(s2[i]) == i)
8926
8927    print ("should see {0} 'bar' and {1} 'foo'".format(num//2,num//2))
8928    for m in s:
8929        print (m)
8930    print ("should see '0' through '{}'".format(num-1))
8931    for m in s2:
8932        print (m)
8933
8934    print ("ok")
8935
8936testList.append(("testWstringArray",testWstringArray))
8937
8938
8939def testVArrays():
8940    '''
8941    Test variable-length arrays.  Currently we only support an
8942    VIntArray with very limited Python functionality.  This test
8943    should be expanded when support for variable-length arrays
8944    becomes more complete.
8945    '''
8946
8947    num = 1000
8948    a1 = VIntArray(num)
8949    a2 = VIntArray(1, num)
8950    a3 = VIntArray(a2)
8951    assert(len(a1) == num)
8952    assert(len(a2) == num)
8953    assert(len(a3) == num)
8954
8955    # test constructor failure cases
8956    failed = False
8957    try:
8958        VIntArray(-1)
8959    except:
8960        failed = True
8961    assert(failed)
8962
8963    failed = False
8964    try:
8965        VIntArray(10,-1)
8966    except:
8967        failed = True
8968    assert(failed)
8969
8970    assert(a2[0][0] == 1)
8971    assert(a2[1][0] == 1)
8972    assert(a2[2][0] == 1)
8973    assert(a2[3][0] == 1)
8974
8975    # index out of bounds
8976    failed = False
8977    try:
8978        a2[num]
8979    except:
8980        failed = True
8981    assert(failed)
8982
8983
8984    values = IntArray(1)
8985    values[0] = 5
8986
8987    # test getitem and setitem
8988    assert(len(a1[0]) == 0)
8989    assert(len(a2[0]) == 1)
8990    assert(len(a3[0]) == 1)
8991    a2[0] = values
8992    assert(a2[0][0] == 5)
8993
8994    # test getitem, negative indices
8995    assert(len(a1[-1]) == 0)
8996    assert(len(a2[-1]) == 1)
8997    assert(len(a3[-1]) == 1)
8998    a2[-1] = values
8999    assert(a2[-1][0] == 5)
9000
9001    mask = IntArray(num)
9002    mask[2] = 1
9003    mask[3] = 1
9004
9005    # test getitem and setitem with mask
9006    assert(len(a2[mask]) == 2) # two elements from the original array
9007    a2[mask] = values
9008    assert(a2[0][0] == 5)
9009    assert(a2[1][0] == 1)
9010    assert(a2[2][0] == 5)
9011    assert(a2[3][0] == 5)
9012
9013    a2[3][0] = 6
9014    assert(a2[3][0] == 6)
9015    a2m = a2[mask] # masked to [2,3]
9016    a2ms = a2m[1:2:1] # sliced to [2]
9017    a2msa = a2ms[0] # indexed to the elemnt 3 array
9018    assert(a2msa[0] == 6) # test slice on mask
9019
9020    # test slice assignment in masked array
9021    tmpValues = IntArray(9,1)
9022    a2m[1:2:1] = tmpValues
9023    assert(a2[3][0] == 9)
9024
9025    tmpValues = IntArray(9,2)
9026    tmpValuesMask = IntArray(2)
9027    tmpValuesMask[1] = 1
9028    tmpValues[1] = 15
9029    a2m[1:2:1] = tmpValues[tmpValuesMask]
9030    assert(a2[3][0] == 15)
9031
9032    # mismatched length on RHG
9033    failed = False
9034    try:
9035        a2m[1:2:1] = tmpValues
9036    except:
9037        failed = True
9038    assert(failed)
9039
9040    tmpValues[1] = 17
9041    a2[3:4:1] = tmpValues[tmpValuesMask]
9042    assert(a2[3][0] == 17)
9043
9044    # mismatched length on RHG
9045    failed = False
9046    try:
9047        a2[3:4:1] = tmpValues
9048    except:
9049        failed = True
9050    assert(failed)
9051
9052    a2[mask] = tmpValues[tmpValuesMask]
9053
9054    # test getitem and setitem with slice
9055    values[:] = 7
9056    assert(len(a2[1:4:2]) == 2) # two elements from the original array
9057    a2[1:4:2] = values
9058    assert(a2[0][0] == 5)
9059    assert(a2[1][0] == 7)
9060    assert(a2[2][0] == 17)
9061    assert(a2[3][0] == 7)
9062
9063    # test size property setitem and getitem
9064    a1.size[0] = 10
9065    assert(len(a1[0]) == 10)
9066    assert(a1.size[0] == 10)
9067
9068    # test internal reference handling
9069    a10 = a1[0]
9070    a10[9] = 15
9071    del a10
9072    a10 = a1[0]
9073    assert(a10[9] == 15)
9074
9075    #  Some tests for Variable V2is
9076
9077    print ("Testing VV2i...")
9078    failed = False
9079    try:
9080        VV2iArray(-1)
9081    except:
9082        failed = True
9083    assert(failed)
9084
9085    failed = False
9086    try:
9087        VV2iArray(10,-1)
9088    except:
9089        failed = True
9090    assert(failed)
9091
9092    defaults2i = V2iArray(1)
9093    defaults2i[0] = V2i(17,31)
9094
9095    a = VV2iArray (defaults2i[0], 5)
9096    count = 0
9097    for elem in a:
9098        assert (elem == V2i(17,31))
9099        count += 1
9100    assert (count == 5)
9101
9102    failed = False
9103    try:
9104        print ("If you see a value here it's bogus: {}".format(a[-6]))
9105    except:
9106        failed = True
9107    assert (failed)
9108    print ("")
9109
9110    #  Some tests for Variable floats
9111
9112    print ("Testing VFloat...")
9113    failed = False
9114    try:
9115        VFloatArray(-1)
9116    except:
9117        failed = True
9118    assert(failed)
9119
9120    failed = False
9121    try:
9122        VFloatArray(10.,-1)
9123    except:
9124        failed = True
9125    assert(failed)
9126
9127    value0 = 42.23
9128    value1 = 2.
9129    defaultsFloats = VFloatArray(1,2)
9130    defaultsFloats[0] = FloatArray(value0, 1)
9131    defaultsFloats[1] = FloatArray(value1, 1)
9132
9133    a = VFloatArray (defaultsFloats[1][0], 7)
9134    count = 0
9135    for elem in a:
9136        assert (len(elem) == 1)
9137        assert (elem[0]  == value1)
9138        assert (elem[-1] == value1)
9139        count += 1
9140    assert (count == 7 and len(a) == count)
9141
9142    failed = False
9143    try:
9144        print ("If you see a value here it's bogus: {}".format(a[8]))
9145    except:
9146        failed = True
9147    assert (failed)
9148    print ("")
9149
9150    # See the 'PyImath/varraySemantics.txt' document for more information.
9151
9152testList.append(("testVArrays", testVArrays))
9153
9154
9155def testReadOnlyBasic(AType, val):
9156    '''
9157    Tests the basic operation, features, and expectations of a read-only
9158    fixed array.  Makes sure the writeable state is accurate and errors
9159    are thrown if we try to modify a read-only array.  Also makes sures
9160    that values returned from arrays are as expected, depending on the
9161    writable state of the array (i.e. copies of array values or direct
9162    references to those array values).
9163    '''
9164
9165    a = AType(13)
9166    assert (len(a) == 13)
9167    assert (a.writable() == True)
9168
9169    for i in range(5):
9170        a[i] = val
9171    for i in range(5):
9172        assert (equalWithAbsError(a[i], val, eps) == True)
9173    for i in range(5,13):
9174        assert (equalWithAbsError(a[i], val, eps) == False)
9175
9176    # Test '__getitem__' subtleties for array items.
9177    if hasattr(a[0], 'setValue'):
9178        l = len(a[0])
9179        # Vector-type arrays.
9180        if l == 2:
9181            for i in range(13):
9182                a[i].setValue(101, 102)
9183            for i in range(13):
9184                assert (equalWithAbsError(a[i].x, 101, eps) == True)
9185                assert (equalWithAbsError(a[i].y, 102, eps) == True)
9186            for i in range(5):
9187                v = a[i]
9188                v.setValue(val.x, val.y)
9189        elif l == 3:
9190            for i in range(13):
9191                a[i].setValue(101, 102, 103)
9192            for i in range(13):
9193                assert (equalWithAbsError(a[i].x, 101, eps) == True)
9194                assert (equalWithAbsError(a[i].y, 102, eps) == True)
9195                assert (equalWithAbsError(a[i].z, 103, eps) == True)
9196            for i in range(5):
9197                v = a[i]
9198                v.setValue(val.x, val.y, val.z)
9199
9200        for i in range(5):
9201            assert (equalWithAbsError(a[i], val, eps) == True)
9202        for i in range(5,13):
9203            assert (equalWithAbsError(a[i], val, eps) == False)
9204
9205    b = a
9206    c = AType (a)
9207    assert (len(b) == 13)
9208    assert (len(c) == 13)
9209    assert (b.writable() == True)
9210    assert (c.writable() == True)
9211
9212    for i in range(5):
9213        assert (equalWithAbsError(b[i], val, eps) == True)
9214        assert (equalWithAbsError(c[i], val, eps) == True)
9215    for i in range(5,13):
9216        assert (equalWithAbsError(b[i], val, eps) == False)
9217        assert (equalWithAbsError(c[i], val, eps) == False)
9218
9219    # Make the array 'read only'.
9220
9221    a.makeReadOnly()
9222    assert (len(a) == 13)
9223    assert (a.writable() == False)
9224
9225    b = a
9226    c = AType (a)
9227    assert (len(b) == 13)
9228    assert (len(c) == 13)
9229    assert (b.writable() == False)
9230    assert (c.writable() == False)
9231
9232    for i in range(5):
9233        assert (equalWithAbsError(a[i], val, eps) == True)
9234        assert (equalWithAbsError(b[i], val, eps) == True)
9235        assert (equalWithAbsError(c[i], val, eps) == True)
9236    for i in range(5,13):
9237        assert (equalWithAbsError(a[i], val, eps) == False)
9238        assert (equalWithAbsError(b[i], val, eps) == False)
9239        assert (equalWithAbsError(c[i], val, eps) == False)
9240
9241    # These should all fail because the array is read-only.
9242    try:
9243        a[3] = val
9244    except:
9245        pass
9246    else:
9247        assert(False)
9248    try:
9249        a[5] = val
9250    except:
9251        pass
9252    else:
9253        assert(False)
9254    try:
9255        a[8:10] = val
9256    except:
9257        pass
9258    else:
9259        assert(False)
9260
9261    # Continue to test '__getitem__' subtleties for array items.
9262    if hasattr(a[0], 'setValue'):
9263        l = len(a[0])
9264        # Vector-type arrays.
9265        if l == 2:
9266            for i in range(13):
9267                a[i].setValue(201, 202)
9268            # For read-only arrays, the setValue should be operating
9269            # on copies of the vaslues.  Because of that, the values
9270            # should not have actually changed.
9271            for i in range(13):
9272                assert (equalWithAbsError(a[i].x, 201, eps) == False)
9273                assert (equalWithAbsError(a[i].y, 202, eps) == False)
9274        elif l == 3:
9275            for i in range(13):
9276                a[i].setValue(201, 202, 203)
9277            # For read-only arrays, the setValue should be operating
9278            # on copies of the vaslues.  Because of that, the values
9279            # should not have actually changed.
9280            for i in range(13):
9281                assert (equalWithAbsError(a[i].x, 201, eps) == False)
9282                assert (equalWithAbsError(a[i].y, 202, eps) == False)
9283                assert (equalWithAbsError(a[i].z, 203, eps) == False)
9284
9285        for i in range(5):
9286            assert (equalWithAbsError(a[i], val, eps) == True)
9287        for i in range(5,13):
9288            assert (equalWithAbsError(a[i], val, eps) == False)
9289
9290    print ("ok")
9291
9292testList.append(("testReadOnlyBasicInt",
9293                 lambda : testReadOnlyBasic(IntArray, 7)))
9294testList.append(("testReadOnlyBasicFloat",
9295                 lambda : testReadOnlyBasic(FloatArray, 1.234)))
9296testList.append(("testReadOnlyBasicV3f",
9297                 lambda : testReadOnlyBasic(V3fArray, V3f(1.2, 3.4, 5.6))))
9298testList.append(("testReadOnlyBasicV2i",
9299                 lambda : testReadOnlyBasic(V2iArray, V2i(8, 9))))
9300
9301
9302def testVectorVectorInPlaceArithmeticOpsReadOnly(f1, f2,
9303                                                 shouldFail = True):
9304    assert(len(f1) == len(f2))
9305
9306    try:    f1 += f2
9307    except: pass
9308    else:   assert(not shouldFail)
9309
9310    try:    f1 -= f2
9311    except: pass
9312    else:   assert(not shouldFail)
9313
9314    try:    f1 *= f2
9315    except: pass
9316    else:   assert(not shouldFail)
9317
9318    try:    f1 /= f2
9319    except: pass
9320    else:   assert(not shouldFail)
9321
9322def testVectorScalarInPlaceArithmeticOpsReadOnly(f1, v):
9323    try:    f1 += v
9324    except: pass
9325    else:   assert(False)
9326
9327    try:    f1 -= v
9328    except: pass
9329    else:   assert(False)
9330
9331    try:    f1 *= v
9332    except: pass
9333    else:   assert(False)
9334
9335    try:    f1 /= v
9336    except: pass
9337    else:   assert(False)
9338
9339def testVectorVectorMaskedInPlaceArithmeticOpsReadOnly(f1, f2, m,
9340                                                       shouldFail = True):
9341    assert(len(f1) == len(f2))
9342    assert(len(f1) == len(m ));
9343
9344    try:    f1[m] += f2
9345    except: pass
9346    else:   assert(not shouldFail)
9347
9348    try:    f1[m] -= f2
9349    except: pass
9350    else:   assert(not shouldFail)
9351
9352    try:    f1[m] *= f2
9353    except: pass
9354    else:   assert(not shouldFail)
9355
9356    try:    f1[m] /= f2
9357    except: pass
9358    else:   assert(not shouldFail)
9359
9360def testVectorVectorMaskedInPlaceArithmeticOps2ReadOnly(f1, f2, m,
9361                                                        shouldFail = True):
9362    assert(len(f1) == len(m))
9363    assert(len(f1[m]) == len(f2))
9364
9365    try:    f1[m] += f2
9366    except: pass
9367    else:   assert(not shouldFail)
9368
9369    try:    f1[m] -= f2
9370    except: pass
9371    else:   assert(not shouldFail)
9372
9373    try:    f1[m] *= f2
9374    except: pass
9375    else:   assert(not shouldFail)
9376
9377    try:    f1[m] /= f2
9378    except: pass
9379    else:   assert(not shouldFail)
9380
9381def testUnaryVecMethodsReadOnly(f):
9382    g = f.length()
9383    assert(len(g) == len(f))
9384    for i in range(0, len(f)):
9385        assert(equalWithRelError(g[i], f[i].length(), eps))
9386
9387    g = f.length2()
9388    assert(len(g) == len(f))
9389    for i in range(0, len(f)):
9390        assert(g[i] == f[i].length2())
9391
9392    # Normalization only makes sense for these types
9393    try:    f.normalize()
9394    except: pass
9395    else:   assert(False)
9396
9397    g = f.normalized()
9398    assert(len(g) == len(f))
9399    for i in range(0, len(f)):
9400        assert(g[i] == f[i].normalized())
9401
9402def testReadOnlyAutoVect(ArrayType, val1, val2):
9403    '''
9404    Tests the auto-vectorized functions operating on read-only arrays.
9405    Generally it is ok if a read-only array is used in a vectorized function
9406    if its values are just read (used), but errors should be thrown if the
9407    auto-vectorized function tries to modify a read-only array.
9408    '''
9409
9410    aLen = 1234
9411    f1  = ArrayType(val1, aLen)
9412    f1w = ArrayType(val1, aLen)
9413    f2 = ArrayType(val2, aLen)
9414
9415    m = IntArray(aLen)
9416    m[    : 100] = 1
9417    m[ 100: 200] = 0
9418    m[ 200: 300] = 1
9419    m[ 300: 400] = 0
9420    m[ 400: 500] = 1
9421    m[ 500: 600] = 0
9422    m[ 600: 700] = 1
9423    m[ 700: 800] = 0
9424    m[ 800: 900] = 1
9425    m[ 900:1000] = 0
9426    m[1000:1100] = 1
9427    m[1100:1200] = 0
9428    m[1200:    ] = 1
9429
9430    m.makeReadOnly()
9431
9432    maskedLen = len(f1[m])
9433    f3 = ArrayType(val2, len(f1[m]))
9434
9435    assert (f1.writable() == True)
9436    assert (f2.writable() == True)
9437    assert (f3.writable() == True)
9438
9439    testVectorVectorArithmeticOps(f1, f2)
9440
9441    testVectorScalarArithmeticOps(f1, val2)
9442
9443    testVectorVectorInPlaceArithmeticOps(f1, f2)
9444
9445    testVectorScalarInPlaceArithmeticOps(f1, val2)
9446
9447    testVectorVectorComparisonOps(f1, f2)
9448
9449    testVectorScalarComparisonOps(f1, val2)
9450
9451    testVectorVectorMaskedInPlaceArithmeticOps(f1, f2, m)
9452
9453    testVectorVectorMaskedInPlaceArithmeticOps2(f1, f3, m)
9454
9455    if ArrayType in [V2fArray, V2dArray, V3fArray, V3dArray]:
9456        testUnaryVecMethods(f1)
9457
9458        testBinaryVecMethods(f1, f2)
9459
9460    # Now do the test again with both arrays read-only.
9461    # Most tests will still pass, but some will fail.
9462
9463    f1.makeReadOnly()
9464    f2.makeReadOnly()
9465    f3.makeReadOnly()
9466    assert (f1.writable() == False)
9467    assert (f2.writable() == False)
9468    assert (f3.writable() == False)
9469
9470    f1w = ArrayType(val1, aLen)
9471    assert (f1w.writable() == True)
9472
9473    testVectorVectorArithmeticOps(f1, f2)
9474
9475    testVectorScalarArithmeticOps(f1, val2)
9476
9477    testVectorVectorInPlaceArithmeticOpsReadOnly(f1 , f2)
9478    testVectorVectorInPlaceArithmeticOpsReadOnly(f1w, f2, False)
9479
9480    testVectorScalarInPlaceArithmeticOpsReadOnly(f1, val2)
9481
9482    testVectorVectorComparisonOps(f1, f2)
9483
9484    testVectorScalarComparisonOps(f1, val2)
9485
9486    testVectorVectorMaskedInPlaceArithmeticOpsReadOnly(f1 , f2, m)
9487    testVectorVectorMaskedInPlaceArithmeticOpsReadOnly(f1w, f2, m, False)
9488
9489    testVectorVectorMaskedInPlaceArithmeticOps2ReadOnly(f1 , f3, m)
9490    testVectorVectorMaskedInPlaceArithmeticOps2ReadOnly(f1w, f3, m, False)
9491
9492    if ArrayType in [V2fArray, V2dArray, V3fArray, V3dArray]:
9493        testUnaryVecMethodsReadOnly(f1)
9494
9495        testBinaryVecMethods(f1, f2)
9496
9497    print ("ok")
9498
9499testList.append(("testReadOnlyAutoVectFloat",
9500                  lambda : testReadOnlyAutoVect(FloatArray, 1.25, 5.0)))
9501testList.append(("testReadOnlyAutoVectDouble",
9502                  lambda : testReadOnlyAutoVect(DoubleArray, 3.456, 4.567)))
9503testList.append(("testReadOnlyAutoVectV3f",
9504                  lambda : testReadOnlyAutoVect(V3fArray, V3f(1.234, 2.345, 3.456),
9505                                                          V3f(4.234, 6.345, 5.456))))
9506testList.append(("testReadOnlyAutoVectV2d",
9507                  lambda : testReadOnlyAutoVect(V2dArray, V2d(3.456, 0.456),
9508                                                           V2d(4.567, 0.581))))
9509
9510
9511def testReadOnlySpecialAccess():
9512    '''
9513    Tests that some of the special array-access operators (for example,
9514    a 'V3fArray' x, y, or z operators) maintain the proper writable
9515    state and behave as expected.
9516    '''
9517
9518    aLen = 123
9519
9520    b2 = Box2dArray(aLen)
9521    b3 = Box3fArray(aLen)
9522
9523    assert (b2.writable() == True)
9524    assert (b3.writable() == True)
9525
9526    assert (b2.min.writable() == True)
9527    assert (b2.max.writable() == True)
9528    assert (b3.min.writable() == True)
9529    assert (b3.max.writable() == True)
9530
9531    b2.min[10] = V2d( 1, 2)
9532    b2.max[10] = V2d( 2, 3)
9533    b3.min[10] = V3f(-1,-1,-1)
9534    b3.max[10] = V3f( 1, 1, 1)
9535
9536    b2.makeReadOnly()
9537    b3.makeReadOnly()
9538
9539    assert (b2.writable() == False)
9540    assert (b3.writable() == False)
9541
9542    assert (b2.min.writable() == False)
9543    assert (b2.max.writable() == False)
9544    assert (b3.min.writable() == False)
9545    assert (b3.max.writable() == False)
9546
9547    assert (equalWithAbsError(b2.min[10], V2d(1,2), eps) == True)
9548    assert (equalWithAbsError(b2.max[10], V2d(2,3), eps) == True)
9549    assert (equalWithAbsError(b3.min[10], V3f(-1,-1,-1), eps) == True)
9550    assert (equalWithAbsError(b3.max[10], V3f( 1, 1, 1), eps) == True)
9551
9552    try:    b2.min[20] = V2d( 1, 2)
9553    except: pass
9554    else:   assert(False)
9555    try:    b2.max[20] = V2d( 2, 3)
9556    except: pass
9557    else:   assert(False)
9558    try:    b3.min[20] = V3f(-1,-1,-1)
9559    except: pass
9560    else:   assert(False)
9561    try:    b3.max[20] = V3f( 1, 1, 1)
9562    except: pass
9563    else:   assert(False)
9564
9565    ##
9566
9567    c3 = C3fArray(aLen)
9568    c4 = C4fArray(aLen)
9569
9570    assert (c3.writable() == True)
9571    assert (c4.writable() == True)
9572
9573    assert (c3.r.writable() == True)
9574    assert (c3.g.writable() == True)
9575    assert (c3.b.writable() == True)
9576
9577    assert (c4.r.writable() == True)
9578    assert (c4.g.writable() == True)
9579    assert (c4.b.writable() == True)
9580    assert (c4.a.writable() == True)
9581
9582    c3.r[10] = 0.1
9583    c3.g[10] = 0.2
9584    c3.b[10] = 0.3
9585
9586    c4.r[10] = 0.1
9587    c4.g[10] = 0.2
9588    c4.b[10] = 0.3
9589    c4.a[10] = 0.4
9590
9591    c3.makeReadOnly()
9592    c4.makeReadOnly()
9593
9594    assert (c3.writable() == False)
9595    assert (c4.writable() == False)
9596
9597    assert (c3.r.writable() == False)
9598    assert (c3.g.writable() == False)
9599    assert (c3.b.writable() == False)
9600
9601    assert (c4.r.writable() == False)
9602    assert (c4.g.writable() == False)
9603    assert (c4.b.writable() == False)
9604    assert (c4.a.writable() == False)
9605
9606    assert (equalWithAbsError(c3.r[10], 0.1, eps) == True)
9607    assert (equalWithAbsError(c3.g[10], 0.2, eps) == True)
9608    assert (equalWithAbsError(c3.b[10], 0.3, eps) == True)
9609
9610    assert (equalWithAbsError(c4.r[10], 0.1, eps) == True)
9611    assert (equalWithAbsError(c4.g[10], 0.2, eps) == True)
9612    assert (equalWithAbsError(c4.b[10], 0.3, eps) == True)
9613    assert (equalWithAbsError(c4.a[10], 0.4, eps) == True)
9614
9615    try:    c3.r[10] = 0.2
9616    except: pass
9617    else:   assert(False)
9618    try:    c3.g[10] = 0.3
9619    except: pass
9620    else:   assert(False)
9621    try:    c3.b[10] = 0.4
9622    except: pass
9623    else:   assert(False)
9624
9625    try:    c4.r[10] = 0.2
9626    except: pass
9627    else:   assert(False)
9628    try:    c4.g[10] = 0.3
9629    except: pass
9630    else:   assert(False)
9631    try:    c4.b[10] = 0.4
9632    except: pass
9633    else:   assert(False)
9634    try:    c4.a[10] = 0.5
9635    except: pass
9636    else:   assert(False)
9637
9638    ##
9639
9640    qd = QuatdArray(aLen)
9641    qf = QuatfArray(aLen)
9642
9643    assert (qd.writable() == True)
9644    assert (qf.writable() == True)
9645
9646    assert (qd.r.writable() == True)
9647    assert (qd.x.writable() == True)
9648    assert (qd.y.writable() == True)
9649    assert (qd.z.writable() == True)
9650    assert (qf.r.writable() == True)
9651    assert (qf.x.writable() == True)
9652    assert (qf.y.writable() == True)
9653    assert (qf.z.writable() == True)
9654
9655    qd.setRotation( V3dArray(V3d(1,2,3), aLen),
9656                    V3dArray(V3d(2,3,4), aLen) )
9657    qf.orientToVectors( V3fArray(V3f(2,3,4), aLen),
9658                        V3fArray(V3f(3,4,5), aLen), False )
9659    qd.setAxisAngle( V3dArray(V3d(4,5,6), aLen), DoubleArray(23.45, aLen) )
9660    qf.setEulerXYZ( V3fArray(V3f(30,-10,20), aLen) )
9661
9662    qd.makeReadOnly()
9663    qf.makeReadOnly()
9664
9665    assert (qd.writable() == False)
9666    assert (qf.writable() == False)
9667
9668    assert (qd.r.writable() == False)
9669    assert (qd.x.writable() == False)
9670    assert (qd.y.writable() == False)
9671    assert (qd.z.writable() == False)
9672    assert (qf.r.writable() == False)
9673    assert (qf.x.writable() == False)
9674    assert (qf.y.writable() == False)
9675    assert (qf.z.writable() == False)
9676
9677    try:
9678        qd.setRotation( V3dArray(V3d(-1,-2,-3), aLen),
9679                        V3dArray(V3d(-2,-3,-4), aLen) )
9680    except:
9681        pass
9682    else:
9683        assert(False)
9684    try:
9685        qf.orientToVectors( V3fArray(V3f(-2,-3,-4), aLen),
9686                            V3fArray(V3f(-3,-4,-5), aLen), True )
9687    except:
9688        pass
9689    else:
9690        assert(False)
9691    try:
9692        qd.setAxisAngle( V3dArray(V3d(-4,-5,-6), aLen), DoubleArray(-23.45, aLen) )
9693    except:
9694        pass
9695    else:
9696        assert(False)
9697    try:
9698        qf.setEulerXYZ( V3fArray(V3f(-30,10,-20), aLen) )
9699    except:
9700        pass
9701    else:
9702        assert(False)
9703
9704    ##
9705
9706    v2 = V2fArray(aLen)
9707    v3 = V3dArray(aLen)
9708    v4 = V4fArray(aLen)
9709
9710    assert (v2.writable() == True)
9711    assert (v3.writable() == True)
9712    assert (v4.writable() == True)
9713
9714    assert (v2.x.writable() == True)
9715    assert (v2.y.writable() == True)
9716    assert (v3.x.writable() == True)
9717    assert (v3.y.writable() == True)
9718    assert (v3.z.writable() == True)
9719    assert (v4.x.writable() == True)
9720    assert (v4.y.writable() == True)
9721    assert (v4.z.writable() == True)
9722    assert (v4.w.writable() == True)
9723
9724    v2.x[10] = 0.1
9725    v2.y[10] = 0.2
9726    v3.x[10] = 0.1
9727    v3.y[10] = 0.2
9728    v3.z[10] = 0.3
9729    v4.x[10] = 0.1
9730    v4.y[10] = 0.2
9731    v4.z[10] = 0.3
9732    v4.w[10] = 0.4
9733
9734    v2.makeReadOnly()
9735    v3.makeReadOnly()
9736    v4.makeReadOnly()
9737
9738    assert (v2.writable() == False)
9739    assert (v3.writable() == False)
9740    assert (v4.writable() == False)
9741
9742    assert (v2.x.writable() == False)
9743    assert (v2.y.writable() == False)
9744    assert (v3.x.writable() == False)
9745    assert (v3.y.writable() == False)
9746    assert (v3.z.writable() == False)
9747    assert (v4.x.writable() == False)
9748    assert (v4.y.writable() == False)
9749    assert (v4.z.writable() == False)
9750    assert (v4.w.writable() == False)
9751
9752    assert (equalWithAbsError(v2.x[10], 0.1, eps) == True)
9753    assert (equalWithAbsError(v2.y[10], 0.2, eps) == True)
9754    assert (equalWithAbsError(v3.x[10], 0.1, eps) == True)
9755    assert (equalWithAbsError(v3.y[10], 0.2, eps) == True)
9756    assert (equalWithAbsError(v3.z[10], 0.3, eps) == True)
9757    assert (equalWithAbsError(v4.x[10], 0.1, eps) == True)
9758    assert (equalWithAbsError(v4.y[10], 0.2, eps) == True)
9759    assert (equalWithAbsError(v4.z[10], 0.3, eps) == True)
9760    assert (equalWithAbsError(v4.w[10], 0.4, eps) == True)
9761
9762    try:    v2.x[20] = 0.2
9763    except: pass
9764    else:   assert(False)
9765    try:    v2.y[20] = 0.3
9766    except: pass
9767    else:   assert(False)
9768    try:    v3.x[20] = 0.2
9769    except: pass
9770    else:   assert(False)
9771    try:    v3.y[20] = 0.3
9772    except: pass
9773    else:   assert(False)
9774    try:    v3.z[20] = 0.4
9775    except: pass
9776    else:   assert(False)
9777    try:    v4.x[20] = 0.2
9778    except: pass
9779    else:   assert(False)
9780    try:    v4.y[20] = 0.3
9781    except: pass
9782    else:   assert(False)
9783    try:    v4.z[20] = 0.4
9784    except: pass
9785    else:   assert(False)
9786    try:    v4.w[20] = 0.5
9787    except: pass
9788    else:   assert(False)
9789
9790    print ("ok")
9791
9792testList.append(("testReadOnlySpecialAccess", testReadOnlySpecialAccess))
9793
9794
9795def testReadOnlyIndexedArrays(ArrayType, val):
9796    '''
9797    Tests that indexed read-only arrays behave as expected.
9798    '''
9799
9800    aLen = 123
9801
9802    a = ArrayType(aLen)
9803    assert (a.writable() == True)
9804
9805    m = IntArray(aLen)
9806    m[:]     = 0
9807    m[10:80] = 1
9808    assert (m.writable() == True)
9809    m.makeReadOnly()
9810    assert (m.writable() == False)
9811
9812    a1 = a[30:100]  # getitem (new array; writable)
9813    assert (len(a1) == 70)
9814    assert (a1.writable() == True)
9815    a1[:] = val
9816
9817    a2 = a[m]   # getitem (copied; writable state preserved)
9818    assert (len(a2) == 70)
9819    assert (a2.writable() == True)
9820    a2[:] = val
9821
9822    assert (equalWithAbsError(a[ 5], val, eps) == False)
9823    assert (equalWithAbsError(a[20], val, eps) == True )
9824    assert (equalWithAbsError(a[90], val, eps) == False)
9825
9826    a2[:] = ArrayType(2 * val, 70)
9827    assert (equalWithAbsError(a[ 5], 2*val, eps) == False)
9828    assert (equalWithAbsError(a[20], 2*val, eps) == True )
9829    assert (equalWithAbsError(a[90], 2*val, eps) == False)
9830
9831    a.makeReadOnly()
9832    assert (a.writable() == False)
9833
9834    a1 = a[30:100]  # getitem (new array; writable by default)
9835    assert (len(a1) == 70)
9836    assert (a1.writable() == True)
9837    a1[:] = val
9838
9839    a2 = a[m]   # getitem (copied; writable state preserved)
9840    assert (len(a2) == 70)
9841    assert (a2.writable() == False)
9842    try:    a2[:] = val
9843    except: pass
9844    else:   assert(False)
9845
9846    a1[:] = ArrayType(val, 70)
9847    try:    a2[:] = ArrayType(val, 70)
9848    except: pass
9849    else:   assert(False)
9850
9851    #
9852
9853    a = ArrayType(aLen)
9854    assert (a.writable() == True)
9855
9856    a[m]       =   val  # setitem_scalar
9857    a[100:110] = 2*val  # setitem_scalar
9858    assert (equalWithAbsError(a[  5],   val, eps) == False)
9859    assert (equalWithAbsError(a[ 30],   val, eps) == True )
9860    assert (equalWithAbsError(a[105], 2*val, eps) == True )
9861    assert (equalWithAbsError(a[115], 2*val, eps) == False)
9862
9863    a[m]       = ArrayType(3*val, 70)  # setitem_vector
9864    a[100:110] = ArrayType(4*val, 10)  # setitem_vector
9865    assert (equalWithAbsError(a[  5], 3*val, eps) == False)
9866    assert (equalWithAbsError(a[ 30], 3*val, eps) == True )
9867    assert (equalWithAbsError(a[105], 4*val, eps) == True )
9868    assert (equalWithAbsError(a[115], 4*val, eps) == False)
9869
9870    a.makeReadOnly()
9871    assert (a.writable() == False)
9872
9873    try:    a[m]      = 5*val;  # setitem_scalar
9874    except: pass
9875    else:   assert(False)
9876    try:    a[100:110] = 6*val;  # setitem_scalar
9877    except: pass
9878    else:   assert(False)
9879
9880    try:    a[m]       = ArrayType(7*val, 70)  # setitem_vector
9881    except: pass
9882    else:   assert(False)
9883    try:    a[100:110] = ArrayType(8*val, 10)  # setitem_vector
9884    except: pass
9885    else:   assert(False)
9886
9887    print ("ok")
9888
9889testList.append(("testReadOnlyIndexedArraysFloat",
9890                 lambda : testReadOnlyIndexedArrays(FloatArray, 1.25)))
9891testList.append(("testReadOnlyIndexedArraysV3f",
9892                 lambda : testReadOnlyIndexedArrays(V3fArray, V3f(1.25, 2, 3))))
9893
9894
9895def testReadOnlyVIntArrays():
9896    '''
9897    Tests the basic operations of read-only Variable-Int arrays and makes
9898    sure they behave as expected and throw access errors when they should.
9899    '''
9900
9901    aLen = 123
9902
9903    a = VIntArray(aLen)
9904    assert (len(a) == aLen)
9905    assert (a.writable() == True)
9906
9907    a.size[:] = 10  # 10 cvs each.
9908
9909    for i in range(aLen):
9910        assert (len(a[i]) == 10)
9911        for j in range(10):
9912            a[i][j] = j + i
9913
9914    for i in range(aLen):
9915        for j in range(len(a[i])):
9916            assert (a[i][j] == (i+j))
9917
9918    a.makeReadOnly()
9919    assert (a.writable() == False)
9920
9921    av = a[70]  # getitem
9922    assert(len(av) == 10)
9923    assert(av.writable() == False)
9924
9925    try:    a[80][5] = 7
9926    except: pass
9927    else:   assert(False)
9928
9929    assert (a.size[12] == 10)
9930    try:    a.size[13] = 12
9931    except: pass
9932    else:   assert(False)
9933
9934    av = a[10:14]
9935    assert (len(av) == 4)
9936    assert (av.writable() == True)  # A new array is returned for slices
9937    for i in range(len(av)):
9938        assert (len(av[i]) == 10)
9939        av[i][3] = 3
9940        av[i][8] = 8
9941
9942    m = IntArray(aLen)
9943    m[:] = 0
9944    m[50:70] = 1
9945    m.makeReadOnly()
9946
9947    av = a[m]
9948    assert (len(av) == 20)
9949    assert (av.writable() == False)  # An copied indexed array is returned for masks.
9950
9951    print ("ok")
9952
9953testList.append(("testReadOnlyVIntArrays", testReadOnlyVIntArrays))
9954
9955
9956def testReadOnlyStringArrays():
9957    '''
9958    Tests the basic operations of read-only string arrays and makes sure
9959    they behave as expected and throw access errors when they should.
9960    '''
9961
9962    aLen = 20
9963
9964    a = StringArray(aLen)
9965    assert (len(a) == aLen)
9966    assert (a.writable() == True)
9967
9968    a[:]  = "Hello"
9969    a[10] = "Hello Joe"
9970
9971    for i in range(20):
9972        if i == 10:
9973            assert (a[i] == "Hello Joe")
9974        else:
9975            assert (a[i] == "Hello")
9976
9977    a.makeReadOnly()
9978    assert (len(a) == aLen)
9979    assert (a.writable() == False)
9980
9981    for i in range(20):
9982        if i == 10:
9983            assert (a[i] == "Hello Joe")
9984        else:
9985            assert (a[i] == "Hello")
9986
9987    try:    a[3:12] = "Goodbye"
9988    except: pass
9989    else:   assert(False)
9990    try:    a[10] = "Goodbye Joe"
9991    except: pass
9992    else:   assert(False)
9993
9994    print ("ok")
9995
9996testList.append(("testReadOnlyStringArrays", testReadOnlyStringArrays))
9997
9998
9999def testQuatArrays():
10000
10001    x  = math.sqrt(2.) / 2.
10002    q1 = QuatfArray(5)
10003
10004    q1[0].setAxisAngle (V3f ( 1., 0., 0.), math.pi)
10005    q1[1].setAxisAngle (V3f ( 1., 1., 0.), math.pi)
10006    q1[2].setAxisAngle (V3f ( 0., 1., 0.), math.pi)
10007    q1[3].setAxisAngle (V3f (-1., 1., 0.), math.pi)
10008    q1[4].setAxisAngle (V3f (-1., 0., 0.), math.pi)
10009
10010    qA = Quatf()
10011    qA.setAxisAngle (V3f (0., 0., 1.), math.pi / 2.)
10012
10013    assert (abs (q1.x[1] - x) <= 1.e-6)
10014    assert (abs (q1.y[1] - x) <= 1.e-6)
10015    assert (abs (q1.x[3] + x) <= 1.e-6)
10016    assert (abs (q1.y[3] - x) <= 1.e-6)
10017
10018    q2 = -q1
10019    for i in range(5):
10020        assert (q2[i] == -q1[i])
10021
10022    s  = q1 ^ q2
10023    for i in range(5):
10024        assert (s[i] == q1[i] ^ q2[i])
10025
10026    q3 = q1 * qA
10027    for i in range(5):
10028        assert (q3[i] == q1[i] * qA)
10029    q3 *= 10.
10030
10031    tmp = QuatfArray (5)
10032    tmp[:] = q3
10033    q3.normalize()
10034    for i in range(5):
10035        assert (q3[i] != tmp[i])
10036        assert (q3[i] == tmp[i].normalized())
10037
10038    q4 = q1.slerp (q3, 0.5)
10039    for i in range(5):
10040        assert (q4[i] == q1[i].slerpShortestArc (q3[i], 0.5))
10041
10042    tmp[:] = q4
10043    q4 *= q3.inverse()
10044    for i in range(5):
10045        assert (q4[i] == tmp[i] * q3[i].inverse())
10046
10047    q5 = QuatfArray (5)
10048    tmp[:] = q4
10049    q5[:] = q4.normalized()
10050    for i in range(5):
10051        assert (q4[i] == tmp[i])
10052        assert (q5[i] == q4[i].normalize())
10053
10054    print ("ok")
10055
10056testList.append(("testQuatArrays", testQuatArrays))
10057
10058
10059def testBufferProtocol():
10060    '''
10061    The buffer protocol can be used to exchange array data between python modules.
10062    For example, numpy and Pixar Vt arrays both support the buffer protocol.
10063    There's a limited amount of testing that can be done with native python, so
10064    the majority of this functionality is tested in the PyImathNumpyTest project.
10065    '''
10066    def verifyScalar (a):
10067
10068        m = memoryview (a)
10069        assert (        m.ndim == 1)
10070        assert (len(m.strides) == m.ndim)
10071        assert (  len(m.shape) == m.ndim)
10072        assert (    m.shape[0] == len(a))
10073        assert (  m.strides[0] == struct.calcsize (m.format))
10074
10075
10076    def verifyVector (a):
10077
10078        m = memoryview (a)
10079        assert (        m.ndim == 2)
10080        assert (len(m.strides) == m.ndim)
10081        assert (  len(m.shape) == m.ndim)
10082        assert (    m.shape[0] == len(a))
10083        assert (    m.shape[1] == len(a[0]))
10084        assert (  m.strides[0] == struct.calcsize (m.format) * len(a[0]))
10085        assert (  m.strides[1] == struct.calcsize (m.format))
10086
10087# .............................................................................
10088
10089    import struct
10090
10091    a = UnsignedCharArray (10)
10092    verifyScalar (a)
10093
10094    a = IntArray (10)
10095    verifyScalar (a)
10096
10097    a = FloatArray (10)
10098    verifyScalar (a)
10099
10100    a = DoubleArray (10)
10101    verifyScalar (a)
10102
10103    a = V2iArray (10)
10104    verifyVector (a)
10105
10106    a = V2fArray (10)
10107    verifyVector (a)
10108
10109    a = V2dArray (10)
10110    verifyVector (a)
10111
10112    a = V3iArray (10)
10113    verifyVector (a)
10114
10115    a = V3fArray (10)
10116    verifyVector (a)
10117
10118    a = V3dArray (10)
10119    verifyVector (a)
10120
10121    print ("ok")
10122
10123testList.append(("Buffer protocol test", testBufferProtocol))
10124
10125# -------------------------------------------------------------------------
10126# Main loop
10127
10128random.seed (1567)
10129
10130import imath
10131print (imath.__file__)
10132
10133for test in testList:
10134    funcName = test[0]
10135    print ("")
10136    print ("Running {}".format (funcName))
10137    test[1]()
10138
10139print ("")
10140
10141# Local Variables:
10142# mode:python
10143# End:
10144