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