Commits

Lisandro Dalcin  committed 688367f

Make NURBS instances callable

  • Participants
  • Parent commits 6807f16

Comments (0)

Files changed (5)

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')

File src/igakit/cad.py

     >>> 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)