Add pointer to parent library to cells, implement first draft of cell size/shape preview

This commit is contained in:
Mario Hüttel 2019-02-27 21:30:41 +01:00
parent bce47f11fc
commit 2e1cf456c7
6 changed files with 81 additions and 9 deletions

View File

@ -58,7 +58,7 @@
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */ #define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
#if GDS_PRINT_DEBUG_INFOS #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 #else
#define GDS_INF(fmt, ...) #define GDS_INF(fmt, ...)
#endif #endif
@ -303,6 +303,7 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
cell->child_cells = NULL; cell->child_cells = NULL;
cell->graphic_objs = NULL; cell->graphic_objs = NULL;
cell->name[0] = 0; cell->name[0] = 0;
cell->parent_library = NULL;
} else } else
return NULL; return NULL;
/* return cell */ /* return cell */
@ -614,12 +615,20 @@ int parse_gds_from_file(const char *filename, GList **library_list)
GDS_INF("Leaving Library\n"); GDS_INF("Leaving Library\n");
break; break;
case BGNSTR: 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, &current_cell); current_lib->cells = append_cell(current_lib->cells, &current_cell);
if (current_lib->cells == NULL) { if (current_lib->cells == NULL) {
GDS_ERROR("Allocating memory failed"); GDS_ERROR("Allocating memory failed");
run = -3; run = -3;
break; break;
} }
current_cell->parent_library = current_lib;
GDS_INF("Entering Cell\n"); GDS_INF("Entering Cell\n");
break; break;
case ENDSTR: 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 */ /* 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); read = fread(workbuff, sizeof(char), rec_data_length, gds_file);

View File

@ -104,6 +104,7 @@ struct gds_cell {
struct gds_time_field access_time; struct gds_time_field access_time;
GList *child_cells; /**< @brief List of #gds_cell_instance elements */ GList *child_cells; /**< @brief List of #gds_cell_instance elements */
GList *graphic_objs; /**< @brief List of #gds_graphics */ GList *graphic_objs; /**< @brief List of #gds_graphics */
struct gds_library *parent_library; /**< @brief Pointer to parent library */
}; };
/** /**

View File

@ -230,7 +230,8 @@ static void on_convert_clicked(gpointer button, gpointer user)
GtkFileFilter *filter; GtkFileFilter *filter;
gint res; gint res;
char *file_name; char *file_name;
union bounding_box *cell_box; union bounding_box cell_box;
double height, width;
/* Get selected cell */ /* Get selected cell */
selection = gtk_tree_view_get_selection(data->tree_view); 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(); layer_list = export_rendered_layer_info();
/* Calculate cell size in DB units */ /* 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 */ /* Show settings dialog */
settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window)); settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window));
renderer_settings_dialog_set_settings(settings, &sett); 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)); res = gtk_dialog_run(GTK_DIALOG(settings));
if (res == GTK_RESPONSE_OK) { if (res == GTK_RESPONSE_OK) {
renderer_settings_dialog_get_settings(settings, &sett); renderer_settings_dialog_get_settings(settings, &sett);

View File

@ -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); 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) 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); 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);
}
} }
/** @} */ /** @} */

View File

@ -32,6 +32,7 @@
#define _BOUNDING_BOX_H_ #define _BOUNDING_BOX_H_
#include <glib.h> #include <glib.h>
#include "vector-operations.h" #include "vector-operations.h"
#include <stdbool.h>
union bounding_box { union bounding_box {
/** Coordinate System is (y up | x right) */ /** 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_update_box(union bounding_box *destination, union bounding_box *update);
void bounding_box_prepare_empty(union bounding_box *box); 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_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_ */ #endif /* _BOUNDING_BOX_H_ */

View File

@ -24,6 +24,7 @@
*/ */
#include "cell-trigonometrics.h" #include "cell-trigonometrics.h"
#include <math.h>
/** /**
* @addtogroup trigonometric * @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. * Please be aware if paths are the outmost elements of your cell.
* You might end up with a completely wrong calculated cell size. * 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,
&current_box);
break; break;
default: default:
/* Unknown graphics object. */ /* 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 */ /* Recursion Woohoo!! This dies if your GDS is faulty and contains a reference loop */
calculate_cell_bounding_box(&temp_box, sub_cell->cell_ref); 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);
} }
} }