Beispiel #1
0
    def test_edge_surfaces(self):
        # test 3D surface vs 2D rational surface

        # more or less random 3D surface with p=[2,2] and n=[3,4]
        controlpoints = [[0, 0, 1], [-1, 1, 1], [0, 2, 1], [1, -1, 1], [1, 0, .5], [1, 1, 1],
                         [2, 1, 1], [2, 2, .5], [2, 3, 1], [3, 0, 1], [4, 1, 1], [3, 2, 1]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(3, [0, 0, 0, .64, 2, 2, 2])
        top = Surface(basis1, basis2, controlpoints)

        # more or less random 2D rational surface with p=[1,2] and n=[3,4]
        controlpoints = [[0, 0, 1], [-1, 1, .96], [0, 2, 1], [1, -1, 1], [1, 0, .8], [1, 1, 1],
                         [2, 1, .89], [2, 2, .9], [2, 3, 1], [3, 0, 1], [4, 1, 1], [3, 2, 1]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(2, [0, 0, .4, .44, 1, 1])
        bottom = Surface(basis1, basis2, controlpoints, True)

        vol = VolumeFactory.edge_surfaces(bottom, top)

        # set parametric domain to [0,1]^2 for easier comparison
        top.reparam()
        bottom.reparam()

        # verify on 7x7x2 evaluation grid
        for u in np.linspace(0, 1, 7):
            for v in np.linspace(0, 1, 7):
                for w in np.linspace(0, 1, 2):  # rational basis, not linear in w-direction
                    self.assertAlmostEqual(
                        vol(u, v, w)[0], bottom(u, v)[0] *
                        (1 - w) + top(u, v)[0] * w)  # x-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[1], bottom(u, v)[1] *
                        (1 - w) + top(u, v)[1] * w)  # y-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[2], 0 * (1 - w) + top(u, v)[2] * w)  # z-coordinate

        # test 3D surface vs 2D surface
        controlpoints = [[0, 0], [-1, 1], [0, 2], [1, -1], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3],
                         [3, 0], [4, 1], [3, 2]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(2, [0, 0, .4, .44, 1, 1])
        bottom = Surface(basis1, basis2, controlpoints)  # non-rational!

        vol = VolumeFactory.edge_surfaces(bottom, top)  # also non-rational!

        # verify on 5x5x7 evaluation grid
        for u in np.linspace(0, 1, 5):
            for v in np.linspace(0, 1, 5):
                for w in np.linspace(0, 1, 7):  # include inner evaluation points
                    self.assertAlmostEqual(
                        vol(u, v, w)[0], bottom(u, v)[0] *
                        (1 - w) + top(u, v)[0] * w)  # x-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[1], bottom(u, v)[1] *
                        (1 - w) + top(u, v)[1] * w)  # y-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[2], 0 * (1 - w) + top(u, v)[2] * w)  # z-coordinate
Beispiel #2
0
    def test_edge_surfaces(self):
        # test 3D surface vs 2D rational surface

        # more or less random 3D surface with p=[2,2] and n=[3,4]
        controlpoints = [[0, 0, 1], [-1, 1, 1], [0, 2, 1], [1, -1, 1], [1, 0, .5], [1, 1, 1],
                         [2, 1, 1], [2, 2, .5], [2, 3, 1], [3, 0, 1], [4, 1, 1], [3, 2, 1]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(3, [0, 0, 0, .64, 2, 2, 2])
        top = Surface(basis1, basis2, controlpoints)

        # more or less random 2D rational surface with p=[1,2] and n=[3,4]
        controlpoints = [[0, 0, 1], [-1, 1, .96], [0, 2, 1], [1, -1, 1], [1, 0, .8], [1, 1, 1],
                         [2, 1, .89], [2, 2, .9], [2, 3, 1], [3, 0, 1], [4, 1, 1], [3, 2, 1]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(2, [0, 0, .4, .44, 1, 1])
        bottom = Surface(basis1, basis2, controlpoints, True)

        vol = vf.edge_surfaces(bottom, top)

        # set parametric domain to [0,1]^2 for easier comparison
        top.reparam()
        bottom.reparam()

        # verify on 7x7x2 evaluation grid
        for u in np.linspace(0, 1, 7):
            for v in np.linspace(0, 1, 7):
                for w in np.linspace(0, 1, 2):  # rational basis, not linear in w-direction
                    self.assertAlmostEqual(
                        vol(u, v, w)[0], bottom(u, v)[0] *
                        (1 - w) + top(u, v)[0] * w)  # x-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[1], bottom(u, v)[1] *
                        (1 - w) + top(u, v)[1] * w)  # y-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[2], 0 * (1 - w) + top(u, v)[2] * w)  # z-coordinate

        # test 3D surface vs 2D surface
        controlpoints = [[0, 0], [-1, 1], [0, 2], [1, -1], [1, 0], [1, 1], [2, 1], [2, 2], [2, 3],
                         [3, 0], [4, 1], [3, 2]]
        basis1 = BSplineBasis(3, [0, 0, 0, 1, 1, 1])
        basis2 = BSplineBasis(2, [0, 0, .4, .44, 1, 1])
        bottom = Surface(basis1, basis2, controlpoints)  # non-rational!

        vol = vf.edge_surfaces(bottom, top)  # also non-rational!

        # verify on 5x5x7 evaluation grid
        for u in np.linspace(0, 1, 5):
            for v in np.linspace(0, 1, 5):
                for w in np.linspace(0, 1, 7):  # include inner evaluation points
                    self.assertAlmostEqual(
                        vol(u, v, w)[0], bottom(u, v)[0] *
                        (1 - w) + top(u, v)[0] * w)  # x-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[1], bottom(u, v)[1] *
                        (1 - w) + top(u, v)[1] * w)  # y-coordinate
                    self.assertAlmostEqual(
                        vol(u, v, w)[2], 0 * (1 - w) + top(u, v)[2] * w)  # z-coordinate
