From 2e1cf456c7969f2e83db390a39435b46de18d46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 27 Feb 2019 21:30:41 +0100 Subject: [PATCH] Add pointer to parent library to cells, implement first draft of cell size/shape preview --- gds-parser/gds-parser.c | 13 +++++++-- gds-parser/gds-types.h | 1 + main-window.c | 12 +++++++- trigonometric/bounding-box.c | 44 +++++++++++++++++++++++++++-- trigonometric/bounding-box.h | 4 ++- trigonometric/cell-trigonometrics.c | 16 +++++++++-- 6 files changed, 81 insertions(+), 9 deletions(-) diff --git a/gds-parser/gds-parser.c b/gds-parser/gds-parser.c index 0c56ddb..e6ef61b 100644 --- a/gds-parser/gds-parser.c +++ b/gds-parser/gds-parser.c @@ -58,7 +58,7 @@ #define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */ #if GDS_PRINT_DEBUG_INFOS - #define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But cna be disabled in code */ + #define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But can be disabled in code */ #else #define GDS_INF(fmt, ...) #endif @@ -303,6 +303,7 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr) cell->child_cells = NULL; cell->graphic_objs = NULL; cell->name[0] = 0; + cell->parent_library = NULL; } else return NULL; /* return cell */ @@ -614,12 +615,20 @@ int parse_gds_from_file(const char *filename, GList **library_list) GDS_INF("Leaving Library\n"); break; case BGNSTR: + if (current_lib == NULL) { + GDS_ERROR("Defining Cell outside of library!\n"); + run = -4; + break; + } current_lib->cells = append_cell(current_lib->cells, ¤t_cell); if (current_lib->cells == NULL) { GDS_ERROR("Allocating memory failed"); run = -3; break; } + + current_cell->parent_library = current_lib; + GDS_INF("Entering Cell\n"); break; case ENDSTR: @@ -726,7 +735,7 @@ int parse_gds_from_file(const char *filename, GList **library_list) /* No Data -> No Processing, go back to top */ - if (!rec_data_length) continue; + if (!rec_data_length || run != 1) continue; read = fread(workbuff, sizeof(char), rec_data_length, gds_file); diff --git a/gds-parser/gds-types.h b/gds-parser/gds-types.h index 1fce5b8..80e2acc 100644 --- a/gds-parser/gds-types.h +++ b/gds-parser/gds-types.h @@ -104,6 +104,7 @@ struct gds_cell { struct gds_time_field access_time; GList *child_cells; /**< @brief List of #gds_cell_instance elements */ GList *graphic_objs; /**< @brief List of #gds_graphics */ + struct gds_library *parent_library; /**< @brief Pointer to parent library */ }; /** diff --git a/main-window.c b/main-window.c index 6874daf..a5328bf 100644 --- a/main-window.c +++ b/main-window.c @@ -230,7 +230,8 @@ static void on_convert_clicked(gpointer button, gpointer user) GtkFileFilter *filter; gint res; char *file_name; - union bounding_box *cell_box; + union bounding_box cell_box; + double height, width; /* Get selected cell */ selection = gtk_tree_view_get_selection(data->tree_view); @@ -246,10 +247,19 @@ static void on_convert_clicked(gpointer button, gpointer user) layer_list = export_rendered_layer_info(); /* Calculate cell size in DB units */ + bounding_box_prepare_empty(&cell_box); + calculate_cell_bounding_box(&cell_box, cell_to_render); + + /* Calculate size in meters */ + height = (cell_box.vectors.upper_right.y - cell_box.vectors.lower_left.y) * cell_to_render->parent_library->unit_in_meters; + width = (cell_box.vectors.upper_right.x - cell_box.vectors.lower_left.x) * cell_to_render->parent_library->unit_in_meters; /* Show settings dialog */ settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window)); renderer_settings_dialog_set_settings(settings, &sett); + renderer_settings_dialog_set_cell_height(settings, height); + renderer_settings_dialog_set_cell_width(settings, width); + res = gtk_dialog_run(GTK_DIALOG(settings)); if (res == GTK_RESPONSE_OK) { renderer_settings_dialog_get_settings(settings, &sett); diff --git a/trigonometric/bounding-box.c b/trigonometric/bounding-box.c index db13baa..80811dd 100644 --- a/trigonometric/bounding-box.c +++ b/trigonometric/bounding-box.c @@ -133,9 +133,32 @@ static void calculate_path_miter_points(struct vector_2d *a, struct vector_2d *b vector_2d_subtract(m2, m2, &v_vec); } -void bounding_box_calculate_path_box(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box) +void bounding_box_calculate_path_box(GList *vertices, double thickness, + conv_generic_to_vector_2d_t conv_func, union bounding_box *box) { - printf("Error! Function bounding_box_calculate_path_box not yet implemented!\n"); + GList *vertex_iterator; + struct vector_2d pt; + + printf("Warning! Function bounding_box_calculate_path_box not yet implemented correctly!\n"); + + if (!vertices || !box) + return; + + for (vertex_iterator = vertices; vertex_iterator != NULL; vertex_iterator = g_list_next(vertex_iterator)) { + + if (conv_func != NULL) + conv_func(vertex_iterator->data, &pt); + else + (void)vector_2d_copy(&pt, (struct vector_2d *)vertex_iterator->data); + + /* These are approximations. + * Used as long as miter point calculation is not fully implemented + */ + box->vectors.lower_left.x = MIN(box->vectors.lower_left.x, pt.x - thickness/2); + box->vectors.lower_left.y = MIN(box->vectors.lower_left.y, pt.y - thickness/2); + box->vectors.upper_right.x = MAX(box->vectors.upper_right.x, pt.x + thickness/2); + box->vectors.upper_right.y = MAX(box->vectors.upper_right.y, pt.y + thickness/2); + } } void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt) @@ -157,9 +180,24 @@ void bounding_box_update_point(union bounding_box *destination, conv_generic_to_ destination->vectors.upper_right.y = MAX(destination->vectors.upper_right.y, point.y); } -void bounding_box_apply_transform(double scale, double rotation, union bounding_box *box) +/** + * @brief bounding_box_apply_transform + * @param scale scaling factor + * @param rotation roation of bounding box around the origin in degrees (counterclockwise) + * @param box bounding box the operations should be applied to + */ +void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box) { + int i; + /* Due to linearity, the order of the operations does not matter. + * flip must be applied before rotation as defined by the GDS format + */ + for (i = 0; i < 2; i++) { + box->vector_array[i].y *= (flip_at_x ? -1 : 1); + vector_2d_rotate(&box->vector_array[i], rotation_deg * M_PI / 180); + vector_2d_scale(&box->vector_array[i], scale); + } } /** @} */ diff --git a/trigonometric/bounding-box.h b/trigonometric/bounding-box.h index e1f733d..12f883d 100644 --- a/trigonometric/bounding-box.h +++ b/trigonometric/bounding-box.h @@ -32,6 +32,7 @@ #define _BOUNDING_BOX_H_ #include #include "vector-operations.h" +#include union bounding_box { /** Coordinate System is (y up | x right) */ @@ -48,7 +49,8 @@ void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t void bounding_box_update_box(union bounding_box *destination, union bounding_box *update); void bounding_box_prepare_empty(union bounding_box *box); void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt); -void bounding_box_apply_transform(double scale, double rotation, union bounding_box *box); +void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box); +void bounding_box_calculate_path_box(GList *vertices, double thickness, conv_generic_to_vector_2d_t conv_func, union bounding_box *box); #endif /* _BOUNDING_BOX_H_ */ diff --git a/trigonometric/cell-trigonometrics.c b/trigonometric/cell-trigonometrics.c index 4254b43..4466bc7 100644 --- a/trigonometric/cell-trigonometrics.c +++ b/trigonometric/cell-trigonometrics.c @@ -24,6 +24,7 @@ */ #include "cell-trigonometrics.h" +#include /** * @addtogroup trigonometric @@ -61,7 +62,9 @@ static void update_box_with_gfx(union bounding_box *box, struct gds_graphics *gf * Please be aware if paths are the outmost elements of your cell. * You might end up with a completely wrong calculated cell size. */ - /* Okay.. You're right. It is not implemented at all. ;P */ + bounding_box_calculate_path_box(gfx->vertices, gfx->width_absolute, + (conv_generic_to_vector_2d_t)&convert_gds_point_to_2d_vector, + ¤t_box); break; default: /* Unknown graphics object. */ @@ -97,8 +100,17 @@ void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell) /* Recursion Woohoo!! This dies if your GDS is faulty and contains a reference loop */ calculate_cell_bounding_box(&temp_box, sub_cell->cell_ref); - /* TODO: Apply transformations! */ + /* Apply transformations */ + bounding_box_apply_transform(ABS(sub_cell->magnification), sub_cell->angle, sub_cell->flipped, &temp_box); + /* Move bounding box to origin */ + temp_box.vectors.lower_left.x += sub_cell->origin.x; + temp_box.vectors.lower_left.x += sub_cell->origin.x; + temp_box.vectors.upper_right.y += sub_cell->origin.y; + temp_box.vectors.upper_right.y += sub_cell->origin.y; + + /* update the parent's box */ + bounding_box_update_box(box, &temp_box); } }