Пример #1
0
    def shape_functions(self,xi1,xi2,number_of_derivatives=0):
        
        if number_of_derivatives > 1: raise "Only coded for first derivative"
        # Make sure values are floating point
        xi1=np.asarray(xi1,np.float).reshape(-1,) 
        xi2=np.asarray(xi2,np.float).reshape(-1,)        
        
        num = np.size(xi1)
        
        Bi = NURBSinC.multiAllBernsteinDers(self.n,xi1,number_of_derivatives)
        Bj = NURBSinC.multiAllBernsteinDers(self.m,xi2,number_of_derivatives)  

        N = Bi[:,0].reshape(num,-1,1) * Bj[:,0].reshape(num,1,-1) * self.wmat
        W = np.sum(np.sum(N,1),1).reshape(-1,1,1)

        if number_of_derivatives==1:
                            
            R = np.zeros((num,(self.n+1)*(self.m+1),3))
            
            Nu = Bi[:,1].reshape(num,-1,1) * Bj[:,0].reshape(num,1,-1) * self.wmat
            Wu = np.sum(np.sum(Nu,1),1).reshape(-1,1,1)
            Nv = Bi[:,0].reshape(num,-1,1) * Bj[:,1].reshape(num,1,-1) * self.wmat
            Wv = np.sum(np.sum(Nv,1),1).reshape(-1,1,1)

            R[:,:,0] = (N/W).reshape(num,-1)
            # From formula S_alpha(u,v) in NURBS books pg 136
            R[:,:,1] = ((Nu*W-N*Wu)/(W**2)).reshape(num,-1)
            R[:,:,2] = ((Nv*W-N*Wv)/(W**2)).reshape(num,-1)
            
        else:
            R = np.zeros((num,(self.n+1)*(self.m+1),1))
            R[:,:,0] = (N/W).reshape(num,-1)
            
        return R
Пример #2
0
 def NURBS_basis_functions(self,xi,num_derivatives=0):
     xi = np.asarray(xi,np.float).reshape(-1,)
     spans = NURBSinC.multiFindSpan(self.n,self.p,xi,self.U)
     if num_derivatives==1:
         N = NURBSinC.multidersNURBSbasis(spans,xi,self.p,1,self.U,self.w)
     else:
         N = np.zeros((xi.size,1,self.n+1))
         N[:,0,:] = NURBSinC.multiNURBSbasis(spans,xi,self.p,self.U,self.w)
     return N
Пример #3
0
 def NURBS_basis_functions(self, xi, num_derivatives=0):
     xi = np.asarray(xi, np.float).reshape(-1, )
     spans = NURBSinC.multiFindSpan(self.n, self.p, xi, self.U)
     if num_derivatives == 1:
         N = NURBSinC.multidersNURBSbasis(spans, xi, self.p, 1, self.U,
                                          self.w)
     else:
         N = np.zeros((xi.size, 1, self.n + 1))
         N[:, 0, :] = NURBSinC.multiNURBSbasis(spans, xi, self.p, self.U,
                                               self.w)
     return N
Пример #4
0
 def shape_functions(self,xi,number_of_derivatives=0):
     """Returns the basis functions on the element
     in the form [i,j,d] where:
         i: xi coordinate index
         j: Bezier function index
         d: derivative"""
     if number_of_derivatives > 1: raise "Only coded for first derivative"
     xi=np.asarray(xi,np.float).reshape(-1,)
     if number_of_derivatives==1:
         B = NURBSinC.multiRationalBernsteinDers(self.n,self.Pw.T,xi,1)
     else:
         B = np.zeros((xi.size,self.n+1,1))
         B[:,:,0] = NURBSinC.multiRationalBernstein(self.n,self.Pw.T,xi)
     return B
Пример #5
0
 def shape_functions(self, xi, number_of_derivatives=0):
     """Returns the basis functions on the element
     in the form [i,j,d] where:
         i: xi coordinate index
         j: Bezier function index
         d: derivative"""
     if number_of_derivatives > 1: raise "Only coded for first derivative"
     xi = np.asarray(xi, np.float).reshape(-1, )
     if number_of_derivatives == 1:
         B = NURBSinC.multiRationalBernsteinDers(self.n, self.Pw.T, xi, 1)
     else:
         B = np.zeros((xi.size, self.n + 1, 1))
         B[:, :, 0] = NURBSinC.multiRationalBernstein(self.n, self.Pw.T, xi)
     return B
