Commits

committed 688367f

Make NURBS instances callable

• Participants
• Parent commits 6807f16

File demo/createc1fromlines.py

` `
` def curve_length(c,res=1000):`
`     u=np.linspace((c.knots[0])[0],(c.knots[0])[-1],res,endpoint=True)`
`-    C = c.evaluate(u)`
`+    C = c(u)`
`     L=0.`
`     for i in range(C.shape[0]-1):`
`         L += np.linalg.norm(C[i+1,:]-C[i,:])`
` yet have the python interface.`
` """`
` u=np.linspace(0,1,1000,endpoint=True)`
`-c=final.evaluate(u)`
`+c=final(u)`
` plt.plot(x_b[:,0],x_b[:,1],'bo',markersize=ms)`
` plt.plot(x_t[:,0],x_t[:,1],'bo',markersize=ms)`
` plt.plot(c[:,0],c[:,1],'-y')`

`     >>> crv = circle()`
`     >>> crv.shape`
`     (9,)`
`-    >>> P = crv.evaluate([0, 0.25, 0.5, 0.75, 1])`
`+    >>> P = crv([0, 0.25, 0.5, 0.75, 1])`
`     >>> assert np.allclose(P[0], ( 1,  0, 0))`
`     >>> assert np.allclose(P[1], ( 0,  1, 0))`
`     >>> assert np.allclose(P[2], (-1,  0, 0))`
`     >>> crv = circle(angle=3*Pi/2)`
`     >>> crv.shape`
`     (7,)`
`-    >>> P = crv.evaluate([0, 1/3., 2/3., 1])`
`+    >>> P = crv([0, 1/3., 2/3., 1])`
`     >>> assert np.allclose(P[0], ( 1,  0, 0))`
`     >>> assert np.allclose(P[1], ( 0,  1, 0))`
`     >>> assert np.allclose(P[2], (-1,  0, 0))`
`     >>> crv = circle(radius=2, center=(1,1), angle=(Pi/2,-Pi/2))`
`     >>> crv.shape`
`     (5,)`
`-    >>> P = crv.evaluate([0, 0.5, 1])`
`+    >>> P = crv([0, 0.5, 1])`
`     >>> assert np.allclose(P[0], (1,  3, 0))`
`     >>> assert np.allclose(P[1], (3,  1, 0))`
`     >>> assert np.allclose(P[2], (1, -1, 0))`
`     >>> crv = circle(radius=3, center=2, angle=Pi/2)`
`     >>> crv.shape`
`     (3,)`
`-    >>> P = crv.evaluate([0, 1])`
`+    >>> P = crv([0, 1])`
`     >>> assert np.allclose(P[0], ( 5, 0, 0))`
`     >>> assert np.allclose(P[1], ( 2, 3, 0))`
` `
`     p, U = C10.degree[0], C10.knots[0]`
`     u0, u1 = U[p], U[-p-1]`
`     P = np.zeros((2,2,3), dtype='d')`
`-    P[0,0] = C10.evaluate(u0)`
`-    P[1,0] = C10.evaluate(u1)`
`-    P[0,1] = C11.evaluate(u0)`
`-    P[1,1] = C11.evaluate(u1)`
`+    P[0,0] = C10(u0)`
`+    P[1,0] = C10(u1)`
`+    P[0,1] = C11(u0)`
`+    P[1,1] = C11(u1)`
`     #`
`     q, V = C00.degree[0], C00.knots[0]`
`     v0, v1 = V[q], V[-q-1]`
`     Q = np.zeros((2,2,3), dtype='d')`
`-    Q[0,0] = C00.evaluate(v0)`
`-    Q[0,1] = C00.evaluate(v1)`
`-    Q[1,0] = C01.evaluate(v0)`
`-    Q[1,1] = C01.evaluate(v1)`
`+    Q[0,0] = C00(v0)`
`+    Q[0,1] = C00(v1)`
`+    Q[1,0] = C01(v0)`
`+    Q[1,1] = C01(v1)`
`     #`
`     assert np.allclose(P, Q, rtol=0, atol=1e-15)`
`     #`

File src/igakit/io.py

`         flag = bool(scalars or vectors)`
`         if not flag: fields = flag`
`         elif fields is None: fields = flag`
`-        out = nurbs.evaluate(*uvw, **dict(fields=fields))`
`+        out = nurbs(*uvw, **dict(fields=fields))`
`         if flag: C, F = out`
`         else:    C, F = out, out[..., 0:0]`
` `

File src/igakit/nurbs.py

