Gerbview: Added support for gerber command SR (Step and Repeat) and multiple MOIN and MOMM in file

This commit is contained in:
jean-pierre charras 2010-10-15 20:59:26 +02:00
parent b5019b823f
commit 9ec8d53604
19 changed files with 484 additions and 253 deletions

View File

@ -4,6 +4,13 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2010-oct-15, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++gerbview:
Added support for gerber commands:
SR (Step and Repeat)
multiple MOIN and/or MOMM in file (switch units from inch to mm and mm to inch)
2010-oct-09, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2010-oct-09, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++gerbview: ++gerbview:

View File

@ -73,7 +73,6 @@ const wxString AllFilesWildcard( _( "All files (*)|*" ) );
wxString g_ProductName = wxT( "KiCad E.D.A. " ); wxString g_ProductName = wxT( "KiCad E.D.A. " );
bool g_ShowPageLimits = true; bool g_ShowPageLimits = true;
wxString g_UserLibDirBuffer; wxString g_UserLibDirBuffer;
int g_DebugLevel;
int g_MouseOldButtons; int g_MouseOldButtons;
int g_KeyPressed; int g_KeyPressed;

View File

@ -127,8 +127,6 @@ bool WinEDA_App::OnInit()
wxFileName filename; wxFileName filename;
WinEDA_SchematicFrame* frame = NULL; WinEDA_SchematicFrame* frame = NULL;
g_DebugLevel = 0; // Debug level */
InitEDA_Appl( wxT( "EESchema" ), APP_TYPE_EESCHEMA ); InitEDA_Appl( wxT( "EESchema" ), APP_TYPE_EESCHEMA );
if( m_Checker && m_Checker->IsAnotherRunning() ) if( m_Checker && m_Checker->IsAnotherRunning() )

View File

@ -42,6 +42,7 @@ set(GERBVIEW_SRCS
options.cpp options.cpp
pcbplot.cpp pcbplot.cpp
readgerb.cpp readgerb.cpp
rs274_read_XY_and_IJ_coordinates.cpp
rs274d.cpp rs274d.cpp
rs274x.cpp rs274x.cpp
select_layers_to_pcb.cpp select_layers_to_pcb.cpp

View File

@ -322,7 +322,7 @@ void WinEDA_GerberFrame::Block_Move( wxDC* DC )
{ {
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item; GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) ) if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
gerb_item->Move( delta ); gerb_item->MoveAB( delta );
} }
DrawPanel->Refresh( TRUE ); DrawPanel->Refresh( TRUE );
@ -355,8 +355,8 @@ void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) ) if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
{ {
/* this item must be duplicated */ /* this item must be duplicated */
BOARD_ITEM* new_item = gerb_item->Copy(); GERBER_DRAW_ITEM* new_item = gerb_item->Copy();
new_item->Move( delta ); new_item->MoveAB( delta );
GetBoard()->m_Drawings.PushFront( new_item ); GetBoard()->m_Drawings.PushFront( new_item );
} }
} }

View File