Пример #6
0
 def NURBSbasis(self,uv,i=None,j=None):
     """Evaluate one basis function given uv, a (2,-1) matrix"""
     if uv.shape[1]>1:
         if i!=None and j!=None:
             uspan = NURBSinC.multiFindSpan(self.n,self.p,uv[0],self.U)
             Nu = NURBSinC.multiBasisFuns(uspan,uv[0],self.p,self.U)
             vspan = NURBSinC.multiFindSpan(self.m,self.q,uv[1],self.V)
             Nv = NURBSinC.multiBasisFuns(vspan,uv[1],self.q,self.V)
             denominator = np.zeros(uv.shape[1],)
             for k in xrange(self.n+1):
                 for l in xrange(self.m+1):
                     denominator += Nu[:,k]*Nv[:,l]*self.w[k,l]
             return Nu[:,i]*Nv[:,j]*self.w[i,j] / denominator
         else:
             return NURBSinC.multiSurfaceBasis(uv,self.p,self.n,self.U,self.q,self.m,self.V,self.w)
     else:
         print "Need to 'NURBSbasis' for single point"
Пример #7
0
 def NURBSbasis(self, uv, i=None, j=None):
     """Evaluate one basis function given uv, a (2,-1) matrix"""
     if uv.shape[1] > 1:
         if i != None and j != None:
             uspan = NURBSinC.multiFindSpan(self.n, self.p, uv[0], self.U)
             Nu = NURBSinC.multiBasisFuns(uspan, uv[0], self.p, self.U)
             vspan = NURBSinC.multiFindSpan(self.m, self.q, uv[1], self.V)
             Nv = NURBSinC.multiBasisFuns(vspan, uv[1], self.q, self.V)
             denominator = np.zeros(uv.shape[1], )
             for k in xrange(self.n + 1):
                 for l in xrange(self.m + 1):
                     denominator += Nu[:, k] * Nv[:, l] * self.w[k, l]
             return Nu[:, i] * Nv[:, j] * self.w[i, j] / denominator
         else:
             return NURBSinC.multiSurfaceBasis(uv, self.p, self.n, self.U,
                                               self.q, self.m, self.V,
                                               self.w)
     else:
         print "Need to 'NURBSbasis' for single point"
Пример #8
0
    def refineknotvector(self, XI, knotvec_choice):
        """Insert the knots contained in XI into U or V"""
        XI = np.asarray(XI, np.float).reshape(-1, )
        if knotvec_choice == 'U':
            if np.min(XI) <= np.min(self.U):
                raise "Knots cannot be inserted: some elements too small"
            if np.max(XI) >= np.max(self.U):
                raise "Knots cannot be inserted: some elements too large"
            if np.any([
                    np.equal(xi, self.U).sum() + np.equal(xi, XI).sum() >
                    self.p for xi in np.unique(XI)
            ]):
                raise "Knots cannot be inserted: some multiplicities too large"
            self.U, self.V, self.Pw = NURBSinC.RefineKnotVectSurface(
                self.n, self.p, self.U, self.m, self.q, self.V, self.Pw, XI, 0)
            self.r = self.U.shape[0] - 1
            self.n = self.r - self.p - 1
            self.pspans = np.unique(self.U)

        if knotvec_choice == 'V':
            if np.min(XI) <= np.min(self.V):
                raise "Knots cannot be inserted: some elements too small"
            if np.max(XI) >= np.max(self.V):
                raise "Knots cannot be inserted: some elements too large"
            if np.any([
                    np.equal(xi, self.V).sum() + np.equal(xi, XI).sum() >
                    self.q for xi in np.unique(XI)
            ]):
                raise "Knots cannot be inserted: some multiplicities too large"
            self.V, self.U, self.Pw = NURBSinC.RefineKnotVectSurface(
                self.m, self.q, self.V, self.n, self.p, self.U,
                np.transpose(self.Pw, (1, 0, 2)), XI, 0)
            self.Pw = np.transpose(self.Pw, (1, 0, 2))

            self.s = self.V.shape[0] - 1
            self.m = self.s - self.q - 1
            self.qspans = np.unique(self.V)

        self.P = (self.Pw[:, :, :3].T / self.Pw[:, :, 3].T).T
        self.w = self.Pw[:, :, 3]
