Beispiel #1
0
    def testGridCombine(self):
        # Construct two grids and add some voxel data to each.
        aGrid, bGrid = openvdb.FloatGrid(), openvdb.FloatGrid(background=1.0)
        for width in range(63, 1, -10):
            aGrid.fill((0, 0, 0), (width, ) * 3, width)
            bGrid.fill((0, 0, 0), (width, ) * 3, 2 * width)

        # Save a copy of grid A.
        copyOfAGrid = aGrid.deepCopy()

        # Combine corresponding values of the two grids, storing the result in grid A.
        # (Since the grids have the same topology and B's active values are twice A's,
        # the function computes 2*min(a, 2*a) + 3*max(a, 2*a) = 2*a + 3*(2*a) = 8*a
        # for active values, and 2*min(0, 1) + 3*max(0, 1) = 2*0 + 3*1 = 3
        # for inactive values.)
        aGrid.combine(bGrid, lambda a, b: 2 * min(a, b) + 3 * max(a, b))

        self.assertTrue(bGrid.empty())

        # Verify that the resulting grid's values are as expected.
        for original, combined in zip(copyOfAGrid.iterOnValues(),
                                      aGrid.iterOnValues()):
            self.assertEqual(combined.min, original.min)
            self.assertEqual(combined.max, original.max)
            self.assertEqual(combined.depth, original.depth)
            self.assertEqual(combined.value, 8 * original.value)
        for original, combined in zip(copyOfAGrid.iterOffValues(),
                                      aGrid.iterOffValues()):
            self.assertEqual(combined.min, original.min)
            self.assertEqual(combined.max, original.max)
            self.assertEqual(combined.depth, original.depth)
            self.assertEqual(combined.value, 3)
Beispiel #2
0
    def testGridCopy(self):
        grid = openvdb.FloatGrid()
        self.assertTrue(grid.sharesWith(grid))
        self.assertFalse(grid.sharesWith([]))  # wrong type; Grid expected

        copyOfGrid = grid.copy()
        self.assertTrue(copyOfGrid.sharesWith(grid))

        deepCopyOfGrid = grid.deepCopy()
        self.assertFalse(deepCopyOfGrid.sharesWith(grid))
        self.assertFalse(deepCopyOfGrid.sharesWith(copyOfGrid))
Beispiel #3
0
    def testMap(self):
        grid = openvdb.BoolGrid()
        grid.fill((-4, -4, -4), (5, 5, 5), grid.zeroValue)  # make active
        grid.mapOn(lambda x: not x)  # replace active False values with True
        n = sum(item.value for item in grid.iterOnValues())
        self.assertEqual(n, 10 * 10 * 10)

        grid = openvdb.FloatGrid()
        grid.fill((-4, -4, -4), (5, 5, 5), grid.oneValue)
        grid.mapOn(lambda x: x * 2)
        n = sum(item.value for item in grid.iterOnValues())
        self.assertEqual(n, 10 * 10 * 10 * 2)

        grid = openvdb.Vec3SGrid()
        grid.fill((-4, -4, -4), (5, 5, 5), grid.zeroValue)
        grid.mapOn(lambda x: (0, 1, 0))
        n = sum(item.value[1] for item in grid.iterOnValues())
        self.assertEqual(n, 10 * 10 * 10)
Beispiel #4
0
    def testGridFill(self):
        grid = openvdb.FloatGrid()
        acc = grid.getAccessor()
        ijk = (1, 1, 1)

        self.assertRaises(TypeError, lambda: grid.fill("",
                                                       (7, 7, 7), 1, False))
        self.assertRaises(TypeError, lambda: grid.fill(
            (0, 0, 0), "", 1, False))
        self.assertRaises(TypeError, lambda: grid.fill((0, 0, 0),
                                                       (7, 7, 7), "", False))

        self.assertFalse(acc.isValueOn(ijk))
        grid.fill((0, 0, 0), (7, 7, 7), 1, active=False)
        self.assertEqual(acc.getValue(ijk), 1)
        self.assertFalse(acc.isValueOn(ijk))

        grid.fill((0, 0, 0), (7, 7, 7), 2, active=True)
        self.assertEqual(acc.getValue(ijk), 2)
        self.assertTrue(acc.isValueOn(ijk))

        activeCount = grid.activeVoxelCount()
        acc.setValueOn(ijk, 2.125)
        self.assertEqual(grid.activeVoxelCount(), activeCount)

        grid.fill(ijk, ijk, 2.125, active=True)
        self.assertEqual(acc.getValue(ijk), 2.125)
        self.assertTrue(acc.isValueOn(ijk))
        self.assertEqual(grid.activeVoxelCount(), activeCount)
        leafCount = grid.leafCount()

        grid.prune()
        self.assertAlmostEqual(acc.getValue(ijk), 2.125)
        self.assertTrue(acc.isValueOn(ijk))
        self.assertEqual(grid.leafCount(), leafCount)
        self.assertEqual(grid.activeVoxelCount(), activeCount)

        grid.prune(tolerance=0.2)
        self.assertEqual(grid.activeVoxelCount(), activeCount)
        self.assertEqual(acc.getValue(ijk), 2.0)  # median
        self.assertTrue(acc.isValueOn(ijk))
        self.assertTrue(grid.leafCount() < leafCount)