@ -35,6 +35,13 @@
#include "gerbview.h" #include "gerbview.h"
#include "class_GERBER.h" #include "class_GERBER.h"
/**
* Function scale
* converts a distance given in floating point to our deci-mils
*/
extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp
/* Format Gerber: NOTES: /* Format Gerber: NOTES:
* Tools and D_CODES * Tools and D_CODES
* tool number (identification of shapes) * tool number (identification of shapes)
@ -133,6 +140,10 @@ void GERBER::ResetDefaultValues()
m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command
m_Offset.x = m_Offset.y = 0; // Coord Offset, from OF command m_Offset.x = m_Offset.y = 0; // Coord Offset, from OF command
m_Rotation = 0; // Allowed 0, 90, 180, 270 m_Rotation = 0; // Allowed 0, 90, 180, 270
m_StepForRepeat.x = m_StepForRepeat.y = 0; // X and Y offsets for Step and Repeat command
m_XRepeatCount = 1; // The repeat count on X axis
m_YRepeatCount = 1; // The repeat count on Y axis
m_StepForRepeatMetric = false; // false = Inches, true = metric
m_Has_DCode = false; // true = DCodes in file m_Has_DCode = false; // true = DCodes in file
// false = no DCode-> // false = no DCode->
// search for separate DCode file // search for separate DCode file
@ -210,3 +221,34 @@ void GERBER::ClearMessageList()
{ {
m_Parent->ClearMessageList(); m_Parent->ClearMessageList();
} }
/** Function StepAndRepeatItem
* Gerber format has a command Step an Repeat
* This function must be called when reading a gerber file and
* after creating a new gerber item that must be repeated
* (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
* @param aItem = the item to repeat
*/
void GERBER::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem )
{
if( m_XRepeatCount < 2 && m_YRepeatCount < 2 )
return; // Nothing to repeat
// Duplicate item:
wxString msg;
for( int ii = 0; ii < m_XRepeatCount; ii++ )
{
for( int jj = 0; jj < m_YRepeatCount; jj++ )
{
// the first gerber item already exists (this is the template)
// create duplicate only if ii or jj > 0
if( jj == 0 && ii == 0 )
continue;
GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem );
wxPoint move_vector;
move_vector.x = scale( ii * m_StepForRepeat.x, m_StepForRepeatMetric );
move_vector.y = scale( jj * m_StepForRepeat.y, m_StepForRepeatMetric );
dupItem->MoveXY(move_vector);
m_Parent->GetBoard()->m_Drawings.Append( dupItem );
}
}
}

View File

@ -12,6 +12,10 @@
#include "class_gerber_draw_item.h" #include "class_gerber_draw_item.h"
#include "class_aperture_macro.h" #include "class_aperture_macro.h"
// An useful macro used when reading gerber files;
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
|| ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) )
class WinEDA_GerberFrame; class WinEDA_GerberFrame;
class BOARD; class BOARD;
class D_CODE; class D_CODE;
@ -49,6 +53,14 @@ public:
wxRealPoint m_LayerScale; // scale (X and Y) of layer. wxRealPoint m_LayerScale; // scale (X and Y) of layer.
int m_Rotation; // Image rotation (0, 90, 180, 270 int m_Rotation; // Image rotation (0, 90, 180, 270
// Note these values are stored in 0.1 degrees // Note these values are stored in 0.1 degrees
wxRealPoint m_StepForRepeat; // X and Y offsets for Step and Repeat command
int m_XRepeatCount; // The repeat count on X axis
int m_YRepeatCount; // The repeat count on Y axis
bool m_StepForRepeatMetric; // false = Inches, true = metric
// needed here because repeated
// gerber items can have coordinates
// in different units than step parameters
// and the actual coordinates calculation must handle this
int m_Iterpolation; // Linear, 90 arc, Circ. int m_Iterpolation; // Linear, 90 arc, Circ.
bool m_ImageNegative; // true = Negative image bool m_ImageNegative; // true = Negative image
int m_Current_Tool; // Current Tool (Dcode) number selected int m_Current_Tool; // Current Tool (Dcode) number selected
@ -115,15 +127,13 @@ public:
// functions to execute G commands or D commands: // functions to execute G commands or D commands:
bool Execute_G_Command( char*& text, int G_commande ); bool Execute_G_Command( char*& text, int G_commande );
bool Execute_DCODE_Command( WinEDA_GerberFrame* frame, bool Execute_DCODE_Command( char*& text, int D_commande );
char*& text, int D_commande );
/** /**
* Function ReadRS274XCommand * Function ReadRS274XCommand
* reads a single RS274X command terminated with a % * reads a single RS274X command terminated with a %
*/ */
bool ReadRS274XCommand( WinEDA_GerberFrame * frame, bool ReadRS274XCommand( char aBuff[GERBER_BUFZ], char* & text );
char aBuff[GERBER_BUFZ], char* & text );
/** /**
* Function ExecuteRS274XCommand * Function ExecuteRS274XCommand
@ -167,6 +177,15 @@ public:
* not found. * not found.
*/ */
APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup ); APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup );
/** Function StepAndRepeatItem
* Gerber format has a command Step an Repeat
* This function must be called when reading a gerber file and
* after creating a new gerber item that must be repeated
* (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
* @param aItem = the item to repeat
*/
void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
}; };