Пример #9
0
    def shape_functions(self, xi1, xi2, number_of_derivatives=0):

        if number_of_derivatives > 1: raise "Only coded for first derivative"
        # Make sure values are floating point
        xi1 = np.asarray(xi1, np.float).reshape(-1, )
        xi2 = np.asarray(xi2, np.float).reshape(-1, )

        num = np.size(xi1)

        Bi = NURBSinC.multiAllBernsteinDers(self.n, xi1, number_of_derivatives)
        Bj = NURBSinC.multiAllBernsteinDers(self.m, xi2, number_of_derivatives)

        N = Bi[:, 0].reshape(num, -1, 1) * Bj[:, 0].reshape(num, 1,
                                                            -1) * self.wmat
        W = np.sum(np.sum(N, 1), 1).reshape(-1, 1, 1)

        if number_of_derivatives == 1:

            R = np.zeros((num, (self.n + 1) * (self.m + 1), 3))

            Nu = Bi[:, 1].reshape(num, -1, 1) * Bj[:, 0].reshape(
                num, 1, -1) * self.wmat
            Wu = np.sum(np.sum(Nu, 1), 1).reshape(-1, 1, 1)
            Nv = Bi[:, 0].reshape(num, -1, 1) * Bj[:, 1].reshape(
                num, 1, -1) * self.wmat
            Wv = np.sum(np.sum(Nv, 1), 1).reshape(-1, 1, 1)

            R[:, :, 0] = (N / W).reshape(num, -1)
            # From formula S_alpha(u,v) in NURBS books pg 136
            R[:, :, 1] = ((Nu * W - N * Wu) / (W**2)).reshape(num, -1)
            R[:, :, 2] = ((Nv * W - N * Wv) / (W**2)).reshape(num, -1)

        else:
            R = np.zeros((num, (self.n + 1) * (self.m + 1), 1))
            R[:, :, 0] = (N / W).reshape(num, -1)

        return R
Пример #10
0
 def refineknotvector(self, XI):
     XI = np.asarray(XI, np.float).reshape(-1, )
     """Refine the curve knot vector"""
     if np.min(XI) <= np.min(self.U):
         raise "Knots cannot be inserted: some values too small"
     if np.max(XI) >= np.max(self.U):
         raise "Knots cannot be inserted: some values too large"
     if np.any([
             np.equal(xi, self.U).sum() + np.equal(xi, XI).sum() > self.p
             for xi in np.unique(XI)
     ]):
         raise "Knots cannot be inserted: some multiplicities too high"
     self.n, self.U, self.Pw = NURBSinC.RefineKnotVectCurve(
         self.n, self.p, self.U, self.Pw, XI)
     self.P, self.w = (self.Pw[:, :2].T / self.Pw[:, 2].T).T, self.Pw[:, 2]
Пример #11
0
 def decompose(self):
     """Decompose NURBS surface into rational Bezier patches"""
     return NURBSinC.DecomposeSurface(self.n, self.p, self.U, self.m,
                                      self.q, self.V, self.Pw)
Пример #12
0
 def vals(self, u, v):
     """Return coordinates of NURBS surface at (u,v)"""
     u = np.asarray(u, np.float).reshape(-1, )
     v = np.asarray(v, np.float).reshape(-1, )
     return NURBSinC.multiSurfacePoint(self.n, self.p, self.U, self.m,
                                       self.q, self.V, self.Pw, u, v)
Пример #13
0
 def vals(self,u,v):
     """Return coordinates of NURBS surface at (u,v)"""
     u=np.asarray(u,np.float).reshape(-1,)
     v=np.asarray(v,np.float).reshape(-1,)
     return NURBSinC.multiSurfacePoint(self.n,self.p,self.U,self.m,self.q,self.V,self.Pw,u,v)
Пример #14
0
 def decompose_into_Bezier_segments(self):
     nb, Qw = NURBSinC.DecomposeCurve(self.n, self.p, self.U, self.Pw)
     return nb, Qw