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: s1161.c,v 1.2 2001-03-19 15:58:41 afr Exp $
45 *
46 */
47
48
49 #define S1161
50
51 #include "sislP.h"
52
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s1161(SISLObject * po1,double * cmax,double aepsge,SISLIntdat ** pintdat,int * jstat)55 s1161(SISLObject *po1,double *cmax,double aepsge,SISLIntdat **pintdat,int *jstat)
56 #else
57 void s1161(po1,cmax,aepsge,pintdat,jstat)
58 SISLObject *po1;
59 double *cmax;
60 double aepsge;
61 SISLIntdat **pintdat;
62 int *jstat;
63 #endif
64 /*
65 *********************************************************************
66 *
67 *********************************************************************
68 *
69 * PURPOSE : Find all maximum points of an onedimentional object (of type
70 * point, curve or surface). The maximum points found has to
71 * be greater or equal to the level value cmax .
72 * In this rouine the outer edges/endpoints of the objects
73 * are treated.
74 *
75 *
76 *
77 * INPUT : po1 - The object.
78 * aepsge - Geometry resolution.
79 *
80 *
81 *
82 * INPUT/OUTPUT:
83 * cmax - The level value.
84 *
85 * OUTPUT : pintdat - Maximum points found.
86 * jstat - status messages
87 * = 1 : Maximumpoints found equal to level value
88 * = 2 : Maximumpoints found over level value
89 * = 0 : no maximum
90 * < 0 : error
91 *
92 *
93 * METHOD : This function is treating point maximum.
94 * Otherwise it is computing edge/endpoint maximum
95 * by recurson on the edges.
96 * The maxima in the inner of the object is found by
97 * calling another recursiv function.
98 * REFERENCES :
99 *
100 *-
101 * CALLS : s6err - Gives error message.
102 * s1435 - Pick edge curve from a surface.
103 * s1438 - Pick endpoint from a curve.
104 * s1162 - Find the intersections in the inner of the objects.
105 * s1190 - A boxtest.
106 * s6idnpt - Put a new intpt to given intdat.
107 * s6idput - Put contence of one intdat in an other intdat.
108 * s6idlis - Compute list elements from given intdat.
109 * s6idedg - Uppdate an edge from given intdat.
110 * freeEdge - Free space occupied by given edge.
111 * freePoint - Free space occupied by given point.
112 * freeCurve - Free space occupied by given curve.
113 * freeObject - Free space occupied by given object.
114 * freeIntdat - Free space occupied by given intdat.
115 * newEdge - Create new edge-structure.
116 * newIntpt - Create new maximum point-structure.
117 * newObject - Create new object.
118 *
119 * WRITTEN BY : Ulf J. Krystad , 05.89.
120 *
121 *********************************************************************
122 */
123 {
124 int klevel=0; /* Parameter into s1162 */
125 int knum=0; /* Parameter into s1162 */
126 int kpar; /* Fixed parameter direction. */
127 int ki; /* Counter. */
128 int kedge; /* Number of edges. */
129 int idim = 1; /* Local dimension, always = 1 */
130 int kstat = 0; /* Local status variable. */
131 int kpos = 0; /* Position of error. */
132 double tpar; /* Help variable used for parameter value
133 and geometric distance. */
134 SISLEdge *qedge[2]; /* Edges for use in s1162(). */
135 SISLObject *qdum = SISL_NULL; /* Dummy pointer. */
136 SISLObject *qob = SISL_NULL; /* Objects for use in recurson. */
137 SISLIntdat *qintdat = SISL_NULL; /* Intdat for use in recurson. */
138
139 qedge[0] = SISL_NULL;
140 qedge[1] = SISL_NULL;
141
142 if (po1->iobj == SISLPOINT)
143 {
144 /* It's a point, treat the case here and return. */
145
146 /* Control the dimension. */
147 if (po1->p1->idim != idim ) goto err106;
148
149 /* Computing the distance beetween the point and level value. */
150 tpar = po1->p1->ecoef[0] - *cmax;
151
152 if (fabs(tpar) <= aepsge)
153
154 /* The point is close enough to the level value to be a max. */
155 *jstat = 1; /* Mark maximum found. */
156
157 else if (tpar > (double)0.0)
158 {
159
160 /* The point is greater than the level value . */
161 *jstat = 2; /* Mark new maximum found. */
162 *cmax = po1->p1->ecoef[0];
163 }
164
165 else
166
167 *jstat = 0; /* Mark no maximum found. */
168
169
170 if ( *jstat > 0 )
171 {
172 SISLIntpt *qt;
173
174 /* Add maximum point. */
175 qt = newIntpt(0,cmax,DZERO);
176 if (qt == SISL_NULL) goto err101;
177
178 /* Uppdate pintdat. */
179 s6idnpt(pintdat,&qt,1,&kstat);
180 if (kstat < 0) goto error;
181 }
182
183 }
184
185
186 else if (po1->iobj > SISLPOINT)
187 {
188 /* It's a higher order geometry, treat the edges here and
189 use a recursiv function to treat the inner of the object */
190
191
192 *jstat = 0;
193 /* Perform a boxtest */
194 s1190(po1,cmax,aepsge,&kstat);
195 if (kstat == 1) goto out;
196
197
198 /*Create a dummy object, to be used when calling
199 the intersection routines
200 treating two objects.*/
201 if ((qdum = newObject(SISLPOINT)) == SISL_NULL) goto err101;
202
203
204
205 kedge = 2 * po1->iobj;
206 kpar = kedge/2;
207
208 /* Create correct number of edges. */
209 if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101;
210
211
212 for (ki=0; ki<kedge; ki++)
213 {
214
215 /* Set correct parameter direction to keep constant */
216 kpar = ((ki == kedge/2) ? kedge/2-1:kpar-1);
217
218 /* Create one lower order helpobject */
219 if ((qob = newObject(po1->iobj - 1)) == SISL_NULL) goto err101;
220
221
222 if (po1->iobj == SISLCURVE)
223
224 /* Pick out end point from a curve. */
225 s1438(po1->c1,ki,&(qob->p1),&tpar,&kstat);
226
227 else if (po1->iobj == SISLSURFACE)
228
229 /* Pick out edge curve from a surface. */
230 s1435(po1->s1,ki,&(qob->c1),&tpar,&kstat);
231
232 else
233 /* Unknown higher order object . */
234 goto err121;
235
236 if (kstat < 0) goto error;
237
238 /* Recursiv computing of end maximum. */
239 s1161(qob,cmax,aepsge,&qintdat,&kstat);
240 if (kstat < 0) goto error;
241
242 if (kstat == 2)
243 {
244
245 /* New maximum found, delete old ones */
246 if (*pintdat != SISL_NULL)
247 {
248 freeIntdat(*pintdat);
249 *pintdat = SISL_NULL;
250 }
251
252 if (qedge[0] != SISL_NULL)
253 {
254 /* Empty the edges */
255 freeEdge(qedge[0]);
256 if ((qedge[0] = newEdge(kedge)) == SISL_NULL) goto err101;
257 }
258
259 }
260
261
262 if (kstat)
263 {
264 /* Maximum found, add them to the list */
265
266 *jstat = max(*jstat,kstat); /* Mark maximum found. */
267
268 /* Put maximum found on edges into pintdat. */
269
270 /* Set parameter border values of object. */
271 s6idput(pintdat,qintdat,kpar,tpar,&kstat);
272 if (kstat < 0) goto error;
273
274 /* Uppdate edge structure. */
275 s6idedg(po1,qdum,1,kpar+1,tpar,*pintdat,
276 &(qedge[0]->prpt[ki]),&(qedge[0]->ipoint),&kstat);
277 if (kstat < 0) goto error;
278 }
279
280 if (qintdat != SISL_NULL) freeIntdat(qintdat);
281 qintdat = SISL_NULL;
282 freeObject(qob);
283 }
284
285
286 /* ---------------------------------------------------------------*/
287 /* Treat the inner of higher order objects. */
288
289 /* Before we enter internal maximum and subdivision we
290 initiate pointers to top level objects. */
291
292 if (po1->o1 == SISL_NULL) po1->o1 = po1;
293
294 /* Find the maximums in the inner of the object. */
295 s1162(po1,cmax,aepsge,pintdat,qedge,klevel,knum,&kstat);
296 if (kstat < 0) goto error;
297 *jstat = max(*jstat,kstat);
298
299 /* Organize the list in pintdat. */
300 s6idlis(po1,po1,pintdat,&kstat);
301 if (kstat < 0) goto error;
302 }
303
304 else
305 /* Unknown object . */
306 goto err121;
307
308
309 goto out;
310
311
312
313 /* -------------- ERROR HANDLING ----------------------------------------*/
314
315 /* Error in space allocation. */
316 err101: *jstat = -101;
317 s6err("s1161",*jstat,kpos);
318 goto out;
319
320 /* Error. Dimensions conflicting. */
321 err106: *jstat = -106;
322 s6err("s1161",*jstat,kpos);
323 goto out;
324
325 /* Error. Kind of object does not exist. */
326 err121: *jstat = -121;
327 s6err("s1161",*jstat,kpos);
328 goto out;
329
330 /* Error in lower order routine. */
331 error : *jstat = kstat;
332 s6err("s1161",*jstat,kpos);
333 goto out;
334
335 out:
336 /* Free the edges used in s1162. */
337 if (qedge[0] != SISL_NULL) freeEdge(qedge[0]);
338
339 /* Free the dummy object(point). */
340 if (qdum != SISL_NULL) freeObject(qdum);
341
342 }
343
344