int main(int argc, char *argv[]) { gerbv_image_t *workingImage; /* create a new, blank, image */ workingImage = gerbv_create_image(NULL, NULL); /* draw the nose */ gerbv_image_create_line_object (workingImage, 1.5, 1.5, 1.6, 1.3, 0.020, GERBV_APTYPE_CIRCLE); gerbv_image_create_line_object (workingImage, 1.5, 1.5, 1.4, 1.3, 0.020, GERBV_APTYPE_CIRCLE); gerbv_image_create_line_object (workingImage, 1.4, 1.3, 1.6, 1.3, 0.020, GERBV_APTYPE_CIRCLE); /* draw the eyes */ gerbv_image_create_arc_object (workingImage, 1, 2, 0.1, 0, 360, 0.020, GERBV_APTYPE_CIRCLE); gerbv_image_create_arc_object (workingImage, 2, 2, 0.1, 0, 360, 0.020, GERBV_APTYPE_CIRCLE); /* draw the mouth */ gerbv_image_create_arc_object (workingImage, 1.5, 1.5, 0.75, -30, -150, 0.20, GERBV_APTYPE_CIRCLE); /* draw the head */ gerbv_image_create_arc_object (workingImage, 1.5, 1.5, 1.5, 0, 360, 0.02, GERBV_APTYPE_CIRCLE); /* draw the ears */ gerbv_image_create_rectangle_object (workingImage, -0.2, 1.3, 0.2, 0.4); gerbv_image_create_rectangle_object (workingImage, 3, 1.3, 0.2, 0.4); /* export the drawn image to a new rs274x file */ gerbv_export_rs274x_file_from_image ("example5-output.gbx", workingImage, NULL); /* destroy all created structures */ gerbv_destroy_image (workingImage); return 0; }
gerbv_image_t * gerbv_image_duplicate_image (gerbv_image_t *sourceImage, gerbv_user_transformation_t *transform) { gerbv_image_t *newImage = gerbv_create_image(NULL, sourceImage->info->type); int i; int lastUsedApertureNumber = APERTURE_MIN - 1; GArray *apertureNumberTable = g_array_new(FALSE,FALSE,sizeof(gerb_translation_entry_t)); newImage->layertype = sourceImage->layertype; /* copy information layer over */ *(newImage->info) = *(sourceImage->info); newImage->info->name = g_strdup (sourceImage->info->name); newImage->info->type = g_strdup (sourceImage->info->type); newImage->info->plotterFilm = g_strdup (sourceImage->info->plotterFilm); newImage->info->attr_list = gerbv_attribute_dup (sourceImage->info->attr_list, sourceImage->info->n_attr); /* copy apertures over, compressing all the numbers down for a cleaner output, and moving and apertures less than 10 up to the correct range */ for (i = 0; i < APERTURE_MAX; i++) { if (sourceImage->aperture[i] != NULL) { gerbv_aperture_t *newAperture = gerbv_image_duplicate_aperture (sourceImage->aperture[i]); lastUsedApertureNumber = gerbv_image_find_unused_aperture_number (lastUsedApertureNumber + 1, newImage); /* store the aperture numbers (new and old) in the translation table */ gerb_translation_entry_t translationEntry={i,lastUsedApertureNumber}; g_array_append_val (apertureNumberTable,translationEntry); newImage->aperture[lastUsedApertureNumber] = newAperture; } } /* step through all nets and create new layers and states on the fly, since we really don't have any other way to figure out where states and layers are used */ gerbv_image_copy_all_nets (sourceImage, newImage, newImage->layers, newImage->states, NULL, transform, apertureNumberTable); g_array_free (apertureNumberTable, TRUE); return newImage; }
/* ------------------------------------------------------------------ * pick_and_place_convert_pnp_data_to_image * ------------------------------------------------------------------ * Description: Render a parsedPickAndPlaceData array into a gerb_image. * Notes: * ------------------------------------------------------------------ */ gerbv_image_t * pick_and_place_convert_pnp_data_to_image(GArray *parsedPickAndPlaceData, gint boardSide) { gerbv_image_t *image = NULL; gerbv_net_t *curr_net = NULL; int i; gerbv_transf_t *tr_rot = gerb_transf_new(); gerbv_drill_stats_t *stats; /* Eventually replace with pick_place_stats */ gboolean foundElement = FALSE; /* step through and make sure we have an element on the layer before we actually create a new image for it and fill it */ for (i = 0; i < parsedPickAndPlaceData->len; i++) { PnpPartData partData = g_array_index(parsedPickAndPlaceData, PnpPartData, i); if ((boardSide == 0) && !((partData.layer[0]=='b') || (partData.layer[0]=='B'))) continue; if ((boardSide == 1) && !((partData.layer[0]=='t') || (partData.layer[0]=='T'))) continue; foundElement = TRUE; } if (!foundElement) return NULL; image = gerbv_create_image(image, "Pick and Place (X-Y) File"); if (image == NULL) { GERB_FATAL_ERROR(_("malloc image failed\n")); } image->format = (gerbv_format_t *)g_malloc(sizeof(gerbv_format_t)); if (image->format == NULL) { GERB_FATAL_ERROR(_("malloc format failed\n")); } memset((void *)image->format, 0, sizeof(gerbv_format_t)); image->layertype = GERBV_LAYERTYPE_PICKANDPLACE; stats = gerbv_drill_stats_new(); if (stats == NULL) GERB_FATAL_ERROR(_("malloc pick_place_stats failed\n")); image->drill_stats = stats; curr_net = image->netlist; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); image->info->min_x = HUGE_VAL; image->info->min_y = HUGE_VAL; image->info->max_x = -HUGE_VAL; image->info->max_y = -HUGE_VAL; image->aperture[0] = (gerbv_aperture_t *)g_malloc(sizeof(gerbv_aperture_t)); memset((void *) image->aperture[0], 0, sizeof(gerbv_aperture_t)); image->aperture[0]->type = GERBV_APTYPE_CIRCLE; image->aperture[0]->amacro = NULL; image->aperture[0]->parameter[0] = 0.01; image->aperture[0]->nuf_parameters = 1; for (i = 0; i < parsedPickAndPlaceData->len; i++) { PnpPartData partData = g_array_index(parsedPickAndPlaceData, PnpPartData, i); float radius,labelOffset; curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); curr_net->layer = image->layers; curr_net->state = image->states; if ((partData.rotation > 89) && (partData.rotation < 91)) labelOffset = fabs(partData.length/2); else if ((partData.rotation > 179) && (partData.rotation < 181)) labelOffset = fabs(partData.width/2); else if ((partData.rotation > 269) && (partData.rotation < 271)) labelOffset = fabs(partData.length/2); else if ((partData.rotation > -91) && (partData.rotation < -89)) labelOffset = fabs(partData.length/2); else if ((partData.rotation > -181) && (partData.rotation < -179)) labelOffset = fabs(partData.width/2); else if ((partData.rotation > -271) && (partData.rotation < -269)) labelOffset = fabs(partData.length/2); else labelOffset = fabs(partData.width/2); partData.rotation *= M_PI/180; /* convert deg to rad */ /* check if the entry is on the specified layer */ if ((boardSide == 0) && !((partData.layer[0]=='b') || (partData.layer[0]=='B'))) continue; if ((boardSide == 1) && !((partData.layer[0]=='t') || (partData.layer[0]=='T'))) continue; /* this first net is just a label holder, so calculate the lower left location to line up above the element */ curr_net->start_x = curr_net->stop_x = partData.mid_x; curr_net->start_y = curr_net->stop_y = partData.mid_y + labelOffset + 0.01; curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_OFF; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); /* assign a label to this first draw primitive, in case we want * to render some text next to the mark */ if (strlen (partData.designator) > 0) { curr_net->label = g_string_new (partData.designator); } gerb_transf_reset(tr_rot); gerb_transf_shift(tr_rot, partData.mid_x, partData.mid_y); gerb_transf_rotate(tr_rot, -partData.rotation); if ((partData.shape == PART_SHAPE_RECTANGLE) || (partData.shape == PART_SHAPE_STD)) { // TODO: draw rectangle length x width taking into account rotation or pad x,y curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); gerb_transf_apply(partData.length/2, partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(-partData.length/2, partData.width/2, tr_rot, &curr_net->stop_x, &curr_net->stop_y); curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); gerb_transf_apply(-partData.length/2, partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(-partData.length/2, -partData.width/2, tr_rot, &curr_net->stop_x, &curr_net->stop_y); curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); gerb_transf_apply(-partData.length/2, -partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(partData.length/2, -partData.width/2, tr_rot, &curr_net->stop_x, &curr_net->stop_y); curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); gerb_transf_apply(partData.length/2, -partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(partData.length/2, partData.width/2, tr_rot, &curr_net->stop_x, &curr_net->stop_y); curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); if (partData.shape == PART_SHAPE_RECTANGLE) { gerb_transf_apply(partData.length/4, -partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(partData.length/4, partData.width/2, tr_rot, &curr_net->stop_x, &curr_net->stop_y); } else { gerb_transf_apply(partData.length/4, partData.width/2, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(partData.length/4, partData.width/4, tr_rot, &curr_net->stop_x, &curr_net->stop_y); curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); gerb_transf_apply(partData.length/2, partData.width/4, tr_rot, &curr_net->start_x, &curr_net->start_y); gerb_transf_apply(partData.length/4, partData.width/4, tr_rot, &curr_net->stop_x, &curr_net->stop_y); } curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); /* calculate a rough radius for the min/max screen calcs later */ radius = max (partData.length/2, partData.width/2); } else { gdouble tmp_x,tmp_y; curr_net->start_x = partData.mid_x; curr_net->start_y = partData.mid_y; gerb_transf_apply( partData.pad_x - partData.mid_x, partData.pad_y - partData.mid_y, tr_rot, &tmp_x, &tmp_y); curr_net->stop_x = tmp_x; curr_net->stop_y = tmp_y; curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_LINEARx1; curr_net->layer = image->layers; curr_net->state = image->states; curr_net->next = (gerbv_net_t *)g_malloc(sizeof(gerbv_net_t)); curr_net = curr_net->next; assert(curr_net); memset((void *)curr_net, 0, sizeof(gerbv_net_t)); curr_net->start_x = partData.mid_x; curr_net->start_y = partData.mid_y; curr_net->stop_x = partData.pad_x; curr_net->stop_y = partData.pad_y; curr_net->aperture = 0; curr_net->aperture_state = GERBV_APERTURE_STATE_ON; curr_net->interpolation = GERBV_INTERPOLATION_CW_CIRCULAR; curr_net->layer = image->layers; curr_net->state = image->states; pick_and_place_reset_bounding_box (curr_net); curr_net->cirseg = g_new0 (gerbv_cirseg_t,1); curr_net->cirseg->angle1 = 0.0; curr_net->cirseg->angle2 = 360.0; curr_net->cirseg->cp_x = partData.mid_x; curr_net->cirseg->cp_y = partData.mid_y; radius = sqrt((partData.pad_x-partData.mid_x)*(partData.pad_x-partData.mid_x) + (partData.pad_y-partData.mid_y)*(partData.pad_y-partData.mid_y)); if (radius < 0.001) radius = 0.1; curr_net->cirseg->width = 2*radius; /* fabs(pad_x-mid_x) */ curr_net->cirseg->height = 2*radius; } /* * update min and max numbers so the screen zoom-to-fit *function will work */ image->info->min_x = min(image->info->min_x, (partData.mid_x - radius - 0.02)); image->info->min_y = min(image->info->min_y, (partData.mid_y - radius - 0.02)); image->info->max_x = max(image->info->max_x, (partData.mid_x + radius + 0.02)); image->info->max_y = max(image->info->max_y, (partData.mid_y + radius + 0.02)); } curr_net->next = NULL; gerb_transf_free(tr_rot); return image; } /* pick_and_place_convert_pnp_data_to_image */