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: sh6edgred.c,v 1.2 2001-03-19 15:59:07 afr Exp $
45  *
46  */
47 
48 
49 #define SH6EDGRED
50 
51 /* commented out - guen Fri Oct 25 12:59:43 MEZ 1991
52  include <stdio.h>
53    commented out - guen Fri Oct 25 12:59:43 MEZ 1991 */
54 
55 #include "sislP.h"
56 
57 #if defined(SISLNEEDPROTOTYPES)
58 void
sh6edgred(SISLObject * po1,SISLObject * po2,SISLIntdat * pintdat,int * jstat)59 sh6edgred (SISLObject * po1, SISLObject * po2,
60 	   SISLIntdat * pintdat, int *jstat)
61 #else
62 void
63 sh6edgred (po1, po2, pintdat, jstat)
64      SISLObject *po1;
65      SISLObject *po2;
66      SISLIntdat *pintdat;
67      int *jstat;
68 #endif
69 
70 /*
71 *********************************************************************
72 *
73 *********************************************************************
74 *
75 * PURPOSE    : Reduse main int point to help point if they are not legal.
76 *
77 *
78 * INPUT      : po1      - Pointer to the first object in the intersection.
79 *              po2      - Pointer to the second object in the intersection.
80 *              pintdat  - Intersection data structure.
81 *
82 *
83 * OUTPUT     : jstat    - status messages
84 *                                > 0   : Warning.
85 *                                = 0   : Ok.
86 *                                < 0   : Error.
87 *
88 *
89 * METHOD     :
90 *
91 * CALLS      :
92 *
93 * REFERENCES :
94 *
95 * WRITTEN BY : Arne Laksaa, SI, Oslo, sep. -91.
96 * CORRECTED BY: UJK
97 *********************************************************************
98 */
99 {
100   int kstat, gstat, i, ki;
101   int change = FALSE;
102   int change_2 = FALSE;
103   int num = 0;
104   SISLIntpt *pt1 = SISL_NULL;
105   SISLIntpt *pt2 = SISL_NULL;
106   SISLIntpt *pcurr = SISL_NULL;
107 
108   if (pintdat != SISL_NULL)
109     {
110       do
111 	{
112 	  change_2 = FALSE;
113 	  /* If trim point is internal and one neighbours, change to help
114 	     point, if two neighbours unite till one of them */
115 	  do
116 	    {
117 	      change = FALSE;
118 	      for (i = 0; i < pintdat->ipoint; i++)
119 		{
120 		  pcurr = pintdat->vpoint[i];
121 		  if (pcurr->iinter == SI_TRIM)
122 		    {
123 		      sh6isinside (po1, po2, pcurr, &kstat);
124 		      if (kstat < 0)
125 			goto error;
126 		      if (kstat == 1)
127 			{
128 			  num = sh6nmbmain (pcurr, &kstat);
129 			  if (kstat < 0)
130 			    goto error;
131 			  if (num == 1)
132 			    {
133 			      sh6tohelp (pcurr, &kstat);
134 			      change = TRUE;
135 			    }
136 			  else if (num == 2)
137 			    {
138 			      sh6getnhbrs (pcurr, &pt1, &pt2, &gstat);
139 			      if (kstat < 0)
140 				goto error;
141 			      if (pt1->iinter == SI_TRIM &&
142 				  pt2->iinter == SI_TRIM)
143 				{
144 				  sh6idunite (&pintdat, &pt1, &pcurr,
145 					      DZERO, &kstat);
146 				  if (kstat < 0)
147 				    goto error;
148 				  change = TRUE;
149 				}
150 			    }
151 			}
152 		    }
153 		}
154 	  } while (change);
155 
156 
157 	  /* For a trim point on the edge with only one trim
158              neighbour on an edge, unit till the other edge
159              neighbour and change status of neighbour*/
160 	  do
161 	    {
162 	      change = FALSE;
163 	      for (i = 0; i < pintdat->ipoint; i++)
164 		{
165 		  pt1 = pt2 = SISL_NULL;
166 		  pcurr = pintdat->vpoint[i];
167 		  if (pcurr->iinter == SI_TRIM)
168 		    {
169 		      sh6isinside (po1, po2, pcurr, &kstat);
170 		      if (kstat < 0)
171 			goto error;
172 		      if (kstat == 2)
173 			{
174 			  for (ki = 0; ki < pcurr->no_of_curves; ki++)
175 			    {
176 			      pt1 = pcurr->pnext[ki];
177 			      if (pt1->iinter == SI_TRIM)
178 				{
179 				  sh6comedg (po1, po2, pcurr, pt1, &kstat);
180 				  if (kstat < 0)
181 				    goto error;
182 				    if (kstat)
183 				    {
184 				       if (pt2)
185 					  {
186 					     pt2 = SISL_NULL;
187 					     break;
188 					  }
189 					  else
190 					  pt2 = pt1;
191 				    }
192 				}
193 			    }
194 			  if (pt2)
195 			    {
196 			       /* sh6idunite (&pintdat, &pt2, &pcurr,
197 				              DZERO, &kstat);  */
198 			       /* UJK, 12.08.93  */
199 			      /* sh6idkpt (&pintdat, &pcurr, 1, &kstat);
200 			     sh6disconnect(pcurr,pt2,&kstat); */
201 			     pcurr->iinter = SI_SING;
202 
203 			      /*------------------- */
204 			      /* If no trim neighbours on common
205 			         edge, remove trim status. */
206 			      pcurr = pt2;
207 			      kstat = 0;
208 
209 			      for (ki = 0; ki < pcurr->no_of_curves; ki++)
210 				{
211 				  pt1 = pcurr->pnext[ki];
212 				  if (pt1->iinter == SI_TRIM)
213 				    {
214 				      sh6comedg (po1, po2, pcurr, pt1, &kstat);
215 				      if (kstat < 0)
216 					goto error;
217 				      if (kstat)
218 					break;
219 
220 				    }
221 
222 				}
223 			      /* -------------------- */
224 			      if (!kstat)
225 				pcurr->iinter = SI_SING;
226 			      change = TRUE;
227 			      change_2 = TRUE;
228 			    }
229 
230 			}
231 
232 		    }
233 		}
234 	  } while (change);
235       } while (change_2);
236 
237 
238       /* Reduce internal stuff */
239       sh6red (po1, po2, pintdat, &kstat);
240       if (kstat < 0)
241 	goto error;
242 
243 
244       /* General edge treatment */
245 
246       /* UJK, aug 93, spesial branch for crv/crv */
247       if (po1->iobj == SISLCURVE &&
248 	  po2->iobj == SISLCURVE )
249       {
250 	 do
251 	 {
252 	    change = 0;
253 	    for (i = 0; i < pintdat->ipoint; i++)
254 	    {
255 	       if (sh6ismain (pintdat->vpoint[i]))
256 	       {
257 		  sh6getnhbrs (pintdat->vpoint[i], &pt1, &pt2, &gstat);
258 		  if (gstat == 1)
259 		  {
260 		     double parval;
261 		     SISLCurve *pcu=SISL_NULL;
262 		     if (pintdat->vpoint[i]->epar[0] == pt1->epar[0])
263 		     {
264 			parval = pintdat->vpoint[i]->epar[1];
265 			pcu    = po2->c1;
266 		     }
267 		     else if (pintdat->vpoint[i]->epar[1] == pt1->epar[1])
268 		     {
269 			parval = pintdat->vpoint[i]->epar[0];
270 			pcu    = po1->c1;
271 		     }
272 
273 		     if (pcu &&
274 			 parval > pcu->et[pcu->ik-1] &&
275 			 parval < pcu->et[pcu->in] )
276 
277 
278 		     {
279 			sh6tohelp (pintdat->vpoint[i], &kstat);
280 			if (kstat < 0)
281 			   goto error;
282 			change = 1;
283 		     }
284 		  }
285 	       }
286 	    }
287 	 } while (change);
288       }
289       else
290       {
291 	 do
292 	 {
293 	    change = 0;
294 	    for (i = 0; i < pintdat->ipoint; i++)
295 	    {
296 	       if (sh6ismain (pintdat->vpoint[i]))
297 	       {
298 		  sh6isinside (po1, po2, pintdat->vpoint[i], &kstat);
299 		  if (kstat < 0)
300 		     goto error;
301 
302 		  /* ALA and VSK. Test if the point lies on edge in
303 		     one or two objects.         */
304 		  if (kstat == 2 || kstat == 5)
305 		  {
306 		     sh6getnhbrs (pintdat->vpoint[i], &pt1, &pt2, &gstat);
307 		     if (gstat == 1)
308 		     {
309 			sh6comedg (po1, po2, pintdat->vpoint[i], pt1, &gstat);
310 
311 			/* ALA and VSK. Test if the points lie on the same
312 			   edge in both objects if it lies on an edge in
313 			   both objects.                  */
314 			if ((kstat == 2 && gstat > 0) ||
315 			    (kstat == 5 && gstat == 3))
316 			{
317 			   sh6tohelp (pintdat->vpoint[i], &kstat);
318 			   if (kstat < 0)
319 			      goto error;
320 			   change = 1;
321 			}
322 		     }
323 		  }
324 	       }
325 	    }
326 	 } while (change);
327       }
328     }
329 
330 
331 
332   *jstat = 0;
333   goto out;
334 
335   /* Error lower level routine.  */
336 
337 error:(*jstat) = kstat;
338   s6err ("sh6edgred", *jstat, 0);
339   goto out;
340 
341 out:
342   return;
343 }
344 
345