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 #define S1538 43 44 #include "sislP.h" 45 46 #if defined(SISLNEEDPROTOTYPES) 47 void s1538(int inbcrv,SISLCurve * vpcurv[],int nctyp[],double astpar,int iopen,int iord2,int iflag,SISLSurf ** rsurf,double ** gpar,int * jstat)48 s1538(int inbcrv,SISLCurve *vpcurv[],int nctyp[],double astpar, 49 int iopen,int iord2,int iflag, 50 SISLSurf **rsurf,double **gpar,int *jstat) 51 #else 52 void s1538(inbcrv,vpcurv,nctyp,astpar,iopen,iord2, 53 iflag,rsurf,gpar,jstat) 54 int inbcrv; 55 SISLCurve *vpcurv[]; 56 int nctyp[]; 57 double astpar; 58 int iopen; 59 int iord2; 60 int iflag; 61 SISLSurf **rsurf; 62 double **gpar; 63 int *jstat; 64 #endif 65 /* 66 ********************************************************************* 67 * 68 * PURPOSE : To create a spline lofted surface 69 * from a set of input-curves. 70 * 71 * INPUT : inbcrv - Number of curves in the curve-set. 72 * vpcurv - Array (length inbcrv) of pointers to the 73 * curves in the curve-set. 74 * nctyp - Array (length inbcrv) containing the types 75 * of curves in the curve-set. 76 * 1 - Ordinary curve. 77 * 2 - Knuckle curve. Treated as ordinary curve. 78 * 3 - Tangent to next curve. 79 * 4 - Tangent to prior curve. 80 * (5 - Double derivative to prior curve.) 81 * (6 - Double derivative to next curve.) 82 * 13 - SISLCurve giving start of tangent to next curve. 83 * 14 - SISLCurve giving end of tengent to prior curve. 84 * astpar - Start-parameter for spline lofting direction. 85 * iopen - Flag telling if the resulting surface should 86 * be closed or open. 87 * -1 - The surface should be closed and periodic. 88 * 0 - The surface should be closed. 89 * 1 - The surface should be open. 90 * iord2 - Maximal order of the B-spline basis in the 91 * lofting direction. 92 * iflag - Flag telling if the size of the tangents in the 93 * derivative curves should be adjusted or not. 94 * 0 - Do not adjust tangent-sizes. 95 * 1 - Adjust tangent-sizes. 96 * 97 * OUTPUT : rsurf - Pointer to the surface produced. 98 * gpar - The input-curves are constant parameter-lines 99 * in the parameter-plane of the produced surface. 100 * (i) - contains the (constant) value of this 101 * parameter of input-curve no. i. 102 * jstat - status messages 103 * > 0 : warning 104 * = 0 : ok 105 * < 0 : error 106 * 107 * METHOD : A common basis for all the B-spline curves are found. 108 * The curves are represented using this basis. 109 * The resulting curves are given to an interpolation 110 * routine that calculates the B-spline vertices of the 111 * resulting spline lofted surface. 112 * Throughout these routines, first parameterdirection 113 * will be the interpolating direction, second parameter- 114 * direction will be along the input curves. 115 *- 116 * CALLS : s1931,s1917,s1918,s1358,s6err. 117 * 118 * WRITTEN BY : A. M. Ytrehus SI Oslo,Norway. Sep. 1988 119 * Revised by : Tor Dokken, SI, Oslo, Norway, 26-feb-1989 120 * Revised by : Trond Vidar Stensby, SI, 91-08 121 * REVISED BY: Vibeke Skytt, 03.94. This routine corresponds to s1333, 122 * but differ in the use of the parameter 123 * iopen. 124 * Revised by : Paal Fugelli, 17/08-1994. Fixed memory leak from 'gpar' 125 * allocated in s1357(). 126 * 127 ********************************************************************* 128 */ 129 { 130 int kind,kcopy,kdim; 131 int kn1,kord1,knbcrv; 132 int kcnsta,kcnend; /* Interpolation condition at start or end */ 133 int ki,kj,kl,km; 134 int kleng; /* Number of doubles describing a curve */ 135 int ktype; /* Kind of interpolation condition. */ 136 int kopen; /* Open/closed parameter in curve direction. */ 137 SISLCurve *qc; /* Pointer to curve representing surface */ 138 int *lder = SISL_NULL; /* Derivative indicators from s1915. */ 139 double *spar=SISL_NULL; /* Param. values of point conditions. */ 140 double *spar2=SISL_NULL; /* Parameter values from s1915. */ 141 double *sknot1=SISL_NULL; /* Knot vector. */ 142 double *scoef2=SISL_NULL; /* Pointer to vertices expressed in same basis */ 143 double tstpar; /* Parameter value of last curve */ 144 int kstat = 0; /* Status variable. */ 145 int kpos = 0; /* Position of error. */ 146 int knbpar; /* Number of parameter values produced */ 147 int kdimcrv; /* kdim multiplied with number of vertices kn1 */ 148 int kcont; /* Continuity at end of curves */ 149 150 151 /* Initiate variables. */ 152 153 kdim = vpcurv[0]->idim; 154 155 if (inbcrv < 2) goto err179; 156 157 /* Put the curves into common basis. */ 158 159 s1931 (inbcrv, vpcurv, &sknot1, &scoef2, &kn1, &kord1, &kstat); 160 if (kstat < 0) 161 goto error; 162 163 /* Create the parameter-values for the knot-vector 164 (in lofting direction) for a lofted surface, allocate array for 165 parameter values. */ 166 167 s1917 (inbcrv, scoef2, kn1, kdim, nctyp, astpar, iopen, 168 &spar2, &lder, &knbcrv, &kstat); 169 170 if (kstat < 0) 171 goto error; 172 173 /* Convert condition 13 and 14 to 3 and 4 */ 174 175 kleng = kn1*kdim; 176 for (ki=0 ; ki<knbcrv ; ki++) 177 { 178 ktype = nctyp[ki]; 179 180 if (ktype == 13 && ki+1<knbcrv) 181 { 182 /* 183 * Start of tangent to next curve, 184 * make difference of next curve and this curve 185 */ 186 187 for (kj=ki*kleng,kl=kj+kleng,km=0; km <kleng ; kj++,kl++,km++) 188 scoef2[kj] = scoef2[kl] - scoef2[kj]; 189 nctyp[ki] = 3; 190 } 191 else if (ktype == 14 && ki>0) 192 { 193 /* End of tangent to prior curve, 194 * make difference of this curve 195 * and prior curve 196 */ 197 198 for (kj=ki*kleng,kl=kj-kleng,km=0; km <kleng ; kj++,kl++,km++) 199 scoef2[kj] = scoef2[kj] - scoef2[kl]; 200 nctyp[ki] = 4; 201 } 202 } 203 204 spar = newarray(knbcrv+1,DOUBLE); 205 if (spar==SISL_NULL) goto err101; 206 207 /* Only copy parameter values of point conditions */ 208 209 for (ki=0,kl=0; ki<knbcrv ; ki++) 210 { 211 if (nctyp[ki] == 1 || nctyp[ki] == 2) 212 { 213 spar[kl] = spar2[ki]; 214 kl++; 215 } 216 } 217 218 /* Add one extra parameter value if closed curve */ 219 220 if (iopen != SISL_CRV_OPEN) spar[kl] = spar2[knbcrv]; 221 222 /* Adjust tangent-lengths if wanted. */ 223 224 if (iflag) 225 { 226 s1918 (knbcrv, sknot1, scoef2, kn1, kord1, kdim, spar2, lder, &kstat); 227 if (kstat < 0) goto error; 228 } 229 230 /* Interpolate with point interpolation method */ 231 232 kcnsta = 0; 233 kcnend = 0; 234 kdimcrv = kdim*kn1; 235 236 s1357(scoef2,knbcrv,kdimcrv,nctyp,spar,kcnsta,kcnend,iopen,iord2,astpar, 237 &tstpar,&qc,gpar,&knbpar,&kstat); 238 if (kstat<0) goto error; 239 240 /* The knot vector in the lofting direction and the coefficients are 241 now contained in the curve object pointed to by qc */ 242 243 /* Create the surface */ 244 245 kind = 1; 246 kcopy = 1; 247 *rsurf = newSurf(kn1,qc->in,kord1,qc->ik,sknot1,qc->et,qc->ecoef, 248 kind,kdim,kcopy); 249 if (*rsurf == SISL_NULL) goto err101; 250 251 /* Copy cuopen flag from curve */ 252 (*rsurf)->cuopen_2 = qc->cuopen; 253 254 /* Release the curve object */ 255 256 freeCurve(qc); 257 258 /* Output parametervalues according to the input curves, but must 259 remember to free the space allocated in call to s1357() first. */ 260 261 if ( (*gpar) != SISL_NULL ) freearray(*gpar); /* PFU 17/08-94. */ 262 *gpar = spar; 263 264 /* Decide if the surface should have a cyclic behaviour in first 265 parameter direction i.e. the direction of the curves */ 266 267 s1333_count(inbcrv,vpcurv,&kcont,&kstat); 268 if (kstat<0) goto error; 269 270 if (kcont>=0) 271 { 272 s1333_cyclic(*rsurf,kcont,&kstat); 273 if (kstat<0) goto error; 274 275 /* Set periodic flag */ 276 (*rsurf)->cuopen_1 = SISL_SURF_PERIODIC; 277 } 278 else 279 { 280 /* Test if the surface should be closed and non-periodic. */ 281 282 for (kopen=-2, ki=0; ki<inbcrv; ki++) 283 kopen = MAX(kopen,vpcurv[ki]->cuopen); 284 if (kopen == SISL_CRV_CLOSED) (*rsurf)->cuopen_1 = SISL_SURF_CLOSED; 285 } 286 287 /* Task done */ 288 289 *jstat = 0; 290 goto out; 291 292 /* Error in allocation. */ 293 294 err101: 295 *jstat = -101; 296 s6err("s1538",*jstat,kpos); 297 goto out; 298 299 300 /* Error in interpolation conditions. No. of curves < 2. */ 301 302 err179: 303 *jstat = -179; 304 s6err("s1538",*jstat,kpos); 305 goto out; 306 307 308 /* Error in lower level routine. */ 309 310 error : 311 *jstat = kstat; 312 s6err("s1538",*jstat,kpos); 313 goto out; 314 out: 315 316 /* Free allocated scratch */ 317 318 if (sknot1 != SISL_NULL) freearray(sknot1); 319 if (scoef2 != SISL_NULL) freearray(scoef2); 320 if (spar2 != SISL_NULL) freearray(spar2); 321 if (lder != SISL_NULL) freearray(lder); 322 323 return; 324 } 325