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: s1601.c,v 1.2 2001-03-19 15:58:51 afr Exp $
45  *
46  */
47 
48 
49 #define S1601
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s1601(SISLSurf * psurf,double epoint[],double enorm[],int idim,SISLSurf ** rsurf,int * jstat)55 s1601(SISLSurf *psurf,double epoint[],double enorm[],int idim,SISLSurf **rsurf,int *jstat)
56 #else
57 void s1601(psurf,epoint,enorm,idim,rsurf,jstat)
58      SISLSurf   *psurf;
59      double epoint[];
60      double enorm[];
61      int    idim;
62      SISLSurf   **rsurf;
63      int    *jstat;
64 #endif
65 /*
66 *********************************************************************
67 *
68 * PURPOSE    : To mirror a B-spline surface about a plane
69 *
70 *
71 * INPUT      : psurf  - The input B-spline surface
72 *              epoint - a point in the plane
73 *              enorm  - normal vector to the plane
74 *              idim   - The dimension of the space
75 *
76 * OUTPUT     : rsurf  - Pointer to the mirrored surface
77 *              jstat  - status messages
78 *                                         > 0      : warning
79 *                                         = 0      : ok
80 *                                         < 0      : error
81 *
82 * METHOD     : The vertices are mirrored. All other surface data
83 *              are copied into the new surface.
84 *
85 * EXAMPLE OF USE:
86 *
87 * REFERENCES :
88 *
89 *-
90 * CALLS      : s6norm,s6diff,s6scpr,newSurf,s6err
91 *
92 *
93 * WRITTEN BY : Qyvind Hjelle, SI, Oslo, Norway. 10. Nov 1988
94 * REVISED BY : Johannes Kaasa, SI, Oslo, Norway April 1992 (Introduced NURBS)
95 *
96 *********************************************************************
97 */
98 {
99   int kstat=0;        /* Status variable                                 */
100   int kiv;            /* Counter for vertices                            */
101   int kid;            /* Counter for dimension                           */
102 
103   int kn1;            /* Number of vertices in first direction of psurf  */
104   int kn2;            /* Number of vertices in second direction of psurf */
105   int kk1;            /* Order in first direction of input psurf         */
106   int kk2;            /* Order in second direction of input psurf        */
107   int kind;           /* Type of surface, 2 and 4 are rational surfaces. */
108   int kdim;           /* The dimension of the space in which the curve
109 			 lies. Equivalently, the number of components
110 			 of each B-spline coefficient.                   */
111   int kvert;          /* Counter for position in mirrored vertex array   */
112   int kpos=0;         /* Position of error                               */
113 
114   double *snorm=SISL_NULL; /* Pointer to normalized normal                    */
115   double *svecpv=SISL_NULL;/* Pointer to vector from pointin plane to vertex  */
116   double *smirr=SISL_NULL; /* Pointer to mirrored vertex array                */
117   double *st1;        /* First knot vector is psurf                       */
118   double *st2;        /* Second knot vector is psurf                      */
119   double *svert;      /* Pointer to a vertex                             */
120   double *scoef;      /* Pointer to the first element of the curve's
121 			 B-spline coefficients. This is assumed to be an
122 			 array with [kn*kdim] elements stored in the
123 			 following order:
124 			 First the kdim components of the first B-spline
125 			 coefficient, then the kdim components of the
126 			 second B-spline coefficient and so on.          */
127 
128   double tdist;       /* Distance */
129 
130   /* Make local pointers */
131 
132   kn1   = psurf -> in1;
133   kn2   = psurf -> in2;
134   kk1   = psurf -> ik1;
135   kk2   = psurf -> ik2;
136   kdim  = psurf -> idim;
137   st1   = psurf -> et1;
138   st2   = psurf -> et2;
139   kind  = psurf -> ikind;
140   if (kind == 2 || kind == 4)
141     scoef = psurf -> rcoef;
142   else
143     scoef = psurf -> ecoef;
144 
145   /* Check if conflicting dimensions */
146 
147   if (kdim != idim) goto err106;
148   if (kind == 2 || kind == 4)
149     kdim++;
150 
151   /* Allocate space for normalized normalvector , vector from point in
152      plane to vertex and new vertex array */
153 
154   snorm = newarray(idim,DOUBLE);
155   if (snorm == SISL_NULL) goto err101;
156 
157   svecpv = newarray(idim,DOUBLE);
158   if (svecpv == SISL_NULL) goto err101;
159 
160   smirr = newarray(kdim*kn1*kn2,DOUBLE);
161   if (svecpv == SISL_NULL) goto err101;
162 
163 
164   /* Normalize normal vector */
165 
166   (void)s6norm(enorm,idim,snorm,&kstat);
167   if (kstat < 0) goto error;
168 
169   /* Do for all vertices */
170 
171   kvert = 0;
172   for (kiv=0; kiv<kn1*kn2; kiv++)
173     {
174 
175       /* Find vector from point in plane to vertex */
176 
177       svert = scoef + kiv*kdim;
178       s6diff(svert,epoint,idim,svecpv);
179 
180       /* Find distance between the vertex and the plane */
181 
182       tdist =  s6scpr(svecpv,snorm,idim);
183       tdist *=(double)2.0;
184 
185       /* Find the mirrored vertex */
186 
187       for (kid=0; kid<idim; kid++,kvert++)
188 	{
189 	  smirr[kvert] = scoef[kvert] - tdist*snorm[kid];
190 	}
191       if (kind == 2 || kind == 4)
192 	{
193 	   smirr[kvert] = scoef[kvert];
194 	   kvert++;
195 	}
196     }
197 
198 
199   /* Make the mirrored surface. */
200 
201   *rsurf = SISL_NULL;
202   *rsurf = newSurf(kn1,kn2,kk1,kk2,st1,st2,smirr,psurf->ikind,idim,1);
203   if (*rsurf == SISL_NULL) goto err101;
204 
205   /* Set periodicity flag. */
206 
207   (*rsurf)->cuopen_1 = psurf->cuopen_1;
208   (*rsurf)->cuopen_2 = psurf->cuopen_2;
209 
210   *jstat = 0;
211   goto out;
212 
213   /* Error in memory allocation */
214 
215  err101:
216   *jstat = -101;
217   s6err("s1601",*jstat,kpos);
218   goto out;
219 
220   /* Error in input, conflicting dimensions */
221 
222  err106:
223   *jstat = -106;
224   s6err("s1601",*jstat,kpos);
225   goto out;
226 
227   /* Error in lower level function */
228 
229  error:
230   *jstat = kstat;
231   s6err("s1601",*jstat,kpos);
232   goto out;
233 
234  out:
235   if (snorm  != SISL_NULL) freearray(snorm);
236   if (svecpv != SISL_NULL) freearray(svecpv);
237   if (smirr  != SISL_NULL) freearray(smirr);
238   return;
239 }
240 
241