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: hp_s1880.c,v 1.5 2003-01-10 12:53:36 vsk Exp $
45  *
46  */
47 
48 
49 #define HP_S1880
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
54 void
hp_s1880(SISLObject * po1,SISLObject * po2,int ideg,int ipar1,int ipar2,SISLIntdat * pintdat,int * jpar,double ** gpar1,double ** gpar2,int ** pretop,int * jcrv,SISLIntcurve *** wcrv,int * jsurf,SISLIntsurf *** wsurf,int * jstat)55     hp_s1880(SISLObject * po1, SISLObject * po2,
56 	     int ideg,
57 	     int ipar1, int ipar2, SISLIntdat *pintdat,
58 	     int *jpar, double **gpar1, double **gpar2, int **pretop,
59 	     int *jcrv, SISLIntcurve *** wcrv, int *jsurf, SISLIntsurf *** wsurf,
60 	     int *jstat)
61 #else
62 void
63    hp_s1880(po1, po2, ideg, ipar1, ipar2, pintdat, jpar, gpar1, gpar2, pretop, jcrv,
64        wcrv, jsurf, wsurf, jstat)
65      SISLObject *po1;
66      SISLObject *po2;
67      int ideg;
68      int ipar1;
69      int ipar2;
70      SISLIntdat *pintdat;
71      int *jpar;
72      double **gpar1;
73      double **gpar2;
74      int **pretop;
75      int *jcrv;
76      SISLIntcurve ***wcrv;
77      int *jsurf;
78      SISLIntsurf ***wsurf;
79      int *jstat;
80 #endif
81 /*
82 *********************************************************************
83 *
84 *********************************************************************
85 *
86 * PURPOSE    : Transform intersection points and curves from internal
87 *              format in the recursive part of intersection routines
88 *              to output format.
89 *
90 *
91 *
92 * INPUT      : po1    - Pointer first object.
93 *              po2    - Pointer second object.
94 *              ideg   - Type of implicit geometry.
95 *              ipar1  - Number of parameter directions of first object.
96 *              ipar2  - Number of parameter directions of second object.
97 *              pintdat - SISLIntdat object.
98 *
99 *
100 * OUTPUT     : jpar   - Number of single intersection points.
101 *              gpar1  - Parameter values of the single intersection points
102 *                       in the parameter area of the first object.
103 *              gpar2  - Parameter values of the single intersection points
104 *                       in the parameter area of the second object.
105 *              pretop - Array of pretopology information for the points.
106 *              jcrv   - Number of intersection curves.
107 *              wcrv   - Array containing description of intersection curves.
108 *              jstat  - status messages
109 *                                         > 0      : warning
110 *                                         = 0      : ok
111 *                                         < 0      : error
112 *
113 *
114 * METHOD     :
115 *
116 *
117 * REFERENCES :
118 *
119 *-
120 * CALLS      : newIntcurve - Create a new instance of Intcurve.
121 *              freeIntpt   - Free space occupied by intersection point.
122 *
123 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
124 * REWRITTEN BY : Ulf J. Krystad, SI, 91-06
125 * REWRITTEN BY : Arne Laksaa & Michael Floater, SI, 91-07
126 *                 Use pintdat directly as input. Fetch pretop info.
127 * REWRITTEN BY : UJK, SI, 93-01
128 *                Exact curve treatment.
129 *********************************************************************
130 */
131 {
132   int kstat;			/* Local status                                */
133   int kpos = 0;			/* Position of error.                          */
134   int ki, kj, kk;		/* Counters.                                   */
135   int kpoint;			/* Number of points in an intersection list.   */
136   int ktype;			/* Kind of intersection curve. (See SISLIntcurve). */
137   int kpt;			/* Used to find number of single intersection points.*/
138   int index;			/* Array index for next point at start        */
139   int sing_1, sing_2;		/* Sing point flag at start and end           */
140   double *spar1, *spar2;	/* Values of points belonging to an intersection
141 				     curve in the parameter area of the objects
142 				     involved in the intersection.                 */
143   double *stpar1, *stpar2, *stpar3;	/* Pointers used to travers arrays
144 				           containing parameter values.        */
145   int *top1;	                /* Pointers used to travers pretop. */
146   SISLIntcurve **ucrv;		/* Pointer used to traverse *wcrv array.     */
147   SISLIntsurf **usurf;		/* Pointer used to traverse *wsurf array.    */
148   SISLIntpt *qpt;		/* Pointer to an intersection point.         */
149   SISLIntpt *qprev;		/* Pointer to an intersection point.         */
150   SISLIntpt *qnext;		/* Pointer to an intersection point.         */
151   SISLIntpt *qpfirst;		/* Pointer to first intersection point.      */
152   SISLIntpt *qplast;		/* Pointer to last intersection point.       */
153 
154   int jpt = pintdat->ipoint;
155   SISLIntpt **vpoint = pintdat->vpoint;
156   int jlist = pintdat->ilist;
157   SISLIntlist **vlist = pintdat->vlist;
158   SISLObject *qo2 = SISL_NULL;
159   int kdir,kdir1=-1,kdir2=-1;
160   int exact=FALSE, exact_treat=FALSE;
161   int log_test = 0;
162   double dummy;
163   /* ------------------------------------------------------------------ */
164 
165   for (ki = 1; ki < 5; ki++)
166      log_test |= 1 << ki;
167 
168   if (po1->iobj == SISLSURFACE && ideg != 0)
169   {
170      /* Surf vs Implicit geometry */
171      qo2 = newObject (SISLPOINT);
172      exact_treat = TRUE;
173   }
174   else  if (po1->iobj == SISLSURFACE &&
175 	    po2->iobj == SISLSURFACE &&
176 	    ideg ==0)
177   {
178      /* Surf vs Implicit geometry */
179      qo2 = po2;
180      exact_treat = TRUE;
181   }
182 
183 
184   /* Initiate output.  */
185 
186   *gpar1 = *gpar2 = SISL_NULL;
187   *wcrv = SISL_NULL;
188   *wsurf = SISL_NULL;
189 
190   *jcrv = 0;
191   *jsurf = 0;
192 
193   /* Allocate space for intersection curve and surface array.  */
194 
195   *wcrv = newarray (jlist, SISLIntcurve *);
196   if (jlist > 0 && *wcrv == SISL_NULL)
197     goto err101;
198   *wsurf = newarray (jlist, SISLIntsurf *);
199   if (jlist > 0 && *wcrv == SISL_NULL)
200     goto err101;
201 
202   /* Transfer curve-information from vlist array to wcrv and wsurf arrais. */
203 
204   ucrv  = *wcrv;
205   usurf = *wsurf;
206 
207   for (kpt = ki = 0; ki < jlist; ki++)
208   {
209      qpfirst = qpt = (*vlist)->pfirst;
210      qplast = (*vlist)->plast;
211      index = (*vlist)->ind_first;
212      kpoint = (*vlist)->inumb;
213      if (kpoint == 0)
214 	goto err137;
215 
216      if (qpfirst->iinter == SI_TRIM && qpfirst == qplast)
217      {
218 	/* Create new intersection surf.  */
219 
220 	*usurf = newIntsurf(*vlist);
221 	if (*usurf == SISL_NULL)
222 	   goto err101;
223 
224 	/* Copy pretopology
225 	   memcopy((*usurf)->pretop,(*vlist)->pretop,4,int); */
226 
227 	kpt += kpoint-1;
228 	usurf++;
229 	(*jsurf)++;
230      }
231      else
232      {
233 	if (qpfirst->iinter == SI_SING ||
234 	    (sh6nmbmain (qpfirst,&kstat)) > 2)
235 	   sing_1 = TRUE;
236 	else
237 	   sing_1 = FALSE;
238 
239 	if (qplast->iinter == SI_SING ||
240 	    (sh6nmbmain (qplast,&kstat)) > 2)
241 	   sing_2 = TRUE;
242 	else
243 	   sing_2 = FALSE;
244 
245 
246 	/* Allocate space for arrays containing parameter values of points
247 	   in intersection curves.                                          */
248 
249 	spar1 = newarray (ipar1 * kpoint, double);
250 	spar2 = newarray (ipar2 * kpoint, double);
251 	if ((ipar1 > 0 && spar1 == SISL_NULL) ||
252 	    (ipar2 > 0 && spar2 == SISL_NULL))
253 	   goto err101;
254 
255 	/* Collect parameter values of the points in this intersection list
256 	   and distribute values to the objects in the intersection.         */
257 
258 	kj = 0;
259 	stpar1 = spar1;
260 	stpar2 = spar2;
261 	while (qpt != SISL_NULL && kj < kpoint)
262 	{
263 	   stpar3 = qpt->epar;
264 	   for (kk = 0; kk < ipar1; kk++)
265 	      *(stpar1++) = *(stpar3++);
266 	   for (kk = 0; kk < ipar2; kk++)
267 	      *(stpar2++) = *(stpar3++);
268 
269 	   /* Reduce no of single points */
270 	   if (qpt->marker != -99)
271 	   {
272 	      kpt++;
273 
274 	      /* Flag point */
275 	      qpt->marker = -99;
276 	   }
277 	   if (qpt == qpfirst)
278 	   {
279 	      qprev = qpt;
280 	      qpt = qpt->pnext[index];
281 	   }
282 	   else
283 	   {
284 	      sh6getother (qpt, qprev, &qnext, &kstat);
285 	      qprev = qpt;
286 	      qpt = qnext;
287 	   }
288 	   kj++;
289 	}
290 
291 	/* Find type of intersection curve.  */
292 
293 	if (sing_1 && sing_2)
294 	   /* Both ends junction */
295 	   ktype = 7;
296 	else if (qpfirst == qplast)
297 	   /* Closed curve, not singular */
298 	   ktype = 2;
299 	else if (sing_1)
300 	   /* Junction at start */
301 	   ktype = 5;
302 	else if (sing_2)
303 	   /* Junction at end */
304 	   ktype = 6;
305 	else
306 	   /* Open and clean */
307 	   ktype = 4;
308 
309 
310 	exact = FALSE;
311 	/* UJK, March 1995, when curve type is 9 and the curve is
312 	   an iso-line in both surfaces, we want to return both
313 	   ppar1 and ppar2. The logic is simple:
314 	   kdir1 > -1 (ie eq 0 or 1) means constant in 1. surf.
315 	   kdir2 > -1 (ie eq 2 or 3) means constant in 2. surf.
316 	   The object space curve pgeom is picked from the 1. surf
317 	   if kdir1 is set and from 2. surf if only kdir2 is set. */
318 
319 	/* UJK, January 1993, if exact curve mark it with type 9. */
320 	kdir1 = kdir2 = -1;
321 	if (exact_treat &&
322 	    kj == 2 &&
323 	    (qpfirst->curve_dir[(*vlist)->ind_first] & log_test))
324 	{
325 	   /* Constant parameter curve */
326 	   for (kdir = 0; kdir < qpfirst->ipar; kdir++)
327 	      if (qpfirst->curve_dir[(*vlist)->ind_first] &
328 		  (1 << (kdir + 1)))
329 	      {
330 		 exact = TRUE;
331 		 ktype = 9;
332 		 if (kdir >= po1->iobj) kdir2 = kdir;
333 		 else                   kdir1 = kdir;
334 	      }
335 	}
336 
337 	if (kdir1>-1) kdir = kdir1;
338 	else          kdir = kdir2;
339 
340 	/* Create new intersection curve.  */
341 	*ucrv = newIntcurve (kj, ipar1, ipar2, spar1, spar2, ktype);
342 	if (*ucrv == SISL_NULL)
343 	   goto err101;
344 
345 	/* Copy pretopology */
346 	memcopy((*ucrv)->pretop,(*vlist)->pretop,4,int);
347 
348 
349 	/* UJK, January 1993, if exact curve mark it with type 9. */
350 	if (exact)
351 	{
352 
353 	   pick_crv_sf (po1, qo2, kdir, qpfirst,
354 			qplast, &(*ucrv)->pgeom, &kstat);
355 	   if (kstat < 0)
356 	      goto error;
357 
358 	   /* UJK, Pick 2D line  */
359 
360 	   if (kdir2 >= po1->iobj)
361 	   {
362 	      s1602(&(qpfirst->epar[po1->iobj]),
363 		    &(qplast->epar[po1->iobj]),
364 		    2,
365 		    2,
366 		    (*ucrv)->pgeom->et[(*ucrv)->pgeom->ik - 1],
367 		    &dummy,
368 		    &(*ucrv)->ppar2,
369 		    &kstat);
370 	      if (kstat < 0) goto error;
371 	   }
372 
373 	   if (kdir1 >= 0)
374 	   {
375 	      s1602(qpfirst->epar,
376 		    qplast->epar,
377 		    2,
378 		    2,
379 		    (*ucrv)->pgeom->et[(*ucrv)->pgeom->ik - 1],
380 		    &dummy,
381 		    &(*ucrv)->ppar1,
382 		    &kstat);
383 
384 	      if (kstat < 0) goto error;
385 	   }
386 
387 	}
388 
389 
390 	ucrv++;
391 	(*jcrv)++;
392      }
393      vlist++;
394   }
395 
396   /* Find number of single intersection points.  */
397 
398   kpt = jpt - kpt;
399   if (kpt < 0) goto err137;
400 
401   /* Create arrays to keep parameter values of intersection points.  */
402 
403   *gpar1 = newarray (ipar1 * kpt, double);
404   *gpar2 = newarray (ipar2 * kpt, double);
405   *pretop = newarray (4 * kpt, int);
406   if ((ipar1 * kpt > 0 && *gpar1 == SISL_NULL)
407       || (ipar2 * kpt > 0 && *gpar2 == SISL_NULL)
408       || (4 * kpt > 0 && *pretop == SISL_NULL))
409     goto err101;
410 
411   /* Copy parameters of single intersection points into output-arrays. */
412 
413   kj = 0;
414   stpar1 = *gpar1;
415   stpar2 = *gpar2;
416   top1 = *pretop;
417   for (ki = 0; ki < jpt; ki++)
418     {
419       qpt = *vpoint;
420       if (qpt != SISL_NULL)
421 	{
422 	  if (sh6ismain(qpt) && qpt->marker != -99)
423 	    {
424 	      kj++;
425 	      stpar3 = qpt->epar;
426 	      for (kk = 0; kk < ipar1; kk++)
427 		*(stpar1++) = *(stpar3++);
428 	      for (kk = 0; kk < ipar2; kk++)
429 		*(stpar2++) = *(stpar3++);
430               *(top1++) = qpt->left_obj_1[0];
431               *(top1++) = qpt->right_obj_1[0];
432               *(top1++) = qpt->left_obj_2[0];
433               *(top1++) = qpt->right_obj_2[0];
434 	    }
435 	}
436 
437       vpoint++;
438     }
439 
440   *jpar = kj;
441 
442   /* Adjust output arrays to correct length.  */
443 
444   if ((*jcrv) < jlist)
445   {
446      if ((*jcrv) > 0)
447      {
448         if (((*wcrv) = increasearray (*wcrv, *jcrv, SISLIntcurve *)) == SISL_NULL)
449            goto err101;
450      }
451      else
452      {
453         if (*wcrv != SISL_NULL)
454 	freearray (*wcrv);
455         *wcrv = SISL_NULL;
456      }
457   }
458   if ((*jsurf) < jlist)
459   {
460      if ((*jsurf) > 0)
461      {
462         if (((*wsurf) = increasearray (*wsurf, *jsurf, SISLIntsurf *)) == SISL_NULL)
463            goto err101;
464      }
465      else
466      {
467         if (*wsurf != SISL_NULL)
468 	freearray (*wsurf);
469         *wsurf = SISL_NULL;
470      }
471   }
472   if (kj * ipar1 > 0)
473     {
474       if ((*gpar1 = increasearray (*gpar1, kj * ipar1, double)) == SISL_NULL)
475 	goto err101;
476     }
477   else
478     {
479       if (*gpar1 != SISL_NULL)
480 	freearray (*gpar1);
481       *gpar1 = SISL_NULL;
482     }
483   if (kj * ipar2 > 0)
484     {
485       if ((*gpar2 = increasearray (*gpar2, kj * ipar2, double)) == SISL_NULL)
486 	goto err101;
487     }
488   else
489     {
490       if (*gpar2 != SISL_NULL)
491 	freearray (*gpar2);
492       *gpar2 = SISL_NULL;
493     }
494   if (kj  > 0)
495     {
496       if ((*pretop= increasearray (*pretop, kj * 4, int)) == SISL_NULL)
497 	goto err101;
498     }
499   else
500     {
501       if (*pretop != SISL_NULL)
502 	freearray (*pretop);
503       *pretop = SISL_NULL;
504     }
505 
506   /* Intersections copied to output format.  */
507 
508   *jstat = 0;
509   goto out;
510 
511   /* Error in space allocation.  */
512 
513 err101:*jstat = -101;
514   s6err ("hp_s1880", *jstat, kpos);
515   goto out;
516 
517   /* Error in data-strucuture. Expected intersection point not found. */
518 
519 err137:*jstat = -137;
520   s6err ("hp_s1880", *jstat, kpos);
521   goto out;
522 
523   /* Error in lower level routine. */
524 error:
525   *jstat = kstat;
526   s6err ("hp_s1880", *jstat, kpos);
527   goto out;
528 
529 
530 out:
531    if (po1->iobj == SISLSURFACE && ideg != 0)
532       freeObject (qo2);
533 return;
534 }
535