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: construct.c,v 1.2 2001-03-19 15:58:39 afr Exp $
45  *
46  */
47 
48 
49 #define CONSTRUCT
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
copyIntpt(SISLIntpt * ppt)54 SISLIntpt *copyIntpt (SISLIntpt * ppt)
55 #else
56 SISLIntpt *
57 copyIntpt (ppt)
58      SISLIntpt *ppt;
59 #endif
60 /*
61 *********************************************************************
62 *
63 *********************************************************************
64 *
65 * PURPOSE    : Make a copy of an instance of Intpt, but do not
66 *              copy the contents of pcurve.
67 *
68 *
69 *
70 * INPUT      : ppt    - Pointer to the intersection point that is
71 *                       to be copied.
72 *
73 *
74 *
75 * OUTPUT     : copyIntpt - New intersection point.
76 *
77 *
78 * METHOD     :
79 *
80 *
81 * REFERENCES :
82 *
83 *-
84 * CALLS      : newIntpt - Make new intersection point.
85 *
86 * WRITTEN BY : Vibeke Skytt, SI, 88-06.
87 *
88 *********************************************************************
89 */
90 {
91   SISLIntpt *qcopy;		/* Local pointer to copied intersection point. */
92 
93   /* Create copy.  */
94 
95   qcopy = newIntpt (ppt->ipar, ppt->epar, ppt->adist);
96   if (qcopy == SISL_NULL)
97     goto err101;
98 
99   /* Set remaining parameter.  */
100 
101   qcopy->iinter = ppt->iinter;
102 
103   /* Copy made.  */
104 
105   goto out;
106 
107   /* Error in space allocation. Return zero.  */
108 
109 err101:goto out;
110 
111 out:return (qcopy);
112 }
113 
114 #if defined(SISLNEEDPROTOTYPES)
hp_copyIntpt(SISLIntpt * ppt)115 SISLIntpt *hp_copyIntpt (SISLIntpt * ppt)
116 #else
117 SISLIntpt *
118 hp_copyIntpt (ppt)
119      SISLIntpt *ppt;
120 #endif
121 /*
122 *********************************************************************
123 *
124 *********************************************************************
125 *
126 * PURPOSE    : Make a copy of an instance of Intpt, but do not
127 *              copy the contents of pcurve.
128 *
129 *
130 *
131 * INPUT      : ppt    - Pointer to the intersection point that is
132 *                       to be copied.
133 *
134 *
135 *
136 * OUTPUT     : copyIntpt - New intersection point.
137 *
138 *
139 * METHOD     :
140 *
141 *
142 * REFERENCES :
143 *
144 *-
145 * CALLS      : hp_newIntpt - Make new intersection point.
146 *
147 * WRITTEN BY : Ulf J. Krystad, SI,  90-06.
148 *
149 *********************************************************************
150 */
151 {
152   SISLIntpt *qcopy;		/* Local pointer to copied intersection point. */
153 
154   /* Create copy.  */
155 
156   qcopy = hp_newIntpt (ppt->ipar, ppt->epar, ppt->adist, ppt->iinter,
157 		       ppt->left_obj_1[0], ppt->right_obj_1[0],
158 		       ppt->left_obj_2[0], ppt->right_obj_2[0],
159 		       ppt->size_1, ppt->size_2, ppt->geo_data_1,
160 		       ppt->geo_data_2);
161   if (qcopy == SISL_NULL)
162     goto err101;
163 
164   /* Copy made.  */
165 
166   goto out;
167 
168   /* Error in space allocation. Return zero.  */
169 
170 err101:goto out;
171 
172 out:return (qcopy);
173 }
174 
175 #if defined(SISLNEEDPROTOTYPES)
176 SISLbox *
newbox(int idim)177 newbox (int idim)
178 #else
179 SISLbox *
180 newbox (idim)
181      int idim;
182 #endif
183 /*
184 *********************************************************************
185 *
186 *********************************************************************
187 *
188 * PURPOSE    : Create and initialize a curve/surface surrounded
189 *	       SISLbox -instance.
190 *
191 *
192 *
193 * INPUT      : idim  -  Dimension of geometry space.
194 *
195 *
196 *
197 * OUTPUT     : newbox - Pointer to new SISLbox structure. If there is
198 *                       impossible to allocate space for the structure,
199 *                       newbox returns zero.
200 *
201 *
202 * METHOD     :
203 *
204 *
205 * REFERENCES :
206 *
207 *-
208 * CALLS      :
209 *
210 * WRITTEN BY : Arne Laksaa, SI, 89-03.
211 * REWISED BY : Vibeke Skytt, SI, 91-01.
212 *
213 *********************************************************************
214 */
215 {
216   SISLbox *qnew;		/* Local pointer to new direction structure.*/
217   int ki;			/* Counter.                                 */
218   int knum;			/* Number of corners in the box.	          */
219 
220 
221   /* Initialise number of corners. */
222 
223   if (idim == 3)
224     knum = 12;
225   else if (idim == 2)
226     knum = 4;
227   else
228     knum = idim;
229 
230   /* Allocate space for SISLbox structure.  */
231 
232   if ((qnew = newarray (1, SISLbox)) != SISL_NULL)
233     {
234       /* Initialise new direction structure. */
235 
236       qnew->imin = 0;
237       qnew->imax = 0;
238 
239       /* Initialize arrays.  */
240 
241       for (ki = 0; ki < 3; ki++)
242 	{
243 	  qnew->e2max[ki] = SISL_NULL;
244 	  qnew->e2min[ki] = SISL_NULL;
245 	  qnew->etol[ki] = DZERO;
246 	}
247 
248       if ((qnew->emax = newarray (knum, double)) == SISL_NULL)
249 	{
250 	  freearray (qnew);
251 	  qnew = SISL_NULL;
252 	}
253       else if ((qnew->emin = newarray (knum, double)) == SISL_NULL)
254 	{
255 	  freearray (qnew->emax);
256 	  freearray (qnew);
257 	  qnew = SISL_NULL;
258 	}
259     }
260   return (qnew);
261 }
262 
263 #if defined(SISLNEEDPROTOTYPES)
newCurve(int in,int ik,double * et,double * ecoef,int ikind,int idim,int icopy)264 SISLCurve *newCurve (int in, int ik, double *et, double *ecoef,
265 	  int ikind, int idim, int icopy)
266 #else
267 SISLCurve *
268 newCurve (in, ik, et, ecoef, ikind, idim, icopy)
269      int in;
270      int ik;
271      double *et;
272      double *ecoef;
273      int ikind;
274      int idim;
275      int icopy;
276 #endif
277 /*
278 *********************************************************************
279 *
280 *********************************************************************
281 *
282 * PURPOSE    : Create and initialize a Curve-instance.
283 *
284 *
285 *
286 * INPUT      : in     - Number of vertices in new curve.
287 *              ik     - Order of curve.
288 *              et     - Knotvector of curve.
289 *              ecoef  - Vertices of curve.
290 *              ikind  - Kind of curve
291 *                        = 1 : Polynomial B-spline curve.
292 *                        = 2 : Rational B-spline curve.
293 *                        = 3 : Polynomial Bezier curve.
294 *                        = 4 : Rational Bezier curve.
295 *              idim   - Dimension of the space in which the curve lies.
296 *              icopy  - Flag
297 *                       = 0 : Set pointer to input arrays.
298 *                       = 1 : Copy input arrays.
299 *                       = 2 : Set pointer and remember to free arrays.
300 *
301 *
302 *
303 * OUTPUT     : newCurve - Pointer to new curve. If there is impossible
304 *                         to allocate space for the curve, newCurve
305 *                         returns zero.
306 *
307 *
308 * METHOD     :
309 *              If curve is rational,
310 *              points input in ecoef should have the form (w*P1,...,w*Pidim,w)
311 *              The new curve will then have two arrays:
312 *              qnew -> ecoef with points of the form (P1,...,Pidim)
313 *              qnew -> rcoef with points of the form (w*P1,...w*Pidim,w).
314 *
315 *
316 * REFERENCES :
317 *
318 *-
319 * CALLS      :
320 *
321 * WRITTEN BY  : Vibeke Skytt, SI, 88-05.
322 * MODIFIED BY : Mike Floater, SI, 91-01 for rational curves.
323 *
324 *             : UJK, 92.03.27 Default value set for cuopen SISL_CRV_OPEN
325 *             : VSK, 92.09.04 Remove superfluous knots and vertices
326 *                             in the start and end of the curve.
327 *
328 *********************************************************************
329 */
330 {
331   SISLCurve *qnew;		/* Local pointer to new curve.  */
332   int i, j, J, jj, k;		/* loop variables               */
333   int k1,k2;                    /* Superflous knots in the ends. */
334   int kdim;			/* Dimension of space (also including potential
335 				   homogenous coordinate        */
336   double *st = SISL_NULL;		/* Copy of knotvector.          */
337   double *rcoef = SISL_NULL;		/* Copy of vertices in rational case.  */
338   double *scoef = SISL_NULL;		/* Copy of vertices.            */
339 
340 
341   /* Allocate space for curve.  */
342 
343   if ((qnew = newarray (1, SISLCurve)) == SISL_NULL)
344     goto err101;
345 
346   if (ikind == 2 || ikind == 4)
347     kdim = idim + 1;
348   else
349     kdim = idim;
350 
351   /* Count superflous knots in the start.  */
352 
353   for (k1=0; k1<in; k1++)
354      if (et[ik-1] < et[ik+k1]) break;
355 
356   /* Count superflous knots in the end.  */
357 
358   for (k2=0; k2<in; k2++)
359      if (et[in] > et[in-1-k2]) break;
360 
361   /* Reduce knots and vertices according to k1 and k2.  */
362 
363   if (k1 > 0)
364   {
365      memcopy(ecoef,ecoef+k1*kdim,(in-k1)*kdim,DOUBLE);
366      memcopy(et,et+k1,in+ik-k1,DOUBLE);
367   }
368   in -= (k1+k2);
369 
370   /* Check if the curve is still valid. Otherwise return zero. */
371 
372   if (in < ik) goto err101;
373 
374   if (icopy == 1)
375     {
376 
377       /* Copy input arrays. First allocate space for new arrays. */
378 
379       if ((st = newarray (in +ik, DOUBLE)) == SISL_NULL ||
380 	  (scoef = newarray (in *kdim, DOUBLE)) == SISL_NULL)
381 	goto err101;
382 
383       /* Copy contents of arrays.  */
384 
385       memcopy (st, et, in +ik, double);
386       memcopy (scoef, ecoef, in *kdim, double);
387     }
388   else
389     {
390       st = et;
391       scoef = ecoef;
392     }
393 
394   /* Initialize new curve.  */
395 
396   qnew->in = in;
397   qnew->ik = ik;
398   qnew->ikind = ikind;
399   qnew->idim = idim;
400   qnew->icopy = icopy;
401   qnew->et = st;
402   qnew->pdir = SISL_NULL;
403   qnew->pbox = SISL_NULL;
404 
405   if (ikind == 2 || ikind == 4)
406     {
407       /* Calculate the weighted control points if the object is rational  */
408       rcoef = newarray (in *idim, DOUBLE);
409       if (rcoef == SISL_NULL)
410 	goto err101;
411       for (i = 0, j = 0, J = 0, k = idim; i < in; i++, k += kdim)
412 	{
413 	  for (jj = 0; jj < idim; jj++, j++, J++)
414 	    {
415 	      rcoef[J] = scoef[j] / scoef[k];
416 	    }
417 	  j++;
418 	}
419       qnew->ecoef = rcoef;
420       qnew->rcoef = scoef;
421     }
422   else
423     {
424       qnew->ecoef = scoef;
425       qnew->rcoef = SISL_NULL;
426     }
427 
428 
429   /* UJK, 92.03.27 Default value must be set for cuopen */
430   qnew->cuopen = SISL_CRV_OPEN;
431 
432   /* Task done. */
433   goto out;
434 
435   /* Error in space allocation. Return zero. */
436 
437 err101:if (qnew != SISL_NULL)
438           { freearray (qnew);  qnew = SISL_NULL;}
439   if (st != SISL_NULL)
440     freearray (st);
441   if (rcoef != SISL_NULL)
442     freearray (rcoef);
443   if (scoef != SISL_NULL)
444     freearray (scoef);
445   goto out;
446 
447 out:return (qnew);
448 }
449 
450 #if defined(SISLNEEDPROTOTYPES)
451 SISLdir *
newdir(int idim)452 newdir (int idim)
453 #else
454 SISLdir *
455 newdir (idim)
456      int idim;
457 #endif
458 /*
459 *********************************************************************
460 *
461 *********************************************************************
462 *
463 * PURPOSE    : Create and initialize a curve/surface direction-instance.
464 *
465 *
466 *
467 * INPUT      : idim   - Dimension of the space in which the object lies.
468 *
469 *
470 *
471 * OUTPUT     : newdir - Pointer to new direction structure. If there is
472 *                       impossible to allocate space for the structure,
473 *                       newdir returns zero.
474 *
475 *
476 * METHOD     :
477 *
478 *
479 * REFERENCES :
480 *
481 *-
482 * CALLS      :
483 *
484 * WRITTEN BY : Arne Laksaa, SI, 89-03.
485 *
486 *********************************************************************
487 */
488 {
489   SISLdir *qnew;		/* Local pointer to new direction structure.*/
490 
491   /* Allocate space for direction structure.  */
492 
493   if ((qnew = newarray (1, SISLdir)) != SISL_NULL)
494     {
495       /* Initialise new direction structure. */
496 
497       qnew->igtpi = 0;
498       qnew->esmooth = SISL_NULL;
499       if ((qnew->ecoef = newarray (idim, double)) == SISL_NULL)
500 	freearray (qnew);
501     }
502   return (qnew);
503 }
504 
505 #if defined(SISLNEEDPROTOTYPES)
newEdge(int iedge)506 SISLEdge *newEdge (int iedge)
507 #else
508 SISLEdge *
509 newEdge (iedge)
510      int iedge;
511 #endif
512 /*
513 *********************************************************************
514 *
515 *********************************************************************
516 *
517 * PURPOSE    : Create and initialize to zero an instance of the
518 *              structure Edge. The instance keeps track of intersection
519 *              points on the edges/endpoints of an object.
520 *
521 *
522 *
523 * INPUT      : iedge  - Number of edges/endpoints of the object to
524 *                       which it corresponds.
525 *                       A curve has iedge = 2.
526 *                       A tensor-product surface has iedge = 4.
527 *
528 *
529 *
530 * OUTPUT     : newEdge - A pointer to the instance created.
531 *
532 *
533 * METHOD     :
534 *
535 *
536 * REFERENCES :
537 *
538 *-
539 * CALLS      :
540 *
541 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
542 *
543 *********************************************************************
544 */
545 {
546   int ki;			/* Counter.                          */
547   SISLEdge *pnew;		/* Local pointer to the instance.    */
548   SISLPtedge *(*ppt);		/* Pointer to traverst array prpt of
549   			       pointers to Ptedge-instances.     */
550 
551   /* Allocate space for instance.  */
552 
553   pnew = newarray (1, SISLEdge);
554   if (pnew == SISL_NULL)
555     goto err101;
556 
557   /* Allocate space for array of pointers to Ptedge. */
558 
559   pnew->prpt = newarray (iedge, SISLPtedge *);
560   if (pnew->prpt == SISL_NULL)
561     goto err101;
562 
563   /* Initiate the variables of the instance. */
564 
565   pnew->iedge = iedge;
566   pnew->ipoint = 0;
567 
568   ppt = pnew->prpt;
569   for (ki = 0; ki < iedge; ki++)
570     *(ppt++) = SISL_NULL;
571 
572   /* Task done. */
573 
574   goto out;
575 
576   /* Error in space allocation. Retrun zero. */
577 
578 err101:pnew = SISL_NULL;
579   goto out;
580 
581 out:return (pnew);
582 }
583 
584 #if defined(SISLNEEDPROTOTYPES)
newIntcurve(int ipoint,int ipar1,int ipar2,double * epar1,double * epar2,int itype)585 SISLIntcurve *newIntcurve (int ipoint, int ipar1, int ipar2,
586 			   double *epar1, double *epar2, int itype)
587 #else
588 SISLIntcurve *
589 newIntcurve (ipoint, ipar1, ipar2, epar1, epar2, itype)
590      int ipoint;
591      int ipar1;
592      int ipar2;
593      double *epar1;
594      double *epar2;
595      int itype;
596 #endif
597 /*
598 *********************************************************************
599 *
600 *********************************************************************
601 *
602 * PURPOSE    : Create and initialize a new instance of the structure
603 *              Intlist.
604 *
605 *
606 *
607 * INPUT      : ipoint - Number of points that define the curve.
608 *              ipar1  - Number of parameter directions of first object
609 *                       involved in the intersection.
610 *              ipar2  - Number of parameter direction of second object.
611 *              epar1  - Parameter values of points in the parameter
612 *                       area of the first object.
613 *                       NB! The epar1-pointer is set to point to this
614 *                           array. The values are not copied.
615 *              epar2  - Parameter values of points in the parameter
616 *                       area of the second object.
617 *                       NB! The epar2-pointer is set to point to this
618 *                           array. The values are not copied.
619 *              itype  - Kind of curve. (See intcurve.dcl).
620 *
621 *
622 *
623 * OUTPUT     : newIntcurve - An instance of the structure Intlist.
624 *                            If it is not possible to allocate the
625 *                            necessary space, zero is returned.
626 *              istat  - status messages
627 *                                         > 0      : warning
628 *                                         = 0      : ok
629 *                                         < 0      : error
630 *
631 *
632 * METHOD     :
633 *
634 *
635 * REFERENCES :
636 *
637 *-
638 * CALLS      :
639 *
640 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
641 *
642 *********************************************************************
643 */
644 {
645   SISLIntcurve *qnew;
646 
647   /* Allocate space for the new Intcurve.  */
648 
649   qnew = newarray (1, SISLIntcurve);
650   if (qnew == SISL_NULL)
651     goto err101;
652 
653   /* Set variables of the intersection curve.  */
654 
655   qnew->ipoint = ipoint;
656   qnew->ipar1 = ipar1;
657   qnew->ipar2 = ipar2;
658   qnew->epar1 = epar1;
659   qnew->epar2 = epar2;
660   qnew->pgeom = SISL_NULL;
661   qnew->ppar1 = SISL_NULL;
662   qnew->ppar2 = SISL_NULL;
663   qnew->itype = itype;
664 
665   /* Task done.  */
666 
667   goto out;
668 
669   /* Error in space allocation. Return zero.  */
670 
671 err101:qnew = SISL_NULL;
672   goto out;
673 
674 out:return (qnew);
675 }
676 
677 #if defined(SISLNEEDPROTOTYPES)
newIntdat(void)678 SISLIntdat *newIntdat (void)
679 #else
680 SISLIntdat *
681 newIntdat ()
682 #endif
683 /*
684 *********************************************************************
685 *
686 *********************************************************************
687 *
688 * PURPOSE    : Create and initialize to zero an instance of the
689 *              structure Intdat.
690 *
691 *
692 *
693 * INPUT
694 *
695 *
696 *
697 * OUTPUT     : newIntdat - A pointer to the instance created.
698 *
699 *
700 * METHOD     :
701 *
702 *
703 * REFERENCES :
704 *
705 *-
706 * CALLS      :
707 *
708 * WRITTEN BY : UJK         , SI, 89-04.
709 *
710 *********************************************************************
711 */
712 {
713   SISLIntdat *pnew = SISL_NULL;	/* Local pointer to the instance.       */
714 
715   /* Allocate space for instance.                                      */
716 
717   if ((pnew = newarray (1, SISLIntdat)) != SISL_NULL)
718     {
719       /* Initiate the variables of the instance.                   */
720       pnew->ipmax = 20;
721       pnew->ilmax = 10;
722       pnew->ipoint = 0;
723       pnew->ilist = 0;
724 
725       /* Allocate space for array of pointers to Intlist.          */
726 
727       if ((pnew->vlist = new0array (pnew->ilmax, SISLIntlist *)) != SISL_NULL)
728 	{
729 	  /* Allocate space for array of pointers to SISLIntpt     */
730 	  if ((pnew->vpoint = new0array (pnew->ipmax, SISLIntpt *))
731 	      != SISL_NULL) ;
732 
733 	  /* Task done.                                        */
734 
735 	  else
736 	    {
737 	      /* Error in space allocation of pnew->vpoint.*/
738 	      freearray (pnew->vlist);
739 	      freearray (pnew);
740 	    }
741 	}
742       else
743 	/* Error in space allocation of pnew->vlist.	     */
744 	freearray (pnew);
745     }
746   return pnew;
747 }
748 
749 #if defined(SISLNEEDPROTOTYPES)
newIntlist(SISLIntpt * pfirst,SISLIntpt * plast,int itype)750 SISLIntlist *newIntlist (SISLIntpt * pfirst, SISLIntpt * plast, int itype)
751 #else
752 SISLIntlist *
753 newIntlist (pfirst, plast, itype)
754      SISLIntpt *pfirst;
755      SISLIntpt *plast;
756      int itype;
757 #endif
758 /*
759 *********************************************************************
760 *
761 *********************************************************************
762 *
763 * PURPOSE    : Create and initialize an instance of the structure
764 *              SISLIntlist that contains a list of intersection points
765 *              defining an intersection curve.
766 *
767 *
768 *
769 * INPUT      : pfirst - Pointer to first intersection point in the list.
770 *              plast  - Pointer to last intersection point in the list.
771 *              itype  - Kind of curve. See definition of the structure
772 *                       Intlist.
773 *
774 *
775 *
776 * OUTPUT     : newIntlist - Pointer to the new instance of Intlist.
777 *
778 *
779 * METHOD     :
780 *
781 *
782 * REFERENCES :
783 *
784 *-
785 * CALLS      :
786 *
787 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
788 *
789 *********************************************************************
790 */
791 {
792   SISLIntlist *pnew;		/* Local pointer to this instance. */
793 
794   /* Allocate space for the instance.  */
795 
796   pnew = newarray (1, SISLIntlist);
797   if (pnew == SISL_NULL)
798     goto err101;
799 
800   /* Initialize.  */
801 
802   pnew->pfirst = pfirst;
803   pnew->plast = plast;
804   pnew->itype = itype;
805   pnew->inumb = 2;
806 
807   /* Tast done. */
808 
809   goto out;
810 
811   /* Error in space allocation. Return zero.  */
812 
813 err101:pnew = SISL_NULL;
814   goto out;
815 
816 out:return (pnew);
817 }
818 
819 #if defined(SISLNEEDPROTOTYPES)
newIntpt(int ipar,double * epar,double adist)820 SISLIntpt *newIntpt (int ipar, double *epar, double adist)
821 #else
822 SISLIntpt *
823 newIntpt (ipar, epar, adist)
824      int ipar;
825      double *epar;
826      double adist;
827 #endif
828 /*
829 *********************************************************************
830 *
831 *********************************************************************
832 *
833 * PURPOSE    : Create and initializes a new instance of the structure
834 *              Intpt. A pointer to this instance is returned.
835 *
836 *
837 *
838 * INPUT      : ipar   - Number of parameter directions in the intersection
839 *                       problem, i.e. dimension of the array epar.
840 *              epar   - Parameter value of intersection point, possibly
841 *                       in two objects.
842 *              adist  - Distance between the objects in the point if
843 *                       there is two objects in the problem.
844 *
845 *
846 *
847 * OUTPUT     : newIntpt - Pointer to the new instance of Intpt.
848 *
849 *
850 * METHOD     :
851 *
852 *
853 * REFERENCES :
854 *
855 *-
856 * CALLS      :
857 *
858 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
859 *
860 *********************************************************************
861 */
862 {
863   SISLIntpt *pnew;		/* Local pointer to instance to create. */
864   int ki;			/* Counter.                             */
865 
866   /* Allocate space for instance of Intpt. */
867 
868   pnew = newarray (1, SISLIntpt);
869   if (pnew == SISL_NULL)
870     goto err101;
871 
872   /* Initialize instance. First allocate space for parameter array. */
873 
874   if (ipar > 0)
875     {
876       pnew->epar = newarray (ipar, DOUBLE);
877       if (pnew->epar == SISL_NULL)
878 	goto err101;
879     }
880 
881 
882   /* Initialize the variables of the instance. */
883 
884   pnew->ipar = ipar;
885   for (ki = 0; ki < ipar; ki++)
886     pnew->epar[ki] = epar[ki];
887   pnew->adist = adist;
888   pnew->pcurve = SISL_NULL;
889   pnew->iinter = 0;
890 
891   /* Set intersection atributes to SISL_NULL */
892   pnew->no_of_curves_alloc = 0;
893   pnew->no_of_curves = 0;
894 
895   pnew->pnext = SISL_NULL;
896   pnew->curve_dir = SISL_NULL;
897   pnew->left_obj_1 = SISL_NULL;
898   pnew->left_obj_2 = SISL_NULL;
899   pnew->right_obj_1 = SISL_NULL;
900   pnew->right_obj_2 = SISL_NULL;
901   pnew->geo_data_1 = SISL_NULL;
902   pnew->size_1 = 0;
903   pnew->geo_data_2 = SISL_NULL;
904   pnew->size_2 = 0;
905 
906   pnew->trim[0] = SISL_NULL;
907   pnew->trim[1] = SISL_NULL;
908 
909   /* Task done.  */
910 
911 
912   goto out;
913 
914   /* Error in space allocation. Return zero. */
915 
916 err101:pnew = SISL_NULL;
917   goto out;
918 
919 out:return (pnew);
920 }
921 
922 #if defined(SISLNEEDPROTOTYPES)
newIntsurf(SISLIntlist * pintlist)923 SISLIntsurf *newIntsurf (SISLIntlist * pintlist)
924 #else
925 SISLIntsurf *
926 newIntsurf (pintlist)
927      SISLIntlist *pintlist;
928 #endif
929 /*
930 *********************************************************************
931 *
932 *********************************************************************
933 *
934 * PURPOSE    : Create a new instance of the structure
935 *              Intsurf.
936 *
937 *
938 *
939 * INPUT      : pintlist - Pointer to the surround curve.
940 *
941 *
942 * OUTPUT     : newIntsurf - Pointer to the new instance,
943 *
944 *
945 * METHOD     :
946 *
947 *
948 * REFERENCES :
949 *
950 *-
951 * CALLS      :
952 *
953 * WRITTEN BY : Ulf J. Krystad, SI, 91-10.
954 *
955 *********************************************************************
956 */
957 {
958   SISLIntsurf *pnew = SISL_NULL;	/* Local pointer to instance to create. */
959   SISLIntpt *qpt = SISL_NULL;	/* Local help pointer                   */
960   SISLIntpt *qpfirst = SISL_NULL;	/* Local help pointer                   */
961   SISLIntpt *qplast = SISL_NULL;	/* Local help pointer                   */
962   SISLIntpt *qprev = SISL_NULL;	/* Local help pointer                   */
963   SISLIntpt *qnext = SISL_NULL;	/* Local help pointer                   */
964   int index, ipar, ipoint;
965   int ki, kk, kdir;		/* Counter.                             */
966   int dummy,kstat;
967   double *stpar1, *stpar2;
968   /* ------------------------------------------------------------------ */
969 
970   if (pintlist == SISL_NULL)
971     goto out;
972 
973   qpfirst = pintlist->pfirst;
974   qplast  = pintlist->plast;
975   ipoint  = pintlist->inumb - 1;
976   ipar    = qpfirst->ipar;
977   index   = pintlist->ind_first;
978 
979 
980   if (ipar <= 0)
981     goto out;
982   if (ipoint <= 1)
983     goto out;
984 
985   /* Allocate space for instance of Intsurf. */
986   pnew = newarray (1, SISLIntsurf);
987   if (pnew == SISL_NULL)
988     goto err101;
989 
990   pnew->ipar = ipar;
991   pnew->ipoint = ipoint;
992 
993   /* First allocate space for parameter array. */
994   pnew->epar = stpar1 = newarray (ipar * ipoint, DOUBLE);
995   if (pnew->epar == SISL_NULL)
996     goto err101;
997 
998   /* Allocate space for constant direction array. */
999   /* UJK, sept 92 */
1000   /* pnew->const_par = newarray (ipar, int); */
1001   pnew->const_par = newarray (ipoint, int);
1002   if (pnew->const_par == SISL_NULL)
1003     goto err101;
1004 
1005   /* Fill in arrays */
1006 
1007   qpt = qprev = qpfirst;
1008   qnext = qpt->pnext[index];
1009 
1010     for (ki = 0; ki < ipoint; ki++)
1011     {
1012       qpt->marker = -99;
1013       stpar2 = qpt->epar;
1014       for (kk = 0; kk < ipar; kk++)
1015 	*(stpar1++) = *(stpar2++);
1016 
1017       for (kdir = 0; kdir < ipar; kdir++)
1018 	if (qpt->curve_dir[index] &
1019 	    (1 << (kdir + 1)))
1020 	  break;
1021 
1022       pnew->const_par[ki] = kdir;
1023 
1024       /* Next point */
1025       qprev = qpt;
1026       qpt = qnext;
1027       sh6getother (qpt, qprev, &qnext, &kstat);
1028 
1029       sh6getlist (qpt, qnext, &index, &dummy, &kstat);
1030     }
1031 
1032   /* Task done.  */
1033 
1034 
1035   goto out;
1036 
1037   /* Error in space allocation. Return zero. */
1038 
1039 err101:pnew = SISL_NULL;
1040   goto out;
1041 
1042 out:return (pnew);
1043 }
1044 
1045 
1046 
1047 
1048 
1049 #if defined(SISLNEEDPROTOTYPES)
newTrimpar(int pt,int par)1050 SISLTrimpar *newTrimpar (int pt, int par)
1051 #else
1052 SISLTrimpar *
1053 newTrimpar (pt, par)
1054      int pt;
1055      int par;
1056 #endif
1057 /*
1058 *********************************************************************
1059 *
1060 *********************************************************************
1061 *
1062 * PURPOSE    : Create and initializes a new instance of the structure
1063 *              SISLTrimpar. A pointer to this instance is returned.
1064 *
1065 *
1066 *
1067 * INPUT      : pt     - Index in pnext to a pointer to an adjacent
1068 *                       point in the trim curve.
1069 *              par    - An integer between 0 and 3 indicating
1070 *                          which parameter is constant on the
1071 *                          trim curve joining ptindex.
1072 *
1073 *
1074 * OUTPUT     : newTrimpar - Pointer to the new instance of Trimpar.
1075 *
1076 *
1077 * METHOD     :
1078 *
1079 *
1080 * REFERENCES :
1081 *
1082 *-
1083 * CALLS      :
1084 *
1085 * WRITTEN BY : Michael Floater, SI, 91-10.
1086 *
1087 *********************************************************************
1088 */
1089 {
1090   SISLTrimpar *newtrim;		/* Local pointer to instance to create. */
1091 
1092   /* Allocate space for instance of Trimpar. */
1093 
1094   newtrim = newarray (1, SISLTrimpar);
1095   if (newtrim == SISL_NULL)
1096     goto err101;
1097 
1098   /* Initialize the variables of the instance. */
1099 
1100   newtrim->ptindex = pt;
1101   newtrim->parindex = par;
1102 
1103   /* Task done.  */
1104 
1105 
1106   goto out;
1107 
1108   /* Error in space allocation. Return zero. */
1109 
1110 err101:newtrim = SISL_NULL;
1111   goto out;
1112 
1113 out:return (newtrim);
1114 }
1115 
1116 #if defined(SISLNEEDPROTOTYPES)
1117 SISLIntpt *
hp_newIntpt(int ipar,double * epar,double adist,int itype,int ileft1,int iright1,int ileft2,int iright2,int size_1,int size_2,double egeom1[],double egeom2[])1118 hp_newIntpt (int ipar, double *epar, double adist, int itype,
1119 	     int ileft1, int iright1, int ileft2, int iright2,
1120 	     int size_1, int size_2, double egeom1[], double egeom2[])
1121 #else
1122 SISLIntpt *
1123 hp_newIntpt (ipar, epar, adist, itype, ileft1, iright1, ileft2, iright2,
1124 	     size_1, size_2, egeom1, egeom2)
1125      int ipar;
1126      double *epar;
1127      double adist;
1128      int itype;
1129      int ileft1;
1130      int iright1;
1131      int ileft2;
1132      int iright2;
1133      int size_1;
1134      int size_2;
1135      double *egeom1;
1136      double *egeom2;
1137 #endif
1138 /*
1139 *********************************************************************
1140 *
1141 *********************************************************************
1142 *
1143 * PURPOSE    : Create and initializes a new instance of the structure
1144 *              Intpt. A pointer to this instance is returned.
1145 *
1146 *
1147 *
1148 * INPUT      : ipar   - Number of parameter directions in the intersection
1149 *                       problem, i.e. dimension of the array epar.
1150 *              epar   - Parameter value of intersection point, possibly
1151 *                       in two objects.
1152 *              adist  - Distance between the objects in the point if
1153 *                       there is two objects in the problem.
1154 *              itype  - Type of intersection point.
1155 *              ileft1, iright1, ileft2, iright2 - Pre-topology information
1156 *                       conserning interpolation point.
1157 *              size_1 - length of egeom1.
1158 *              size_2 - length of egeom2.
1159 *              egeom1 - Geometry information of intersection point in
1160 *                       first object.
1161 *              egeom2 - Geometry information of intersection point in
1162 *                       second object.
1163 *
1164 *
1165 *
1166 * OUTPUT     : hp_newIntpt - Pointer to the new instance of Intpt.
1167 *
1168 *
1169 * METHOD     :
1170 *
1171 *
1172 * REFERENCES :
1173 *
1174 *-
1175 * CALLS      :
1176 *
1177 * WRITTEN BY : Ulf J. Krystad, SI, 91-06.
1178 *
1179 *********************************************************************
1180 */
1181 {
1182   SISLIntpt *pnew;		/* Local pointer to instance to create. */
1183   int ki;			/* Counter.                             */
1184 
1185 
1186   /* Allocate space for instance of Intpt. */
1187 
1188   pnew = new0array (1, SISLIntpt);
1189   if (pnew == SISL_NULL)
1190     goto err101;
1191 
1192   /* Initialize parameters concerning the size of arrays describing
1193      the intersection curves in which this points lie, and allocate
1194      scratch for the arrays.      */
1195 
1196   pnew->no_of_curves_alloc = 4;
1197   pnew->no_of_curves = 0;
1198 
1199   if ((pnew->pnext = newarray (pnew->no_of_curves_alloc, SISLIntpt *)) == SISL_NULL)
1200     goto err101;
1201   if ((pnew->curve_dir = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL)
1202     goto err101;
1203   if ((pnew->left_obj_1 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL)
1204     goto err101;
1205   if ((pnew->left_obj_2 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL)
1206     goto err101;
1207   if ((pnew->right_obj_1 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL)
1208     goto err101;
1209   if ((pnew->right_obj_2 = newarray (pnew->no_of_curves_alloc, INT)) == SISL_NULL)
1210     goto err101;
1211 
1212   /* Initialize instance. First allocate space for parameter array. */
1213 
1214   pnew->epar = SISL_NULL;
1215   if (ipar > 0)
1216     {
1217       pnew->epar = newarray (ipar, DOUBLE);
1218       if (pnew->epar == SISL_NULL)
1219 	goto err101;
1220     }
1221 
1222 
1223   /* Initialize the variables of the instance. */
1224 
1225   pnew->ipar = ipar;
1226   for (ki = 0; ki < ipar; ki++)
1227     pnew->epar[ki] = epar[ki];
1228   pnew->adist = adist;
1229   pnew->pcurve = SISL_NULL;
1230   pnew->edge_1 = 0;
1231   pnew->edge_2 = 0;
1232   pnew->iinter = itype;
1233   pnew->marker = 0;
1234   pnew->evaluated = 0;
1235 
1236   if (size_1 > 0)
1237     {
1238       pnew->geo_data_1 = newarray (size_1, DOUBLE);
1239       pnew->size_1 = size_1;
1240       memcopy (pnew->geo_data_1, egeom1, size_1, double);
1241     }
1242   else
1243     {
1244       pnew->geo_data_1 = SISL_NULL;
1245       pnew->size_1 = 0;
1246     }
1247 
1248   if (size_2 > 0)
1249     {
1250       pnew->geo_data_2 = newarray (size_2, DOUBLE);
1251       pnew->size_2 = size_2;
1252       memcopy (pnew->geo_data_2, egeom2, size_2, double);
1253     }
1254   else
1255     {
1256       pnew->geo_data_2 = SISL_NULL;
1257       pnew->size_2 = 0;
1258     }
1259 
1260 
1261   *(pnew->left_obj_1) = ileft1;
1262   *(pnew->left_obj_2) = ileft2;
1263   *(pnew->right_obj_1) = iright1;
1264   *(pnew->right_obj_2) = iright2;
1265 
1266   for (ki = 0; ki < pnew->no_of_curves_alloc; ki++)
1267     pnew->pnext[ki] = SISL_NULL;
1268 
1269   /*  for (ki=0; ki<6; ki++) pnew -> geo_aux[ki] = DZERO; */
1270 
1271   pnew->trim[0] = SISL_NULL;
1272   pnew->trim[1] = SISL_NULL;
1273 
1274   /* Init the left/right evaluator to default value zero. */
1275   pnew->iside_1 = 0;
1276   pnew->iside_2 = 0;
1277 
1278   /* Task done.  */
1279 
1280   goto out;
1281 
1282   /* Error in space allocation. Return zero. */
1283 
1284 err101:pnew = SISL_NULL;
1285   goto out;
1286 
1287 out:return (pnew);
1288 }
1289 
1290 #if defined(SISLNEEDPROTOTYPES)
1291 SISLTrack *
newTrack(SISLSurf * psurf_1,SISLSurf * psurf_2,SISLCurve * pcurve_3d,SISLCurve * pcurve_2d_1,SISLCurve * pcurve_2d_2,int ideg,double eimpli[],int sing_start,int sing_end,int turned)1292 newTrack (SISLSurf * psurf_1, SISLSurf * psurf_2, SISLCurve * pcurve_3d,
1293 	  SISLCurve * pcurve_2d_1, SISLCurve * pcurve_2d_2,
1294 	int ideg, double eimpli[], int sing_start, int sing_end, int turned)
1295 #else
1296 SISLTrack *
1297 newTrack (psurf_1, psurf_2, pcurve_3d,
1298 	  pcurve_2d_1, pcurve_2d_2,
1299 	  ideg, eimpli, sing_start, sing_end, turned)
1300      SISLSurf *psurf_1;
1301      SISLSurf *psurf_2;
1302      SISLCurve *pcurve_3d;
1303 
1304      SISLCurve *pcurve_2d_1;
1305      SISLCurve *pcurve_2d_2;
1306 
1307      int ideg;
1308      double eimpli[];
1309      int sing_start;
1310      int sing_end;
1311      int turned;
1312 
1313 #endif
1314 /*
1315 *********************************************************************
1316 *
1317 *********************************************************************
1318 *
1319 * PURPOSE    : Create and initializes a new instance of the structure
1320 *              SISLTrack. A pointer to this instance is returned.
1321 *
1322 *
1323 *
1324 * INPUT      : Compatible with the attributes in the structure track
1325 *
1326 *
1327 *
1328 * OUTPUT     : newTrack - Pointer to the new instance of SISLTrack
1329 *
1330 *
1331 * REFERENCES :
1332 *
1333 *-
1334 * CALLS      :
1335 *
1336 * WRITTEN BY : Ulf J. Krystad, SI, 91-06.
1337 *
1338 *********************************************************************
1339 */
1340 {
1341   SISLTrack *pnew;		/* Local pointer to instance to create. */
1342 
1343 
1344   /* Allocate space for instance of Intpt. */
1345 
1346   pnew = new0array (1, SISLTrack);
1347   if (pnew == SISL_NULL)
1348     goto err101;
1349 
1350   /* Set atributes */
1351 
1352 
1353   pnew->psurf_1 = psurf_1;
1354   pnew->psurf_2 = psurf_2;
1355   pnew->pcurve_3d = pcurve_3d;
1356   pnew->pcurve_2d_1 = pcurve_2d_1;
1357   pnew->pcurve_2d_2 = pcurve_2d_2;
1358   pnew->ideg = ideg;
1359   if (pnew->ideg)
1360     memcopy (pnew->eimpli, eimpli, 16, DOUBLE);
1361   pnew->sing_start = sing_start;
1362   pnew->sing_end = sing_end;
1363   pnew->turned = turned;
1364 
1365   /* Task done.  */
1366 
1367   goto out;
1368 
1369   /* Error in space allocation. Return zero. */
1370 
1371 err101:pnew = SISL_NULL;
1372   goto out;
1373 
1374 out:return (pnew);
1375 }
1376 
1377 #if defined(SISLNEEDPROTOTYPES)
newObject(int iobj)1378 SISLObject *newObject (int iobj)
1379 #else
1380 SISLObject *
1381 newObject (iobj)
1382      int iobj;
1383 #endif
1384 /*
1385 *********************************************************************
1386 *
1387 *********************************************************************
1388 *
1389 * PURPOSE    : Create and initialize partly an Object-instance.
1390 *
1391 *
1392 *
1393 * INPUT      : iobj   - Kind of object.
1394 *
1395 *
1396 *
1397 * OUTPUT     : newObject - Pointer to new object. If there is impossible
1398 *                          to allocate space for the object, newObject
1399 *                          returns zero.
1400 *              istat     - status messages
1401 *                                         > 0      : warning
1402 *                                         = 0      : ok
1403 *                                         < 0      : error
1404 *
1405 *
1406 * METHOD     :
1407 *
1408 *
1409 * REFERENCES :
1410 *
1411 *-
1412 * CALLS      :
1413 *
1414 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
1415 * MODIFIED BY: UJK               89-04.
1416 *              The structure SISLPoint is included.
1417 *              The pointer to structure object itself is included.
1418 *
1419 *********************************************************************
1420 */
1421 {
1422   SISLObject *qnew;		/* Local pointer to new object.  */
1423 
1424   qnew = newarray (1, SISLObject);
1425   if (qnew == SISL_NULL)
1426     goto out;
1427 
1428   qnew->iobj = iobj;
1429 
1430   qnew->p1 = SISL_NULL;
1431   qnew->c1 = SISL_NULL;
1432   qnew->s1 = SISL_NULL;
1433   qnew->o1 = SISL_NULL;
1434   qnew->edg[0] = SISL_NULL;
1435   qnew->edg[1] = SISL_NULL;
1436   qnew->edg[2] = SISL_NULL;
1437   qnew->edg[3] = SISL_NULL;
1438   qnew->psimple = SISL_NULL;
1439 
1440   /* Task done.  */
1441 
1442 out:return qnew;
1443 }
1444 
1445 #if defined(SISLNEEDPROTOTYPES)
newPoint(double * ecoef,int idim,int icopy)1446 SISLPoint *newPoint (double *ecoef, int idim, int icopy)
1447 #else
1448 SISLPoint *
1449 newPoint (ecoef, idim, icopy)
1450      double *ecoef;
1451      int idim;
1452      int icopy;
1453 #endif
1454 /*
1455 *********************************************************************
1456 *
1457 *********************************************************************
1458 *
1459 * PURPOSE    : Create and initialize a Point-instance.
1460 *
1461 *
1462 *
1463 * INPUT      : ecoef  - Coordinates of point.
1464 *              idim   - Dimension of the space in which the point lies.
1465 *              icopy  - Flag
1466 *                       = 0 : Set pointer to input array.
1467 *                       = 1 : Copy input arrays.
1468 *                       = 2 : Set pointer and remember to free array.
1469 *
1470 *
1471 *
1472 * OUTPUT     : newPoint - Pointer to new point. If there is impossible
1473 *                         to allocate space for the point, newPoint
1474 *                         returns zero.
1475 *
1476 *
1477 * METHOD     :
1478 *
1479 *
1480 * REFERENCES :
1481 *
1482 *-
1483 * CALLS      :
1484 *
1485 * WRITTEN BY : UJK, SI. 89-04.
1486 *
1487 *********************************************************************
1488 */
1489 {
1490   SISLPoint *qnew;		/* Local pointer to new point.  */
1491   double *scoef = SISL_NULL;		/* Copy of coordinates          */
1492 
1493 
1494   /* Allocate space for point.  */
1495 
1496   if ((qnew = newarray (1, SISLPoint)) == SISL_NULL)
1497     goto err101;
1498 
1499 
1500   if (icopy == 1)
1501     {
1502 
1503       /* Copy input array. First allocate space for new array. */
1504 
1505       if (idim < 4) 	scoef = qnew->ec;
1506       else if ((scoef = newarray (idim, double)) == SISL_NULL) goto err101;
1507 
1508       /* Copy contents of arrays.  */
1509 
1510       memcopy (scoef, ecoef, idim, double);
1511     }
1512   else
1513     {
1514       scoef = ecoef;
1515     }
1516 
1517   /* Initialize new point.  */
1518 
1519   qnew->idim = idim;
1520   qnew->icopy = icopy;
1521   qnew->ecoef = scoef;
1522   qnew->pbox = SISL_NULL;
1523 
1524   /* Task done. */
1525 
1526   goto out;
1527 
1528   /* Error in space allocation. Return zero. */
1529 
1530 err101:if (qnew != SISL_NULL)
1531     freearray (qnew);
1532   qnew = SISL_NULL;
1533   goto out;
1534 out:return qnew;
1535 }
1536 
1537 #if defined(SISLNEEDPROTOTYPES)
newPtedge(SISLIntpt * ppt)1538 SISLPtedge *newPtedge (SISLIntpt * ppt)
1539 #else
1540 SISLPtedge *
1541 newPtedge (ppt)
1542      SISLIntpt *ppt;
1543 #endif
1544 /*
1545 *********************************************************************
1546 *
1547 *********************************************************************
1548 *
1549 * PURPOSE    : Create and initialize an instance of the structure
1550 *              Ptedge, that contains elements in a list where each
1551 *              element has a pointer to an intersection point.
1552 *
1553 *
1554 *
1555 * INPUT      : ppt    - The intersection point at which this instance
1556 *                       point.
1557 *
1558 *
1559 *
1560 * OUTPUT     : newPtedge - Pointer to the crated instance.
1561 *
1562 *
1563 * METHOD     :
1564 *
1565 *
1566 * REFERENCES :
1567 *
1568 *-
1569 * CALLS      :
1570 *
1571 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
1572 *
1573 *********************************************************************
1574 */
1575 {
1576   SISLPtedge *pnew;		/* Local pointer to the instance to create. */
1577 
1578   /* Allocate space for the instance. */
1579 
1580   pnew = newarray (1, SISLPtedge);
1581   if (pnew == SISL_NULL)
1582     goto err101;
1583 
1584   /* Initialize instance.  */
1585 
1586   pnew->ppt = ppt;
1587   pnew->pnext = SISL_NULL;
1588 
1589   /* Task done.  */
1590 
1591   goto out;
1592 
1593   /* Error in space allocation. Return zero. */
1594 
1595 err101:pnew = SISL_NULL;
1596   goto out;
1597 
1598 out:return (pnew);
1599 }
1600 
1601 #if defined(SISLNEEDPROTOTYPES)
1602 SISLSurf *
newSurf(int in1,int in2,int ik1,int ik2,double * et1,double * et2,double * ecoef,int ikind,int idim,int icopy)1603 newSurf (int in1, int in2, int ik1, int ik2, double *et1, double *et2,
1604 	 double *ecoef, int ikind, int idim, int icopy)
1605 #else
1606 SISLSurf *
1607 newSurf (in1, in2, ik1, ik2, et1, et2, ecoef, ikind, idim, icopy)
1608      int in1;
1609      int in2;
1610      int ik1;
1611      int ik2;
1612      double *et1;
1613      double *et2;
1614      double *ecoef;
1615      int ikind;
1616      int idim;
1617      int icopy;
1618 #endif
1619 /*
1620 *********************************************************************
1621 *
1622 *********************************************************************
1623 *
1624 * PURPOSE    : Create and initialize a surface (instance of SISLSurf).
1625 *
1626 *
1627 *
1628 * INPUT      : in1    - Number of vertices in first parameter direction
1629 *                       of new surface.
1630 *            : in2    - Number of vertices in second parameter direction
1631 *                       of new surface.
1632 *              ik1    - Order of surface in first parameter direction.
1633 *              ik2    - Order of surface in second parameter direction.
1634 *              et1    - Knotvector of surface in first parameter direction.
1635 *              et2    - Knotvector of surface in second parameter direction.
1636 *              ecoef  - Vertices of surface.
1637 *              ikind  - Kind of surface
1638 *                        = 1 : Polynomial B-spline surface.
1639 *                        = 2 : Rational B-spline surface.
1640 *                        = 3 : Polynomial Bezier surface.
1641 *                        = 4 : Rational Bezier surface.
1642 *              idim   - Dimension of the space in which the surface lies.
1643 *              icopy  - Flag
1644 *                       = 0 : Set pointer to input arrays.
1645 *                       = 1 : Copy input arrays.
1646 *                       = 2 : Set pointer and mark to free.
1647 *
1648 *
1649 *
1650 * OUTPUT     : newSurf  - Pointer to new surface. If there is impossible
1651 *                         to allocate space for the surface, newSurf
1652 *                         returns zero.
1653 *
1654 *
1655 * METHOD     :
1656 *              If surface is rational,
1657 *              points input in ecoef should have the form (w*P1,...,w*Pidim,w)
1658 *              The new surface will then have two arrays:
1659 *              qnew -> ecoef with points of the form (P1,...,Pidim)
1660 *              qnew -> rcoef with points of the form (w*P1,...w*Pidim,w).
1661 *
1662 *
1663 * REFERENCES :
1664 *
1665 *-
1666 * CALLS      :
1667 *
1668 * WRITTEN BY : Vibeke Skytt, SI, 88-05.
1669 * MODIFIED BY : Mike Floater, SI, 91-01 for rational surfaces.
1670 *
1671 *********************************************************************
1672 */
1673 {
1674   SISLSurf *qnew;		/* Local pointer to new surface.       */
1675   int i, j, J, jj, k;		/* loop variables                      */
1676   int k1, k2;                   /* Superfluous knots at the ends.      */
1677   int kdim;			/* Dimension indicator.                */
1678   double *st1 = SISL_NULL, *st2 = SISL_NULL;	/* Copy of knotvectors.        */
1679   double *rcoef = SISL_NULL;		/* Copy of vertices in rational case.  */
1680   double *scoef = SISL_NULL;		/* Copy of vertices.                   */
1681   double *ucoef = SISL_NULL;         /* Utility coefficient array.          */
1682 
1683   /* Allocate space for surface.  */
1684 
1685   if ((qnew = newarray (1, SISLSurf)) == SISL_NULL)
1686     goto err101;
1687 
1688   if (ikind == 2 || ikind == 4)
1689     kdim = idim + 1;
1690   else
1691     kdim = idim;
1692 
1693   /* Count superfluous knots at ends, first in u parameter directions. */
1694 
1695   if (ik1 == 0)
1696   {
1697     k1 = k2 = 0;
1698   }
1699   else
1700   {
1701     /* Count superfluous knots in the start. */
1702 
1703     for (k1 = 0; k1 < in1; k1++)
1704       if (et1[ik1 - 1] < et1[ik1 + k1]) break;
1705 
1706     /* Count superfluous knots in the end. */
1707 
1708     for (k2 = 0; k2 < in1; k2++)
1709       if (et1[in1] > et1[in1 - 1 - k2]) break;
1710   }
1711 
1712   /* Reduce knots and vertices according to k1 and k2. */
1713 
1714   if (k1 > 0 || k2 > 0)
1715   {
1716      ucoef = newarray(in1*in2*kdim, DOUBLE);
1717      s6chpar(ecoef, in1, in2, kdim, ucoef);
1718   }
1719   if (k1 > 0)
1720   {
1721      memcopy(ucoef, ucoef + k1*in2*kdim, (in1 - k1)*in2*kdim, DOUBLE);
1722      memcopy(et1, et1 + k1, in1 + ik1 - k1, DOUBLE);
1723   }
1724   in1 -= (k1 + k2);
1725   if (k1 > 0 || k2 > 0)
1726   {
1727      s6chpar(ucoef, in2, in1, kdim, ecoef);
1728      if (ucoef != SISL_NULL) freearray(ucoef);
1729   }
1730 
1731   /* Count superfluous knots at ends in v parameter directions. */
1732 
1733   if (ik2 == 0)
1734   {
1735     k1 = k2 = 0;
1736   }
1737   else
1738   {
1739     /* Count superfluous knots in the start. */
1740 
1741     for (k1 = 0; k1 < in2; k1++)
1742      if (et2[ik2 - 1] < et2[ik2 + k1]) break;
1743 
1744     /* Count superfluous knots in the end. */
1745 
1746     for (k2 = 0; k2 < in2; k2++)
1747       if (et2[in2] > et2[in2 - 1 - k2]) break;
1748   }
1749   /* Reduce knots and vertices according to k1 and k2. */
1750 
1751   if (k1 > 0)
1752   {
1753      memcopy(ecoef, ecoef + k1*in1*kdim, (in2 - k1)*in1*kdim, DOUBLE);
1754      memcopy(et2, et2 + k1, in2 + ik2 - k1, DOUBLE);
1755   }
1756   in2 -= (k1 + k2);
1757 
1758   if (icopy == 1)
1759     {
1760 
1761       /* Copy input arrays. First allocate space for new arrays. */
1762 
1763       st1 = newarray (in1 + ik1, DOUBLE);
1764       st2 = newarray (in2 + ik2, DOUBLE);
1765       scoef = newarray (in1 * in2 * kdim, DOUBLE);
1766       if (st1 == SISL_NULL || st2 == SISL_NULL || scoef == SISL_NULL)
1767 	goto err101;
1768 
1769       /* Copy contents of arrays.  */
1770       memcopy (st1, et1, in1 + ik1, double);
1771       memcopy (st2, et2, in2 + ik2, double);
1772       memcopy (scoef, ecoef, in1 * in2 * kdim, double);
1773     }
1774   else
1775     {
1776       st1 = et1;
1777       st2 = et2;
1778       scoef = ecoef;
1779     }
1780 
1781   /* Initialize new surface. */
1782 
1783   qnew->in1 = in1;
1784   qnew->in2 = in2;
1785   qnew->ik1 = ik1;
1786   qnew->ik2 = ik2;
1787   qnew->ikind = ikind;
1788   qnew->idim = idim;
1789   qnew->icopy = icopy;
1790   qnew->et1 = st1;
1791   qnew->et2 = st2;
1792   qnew->pdir = SISL_NULL;
1793   qnew->pbox = SISL_NULL;
1794   qnew->seg1 = SISL_NULL;
1795   qnew->seg2 = SISL_NULL;
1796   qnew->sf_type = NO_SURFACE_TYPE;
1797 
1798   if (ikind == 2 || ikind == 4)
1799     {
1800       /* Calculate the weighted control points if the object is rational  */
1801       rcoef = newarray (in1 * in2 * idim, DOUBLE);
1802       if (rcoef == SISL_NULL)
1803 	goto err101;
1804       for (i = 0, j = 0, J = 0, k = idim; i < in1 * in2; i++, k += kdim)
1805 	{
1806 	  for (jj = 0; jj < idim; jj++, j++, J++)
1807 	    {
1808 	      rcoef[J] = scoef[j] / scoef[k];
1809 	    }
1810 	  j++;
1811 	}
1812       qnew->ecoef = rcoef;
1813       qnew->rcoef = scoef;
1814     }
1815   else
1816     {
1817       qnew->ecoef = scoef;
1818       qnew->rcoef = SISL_NULL;
1819     }
1820 
1821   /* UJK, 92.05.05 Default value must be set for cuopen */
1822   qnew->cuopen_1 = SISL_SURF_OPEN;
1823   qnew->cuopen_2 = SISL_SURF_OPEN;
1824 
1825   /* Segmentation and type information not set   */
1826   qnew->seg1 = NULL;
1827   qnew->seg2 = NULL;
1828   qnew->sf_type = NO_SURFACE_TYPE;
1829 
1830   /* Task done. */
1831 
1832   goto out;
1833 
1834   /* Error in space allocation. Return zero. */
1835 
1836 err101:if (qnew != SISL_NULL)
1837     freearray (qnew);
1838   /* if (st1 != SISL_NULL) */
1839   /*   freearray (st1); */
1840   /* if (st2 != SISL_NULL) */
1841   /*   freearray (st2); */
1842   /* if (rcoef != SISL_NULL) */
1843   /*   freearray (rcoef); */
1844   /* if (scoef != SISL_NULL) */
1845   /*   freearray (scoef); */
1846   goto out;
1847 
1848 out:return (qnew);
1849 }
1850 
1851 #if defined(SISLNEEDPROTOTYPES)
copyCurve(SISLCurve * pcurve)1852 SISLCurve *copyCurve (SISLCurve * pcurve)
1853 #else
1854 SISLCurve *
1855 copyCurve (pcurve)
1856      SISLCurve *pcurve;
1857 #endif
1858 /*
1859 *********************************************************************
1860 *
1861 *********************************************************************
1862 *
1863 * PURPOSE    : Make a copy of a SISLCurve.
1864 *
1865 *
1866 *
1867 * INPUT      : pcurve  -  Curve to be copied.
1868 *
1869 *
1870 *
1871 * OUTPUT     : copyCurve - The new curve.
1872 *
1873 *
1874 * METHOD     :
1875 *
1876 *
1877 * REFERENCES :
1878 *
1879 *-
1880 * CALLS      : newCurve - Make new SISLCurve.
1881 *
1882 * WRITTEN BY : Vibeke Skytt, SI, 93-11.
1883 *
1884 *********************************************************************
1885 */
1886 {
1887   int kstat = 0;
1888   SISLCurve *qc = SISL_NULL;
1889   int knum;
1890   int ki;
1891 
1892   /* Make new curve. */
1893 
1894   if (pcurve->ikind == 2 || pcurve->ikind == 4)
1895   {
1896      if ((qc = newCurve(pcurve->in, pcurve->ik, pcurve->et, pcurve->rcoef,
1897 			pcurve->ikind, pcurve->idim, 1)) == SISL_NULL) goto err101;
1898   }
1899   else
1900   {
1901      if ((qc = newCurve(pcurve->in, pcurve->ik, pcurve->et, pcurve->ecoef,
1902 			pcurve->ikind, pcurve->idim, 1)) == SISL_NULL) goto err101;
1903   }
1904 
1905   /* Set the open/closed flag. */
1906 
1907   qc->cuopen = pcurve->cuopen;
1908 
1909   /* Copy box and  cone information. */
1910 
1911   if (pcurve->pbox != SISL_NULL)
1912   {
1913      /* Copy box information. */
1914 
1915      if ((qc->pbox = newbox(pcurve->idim)) == SISL_NULL)
1916      {
1917 	freeCurve(qc);
1918 	qc = SISL_NULL;
1919 	goto err101;
1920      }
1921      if (pcurve->idim == 3) knum = 9;
1922      else if (pcurve->idim == 2) knum = 4;
1923      else knum = pcurve->idim;
1924 
1925      memcopy(qc->pbox->emin, pcurve->pbox->emin, knum, DOUBLE);
1926      memcopy(qc->pbox->emax, pcurve->pbox->emax, knum, DOUBLE);
1927      memcopy(qc->pbox->etol, pcurve->pbox->etol, 3, DOUBLE);
1928 
1929      for (ki=0; ki<3; ki++)
1930      {
1931 	if (s6existbox(pcurve->pbox, ki, pcurve->pbox->etol[ki]))
1932 	{
1933 	   s6newbox(qc->pbox, knum, ki, pcurve->pbox->etol[ki], &kstat);
1934 	   if (kstat < 0)
1935 	   {
1936 	      freeCurve(qc);
1937 	      qc = SISL_NULL;
1938 	      goto err101;
1939 	   }
1940 	   memcopy(qc->pbox->e2min[ki], pcurve->pbox->e2min[ki], knum,
1941 		   DOUBLE);
1942 	   memcopy(qc->pbox->e2max[ki], pcurve->pbox->e2max[ki], knum,
1943 		   DOUBLE);
1944 	}
1945      }
1946   }
1947 
1948   if (pcurve->pdir != SISL_NULL)
1949   {
1950      /* Copy cone information. */
1951 
1952      if ((qc->pdir = newdir(pcurve->idim)) == SISL_NULL)
1953      {
1954 	freeCurve(qc);
1955 	qc = SISL_NULL;
1956 	goto err101;
1957      }
1958      qc->pdir->igtpi = pcurve->pdir->igtpi;
1959      qc->pdir->aang = pcurve->pdir->aang;
1960      memcopy(qc->pdir->ecoef, pcurve->pdir->ecoef, pcurve->idim, DOUBLE);
1961 
1962      if (pcurve->pdir->esmooth != SISL_NULL)
1963      {
1964 	if ((qc->pdir->esmooth = newarray(qc->in*qc->idim,DOUBLE)) == SISL_NULL)
1965 	{
1966 	   freeCurve(qc);
1967 	   qc = SISL_NULL;
1968 	   goto err101;
1969 	}
1970 	memcopy(qc->pdir->esmooth, pcurve->pdir->esmooth, qc->in*qc->idim,
1971 		DOUBLE);
1972      }
1973   }
1974 
1975   goto out;
1976 
1977   /* Error in allocation. */
1978 
1979   err101 :
1980      goto out;
1981 
1982   out :
1983      return qc;
1984 }
1985 
1986 #if defined(SISLNEEDPROTOTYPES)
copySurface(SISLSurf * psurf)1987 SISLSurf *copySurface (SISLSurf * psurf)
1988 #else
1989 SISLSurf *
1990 copySurface (psurf)
1991      SISLSurf *psurf;
1992 #endif
1993 /*
1994 *********************************************************************
1995 *
1996 *********************************************************************
1997 *
1998 * PURPOSE    : Make a copy of a SISLSurface.
1999 *
2000 *
2001 *
2002 * INPUT      : psurf  -  Surface to be copied.
2003 *
2004 *
2005 *
2006 * OUTPUT     : copySurface - The new curve.
2007 *
2008 *
2009 * METHOD     :
2010 *
2011 *
2012 * REFERENCES :
2013 *
2014 *-
2015 * CALLS      : newSurf - Make new SISLSurface.
2016 *
2017 * WRITTEN BY : Vibeke Skytt, SI, 93-11.
2018 *
2019 *********************************************************************
2020 */
2021 {
2022   int kstat = 0;
2023   SISLSurf *qs = SISL_NULL;
2024   int knum;
2025   int ki;
2026 
2027   /* Make new curve. */
2028 
2029   if (psurf->ikind == 2 || psurf->ikind == 4)
2030   {
2031      if ((qs = newSurf(psurf->in1, psurf->in2, psurf->ik1, psurf->ik2,
2032 		       psurf->et1, psurf->et2, psurf->rcoef,
2033 		       psurf->ikind, psurf->idim, 1)) == SISL_NULL) goto err101;
2034   }
2035   else
2036   {
2037      if ((qs = newSurf(psurf->in1, psurf->in2, psurf->ik1, psurf->ik2,
2038 		       psurf->et1, psurf->et2, psurf->ecoef,
2039 		       psurf->ikind, psurf->idim, 1)) == SISL_NULL) goto err101;
2040   }
2041 
2042   /* Set the open/closed flag. */
2043 
2044   qs->cuopen_1 = psurf->cuopen_1;
2045   qs->cuopen_2 = psurf->cuopen_2;
2046 
2047   /* Copy box and  cone information. */
2048 
2049   if (psurf->pbox != SISL_NULL)
2050   {
2051      /* Copy box information. */
2052 
2053      if ((qs->pbox = newbox(psurf->idim)) == SISL_NULL)
2054      {
2055 	freeSurf(qs);
2056 	qs = SISL_NULL;
2057 	goto err101;
2058      }
2059      if (psurf->idim == 3) knum = 9;
2060      else if (psurf->idim == 2) knum = 4;
2061      else knum = psurf->idim;
2062 
2063      memcopy(qs->pbox->emin, psurf->pbox->emin, knum, DOUBLE);
2064      memcopy(qs->pbox->emax, psurf->pbox->emax, knum, DOUBLE);
2065      memcopy(qs->pbox->etol, psurf->pbox->etol, 3, DOUBLE);
2066 
2067      for (ki=0; ki<3; ki++)
2068      {
2069 	if (s6existbox(psurf->pbox, ki, psurf->pbox->etol[ki]))
2070 	{
2071 	   s6newbox(qs->pbox, knum, ki, psurf->pbox->etol[ki], &kstat);
2072 	   if (kstat < 0)
2073 	   {
2074 	      freeSurf(qs);
2075 	      qs = SISL_NULL;
2076 	      goto err101;
2077 	   }
2078 	   memcopy(qs->pbox->e2min[ki], psurf->pbox->e2min[ki], knum,
2079 		   DOUBLE);
2080 	   memcopy(qs->pbox->e2max[ki], psurf->pbox->e2max[ki], knum,
2081 		   DOUBLE);
2082 	}
2083      }
2084   }
2085 
2086   if (psurf->pdir != SISL_NULL)
2087   {
2088      /* Copy cone information. */
2089 
2090      if ((qs->pdir = newdir(psurf->idim)) == SISL_NULL)
2091      {
2092 	freeSurf(qs);
2093 	qs = SISL_NULL;
2094 	goto err101;
2095      }
2096      qs->pdir->igtpi = psurf->pdir->igtpi;
2097      qs->pdir->aang = psurf->pdir->aang;
2098      memcopy(qs->pdir->ecoef, psurf->pdir->ecoef, psurf->idim, DOUBLE);
2099 
2100      if (psurf->pdir->esmooth != SISL_NULL)
2101      {
2102 	if ((qs->pdir->esmooth = newarray(qs->in1*qs->in2*qs->idim,DOUBLE))
2103 	    == SISL_NULL)
2104 	{
2105 	   freeSurf(qs);
2106 	   qs = SISL_NULL;
2107 	   goto err101;
2108 	}
2109 	memcopy(qs->pdir->esmooth, psurf->pdir->esmooth,
2110 		qs->in1*qs->in2*qs->idim, DOUBLE);
2111      }
2112   }
2113 
2114   if (psurf->seg1 != NULL)
2115     {
2116     }
2117   if (psurf->seg2 != NULL)
2118     {
2119     }
2120   qs->sf_type = psurf->sf_type;
2121 
2122   goto out;
2123 
2124   /* Error in allocation. */
2125 
2126   err101 :
2127      goto out;
2128 
2129   out :
2130      return qs;
2131 }
2132 
2133 
2134 #if defined(SISLNEEDPROTOTYPES)
2135 SISLSegmentation*
newSegmentation(double * segmentation,int * type,int nseg)2136 newSegmentation(double *segmentation, int *type, int nseg)
2137 #else
2138 SISLSegmentation *
2139 newSegmentation(segmentation, type, nseg)
2140 double *segmentation;
2141 int type;
2142 int nseg;
2143 #endif
2144 /*
2145 *********************************************************************
2146 *
2147 *********************************************************************
2148 *
2149 * PURPOSE    : Create and initialize a segmentation array for use in
2150 *              intersection problems. Each segmentation value has
2151 *              a corresponding type.
2152 *
2153 *
2154 *
2155 * INPUT      :
2156 *
2157 *
2158 *
2159 * OUTPUT     : newSegmentation - Pointer to resulting structure
2160 *
2161 *
2162 * METHOD     :
2163 *
2164 *
2165 * REFERENCES :
2166 *
2167 *-
2168 * CALLS      :
2169 *
2170 * WRITTEN BY : Vibeke Skytt, SINTEF, 2018-02
2171 *
2172 *********************************************************************
2173 */
2174 {
2175   SISLSegmentation *qseg = SISL_NULL;
2176   qseg = newarray(1, SISLSegmentation);
2177 
2178   if (qseg != NULL)
2179     {
2180       qseg->seg_val = newarray(nseg, DOUBLE);
2181       qseg->seg_type = newarray(nseg, INT);  /* SEGMENTATION_TYPE */
2182 
2183       if (qseg->seg_val == NULL || qseg->seg_type == NULL)
2184 	{
2185 	  if (qseg->seg_val != NULL) freearray(qseg->seg_val);
2186 	  if (qseg->seg_type != NULL) freearray(qseg->seg_type);
2187 	  freearray(qseg);
2188 	  qseg = NULL;
2189 	}
2190       else
2191 	{
2192 	  memcopy(qseg->seg_val, segmentation, nseg, DOUBLE);
2193 	  memcopy(qseg->seg_type, type, nseg, INT);
2194 	  qseg->num_seg = nseg;
2195 	}
2196     }
2197   return qseg;
2198 }
2199 
2200