View File

@ -34,12 +34,7 @@
#include "trigo.h" #include "trigo.h"
#include "gerbview.h" #include "gerbview.h"
/** helper Function mapPt
* translates a point from the aperture macro coordinate system to our
* deci-mils coordinate system.
* @return wxPoint - The gerbview coordinate system vector.
*/
extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d.cpp
/** /**
* Function scale * Function scale
@ -47,6 +42,19 @@ extern wxPoint mapPt( double x, double y, bool isMetric ); // defined it rs274d
*/ */
extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp
/**
* Function mapPt
* translates a point from the aperture macro coordinate system to our
* deci-mils coordinate system.
* @return wxPoint - The gerbview coordinate system vector.
*/
static wxPoint mapPt( double x, double y, bool isMetric )
{
wxPoint ret( scale( x, isMetric ), scale( y, isMetric ) );
return ret;
}
/** /**
* Function mapExposure * Function mapExposure
@ -130,7 +138,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
wxPoint curPos = aShapePos; wxPoint curPos = aShapePos;
D_CODE* tool = aParent->GetDcodeDescr(); D_CODE* tool = aParent->GetDcodeDescr();
bool gerberMetric = aParent->m_UnitsMetric; bool gerberMetric = m_GerbMetric;
int rotation; int rotation;
if( mapExposure( aParent ) == false ) if( mapExposure( aParent ) == false )
{ {

View File

@ -69,11 +69,14 @@ public:
AM_PRIMITIVE_ID primitive_id; ///< The primitive type AM_PRIMITIVE_ID primitive_id; ///< The primitive type
DCODE_PARAMS params; ///< A sequence of parameters used by DCODE_PARAMS params; ///< A sequence of parameters used by
// the primitive // the primitive
bool m_GerbMetric; // units for this primitive:
// false = Inches, true = metric
public: public:
AM_PRIMITIVE( AM_PRIMITIVE_ID aId = AMP_UNKNOWN ) AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
{ {
primitive_id = aId; primitive_id = aId;
m_GerbMetric = aGerbMetric;
} }

View File

@ -253,11 +253,11 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
/** /**
* Function Move * Function MoveAB
* move this object. * move this object.
* @param const wxPoint& aMoveVector - the move vector for this object, in AB plotter axis. * @param const wxPoint& aMoveVector - the move vector for this object, in AB plotter axis.
*/ */
void GERBER_DRAW_ITEM::Move( const wxPoint& aMoveVector ) void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
{ {
wxPoint xymove = GetXYPosition( aMoveVector ); wxPoint xymove = GetXYPosition( aMoveVector );
m_Start += xymove; m_Start += xymove;
@ -267,6 +267,19 @@ void GERBER_DRAW_ITEM::Move( const wxPoint& aMoveVector )
m_PolyCorners[ii] += xymove; m_PolyCorners[ii] += xymove;
} }
/**
* Function MoveXY
* move this object.
* @param const wxPoint& aMoveVector - the move vector for this object, in XY gerber axis.
*/
void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector )
{
m_Start += aMoveVector;
m_End += aMoveVector;
m_ArcCentre += aMoveVector;
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
m_PolyCorners[ii] += aMoveVector;
}
/** function Save. /** function Save.
* currently: no nothing, but must be defined to meet requirements * currently: no nothing, but must be defined to meet requirements

View File

@ -126,11 +126,18 @@ public:
void SetLayerParameters( ); void SetLayerParameters( );
/** /**
* Function Move * Function MoveAB
* move this object. * move this object.
* @param const wxPoint& aMoveVector - the move vector for this object. * @param const wxPoint& aMoveVector - the move vector for this object.
*/ */
void Move( const wxPoint& aMoveVector ); void MoveAB( const wxPoint& aMoveVector );
/**
* Function MoveXY
* move this object.
* @param const wxPoint& aMoveVector - the move vector for this object, in XY gerber axis.
*/
void MoveXY( const wxPoint& aMoveVector );
/** /**
* Function GetPosition * Function GetPosition

View File

@ -0,0 +1,68 @@
G04 Test handling of unit changes within a RS274X file *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
G04 Aperture 10 should be in Inches *
%ADD10C,0.050*%
%MOMM*%
G04 Aperture 11 should be in MMs *
%ADD11C,1.250*%
G04 Aperture 12 should be in MMs *
%AMTHERMAL*
7,0,0,25.4,12.7,2.54,0*%
%MOIN*%
G04 Aperture 13 is in inches *
%AMTHERMALTWO*
7,0,0,1,0.5,0.1,0*%
%MOMM*%
%ADD12THERMAL*%
%MOIN*%
%ADD13THERMALTWO*%
%MOIN*%
G04 Box 1, using aperture 10*
X0Y0D02*
G54D10*
X0Y0D01*
X1000D01*
Y1000D01*
X0D01*
Y0D01*
G04 Box 2, using aperture 11*
X2000Y0D02*
G54D11*
X2000Y0D01*
X3000D01*
Y1000D01*
X2000D01*
Y0D01*
%MOMM*%
G04 Box 3, using aperture 10*
X100000Y0D02*
G54D10*
X100000Y0D01*
X125000D01*
Y25000D01*
X100000D01*
Y0D01*
G04 Draw Thermal in box 1*
G54D12*
Y12000X12700D03*
G04 Draw Thermal in box 2*
G04 ..switch to inches for coordinates*
G70*
Y500X2500D02*
G54D12*
Y500X2500D03*
G04 ..switch to mms for coordinates*
G71*
G04 Draw Thermal in box 3*
G54D13*
Y12000X112000D03*
M02*

View File

@ -0,0 +1,17 @@
G04 Test step and repeat 1*
G04 Repeat a crosshair 3 times in the x direction and 2 times in the Y *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%SRX3Y2I5.0J2*%
%ADD10C,0.050*%
G04 Draw crosshairs *
X-1000Y0D02*
G54D10*
X1000Y0D01*
X0Y-1000D02*
G54D10*
X0Y1000D01*
M02*

View File

@ -0,0 +1,18 @@
G04 Test step and repeat 1*
G04 Repeat a crosshair 3 times in the x direction and 2 times in the Y *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%SRX3Y2I1J1*%
%ADD10C,0.050*%
G04 Draw a simple square*
G36*
G01X00400Y0D02*
X00600Y0D01*
X00600Y00200D01*
X00400Y00200D01*
X00400Y0D01*
G37*
M02*

View File

@ -106,7 +106,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
case 'D': /* Line type Dxx : Tool selection (xx > 0) or case 'D': /* Line type Dxx : Tool selection (xx > 0) or
* command if xx = 0..9 */ * command if xx = 0..9 */
D_commande = gerber->ReturnDCodeNumber( text ); D_commande = gerber->ReturnDCodeNumber( text );
gerber->Execute_DCODE_Command( this, text, D_commande ); gerber->Execute_DCODE_Command( text, D_commande );
break; break;
case 'X': case 'X':
@ -114,7 +114,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
gerber->m_CurrentPos = gerber->ReadXYCoord( text ); gerber->m_CurrentPos = gerber->ReadXYCoord( text );
if( *text == '*' ) // command like X12550Y19250* if( *text == '*' ) // command like X12550Y19250*
{ {
gerber->Execute_DCODE_Command( this, text, gerber->Execute_DCODE_Command( text,
gerber->m_Last_Pen_Command ); gerber->m_Last_Pen_Command );
} }
break; break;
@ -124,7 +124,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
gerber->m_IJPos = gerber->ReadIJCoord( text ); gerber->m_IJPos = gerber->ReadIJCoord( text );
if( *text == '*' ) // command like X35142Y15945J504* if( *text == '*' ) // command like X35142Y15945J504*
{ {
gerber->Execute_DCODE_Command( this, text, gerber->Execute_DCODE_Command( text,
gerber->m_Last_Pen_Command ); gerber->m_Last_Pen_Command );
} }
break; break;
@ -133,7 +133,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
if( gerber->m_CommandState != ENTER_RS274X_CMD ) if( gerber->m_CommandState != ENTER_RS274X_CMD )
{ {
gerber->m_CommandState = ENTER_RS274X_CMD; gerber->m_CommandState = ENTER_RS274X_CMD;
gerber->ReadRS274XCommand( this, line, text ); gerber->ReadRS274XCommand( line, text );
} }
else //Error else //Error
{ {

View File

@ -0,0 +1,203 @@
/**********************************************/
/**** rs274_read_XY_and_IJ_coordinates.cpp ****/
/**********************************************/
#include "fctsys.h"
#include "common.h"
#include "gerbview.h"
#include "macros.h"
#include "class_GERBER.h"
/* These routines read the text string point from Text.
* After use, advanced Text the beginning of the sequence unread
*/
wxPoint GERBER::ReadXYCoord( char*& Text )
{
wxPoint pos;
int type_coord = 0, current_coord, nbdigits;
bool is_float = false;
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++;
text = line;
nbdigits = 0;
while( IsNumber( *Text ) )
{
if( *Text == '.' )
is_float = true;
// count digits only (sign and decimal point are not counted)
if( (*Text >= '0') && (*Text <='9') )
nbdigits++;
*(text++) = *(Text++);
}
*text = 0;
if( is_float )
{
if( m_GerbMetric )
current_coord = wxRound( atof( line ) / 0.00254 );
else
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
}
else
{
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
(type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
while( nbdigits < min_digit )
{
*(text++) = '0';
nbdigits++;
}
*text = 0;
}
current_coord = atoi( line );
double real_scale = 1.0;
double scale_list[10] =
{
10000.0, 1000.0, 100.0, 10.0,
1,
0.1, 0.01, 0.001, 0.0001,0.00001
};
real_scale = scale_list[fmt_scale];
if( m_GerbMetric )
real_scale = real_scale / 25.4;
current_coord = wxRound( current_coord * real_scale );
}
if( type_coord == 'X' )
pos.x = current_coord;
else if( type_coord == 'Y' )
pos.y = current_coord;
continue;
}
else
break;
}
if( m_Relative )
{
pos.x += m_CurrentPos.x;
pos.y += m_CurrentPos.y;
}
m_CurrentPos = pos;
return pos;
}
/* Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm)
* These coordinates are relative, so if coordinate is absent, it's value
* defaults to 0
*/
wxPoint GERBER::ReadIJCoord( char*& Text )
{
wxPoint pos( 0, 0 );
int type_coord = 0, current_coord, nbdigits;
bool is_float = false;
char* text;
char line[256];
if( Text == NULL )
return pos;
text = line;
while( *Text )
{
if( (*Text == 'I') || (*Text == 'J') )
{
type_coord = *Text;
Text++;
text = line;
nbdigits = 0;
while( IsNumber( *Text ) )
{
if( *Text == '.' )
is_float = true;
// count digits only (sign and decimal point are not counted)
if( (*Text >= '0') && (*Text <='9') )
nbdigits++;
*(text++) = *(Text++);
}
*text = 0;
if( is_float )
{
if( m_GerbMetric )
current_coord = wxRound( atof( line ) / 0.00254 );
else
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
}
else
{
int fmt_scale =
(type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
(type_coord == 'I') ? m_FmtLen.x : m_FmtLen.y;
while( nbdigits < min_digit )
{
*(text++) = '0';
nbdigits++;
}
*text = 0;
}
current_coord = atoi( line );
double real_scale = 1.0;
if( fmt_scale < 0 || fmt_scale > 9 )
fmt_scale = 4; // select scale 1.0
double scale_list[10] =
{
10000.0, 1000.0, 100.0, 10.0,
1,
0.1, 0.01, 0.001, 0.0001,0.00001
};
real_scale = scale_list[fmt_scale];
if( m_GerbMetric )
real_scale = real_scale / 25.4;
current_coord = wxRound( current_coord * real_scale );
}
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;
}

View File

@ -3,12 +3,8 @@
/********************/ /********************/
#include "fctsys.h" #include "fctsys.h"
//#include "polygons_defs.h"
#include "common.h" #include "common.h"
//#include "confirm.h"
//#include "macros.h"
#include "gerbview.h" #include "gerbview.h"
#include "trigo.h" #include "trigo.h"
#include "macros.h" #include "macros.h"
@ -17,9 +13,6 @@
#include <math.h> #include <math.h>
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
|| ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) )
/* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes): /* Gerber: NOTES about some important commands found in RS274D and RS274X (G codes):
* Gn = * Gn =
* G01 linear interpolation (right trace) * G01 linear interpolation (right trace)
@ -448,199 +441,6 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
} }
/* These routines read the text string point from Text.
* After use, advanced Text the beginning of the sequence unread
*/
wxPoint GERBER::ReadXYCoord( char*& Text )
{
wxPoint pos;
int type_coord = 0, current_coord, nbdigits;
bool is_float = false;
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++;
text = line;
nbdigits = 0;
while( IsNumber( *Text ) )
{
if( *Text == '.' )
is_float = true;
// count digits only (sign and decimal point are not counted)
if( (*Text >= '0') && (*Text <='9') )
nbdigits++;
*(text++) = *(Text++);
}
*text = 0;
if( is_float )
{
if( m_GerbMetric )
current_coord = wxRound( atof( line ) / 0.00254 );
else
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
}
else
{
int fmt_scale = (type_coord == 'X') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
(type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y;
while( nbdigits < min_digit )
{
*(text++) = '0';
nbdigits++;
}
*text = 0;
}
current_coord = atoi( line );
double real_scale = 1.0;
double scale_list[10] =
{
10000.0, 1000.0, 100.0, 10.0,
1,
0.1, 0.01, 0.001, 0.0001,0.00001
};
real_scale = scale_list[fmt_scale];
if( m_GerbMetric )
real_scale = real_scale / 25.4;
current_coord = wxRound( current_coord * real_scale );
}
if( type_coord == 'X' )
pos.x = current_coord;
else if( type_coord == 'Y' )
pos.y = current_coord;
continue;
}
else
break;
}
if( m_Relative )
{
pos.x += m_CurrentPos.x;
pos.y += m_CurrentPos.y;
}
m_CurrentPos = pos;
return pos;
}
/* Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm)
* These coordinates are relative, so if coordinate is absent, it's value
* defaults to 0
*/
wxPoint GERBER::ReadIJCoord( char*& Text )
{
wxPoint pos( 0, 0 );
int type_coord = 0, current_coord, nbdigits;
bool is_float = false;
char* text;
char line[256];
if( Text == NULL )
return pos;
text = line;
while( *Text )
{
if( (*Text == 'I') || (*Text == 'J') )
{
type_coord = *Text;
Text++;
text = line;
nbdigits = 0;
while( IsNumber( *Text ) )
{
if( *Text == '.' )
is_float = true;
// count digits only (sign and decimal point are not counted)
if( (*Text >= '0') && (*Text <='9') )
nbdigits++;
*(text++) = *(Text++);
}
*text = 0;
if( is_float )
{
if( m_GerbMetric )
current_coord = wxRound( atof( line ) / 0.00254 );
else
current_coord = wxRound( atof( line ) * PCB_INTERNAL_UNIT );
}
else
{
int fmt_scale =
(type_coord == 'I') ? m_FmtScale.x : m_FmtScale.y;
if( m_NoTrailingZeros )
{
int min_digit =
(type_coord == 'I') ? m_FmtLen.x : m_FmtLen.y;
while( nbdigits < min_digit )
{
*(text++) = '0';
nbdigits++;
}
*text = 0;
}
current_coord = atoi( line );
double real_scale = 1.0;
if( fmt_scale < 0 || fmt_scale > 9 )
fmt_scale = 4; // select scale 1.0
double scale_list[10] =
{
10000.0, 1000.0, 100.0, 10.0,
1,
0.1, 0.01, 0.001, 0.0001,0.00001
};
real_scale = scale_list[fmt_scale];
if( m_GerbMetric )
real_scale = real_scale / 25.4;
current_coord = wxRound( current_coord * real_scale );
}
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;
}
/* Read the Gnn sequence and returns the value nn. /* Read the Gnn sequence and returns the value nn.
*/ */
int GERBER::ReturnGCodeNumber( char*& Text ) int GERBER::ReturnGCodeNumber( char*& Text )
@ -770,6 +570,13 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
break; break;
case GC_TURN_OFF_POLY_FILL: case GC_TURN_OFF_POLY_FILL:
if( m_Exposure && m_Parent->GetBoard()->m_Drawings ) // End of polygon
{
GERBER_DRAW_ITEM * gbritem =
(GERBER_DRAW_ITEM*)( m_Parent->GetBoard()->m_Drawings.GetLast() );
StepAndRepeatItem( *gbritem );
}
m_Exposure = false;
m_PolygonFillMode = false; m_PolygonFillMode = false;
m_PolygonFillModeState = 0; m_PolygonFillModeState = 0;
break; break;
@ -806,29 +613,15 @@ int scale( double aCoord, bool isMetric )
} }
/** bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
* Function mapPt
* translates a point from the aperture macro coordinate system to our
* deci-mils coordinate system.
* @return wxPoint - The gerbview coordinate system vector.
*/
wxPoint mapPt( double x, double y, bool isMetric )
{
wxPoint ret( scale( x, isMetric ), scale( y, isMetric ) );
return ret;
}
bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int D_commande )
{ {
wxSize size( 15, 15 ); wxSize size( 15, 15 );
APERTURE_T aperture = APT_CIRCLE; APERTURE_T aperture = APT_CIRCLE;
GERBER_DRAW_ITEM* gbritem; GERBER_DRAW_ITEM* gbritem;
BOARD* pcb = frame->GetBoard(); BOARD* pcb = m_Parent->GetBoard();
int activeLayer = frame->GetScreen()->m_Active_Layer; int activeLayer = m_Parent->GetScreen()->m_Active_Layer;
int dcode = 0; int dcode = 0;
D_CODE* tool = NULL; D_CODE* tool = NULL;
@ -915,6 +708,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
break; break;
case 2: // code D2: exposure OFF (i.e. "move to") case 2: // code D2: exposure OFF (i.e. "move to")
if( m_Exposure && pcb->m_Drawings ) // End of polygon
{
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
StepAndRepeatItem( *gbritem );
}
m_Exposure = false; m_Exposure = false;
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
m_PolygonFillModeState = 0; m_PolygonFillModeState = 0;
@ -950,6 +748,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
// m_CurrentPos.x, m_CurrentPos.y ); ) // m_CurrentPos.x, m_CurrentPos.y ); )
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos, fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative ); m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative );
StepAndRepeatItem( *gbritem );
break; break;
case GERB_INTERPOL_LINEAR_01X: case GERB_INTERPOL_LINEAR_01X:
@ -972,6 +771,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
false : true, m_360Arc_enbl, false : true, m_360Arc_enbl,
m_LayerNegative, m_ImageNegative ); m_LayerNegative, m_ImageNegative );
StepAndRepeatItem( *gbritem );
break; break;
default: default:
@ -1010,6 +810,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
fillFlashedGBRITEM( gbritem, aperture, fillFlashedGBRITEM( gbritem, aperture,
dcode, activeLayer, m_CurrentPos, dcode, activeLayer, m_CurrentPos,
size, m_LayerNegative, m_ImageNegative ); size, m_LayerNegative, m_ImageNegative );
StepAndRepeatItem( *gbritem );
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
break; break;

