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: sh1787.c,v 1.4 2005-02-28 09:04:50 afr Exp $
45  *
46  */
47 
48 
49 #define SH1787
50 
51 #include "sislP.h"
52 
53 
54 
55 #if defined(SISLNEEDPROTOTYPES)
56 void
sh1787(SISLObject * po1,SISLObject * po2,double aepsge,SISLIntdat ** rintdat,SISLIntpt * pintpt,int * jnewpt,int * jstat)57     sh1787 (SISLObject * po1, SISLObject * po2, double aepsge,
58 	SISLIntdat ** rintdat, SISLIntpt * pintpt, int *jnewpt,
59 	int *jstat)
60 #else
61 void
62    sh1787 (po1, po2, aepsge, rintdat, pintpt, jnewpt, jstat)
63      SISLObject *po1;
64      SISLObject *po2;
65      double aepsge;
66      SISLIntdat **rintdat;
67      SISLIntpt *pintpt;
68      int *jnewpt;
69      int *jstat;
70 #endif
71 /*
72 ******************************************************************
73 *
74 *********************************************************************
75 *
76 * PURPOSE    : Set pre-topology data in n-dimensional surface-point
77 *              intersection.
78 *
79 *
80 * INPUT      : po1      - Pointer to the first object in the intersection.
81 *              po2      - Pointer to the second object in the intersection.
82 *              aepsge   - Geometry resolution.
83 *              rintdat  - Intersection data structure.
84 *              pintpt   - Current intersection point.
85 *
86 *
87 * OUTPUT     : pintpt   - Intersection point after updating pre-topology.
88 *              jnewpt   - Number of new int.pt. created.
89 *              jstat    - status messages
90 *                                > 0   : Warning.
91 *                                = 0   : Ok.
92 *                                < 0   : Error.
93 *
94 *
95 * METHOD     :
96 *
97 * CALLS      : shevalc  -  Evaluate surface using filtered coefficients.
98 *              s6ang    -  Angle between two vectors.
99 *              s6idcon  -  Connect two intersection points.
100 *              hp_newIntpt -  Create new intersection point.
101 *
102 * REFERENCES :
103 *
104 * WRITTEN BY : Michael Floater, SI, Oslo, Norway. 09.91.
105 *********************************************************************
106 */
107 {
108   int kstat = 0;		/* Status variable.                        */
109   int kdim;			/* Dimension of geometry space.              */
110   int kn1;			/* Nmb vertices of surface in 1st direc.     */
111   int kn2;			/* Nmb vertices of surface in 1st direc.     */
112   int kk1;			/* Order of surface in 1st direction.        */
113   int kk2;			/* Order of surface in 1st direction.        */
114   int kpos = 0;			/* Current position in int.pt. array.        */
115   int lleft[2];			/* Array storing pre-topology information.   */
116   int lright[2];		/* Array storing pre-topology information.   */
117   int *ll1, *ll2, *lr1, *lr2;	/* Pointers into pre-topology arrays.        */
118   double tpoint[3];		/* Value of point to intersect.              */
119   double sder[21];		/* Result of surface evaluation.             */
120   double *st1;			/* First knot vector of surface.             */
121   double *st2;			/* Second knot vector of surface.            */
122   double tref1;			/* Referance value in equality test.         */
123   double tref2;			/* Referance value in equality test.         */
124   SISLSurf *qs;		        /* Pointer to current surface.               */
125   double *ret_val;		/* Pointer to geo data from sh6getgeom       */
126   double *ret_norm;		/* Pointer to geo data from sh6getgeom       */
127   int i;                        /* Loop variable.                            */
128   double cross;                 /* utang x vtang.                            */
129   double in_out[2];             /* To be used in touchy situations           */
130   /* ----------------------------------------------------------------------  */
131 
132   /* Don't make pretop for help points ! */
133   /* Oh, yes ?, 2D is some nice case ! */
134   /* if (sh6ishelp (pintpt))
135      {
136      *jstat = 0;
137      goto out;
138      }
139      */
140 
141   /* Set pointers into the arrays storing pre-topology information. */
142   if (po1->iobj == SISLSURFACE)
143     {
144       ll1 = lleft;
145       lr1 = lright;
146       ll2 = lleft + 1;
147       lr2 = lright + 1;
148     }
149   else
150     {
151       ll1 = lleft + 1;
152       lr1 = lright + 1;
153       ll2 = lleft;
154       lr2 = lright;
155     }
156 
157   /* Get pre-topology information. */
158   sh6gettop (pintpt, -1, lleft, lright, lleft + 1, lright + 1, &kstat);
159   if (kstat < 0)
160     goto error;
161 
162   /* Test dimension of geometry space. */
163   if (po1->iobj == SISLSURFACE)
164       qs = po1->s1;
165   else
166       qs = po2->s1;
167 
168   kdim = qs->idim;
169   if (kdim != 2)
170     goto err106;
171 
172   /* Store surface information in local parameters. */
173 
174   kn1 = qs->in1;
175   kn2 = qs->in2;
176   kk1 = qs->ik1;
177   kk2 = qs->ik2;
178   st1 = qs->et1;
179   st2 = qs->et2;
180   tref1 = st1[kn1] - st1[kk1 - 1];
181   tref2 = st2[kn2] - st2[kk2 - 1];
182 
183   /* Fetch geometry information, point.  */
184   sh6getgeom ((po1->iobj == SISLPOINT) ? po1 : po2,
185 	      (po1->iobj == SISLPOINT) ? 1 : 2,
186 	      pintpt, &ret_val, &ret_norm, aepsge, &kstat);
187   if (kstat < 0)
188     goto error;
189 
190   for(i=0; i<kdim; i++)
191       tpoint[i]=ret_val[i];
192 
193 
194   /* Fetch geometry information, surface.  */
195   sh6getgeom ((po1->iobj == SISLSURFACE) ? po1 : po2,
196 	      (po1->iobj == SISLSURFACE) ? 1 : 2,
197 	      pintpt, &ret_val, &ret_norm, aepsge, &kstat);
198   if (kstat < 0)
199     goto error;
200 
201   for(i=0; i<kdim*3; i++)
202        sder[i]=ret_val[i];
203 
204 /* Set normal vector from the 2D tangent vectors. */
205 
206   cross = sder[kdim]*sder[2*kdim+1] + sder[kdim+1]*sder[2*kdim];
207 
208   /*  Could improve this test. */
209   if (fabs(cross) > ANGULAR_TOLERANCE)
210     {
211       /* Compute pre-topology using local information.  */
212 
213       if (cross > 0)
214 	{
215 	  *ll1 = SI_UNDEF;
216 	  *lr1 = SI_UNDEF;
217 	  *ll2 = SI_IN;
218 	  *lr2 = SI_OUT;
219 	}
220       else
221 	{
222 	  *ll1 = SI_UNDEF;
223 	  *lr1 = SI_UNDEF;
224 	  *ll2 = SI_OUT;
225 	  *lr2 = SI_IN;
226 	}
227 
228     }
229   else if (qs->pdir && qs->pdir->ecoef &&
230 	   (DNEQUAL(qs->pdir->ecoef[0],DZERO) ||
231 	    DNEQUAL(qs->pdir->ecoef[1],DZERO)))
232     {
233        /* March to find help points.
234 	   Not implemented yet. */
235        /* UJK, I'm not sure, but something like this should work :
236 	  Remeber we are in a simple case situation !
237 	  */
238        in_out[0] =  (double)1.0;
239        in_out[1] = -(double)1.0;
240 
241        if (s6scpr(qs->pdir->ecoef,in_out,kdim) > 0)
242 	  {
243 	     *ll1 = SI_UNDEF;
244 	     *lr1 = SI_UNDEF;
245 	     if (*ll2 == SI_UNDEF &&
246 		 *lr2 == SI_UNDEF)
247 	     {
248 		*ll2 = SI_IN;
249 		*lr2 = SI_OUT;
250 	     }
251 	     else if (!((*ll2 == SI_IN && *lr2 == SI_IN) ||
252 		      (*ll2 == SI_OUT && *lr2 == SI_OUT)))
253 		{
254 		   if (*ll2 != SI_IN) *ll2 = SI_IN;
255 		}
256 	  }
257 	  else
258 	  {
259 	     *ll1 = SI_UNDEF;
260 	     *lr1 = SI_UNDEF;
261 	     if (*ll2 == SI_UNDEF &&
262 		 *lr2 == SI_UNDEF)
263 	     {
264 		*ll2 = SI_OUT;
265 		*lr2 = SI_IN;
266 	     }
267 	     else if (!((*ll2 == SI_IN && *lr2 == SI_IN) ||
268 		      (*ll2 == SI_OUT && *lr2 == SI_OUT)))
269 		{
270 		   if (*lr2 != SI_IN) *lr2 = SI_IN;
271 		}
272 	  }
273 
274     }
275 
276   /* Update pretopology of intersection point.  */
277 
278   sh6settop (pintpt, -1, lleft[0], lright[0], lleft[1], lright[1], &kstat);
279   if (kstat < 0)
280     goto error;
281 
282   /* Pre-topology information computed. */
283 
284   *jnewpt = kpos;
285   *jstat = 0;
286   goto out;
287 
288   /* Error in input. Incorrect dimension.  */
289 
290 err106:*jstat = -106;
291   goto out;
292 
293   /* Error lower level routine.  */
294 
295 error:*jstat = kstat;
296   goto out;
297 
298 out:
299   return;
300 }
301