export-rs274x.c

Go to the documentation of this file.
00001 /*
00002  * gEDA - GNU Electronic Design Automation
00003  * This file is a part of gerbv.
00004  *
00005  *   Copyright (C) 2008 Julian Lamb
00006  *
00007  * $Id$
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
00022  */
00023 
00030 #ifdef HAVE_CONFIG_H
00031 #include "config.h"
00032 #endif
00033 
00034 #include <glib.h>
00035 #include <math.h>
00036 
00037 #include <glib/gstdio.h>
00038 #include "gerbv.h"
00039 #include "draw-gdk.h"
00040 
00041 /* DEBUG printing.  #define DEBUG 1 in config.h to use this fcn. */
00042 #define dprintf if(DEBUG) printf
00043 #define round(x) floor(x+0.5)
00044 
00045 void
00046 export_rs274x_write_macro (FILE *fd, gerbv_aperture_t *currentAperture,
00047                      gint apertureNumber) {
00048        gerbv_simplified_amacro_t *ls = currentAperture->simplified;
00049 
00050        /* write the macro portion first */
00051        fprintf(fd, "%%AMMACRO%d*\n",apertureNumber);
00052        while (ls != NULL) {
00053               if (ls->type == GERBV_APTYPE_MACRO_CIRCLE) {
00054                      fprintf(fd, "1,%d,%f,%f,%f*\n",(int) ls->parameter[CIRCLE_EXPOSURE],
00055                             ls->parameter[CIRCLE_DIAMETER],ls->parameter[CIRCLE_CENTER_X],
00056                             ls->parameter[CIRCLE_CENTER_Y]);
00057               }
00058               else if (ls->type == GERBV_APTYPE_MACRO_OUTLINE) {
00059                      int pointCounter;
00060                      int numberOfPoints = (int) ls->parameter[OUTLINE_NUMBER_OF_POINTS];
00061                      
00062                      fprintf(fd, "4,%d,%d,\n",(int) ls->parameter[OUTLINE_EXPOSURE],
00063                             numberOfPoints);
00064                      
00065                      for (pointCounter=0; pointCounter < numberOfPoints; pointCounter++) {
00066                          fprintf(fd, "%f,%f,",ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X],
00067                                       ls->parameter[pointCounter * 2 + OUTLINE_FIRST_Y]);
00068                      }
00069                      fprintf(fd, "%f*\n",ls->parameter[pointCounter * 2 + OUTLINE_FIRST_X]);
00070               }
00071               else if (ls->type == GERBV_APTYPE_MACRO_POLYGON) {
00072                      fprintf(fd, "5,%d,%d,%f,%f,%f,%f*\n",(int) ls->parameter[POLYGON_EXPOSURE],
00073                             (int) ls->parameter[POLYGON_NUMBER_OF_POINTS],
00074                             ls->parameter[POLYGON_CENTER_X],ls->parameter[POLYGON_CENTER_Y],
00075                             ls->parameter[POLYGON_DIAMETER],ls->parameter[POLYGON_ROTATION]);
00076               }
00077               else if (ls->type == GERBV_APTYPE_MACRO_MOIRE) {
00078                      fprintf(fd, "6,%f,%f,%f,%f,%f,%d,%f,%f,%f*\n",ls->parameter[MOIRE_CENTER_X],
00079                             ls->parameter[MOIRE_CENTER_Y],ls->parameter[MOIRE_OUTSIDE_DIAMETER],
00080                             ls->parameter[MOIRE_CIRCLE_THICKNESS],ls->parameter[MOIRE_GAP_WIDTH],
00081                             (int) ls->parameter[MOIRE_NUMBER_OF_CIRCLES],ls->parameter[MOIRE_CROSSHAIR_THICKNESS],
00082                             ls->parameter[MOIRE_CROSSHAIR_LENGTH],ls->parameter[MOIRE_ROTATION]);
00083               }
00084               else if (ls->type == GERBV_APTYPE_MACRO_THERMAL) {
00085                      fprintf(fd, "7,%f,%f,%f,%f,%f,%f*\n",ls->parameter[THERMAL_CENTER_X],
00086                             ls->parameter[THERMAL_CENTER_Y],ls->parameter[THERMAL_OUTSIDE_DIAMETER],
00087                             ls->parameter[THERMAL_INSIDE_DIAMETER],ls->parameter[THERMAL_CROSSHAIR_THICKNESS],
00088                             ls->parameter[THERMAL_ROTATION]);
00089               }
00090               else if (ls->type == GERBV_APTYPE_MACRO_LINE20) {
00091                      fprintf(fd, "20,%d,%f,%f,%f,%f,%f,%f*\n",(int) ls->parameter[LINE20_EXPOSURE],
00092                             ls->parameter[LINE20_LINE_WIDTH],ls->parameter[LINE20_START_X],
00093                             ls->parameter[LINE20_START_Y],ls->parameter[LINE20_END_X],
00094                             ls->parameter[LINE20_END_Y],ls->parameter[LINE20_ROTATION]);
00095               }
00096               else if (ls->type == GERBV_APTYPE_MACRO_LINE21) {
00097                      fprintf(fd, "21,%d,%f,%f,%f,%f,%f*\n",(int) ls->parameter[LINE21_EXPOSURE],
00098                             ls->parameter[LINE21_WIDTH],ls->parameter[LINE21_HEIGHT],
00099                             ls->parameter[LINE21_CENTER_X],ls->parameter[LINE21_CENTER_Y],
00100                             ls->parameter[LINE21_ROTATION]);
00101               }
00102               else if (ls->type == GERBV_APTYPE_MACRO_LINE22) {
00103                      fprintf(fd, "22,%d,%f,%f,%f,%f,%f*\n",(int) ls->parameter[LINE22_EXPOSURE],
00104                             ls->parameter[LINE22_WIDTH],ls->parameter[LINE22_HEIGHT],
00105                             ls->parameter[LINE22_LOWER_LEFT_X],ls->parameter[LINE22_LOWER_LEFT_Y],
00106                             ls->parameter[LINE22_ROTATION]);
00107               }
00108               ls = ls->next;
00109        }
00110        fprintf(fd, "%%\n");
00111        /* and finally create an aperture definition to use the macro */
00112        fprintf(fd, "%%ADD%dMACRO%d*%%\n",apertureNumber,apertureNumber);
00113 }
00114 
00115 void
00116 export_rs274x_write_apertures (FILE *fd, gerbv_image_t *image) {
00117        gerbv_aperture_t *currentAperture;
00118        gint numberOfRequiredParameters=0,numberOfOptionalParameters=0,i,j;
00119               
00120        for (i=APERTURE_MIN; i<APERTURE_MAX; i++) {
00121               gboolean writeAperture=TRUE;
00122               
00123               currentAperture = image->aperture[i];
00124               
00125               if (!currentAperture)
00126                      continue;
00127               
00128               switch (currentAperture->type) {
00129                      case GERBV_APTYPE_CIRCLE:
00130                             fprintf(fd, "%%ADD%d",i);
00131                             fprintf(fd, "C,");
00132                             numberOfRequiredParameters = 1;
00133                             numberOfOptionalParameters = 2;
00134                             break;
00135                      case GERBV_APTYPE_RECTANGLE:
00136                             fprintf(fd, "%%ADD%d",i);
00137                             fprintf(fd, "R,");
00138                             numberOfRequiredParameters = 2;
00139                             numberOfOptionalParameters = 2;
00140                             break;
00141                      case GERBV_APTYPE_OVAL:
00142                             fprintf(fd, "%%ADD%d",i);
00143                             fprintf(fd, "O,");
00144                             numberOfRequiredParameters = 2;
00145                             numberOfOptionalParameters = 2;
00146                             break;
00147                      case GERBV_APTYPE_POLYGON:
00148                             fprintf(fd, "%%ADD%d",i);
00149                             fprintf(fd, "P,");
00150                             numberOfRequiredParameters = 2;
00151                             numberOfOptionalParameters = 3;
00152                             break;
00153                      case GERBV_APTYPE_MACRO:
00154                             export_rs274x_write_macro (fd, currentAperture, i);
00155                             writeAperture=FALSE;
00156                             break;
00157                      default:
00158                             writeAperture=FALSE;
00159                             break;
00160               }
00161               if (writeAperture) {
00162                      /* write the parameter list */
00163                      for (j=0; j<(numberOfRequiredParameters + numberOfOptionalParameters); j++) {
00164                             if ((j < numberOfRequiredParameters) || (currentAperture->parameter[j] != 0)) {
00165                                    /* print the "X" character to separate the parameters */
00166                                    if (j>0)
00167                                           fprintf(fd, "X");
00168                                    fprintf(fd, "%.4f",currentAperture->parameter[j]);
00169                             }
00170                      }
00171                      fprintf(fd, "*%%\n");
00172               }
00173        }
00174 }
00175 
00176 void
00177 export_rs274x_write_layer_change (gerbv_layer_t *oldLayer, gerbv_layer_t *newLayer, FILE *fd) {
00178        if (oldLayer->polarity != newLayer->polarity) {
00179               /* polarity changed */
00180               if ((newLayer->polarity == GERBV_POLARITY_CLEAR))
00181                      fprintf(fd, "%%LPC*%%\n");
00182               else
00183                      fprintf(fd, "%%LPD*%%\n");
00184        }
00185 }
00186 
00187 void
00188 export_rs274x_write_state_change (gerbv_netstate_t *oldState, gerbv_netstate_t *newState, FILE *fd) {
00189 
00190 
00191 }
00192 
00193 gboolean
00194 gerbv_export_rs274x_file_from_image (gchar *filename, gerbv_image_t *image) {
00195        FILE *fd;
00196        gerbv_netstate_t *oldState;
00197        gerbv_layer_t *oldLayer;
00198        gboolean insidePolygon=FALSE;
00199        
00200        if ((fd = g_fopen(filename, "w")) == NULL) {
00201               GERB_MESSAGE("Can't open file for writing: %s\n", filename);
00202               return FALSE;
00203        }
00204        /* write header info */
00205        fprintf(fd, "G04 This is an RS-274x file exported by *\n");
00206        fprintf(fd, "G04 gerbv version %s *\n",VERSION);
00207        fprintf(fd, "G04 More information is available about gerbv at *\n");
00208        fprintf(fd, "G04 http://gerbv.sourceforge.net/ *\n");
00209        fprintf(fd, "G04 --Header info--*\n");
00210        fprintf(fd, "%%MOIN*%%\n");
00211        fprintf(fd, "%%FSLAX23Y23*%%\n");
00212        
00213        /* check the image info struct for any non-default settings */
00214        /* image offset */
00215        if ((image->info->offsetA > 0.0) || (image->info->offsetB > 0.0))
00216               fprintf(fd, "%%IOA%fB%f*%%\n",image->info->offsetA,image->info->offsetB);
00217        /* image polarity */
00218        if (image->info->polarity == GERBV_POLARITY_CLEAR)
00219               fprintf(fd, "%%IPNEG*%%\n");
00220        else
00221               fprintf(fd, "%%IPPOS*%%\n");
00222        /* image name */
00223        if (image->info->name)
00224               fprintf(fd, "%%IN%s*%%\n",image->info->name);
00225        /* plotter film */
00226        if (image->info->plotterFilm)
00227               fprintf(fd, "%%PF%s*%%\n",image->info->plotterFilm);
00228        /* image rotation */
00229        if (image->info->imageRotation != 0.0)
00230               fprintf(fd, "%%IR%d*%%\n",(int) image->info->imageRotation);
00231        if ((image->info->imageJustifyTypeA != GERBV_JUSTIFY_NOJUSTIFY) ||
00232               (image->info->imageJustifyTypeB != GERBV_JUSTIFY_NOJUSTIFY)) {
00233               fprintf(fd, "%%IJA");
00234               if (image->info->imageJustifyTypeA == GERBV_JUSTIFY_CENTERJUSTIFY)
00235                      fprintf(fd, "C");
00236               else 
00237                      fprintf(fd, "%.4f",image->info->imageJustifyOffsetA);
00238               fprintf(fd, "B");
00239               if (image->info->imageJustifyTypeB == GERBV_JUSTIFY_CENTERJUSTIFY)
00240                      fprintf(fd, "C");
00241               else 
00242                      fprintf(fd, "%.4f",image->info->imageJustifyOffsetB);
00243               fprintf(fd, "*%%\n");
00244 
00245        }
00246        /* define all apertures */
00247        fprintf(fd, "G04 --Define apertures--*\n");
00248        export_rs274x_write_apertures (fd, image);
00249        
00250        /* write rest of image */
00251        fprintf(fd, "G04 --Start main section--*\n");
00252        gint currentAperture = 0;
00253        gerbv_net_t *currentNet;
00254        
00255        oldLayer = image->layers;
00256        oldState = image->states;
00257        /* skip the first net, since it's always zero due to the way we parse things */
00258        for (currentNet = image->netlist->next; currentNet; currentNet = currentNet->next){
00259               /* check for "layer" changes (RS274X commands) */
00260               if (currentNet->layer != oldLayer)
00261                      export_rs274x_write_layer_change (oldLayer, currentNet->layer, fd);
00262               
00263               /* check for new "netstate" (more RS274X commands) */
00264               if (currentNet->state != oldState)
00265                      export_rs274x_write_state_change (oldState, currentNet->state, fd);
00266               
00267               /* check for tool changes */
00268               /* also, make sure the aperture number is a valid one, since sometimes
00269                  the loaded file may refer to invalid apertures */
00270               if ((currentNet->aperture != currentAperture)&&
00271                      (image->aperture[currentNet->aperture] != NULL)) {
00272                      fprintf(fd, "G54D%02d*\n",currentNet->aperture);
00273                      currentAperture = currentNet->aperture;
00274               }
00275               
00276               oldLayer = currentNet->layer;
00277               oldState = currentNet->state;
00278               
00279               long xVal,yVal,endX,endY,centerX,centerY;
00280               switch (currentNet->interpolation) {
00281                      case GERBV_INTERPOLATION_x10 :
00282                      case GERBV_INTERPOLATION_LINEARx01 :
00283                      case GERBV_INTERPOLATION_LINEARx001 :
00284                      case GERBV_INTERPOLATION_LINEARx1 :
00285                             /* see if we need to write an "aperture off" line to get
00286                                the pen to the right start point */
00287                             if ((!insidePolygon) && (currentNet->aperture_state == GERBV_APERTURE_STATE_ON)) {
00288                                    xVal = (long) round(currentNet->start_x * 1000.0);
00289                                    yVal = (long) round(currentNet->start_y * 1000.0);
00290                                    fprintf(fd, "G01X%05ldY%05ldD02*\n",xVal,yVal);
00291                             }
00292                             xVal = (long) round(currentNet->stop_x * 1000.0);
00293                             yVal = (long) round(currentNet->stop_y * 1000.0);
00294                             fprintf(fd, "G01X%05ldY%05ld",xVal,yVal);
00295                             /* and finally, write the esposure value */
00296                             if (currentNet->aperture_state == GERBV_APERTURE_STATE_OFF)
00297                                    fprintf(fd, "D02*\n");
00298                             else if (currentNet->aperture_state == GERBV_APERTURE_STATE_ON)
00299                                    fprintf(fd, "D01*\n");
00300                             else
00301                                    fprintf(fd, "D03*\n");
00302                             break;
00303                      case GERBV_INTERPOLATION_CW_CIRCULAR :
00304                      case GERBV_INTERPOLATION_CCW_CIRCULAR :
00305                             /* see if we need to write an "aperture off" line to get
00306                                the pen to the right start point */
00307                             if ((!insidePolygon) && (currentNet->aperture_state == GERBV_APERTURE_STATE_ON)) {
00308                                    xVal = (long) round(currentNet->start_x * 1000.0);
00309                                    yVal = (long) round(currentNet->start_y * 1000.0);
00310                                    fprintf(fd, "G01X%05ldY%05ldD02*\n",xVal,yVal);
00311                             }
00312                             centerX= (long) round((currentNet->cirseg->cp_x - currentNet->start_x) * 1000.0);
00313                             centerY= (long) round((currentNet->cirseg->cp_y - currentNet->start_y) * 1000.0);
00314                             endX = (long) round(currentNet->stop_x * 1000.0);
00315                             endY = (long) round(currentNet->stop_y * 1000.0);
00316                             
00317                             /* always use multi-quadrant, since it's much easier to export */
00318                             /*  and most all software should support it */
00319                             fprintf(fd, "G75*\n");
00320                             /* figure out clockwise or c-clockwise */
00321                             if (currentNet->cirseg->angle2 > currentNet->cirseg->angle1)
00322                                    fprintf(fd, "G03");
00323                             else
00324                                    fprintf(fd, "G02");
00325                             /* don't write the I and J values if the exposure is off */
00326                             if (currentNet->aperture_state == GERBV_APERTURE_STATE_ON)
00327                                    fprintf(fd, "X%05ldY%05ldI%05ldJ%05ld",endX,endY,centerX,centerY);
00328                             else
00329                                    fprintf(fd, "X%05ldY%05ld",endX,endY);
00330                             /* and finally, write the esposure value */
00331                             if (currentNet->aperture_state == GERBV_APERTURE_STATE_OFF)
00332                                    fprintf(fd, "D02*\n");
00333                             else if (currentNet->aperture_state == GERBV_APERTURE_STATE_ON)
00334                                    fprintf(fd, "D01*\n");
00335                             else
00336                                    fprintf(fd, "D03*\n");
00337                             break;
00338                      case GERBV_INTERPOLATION_PAREA_START:
00339                             fprintf(fd, "G36*\n");
00340                             insidePolygon = TRUE;
00341                             break;
00342                      case GERBV_INTERPOLATION_PAREA_END:
00343                             fprintf(fd, "G37*\n");
00344                             insidePolygon = FALSE;
00345                             break;
00346                      default:
00347                             break;
00348               }
00349        }
00350        
00351        /* write footer */
00352        fprintf(fd, "G04 --Footer info--*\n");
00353        fprintf(fd, "M02*\n");
00354 
00355        fclose(fd);
00356        return TRUE;
00357 }

Generated on Tue Aug 19 00:14:48 2008 for gerbv by  doxygen 1.5.6