View File

@ -53,7 +53,7 @@ enum RS274X_PARAMETERS {
LAYER_NAME = CODE( 'L', 'N' ), // Default: Positive LAYER_NAME = CODE( 'L', 'N' ), // Default: Positive
LAYER_POLARITY = CODE( 'L', 'P' ), LAYER_POLARITY = CODE( 'L', 'P' ),
KNOCKOUT = CODE( 'K', 'O' ), // Default: off KNOCKOUT = CODE( 'K', 'O' ), // Default: off
STEP_AND_REPEAT = CODE( 'S', 'P' ), // Default: A = 1, B = 1 STEP_AND_REPEAT = CODE( 'S', 'R' ), // Default: A = 1, B = 1
ROTATE = CODE( 'R', 'O' ), // Default: 0 ROTATE = CODE( 'R', 'O' ), // Default: 0
// Miscellaneous parameters: // Miscellaneous parameters:
@ -126,8 +126,7 @@ static double ReadDouble( char*& text )
} }
bool GERBER::ReadRS274XCommand( WinEDA_GerberFrame* frame, bool GERBER::ReadRS274XCommand( char buff[GERBER_BUFZ], char*& text )
char buff[GERBER_BUFZ], char*& text )
{ {
bool ok = true; bool ok = true;
int code_command; int code_command;
@ -366,10 +365,43 @@ bool GERBER::ExecuteRS274XCommand( int command,
ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) ); ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) );
break; break;
case STEP_AND_REPEAT: // command SR, like %SRX3Y2I5.0J2*%
m_StepForRepeat.x = m_StepForRepeat.x = 0.0; // offset for Step and Repeat command
m_XRepeatCount = m_YRepeatCount =1; // The repeat count
m_StepForRepeatMetric = m_GerbMetric; // the step units
while( *text && *text != '*' )
{
switch( *text )
{
case 'I': // X axis offset
text++;
m_StepForRepeat.x = ReadDouble( text );
break;
case 'J': // Y axis offset
text++;
m_StepForRepeat.y = ReadDouble( text );
break;
case 'X': // X axis repeat count
text++;
m_XRepeatCount = ReadInt( text );
break;
case 'Y': // Y axis offset
text++;
m_YRepeatCount = ReadInt( text );
break;
default:
text++;
break;
}
}
break;
case IMAGE_JUSTIFY: case IMAGE_JUSTIFY:
case PLOTTER_FILM: case PLOTTER_FILM:
case KNOCKOUT: case KNOCKOUT:
case STEP_AND_REPEAT:
case ROTATE: case ROTATE:
msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ), msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ),
(command >> 8) & 0xFF, command & 0xFF ); (command >> 8) & 0xFF, command & 0xFF );
@ -706,12 +738,9 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
am.name.Append( *text++ ); am.name.Append( *text++ );
} }
if( g_DebugLevel > 0 )
wxMessageBox( am.name, wxT( "macro name" ) );
for( ; ; ) for( ; ; )
{ {
AM_PRIMITIVE prim; AM_PRIMITIVE prim( m_GerbMetric );
if( *text == '*' ) if( *text == '*' )
++text; ++text;
@ -797,7 +826,6 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
prim.primitive_id, i ); prim.primitive_id, i );
ReportMessage( msg ); ReportMessage( msg );
} }
// there are more parameters to read if this is an AMP_OUTLINE // there are more parameters to read if this is an AMP_OUTLINE
if( prim.primitive_id == AMP_OUTLINE ) if( prim.primitive_id == AMP_OUTLINE )
{ {

View File

@ -156,7 +156,6 @@ extern wxString g_ProductName;
/* Default user lib path can be left void, if the standard lib path is used */ /* Default user lib path can be left void, if the standard lib path is used */
extern wxString g_UserLibDirBuffer; extern wxString g_UserLibDirBuffer;
extern int g_DebugLevel;
extern int g_MouseOldButtons; extern int g_MouseOldButtons;
extern int g_KeyPressed; extern int g_KeyPressed;