1 /* Copyright (C) 1992-1998 The Geometry Center
2  * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3  *
4  * This file is part of Geomview.
5  *
6  * Geomview is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * Geomview is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Geomview; see the file COPYING.  If not, write
18  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19  * USA, or visit http://www.gnu.org.
20  */
21 
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25 
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30 
31 
32 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
33 
34 #include "skelP.h"
35 #include "pickP.h"
36 
NSkelPick(Skel * s,Pick * p,Appearance * ap,Transform T,TransformN * TN,int * axes)37 static Skel *NSkelPick(Skel *s, Pick *p, Appearance *ap,
38 		       Transform T, TransformN *TN, int *axes)
39 {
40   Point3 plist[2];
41   int i, j, ok[2];
42   bool found;
43   unsigned int apflag = 0;
44   HPointN ptN[1];
45 
46   if (!TN)
47     return NULL;
48 
49   /* we have full-featured ND-points here. */
50   ptN->flags = 0;
51   ptN->dim = s->pdim;
52 
53   /* Make sure that the edges do not count as visible - otherwise
54    * they could really mess things up */
55   if (ap != NULL) {
56     apflag = ap->flag;
57     ap->flag &= ~APF_EDGEDRAW;
58   }
59 
60   found = false;
61 
62   for (i = 0; i < s->nlines && !found; i++) {
63     int nv = abs(s->l[i].nv);
64     int *idx = s->vi + s->l[i].v0;
65 
66     ptN->v = s->p + idx[0]*s->pdim;
67     ok[0] = (0 < HPtNNTransPt3(TN, axes, ptN, &plist[0]));
68     if (nv == 1) {
69       if (ok[0] && PickFace(1, &plist[0], p, ap)) {
70 	found = true;
71 	p->vi = idx[0];
72 	break;
73       }
74       continue;
75     }
76     for (j = 0; j < nv - 1;) {
77       ptN->v = s->p + idx[++j]*s->pdim;
78       ok[1] = (0 < HPtNNTransPt3(TN, axes, ptN, &plist[1]));
79       if ((ok[0]||ok[1]) && PickFace(2, plist, p, ap)) {
80 	found = true;
81 	p->vi = p->vi ? idx[j] : idx[j-1];
82 	p->ei[0] = idx[j-1];
83 	p->ei[1] = idx[j];
84 	break;
85       }
86       ok[0] = ok[1];
87       plist[0] = plist[1];
88     }
89     if (s->l[i].nv < 0) {
90       ptN->v = s->p + idx[0]*s->pdim;
91       ok[1] = (0 < HPtNNTransPt3(TN, axes, ptN, &plist[1]));
92       if ((ok[0]||ok[1]) && PickFace(2, plist, p, ap)) {
93 	found = true;
94 	p->vi = p->vi ? idx[0] : idx[j];
95 	p->ei[0] = idx[j];
96 	p->ei[1] = idx[0];
97 	break;
98       }
99     }
100     if (found) {
101       break;
102     }
103   }
104 
105   if (ap != NULL) ap->flag = apflag;
106 
107   if (!found) {
108     return NULL;
109   }
110 
111   if (p->found & PW_VERT) {
112     ptN->v = s->p + p->vi*s->pdim;
113     HPtNTransformComponents(TN, ptN, axes, &p->v);
114   } else
115     p->vi = -1;
116 
117   if (p->found & PW_EDGE) {
118     ptN->v = s->p + p->ei[0]*s->pdim;
119     HPtNTransformComponents(TN, ptN, axes, &p->e[0]);
120     ptN->v = s->p + p->ei[1]*s->pdim;
121     HPtNTransformComponents(TN, ptN, axes, &p->e[1]);
122   } else
123     p->ei[0] = p->ei[1] = -1;
124 
125   if (p->found & PW_FACE) {
126     p->fi = i;
127     if (p->f) {
128       OOGLFree(p->f);
129     }
130     p->f = OOGLNewNE(HPoint3, p->fn, "Skel pick");
131     for (i = 0; i < p->fn; i++) {
132       int vi = s->vi[s->l[p->fi].v0+i];
133       ptN->v = s->p + vi*s->pdim;
134       HPtNTransformComponents(TN, ptN, axes, &p->f[i]);
135     }
136   }
137 
138   if (TN) {
139     p->TprimN = TmNCopy(TN, p->TprimN);
140     memcpy(p->axes, axes, sizeof(p->axes));
141   } else
142     TmCopy(T, p->Tprim);
143 
144   return s;
145 }
146 
SkelPick(Skel * s,Pick * p,Appearance * ap,Transform T,TransformN * TN,int * axes)147 Skel *SkelPick(Skel *s, Pick *p, Appearance *ap,
148 	       Transform T, TransformN *TN, int *axes)
149 {
150   Point3 plist[2];
151   int i, j, ok[2];
152   bool found;
153   int v4d;
154   unsigned int apflag = 0;
155 
156   if (s->pdim > 4) {
157     return NSkelPick(s, p, ap, T, TN, axes);
158   }
159 
160   /* Make sure that the edges do not count as visible - otherwise
161    * they could really mess things up */
162   if (ap != NULL) {
163     apflag = ap->flag;
164     ap->flag &= ~APF_EDGEDRAW;
165   }
166 
167   found = false;
168 
169   v4d = (s->geomflags & VERT_4D) != 0;
170 
171   for (i = 0; i < s->nlines && !found; i++) {
172     int nv = abs(s->l[i].nv);
173     int *idx = &s->vi[s->l[i].v0];
174 
175     if (TN) {
176       ok[0] = (0 < HPt3NTransPt3(TN, axes,
177 				 (HPoint3 *)(s->p + idx[0]*s->pdim), v4d,
178 				 &plist[0]));
179     } else {
180       ok[0] = (0 < HPt3TransPt3(T, (HPoint3 *)(s->p + idx[0]*s->pdim),
181 				&plist[0]));
182     }
183 
184     if (nv == 1) {
185       if (ok[0] && PickFace(1, &plist[0], p, ap)) {
186 	found = true;
187 	p->vi = idx[0];
188 	break;
189       }
190       continue;
191     }
192     for (j = 0; j < nv - 1;) {
193       if (TN) {
194 	ok[1] = (0 < HPt3NTransPt3(TN, axes,
195 				   (HPoint3 *)(s->p + idx[++j]*s->pdim), v4d,
196 				   &plist[1]));
197       } else {
198 	ok[1] = (0 < HPt3TransPt3(T,
199 				  (HPoint3 *)(s->p + idx[++j]*s->pdim),
200 				  &plist[1]));
201       }
202 
203       if ((ok[0]||ok[1]) && PickFace(2, plist, p, ap)) {
204 	found = true;
205 	p->vi = p->vi ? idx[j] : idx[j-1];
206 	p->ei[0] = idx[j-1];
207 	p->ei[1] = idx[j];
208 	break;
209       }
210       ok[0] = ok[1];
211       plist[0] = plist[1];
212     }
213     if (s->l[i].nv < 0) {
214       if (TN)
215 	ok[1] = (0 < HPt3NTransPt3(TN, axes,
216 				   (HPoint3 *)(s->p + idx[0]*s->pdim), v4d,
217 				   &plist[1]));
218       else
219 	ok[1] = (0 < HPt3TransPt3(T, (HPoint3 *)(s->p + idx[0]*s->pdim),
220 				  &plist[1]));
221       if ((ok[0]||ok[1]) && PickFace(2, plist, p, ap)) {
222 	found = true;
223 	p->vi = p->vi ? idx[0] : idx[j];
224 	p->ei[0] = idx[j];
225 	p->ei[1] = idx[0];
226 	break;
227       }
228     }
229     if (found) {
230       break;
231     }
232   }
233 
234   if (ap != NULL) {
235     ap->flag = apflag;
236   }
237 
238   if (!found) {
239     return NULL;
240   }
241 
242   if (p->found & PW_VERT) {
243     if (TN) {
244       HPt3NTransHPt3(TN, axes, (HPoint3 *)(s->p + p->vi*s->pdim), v4d, &p->v);
245     } else {
246       HPt3Transform(T, (HPoint3 *)(s->p + p->vi*s->pdim), &p->v);
247     }
248   } else {
249     p->vi = -1;
250   }
251 
252   if (p->found & PW_EDGE) {
253     if (TN) {
254       HPt3NTransHPt3(TN, axes,
255 		     (HPoint3 *)(s->p + p->ei[0]*s->pdim), v4d,
256 		     &p->e[0]);
257       HPt3NTransHPt3(TN, axes,
258 		     (HPoint3 *)(s->p + p->ei[1]*s->pdim), v4d,
259 		     &p->e[1]);
260     } else {
261       HPt3Transform(T, (HPoint3 *)(s->p + p->ei[0]*s->pdim), &p->e[0]);
262       HPt3Transform(T, (HPoint3 *)(s->p + p->ei[1]*s->pdim), &p->e[1]);
263     }
264   } else {
265     p->ei[0] = p->ei[1] = -1;
266   }
267 
268   if (p->found & PW_FACE) {
269     p->fi = i;
270     if (p->f) {
271       OOGLFree(p->f);
272     }
273     p->f = OOGLNewNE(HPoint3, p->fn, "Skel pick");
274     if (TN) {
275       for (i = 0; i < p->fn; i++) {
276 	int vi = s->vi[s->l[p->fi].v0+i];
277 	HPt3NTransHPt3(TN, axes, (HPoint3 *)(s->p + vi*s->pdim), v4d, &p->f[i]);
278       }
279     } else {
280       for (i = 0; i < p->fn; i++) {
281 	int vi = s->vi[s->l[p->fi].v0+i];
282 	HPt3Transform(T, (HPoint3 *)(s->p + vi*s->pdim), &p->f[i]);
283       }
284     }
285   } else {
286     p->fi = -1;
287   }
288 
289   if (TN) {
290     p->TprimN = TmNCopy(TN, p->TprimN);
291     memcpy(p->axes, axes, sizeof(p->axes));
292   } else
293     TmCopy(T, p->Tprim);
294 
295   return s;
296 }
297 
298 /*
299  * Local Variables: ***
300  * c-basic-offset: 2 ***
301  * End: ***
302  */
303