1 /* Copyright (C) 1992-1998 The Geometry Center
2  * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3  * Copyright (C) 2007 Claus-Justus Heine
4  *
5  * This file is part of Geomview.
6  *
7  * Geomview is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published
9  * by the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * Geomview is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Geomview; see the file COPYING.  If not, write
19  * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
20  * USA, or visit http://www.gnu.org.
21  */
22 
23 #if HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26 
27 #if 0
28 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
29 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
30 #endif
31 
32 /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
33 
34 #include "skelP.h"
35 
36 /*
37  * Vect object creation, editing, copying, deletion.
38  */
39 
SkelCopy(Skel * os)40 Skel *SkelCopy(Skel *os)
41 {
42   Skel  *s;
43 
44   if (os == NULL) return (NULL);
45 
46   s = OOGLNewE(Skel, "new SKEL");
47 
48   *s = *os;
49   s->p = OOGLNewNE(float, os->nvert * os->pdim, "Skel vertices");
50   s->c = os->nc > 0 ? OOGLNewNE(ColorA, os->nc, "Skel colors") : NULL;
51   s->l = OOGLNewNE(Skline, os->nlines, "Skel lines");
52   s->vi = OOGLNewNE(int, os->nvi, "Skel nverts");
53   if (s->vc) {
54     s->vc = OOGLNewNE(ColorA, os->nvert, "Skel vertex colors");
55   }
56 
57   memcpy(s->p, os->p, os->nvert * os->pdim * sizeof(float));
58   memcpy(s->l, os->l, os->nlines * sizeof(Skline));
59   if(os->nc > 0) memcpy(s->c, os->c, os->nc * sizeof(ColorA));
60   memcpy(s->vi, os->vi, os->nvi * sizeof(int));
61   if (os->vc) memcpy(s->vc, os->vc, os->nvert * sizeof(ColorA));
62   return s;
63 }
64 
SkelDelete(Skel * s)65 void SkelDelete(Skel *s)
66 {
67   if (s) {
68     if (s->p != NULL) OOGLFree(s->p);
69     if (s->c != NULL) OOGLFree(s->c);
70     if (s->vi != NULL) OOGLFree(s->vi);
71     if (s->vc != NULL) OOGLFree(s->vc);
72   }
73 }
74 
SkelCreate(Skel * exist,GeomClass * classp,va_list * a_list)75 Skel *SkelCreate(Skel *exist, GeomClass *classp, va_list *a_list)
76 {
77   Skel *s;
78 
79   (void)a_list;
80 
81   if (exist == NULL) {
82     s = OOGLNewE(Skel, "new skel");
83     GGeomInit (s, classp, SKELMAGIC, NULL);
84     s->nlines = 0;
85     s->nvert = 0;
86     s->nvi = 0;
87     s->p = NULL;
88     s->c = NULL;
89     s->vi = NULL;
90     s->vc = NULL;
91   } else {
92     /* Should check that exist is a vect */
93     s = exist;
94   }
95 
96 #ifdef notyet
97   while (attr = va_arg (*a_list, int))
98     switch (attr) {
99     case CR_FLAG:
100       vect->flag = va_arg (*a_list, int);
101       break;
102 
103     case CR_NVECT:
104       vect->nvec = va_arg (*a_list, int);
105       break;
106 
107     case CR_NVERT:
108       vect->nvert = va_arg (*a_list, int);
109       break;
110 
111     case CR_NCOLR:
112       vect->ncolor = va_arg (*a_list, int);
113       break;
114 
115     case CR_VECTC:
116       vectcounts = va_arg (*a_list, short *);
117       if (vectcounts == NULL) {
118 	vect->vnvert = NULL;
119 	vect->nvert = 0;
120       } else if (copy) {
121 	vect->vnvert = OOGLNewNE(short, vect->nvec, "vect vert counts");
122 	memcpy(vect->vnvert, vectcounts, vect->nvec*sizeof(*vect->vnvert));
123       } else {
124 	vect->vnvert = vectcounts;
125       }
126       break;
127 
128     case CR_COLRC:
129       colorcounts = va_arg (*a_list, short *);
130       if (colorcounts == NULL) {
131 	vect->vncolor = NULL;
132 	vect->nvert = 0;
133       } else if (copy) {
134 	vect->vncolor = OOGLNewNE(short, vect->nvec, "vect vert counts");
135 	memcpy(vect->vncolor, colorcounts, vect->nvec*sizeof(*vect->vncolor));
136       } else {
137 	vect->vncolor = colorcounts;
138       }
139       break;
140 
141     case CR_POINT:
142       v3 = va_arg (*a_list, Point3 *);
143       if (v3 == NULL) {
144 	vect->p = NULL;
145 	vect->nvert = 0;
146       } else if (copy) {
147 	vect->p = OOGLNewNE(HPoint3, vect->nvert, "vect points");
148 	Pt3ToPt4(v3, vect->p, vect->nvert);
149       } else {
150 	Pt3ToPt4(v3, vect->p, vect->nvert);
151       }
152       break;
153 
154     case CR_POINT4:
155       v4 = va_arg (*a_list, HPoint3 *);
156       if (v4 == NULL) {
157 	vect->p = NULL;
158 	vect->nvert = 0;
159       } else if (copy) {
160 	vect->p = OOGLNewNE(HPoint3, vect->nvert, "vect points");
161 	memcpy(vect->p, v4, vect->nvert*sizeof(HPoint3));
162       } else {
163 	vect->p = v4;
164       }
165       break;
166 
167     case CR_COLOR:
168       colors = va_arg (*a_list, ColorA *);
169       if (colors == NULL) {
170 	vect->c = NULL;
171 	vect->ncolor = 0;
172       } else if (copy) {
173 	vect->c = OOGLNewNE(ColorA, vect->ncolor, "vect colors");
174 	memcpy(vect->c, colors, vect->ncolor*sizeof(ColorA));
175       } else {
176 	vect->c = colors;
177       }
178       break;
179 
180     default:
181       if (GeomDecorate (s, &copy, attr, a_list)) {
182 	OOGLError (0, "VectCreate: Undefined option: %d\n", attr);
183 	OOGLFree (vect);
184 	return NULL;
185       }
186     }
187 
188 
189   if (!SkelSane(s)) {
190     OOGLError (0, "SkelCreate: Bogus data supplied");
191     GeomDelete((Geom *)s);
192     return NULL;
193   }	/* end police work */
194 
195   if (exist != NULL) return exist;
196 #endif
197 
198   return s;
199 }
200 
SkelSane(Skel * s)201 int SkelSane(Skel *s)
202 {
203   int i;
204   Skline *l;
205 
206   if (s == NULL || s->vi==NULL || s->p==NULL || s->nlines < 0 ||
207      s->nvert < 0 || s->nc < 0 || (s->nc>0 && s->c==NULL))
208     return 0;
209   for (i = s->nlines, l = s->l; --i >= 0; ) {
210     if (l->v0 < 0 || l->nv < 0 || l->nv + l->v0 > s->nvi)
211       return 0;
212     if (l->nc < 0 || l->c0 < 0 || l->c0 + l->nc > s->nc)
213       return 0;
214   }
215   for (i = 0; i < s->nvi; i++)
216     if ((unsigned)s->vi[i] >= (unsigned)s->nvi)
217       return 0;
218   return 1;
219 }
220