Beispiel #3
0
    def test_edge_surfaces_six_sides(self):
        # create the unit cube
        vol = Volume()
        vol.raise_order(2,2,2)
        vol.refine(3)

        edges = vol.faces()

        # edge_surface should give back the same unit cube
        vol2 = VolumeFactory.edge_surfaces(edges)

        # check discretization
        self.assertEqual(vol2.order(0), 4)
        self.assertEqual(vol2.order(1), 4)
        self.assertEqual(vol2.order(2), 4)

        self.assertEqual(len(vol2.knots(0)), 5) # [0,.25,.5,.75,1]
        self.assertEqual(len(vol2.knots(1)), 5)
        self.assertEqual(len(vol2.knots(2)), 5)

        # check a 5x5x5 evaluation grid
        u = np.linspace(0,1,5)
        v = np.linspace(0,1,5)
        w = np.linspace(0,1,5)
        pt  = vol( u,v,w)
        pt2 = vol2(u,v,w)
        self.assertAlmostEqual(np.linalg.norm(pt-pt2), 0.0)
Beispiel #4
0
    def test_edge_surfaces_six_sides_issue_141(self):
        # create the unit cube
        vol = Volume()
        # modify slightly one edge: umin(w=0) is now a parabola instead of a line
        vol.raise_order(0,1,0)
        vol.controlpoints[-1, 1, 0, 0] += 1

        faces = vol.faces()

        # edge_surface should give back the same modified unit cube
        vol2 = vf.edge_surfaces(faces)

        # check discretization
        self.assertEqual(vol2.order(0),2)
        self.assertEqual(vol2.order(1),3)
        self.assertEqual(vol2.order(2),2)

        self.assertEqual(len(vol2.knots(0)),2) # [0, 1]
        self.assertEqual(len(vol2.knots(1)),2)
        self.assertEqual(len(vol2.knots(2)),2)

        # check a 5x5x5 evaluation grid
        u = np.linspace(0,1,5)
        v = np.linspace(0,1,5)
        w = np.linspace(0,1,5)
        pt  = vol( u,v,w)
        pt2 = vol2(u,v,w)

        self.assertTrue(np.allclose(pt, pt2))
Beispiel #5
0
    def test_edge_surfaces_six_sides(self):
        # create the unit cube
        vol = Volume()
        vol.raise_order(2,2,2)
        vol.refine(3)

        edges = vol.faces()

        # edge_surface should give back the same unit cube
        vol2 = vf.edge_surfaces(edges)

        # check discretization
        self.assertEqual(vol2.order(0), 4)
        self.assertEqual(vol2.order(1), 4)
        self.assertEqual(vol2.order(2), 4)

        self.assertEqual(len(vol2.knots(0)), 5) # [0,.25,.5,.75,1]
        self.assertEqual(len(vol2.knots(1)), 5)
        self.assertEqual(len(vol2.knots(2)), 5)

        # check a 5x5x5 evaluation grid
        u = np.linspace(0,1,5)
        v = np.linspace(0,1,5)
        w = np.linspace(0,1,5)
        pt  = vol( u,v,w)
        pt2 = vol2(u,v,w)
        self.assertAlmostEqual(np.linalg.norm(pt-pt2), 0.0)