Beispiel #5
0
    def testTransform(self):
        xform1 = openvdb.createLinearTransform([[.5, 0, 0, 0], [0, 1, 0, 0],
                                                [0, 0, 2, 0], [1, 2, 3, 1]])
        self.assertTrue(xform1.typeName != '')
        self.assertEqual(xform1.indexToWorld((1, 1, 1)), (1.5, 3, 5))
        xform2 = xform1
        self.assertEqual(xform2, xform1)
        xform2 = xform1.deepCopy()
        self.assertEqual(xform2, xform1)
        xform2 = openvdb.createFrustumTransform(taper=0.5,
                                                depth=100,
                                                xyzMin=(0, 0, 0),
                                                xyzMax=(100, 100, 100),
                                                voxelSize=0.25)
        self.assertNotEqual(xform2, xform1)
        worldp = xform2.indexToWorld((10, 10, 10))
        worldp = [int(round(x * 1000000)) for x in worldp]
        self.assertEqual(worldp, [-110000, -110000, 2500000])

        grid = openvdb.FloatGrid()
        self.assertEqual(grid.transform, openvdb.createLinearTransform())
        grid.transform = openvdb.createLinearTransform(2.0)
        self.assertEqual(grid.transform, openvdb.createLinearTransform(2.0))
Beispiel #6
0
    def testCopyToArray(self):
        import random
        import time

        # Skip this test if NumPy is not available.
        try:
            import numpy as np
        except ImportError:
            return

        # Skip this test if the OpenVDB module was built without NumPy support.
        arr = np.zeros((1, 2, 1))
        grid = openvdb.FloatGrid()
        try:
            grid.copyFromArray(arr)
        except NotImplementedError:
            return

        # Verify that a grid can't be copied into a non-three-dimensional array.
        grid = openvdb.FloatGrid()
        self.assertRaises(TypeError, lambda: grid.copyToArray('abc'))
        arr = np.zeros((1, 2))
        self.assertRaises(ValueError, lambda: grid.copyToArray(arr))

        # Verify that complex-valued arrays are not supported.
        arr = np.zeros((1, 2, 1), dtype=complex)
        grid = openvdb.FloatGrid()
        self.assertRaises(TypeError, lambda: grid.copyToArray(arr))

        ARRAY_DIM = 201
        BG, FG = 0, 1

        # Generate some random voxel coordinates.
        random.seed(0)

        def randCoord():
            return tuple(random.randint(0, ARRAY_DIM - 1) for i in range(3))

        coords = set(randCoord() for i in range(200))

        def createArrays():
            # Test both scalar- and vec3-valued (i.e., four-dimensional) arrays.
            for shape in (
                (ARRAY_DIM, ARRAY_DIM, ARRAY_DIM),  # scalar array
                (ARRAY_DIM, ARRAY_DIM, ARRAY_DIM, 3)  # vec3 array
            ):
                for dtype in (np.float32, np.int32, np.float64, np.int64,
                              np.uint32, np.bool):
                    # Return a new NumPy array.
                    arr = np.ndarray(shape, dtype)
                    arr.fill(-100)
                    yield arr

        # Test copying from arrays of various types to grids of various types.
        for cls in openvdb.GridTypes:
            # skip copying test for PointDataGrids
            if cls.valueTypeName.startswith('ptdataidx'):
                continue
            for arr in createArrays():
                isScalarArray = (len(arr.shape) == 3)
                isScalarGrid = False
                try:
                    len(
                        cls.zeroValue
                    )  # values of vector grids are sequences, which have a length
                except TypeError:
                    isScalarGrid = True  # values of scalar grids have no length

                gridBG = valueFactory(cls.zeroValue, BG)
                gridFG = valueFactory(cls.zeroValue, FG)

                # Create an empty grid, fill it with the background value,
                # then set some elements to the foreground value.
                grid = cls(gridBG)
                acc = grid.getAccessor()
                for c in coords:
                    acc.setValueOn(c, gridFG)

                # Verify that scalar grids can't be copied into vector arrays
                # and vector grids can't be copied into scalar arrays.
                if isScalarGrid != isScalarArray:
                    self.assertRaises(ValueError,
                                      lambda: grid.copyToArray(arr))
                    continue

                # Copy values from the grid to the NumPy array.
                #now = time.process_time()
                grid.copyToArray(arr)
                #elapsed = time.process_time() - now
                #print 'copied %d voxels from %s to %s array in %f sec' % (
                #    arr.shape[0] * arr.shape[1] * arr.shape[2], grid.__class__.__name__,
                #    str(arr.dtype) + ('' if isScalarArray else '[]'), elapsed)

                # Verify that the grid's active voxels match the array's foreground elements.
                for c in coords:
                    self.assertEqual(
                        arr[c] if isScalarArray else tuple(arr[c]), gridFG)
                    arr[c] = gridBG
                self.assertEqual(np.amin(arr), BG)
                self.assertEqual(np.amax(arr), BG)