1 /*
2 * gdsreader - simple Calma parser/printer tool
3 * Copyright (C) 1999 Serban-Mihai Popescu, serbanp@ix.netcom.com
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23
24 #include <GDSstructs.h>
25 #include <GDSconsts.h>
26 #include <GDSaux.h>
27 #include <GDSreader.h>
28 #include <GDSboundary.h>
29 #include <GDSpath.h>
30 #include <GDSsref.h>
31 #include <GDSaref.h>
32 #include <GDStext.h>
33 #include <GDStext.h>
34 #include <GDSnode.h>
35 #include <GDSbox.h>
36 #include <GDSstruct.h>
37 #include <GDStransf.h>
38 #include <GDSparser.h>
39 /*
40 static char
41 *PSInit[] =
42 {
43
44 };
45 */
46
47
48 extern PSStyle psStyles[];
49 extern int howmanylayers; /* set by GDSinitPSStyles(cfgfileptr); in GDStoPS.c */
50
51
52 /*
53 Layer to style... Map layer to style number using best find.
54 all layers have gdsno and datatype, not all styles have datatype
55 Ugh... What about layers that have no entry in config file? Damn.
56 We need to return a number for a style that is hidden. I will make
57 a dummy [0] style with a neg gds number which will always be present.
58
59 Ugh. That also means I have to modify the GDStoPS and GDStoHPGL
60 converters to ignore entry zero. Damn, this code sucks.
61
62 */
layer_to_style_no(layer * layerptr)63 int layer_to_style_no(layer *layerptr)
64 {
65 int i,generic=-1;
66 for(i=0;i<howmanylayers;i++) {
67 if (psStyles[i].gdsno==layerptr->layerno && psStyles[i].dataspec
68 && psStyles[i].datatype==layerptr->datatype)
69 {
70 return(i); /* Perfect Match */
71 }
72 if (psStyles[i].gdsno==layerptr->layerno && !(psStyles[i].dataspec)) generic=i;
73 }
74 if (generic!=-1) {
75 return(generic);
76 }
77 fprintf(stderr,"Warning: Layer %d, datatype %d found with no corresponding\n"
78 " layer entry in configuration file.\n",
79 layerptr->layerno,layerptr->datatype);
80 /* exit(1); */
81 return(0); /* Dummy hidden layer */
82 }
83
84
85
86
87 /* Returns true if any part of structure is visible, actually
88 returns number of items visible. Subitems count as one. */
is_visible(GDSstruct * structptr)89 int is_visible(GDSstruct *structptr)
90 {
91 layer *lp;
92 GDScell *cellptr;
93 int vis=0;
94 lp=structptr->layers;
95 while (lp!=NULL) {
96 if (!psStyles[layer_to_style_no(lp)].hidden) {
97 vis++;
98 }
99 lp=lp->next;
100 }
101 /* Now we must check srefs and arefs if they are present. */
102 cellptr=structptr->cells;
103 while (cellptr!=NULL) {
104 switch(cellptr->type)
105 {
106 case SREF:
107 if (is_visible(cellptr->detail.aref->strptr)) vis++;
108 break;
109 case AREF:
110 if (is_visible(cellptr->detail.sref->strptr)) vis++;
111 break;
112 default:
113 break;
114 }
115 cellptr=cellptr->next;
116 }
117 return(vis);
118 }
119
120 /* Dump a particular cell declaration to the file.
121 We need to see if any of the layers are visible first, also
122 check if only a single subcell VISIBLE, no union or braces....
123 note this is not topcellname here really... */
124 void
GDStoPOVCell(GDSlibrary * libptr,FILE * povfileptr,char * topcellname)125 GDStoPOVCell(GDSlibrary *libptr, FILE *povfileptr, char *topcellname)
126 {
127 GDSstruct *structptr;
128 GDScell *cellptr;
129 bbox bbx;
130 char *esctopcell=NULL;
131
132 double scalex, scaley, scale;
133 int i=0,subcells=0;
134
135
136 structptr = GDSgetStructByName(libptr, topcellname);
137 if(structptr == NULL)
138 {
139 fprintf(stderr, "Couldn't find the structure named \"%s\"\n",
140 topcellname);
141 return;
142 }
143 /* We should check to see if any of the layers in this cell are visible. If
144 not, then we should draw no structure(s)? */
145 /* Visibility check */
146
147 if (!(subcells=is_visible(structptr))) return;
148
149 bbx = GDSgetStructBBox(structptr);
150
151 scalex = 8.5 * InternalScaleFactor * 72.0 * 0.85 / (bbx.ur.x - bbx.ll.x);
152 scaley = 11.0 * InternalScaleFactor * 72.0 * 0.85 / (bbx.ur.y - bbx.ll.y);
153 fprintf(stderr, "scalex = %f, scaley = %f\n", scalex, scaley);
154 scale = (scalex < scaley) ? scalex : scaley;
155
156 /* Loop through any layers not invisible. */
157 esctopcell=GDSEscPovString(topcellname);
158 if (subcells>1) {
159 fprintf(povfileptr,"#declare %s = union {\n",esctopcell);
160 } else {
161 fprintf(povfileptr,"#declare %s = \n",esctopcell);
162 }
163
164 /* Loop through cells */
165 for(cellptr = structptr->cells; cellptr != NULL;
166 cellptr = cellptr->next)
167 {
168 switch(cellptr->type)
169 {
170 case BOUNDARY: /* All drawing is actually done here. */
171 if (!(psStyles[i=layer_to_style_no(cellptr->detail.boundary->layerptr)].hidden))
172 BoundaryToPOV(povfileptr, cellptr->detail.boundary,
173 psStyles[i]);
174 break;
175 case PATH:
176 if (!(psStyles[i=layer_to_style_no(cellptr->detail.path->layerptr)].hidden))
177 PathToPOV(povfileptr, cellptr->detail.path, psStyles[i]);
178 break;
179 case SREF:
180 if (is_visible(cellptr->detail.sref->strptr))
181 SrefToPOV(povfileptr, cellptr->detail.sref, &Ident, psStyles[i]);
182 break;
183 case AREF: /* calls sref for each element in the array */
184 fprintf(povfileptr,"//Aref:\n");
185 if (is_visible(cellptr->detail.aref->strptr))
186 ArefToPOV(povfileptr, cellptr->detail.aref, &Ident, psStyles[i]);
187 break;
188 case TEXT: /* does nothing in POV yet */
189 if (!psStyles[i=layer_to_style_no(cellptr->detail.text->layerptr)].hidden)
190 TextToPOV(povfileptr, cellptr->detail.text, &Ident, psStyles[i]);
191 break;
192 case NODE: /* does nothing? */
193 if (!psStyles[i=layer_to_style_no(cellptr->detail.node->layerptr)].hidden)
194 NodeToPOV(povfileptr, cellptr->detail.node, psStyles[i]);
195 break;
196 case BOX: /* does nothing? */
197 if (!psStyles[i=layer_to_style_no(cellptr->detail.box->layerptr)].hidden)
198 BoxToPOV(povfileptr, cellptr->detail.box, psStyles[i]);
199 break;
200 default:
201 break;
202 } /* switch */
203 } /* cell loop */
204 if (subcells>1) {
205 fprintf(povfileptr,"}\n");
206 } else {
207 fprintf(povfileptr,"\n");
208 }
209
210 FREE(esctopcell);
211 }
212
213
214
215 struct callorder {
216 char *name;
217 struct callorder *next;
218 } *callorderfirst=NULL;
219
220
221
222 /* Call with topcell, will descend heirarchy and create a call order */
223
POVStructsInOrder(GDSlibrary * libptr,char * cellname)224 void POVStructsInOrder(GDSlibrary *libptr,char *cellname)
225 {
226 GDSstruct *structptr;
227 GDScell *fcell;
228 struct callorder *cur,*pre;
229 structptr = GDSgetStructByName(libptr, cellname);
230 fcell=structptr->cells;
231 while (fcell!=NULL) {
232 if (fcell->type==SREF) {
233 POVStructsInOrder(libptr,fcell->detail.sref->refname);
234 }
235 if (fcell->type==AREF) {
236 POVStructsInOrder(libptr,fcell->detail.aref->refname);
237 }
238 fcell=fcell->next;
239 }
240 cur=callorderfirst;
241 pre=NULL;
242 while (cur!=NULL && strcmp(cellname,cur->name)!=0) {
243 pre=cur;
244 cur=cur->next;
245 }
246 if (cur==NULL) { /* Must add */
247 cur=(struct callorder *)MALLOC(sizeof(struct callorder));
248 cur->next=NULL;
249 cur->name=(char *)MALLOC(sizeof(char)*(strlen(cellname)+1));
250 strcpy(cur->name,cellname);
251 if (pre==NULL) callorderfirst=cur; else pre->next=cur;
252 }
253 }
254
255
256 void
GDStoPOV(GDSlibrary * libptr,char * povfile,char * topcellname)257 GDStoPOV(GDSlibrary *libptr, char *povfile, char *topcellname)
258 {
259 FILE *povfileptr;
260 GDSstruct *structptr;
261 struct callorder *cur;
262 bbox bbx;
263 char *esctopcell,*ts;
264 int i;
265
266 povfileptr = fopen(povfile, "w");
267
268 if(povfileptr == NULL)
269 {
270 fprintf(stderr, "Couldn't open %s for writing. Aborting...\n", povfile);
271 exit(1);
272 }
273
274 structptr = GDSgetStructByName(libptr, topcellname);
275 if(structptr == NULL)
276 {
277 fprintf(stderr, "Couldn't find the structure named \"%s\"\n",
278 topcellname);
279 fclose(povfileptr);
280 return;
281 }
282 bbx = GDSgetStructBBox(structptr);
283 esctopcell=GDSEscPovString(topcellname);
284 fprintf(povfileptr,
285 "// POVRAY file generated from gdsreader-0.3.1\n"
286 "// Top level cell is %s (or %s if escaping is needed.)\n"
287 "// Bounding box is (%d,%d)-(%d,%d)\n"
288 "// UserUnit: %e MeterUnit: %e \n"
289 "// Since thickness in the config is specified in microns,\n"
290 "// the instance of the final object will be vertically scaled\n"
291 "// by %e at the end of the file.\n\n"
292 // "#include \"colors.inc\"\n"
293 // "#include \"shapes.inc\"\n"
294 // "#include \"finish.inc\"\n"
295 // "#include \"glass.inc\"\n"
296 "camera {\n"
297 " location <%f,%f,%f>\n"
298 " look_at <%f,0,%f>\n"
299 "}\n"
300 "global_settings { ambient_light rgb <4.5,4.5,4.5> }\n"
301 "light_source { <%f,%f,%f> color rgb <1.0, 1.0, 1.0> }\n\n",
302 topcellname,esctopcell,
303 /* bbox of whole thing. */ bbx.ur.x,bbx.ur.y,bbx.ll.x,bbx.ll.y,
304 /* This is the units specified in the file: */ libptr->userunit,libptr->meterunit,
305 /* Scale vertically by: ----> */ 1.0e-6/libptr->meterunit,
306 /* Camera at a corner, height is x+y */
307 (double)bbx.ll.x, (double)abs(bbx.ur.x-bbx.ll.x)+abs(bbx.ur.y-bbx.ll.y) ,(double)bbx.ll.y,
308 /* Look at center of bounding box */
309 (bbx.ur.x+bbx.ll.x)/2.0,(bbx.ur.y+bbx.ll.y)/2.0,
310 /* Light source diagonally from camera, height same as camera */
311 (double)bbx.ur.x, (double) abs(bbx.ur.x-bbx.ll.x)+abs(bbx.ur.y-bbx.ll.y) ,(double)bbx.ll.y
312 );
313 /* fprintf(stderr,"Wrote POV Header.\n");
314 fflush(stderr); */
315 /* Time to go through the "how many layers" PSStyles and dump them */
316 for(i=0;i<howmanylayers;i++) if (!(psStyles[i].hidden)) {
317 /* Print out a layer description. */
318 fprintf(povfileptr,
319 "#declare %s = texture { // Layer name: %s \n"
320 " pigment {\n"
321 " color rgb <%f,%f,%f>\n"
322 " }\n"
323 " }\n",
324 ts=GDSpsStyleNoToTEXName(i),
325 psStyles[i].layername,
326 psStyles[i].edgecolor.r,
327 psStyles[i].edgecolor.g,
328 psStyles[i].edgecolor.b );
329 FREE(ts);
330 }
331 /* I need to find the cells, in the right order, and then dump them. */
332 POVStructsInOrder(libptr,topcellname);
333 cur=callorderfirst;
334 while (cur!=NULL) {
335 GDStoPOVCell(libptr, povfileptr, cur->name);
336 cur=cur->next;
337 }
338 fprintf(povfileptr, "object { %s scale <1.0,%f,1.0> }\n// end of povray file\n",esctopcell,1.0e-6/libptr->meterunit);
339 FREE(esctopcell);
340
341 /* x,z x,z */
342
343
344
345 fclose(povfileptr);
346 }
347