Skip to content

Commit f6c65d9

Browse files
committed
Merge branch 'dev'
2 parents ac87caf + d43bec2 commit f6c65d9

5 files changed

Lines changed: 121 additions & 15 deletions

File tree

command-line.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ int command_line_convert_gds(const char *gds_name,
155155
LayerSettings *layer_sett;
156156
GdsOutputRenderer *current_renderer;
157157

158+
const struct gds_library_parsing_opts gds_parsing_options = {
159+
.simplified_polygons = 1,
160+
};
161+
158162
/* Check if parameters are valid */
159163
if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) {
160164
printf(_("Probably missing argument. Check --help option\n"));
@@ -173,7 +177,7 @@ int command_line_convert_gds(const char *gds_name,
173177

174178
/* Load GDS */
175179
clear_lib_list(&libs);
176-
res = parse_gds_from_file(gds_name, &libs);
180+
res = parse_gds_from_file(gds_name, &libs, &gds_parsing_options);
177181
if (res)
178182
goto ret_destroy_library_list;
179183

gds-render-gui.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ static void on_load_gds(gpointer button, gpointer user)
278278
char *filename;
279279
unsigned int cell_error_level;
280280

281+
const struct gds_library_parsing_opts gds_parsing_options = {
282+
.simplified_polygons = 1,
283+
};
284+
281285
self = RENDERER_GUI(user);
282286
if (!self)
283287
return;
@@ -307,7 +311,7 @@ static void on_load_gds(gpointer button, gpointer user)
307311
clear_lib_list(&self->gds_libraries);
308312

309313
/* Parse new GDSII file */
310-
gds_result = parse_gds_from_file(filename, &self->gds_libraries);
314+
gds_result = parse_gds_from_file(filename, &self->gds_libraries, &gds_parsing_options);
311315

312316
/* Delete file name afterwards */
313317
g_free(filename);

gds-utils/gds-parser.c

Lines changed: 100 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ static uint16_t gds_convert_unsigned_int16(const char *data)
266266
* @param library_ptr Return of newly created library.
267267
* @return Newly created list pointer
268268
*/
269-
static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
269+
static GList *append_library(GList *curr_list, const struct gds_library_parsing_opts *opts,
270+
struct gds_library **library_ptr)
270271
{
271272
struct gds_library *lib;
272273

@@ -276,6 +277,8 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
276277
lib->name[0] = 0;
277278
lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten
278279
lib->cell_names = NULL;
280+
/* Copy the settings into the library */
281+
memcpy(&lib->parsing_opts, opts, sizeof(struct gds_library_parsing_opts));
279282
} else
280283
return NULL;
281284
if (library_ptr)
@@ -488,20 +491,102 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
488491
}
489492

490493
/**
491-
* @brief Scans cell references inside cell
492-
This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance
494+
* @brief Simplify graphics objects
495+
* @param graphics gfx struct
496+
* @param user_data GDS library
497+
*/
498+
static void simplify_graphics(gpointer graphics, gpointer user_data)
499+
{
500+
struct gds_graphics *gfx;
501+
const struct gds_point *first_vertex = NULL;
502+
const struct gds_point *prev_vertex = NULL;
503+
const struct gds_point *current_vertex;
504+
GList *vertex_iter;
505+
GList *next_iter;
506+
(void)user_data;
507+
size_t processed_count = 0U;
508+
size_t removed_count = 0U;
509+
510+
gfx = (struct gds_graphics *)graphics;
511+
if (gfx->gfx_type == GRAPHIC_POLYGON) {
512+
GDS_INF("\t\t\tPolygon found\n");
513+
514+
/* Loop over all vertices */
515+
for (vertex_iter = gfx->vertices; vertex_iter;) {
516+
current_vertex = (const struct gds_point *)vertex_iter->data;
517+
next_iter = g_list_next(vertex_iter);
518+
processed_count++;
519+
520+
if (vertex_iter == gfx->vertices) {
521+
/* This is the first vertex */
522+
first_vertex = current_vertex;
523+
prev_vertex = NULL;
524+
}
525+
526+
if (prev_vertex) {
527+
if (current_vertex->x == prev_vertex->x && current_vertex->y == prev_vertex->y) {
528+
/* Vertex is the same as the previous one */
529+
GDS_INF("\t\t\t\tDuplicate vertex (%d,%d). Removing...\n",
530+
current_vertex->x, current_vertex->y);
531+
532+
/* Delete the current one from the list */
533+
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
534+
535+
/* Free the data */
536+
if (vertex_iter->data)
537+
free(vertex_iter->data);
538+
vertex_iter->data = NULL;
539+
g_list_free_1(vertex_iter);
540+
removed_count++;
541+
} else if (!g_list_next(vertex_iter)) {
542+
/* This is the last element in the list */
543+
if (current_vertex->x == first_vertex->x &&
544+
current_vertex->y == first_vertex->y) {
545+
GDS_INF("\t\t\t\tLast vertex is identical to first vertex (%d,%d). Removing\n",
546+
current_vertex->x, current_vertex->y);
547+
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
548+
if (vertex_iter->data)
549+
free(vertex_iter->data);
550+
g_list_free_1(vertex_iter);
551+
removed_count++;
552+
} else {
553+
GDS_WARN("First vertex is not coincident with first vertex, although the GDS file format specifies this. However, this is not a problem.");
554+
}
555+
}
556+
}
557+
558+
vertex_iter = next_iter;
559+
prev_vertex = current_vertex;
560+
}
561+
GDS_INF("\t\t\tProcessed %zu vertices. %zu removed.\n", processed_count, removed_count);
562+
}
563+
}
564+
565+
/**
566+
* @brief Scans cell and resolves references and simplifies polygons
567+
* This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance
568+
*
493569
* @param gcell pointer cast of #gds_cell *
494570
* @param library Library where the cell references are searched in
495571
*/
496-
static void scan_cell_reference_dependencies(gpointer gcell, gpointer library)
572+
static void scan_cell_references_and_polygons(gpointer gcell, gpointer library)
497573
{
498574
struct gds_cell *cell = (struct gds_cell *)gcell;
575+
struct gds_library *my_lib = (struct gds_library *)library;
576+
int simplify_polygons;
499577

500-
GDS_INF("\tScanning cell: %s\n", cell->name);
578+
simplify_polygons = my_lib->parsing_opts.simplified_polygons;
501579

580+
GDS_INF("\tScanning cell: %s\n", cell->name);
581+
GDS_INF("\t\tCell references\n");
502582
/* Scan all library references */
503583
g_list_foreach(cell->child_cells, parse_reference_list, library);
504584

585+
586+
GDS_INF("\t\tSimplifying Polygons%s\n", simplify_polygons ? "" : ": skipped");
587+
if (simplify_polygons) {
588+
g_list_foreach(cell->graphic_objs, simplify_graphics, library);
589+
}
505590
}
506591

507592
/**
@@ -517,7 +602,7 @@ static void scan_library_references(gpointer library_list_item, gpointer user)
517602
(void)user;
518603

519604
GDS_INF("Scanning Library: %s\n", lib->name);
520-
g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib);
605+
g_list_foreach(lib->cells, scan_cell_references_and_polygons, lib);
521606
}
522607

523608
/**
@@ -617,7 +702,8 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
617702
GDS_INF("Converted AREF to SREFs\n");
618703
}
619704

620-
int parse_gds_from_file(const char *filename, GList **library_list)
705+
int parse_gds_from_file(const char *filename, GList **library_list,
706+
const struct gds_library_parsing_opts *parsing_options)
621707
{
622708
char *workbuff;
623709
int read;
@@ -697,7 +783,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
697783
/* if begin: Allocate structures */
698784
switch (rec_type) {
699785
case BGNLIB:
700-
lib_list = append_library(lib_list, &current_lib);
786+
lib_list = append_library(lib_list, parsing_options, &current_lib);
701787
if (lib_list == NULL) {
702788
GDS_ERROR("Allocating memory failed");
703789
run = -3;
@@ -771,7 +857,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
771857
run = -4;
772858
break;
773859
}
774-
GDS_INF("\tEntering boundary/Box\n");
860+
GDS_INF("\tEntering boundary of type %s\n", rec_type==BOUNDARY ? "polygon" : "box");
775861
break;
776862
case SREF:
777863
if (current_cell == NULL) {
@@ -806,7 +892,9 @@ int parse_gds_from_file(const char *filename, GList **library_list)
806892
break;
807893
case ENDEL:
808894
if (current_graphics != NULL) {
809-
GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path"));
895+
GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary"
896+
: (current_graphics->gfx_type == GRAPHIC_PATH ? "path"
897+
: "box")));
810898
current_graphics = NULL;
811899
}
812900
if (current_s_reference != NULL) {
@@ -825,11 +913,11 @@ int parse_gds_from_file(const char *filename, GList **library_list)
825913

826914
} else if (current_s_reference) {
827915
if (rec_data_length != 8) {
828-
GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!");
916+
GDS_WARN("Instance has weird coordinates. Rendered output might be wrong!");
829917
}
830918
} else if (current_a_reference) {
831919
if (rec_data_length != (3*(4+4)))
832-
GDS_WARN("Array instance has weird coordinates. Rendered output might be screwed!");
920+
GDS_WARN("Array instance has weird coordinates. Rendered output might be wrong!");
833921
}
834922
break;
835923
case AREF:

include/gds-render/gds-utils/gds-parser.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@
4848
*
4949
* @param[in] filename Path to the GDS file
5050
* @param[in,out] library_array GList Pointer.
51+
* @param[in] parsing_options Parsing options.
5152
* @return 0 if successful
5253
*/
53-
int parse_gds_from_file(const char *filename, GList **library_array);
54+
int parse_gds_from_file(const char *filename, GList **library_array,
55+
const struct gds_library_parsing_opts *parsing_options);
5456

5557
/**
5658
* @brief Deletes all libraries including cells, references etc.

include/gds-render/gds-utils/gds-types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,21 @@ struct gds_cell {
129129
struct gds_cell_checks checks; /**< @brief Checking results */
130130
};
131131

132+
/**
133+
* @brief Options, hwo this liobrary was parsed.
134+
*/
135+
struct gds_library_parsing_opts {
136+
int simplified_polygons; /**< @brief Polygons have been simplified. Coincident end point removed. */
137+
};
138+
132139
/**
133140
* @brief GDS Toplevel library
134141
*/
135142
struct gds_library {
136143
char name[CELL_NAME_MAX];
137144
struct gds_time_field mod_time;
138145
struct gds_time_field access_time;
146+
struct gds_library_parsing_opts parsing_opts;
139147
double unit_in_meters; /**< Length of a database unit in meters */
140148
GList *cells; /**< List of #gds_cell that contains all cells in this library*/
141149
GList *cell_names /**< List of strings that contains all cell names */;

0 commit comments

Comments
 (0)