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: sh6idnwun.c,v 1.2 2001-03-19 15:59:08 afr Exp $
45  *
46  */
47 
48 
49 #define SH6IDNEWUNITE
50 
51 #include "sislP.h"
52 
53 
54 #if defined(SISLNEEDPROTOTYPES)
55 void
sh6idnewunite(SISLObject * po1,SISLObject * po2,SISLIntdat ** intdat,SISLIntpt ** pt1,SISLIntpt ** pt2,double weight,double aepsge,int * jstat)56 sh6idnewunite (SISLObject *po1, SISLObject *po2, SISLIntdat ** intdat,
57 	       SISLIntpt ** pt1, SISLIntpt ** pt2, double weight,
58 	       double aepsge, int *jstat)
59 #else
60 void
61 sh6idnewunite (po1, po2, intdat, pt1, pt2, weight, aepsge, jstat)
62      SISLObject *po1;
63      SISLObject *po2;
64      SISLIntdat **intdat;
65      SISLIntpt **pt1;
66      SISLIntpt **pt2;
67      double weight;
68      double aepsge;
69      int *jstat;
70 #endif
71 /*
72 *********************************************************************
73 *
74 *********************************************************************
75 *
76 * PURPOSE    : Given two Intpt, unite them to one by finding the
77 *              weighted medium in the parameter values corresponding
78 *              to one object, and iterate to the closest point in
79 *              the other. If one of the objects is a point, no
80 *              iteration is necessary.
81 *
82 *
83 * INPUT      : po1      - First object in the intersection.
84 *              po2      - Second object in the intersection.
85 *              intdat	- Pointer to intersection data.
86 *	       pt1	- Pointer to the first Intpt.
87 *	       pt2	- Pointer to the second Intpt.
88 *	       weight	- Weight to middle parameter values. ((1-W)*p1+W*p2).
89 *              aepsge   - Geometry tolerance.
90 *
91 *
92 * OUTPUT     : pt1   	- Pointer to joined Intpt.
93 *	       jstat   	- Status value
94 *
95 *
96 * METHOD     :
97 *
98 * CALLS      : sh6ptobj - Iterate to closest point in second object.
99 *              s1221    - Curve evaluation.
100 *              s1421    - Surface evaluation.
101 *
102 *
103 * REFERENCES :
104 *
105 * WRITTEN BY : Arne Laksaa, SI, Oslo, Norway. May 91.
106 * CORRECTED BY: UJK, SI, Oslo, Norway. October 91.
107 * RENAMED AND MODIFIED BY : Vibeke Skytt, SI, 92-11. Iterate in second
108 *                                                    object.
109 *********************************************************************
110 */
111 {
112    int ki, kstat;
113    int kpar;           /* Number of parameter directions in 1. object. */
114    int kiterate;       /* Indicates if iteration is necessary.    */
115    int kleft1=0,kleft2=0; /* Parameters used in evaluation.       */
116    double spar[4];     /* Parameter values of intersection point. */
117    double start[2];    /* Start parameter value to iteration.     */
118    double spoint[3];   /* Position in curve or surface.           */
119    double snorm[3];    /* Dummy vector. Surface normal.           */
120    SISLIntpt *lpt;
121    SISLIntpt *lpt1;
122    SISLIntpt *lpt2;
123 
124    /* Test if one object is a point.  */
125 
126    if (po1->iobj == SISLPOINT || po2->iobj == SISLPOINT)
127    {
128       kpar = po1->iobj + po2->iobj;
129       kiterate = 0;
130    }
131    else
132    {
133       kpar = po1->iobj;
134       kiterate = 1;
135    }
136 
137   sh6idnpt (intdat, pt1, 0, &kstat);
138   if (kstat < 0)
139     goto error;
140   sh6idnpt (intdat, pt2, 0, &kstat);
141   if (kstat < 0)
142     goto error;
143 
144   if (sh6ismain (*pt1))
145     {
146       lpt1 = (*pt1);
147       lpt2 = (*pt2);
148     }
149   else
150     {
151       lpt1 = (*pt2);
152       lpt2 = (*pt1);
153       weight = 1.0 - weight;
154     }
155 
156   sh6disconnect (lpt1, lpt2, &kstat);
157   if (kstat < 0)
158     goto error;
159 
160   /* UJK, Oct. 91 */
161   /* for (ki=0;;ki++) */
162   for (ki = 0;;)
163     {
164       if ((lpt = sh6getnext (lpt2, ki)) == SISL_NULL)
165 	break;
166 
167       sh6disconnect (lpt2, lpt, &kstat);
168       if (kstat < 0)
169 	goto error;
170 
171 
172       sh6connect (lpt1, lpt, &kstat);
173       if (kstat < 0)
174 	goto error;
175     }
176 
177   for (ki = 0; ki < kpar; ki++)
178     spar[ki] = lpt1->epar[ki] * (1.0 - weight) + lpt2->epar[ki] * weight;
179 
180   if (kiterate)
181   {
182      /* Compute start parameter to iteration.  */
183 
184      for (; ki < lpt1->ipar; ki++)
185 	start[ki-kpar] = lpt1->epar[ki] * (1.0 - weight) + lpt2->epar[ki] * weight;
186 
187      /* Iterate to closest point in second object. First evaluate
188 	value of intersection point in first object.  */
189 
190      if (po1->iobj == SISLCURVE)
191      {
192 	s1221(po1->c1,0,spar[0],&kleft1,spoint,&kstat);
193 	if (kstat < 0) goto error;
194      }
195      else
196      {
197 	s1421(po1->s1,0,spar,&kleft1,&kleft2,spoint,snorm,&kstat);
198 	if (kstat < 0) goto error;
199      }
200 
201      /* Iterate. */
202 
203      sh6ptobj(spoint,po2,aepsge,start,spar+kpar,&kstat);
204      if (kstat < 0) goto error;
205   }
206 
207   /* Copy new parameter values into intersection point. */
208 
209   memcopy(lpt1->epar,spar,lpt1->ipar,DOUBLE);
210 
211 
212   sh6idkpt (intdat, &lpt2, 0, &kstat);
213   if (kstat < 0)
214     goto error;
215 
216   (*pt1) = lpt1;
217   (*pt2) = lpt2;
218 
219   goto out;
220 
221 error:
222   *jstat = kstat;
223   s6err ("sh6idunite", kstat, 0);
224   goto out;
225 out:
226   ;
227 }
228 
229