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: s1389.c,v 1.2 2001-03-19 15:58:48 afr Exp $
45 *
46 */
47
48
49 #define S1389
50
51 #include "sislP.h"
52
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s1389(SISLCurve * pc1,double * gcubic[],int * jnumb,int * jdim,int * jstat)55 s1389(SISLCurve *pc1,double *gcubic[],int *jnumb,int *jdim,int *jstat)
56 #else
57 void s1389(pc1,gcubic,jnumb,jdim,jstat)
58 SISLCurve *pc1;
59 double *gcubic[];
60 int *jnumb;
61 int *jdim;
62 int *jstat;
63 #endif
64 /*
65 *********************************************************************
66 *
67 *********************************************************************
68 *
69 * PURPOSE : Convert a B-spline curve of order up to 4 to a sequence
70 * of cubic segment with uniform parametrization
71 *
72 *
73 * INPUT : pc1 - Pointer to the curve to be converted
74 *
75 *
76 * OUTPUT : gcubic - Array containing the sequence of cubic segments.
77 * Each segment is represented by the start point,
78 * followed by the start tangent, end point and end
79 * tangent. Each segment takes 4*jdim doubles.
80 * This array is allocated inside the function and must
81 * be released by the calling function.
82 *
83 * jstat - status messages
84 * = 1 : Order too high, curve
85 * interpolated
86 * = 0 : ok
87 * < 0 : error
88 *
89 *
90 * METHOD : For each polynomial segment end, the position and first
91 * derivative is calculated.
92 *
93 * USE: int knumb,kdim,kstat;
94 * double *scubic;
95 * SISLSurf *qc1;
96 * .
97 * .
98 * s1389(qc1,&scubic,&knumb,&kdim,&kstat);
99 * .
100 * If one of the order of the curve is greater than four
101 * (*jstat==1) then degree reduction (order reduction) should
102 * be applied before using this routine to get a satisfactory
103 * representation of the curve by Coons patches.
104 * The degree reduction routine is s1343.
105 *
106 *
107 *
108 * REFERENCES :
109 *
110 *-
111 * CALLS : s1221, s1227, s6err
112 *
113 * WRITTEN BY : Tor Dokken, SI, Norway, 1988-11
114 *
115 *********************************************************************
116 */
117 {
118 int kstat=0; /* Local status variable. */
119 int kpos=0; /* Position of error. */
120 int kdim; /* Dimension of the space in which the surface lies. */
121 int kder=1; /* Calculate all first derivatives */
122 int kleft=0; /* Pointer into knot vector */
123 int kdumlft; /* Temporary pointer into knot vector */
124 int ksize; /* Number of doubles to store a cubic segment */
125
126 int ki; /* Control variables in for loop */
127 int kn; /* Number of vertices */
128 int kk; /* Polynomial order */
129 double *st; /* Knots */
130 double tpar; /* Current parameter value */
131 double tparx; /* Temporary parameter value */
132 double tdiff1; /* Length of parameter interval */
133 double *scorn1; /* Pointer to first end of segment */
134 double *scorn2; /* Pointer to second end of segment */
135
136 kn = pc1->in;
137 kk = pc1->ik;
138 kdim = pc1 -> idim;
139 st = pc1 -> et;
140
141
142 /* Calculate number of doubles to store a cubic segment*/
143
144 ksize = kdim*4;
145
146
147 /* Allocate array for storage of the coefficients */
148
149 *gcubic = newarray((kn*4*kdim),DOUBLE);
150 if (*gcubic == SISL_NULL) goto err101;
151
152 kleft = kk - 1;
153
154 *jnumb = 0;
155
156 scorn1 = *gcubic;
157
158 while (kleft < kn)
159 {
160
161 /* Set pointers to the end of the segment */
162
163 scorn2 = scorn1 + 2*kdim;
164
165 tpar = st[kleft];
166
167 /* The parameter describes the left corner of the segment. By
168 evaluating at tpar we get the kleft to point to the parameter
169 interval. The other end is at st[kleft+1].
170 */
171
172 /* Calulate start of segement */
173
174 s1221(pc1,kder,tpar,&kleft,scorn1,&kstat);
175 if (kstat<0) goto error;
176
177 /* Find length of aprameter intervals */
178
179 tdiff1 = st[kleft+1] - st[kleft];
180
181 /* Calculate end of segment, us left derivative */
182
183 tparx = st[kleft+1];
184 kdumlft = kleft;
185
186 s1227(pc1,kder,tparx,&kdumlft,scorn2,&kstat);
187 if (kstat<0) goto error;
188
189 /* Scale derivatives to match uniform parametrization */
190
191 for (ki=kdim;ki<2*kdim;ki++)
192 {
193 scorn1[ki] *= tdiff1;
194 scorn2[ki] *= tdiff1;
195 }
196
197 kleft += 1;
198 *jnumb +=1;
199 scorn1 += kdim*4;
200 }
201
202 /* The array is probably too big for the Coons patches, decrease the
203 array size */
204
205
206 /* Allocate array for storage of the coefficients */
207
208 *gcubic = increasearray(*gcubic,((*jnumb)*4*kdim),DOUBLE);
209 if (*gcubic == SISL_NULL) goto err101;
210
211
212 /* Test if order to high */
213
214 *jdim = kdim;
215
216 if (kk>4) goto war01;
217
218 *jstat = 0;
219
220 goto out;
221
222 /* Orders too high */
223
224 war01:*jstat=1;
225 goto out;
226
227 /* Error in scratch allocation */
228
229 err101:
230 *jstat = -101;
231 s6err("s1389",*jstat,kpos);
232 goto freeout;
233
234 /* Error in lower level function. */
235
236 error : *jstat = kstat;
237 s6err("s1389",*jstat,kpos);
238 goto freeout;
239
240 /* Some error has occured free allocated space */
241
242 freeout:
243 if (*gcubic != SISL_NULL) freearray(*gcubic);
244 goto out;
245
246 out:
247 return;
248 }
249
250