1 /*
2  * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
3  * Applied Mathematics, Norway.
4  *
5  * Contact information: E-mail: tor.dokken@sintef.no
6  * SINTEF ICT, Department of Applied Mathematics,
7  * P.O. Box 124 Blindern,
8  * 0314 Oslo, Norway.
9  *
10  * This file is part of SISL.
11  *
12  * SISL is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Affero General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * SISL is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Affero General Public License for more details.
21  *
22  * You should have received a copy of the GNU Affero General Public
23  * License along with SISL. If not, see
24  * <http://www.gnu.org/licenses/>.
25  *
26  * In accordance with Section 7(b) of the GNU Affero General Public
27  * License, a covered work must retain the producer line in every data
28  * file that is created or manipulated using SISL.
29  *
30  * Other Usage
31  * You can be released from the requirements of the license by purchasing
32  * a commercial license. Buying such a license is mandatory as soon as you
33  * develop commercial activities involving the SISL library without
34  * disclosing the source code of your own applications.
35  *
36  * This file may be used in accordance with the terms contained in a
37  * written agreement between you and SINTEF ICT.
38  */
39 
40 #include "sisl-copyright.h"
41 
42 /*
43  *
44  * $Id: s6crvcheck.c,v 1.3 2001-03-19 15:59:01 afr Exp $
45  *
46  */
47 
48 
49 #define S6CRVCHECK
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s6crvcheck(SISLCurve * pc,int * jstat)55 s6crvcheck(SISLCurve *pc,int *jstat)
56 #else
57 void s6crvcheck(pc,jstat)
58      SISLCurve *pc;
59      int   *jstat;
60 #endif
61 /*
62 *********************************************************************
63 *
64 *********************************************************************
65 *
66 * PURPOSE    : To check a curve descripiton and remove unneccessary
67 *              knots and vertices. Such that no continuous curve will
68 *              have knots with more than the order minus one in
69 *              multiplicity.
70 *
71 *
72 *
73 * INPUT/OUTPUT:pc     - The curve identifcation
74 *
75 * OUTPUT     : kstat  - Status variable
76 *                        < 0 - Error
77 *                        = 0 - SISLCurve object not changed
78 *                        = 1 - SISLCurve object changed
79 *
80 * METHOD     :
81 *
82 *
83 * REFERENCES :
84 *
85 *-
86 * CALLS      : s6dist  - Distance between two points.
87 *
88 * WRITTEN BY : Tor Dokken, SI, Oslo, Norway,  August 1989
89 * REWISED BY : Vibeke Skytt, SI, August 1990
90 * REVISED BY : Johannes Kaasa, SI, April 1992 (Intoduced NURBS)
91 * REVISED BY : Christophe Rene Birkeland, SINTEF, May 1993 (Status variable)
92 *
93 *********************************************************************
94 */
95 {
96   int kstat = 0;              /* Status variable.                 */
97   int ki,kj;                  /* Counter.                         */
98   int kdim;                   /* Dimension of space               */
99   int rdim;                   /* Rational dimension.              */
100   int kn;                     /* Number of knots                  */
101   int kk;                     /* Number of vertices               */
102   int kmark;                  /* Indicates if k-tupple knots      */
103   int knnew;                  /* New number of vertices           */
104   int kind;                   /* Type of curve, 2 and 4 rational. */
105   double *snt=SISL_NULL;           /* Compressed knot vector           */
106   double *sncoef=SISL_NULL;        /* Compressed vertex vector         */
107   double *srcoef=SISL_NULL;        /* Compressed vertex vector         */
108   double *st;                 /* Knots                            */
109   double *scoef;              /* Vertices                         */
110   double *rcoef;              /* Rational vertices.               */
111 
112   *jstat = 0;
113 
114   if (pc == SISL_NULL) goto out;
115 
116   kk    = pc -> ik;
117   kn    = pc -> in;
118   kdim  = pc -> idim;
119   rdim  = kdim + 1;
120   kind  = pc -> ikind;
121   st    = pc -> et;
122   scoef = pc -> ecoef;
123   rcoef = pc -> rcoef;
124 
125   /* Run through all knots to detect if st[ki]=st[ki+kk-1] e.g. that we
126      have at least kk-tupple internal knots */
127 
128   kmark = 0;
129   for (ki=1 ; ki < kn-1 ; ki++)
130     if (st[ki] == st[ki+kk-1] &&
131 	DEQUAL(s6dist(scoef+(ki-1)*kdim,scoef+ki*kdim,kdim),DZERO))
132       {
133         kmark = 1;
134         break;
135       }
136 
137   if (kmark == 0) goto out;
138 
139   /* We have at least kk-tupple knots, remove not necessary knots and vertices */
140 
141   if((snt = newarray(kn+kk,DOUBLE)) == SISL_NULL) goto err101;
142   if((sncoef = newarray(kn*kdim,DOUBLE)) == SISL_NULL) goto err101;
143 
144   if (kind == 2 || kind == 4)
145     {
146       srcoef = newarray(kn*rdim,DOUBLE);
147       if (srcoef == SISL_NULL) goto err101;
148       for (ki=0,kj=0 ; ki < kn ; ki ++)
149         if (ki == 0 || ki == kn-1 || st[ki] < st[ki+kk-1] ||
150 	  DNEQUAL(s6dist(rcoef+(ki-1)*rdim,rcoef+ki*rdim,rdim),DZERO))
151           {
152             snt[kj] = st[ki];
153             memcopy(sncoef+kdim*kj,scoef+kdim*ki,kdim,DOUBLE);
154             memcopy(srcoef+rdim*kj,rcoef+rdim*ki,rdim,DOUBLE);
155             kj++;
156           }
157     }
158   else
159     {
160       for (ki=0,kj=0 ; ki < kn ; ki ++)
161         if (ki == 0 || ki == kn-1 || st[ki] < st[ki+kk-1] ||
162 	  DNEQUAL(s6dist(scoef+(ki-1)*kdim,scoef+ki*kdim,kdim),DZERO))
163           {
164             snt[kj] = st[ki];
165             memcopy(sncoef+kdim*kj,scoef+kdim*ki,kdim,DOUBLE);
166             kj++;
167           }
168     }
169 
170   for (ki=kn ; ki<kn+kk ; ki++,kj++)
171     snt[kj] = st[ki];
172 
173   knnew = kj - kk;
174 
175   /* An additional end knot might have been left */
176 
177   if (snt[knnew-1] == snt[knnew+kk-1]) knnew--;
178 
179   /* Put compressed description back to curve object */
180 
181   if (pc->icopy > 0)
182     {
183       pc -> in = knnew;
184       memcopy(pc->et,snt,knnew+kk,DOUBLE);
185       memcopy(pc->ecoef,sncoef,knnew*kdim,DOUBLE);
186       if (kind == 2 || kind == 4)
187         memcopy(pc->rcoef,srcoef,knnew*rdim,DOUBLE);
188       kstat = 1;
189     }
190 
191   /* Task done. */
192 
193   *jstat = kstat;
194   goto out;
195 
196   /* Error in space allocation. */
197 
198   err101:
199     *jstat = -101;
200     goto out;
201 
202   out:
203     if (snt != SISL_NULL) freearray(snt);
204     if (sncoef != SISL_NULL) freearray(sncoef);
205 }
206