2007-09-26 04:09:22 +00:00
|
|
|
|
/********************************************************/
|
|
|
|
|
/**** Routine de lecture et visu d'un fichier GERBER ****/
|
|
|
|
|
/********************************************************/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2008-12-16 02:20:21 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#include "fctsys.h"
|
|
|
|
|
#include "common.h"
|
2009-02-04 15:25:03 +00:00
|
|
|
|
#include "confirm.h"
|
2009-04-05 20:49:15 +00:00
|
|
|
|
#include "macros.h"
|
2007-06-05 12:10:51 +00:00
|
|
|
|
#include "gerbview.h"
|
|
|
|
|
#include "pcbplot.h"
|
|
|
|
|
#include "protos.h"
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
|
|
|
|
|
|| ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) )
|
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/* Format Gerber : NOTES :
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* Fonctions preparatoires:
|
|
|
|
|
* Gn =
|
|
|
|
|
* G01 interpolation lineaire ( trace de droites )
|
|
|
|
|
* G02,G20,G21 Interpolation circulaire , sens trigo < 0
|
|
|
|
|
* G03,G30,G31 Interpolation circulaire , sens trigo > 0
|
|
|
|
|
* G04 commentaire
|
|
|
|
|
* G06 Interpolation parabolique
|
|
|
|
|
* G07 Interpolation cubique
|
|
|
|
|
* G10 interpolation lineaire ( echelle 10x )
|
|
|
|
|
* G11 interpolation lineaire ( echelle 0.1x )
|
|
|
|
|
* G12 interpolation lineaire ( echelle 0.01x )
|
|
|
|
|
* G52 plot symbole reference par Dnn code
|
|
|
|
|
* G53 plot symbole reference par Dnn ; symbole tourne de -90 degres
|
|
|
|
|
* G54 Selection d'outil
|
|
|
|
|
* G55 Mode exposition photo
|
|
|
|
|
* G56 plot symbole reference par Dnn A code
|
|
|
|
|
* G57 affiche le symbole reference sur la console
|
|
|
|
|
* G58 plot et affiche le symbole reference sur la console
|
|
|
|
|
* G60 interpolation lineaire ( echelle 100x )
|
|
|
|
|
* G70 Unites = Inches
|
|
|
|
|
* G71 Unites = Millimetres
|
|
|
|
|
* G74 supprime interpolation circulaire sur 360 degre, revient a G01
|
|
|
|
|
* G75 Active interpolation circulaire sur 360 degre
|
|
|
|
|
* G90 Mode Coordonnees absolues
|
|
|
|
|
* G91 Mode Coordonnees Relatives
|
2008-04-17 16:25:29 +00:00
|
|
|
|
*
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* Coordonnees X,Y
|
|
|
|
|
* X,Y sont suivies de + ou - et de m+n chiffres (non separes)
|
|
|
|
|
* m = partie entiere
|
|
|
|
|
* n = partie apres la virgule
|
2009-04-29 17:09:00 +00:00
|
|
|
|
* formats classiques : m = 2, n = 3 (format 2.3)
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* m = 3, n = 4 (format 3.4)
|
|
|
|
|
* ex:
|
|
|
|
|
* G__ X00345Y-06123 D__*
|
2008-04-17 16:25:29 +00:00
|
|
|
|
*
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* Outils et D_CODES
|
|
|
|
|
* numero d'outil ( identification des formes )
|
2009-04-29 17:09:00 +00:00
|
|
|
|
* 1 a 99 (classique)
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* 1 a 999
|
|
|
|
|
* D_CODES:
|
2008-04-17 16:25:29 +00:00
|
|
|
|
*
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* D01 ... D9 = codes d'action:
|
2008-02-12 21:12:46 +00:00
|
|
|
|
* D01 = activation de lumiere (baisser de plume) lors du d<EFBFBD>placement
|
|
|
|
|
* D02 = extinction de lumiere (lever de plume) lors du d<EFBFBD>placement
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* D03 = Flash
|
|
|
|
|
* D09 = VAPE Flash
|
|
|
|
|
* D51 = precede par G54 -> Select VAPE
|
2008-04-17 16:25:29 +00:00
|
|
|
|
*
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* D10 ... D255 = Indentification d'outils ( d'ouvertures )
|
|
|
|
|
* Ne sont pas tj dans l'ordre ( voir tableau dans PCBPLOT.H)
|
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
// Type d'action du phototraceur:
|
2007-09-26 04:09:22 +00:00
|
|
|
|
#define GERB_ACTIVE_DRAW 1 // activation de lumiere ( baisser de plume)
|
|
|
|
|
#define GERB_STOP_DRAW 2 // extinction de lumiere ( lever de plume)
|
|
|
|
|
#define GERB_FLASH 3 // Flash
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
/* Variables locales : */
|
|
|
|
|
static wxPoint LastPosition;
|
|
|
|
|
|
2008-12-16 02:20:21 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/* Local Functions (are lower case since they are private to this source file) */
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
2008-12-29 18:02:54 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function fillCircularTRACK
|
|
|
|
|
* initializes a given TRACK so that it can draw a circle which is not filled and
|
|
|
|
|
* has a given pen width (\a aPenWidth ).
|
|
|
|
|
*
|
|
|
|
|
* @param aTrack The TRACK to fill in.
|
|
|
|
|
* @param Dcode_index The DCODE value, like D14
|
|
|
|
|
* @param aLayer The layer index to set into the TRACK
|
|
|
|
|
* @param aPos The center point of the flash
|
|
|
|
|
* @param aDiameter The diameter of the round flash
|
|
|
|
|
* @param aPenWidth The width of the pen used to draw the circle's circumfrance.
|
|
|
|
|
* @param isDark True if flash is positive and should use a drawing
|
|
|
|
|
* color other than the background color, else use the background color
|
|
|
|
|
* when drawing so that an erasure happens.
|
|
|
|
|
*/
|
2009-04-29 17:09:00 +00:00
|
|
|
|
static void fillCircularTRACK( TRACK* aTrack,
|
|
|
|
|
int Dcode_index,
|
|
|
|
|
int aLayer,
|
|
|
|
|
const wxPoint& aPos,
|
|
|
|
|
int aDiameter,
|
|
|
|
|
int aPenWidth,
|
|
|
|
|
bool isDark )
|
2008-12-29 18:02:54 +00:00
|
|
|
|
{
|
|
|
|
|
aTrack->m_Shape = S_CIRCLE;
|
|
|
|
|
aTrack->m_Width = aPenWidth;
|
|
|
|
|
|
|
|
|
|
aTrack->SetLayer( aLayer );
|
|
|
|
|
aTrack->SetNet( Dcode_index );
|
|
|
|
|
|
|
|
|
|
// When drawing a TRACK with shape S_CIRCLE, the hypotenuse (i.e. distance)
|
|
|
|
|
// between the Start and End points gives the radius of the circle.
|
2009-04-29 17:09:00 +00:00
|
|
|
|
aTrack->m_Start = aTrack->m_End = aPos;
|
|
|
|
|
aTrack->m_End.x += max( 0, (aDiameter + 1) / 2 );
|
2008-12-29 18:02:54 +00:00
|
|
|
|
|
|
|
|
|
NEGATE( aTrack->m_Start.y );
|
|
|
|
|
NEGATE( aTrack->m_End.y );
|
|
|
|
|
|
|
|
|
|
if( !isDark )
|
|
|
|
|
{
|
|
|
|
|
aTrack->m_Flags |= DRAW_ERASED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function fillRoundFlashTRACK
|
2008-12-29 18:02:54 +00:00
|
|
|
|
* initializes a given TRACK so that it can draw a circle which is filled and
|
|
|
|
|
* has no pen border.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
*
|
|
|
|
|
* @param aTrack The TRACK to fill in.
|
|
|
|
|
* @param Dcode_index The DCODE value, like D14
|
|
|
|
|
* @param aLayer The layer index to set into the TRACK
|
|
|
|
|
* @param aPos The center point of the flash
|
|
|
|
|
* @param aDiameter The diameter of the round flash
|
|
|
|
|
* @param isDark True if flash is positive and should use a drawing
|
|
|
|
|
* color other than the background color, else use the background color
|
|
|
|
|
* when drawing so that an erasure happens.
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*/
|
2009-04-29 17:09:00 +00:00
|
|
|
|
static void fillRoundFlashTRACK( TRACK* aTrack,
|
|
|
|
|
int Dcode_index,
|
|
|
|
|
int aLayer,
|
|
|
|
|
const wxPoint& aPos,
|
|
|
|
|
int aDiameter,
|
|
|
|
|
bool isDark )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetLayer( aLayer );
|
|
|
|
|
aTrack->m_Width = aDiameter;
|
|
|
|
|
aTrack->m_Start = aTrack->m_End = aPos;
|
|
|
|
|
NEGATE( aTrack->m_Start.y );
|
|
|
|
|
NEGATE( aTrack->m_End.y );
|
|
|
|
|
aTrack->SetNet( Dcode_index );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
aTrack->m_Shape = S_SPOT_CIRCLE;
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
|
|
|
|
if( !isDark )
|
|
|
|
|
{
|
|
|
|
|
aTrack->m_Flags |= DRAW_ERASED;
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function fillOvalOrRectFlashTRACK
|
2009-04-29 17:09:00 +00:00
|
|
|
|
* initializes a given TRACK so that it can draw an oval or rectangular
|
|
|
|
|
* filled rectangle.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
*
|
|
|
|
|
* @param aTrack The TRACK to fill in.
|
|
|
|
|
* @param Dcode_index The DCODE value, like D14
|
|
|
|
|
* @param aLayer The layer index to set into the TRACK
|
2008-12-29 18:02:54 +00:00
|
|
|
|
* @param aPos The center point of the rectangle
|
2008-11-14 17:49:38 +00:00
|
|
|
|
* @param aSize The size of the flash
|
|
|
|
|
* @param aShape What type of flash, S_SPOT_OVALE or S_SPOT_RECT
|
|
|
|
|
* @param isDark True if flash is positive and should use a drawing
|
|
|
|
|
* color other than the background color, else use the background color
|
|
|
|
|
* when drawing so that an erasure happens.
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*/
|
2009-04-29 17:09:00 +00:00
|
|
|
|
static void fillOvalOrRectFlashTRACK( TRACK* aTrack,
|
|
|
|
|
int Dcode_index,
|
|
|
|
|
int aLayer,
|
|
|
|
|
const wxPoint& aPos,
|
|
|
|
|
const wxSize& aSize,
|
|
|
|
|
int aShape,
|
|
|
|
|
bool isDark )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
int width = MIN( aSize.x, aSize.y );
|
|
|
|
|
int len = MAX( aSize.x, aSize.y ) - width;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetLayer( aLayer );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Width = width;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aTrack->m_End = aPos;
|
|
|
|
|
NEGATE( aTrack->m_Start.y );
|
|
|
|
|
NEGATE( aTrack->m_End.y );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetNet( Dcode_index );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Shape = aShape;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
|
|
|
|
len >>= 1;
|
2008-11-14 17:49:38 +00:00
|
|
|
|
if( aSize.x > aSize.y ) // oval or rectangle is horizontal
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start.x -= len;
|
|
|
|
|
aTrack->m_End.x += len;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2008-11-14 17:49:38 +00:00
|
|
|
|
else // oval or rectangle is vertical
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start.y -= len;
|
|
|
|
|
aTrack->m_End.y += len;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
|
|
|
|
if( !isDark )
|
|
|
|
|
{
|
|
|
|
|
aTrack->m_Flags |= DRAW_ERASED;
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function fillLineTRACK
|
|
|
|
|
* initializes a given TRACK so that it can draw a linear D code.
|
|
|
|
|
*
|
|
|
|
|
* @param aTrack The TRACK to fill in.
|
|
|
|
|
* @param Dcode_index The DCODE value, like D14
|
|
|
|
|
* @param aLayer The layer index to set into the TRACK
|
|
|
|
|
* @param aPos The center point of the flash
|
|
|
|
|
* @param aDiameter The diameter of the round flash
|
|
|
|
|
* @param isDark True if flash is positive and should use a drawing
|
|
|
|
|
* color other than the background color, else use the background color
|
|
|
|
|
* when drawing so that an erasure happens.
|
|
|
|
|
*/
|
2009-04-29 17:09:00 +00:00
|
|
|
|
static void fillLineTRACK( TRACK* aTrack,
|
|
|
|
|
int Dcode_index,
|
|
|
|
|
int aLayer,
|
|
|
|
|
const wxPoint& aStart,
|
|
|
|
|
const wxPoint& aEnd,
|
|
|
|
|
int aWidth,
|
|
|
|
|
bool isDark )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetLayer( aLayer );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Width = aWidth;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aStart;
|
|
|
|
|
NEGATE( aTrack->m_Start.y );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_End = aEnd;
|
|
|
|
|
NEGATE( aTrack->m_End.y );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetNet( Dcode_index );
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
|
|
|
|
if( !isDark )
|
|
|
|
|
{
|
|
|
|
|
aTrack->m_Flags |= DRAW_ERASED;
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function fillArcTRACK
|
|
|
|
|
* initializes a given TRACK so that it can draw an arc G code.
|
2008-12-29 20:05:47 +00:00
|
|
|
|
* <p>
|
|
|
|
|
* if multiquadrant == true : arc can be 0 to 360 degres
|
|
|
|
|
* and \a rel_center is the center coordiante relative to startpoint.
|
|
|
|
|
* <p>
|
|
|
|
|
* if multiquadrant == false arc can be only 0 to 90 deg,
|
|
|
|
|
* and only in the same quadrant :
|
|
|
|
|
* <ul>
|
|
|
|
|
* <li> absolute angle 0 to 90 (quadrant 1) or
|
|
|
|
|
* <li> absolute angle 90 to 180 (quadrant 2) or
|
|
|
|
|
* <li> absolute angle 180 to 270 (quadrant 3) or
|
|
|
|
|
* <li> absolute angle 270 to 0 (quadrant 4)
|
|
|
|
|
* </ul><p>
|
|
|
|
|
* @param aTrack is the TRACK to fill in.
|
|
|
|
|
* @param Dcode_index is the DCODE value, like D14
|
|
|
|
|
* @param aLayer is the layer index to set into the TRACK
|
|
|
|
|
* @param aStart is the starting point
|
|
|
|
|
* @param aEnd is the ending point
|
|
|
|
|
* @param rel_center is the center coordiante relative to startpoint,
|
|
|
|
|
* given in ABSOLUE VALUE and the signe of values x et y de rel_center
|
|
|
|
|
* must be calculated from the previously given constraint: arc only in the same quadrant.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
* @param aDiameter The diameter of the round flash
|
2008-12-29 20:05:47 +00:00
|
|
|
|
* @param aWidth is the pen width.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
* @param isDark True if flash is positive and should use a drawing
|
|
|
|
|
* color other than the background color, else use the background color
|
|
|
|
|
* when drawing so that an erasure happens.
|
|
|
|
|
*/
|
|
|
|
|
static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
2009-04-29 17:09:00 +00:00
|
|
|
|
const wxPoint& aStart, const wxPoint& aEnd,
|
|
|
|
|
const wxPoint& rel_center, int aWidth,
|
2009-05-10 15:43:41 +00:00
|
|
|
|
bool clockwise, bool multiquadrant, bool isDark )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
{
|
|
|
|
|
wxPoint center, delta;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Shape = S_ARC;
|
|
|
|
|
aTrack->SetLayer( aLayer );
|
|
|
|
|
aTrack->m_Width = aWidth;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
|
|
|
|
if( multiquadrant )
|
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
center.x = aStart.x + rel_center.x;
|
2009-05-10 15:43:41 +00:00
|
|
|
|
center.y = aStart.y + rel_center.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2009-05-10 15:43:41 +00:00
|
|
|
|
if( clockwise )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aStart;
|
|
|
|
|
aTrack->m_End = aEnd;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aEnd;
|
|
|
|
|
aTrack->m_End = aStart;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-05-10 15:43:41 +00:00
|
|
|
|
center = rel_center;
|
2008-11-14 17:49:38 +00:00
|
|
|
|
delta.x = aEnd.x - aStart.x;
|
|
|
|
|
delta.y = aEnd.y - aStart.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2009-05-10 15:43:41 +00:00
|
|
|
|
if( (delta.x >= 0) && (delta.y >= 0) )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2009-05-10 15:43:41 +00:00
|
|
|
|
// Quadrant 2
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2009-05-10 15:43:41 +00:00
|
|
|
|
else if( (delta.x >= 0) && (delta.y < 0) )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2009-05-10 15:43:41 +00:00
|
|
|
|
// Quadrant 1
|
2007-09-26 04:09:22 +00:00
|
|
|
|
center.y = -center.y;
|
|
|
|
|
}
|
2009-05-10 15:43:41 +00:00
|
|
|
|
else if( (delta.x < 0) && (delta.y >= 0) )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2009-05-10 15:43:41 +00:00
|
|
|
|
// Quadrant 4
|
|
|
|
|
center.x = -center.x;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2009-05-10 15:43:41 +00:00
|
|
|
|
else
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2009-05-10 15:43:41 +00:00
|
|
|
|
// Quadrant 3
|
|
|
|
|
center.x = -center.x;
|
|
|
|
|
center.y = -center.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
center.x += aStart.x;
|
2009-05-10 15:43:41 +00:00
|
|
|
|
center.y += aStart.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2009-05-10 15:43:41 +00:00
|
|
|
|
if( clockwise )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aStart;
|
|
|
|
|
aTrack->m_End = aEnd;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->m_Start = aEnd;
|
|
|
|
|
aTrack->m_End = aStart;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetNet( Dcode_index );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
aTrack->m_Param = center.x;
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetSubNet( center.y );
|
2008-04-17 16:25:29 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
NEGATE( aTrack->m_Start.y );
|
|
|
|
|
NEGATE( aTrack->m_End.y );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
aTrack->SetSubNet( -aTrack->GetSubNet() );
|
2008-12-04 04:28:11 +00:00
|
|
|
|
|
|
|
|
|
if( !isDark )
|
|
|
|
|
{
|
|
|
|
|
aTrack->m_Flags |= DRAW_ERASED;
|
|
|
|
|
}
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
/**************************************************/
|
2008-02-12 21:12:46 +00:00
|
|
|
|
/* Routines utilis<69>es en lecture de ficher gerber */
|
2007-09-26 04:09:22 +00:00
|
|
|
|
/**************************************************/
|
|
|
|
|
|
2008-02-12 21:12:46 +00:00
|
|
|
|
/* ces routines lisent la chaine de texte point<6E>e par Text.
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* Apres appel, Text pointe le debut de la sequence non lue
|
|
|
|
|
*/
|
2007-06-05 12:10:51 +00:00
|
|
|
|
|
|
|
|
|
/***********************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
wxPoint GERBER::ReadXYCoord( char*& Text )
|
2009-04-29 17:09:00 +00:00
|
|
|
|
{
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/***********************************************/
|
|
|
|
|
/* Retourne la coord courante pointee par Text (XnnnnYmmmm)
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*/
|
|
|
|
|
wxPoint pos = m_CurrentPos;
|
|
|
|
|
int type_coord = 0, current_coord, nbchar;
|
2008-11-14 17:49:38 +00:00
|
|
|
|
bool is_float = false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
char* text;
|
|
|
|
|
char line[256];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( m_Relative )
|
|
|
|
|
pos.x = pos.y = 0;
|
|
|
|
|
else
|
|
|
|
|
pos = m_CurrentPos;
|
|
|
|
|
|
|
|
|
|
if( Text == NULL )
|
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
|
|
text = line;
|
|
|
|
|
while( *Text )
|
|
|
|
|
{
|
|
|
|
|
if( (*Text == 'X') || (*Text == 'Y') )
|
|
|
|
|
{
|
|
|
|
|
type_coord = *Text;
|
|
|
|
|
Text++;
|
2009-04-29 17:09:00 +00:00
|
|
|
|
text = line;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
nbchar = 0;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
while( IsNumber( *Text ) )
|
|
|
|
|
{
|
|
|
|
|
if( *Text == '.' )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
is_float = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*(text++) = *(Text++);
|
|
|
|
|
if( (*Text >= '0') && (*Text <='9') )
|
|
|
|
|
nbchar++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
if( is_float )
|
|
|
|
|
{
|
|
|
|
|
if( m_GerbMetric )
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( atof( line ) / 0.00254 );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
else
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int fmt_scale =
|
|
|
|
|
(type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( m_NoTrailingZeros )
|
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int min_digit =
|
|
|
|
|
(type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
while( nbchar < min_digit )
|
|
|
|
|
{
|
2008-11-10 07:13:37 +00:00
|
|
|
|
*(text++) = '0';
|
|
|
|
|
nbchar++;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
}
|
|
|
|
|
current_coord = atoi( line );
|
|
|
|
|
double real_scale = 1.0;
|
|
|
|
|
|
|
|
|
|
switch( fmt_scale )
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
real_scale = 10000.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
real_scale = 1000.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
real_scale = 100.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
real_scale = 10.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
|
real_scale = 0.1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
|
real_scale = 0.01;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
|
real_scale = 0.001;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
|
real_scale = 0.0001;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
|
real_scale = 0.00001;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( m_GerbMetric )
|
|
|
|
|
real_scale = real_scale / 25.4;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( current_coord * real_scale );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( type_coord == 'X' )
|
|
|
|
|
pos.x = current_coord;
|
|
|
|
|
else if( type_coord == 'Y' )
|
|
|
|
|
pos.y = current_coord;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( m_Relative )
|
|
|
|
|
{
|
|
|
|
|
pos.x += m_CurrentPos.x;
|
|
|
|
|
pos.y += m_CurrentPos.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_CurrentPos = pos;
|
|
|
|
|
return pos;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/************************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
wxPoint GERBER::ReadIJCoord( char*& Text )
|
2009-04-29 17:09:00 +00:00
|
|
|
|
{
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/************************************************/
|
|
|
|
|
/* Retourne la coord type InnJnn courante pointee par Text (InnnnJmmmm)
|
2008-02-12 21:12:46 +00:00
|
|
|
|
* Ces coordonn<EFBFBD>es sont relatives, donc si une coord est absente, sa valeur
|
2007-09-26 04:09:22 +00:00
|
|
|
|
* par defaut est 0
|
|
|
|
|
*/
|
|
|
|
|
wxPoint pos( 0, 0 );
|
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int type_coord = 0, current_coord, nbchar;
|
|
|
|
|
bool is_float = false;
|
|
|
|
|
char* text;
|
|
|
|
|
char line[256];
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
|
|
|
|
if( Text == NULL )
|
|
|
|
|
return pos;
|
|
|
|
|
|
|
|
|
|
text = line;
|
|
|
|
|
while( *Text )
|
|
|
|
|
{
|
|
|
|
|
if( (*Text == 'I') || (*Text == 'J') )
|
|
|
|
|
{
|
|
|
|
|
type_coord = *Text;
|
|
|
|
|
Text++;
|
2009-04-29 17:09:00 +00:00
|
|
|
|
text = line;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
nbchar = 0;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
while( IsNumber( *Text ) )
|
|
|
|
|
{
|
|
|
|
|
if( *Text == '.' )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
is_float = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*(text++) = *(Text++);
|
|
|
|
|
if( (*Text >= '0') && (*Text <='9') )
|
|
|
|
|
nbchar++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
if( is_float )
|
|
|
|
|
{
|
|
|
|
|
if( m_GerbMetric )
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( atof( line ) / 0.00254 );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
else
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int fmt_scale =
|
|
|
|
|
(type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( m_NoTrailingZeros )
|
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int min_digit =
|
|
|
|
|
(type_coord == 'I') ? m_FmtLen.x : m_FmtLen.y;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
while( nbchar < min_digit )
|
|
|
|
|
{
|
2008-11-14 07:46:43 +00:00
|
|
|
|
*(text++) = '0';
|
|
|
|
|
nbchar++;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
}
|
|
|
|
|
current_coord = atoi( line );
|
|
|
|
|
double real_scale = 1.0;
|
|
|
|
|
|
|
|
|
|
switch( fmt_scale )
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
real_scale = 10000.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
real_scale = 1000.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
|
real_scale = 100.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
real_scale = 10.0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
|
real_scale = 0.1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
|
real_scale = 0.01;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
|
real_scale = 0.001;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
|
real_scale = 0.0001;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
|
real_scale = 0.00001;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( m_GerbMetric )
|
|
|
|
|
real_scale = real_scale / 25.4;
|
2009-04-05 20:49:15 +00:00
|
|
|
|
current_coord = wxRound( current_coord * real_scale );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
if( type_coord == 'I' )
|
|
|
|
|
pos.x = current_coord;
|
|
|
|
|
else if( type_coord == 'J' )
|
|
|
|
|
pos.y = current_coord;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_IJPos = pos;
|
|
|
|
|
return pos;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/*****************************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
int GERBER::ReturnGCodeNumber( char*& Text )
|
2009-04-29 17:09:00 +00:00
|
|
|
|
{
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/*****************************************************/
|
|
|
|
|
/* Lit la sequence Gnn et retourne la valeur nn
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*/
|
|
|
|
|
int ii = 0;
|
|
|
|
|
char* text;
|
|
|
|
|
char line[1024];
|
|
|
|
|
|
|
|
|
|
if( Text == NULL )
|
|
|
|
|
return 0;
|
|
|
|
|
Text++;
|
|
|
|
|
text = line;
|
|
|
|
|
while( IsNumber( *Text ) )
|
|
|
|
|
{
|
|
|
|
|
*(text++) = *(Text++);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
ii = atoi( line );
|
|
|
|
|
return ii;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**************************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
int GERBER::ReturnDCodeNumber( char*& Text )
|
2009-04-29 17:09:00 +00:00
|
|
|
|
{
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/**************************************************/
|
|
|
|
|
/* Lit la sequence Dnn et retourne la valeur nn
|
2007-09-26 04:09:22 +00:00
|
|
|
|
*/
|
|
|
|
|
int ii = 0;
|
|
|
|
|
char* text;
|
|
|
|
|
char line[1024];
|
|
|
|
|
|
|
|
|
|
if( Text == NULL )
|
|
|
|
|
return 0;
|
2008-12-16 02:20:21 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
Text++;
|
|
|
|
|
text = line;
|
|
|
|
|
while( IsNumber( *Text ) )
|
|
|
|
|
*(text++) = *(Text++);
|
|
|
|
|
|
|
|
|
|
*text = 0;
|
|
|
|
|
ii = atoi( line );
|
|
|
|
|
return ii;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/******************************************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
bool GERBER::Execute_G_Command( char*& text, int G_commande )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
/******************************************************************/
|
|
|
|
|
D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); )
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
switch( G_commande )
|
|
|
|
|
{
|
2008-12-17 14:51:39 +00:00
|
|
|
|
case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored
|
|
|
|
|
break;
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
case GC_LINEAR_INTERPOL_1X:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_LINEAR_1X;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_CIRCLE_NEG_INTERPOL:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_ARC_NEG;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_CIRCLE_POS_INTERPOL:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_ARC_POS;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_COMMENT:
|
|
|
|
|
text = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_LINEAR_INTERPOL_10X:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_LINEAR_10X;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_LINEAR_INTERPOL_0P1X:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_LINEAR_01X;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_LINEAR_INTERPOL_0P01X:
|
|
|
|
|
m_Iterpolation = GERB_INTERPOL_LINEAR_001X;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_SELECT_TOOL:
|
|
|
|
|
{
|
|
|
|
|
int D_commande = ReturnDCodeNumber( text );
|
|
|
|
|
if( D_commande < FIRST_DCODE )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( D_commande > (MAX_TOOLS - 1) )
|
|
|
|
|
D_commande = MAX_TOOLS - 1;
|
|
|
|
|
m_Current_Tool = D_commande;
|
2008-11-09 02:58:16 +00:00
|
|
|
|
D_CODE* pt_Dcode = GetDCODE( D_commande, false );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( pt_Dcode )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
pt_Dcode->m_InUse = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case GC_SPECIFY_INCHES:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_GerbMetric = false; // false = Inches, true = metric
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_SPECIFY_MILLIMETERS:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_GerbMetric = true; // false = Inches, true = metric
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_TURN_OFF_360_INTERPOL:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_360Arc_enbl = false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_TURN_ON_360_INTERPOL:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_360Arc_enbl = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_SPECIFY_ABSOLUES_COORD:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_Relative = false; // false = absolute Coord, RUE = relative Coord
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_SPECIFY_RELATIVEES_COORD:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_Relative = true; // false = absolute Coord, RUE = relative Coord
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_TURN_ON_POLY_FILL:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
m_PolygonFillMode = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_TURN_OFF_POLY_FILL:
|
2009-04-29 17:09:00 +00:00
|
|
|
|
m_PolygonFillMode = false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
m_PolygonFillModeState = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GC_MOVE: // Non existant
|
|
|
|
|
default:
|
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
wxString msg; msg.Printf( wxT( "G%0.2d command not handled" ),
|
|
|
|
|
G_commande );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
DisplayError( NULL, msg );
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 07:46:43 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function scale
|
|
|
|
|
* converts a distance given in floating point to our deci-mils
|
|
|
|
|
*/
|
|
|
|
|
static int scale( double aCoord, bool isMetric )
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if( isMetric )
|
2009-04-05 20:49:15 +00:00
|
|
|
|
ret = wxRound( aCoord / 0.00254 );
|
2008-11-14 07:46:43 +00:00
|
|
|
|
else
|
2009-04-05 20:49:15 +00:00
|
|
|
|
ret = wxRound( aCoord * PCB_INTERNAL_UNIT );
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Function mapPt
|
|
|
|
|
* translates a point from the aperture macro coordinate system to our
|
|
|
|
|
* deci-mils coordinate system.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
* @return wxPoint - The gerbview coordinate system vector.
|
2008-11-14 07:46:43 +00:00
|
|
|
|
*/
|
2008-11-14 17:49:38 +00:00
|
|
|
|
static wxPoint mapPt( double x, double y, bool isMetric )
|
2008-11-14 07:46:43 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
wxPoint ret( scale( x, isMetric ),
|
|
|
|
|
scale( y, isMetric ) );
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
/**
|
|
|
|
|
* Function mapExposure
|
|
|
|
|
* translates the first parameter from an aperture macro into a current exposure
|
|
|
|
|
* setting.
|
2009-04-29 17:09:00 +00:00
|
|
|
|
* @param curExposure A dynamic setting which can change throughout the
|
|
|
|
|
* reading of the gerber file, and it indicates whether the current tool
|
|
|
|
|
* is lit or not.
|
2008-11-14 17:49:38 +00:00
|
|
|
|
* @param isNegative A dynamic setting which can change throughout the reading of
|
|
|
|
|
* the gerber file, and it indicates whether the current D codes are to
|
|
|
|
|
* be interpreted as erasures or not.
|
|
|
|
|
*/
|
|
|
|
|
static bool mapExposure( int param1, bool curExposure, bool isNegative )
|
2008-11-14 07:46:43 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
bool exposure;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
|
|
|
|
switch( param1 )
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
exposure = false;
|
|
|
|
|
break;
|
2009-04-29 17:09:00 +00:00
|
|
|
|
|
2008-11-14 07:46:43 +00:00
|
|
|
|
default:
|
|
|
|
|
case 1:
|
|
|
|
|
exposure = true;
|
|
|
|
|
break;
|
2009-04-29 17:09:00 +00:00
|
|
|
|
|
2008-11-14 07:46:43 +00:00
|
|
|
|
case 2:
|
|
|
|
|
exposure = !curExposure;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return exposure ^ isNegative;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
|
/*****************************************************************************/
|
2008-11-08 06:44:07 +00:00
|
|
|
|
bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
|
2009-04-29 17:09:00 +00:00
|
|
|
|
char*& text, int D_commande )
|
2007-06-05 12:10:51 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
wxSize size( 15, 15 );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
APERTURE_T aperture = APT_CIRCLE;
|
|
|
|
|
TRACK* track;
|
|
|
|
|
BOARD* pcb = frame->GetBoard();
|
2008-11-14 17:49:38 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int activeLayer = frame->GetScreen()->m_Active_Layer;
|
2008-11-08 06:44:07 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int dcode = 0;
|
|
|
|
|
D_CODE* tool = NULL;
|
|
|
|
|
wxString msg;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); )
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
|
|
|
|
|
{
|
|
|
|
|
if( D_commande > (MAX_TOOLS - 1) )
|
|
|
|
|
D_commande = MAX_TOOLS - 1;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
// remember which tool is selected, nothing is done with it in this call
|
2007-09-26 04:09:22 +00:00
|
|
|
|
m_Current_Tool = D_commande;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
2008-11-09 02:58:16 +00:00
|
|
|
|
D_CODE* pt_Dcode = GetDCODE( D_commande, false );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
if( pt_Dcode )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
pt_Dcode->m_InUse = true;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
else // D_commande = 0..9: this is a pen command (usualy D1, D2 or D3)
|
|
|
|
|
{
|
|
|
|
|
m_Last_Pen_Command = D_commande;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( m_PolygonFillMode ) // Enter a polygon description:
|
|
|
|
|
{
|
|
|
|
|
switch( D_commande )
|
|
|
|
|
{
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case 1: // code D01 Draw line, exposure ON
|
2008-11-14 07:46:43 +00:00
|
|
|
|
m_Exposure = true;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-12-29 18:02:54 +00:00
|
|
|
|
SEGZONE* edge_poly;
|
|
|
|
|
edge_poly = new SEGZONE( pcb );
|
|
|
|
|
pcb->m_Zone.Append( edge_poly );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "R:%p\n", edge_poly ); )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
edge_poly->SetLayer( activeLayer );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
edge_poly->m_Width = 1;
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
edge_poly->m_Start = m_PreviousPos;
|
|
|
|
|
NEGATE( edge_poly->m_Start.y );
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
edge_poly->m_End = m_CurrentPos;
|
|
|
|
|
NEGATE( edge_poly->m_End.y );
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-10-13 06:18:44 +00:00
|
|
|
|
edge_poly->SetNet( m_PolygonFillModeState );
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
// the first track of each polygon has a netcode of zero,
|
|
|
|
|
// otherwise one. Sset the erasure flag in that special track,
|
|
|
|
|
// if a negative polygon.
|
2008-12-29 18:02:54 +00:00
|
|
|
|
if( !m_PolygonFillModeState )
|
|
|
|
|
{
|
|
|
|
|
if( m_LayerNegative ^ m_ImageNegative )
|
|
|
|
|
edge_poly->m_Flags |= DRAW_ERASED;
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "\nm_Flags=0x%08X\n", edge_poly->m_Flags ); )
|
2008-12-29 18:02:54 +00:00
|
|
|
|
}
|
2008-12-29 20:05:47 +00:00
|
|
|
|
|
2007-09-26 04:09:22 +00:00
|
|
|
|
m_PreviousPos = m_CurrentPos;
|
|
|
|
|
m_PolygonFillModeState = 1;
|
|
|
|
|
break;
|
|
|
|
|
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case 2: // code D2: exposure OFF (i.e. "move to")
|
2009-04-29 17:09:00 +00:00
|
|
|
|
m_Exposure = false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
m_PreviousPos = m_CurrentPos;
|
|
|
|
|
m_PolygonFillModeState = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2008-12-16 02:20:21 +00:00
|
|
|
|
{
|
2007-09-26 04:09:22 +00:00
|
|
|
|
switch( D_commande )
|
|
|
|
|
{
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case 1: // code D01 Draw line, exposure ON
|
2008-11-14 07:46:43 +00:00
|
|
|
|
m_Exposure = true;
|
|
|
|
|
|
|
|
|
|
tool = GetDCODE( m_Current_Tool, false );
|
|
|
|
|
if( tool )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 07:46:43 +00:00
|
|
|
|
size = tool->m_Size;
|
|
|
|
|
dcode = tool->m_Num_Dcode;
|
|
|
|
|
aperture = tool->m_Shape;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch( m_Iterpolation )
|
|
|
|
|
{
|
|
|
|
|
case GERB_INTERPOL_LINEAR_1X:
|
2008-12-29 18:02:54 +00:00
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillLineTRACK( track, dcode, activeLayer, m_PreviousPos,
|
|
|
|
|
m_CurrentPos, size.x,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GERB_INTERPOL_LINEAR_01X:
|
|
|
|
|
case GERB_INTERPOL_LINEAR_001X:
|
|
|
|
|
case GERB_INTERPOL_LINEAR_10X:
|
|
|
|
|
wxBell();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GERB_INTERPOL_ARC_NEG:
|
|
|
|
|
case GERB_INTERPOL_ARC_POS:
|
2008-12-29 18:02:54 +00:00
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillArcTRACK( track, dcode, activeLayer, m_PreviousPos,
|
|
|
|
|
m_CurrentPos, m_IJPos, size.x,
|
|
|
|
|
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
|
|
|
|
|
false : true, m_360Arc_enbl,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2009-05-21 17:42:42 +00:00
|
|
|
|
msg.Printf( wxT( "Execute_DCODE_Command: interpol error (type %X)" ),
|
|
|
|
|
m_Iterpolation );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
DisplayError( frame, msg );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_PreviousPos = m_CurrentPos;
|
|
|
|
|
break;
|
|
|
|
|
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case 2: // code D2: exposure OFF (i.e. "move to")
|
2009-04-29 17:09:00 +00:00
|
|
|
|
m_Exposure = false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
m_PreviousPos = m_CurrentPos;
|
|
|
|
|
break;
|
|
|
|
|
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case 3: // code D3: flash aperture
|
2008-11-14 07:46:43 +00:00
|
|
|
|
tool = GetDCODE( m_Current_Tool, false );
|
|
|
|
|
if( tool )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 07:46:43 +00:00
|
|
|
|
size = tool->m_Size;
|
|
|
|
|
dcode = tool->m_Num_Dcode;
|
|
|
|
|
aperture = tool->m_Shape;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-11-08 06:44:07 +00:00
|
|
|
|
switch( aperture )
|
2007-09-26 04:09:22 +00:00
|
|
|
|
{
|
2008-11-14 17:49:38 +00:00
|
|
|
|
case APT_LINE: // APT_LINE is not in the spec, don't know why it's here
|
2008-11-08 06:44:07 +00:00
|
|
|
|
case APT_CIRCLE:
|
2008-12-29 18:02:54 +00:00
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "R:%p\n", track ); )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
fillRoundFlashTRACK( track, dcode, activeLayer,
|
2009-04-29 17:09:00 +00:00
|
|
|
|
m_CurrentPos, size.x,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2008-11-08 06:44:07 +00:00
|
|
|
|
case APT_OVAL:
|
|
|
|
|
case APT_RECT:
|
2008-12-29 18:02:54 +00:00
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
D( printf( "R:%p\n", track ); )
|
2008-11-14 17:49:38 +00:00
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
2009-04-29 17:09:00 +00:00
|
|
|
|
m_CurrentPos, size,
|
|
|
|
|
( aperture == APT_RECT ) ?
|
|
|
|
|
S_SPOT_RECT : S_SPOT_OVALE,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2008-11-10 07:13:37 +00:00
|
|
|
|
case APT_MACRO:
|
2009-04-29 17:09:00 +00:00
|
|
|
|
{
|
|
|
|
|
APERTURE_MACRO* macro = tool->GetMacro();
|
|
|
|
|
wxASSERT( macro );
|
|
|
|
|
|
|
|
|
|
// split the macro primitives up into multiple normal TRACK elements
|
|
|
|
|
for( AM_PRIMITIVES::iterator p = macro->primitives.begin();
|
|
|
|
|
p!=macro->primitives.end();
|
|
|
|
|
++p )
|
2008-11-10 07:13:37 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
bool exposure;
|
|
|
|
|
wxPoint curPos = m_CurrentPos;
|
|
|
|
|
|
|
|
|
|
switch( p->primitive_id )
|
|
|
|
|
{
|
|
|
|
|
case AMP_CIRCLE:
|
|
|
|
|
{
|
|
|
|
|
exposure = mapExposure( p->GetExposure(), m_Exposure,
|
|
|
|
|
m_ImageNegative );
|
|
|
|
|
curPos += mapPt( p->params[2].GetValue( tool ),
|
|
|
|
|
p->params[3].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
int diameter = scale( p->params[1].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillRoundFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
m_CurrentPos, diameter, exposure );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AMP_LINE2:
|
|
|
|
|
case AMP_LINE20:
|
|
|
|
|
{
|
|
|
|
|
exposure = mapExposure(
|
|
|
|
|
p->GetExposure(), m_Exposure, m_ImageNegative );
|
|
|
|
|
int width = scale( p->params[1].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
wxPoint start = mapPt( p->params[2].GetValue( tool ),
|
|
|
|
|
p->params[3].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
wxPoint end = mapPt( p->params[4].GetValue( tool ),
|
|
|
|
|
p->params[5].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
if( start.x == end.x )
|
|
|
|
|
{
|
|
|
|
|
size.x = width;
|
|
|
|
|
size.y = ABS( end.y - start.y ) + 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
size.x = ABS( end.x - start.x ) + 1;
|
|
|
|
|
size.y = width;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wxPoint midPoint( (start.x + end.x) / 2,
|
|
|
|
|
(start.y + end.y) / 2 );
|
|
|
|
|
curPos += midPoint;
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos, size, S_SPOT_RECT,
|
|
|
|
|
exposure );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AMP_LINE_CENTER:
|
|
|
|
|
{
|
|
|
|
|
exposure = mapExposure( p->GetExposure(), m_Exposure,
|
|
|
|
|
m_ImageNegative );
|
|
|
|
|
wxPoint msize = mapPt( p->params[1].GetValue( tool ),
|
|
|
|
|
p->params[2].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
size.x = msize.x;
|
|
|
|
|
size.y = msize.y;
|
|
|
|
|
curPos += mapPt( p->params[3].GetValue( tool ),
|
|
|
|
|
p->params[4].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos, size, S_SPOT_RECT,
|
|
|
|
|
exposure );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AMP_LINE_LOWER_LEFT:
|
|
|
|
|
{
|
|
|
|
|
exposure = mapExposure(
|
|
|
|
|
p->GetExposure(), m_Exposure, m_ImageNegative );
|
|
|
|
|
wxPoint msize = mapPt( p->params[1].GetValue( tool ),
|
|
|
|
|
p->params[2].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
size.x = msize.x;
|
|
|
|
|
size.y = msize.y;
|
|
|
|
|
wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ),
|
|
|
|
|
p->params[4].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
curPos += lowerLeft;
|
|
|
|
|
|
|
|
|
|
// need the middle, so adjust from the lower left
|
|
|
|
|
curPos.y += size.y / 2;
|
|
|
|
|
curPos.x += size.x / 2;
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos, size, S_SPOT_RECT,
|
|
|
|
|
exposure );
|
|
|
|
|
}
|
|
|
|
|
break;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
case AMP_THERMAL:
|
2008-11-10 07:13:37 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int outerDiam = scale( p->params[2].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
int innerDiam = scale( p->params[3].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
curPos += mapPt( p->params[0].GetValue( tool ),
|
|
|
|
|
p->params[1].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillRoundFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos, outerDiam,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
|
|
|
|
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillRoundFlashTRACK( track, dcode, activeLayer, curPos,
|
|
|
|
|
innerDiam,
|
|
|
|
|
(m_LayerNegative ^ m_ImageNegative) );
|
|
|
|
|
|
|
|
|
|
// @todo: draw the cross hairs, see page 23 of rs274
|
|
|
|
|
// spec. this might be done with two lines, thickness
|
|
|
|
|
// from params[4], and drawing
|
|
|
|
|
// darkness "(m_LayerNegative ^ m_ImageNegative)"
|
|
|
|
|
}
|
|
|
|
|
break;
|
2008-11-14 07:46:43 +00:00
|
|
|
|
|
2009-04-29 17:09:00 +00:00
|
|
|
|
case AMP_MOIRE:
|
|
|
|
|
{
|
|
|
|
|
curPos += mapPt( p->params[0].GetValue( tool ),
|
|
|
|
|
p->params[1].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
// e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
|
|
|
|
|
int outerDiam = scale( p->params[2].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
int penThickness = scale( p->params[3].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
|
|
|
|
int gap = scale( p->params[4].GetValue( tool ),
|
|
|
|
|
m_GerbMetric );
|
2009-05-21 17:42:42 +00:00
|
|
|
|
int numCircles = (int)p->params[5].GetValue( tool );
|
2009-04-29 17:09:00 +00:00
|
|
|
|
int crossHairThickness =
|
|
|
|
|
scale( p->params[6].GetValue( tool ), m_GerbMetric );
|
|
|
|
|
int crossHairLength =
|
|
|
|
|
scale( p->params[7].GetValue( tool ), m_GerbMetric );
|
|
|
|
|
|
|
|
|
|
// ignore rotation, not supported
|
|
|
|
|
|
|
|
|
|
int diamAdjust = 2 * (gap + penThickness); // adjust outerDiam by this on each nested circle
|
|
|
|
|
for( int i = 0;
|
|
|
|
|
i < numCircles;
|
|
|
|
|
++i, outerDiam -= diamAdjust )
|
2008-11-10 07:13:37 +00:00
|
|
|
|
{
|
2009-04-29 17:09:00 +00:00
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillCircularTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos, outerDiam,
|
|
|
|
|
penThickness,
|
|
|
|
|
!(m_LayerNegative ^ m_ImageNegative) );
|
2008-11-10 07:13:37 +00:00
|
|
|
|
}
|
2009-04-29 17:09:00 +00:00
|
|
|
|
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos,
|
|
|
|
|
wxSize( crossHairThickness,
|
|
|
|
|
crossHairLength ),
|
|
|
|
|
S_SPOT_RECT,
|
|
|
|
|
!(m_LayerNegative ^
|
|
|
|
|
m_ImageNegative) );
|
|
|
|
|
|
|
|
|
|
track = new TRACK( pcb );
|
|
|
|
|
pcb->m_Track.Append( track );
|
|
|
|
|
D( printf( "R:%p\n", track ); )
|
|
|
|
|
|
|
|
|
|
// swap x and y in wxSize() for this one
|
|
|
|
|
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
|
|
|
|
curPos,
|
|
|
|
|
wxSize( crossHairLength,
|
|
|
|
|
crossHairThickness ),
|
|
|
|
|
S_SPOT_RECT,
|
|
|
|
|
!(m_LayerNegative ^
|
|
|
|
|
m_ImageNegative) );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case AMP_EOF:
|
|
|
|
|
case AMP_OUTLINE:
|
|
|
|
|
case AMP_POLYGON:
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
|
|
// not yet supported, waiting for you.
|
|
|
|
|
break;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-04-29 17:09:00 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
2008-11-10 07:13:37 +00:00
|
|
|
|
|
|
|
|
|
default:
|
2007-09-26 04:09:22 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_PreviousPos = m_CurrentPos;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return false;
|
2007-09-26 04:09:22 +00:00
|
|
|
|
}
|
2008-12-16 02:20:21 +00:00
|
|
|
|
}
|
2007-09-26 04:09:22 +00:00
|
|
|
|
|
2008-11-14 17:49:38 +00:00
|
|
|
|
return true;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
}
|