Beispiel #6
0
    def texture(self, p, ngeom, ntexture, method='full', irange=[None,None], jrange=[None,None]):
        # Set the dimensions of geometry and texture map
        # ngeom    = np.floor(self.n / (p-1))
        # ntexture = np.floor(self.n * n)
        # ngeom    = ngeom.astype(np.int32)
        # ntexture = ntexture.astype(np.int32)
        ngeom    = ensure_listlike(ngeom, 3)
        ntexture = ensure_listlike(ntexture, 3)
        p        = ensure_listlike(p, 3)


        # Create the geometry
        ngx, ngy, ngz = ngeom
        b1 = BSplineBasis(p[0], [0]*(p[0]-1) + [i/ngx for i in range(ngx+1)] + [1]*(p[0]-1))
        b2 = BSplineBasis(p[1], [0]*(p[1]-1) + [i/ngy for i in range(ngy+1)] + [1]*(p[1]-1))
        b3 = BSplineBasis(p[2], [0]*(p[2]-1) + [i/ngz for i in range(ngz+1)] + [1]*(p[2]-1))

        l2_fit = surface_factory.least_square_fit
        vol = self.get_c0_mesh()

        i = slice(irange[0], irange[1], None)
        j = slice(jrange[0], jrange[1], None)
        # special case number of evaluation points for full domain
        if irange[1] == None: irange[1] = vol.shape[0]
        if jrange[1] == None: jrange[1] = vol.shape[1]
        if irange[0] == None: irange[0] = 0
        if jrange[0] == None: jrange[0] = 0

        nu = np.diff(irange)
        nv = np.diff(jrange)
        nw = vol.shape[2]

        u = np.linspace(0, 1, nu)
        v = np.linspace(0, 1, nv)
        w = np.linspace(0, 1, nw)

        crvs = []
        crvs.append(curve_factory.polygon(vol[i          ,jrange[0]  , 0,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[i          ,jrange[0]  ,-1,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[i          ,jrange[1]-1, 0,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[i          ,jrange[1]-1,-1,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[0]  ,j          , 0,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[0]  ,j          ,-1,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[1]-1,j          , 0,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[1]-1,j          ,-1,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[0]  ,jrange[0]  , :,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[0]  ,jrange[1]-1, :,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[1]-1,jrange[0]  , :,:].squeeze()))
        crvs.append(curve_factory.polygon(vol[irange[1]-1,jrange[1]-1, :,:].squeeze()))
#        with G2('curves.g2') as myfile:
#            myfile.write(crvs)
#        print('Written curve.g2')


        if method == 'full':
            bottom = l2_fit(vol[i,          j,          0,:].squeeze(), [b1, b2], [u, v])
            top    = l2_fit(vol[i,          j,         -1,:].squeeze(), [b1, b2], [u, v])
            left   = l2_fit(vol[irange[0]  ,j,          :,:].squeeze(), [b2, b3], [v, w])
            right  = l2_fit(vol[irange[1]-1,j,          :,:].squeeze(), [b2, b3], [v, w])
            front  = l2_fit(vol[i,          jrange[0],  :,:].squeeze(), [b1, b3], [u, w])
            back   = l2_fit(vol[i,          jrange[1]-1,:,:].squeeze(), [b1, b3], [u, w])
            volume = volume_factory.edge_surfaces([left, right, front, back, bottom, top])

        elif method == 'z':
            bottom = l2_fit(vol[i,j, 0,:].squeeze(), [b1, b2], [u, v])
            top    = l2_fit(vol[i,j,-1,:].squeeze(), [b1, b2], [u, v])
            volume = volume_factory.edge_surfaces([bottom, top])
            volume.set_order(*p)
            volume.refine(ngz - 1, direction='w')

        volume.reverse(direction=2)

        # Point-to-cell mapping
        # TODO: Optimize more
        eps = 1e-2
        u = [np.linspace(eps, 1-eps, n) for n in ntexture]
        points = volume(*u).reshape(-1, 3)
        cellids = np.zeros(points.shape[:-1], dtype=int)
        cell = None
        nx, ny, nz = self.n
        for ptid, point in enumerate(tqdm(points, desc='Inverse mapping')):
            i, j, k = cell = self.raw.cell_at(point) # , guess=cell)
            cellid = i*ny*nz + j*nz + k
            cellids[ptid] = cellid

        cellids = cellids.reshape(tuple(ntexture))

        all_textures = {}
        for name in self.attribute:
            data = self.attribute[name][cellids]

            # TODO: This flattens the image if it happens to be 3D (or higher...)
            # do we need a way to communicate the structure back to the caller?
            # data = data.reshape(-1, data.shape[-1])

            # TODO: This normalizes the image,
            # but we need a way to communicate the ranges back to the caller
            # a, b = min(data.flat), max(data.flat)
            # data = ((data - a) / (b - a) * 255).astype(np.uint8)

            all_textures[name] = data
        all_textures['cellids'] = cellids

        return volume, all_textures