`     >>> U = [0,0,0, 1,1,1]           # knot vector`
`     >>> crv = NURBS([U], C, weights=w)`
`     >>> u = np.linspace(0,1,1000)`
`-    >>> xyz = crv.evaluate(u)`
`+    >>> xyz = crv(u)`
`     >>> x, y, z = xyz.T`
`     >>> r = np.sqrt(x**2+y**2)`
`     >>> np.allclose(r, 1, rtol=0, atol=1e-15)`
`     >>> Cw[2,:] = [1.0, 0.0, 0.0, 1.0]`
`     >>> crv = NURBS([U], Cw)`
`     >>> u = np.linspace(0,1,1000)`
`-    >>> xyz = crv.evaluate(u)`
`+    >>> xyz = crv(u)`
`     >>> x, y, z = xyz.T`
`     >>> r = np.sqrt(x**2+y**2)`
`     >>> np.allclose(r, 1, rtol=0, atol=1e-15)`
`         >>> vol1 = NURBS([U,V,W], C)`
`         >>> vol2 = vol1.clone().transpose([0,2,1])`
`         >>> u = 0.25; v = 0.50; w = 0.75`
`-        >>> xyz1 = vol1.evaluate(u,v,w)`
`-        >>> xyz2 = vol2.evaluate(u,w,v)`
`+        >>> xyz1 = vol1(u, v, w)`
`+        >>> xyz2 = vol2(u, w, v)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
`         >>> vol3 = vol1.clone().transpose()`
`-        >>> xyz3 = vol3.evaluate(w,v,u)`
`+        >>> xyz3 = vol3(w,v,u)`
`         >>> np.allclose(xyz1, xyz3, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> vol2 = vol1.clone().swap(1,2)`
`         >>> vol3 = vol1.clone().swap(0,-1)`
`         >>> u = 0.25; v = 0.50; w = 0.75`
`-        >>> xyz1 = vol1.evaluate(u,v,w)`
`-        >>> xyz2 = vol2.evaluate(u,w,v)`
`-        >>> xyz3 = vol3.evaluate(w,v,u)`
`+        >>> xyz1 = vol1(u, v, w)`
`+        >>> xyz2 = vol2(u, w, v)`
`+        >>> xyz3 = vol3(w, v, u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
`         >>> np.allclose(xyz1, xyz3, rtol=0, atol=1e-15)`
`         >>> c2 = c1.copy()`
`         >>> c2 = c2.reverse()`
`         >>> u = 0.3`
`-        >>> (abs(c1.evaluate(u)-c2.evaluate(1.0-u))).max() < 1.0e-15`
`+        >>> (abs(c1(u)-c2(1.0-u))).max() < 1.0e-15`
`         True`
` `
`         """`
`         >>> C = np.random.rand(6,3)`
`         >>> U = [0,0,0,0.25,0.75,0.75,1,1,1]`
`         >>> c0 = NURBS([U], C)`
`-        >>> v0 = c0.evaluate([0,0.5,1])`
`+        >>> v0 = c0([0,0.5,1])`
`         >>> c1 = c0.copy().remap(0, -2, 2)`
`         >>> c1.knots[0].tolist()`
`         [-2.0, -2.0, -2.0, -1.0, 1.0, 1.0, 2.0, 2.0, 2.0]`
`-        >>> v1 = c1.evaluate([-2,0.0,2])`
`+        >>> v1 = c1([-2,0.0,2])`
`         >>> np.allclose(v0, v1, rtol=0, atol=1e-15)`
`         True`
`         >>> c2 = c0.copy().remap(0, None, 2)`
`         >>> c2.knots[0].tolist()`
`         [0.0, 0.0, 0.0, 0.5, 1.5, 1.5, 2.0, 2.0, 2.0]`
`-        >>> v2 = c2.evaluate([0,1.0,2])`
`+        >>> v2 = c2([0,1.0,2])`
`         >>> np.allclose(v0, v2, rtol=0, atol=1e-15)`
`         True`
`         >>> c3 = c0.copy().remap(0, -1, None)`
`         >>> c3.knots[0].tolist()`
`         [-1.0, -1.0, -1.0, -0.5, 0.5, 0.5, 1.0, 1.0, 1.0]`
`-        >>> v3 = c3.evaluate([-1,0.0,1])`
`+        >>> v3 = c3([-1,0.0,1])`
`         >>> np.allclose(v0, v3, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> c3 = c2.clone().insert(0, 0.50, 2)`
`         >>> c4 = c3.clone().insert(0, 0.75, 3)`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`-        >>> xyz3 = c3.evaluate(u)`
`-        >>> xyz4 = c4.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`+        >>> xyz3 = c3(u)`
`+        >>> xyz4 = c4(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
`         >>> np.allclose(xyz1, xyz3, rtol=0, atol=1e-15)`
`         >>> s2.shape`
`         (5, 5)`
`         >>> u = v = np.linspace(0,1,100)`
`-        >>> xyz1 = s1.evaluate(u, v)`
`-        >>> xyz2 = s2.evaluate(u, v)`
`+        >>> xyz1 = s1(u, v)`
`+        >>> xyz2 = s2(u, v)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> c3.shape`
`         (5,)`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`-        >>> xyz3 = c3.evaluate(u)`
`-        >>> xyz4 = c4.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`+        >>> xyz3 = c3(u)`
`+        >>> xyz4 = c4(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
`         >>> np.allclose(xyz1, xyz3, rtol=0, atol=1e-15)`
`         >>> c2.knots[0].tolist()`
`         [-2.0, -1.0, 0.0, 1.0, 2.0, 3.0]`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> c3.knots[0].tolist()`
`         [-2.0, -1.0, 0.0, 1.0, 1.0, 1.0]`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> c4.knots[0].tolist()`
`         [0.0, 0.0, 0.0, 1.0, 2.0, 3.0]`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> s3.shape`
`         (8, 7)`
`         >>> u = v = np.linspace(0,1,100)`
`-        >>> xyz1 = s1.evaluate(u, v)`
`-        >>> xyz2 = s2.evaluate(u, v)`
`-        >>> xyz3 = s3.evaluate(u, v)`
`+        >>> xyz1 = s1(u, v)`
`+        >>> xyz2 = s2(u, v)`
`+        >>> xyz3 = s3(u, v)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
`         >>> np.allclose(xyz1, xyz3, rtol=0, atol=1e-15)`
`         >>> c2.degree`
`         (4,)`
`         >>> u = np.linspace(0,1,100)`
`-        >>> xyz1 = c1.evaluate(u)`
`-        >>> xyz2 = c2.evaluate(u)`
`+        >>> xyz1 = c1(u)`
`+        >>> xyz2 = c2(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> s2.degree`
`         (3, 2)`
`         >>> u = v = np.linspace(0,1,100)`
`-        >>> xyz1 = s1.evaluate(u, v)`
`-        >>> xyz2 = s2.evaluate(u, v)`
`+        >>> xyz1 = s1(u, v)`
`+        >>> xyz2 = s2(u, v)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> crv = NURBS([U], C)`
`         >>> sub = crv.slice(0,0.5,0.75)`
`         >>> u = np.linspace(0.5,0.75,100)`
`-        >>> xyz1 = crv.evaluate(u)`
`-        >>> xyz2 = sub.evaluate(u)`
`+        >>> xyz1 = crv(u)`
`+        >>> xyz2 = sub(u)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=1e-15)`
`         True`
` `
`         >>> sub = srf.slice(0,1./3,2./3)`
`         >>> u = np.linspace(1./3,2./3,100)`
`         >>> v = np.linspace(0,1,100)`
`-        >>> xyz1 = srf.evaluate(u,v)`
`-        >>> xyz2 = sub.evaluate(u,v)`
`+        >>> xyz1 = srf(u, v)`
`+        >>> xyz2 = sub(u, v)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=2e-15)`
`         True`
` `
`         >>> u = np.linspace(1./3,2./3,100)`
`         >>> v = np.linspace(0.25,0.75,100)`
`         >>> w = np.linspace(0,1,100)`
`-        >>> xyz1 = vol.evaluate(u,v,w)`
`-        >>> xyz2 = sub.evaluate(u,v,w)`
`+        >>> xyz1 = vol(u, v, w)`
`+        >>> xyz2 = sub(u, v, w)`
`         >>> np.allclose(xyz1, xyz2, rtol=0, atol=2e-15)`
`         True`
` `
`         ()`
`         >>> pnt.degree`
`         ()`
`-        >>> p1 = vol.evaluate(u,v,w)`
`-        >>> p2 = srf.evaluate(u,v)`
`-        >>> p3 = crv.evaluate(u)`
`-        >>> p4 = pnt.evaluate()`
`+        >>> p1 = vol(u, v, w)`
`+        >>> p2 = srf(u, v)`
`+        >>> p3 = crv(u)`
`+        >>> p4 = pnt()`
`         >>> np.allclose(p1, p2, rtol=0, atol=1e-15)`
`         True`
`         >>> np.allclose(p1, p3, rtol=0, atol=1e-15)`
` `
`     #`
` `
`+    def __call__(self, u=None, v=None, w=None, fields=False):`
`+        """`
`+        Evaluate the NURBS object at the given parametric values.`
`+`
`+        Parameters`
`+        ----------`
`+        u, v, w : float or array_like, optional`
`+        fields : bool or array_like, optional`
`+`
`+        Examples`
`+        --------`
`+`
`+        >>> C = [[-1,0],[0,1],[1,0]]`
`+        >>> U = [0,0,0,1,1,1]`
`+        >>> crv = NURBS([U], C)`
`+        >>> crv(0.5).tolist()`
`+        [0.0, 0.5, 0.0]`
`+        >>> crv([0.5]).tolist()`
`+        [[0.0, 0.5, 0.0]]`
`+        >>> crv([0,1]).tolist()`
`+        [[-1.0, 0.0, 0.0], [1.0, 0.0, 0.0]]`
`+`
`+        """`
`+        def Arg(p, U, u):`
`+            u = np.asarray(u, dtype='d')`
`+            assert u.min() >= U[p]`
`+            assert u.max() <= U[-p-1]`
`+            return u`
`+        #`
`+        dim = self.dim`
`+        uvw = [u,v,w][:dim]`
`+        for i, a in enumerate(uvw):`
`+            if a is None:`
`+                uvw[i] = self.greville(i)`
`+            else:`
`+                U = self.knots[i]`
`+                p = self.degree[i]`
`+                uvw[i] = Arg(p, U, a)`
`+        #`
`+        if fields is True:`
`+            array = self.array`
`+        elif fields is False:`
`+            array = np.ascontiguousarray(self.control)`
`+            fields = False`
`+        else:`
`+            F = np.asarray(fields, dtype='d')`
`+            fields = True`
`+            shape = self.shape`
`+            if F.shape == shape:`
`+                F = F[...,np.newaxis]`
`+            else:`
`+                assert F.ndim-1 == len(shape)`
`+                assert F.shape[:-1] == shape`
`+            Cw = self.control`
`+            w = Cw[...,3,np.newaxis]`
`+            CwF = np.concatenate([Cw, F*w], axis=-1)`
`+            array = np.ascontiguousarray(CwF)`
`+        #`
`+        arglist = []`
`+        for p, U in zip(self.degree, self.knots):`
`+            arglist.extend([p, U])`
`+        arglist.append(array)`
`+        arglist.extend(uvw)`
`+        #`
`+        Evaluate = getattr(_bsp, 'Evaluate%d' % self.dim)`
`+        CwF = Evaluate(*arglist)`
`+        w = CwF[...,3,np.newaxis]`
`+        C = CwF[...,:3] / w`
`+        if fields:`
`+            F = CwF[...,4:] / w`
`+        else:`
`+            F = None`
`+        #`
`+        shape = list(C.shape[:-1])`
`+        remove = [i for (i, a) in enumerate(uvw) if not a.ndim]`
`+        for i in reversed(remove): del shape[i]`
`+        C.shape = shape + [-1]`
`+        if fields:`
`+            F.shape = shape + [-1]`
`+        #`
`+        if fields:`
`+            return C, F`
`+        else:`
`+            return C`
`+`
`     def evaluate(self, u=None, v=None, w=None, fields=None):`
`         """`
`         Evaluate the NURBS object at the given parametric values.`

File src/igakit/plot.py

` `
`     def kpoint(self, nurbs, **kwargs):`
`         uvw = nurbs.breaks()`
`-        C = nurbs.evaluate(*uvw)`
`+        C = nurbs(*uvw)`
`         x, y, z = C.T`
`         #`
`         options = dict(kwargs)`
`             a = np.linspace(u[0], u[-1], resolution)`
`             abc = list(uvw)`
`             abc[axis] = a`
`-            C = nurbs.evaluate(*abc)`
`+            C = nurbs(*abc)`
`             C = np.rollaxis(C, axis, -1)`
`             C = C.reshape((-1, a.size, 3))`
`             lines.extend(C)`
`                 resolution = self.backend._resolution[2]`
`                 uvw = [np.linspace(U[p], U[-p-1], resolution)`
`                        for (p, U) in zip(nrb.degree, nrb.knots)]`
`-                C = nrb.evaluate(*uvw)`
`+                C = nrb(*uvw)`
`                 surfs.append(C)`
`         #`
`         options = dict(kwargs)`
`         resolution = self.backend._resolution[1]`
`         p, U = nurbs.degree[0], nurbs.knots[0]`
`         u = np.linspace(U[p], U[-p-1], resolution)`
`-        C = nurbs.evaluate(u)`
`+        C = nurbs(u)`
`         x, y, z = C.T`
`         #`
`         options = dict(kwargs)`
`             resolution = self.backend._resolution[2]`
`             uvw = [np.linspace(U[p], U[-p-1], resolution)`
`                    for (p, U) in zip(nrb.degree, nrb.knots)]`
`-            C = nrb.evaluate(*uvw)`
`+            C = nrb(*uvw)`
`             surfs.append(C)`
`         #`
`         options = dict(kwargs)`