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 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
32 
33 #include "discgrp.h"
34 #include "discgrpP.h"
35 
36 DiscGrp *
DiscGrpSetPreDraw(DiscGrp * dg,void (* predraw)())37 DiscGrpSetPreDraw( DiscGrp *dg, void (*predraw)() )
38 {
39     dg->predraw = predraw;
40     return (dg);
41 }
42 
43 DiscGrpElList *
DiscGrpElListCreate(DiscGrpElList * exist,...)44 DiscGrpElListCreate (DiscGrpElList *exist, ...)
45 {
46     va_list a_list;
47     DiscGrpElList *dgellist;
48     DiscGrpEl 	*passedin;
49     Transform 	*tformin;
50     ColorA  	*colorin;
51     char	(*wordin)[DG_WORDLENGTH] = NULL;
52     int 	*attrin;
53     int		attr, copy = 1;
54     int i;
55 
56     va_start (a_list, exist);
57     if (exist == NULL) {
58 	dgellist = OOGLNewE(DiscGrpElList, "DiscGrpElListCreate discgrp");
59 	memset(dgellist, 0, sizeof(DiscGrpElList));
60 	}
61     else (dgellist = exist);
62 
63     while ((attr = va_arg (a_list, int))) switch (attr) {
64 	case CR_NELEM:
65 	    dgellist->num_el = va_arg (a_list, int);
66 	    if (dgellist->el_list)  OOGLFree(dgellist->el_list);
67 	    dgellist->el_list = OOGLNewNE(DiscGrpEl, dgellist->num_el, "DiscGrpElListCreate: unable to allocate");
68 	    memset(dgellist->el_list, 0, sizeof(DiscGrpEl) * dgellist->num_el);
69 	    break;
70 
71 	case DGCR_ELEM:		/* already packed up */
72 	    passedin = va_arg (a_list, DiscGrpEl *);
73 	    if (copy)	{
74 		for (i=0; i<dgellist->num_el; ++i)	{
75 		    dgellist->el_list[i] =  passedin[i];
76 		    TmCopy(passedin[i].tform, dgellist->el_list[i].tform);
77 		    }
78 		}
79 	    else	{
80 		if (dgellist->el_list) OOGLFree(dgellist->el_list);
81 		dgellist->el_list = passedin;
82 		}
83 	    break;
84 
85 	case CR_ELEM:
86 	    tformin = va_arg (a_list, Transform *);
87 	    for (i=0; i<dgellist->num_el; ++i)
88 		    TmCopy(tformin[i], dgellist->el_list[i].tform);
89 	    break;
90 
91 	case CR_COLOR:
92 	    colorin = va_arg (a_list, ColorA *);
93 	    for (i=0; i<dgellist->num_el; ++i)
94 		   dgellist->el_list[i].color = colorin[i];
95 	    break;
96 
97 	/* we assume attributes is constant for this list */
98 	case DGCR_ATTRIBUTE:
99 	    attr = va_arg (a_list, int);
100 	    for (i=0; i<dgellist->num_el; ++i)
101 		   dgellist->el_list[i].attributes = attr;
102 	    break;
103 
104 	/* or can be passed in as a list */
105 	case DGCR_ATTRIBUTELIST:
106 	    attrin = va_arg (a_list, int *);
107 	    for (i=0; i<dgellist->num_el; ++i)
108 		   dgellist->el_list[i].attributes = attrin[i];
109 	    break;
110 
111 	case DGCR_WORD:
112 	    wordin = (char (*)[DG_WORDLENGTH] ) va_arg (a_list, char *);
113 	    for (i=0; i<dgellist->num_el; ++i)
114 		   strcpy(dgellist->el_list[i].word,  wordin[i]);
115 	    break;
116 
117 	default:
118 	    if (GeomDecorate (dgellist, &copy, attr, &a_list)) {
119 		GeomError (0, "DiscGrpElListCreate: Undefined option: %d", attr);
120 		OOGLFree (dgellist);
121 		return NULL;
122 	    }
123 
124 	}
125     va_end (a_list);
126     return(dgellist);
127 }
128 
DiscGrpGet(DiscGrp * discgrp,int attr,void * attrp)129 int DiscGrpGet(DiscGrp *discgrp, int attr, void *attrp)
130 {
131     switch (attr) {
132 
133     case DGCR_NAME: *(char **)attrp = discgrp->name; break;
134     case DGCR_COMMENT: *(char **)attrp = discgrp->comment; break;
135     case DGCR_FLAG: *(unsigned *)attrp = discgrp->flag; break;
136     case DGCR_ATTRIBUTE: *(int *)attrp = discgrp->attributes; break;
137     case DGCR_GENS: *(DiscGrpElList **)attrp = discgrp->gens; break;
138     case DGCR_BIGLIST: *(DiscGrpElList **)attrp = discgrp->big_list; break;
139     case DGCR_CPOINT: *(HPoint3 *)attrp = discgrp->cpoint; break;
140     case DGCR_ENUMDEPTH: *(int *)attrp = discgrp->enumdepth; break;
141     case DGCR_ENUMDIST: *(float *)attrp = discgrp->enumdist; break;
142     case DGCR_DRAWDIST: *(float *)attrp = discgrp->drawdist; break;
143     case DGCR_SCALE: *(float *)attrp = discgrp->scale; break;
144     case DGCR_CAMGEOM: *(Geom **)attrp = discgrp->camgeom; break;
145     case DGCR_CAMGEOMHANDLE: *(Handle **)attrp = discgrp->camgeomhandle; break;
146     case DGCR_DDGEOM: *(Geom **)attrp = discgrp->ddgeom; break;
147     case DGCR_DDGEOMHANDLE: *(Handle **)attrp = discgrp->ddgeomhandle; break;
148     case CR_GEOM: *(Geom **)attrp = discgrp->geom; break;
149     case CR_GEOMHANDLE: *(Handle **)attrp = discgrp->geomhandle; break;
150     default: return -1;
151     }
152     return 1;
153 }
154 
155 DiscGrp *
DiscGrpCreate(DiscGrp * exist,GeomClass * classp,va_list * a_list)156 DiscGrpCreate (DiscGrp *exist, GeomClass *classp, va_list *a_list)
157 {
158     DiscGrp *discgrp;
159     int	attr, copy = 1;
160     Geom *g;
161     Handle *h;
162 
163     if (exist == NULL) {
164 	discgrp = OOGLNewE(DiscGrp, "DiscGrpCreate discgrp");
165 	memset(discgrp, 0, sizeof(DiscGrp));
166 	GGeomInit (discgrp, classp, DISCGRPMAGIC, NULL);
167 	discgrp->flag = DG_DDSLICE;  /* default is to slice off cusps */
168 	discgrp->name = NULL;
169 	discgrp->comment = NULL;
170 	discgrp->attributes = 0;
171 	discgrp->c2m = NULL;
172 	discgrp->fsa = NULL;
173 	discgrp->dimn = 3;	/* make a guess */
174 	discgrp->gens = NULL;
175 	discgrp->nhbr_list = NULL;
176 	discgrp->big_list = NULL;
177 	discgrp->cpoint = DGorigin;
178 	discgrp->camgeom = NULL;
179 	discgrp->ddgeom = NULL;
180 	discgrp->geom = NULL;
181 	discgrp->camgeomhandle = NULL;
182 	discgrp->ddgeomhandle = NULL;
183 	discgrp->geomhandle = NULL;
184 	discgrp->scale = .2;
185 	discgrp->enumdepth = 2;
186 	discgrp->enumdist = 5.0;
187 	discgrp->drawdist = 5.0;
188 	discgrp->predraw = NULL;
189     } else {
190 	/* Check that exist is a DiscGrp... */
191 	discgrp = exist;
192     }
193 
194     while ((attr = va_arg (*a_list, int))) switch (attr) {
195     case DGCR_NAME:
196 	discgrp->name = va_arg (*a_list, char *);
197 	break;
198 
199     case DGCR_COMMENT:
200 	discgrp->comment = va_arg (*a_list, char *);
201 	break;
202 
203     case DGCR_FLAG:
204 	discgrp->flag = va_arg (*a_list, int);
205 	break;
206 
207     case DGCR_ATTRIBUTE:
208 	discgrp->attributes = va_arg (*a_list, int);
209 	break;
210 
211     case DGCR_GENS:
212 	discgrp->gens = va_arg (*a_list, DiscGrpElList *);
213 	break;
214 
215     case DGCR_BIGLIST:
216 	discgrp->big_list = va_arg (*a_list, DiscGrpElList *);
217 	break;
218 
219     case DGCR_CPOINT:
220 	{
221 	    HPoint3 *cptr;
222 	    cptr = va_arg (*a_list, HPoint3 *);
223 	    discgrp->cpoint = *cptr;
224 	}
225 	break;
226 
227     case DGCR_ENUMDEPTH:
228 	discgrp->enumdepth = va_arg (*a_list, int);
229 	break;
230 
231     case DGCR_ENUMDIST:
232 	discgrp->enumdist = ((float) va_arg (*a_list, double));
233 	break;
234 
235     case DGCR_DRAWDIST:
236 	discgrp->drawdist = ((float) va_arg (*a_list, double));
237 	break;
238 
239     case DGCR_SCALE:
240 	discgrp->scale = ((float) va_arg (*a_list, double));
241 	break;
242 
243 	/* Geometries and their handles: copy the logic from InstCreate() and
244 	 * duplicate it for ddgeom and camgeom.
245 	 */
246     case CR_GEOMHANDLE:
247 	h = va_arg(*a_list, Handle *);
248 	if (copy) {
249 	    REFINCR(h);
250 	}
251 	if (discgrp->geomhandle) {
252 	    HandlePDelete(&discgrp->geomhandle);
253 	}
254 	discgrp->geomhandle = h;
255 	HandleRegister(&discgrp->geomhandle, (Ref *)discgrp, &discgrp->geom,
256 		       HandleUpdRef);
257 	break;
258     case CR_HANDLE_GEOM:
259 	h = va_arg(*a_list, Handle *);
260 	g = va_arg(*a_list, Geom *);
261 	if (copy) {
262 	    REFINCR(h);
263 	    REFINCR(g);
264 	}
265 	if (discgrp->geomhandle) {
266 	    HandlePDelete(&discgrp->geomhandle);
267 	}
268 	if (discgrp->geom) {
269 	    GeomDelete(discgrp->geom);
270 	}
271 	discgrp->geomhandle = h;
272 	discgrp->geom = g;
273 	if (h) {
274 	    HandleRegister(&discgrp->geomhandle,
275 			   (Ref *)discgrp, &discgrp->geom, HandleUpdRef);
276 	    HandleSetObject(discgrp->geomhandle, (Ref *)g);
277 	}
278 	break;
279     case CR_GEOM:
280 	g = va_arg (*a_list, Geom *);
281 	if (copy) {
282 	    REFINCR(g);
283 	}
284 	if (discgrp->geom) {
285 	    GeomDelete(discgrp->geom);
286 	}
287 	discgrp->geom = g;
288 	if (discgrp->geomhandle) {
289 	    HandlePDelete(&discgrp->geomhandle);
290 	}
291 	break;
292 
293     case DGCR_CAMGEOMHANDLE:
294 	h = va_arg(*a_list, Handle *);
295 	if (copy) {
296 	    REFINCR(h);
297 	}
298 	if (discgrp->camgeomhandle) {
299 	    HandlePDelete(&discgrp->camgeomhandle);
300 	}
301 	discgrp->camgeomhandle = h;
302 	HandleRegister(&discgrp->camgeomhandle,
303 		       (Ref *)discgrp, &discgrp->camgeom,
304 		       HandleUpdRef);
305 	break;
306     case DGCR_HANDLE_CAMGEOM:
307 	h = va_arg(*a_list, Handle *);
308 	g = va_arg(*a_list, Geom *);
309 	if (copy) {
310 	    REFINCR(h);
311 	    REFINCR(g);
312 	}
313 	if (discgrp->camgeomhandle) {
314 	    HandlePDelete(&discgrp->camgeomhandle);
315 	}
316 	if (discgrp->camgeom) {
317 	    GeomDelete(discgrp->camgeom);
318 	}
319 	discgrp->camgeomhandle = h;
320 	discgrp->camgeom = g;
321 	if (h) {
322 	    HandleRegister(&discgrp->camgeomhandle,
323 			   (Ref *)discgrp, &discgrp->camgeom, HandleUpdRef);
324 	    HandleSetObject(discgrp->camgeomhandle, (Ref *)g);
325 	}
326 	break;
327     case DGCR_CAMGEOM:
328 	g = va_arg (*a_list, Geom *);
329 	if (copy) {
330 	    REFINCR(g);
331 	}
332 	if (discgrp->camgeom) {
333 	    GeomDelete(discgrp->camgeom);
334 	}
335 	discgrp->camgeom = g;
336 	if (discgrp->camgeomhandle) {
337 	    HandlePDelete(&discgrp->camgeomhandle);
338 	}
339 	break;
340 
341     case DGCR_DDGEOMHANDLE:
342 	h = va_arg(*a_list, Handle *);
343 	if (copy) {
344 	    REFINCR(h);
345 	}
346 	if (discgrp->ddgeomhandle) {
347 	    HandlePDelete(&discgrp->ddgeomhandle);
348 	}
349 	discgrp->ddgeomhandle = h;
350 	HandleRegister(&discgrp->ddgeomhandle,
351 		       (Ref *)discgrp, &discgrp->ddgeom,
352 		       HandleUpdRef);
353 	break;
354     case DGCR_HANDLE_DDGEOM:
355 	h = va_arg(*a_list, Handle *);
356 	g = va_arg(*a_list, Geom *);
357 	if (copy) {
358 	    REFINCR(h);
359 	    REFINCR(g);
360 	}
361 	if (discgrp->ddgeomhandle) {
362 	    HandlePDelete(&discgrp->ddgeomhandle);
363 	}
364 	if (discgrp->ddgeom) {
365 	    GeomDelete(discgrp->ddgeom);
366 	}
367 	discgrp->ddgeomhandle = h;
368 	discgrp->ddgeom = g;
369 	if (h) {
370 	    HandleRegister(&discgrp->ddgeomhandle,
371 			   (Ref *)discgrp, &discgrp->ddgeom, HandleUpdRef);
372 	    HandleSetObject(discgrp->ddgeomhandle, (Ref *)g);
373 	}
374 	break;
375     case DGCR_DDGEOM:
376 	g = va_arg (*a_list, Geom *);
377 	if (copy) {
378 	    REFINCR(g);
379 	}
380 	if (discgrp->ddgeom) {
381 	    GeomDelete(discgrp->ddgeom);
382 	}
383 	discgrp->ddgeom = g;
384 	if (discgrp->ddgeomhandle) {
385 	    HandlePDelete(&discgrp->ddgeomhandle);
386 	}
387 	break;
388 
389 
390     default:
391 	if (GeomDecorate (discgrp, &copy, attr, a_list)) {
392 	    GeomError (0, "DiscGrpCreate: Undefined option: %d", attr);
393 	    OOGLFree (discgrp);
394 	    return NULL;
395 	}
396     }
397     return discgrp;
398 }
399 
400 
401 /*
402  * Local Variables: ***
403  * mode: c ***
404  * c-basic-offset: 4 ***
405  * End: ***
406  */
407