try:
    from . import generic as g
except BaseException:
    import generic as g


class BooleanTest(g.unittest.TestCase):

    def setUp(self):
        self.a = g.get_mesh('ballA.off')
        self.b = g.get_mesh('ballB.off')
        self.truth = g.data['boolean']

    def is_zero(self, value):
        return abs(value) < .001

    def test_boolean(self):
        a, b = self.a, self.b

        engines = [('blender', g.trimesh.interfaces.blender.exists),
                   ('scad', g.trimesh.interfaces.scad.exists)]

        for engine, exists in engines:
            # if we have all_dep set it means we should fail if
            # engine is not installed so don't continue
            if not exists:
                g.log.warning('skipping boolean engine %s', engine)
                continue

            g.log.info('Testing boolean ops with engine %s', engine)
            d = a.difference(b, engine=engine)
            if not d.is_volume:
                d.show()
            self.assertTrue(d.is_volume)
            self.assertTrue(self.is_zero(d.volume -
                                         self.truth['difference']))

            i = a.intersection(b, engine=engine)
            self.assertTrue(i.is_volume)
            self.assertTrue(self.is_zero(i.volume -
                                         self.truth['intersection']))

            u = a.union(b, engine=engine)
            self.assertTrue(u.is_volume)
            self.assertTrue(self.is_zero(u.volume - self.truth['union']))

            g.log.info('booleans succeeded with %s', engine)

    def test_multiple(self):
        """
        Make sure boolean operations work on multiple meshes.
        """
        engines = [
            ('blender', g.trimesh.interfaces.blender.exists),
            ('scad', g.trimesh.interfaces.scad.exists)]
        for engine, exists in engines:
            if not exists:
                continue
            a = g.trimesh.primitives.Sphere(center=[0, 0, 0])
            b = g.trimesh.primitives.Sphere(center=[0, 0, .75])
            c = g.trimesh.primitives.Sphere(center=[0, 0, 1.5])

            r = g.trimesh.boolean.union([a, b, c])

            assert r.is_volume
            assert r.body_count == 1
            assert g.np.isclose(r.volume,
                                8.617306056726884)


if __name__ == '__main__':
    g.trimesh.util.attach_to_log()
    g.unittest.main()

@@ -878,17 +878,18 @@
         
-d
+ab
  = a.dif
@@ -930,16 +930,17 @@
     
-if not d
+assert ab
 .is_
@@ -945,17 +945,16 @@
 s_volume
-:
 %0A       
@@ -962,50 +962,247 @@
     
-    d.show()%0A            self.assertTrue(d
+assert self.is_zero(%0A                ab.volume - self.truth%5B'difference'%5D)%0A%0A            assert g.np.allclose(%0A                ab.bounds%5B0%5D,%0A                a.bounds%5B0%5D)%0A%0A            ba = b.difference(a, engine=engine)%0A            assert ba
 .is_
@@ -1199,33 +1199,32 @@
 ert ba.is_volume
-)
 %0A            sel
@@ -1220,32 +1220,23 @@
         
-self.
 assert
-True(
+ 
 self.is_
@@ -1244,85 +1244,155 @@
 ero(
-d.volume -%0A                                         self.truth%5B'difference'%5D)
+%0A                ba.volume - self.truth%5B'difference'%5D)%0A%0A            assert g.np.allclose(%0A                ba.bounds%5B1%5D,%0A                b.bounds%5B1%5D
 )%0A%0A 
@@ -1451,32 +1451,23 @@
         
-self.
 assert
-True(
+ 
 i.is_vol
@@ -1461,33 +1461,32 @@
 sert i.is_volume
-)
 %0A            sel
@@ -1482,32 +1482,23 @@
         
-self.
 assert
-True(
+ 
 self.is_
@@ -1506,20 +1506,9 @@
 ero(
-i.volume -%0A 
+%0A
     
@@ -1519,39 +1519,26 @@
         
-                       
+i.volume -
  self.tr
@@ -1553,25 +1553,24 @@
 ersection'%5D)
-)
 %0A%0A          
@@ -1613,32 +1613,23 @@
         
-self.
 assert
-True(
+ 
 u.is_vol
@@ -1631,17 +1631,16 @@
 s_volume
-)
 %0A       
@@ -1648,24 +1648,15 @@
     
-self.
 assert
-True(
+ 
 self
@@ -1695,17 +1695,16 @@
 union'%5D)
-)
 %0A%0A      

add order check for blender booleans