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