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