/* * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT, * Applied Mathematics, Norway. * * Contact information: E-mail: tor.dokken@sintef.no * SINTEF ICT, Department of Applied Mathematics, * P.O. Box 124 Blindern, * 0314 Oslo, Norway. * * This file is part of SISL. * * SISL is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * SISL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with SISL. If not, see * . * * In accordance with Section 7(b) of the GNU Affero General Public * License, a covered work must retain the producer line in every data * file that is created or manipulated using SISL. * * Other Usage * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the SISL library without * disclosing the source code of your own applications. * * This file may be used in accordance with the terms contained in a * written agreement between you and SINTEF ICT. */ #include "sisl-copyright.h" /* * * $Id: s6addcurve.c,v 1.2 2001-03-19 15:59:00 afr Exp $ * */ #define S6ADDCURVE #include "sislP.h" #if defined(SISLNEEDPROTOTYPES) static void s6addcurve_s9moveknots(double [],int,double,double, double [],int *); #else static void s6addcurve_s9moveknots(); #endif #if defined(SISLNEEDPROTOTYPES) void s6addcurve(SISLCurve *pc1,SISLCurve *pc2,int isign, SISLCurve **rcurve,int *jstat) #else void s6addcurve(pc1,pc2,isign,rcurve,jstat) SISLCurve *pc1; SISLCurve *pc2; int isign; SISLCurve **rcurve; int *jstat; #endif /* ********************************************************************* * * PURPOSE : Compute the sum or difference between two B-spline * curves depending on the constang isign. That is find * the curve pc1 + isign*pc2. * * * * INPUT : pc1 - First curve in expression. * pc2 - Second curve in expression. * isign - Sign of second curve. * * * OUTPUT : rcurve - Sum/difference between the input curves. * jstat - status messages * > 0 : warning * = 0 : ok * < 0 : error * * * METHOD : Express the curves on the same knot vector. Compute the * sum difference between corresponding vertices. * * * REFERENCES : * * * USE : * *- * CALLS : s1932 - Express curve-set in given basis. * s1363 - Pick parametrisation of curve. * s6takeunion - Union of two ordered vectors. * make_cv_kreg - Make curve k-regular. * s1333_count - Count continuity in ends of closed curves. * make_cv_cyclic - Represent curve in a periodic basis. * newCurve - Create new curve-object. * s6addcurve_s9moveknots() - Move knotvector into new parameter interval. * * * WRITTEN BY : Vibeke Skytt, SI, 08.90. * REWISED BY : Vibeke Skytt, SI, 05.92. To treat periodic curves. * ********************************************************************* */ { int kstat = 0; /* Status variable. */ int ki; /* Counter. */ int kdim = pc1->idim; /* Dimension of geometry space. */ int knbcrv = 2; /* Number of input curves. */ int kknot1 = pc1->in + pc1->ik; /* Number of knots of first curve. */ int kknot2 = pc2->in + pc2->ik; /* Number of knots of second curve. */ int korder; /* Order of output curve. */ int ktau; /* Number of knots / number of vertices of output curve. */ int kcont; /* Continuity at ends in periodic case. */ int kopen; /* Open/closed/periodic parameter. */ int kkind = pc1->ikind; /* Kind of curves. */ int kcopy = 1; /* Copy arrays when creating new curve. */ double tmin1,tmax1; /* Parameter interval of first input curve. */ double tmin2,tmax2; /* Parameter interval of second input curve. */ double *st = SISL_NULL; /* Knot vector of second curve. */ double *stau = SISL_NULL; /* Knot vector of output curve. */ double *scoef = SISL_NULL; /* Vertices of input curves represented in the same knot vector, then of output curve. */ SISLCurve *ucurves[2]; /* Local pointer array to input curves. */ ucurves[0] = ucurves[1] = SISL_NULL; /* Test input. */ if (kdim != pc2->idim) goto err106; /* Make curves k-regular. */ make_cv_kreg(pc1,ucurves,&kstat); if (kstat < 0) goto error; make_cv_kreg(pc2,ucurves+1,&kstat); if (kstat < 0) goto error; /* Allocate scratch for local knot vector. */ if ((st = newarray(kknot2,DOUBLE)) == SISL_NULL) goto err101; /* Fetch endparameter values of the input curves. */ s1363(ucurves[0],&tmin1,&tmax1,&kstat); if (kstat < 0) goto error; s1363(ucurves[1],&tmin2,&tmax2,&kstat); if (kstat < 0) goto error; if (DNEQUAL(tmin1,tmin2) || DNEQUAL(tmax1,tmax2)) { /* Move the knot vector of the second curve into the parameter interval of the first curve. */ s6addcurve_s9moveknots(ucurves[1]->et,kknot2,tmin1,tmax1,st,&kstat); if (kstat < 0) goto error; } else memcopy(st,ucurves[1]->et,kknot2,DOUBLE); /* Find the union of the knot vectors of the two curves. */ s6takeunion(ucurves[0]->et,kknot1,st,kknot2,&stau,&ktau,&kstat); if (kstat < 0) goto error; korder = MAX(ucurves[0]->ik,ucurves[1]->ik); ktau -= korder; /* Express the curves in the basis. */ s1932(2,ucurves,tmin1,tmax1,stau,ktau,korder,&scoef,&kstat); if (kstat < 0) goto error; /* Find the coefficients of the sum/difference curve. */ for (ki=0; kicuopen = kopen = MAX(pc1->cuopen,pc2->cuopen); if (kopen == SISL_CRV_PERIODIC) { /* Represent the output curve cyclic. First find continuity. */ s1333_count(knbcrv,ucurves,&kcont,&kstat); if (kstat < 0) goto error; make_cv_cyclic(*rcurve,kcont,&kstat); if (kstat < 0) goto error; } /* Task performed. */ *jstat = 0; goto out; /* Error in scratch allocation. */ err101 : *jstat = -101; goto out; /* Error in input. Conflicting dimensions. */ err106 : *jstat = -106; goto out; /* Error in lower order routine. */ error : *jstat = kstat; goto out; out : /* Free scratch occupied by local arrays. */ if (st != SISL_NULL) freearray(st); if (stau != SISL_NULL) freearray(stau); if (scoef != SISL_NULL) freearray(scoef); if (ucurves[0] != SISL_NULL) freeCurve(ucurves[0]); if (ucurves[1] != SISL_NULL) freeCurve(ucurves[1]); return; } #if defined(SISLNEEDPROTOTYPES) static void s6addcurve_s9moveknots(double et[],int inmbknot,double astart, double aend,double etmoved[],int *jstat) #else static void s6addcurve_s9moveknots(et,inmbknot,astart,aend,etmoved,jstat) double et[]; int inmbknot; double astart; double aend; double etmoved[]; int *jstat; #endif /* ********************************************************************* * * PURPOSE : Move knot vector into the parameter interval * [astart,aend]. * * * * INPUT : et - Knot vector. * inmbknot - Number of knots in the vector et. * astart - Start parameter value of new parameter interval. * aend - End parameter value of new parameter interval. * * * OUTPUT : etmoved - Knot vector on new parameter interval. * jstat - status messages * = 1 : Parameter interval changed. Thus, * reparametrization is performed. * = 0 : ok * < 0 : error * * * METHOD : * * * REFERENCES : * * * USE : * *- * CALLS : * * * WRITTEN BY : Vibeke Skytt, SI, 07.90. * ********************************************************************* */ { int kwarn = 0; /* Indicates if reparametrization is performed. */ double tstart = et[0]; /* Start parameter of original knot vector. */ double tend = et[inmbknot-1]; /* End parameter of original knot vector. */ double tfac = (aend - astart)/(tend - tstart); /* Factor used when moving knot vector. */ double *s1,*s2,*s3; /* Pointers used to traverse knot vectors. */ /* Test if reparametrization is performed. */ if (DNEQUAL(aend-astart,tend-tstart)) kwarn = 1; /* Put knot vector into new parameter interval. */ for (s1=et,s2=et+inmbknot,s3=etmoved; s1