summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2019-10-18 21:46:50 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2019-10-18 21:46:50 +0200
commitf21f92c37f48bf1403b09188f087bb450d8c968a (patch)
treeefa7660a3e71807fde8092b3fdda3d3e090bfa9a
parent309522f5629ef97d41b2c4957c0e7d776f4d7e13 (diff)
parent0fd6ff7ea7c1cfb4f53b2f79e5afac228e283f0f (diff)
Update upstream source from tag 'upstream/0.2+ds.1'
Update to upstream version '0.2+ds.1' with Debian dir 365b45b27fd27ab4474ca2cd06935a64ab66979d
-rw-r--r--COPYRIGHT18
-rw-r--r--Makefile.am2
-rw-r--r--applications/DumpGDSIIFile.cc36
-rw-r--r--applications/DumpGDSIIRecords.cc47
-rw-r--r--applications/GDSII2GMSH.cc418
-rw-r--r--applications/GDSIIConvert.cc27
-rw-r--r--lib/Flatten.cc26
-rw-r--r--lib/ReadGDSIIFile.cc9
-rw-r--r--lib/libGDSII.cc5
-rw-r--r--lib/libGDSII.h24
10 files changed, 75 insertions, 537 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..bbaa3b9
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,18 @@
+/* Copyright (C) 2018 M. T. Homer Reid
+ *
+ * This file is part of LIBGDSII.
+ *
+ * LIBGDSII is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * LIBGDSII is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
diff --git a/Makefile.am b/Makefile.am
index f12cfd2..cf3853a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,3 +4,5 @@ AM_CFLAGS = -O3
AM_CXXFLAGS = -O3
SUBDIRS = lib applications examples
EXTRA_DIST = COPYRIGHT
+
+
diff --git a/applications/DumpGDSIIFile.cc b/applications/DumpGDSIIFile.cc
deleted file mode 100644
index 253f1f4..0000000
--- a/applications/DumpGDSIIFile.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2005-2017 Massachusetts Institute of Technology
-%
-% This program is free software; you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation; either version 2, or (at your option)
-% any later version.
-%
-% This program is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with this program; if not, write to the Free Software Foundation,
-% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/*
- * DumpGDSIIFile -- simple test/demo program for libGDSII library
- * -- for working with GDSII files
- * Homer Reid 11/2017
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <string>
-
-#include "libGDSII.h"
-#include "GDSIIOptions.h"
-
-int main(int argc, char *argv[])
-{
- GDSIIOptions *Options = ProcessGDSIIOptions(argc, argv);
-}
diff --git a/applications/DumpGDSIIRecords.cc b/applications/DumpGDSIIRecords.cc
deleted file mode 100644
index afd6c74..0000000
--- a/applications/DumpGDSIIRecords.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* Copyright (C) 2005-2017 Massachusetts Institute of Technology
-%
-% This program is free software; you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation; either version 2, or (at your option)
-% any later version.
-%
-% This program is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with this program; if not, write to the Free Software Foundation,
-% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/*
- * DumpGDSIIRecords -- utility for writing text descriptions
- * -- of data records in a GDS II file
- *
- * Homer Reid 11/2017
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string>
-
-#include "libGDSII.h"
-
-using namespace std;
-using namespace libGDSII;
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-int main(int argc, char *argv[])
-{
- if ( argc!=2 )
- { printf("usage: DumpGDSIIRecords File.gds\n");
- exit(1);
- };
-
- DumpGDSIIFile(argv[1]);
-}
diff --git a/applications/GDSII2GMSH.cc b/applications/GDSII2GMSH.cc
deleted file mode 100644
index e998659..0000000
--- a/applications/GDSII2GMSH.cc
+++ /dev/null
@@ -1,418 +0,0 @@
-/* Copyright (C) 2005-2017 Massachusetts Institute of Technology
-%
-% This program is free software; you can redistribute it and/or modify
-% it under the terms of the GNU General Public License as published by
-% the Free Software Foundation; either version 2, or (at your option)
-% any later version.
-%
-% This program is distributed in the hope that it will be useful,
-% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-% GNU General Public License for more details.
-%
-% You should have received a copy of the GNU General Public License
-% along with this program; if not, write to the Free Software Foundation,
-% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-/*
- * GDSII2GMSH.cc -- convert GDSII file to GMSH geometry file
- * Homer Reid 12/2017
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <math.h>
-#include <string>
-#include <sstream>
-
-#include "libGDSII.h"
-#include "GDSIIOptions.h"
-
-using namespace std;
-using namespace libGDSII;
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-typedef struct GTransform
- { double X0, Y0;
- double CosTheta, SinTheta;
- double Mag;
- bool Refl;
- } GTransform;
-
-typedef vector<GTransform> GTVec;
-
-void ApplyGTransform(GTransform GT, double X, double Y, double *XP, double *YP)
-{
- X *= GT.Mag;
- Y *= (GT.Refl ? -1.0 : 1.0)*GT.Mag;
- *XP = GT.X0 + GT.CosTheta*X - GT.SinTheta*Y;
- *YP = GT.Y0 + GT.SinTheta*X + GT.CosTheta*Y;
-}
-
-/***************************************************************/
-/* data structure that keeps track of the status of the GMSH */
-/* file output process */
-/***************************************************************/
-typedef struct StatusData
-{
- int NumNodes, NumLines, NumSurfaces, RefDepth;
- bool PPFormat;
- double UnitInMM, LayerThickness;
- string GeoFileName, PPFileName;
- FILE *GeoFile, *PPFile;
- int CurrentLayer;
- GTVec GTStack;
-} StatusData;
-
-void InitStatusData(StatusData *SD)
-{
- SD->NumNodes=0;
- SD->NumLines=0;
- SD->NumSurfaces=0;
- SD->RefDepth=0;
- SD->PPFormat=false;
- SD->UnitInMM=1.0;
- SD->LayerThickness=0.0;
- SD->GeoFile = 0;
- SD->PPFile = 0;
- SD->CurrentLayer = -1;
- SD->GTStack.clear();
-}
-
-void OpenGeoFile(StatusData *SD)
-{ if (SD->GeoFile) return;
- SD->GeoFile=fopen(SD->GeoFileName.c_str(),"w");
- if (!SD->GeoFile)
- GDSIIData::ErrExit("could not open file %s",SD->GeoFileName.c_str());
-}
-
-void OpenPPFile(StatusData *SD)
-{ if (SD->PPFile) return;
- SD->PPFile=fopen(SD->PPFileName.c_str(),"w");
- if (!SD->PPFile)
- GDSIIData::ErrExit("could not open file %s",SD->PPFileName.c_str());
-}
-
-void GetPhysicalXY(StatusData *SD, double X, double Y, double *pXP, double *pYP)
-{
- double XP=X, YP=Y;
- for(unsigned n=SD->GTStack.size(); n>0; n--)
- { ApplyGTransform(SD->GTStack[n-1],X,Y,&XP,&YP);
- X=XP;
- Y=YP;
- }
- *pXP = SD->UnitInMM * XP;
- *pYP = SD->UnitInMM * YP;
-}
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-void WriteBoundary(StatusData *SD, GDSIIData *Data, int ns, int ne)
-{
- GDSIIStruct *s = Data->Structs[ns];
- GDSIIElement *e = s->Elements[ne];
- vector<int> XY = e->XY;
- int NXY = XY.size() / 2;
-
- double Z0 = e->Layer * SD->LayerThickness;
- double Unit = SD->UnitInMM;
-
- if (SD->CurrentLayer!=-1 && SD->CurrentLayer!=e->Layer) return;
- OpenGeoFile(SD);
-
- fprintf(SD->GeoFile,"// Struct %s element #%i (boundary)\n",s->Name->c_str(),ne);
-
- int Node0=SD->NumNodes;
- for(int n=0; n<NXY-1; n++)
- { double X, Y;
- GetPhysicalXY(SD, XY[2*n+0], XY[2*n+1], &X, &Y);
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e};\n",++(SD->NumNodes),X,Y,Z0);
- }
-
- int Line0=SD->NumLines;
- for(int n=0; n<NXY-2; n++)
- fprintf(SD->GeoFile,"Line(%i)={%i,%i}; \n",++(SD->NumLines),Node0+1+n,Node0+n+2);
- fprintf(SD->GeoFile,"Line(%i)={%i,%i}; \n",++(SD->NumLines),Node0+NXY-1,Node0+1);
-
- fprintf(SD->GeoFile,"Line Loop(%i)={",(SD->NumSurfaces)++);
- for(int n=0; n<NXY-2; n++)
- fprintf(SD->GeoFile,"%i,",Line0+n+1);
- fprintf(SD->GeoFile,"%i};\n",Line0+NXY-1);
- fprintf(SD->GeoFile,"Plane Surface(%i)={%i};\n",SD->NumSurfaces-1,SD->NumSurfaces-1);
-
- //fprintf(SD->GeoFile,"Extrude{ 0, 0, %e } { Surface{%i}; }\n",LayerThickness,NumSurfaces-1);
- fprintf(SD->GeoFile,"\n");
-}
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-void WritePath(StatusData *SD, GDSIIData *Data, int ns, int ne)
-{
- GDSIIStruct *s = Data->Structs[ns];
- GDSIIElement *e = s->Elements[ne];
- vector<int> XY = e->XY;
- int NXY = XY.size() / 2;
-
- double Z0 = SD->LayerThickness;
- double Unit = SD->UnitInMM;
- double DeltaZ = 1.0*Unit;
- double W = e->Width*Unit;
-
- if (SD->CurrentLayer!=-1 && SD->CurrentLayer!=e->Layer) return;
- OpenGeoFile(SD);
-
- fprintf(SD->GeoFile,"// Struct %s element #%i (path)\n",s->Name->c_str(),ne);
-
- int Line0 = SD->NumLines;
-
- for(int n=0; n<NXY; n++)
- {
- // coordinates of center point
- double X1, Y1;
- GetPhysicalXY(SD, XY[2*n+0], XY[2*n+1], &X1, &Y1);
-
- if (W==0.0)
- {
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e}; \n",(SD->NumNodes)++,X1,Y1,Z0);
- if (n>0) fprintf(SD->GeoFile,"Line(%i)={%i,%i};\n",(SD->NumLines)++,SD->NumNodes-2,SD->NumNodes-1);
- }
- else if (n<(NXY-1))
- {
- int np1 = (n+1)%NXY;
- double X2, Y2;
- GetPhysicalXY(SD, XY[2*np1+0], XY[2*np1+1], &X2, &Y2);
-
- // unit vector in width direction
- double DX = X2-X1, DY=Y2-Y1, DNorm = sqrt(DX*DX + DY*DY);
- if (DNorm==0.0) DNorm=1.0;
- double XHat = +1.0*DY / DNorm;
- double YHat = -1.0*DX / DNorm;
-
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e};\n",SD->NumNodes++,X1-0.5*W*XHat,Y1-0.5*W*YHat,Z0);
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e};\n",SD->NumNodes++,X2-0.5*W*XHat,Y2-0.5*W*YHat,Z0);
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e};\n",SD->NumNodes++,X2+0.5*W*XHat,Y2+0.5*W*YHat,Z0);
- fprintf(SD->GeoFile,"Point(%i)={%e,%e,%e};\n",SD->NumNodes++,X1+0.5*W*XHat,Y1+0.5*W*YHat,Z0);
-
- fprintf(SD->GeoFile,"Line(%i)={%i,%i};\n",SD->NumLines++,SD->NumNodes-4,SD->NumNodes-3);
- fprintf(SD->GeoFile,"Line(%i)={%i,%i};\n",SD->NumLines++,SD->NumNodes-3,SD->NumNodes-2);
- fprintf(SD->GeoFile,"Line(%i)={%i,%i};\n",SD->NumLines++,SD->NumNodes-2,SD->NumNodes-1);
- fprintf(SD->GeoFile,"Line(%i)={%i,%i};\n",SD->NumLines++,SD->NumNodes-1,SD->NumNodes-4);
-
- if (n<(NXY-2)) continue;
-
- fprintf(SD->GeoFile,"Line Loop(%i)={",SD->NumSurfaces++);
- for(int m=0; m<NXY-2; m++)
- fprintf(SD->GeoFile,"%i,",Line0+m+1);
- fprintf(SD->GeoFile,"%i};\n",Line0+NXY-1);
- fprintf(SD->GeoFile,"Plane Surface(%i)={%i};\n",SD->NumSurfaces-1,SD->NumSurfaces-1);
- }
- }
-}
-
-void WriteStruct(StatusData *SD, GDSIIData *Data, int ns, bool ASRef=false);
-
-void WriteASRef(StatusData *SD, GDSIIData *Data, int ns, int ne)
-{
- SD->RefDepth++;
-
- GDSIIStruct *s = Data->Structs[ns];
- GDSIIElement *e = s->Elements[ne];
- vector<int> XY = e->XY;
-
- int nsRef = e->nsRef;
- if ( nsRef==-1 || nsRef>=((int)(Data->Structs.size())) )
- GDSIIData::ErrExit("structure %s, element %i: REF to unknown structure %s",s->Name,ne,e->SName);
-
- double Mag = (e->Type==SREF) ? e->Mag : 1.0;
- double Angle = (e->Type==SREF) ? e->Angle : 0.0;
- bool Refl = (e->Type==SREF) ? e->Refl : false;
-
- GTransform GT;
- GT.CosTheta=cos(Angle*M_PI/180.0);
- GT.SinTheta=sin(Angle*M_PI/180.0);
- GT.Mag=Mag;
- GT.Refl=Refl;
- SD->GTStack.push_back(GT);
- GTransform *CurrentTransform = &(SD->GTStack[SD->GTStack.size()-1]);
-
- double Unit = SD->UnitInMM;
-
- int NC=1, NR=1;
- double XYCenter[2], DeltaXYC[2]={0,0}, DeltaXYR[2]={0,0};
- XYCenter[0] = (double)XY[0];
- XYCenter[1] = (double)XY[1];
- if (e->Type == AREF)
- {
- NC = e->Columns;
- NR = e->Rows;
- DeltaXYC[0] = (XY[2] - XYCenter[0]) / NC;
- DeltaXYC[1] = (XY[3] - XYCenter[1]) / NC;
- DeltaXYR[0] = (XY[4] - XYCenter[0]) / NR;
- DeltaXYR[1] = (XY[5] - XYCenter[1]) / NR;
- }
-
- for(int nc=0; nc<NC; nc++)
- for(int nr=0; nr<NR; nr++)
- {
- CurrentTransform->X0 = XYCenter[0] + nc*DeltaXYC[0] + nr*DeltaXYR[0];
- CurrentTransform->Y0 = XYCenter[1] + nc*DeltaXYC[1] + nr*DeltaXYR[1];
- WriteStruct(SD, Data, nsRef, true);
- }
-
- SD->GTStack.pop_back();
- SD->RefDepth--;
-}
-
-void WriteText(StatusData *SD, GDSIIData *Data, int ns, int ne)
-{
- GDSIIStruct *s = Data->Structs[ns];
- GDSIIElement *e = s->Elements[ne];
- vector<int> XY = e->XY;
-
- if (SD->CurrentLayer!=-1 && SD->CurrentLayer!=e->Layer) return;
-
- double X, Y;
- GetPhysicalXY(SD, e->XY[0], e->XY[1], &X, &Y);
-
- double Z = e->Layer * SD->LayerThickness;
-
- OpenPPFile(SD);
- fprintf(SD->PPFile,"View \"Layer %i, TextType %i\" {\n",e->Layer,e->TextType);
- fprintf(SD->PPFile,"T3 (%e,%e,%e,0) {\"%s\"};\n",X,Y,Z,e->Text->c_str());
- fprintf(SD->PPFile,"};\n");
-
- // TODO handle magnigification and reflection
- if (e->Angle!=0.0)
- { double CosTheta=cos(e->Angle*M_PI/180.0);
- double SinTheta=sin(e->Angle*M_PI/180.0);
- fprintf(SD->PPFile,"v0=PostProcessing.NbViews-1;\n");
- fprintf(SD->PPFile,"View[v0].TransformXX=%e;\n",CosTheta);
- fprintf(SD->PPFile,"View[v0].TransformXY=%e;\n",-1.0*SinTheta);
- fprintf(SD->PPFile,"View[v0].TransformYX=%e;\n",1.0*SinTheta);
- fprintf(SD->PPFile,"View[v0].TransformYY=%e;\n",CosTheta);
- }
-}
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-void WriteElement(StatusData *SD, GDSIIData *Data, int ns, int ne)
-{
- GDSIIStruct *s = Data->Structs[ns];
- GDSIIElement *e = s->Elements[ne];
-
- switch(e->Type)
- {
- /*--------------------------------------------------------------*/
- /*--------------------------------------------------------------*/
- /*--------------------------------------------------------------*/
- case BOUNDARY:
- WriteBoundary(SD, Data, ns, ne);
- break;
-
- case PATH:
- WritePath(SD, Data, ns, ne);
- break;
-
- case SREF:
- case AREF:
- WriteASRef(SD, Data, ns, ne);
- break;
-
- case TEXT:
- WriteText(SD, Data, ns, ne);
- break;
-
- default:
- ; // all other element types ignored for now
- };
-}
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-void WriteStruct(StatusData *SD, GDSIIData *Data, int ns, bool ASRef)
-{
- GDSIIStruct *s=Data->Structs[ns];
-
- if (s->IsPCell) return;
- if (ASRef==false && s->IsReferenced) return;
-
- if (SD->PPFormat)
- fprintf(SD->GeoFile,"View \"{%s}\" {\n",s->Name->c_str());
-
- for(size_t ne=0; ne<s->Elements.size(); ne++)
- WriteElement(SD, Data, ns, ne);
-
- if (SD->PPFormat)
- fprintf(SD->GeoFile,"};\n");
-}
-
-/***************************************************************/
-/***************************************************************/
-/***************************************************************/
-int main(int argc, char *argv[])
-{
- /***************************************************************/
- /* parse command-line options **********************************/
- /***************************************************************/
- GDSIIOptions *Options = ProcessGDSIIOptions(argc, argv);
-
- GDSIIData *gdsIIData = Options->gdsIIData;
- Options->gdsIIData->WriteDescription();
-
- StatusData SD;
- InitStatusData(&SD);
-
- SD.UnitInMM = Options->UnitInMM * gdsIIData->UnitInMeters;
-
- if (Options->SeparateLayers)
- SD.LayerThickness=0.0;
- else
- SD.LayerThickness = SD.UnitInMM;
-
- string FileBase(Options->FileBase);
- SD.GeoFileName = FileBase + ".geo";
- SD.PPFileName = FileBase + ".pp";
-
- /***************************************************************/
- /***************************************************************/
- /***************************************************************/
- iVec LayerNames;
- EntityTable ETable = gdsIIData->Flatten(LayerNames);
- char FlatFileBase[100];
- snprintf(FlatFileBase,100,"%s.flat",FileBase.c_str());
- WriteGMSHFile(ETable, LayerNames, FlatFileBase, Options->SeparateLayers);
-
- /***************************************************************/
- /***************************************************************/
- /***************************************************************/
- int LList[1]={-1};
- set<int> LayersToWrite = (Options->SeparateLayers ? gdsIIData->Layers : set<int>(LList,LList+1));
- for(set<int>::iterator it=LayersToWrite.begin(); it!=LayersToWrite.end(); it++)
- { int Layer = SD.CurrentLayer = *it;
- char LayerStr[20]="";
- if (Layer!=-1) snprintf(LayerStr,20,".Layer%i",Layer);
- SD.GeoFileName = FileBase + LayerStr + ".geo";
- for(size_t ns=0; ns<gdsIIData->Structs.size(); ns++)
- WriteStruct(&SD,gdsIIData,ns,false);
- if (SD.GeoFile)
- { printf("Wrote GMSH geometry file %s.\n",SD.GeoFileName.c_str());
- fclose(SD.GeoFile);
- SD.GeoFile=0;
- }
- }
- if (SD.PPFile)
- { printf("Wrote GMSH post-processing file %s.\n",SD.PPFileName.c_str());
- fclose(SD.PPFile);
- }
- printf("Thank you for your support.\n");
-
-}
diff --git a/applications/GDSIIConvert.cc b/applications/GDSIIConvert.cc
index 8bf3af3..0335000 100644
--- a/applications/GDSIIConvert.cc
+++ b/applications/GDSIIConvert.cc
@@ -58,7 +58,7 @@ void Usage(const char *ErrorMessage, ...)
printf("\n");
printf(" ** Other flags: **\n");
printf(" --MetalLayer 12 define layer 12 as a metal layer (may be specified multiple times)\n");
- printf(" --LengthUnit xx set output length unit in mm (default = 1)\n");
+ printf(" --LengthUnit xx set output length unit in meters (default = 1e-6)\n");
printf(" --FileBase xx set base name for output files\n");
printf(" --verbose produce more output\n");
printf(" --SeparateLayers write separate output files for objects on each layer\n");
@@ -68,7 +68,7 @@ void Usage(const char *ErrorMessage, ...)
typedef struct GDSIIOptions
{ char *GDSIIFile;
bool Raw, Analyze, WriteGMSH, WritePorts;
- double UnitInMM;
+ double CoordinateLengthUnit;
char *FileBase;
bool Verbose;
bool SeparateLayers;
@@ -86,16 +86,16 @@ GDSIIOptions *ProcessGDSIIOptions(int argc, char *argv[])
/***************************************************************/
/* process command-line options *******************************/
/***************************************************************/
- GDSIIOptions *Options = new GDSIIOptions;
- Options->GDSIIFile = 0;
- Options->Raw = false;
- Options->Analyze = false;
- Options->WriteGMSH = false;
- Options->WritePorts = false;
- Options->UnitInMM = 1.0;
- Options->FileBase = 0;
- Options->Verbose = false;
- Options->SeparateLayers = false;
+ GDSIIOptions *Options = new GDSIIOptions;
+ Options->GDSIIFile = 0;
+ Options->Raw = false;
+ Options->Analyze = false;
+ Options->WriteGMSH = false;
+ Options->WritePorts = false;
+ Options->CoordinateLengthUnit = 1.0e-6;
+ Options->FileBase = 0;
+ Options->Verbose = false;
+ Options->SeparateLayers = false;
int narg=1;
for(; narg<argc; narg++)
@@ -142,7 +142,7 @@ GDSIIOptions *ProcessGDSIIOptions(int argc, char *argv[])
else if (!strcasecmp(argv[narg],"--LogFile"))
GDSIIData::LogFileName=strdup(argv[++narg]);
else if (!strcasecmp(argv[narg],"--LengthUnit"))
- sscanf(argv[++narg],"%le",&Options->UnitInMM);
+ sscanf(argv[++narg],"%le",&Options->CoordinateLengthUnit);
else if (!strcasecmp(argv[narg],"--MetalLayer"))
{ int nml; if (1==sscanf(argv[++narg],"%i",&nml)) Options->MetalLayers.push_back(nml);
}
@@ -441,7 +441,6 @@ n,MemBefore[n],MemDuring[n],MemAfter[n],MemAfter[n]-MemBefore[n]);
if (Options->WriteGMSH)
WriteGeometryAndPorts(gdsIIData, Options);
-
printf("Thank you for your support.\n");
}
diff --git a/lib/Flatten.cc b/lib/Flatten.cc
index 6a884c3..44a6bc7 100644
--- a/lib/Flatten.cc
+++ b/lib/Flatten.cc
@@ -62,15 +62,15 @@ static void ApplyGTransform(GTransform GT, double X, double Y, double *XP, doubl
/***************************************************************/
typedef struct StatusData
{ int CurrentLayer;
- double UnitInMM;
+ double IJ2XY; // scale factor converting GDSII integer-value vertex indices to real-valued coordinates in the chosen length units
EntityList EntitiesThisLayer;
GTVec GTStack;
int RefDepth;
} StatusData;
-static void InitStatusData(StatusData *SD)
+static void InitStatusData(StatusData *SD, double CoordinateLengthUnit, double PixelLengthUnit)
{ SD->CurrentLayer=-1;
- SD->UnitInMM = 1.0e-6;
+ SD->IJ2XY = PixelLengthUnit / CoordinateLengthUnit;
SD->RefDepth=0;
}
@@ -83,8 +83,8 @@ static void GetPhysicalXY(StatusData *SD, double X, double Y, double *pXP, doubl
X=XP;
Y=YP;
}
- *pXP = SD->UnitInMM * XP;
- *pYP = SD->UnitInMM * YP;
+ *pXP = SD->IJ2XY * XP;
+ *pYP = SD->IJ2XY * YP;
}
/***************************************************************/
@@ -128,8 +128,8 @@ void AddPath(StatusData *SD, GDSIIData *Data, int ns, int ne)
vector<int> IXY = e->XY;
int NXY = IXY.size() / 2;
- double Unit = SD->UnitInMM;
- double W = e->Width*Unit;
+ double IJ2XY = SD->IJ2XY;
+ double W = e->Width*IJ2XY;
Entity E;
E.Text = 0;
@@ -297,11 +297,17 @@ void AddStruct(StatusData *SD, GDSIIData *Data, int ns, bool ASRef)
/***************************************************************/
/***************************************************************/
/***************************************************************/
-void GDSIIData::Flatten(double UnitInMM)
+void GDSIIData::Flatten(double CoordinateLengthUnit)
{
+ if (CoordinateLengthUnit==0.0)
+ { CoordinateLengthUnit = 1.0e-6;
+ char *s=getenv("LIBGDSII_LENGTH_UNIT");
+ if (s && 1==sscanf(s,"%le",&CoordinateLengthUnit))
+ Log("Setting libGDSII length unit to %g meters.\n",CoordinateLengthUnit);
+ }
+
StatusData SD;
- InitStatusData(&SD);
- SD.UnitInMM = UnitInMM * this->UnitInMeters;
+ InitStatusData(&SD, CoordinateLengthUnit, FileUnits[1]);
for(size_t nl=0; nl<Layers.size(); nl++)
{ SD.CurrentLayer = Layers[nl];
diff --git a/lib/ReadGDSIIFile.cc b/lib/ReadGDSIIFile.cc
index dbfdd48..308b984 100644
--- a/lib/ReadGDSIIFile.cc
+++ b/lib/ReadGDSIIFile.cc
@@ -727,9 +727,10 @@ void InitializeParseState(ParseState *PState, GDSIIData *Data)
}
/*--------------------------------------------------------------*/
+/*- If CoordinateLengthUnit is nonzero, it sets the desired */
+/*- output unit (in meters) for vertex coordinates. */
/*--------------------------------------------------------------*/
-/*--------------------------------------------------------------*/
-void GDSIIData::ReadGDSIIFile(const string FileName)
+void GDSIIData::ReadGDSIIFile(const string FileName, double CoordinateLengthUnit)
{
ErrMsg=0;
@@ -789,9 +790,7 @@ void GDSIIData::ReadGDSIIFile(const string FileName)
/*- Flatten hierarchy to obtain simple unstructured lists */
/*- of polygons and text labels on each layer. */
/*--------------------------------------------------------------*/
- Flatten();
-
- //printf("Read %i data records from file %s.\n", PState.NumRecords,FileName.c_str());
+ Flatten(CoordinateLengthUnit);
}
/***************************************************************/
diff --git a/lib/libGDSII.cc b/lib/libGDSII.cc
index 8101f25..4cbd397 100644
--- a/lib/libGDSII.cc
+++ b/lib/libGDSII.cc
@@ -7,7 +7,7 @@
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
-% MERCHANTABILITY or FITNESS FOR A PARTICULAh PURPOSE. See the
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
@@ -40,8 +40,9 @@ GDSIIData::GDSIIData(const string FileName)
{
// initialize class data
LibName = 0;
+ FileUnits[0] = 1.0e-3; // these seem to be the default for GDSII files
+ FileUnits[1] = 1.0e-9;
UnitInMeters = 1.0e-6;
- FileUnits[0] = FileUnits[1]=0.0;
GDSIIFileName = new string(FileName);
ReadGDSIIFile(FileName);
diff --git a/lib/libGDSII.h b/lib/libGDSII.h
index d520c86..d30d7e7 100644
--- a/lib/libGDSII.h
+++ b/lib/libGDSII.h
@@ -65,10 +65,10 @@ typedef struct { char *Text; dVec XY; int Layer; } TextString;
typedef vector<TextString> TextStringList;
/***************************************************************/
-/* Data structures used to process GDSII files: */
+/* Data structures used to process GDSII files. */
/* (a) GDSIIElement and GDSIIStruct are used to store info */
/* on the geometry as described in the GDSII file, with */
-/* nesting hierarchy intact */
+/* nesting hierarchy intact. */
/* (b) Flattening the hierarchy (i.e. eliminating all SREFS */
/* and AREFS to instantiate all objects and text directly)*/
/* yields a table of Entity structures, organized by the */
@@ -78,7 +78,21 @@ typedef vector<TextString> TextStringList;
/* reference point/location). An EntityList is a */
/* collection of Entities, in no particular order, all on */
/* the same layer. An EntityTable is a collection of */
-/* (LayerIndex, EntityList) pairs. */
+/* (LayerIndex, EntityList) pairs. */
+/* */
+/* Note that, whereas GDSIIElements and GDSIIStructs */
+/* represent vertices as pairs of integers (multiples of */
+/* the GDSII database unit), Entities represent vertices */
+/* by pairs of doubles (real-valued, continuous physical */
+/* coordinates). The default length unit for the */
+/* coordinates of Entity vertices is 1 micron, but this */
+/* may be changed by specifying a nonzero value for the */
+/* CoordinateLengthUnit argument to Flatten(), or by */
+/* setting the environment variable LIBGDSII_LENGTH_UNIT, */
+/* to the desired length unit in meters (default=1e-6). */
+/* Thus, to output vertex coordinates in units of */
+/* millimeters, set LengthUnit or LIBGDSII_LENGTH_UNIT to */
+/* 1.0e-3. */
/***************************************************************/
enum ElementType { BOUNDARY, PATH, SREF, AREF, TEXT, NODE, BOX };
@@ -158,9 +172,9 @@ namespace libGDSII
/*--------------------------------------------------------*/
// private:
// constructor helper methods
- void ReadGDSIIFile(const std::string FileName);
+ void ReadGDSIIFile(const std::string FileName, double CoordinateLengthUnit=0.0);
int GetStructByName(std::string Name);
- void Flatten(double UnitInMM=1.0);
+ void Flatten(double CoordinateLengthUnit=0.0);
/*--------------------------------------------------------*/
/* variables intended for internal use */