Gerbview: Added support for gerber command SR (Step and Repeat) and multiple MOIN and MOMM in file
This commit is contained in:
parent
b5019b823f
commit
9ec8d53604
|
@ -4,6 +4,13 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
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>
|
||||
================================================================================
|
||||
++gerbview:
|
||||
|
|
|
@ -73,7 +73,6 @@ const wxString AllFilesWildcard( _( "All files (*)|*" ) );
|
|||
wxString g_ProductName = wxT( "KiCad E.D.A. " );
|
||||
bool g_ShowPageLimits = true;
|
||||
wxString g_UserLibDirBuffer;
|
||||
int g_DebugLevel;
|
||||
int g_MouseOldButtons;
|
||||
int g_KeyPressed;
|
||||
|
||||
|
|
|
@ -127,8 +127,6 @@ bool WinEDA_App::OnInit()
|
|||
wxFileName filename;
|
||||
WinEDA_SchematicFrame* frame = NULL;
|
||||
|
||||
g_DebugLevel = 0; // Debug level */
|
||||
|
||||
InitEDA_Appl( wxT( "EESchema" ), APP_TYPE_EESCHEMA );
|
||||
|
||||
if( m_Checker && m_Checker->IsAnotherRunning() )
|
||||
|
|
|
@ -42,6 +42,7 @@ set(GERBVIEW_SRCS
|
|||
options.cpp
|
||||
pcbplot.cpp
|
||||
readgerb.cpp
|
||||
rs274_read_XY_and_IJ_coordinates.cpp
|
||||
rs274d.cpp
|
||||
rs274x.cpp
|
||||
select_layers_to_pcb.cpp
|
||||
|
|
|
@ -322,7 +322,7 @@ void WinEDA_GerberFrame::Block_Move( wxDC* DC )
|
|||
{
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
|
||||
gerb_item->Move( delta );
|
||||
gerb_item->MoveAB( delta );
|
||||
}
|
||||
|
||||
DrawPanel->Refresh( TRUE );
|
||||
|
@ -355,8 +355,8 @@ void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
|
|||
if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) )
|
||||
{
|
||||
/* this item must be duplicated */
|
||||
BOARD_ITEM* new_item = gerb_item->Copy();
|
||||
new_item->Move( delta );
|
||||
GERBER_DRAW_ITEM* new_item = gerb_item->Copy();
|
||||
new_item->MoveAB( delta );
|
||||
GetBoard()->m_Drawings.PushFront( new_item );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,13 @@
|
|||
#include "gerbview.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:
|
||||
* Tools and D_CODES
|
||||
* 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_Offset.x = m_Offset.y = 0; // Coord Offset, from OF command
|
||||
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
|
||||
// false = no DCode->
|
||||
// search for separate DCode file
|
||||
|
@ -210,3 +221,34 @@ void GERBER::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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
#include "class_gerber_draw_item.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 BOARD;
|
||||
class D_CODE;
|
||||
|
@ -49,6 +53,14 @@ public:
|
|||
wxRealPoint m_LayerScale; // scale (X and Y) of layer.
|
||||
int m_Rotation; // Image rotation (0, 90, 180, 270
|
||||
// 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.
|
||||
bool m_ImageNegative; // true = Negative image
|
||||
int m_Current_Tool; // Current Tool (Dcode) number selected
|
||||
|
@ -115,15 +127,13 @@ public:
|
|||
|
||||
// functions to execute G commands or D commands:
|
||||
bool Execute_G_Command( char*& text, int G_commande );
|
||||
bool Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
||||
char*& text, int D_commande );
|
||||
bool Execute_DCODE_Command( char*& text, int D_commande );
|
||||
|
||||
/**
|
||||
* Function ReadRS274XCommand
|
||||
* reads a single RS274X command terminated with a %
|
||||
*/
|
||||
bool ReadRS274XCommand( WinEDA_GerberFrame * frame,
|
||||
char aBuff[GERBER_BUFZ], char* & text );
|
||||
bool ReadRS274XCommand( char aBuff[GERBER_BUFZ], char* & text );
|
||||
|
||||
/**
|
||||
* Function ExecuteRS274XCommand
|
||||
|
@ -167,6 +177,15 @@ public:
|
|||
* not found.
|
||||
*/
|
||||
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 );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -34,12 +34,7 @@
|
|||
#include "trigo.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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -130,7 +138,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
|
|||
|
||||
wxPoint curPos = aShapePos;
|
||||
D_CODE* tool = aParent->GetDcodeDescr();
|
||||
bool gerberMetric = aParent->m_UnitsMetric;
|
||||
bool gerberMetric = m_GerbMetric;
|
||||
int rotation;
|
||||
if( mapExposure( aParent ) == false )
|
||||
{
|
||||
|
|
|
@ -69,11 +69,14 @@ public:
|
|||
AM_PRIMITIVE_ID primitive_id; ///< The primitive type
|
||||
DCODE_PARAMS params; ///< A sequence of parameters used by
|
||||
// the primitive
|
||||
bool m_GerbMetric; // units for this primitive:
|
||||
// false = Inches, true = metric
|
||||
|
||||
public:
|
||||
AM_PRIMITIVE( AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
|
||||
AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
|
||||
{
|
||||
primitive_id = aId;
|
||||
m_GerbMetric = aGerbMetric;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -253,11 +253,11 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
|
|||
|
||||
|
||||
/**
|
||||
* Function Move
|
||||
* Function MoveAB
|
||||
* move this object.
|
||||
* @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 );
|
||||
m_Start += xymove;
|
||||
|
@ -267,6 +267,19 @@ void GERBER_DRAW_ITEM::Move( const wxPoint& aMoveVector )
|
|||
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.
|
||||
* currently: no nothing, but must be defined to meet requirements
|
||||
|
|
|
@ -126,11 +126,18 @@ public:
|
|||
void SetLayerParameters( );
|
||||
|
||||
/**
|
||||
* Function Move
|
||||
* Function MoveAB
|
||||
* move 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
|
||||
|
|
|
@ -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*
|
|
@ -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*
|
|
@ -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*
|
|
@ -106,7 +106,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
|
|||
case 'D': /* Line type Dxx : Tool selection (xx > 0) or
|
||||
* command if xx = 0..9 */
|
||||
D_commande = gerber->ReturnDCodeNumber( text );
|
||||
gerber->Execute_DCODE_Command( this, text, D_commande );
|
||||
gerber->Execute_DCODE_Command( text, D_commande );
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
|
@ -114,7 +114,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
|
|||
gerber->m_CurrentPos = gerber->ReadXYCoord( text );
|
||||
if( *text == '*' ) // command like X12550Y19250*
|
||||
{
|
||||
gerber->Execute_DCODE_Command( this, text,
|
||||
gerber->Execute_DCODE_Command( text,
|
||||
gerber->m_Last_Pen_Command );
|
||||
}
|
||||
break;
|
||||
|
@ -124,7 +124,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
|
|||
gerber->m_IJPos = gerber->ReadIJCoord( text );
|
||||
if( *text == '*' ) // command like X35142Y15945J504*
|
||||
{
|
||||
gerber->Execute_DCODE_Command( this, text,
|
||||
gerber->Execute_DCODE_Command( text,
|
||||
gerber->m_Last_Pen_Command );
|
||||
}
|
||||
break;
|
||||
|
@ -133,7 +133,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
|
|||
if( gerber->m_CommandState != ENTER_RS274X_CMD )
|
||||
{
|
||||
gerber->m_CommandState = ENTER_RS274X_CMD;
|
||||
gerber->ReadRS274XCommand( this, line, text );
|
||||
gerber->ReadRS274XCommand( line, text );
|
||||
}
|
||||
else //Error
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -3,12 +3,8 @@
|
|||
/********************/
|
||||
|
||||
#include "fctsys.h"
|
||||
|
||||
//#include "polygons_defs.h"
|
||||
#include "common.h"
|
||||
|
||||
//#include "confirm.h"
|
||||
//#include "macros.h"
|
||||
#include "gerbview.h"
|
||||
#include "trigo.h"
|
||||
#include "macros.h"
|
||||
|
@ -17,9 +13,6 @@
|
|||
|
||||
#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):
|
||||
* Gn =
|
||||
* 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.
|
||||
*/
|
||||
int GERBER::ReturnGCodeNumber( char*& Text )
|
||||
|
@ -770,6 +570,13 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
|
|||
break;
|
||||
|
||||
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_PolygonFillModeState = 0;
|
||||
break;
|
||||
|
@ -806,29 +613,15 @@ int scale( double aCoord, bool isMetric )
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
|
||||
{
|
||||
wxSize size( 15, 15 );
|
||||
|
||||
APERTURE_T aperture = APT_CIRCLE;
|
||||
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;
|
||||
D_CODE* tool = NULL;
|
||||
|
@ -915,6 +708,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
|
|||
break;
|
||||
|
||||
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_PreviousPos = m_CurrentPos;
|
||||
m_PolygonFillModeState = 0;
|
||||
|
@ -950,6 +748,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
|
|||
// m_CurrentPos.x, m_CurrentPos.y ); )
|
||||
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative );
|
||||
StepAndRepeatItem( *gbritem );
|
||||
break;
|
||||
|
||||
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 ) ?
|
||||
false : true, m_360Arc_enbl,
|
||||
m_LayerNegative, m_ImageNegative );
|
||||
StepAndRepeatItem( *gbritem );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1010,6 +810,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int
|
|||
fillFlashedGBRITEM( gbritem, aperture,
|
||||
dcode, activeLayer, m_CurrentPos,
|
||||
size, m_LayerNegative, m_ImageNegative );
|
||||
StepAndRepeatItem( *gbritem );
|
||||
m_PreviousPos = m_CurrentPos;
|
||||
break;
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ enum RS274X_PARAMETERS {
|
|||
LAYER_NAME = CODE( 'L', 'N' ), // Default: Positive
|
||||
LAYER_POLARITY = CODE( 'L', 'P' ),
|
||||
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
|
||||
|
||||
// Miscellaneous parameters:
|
||||
|
@ -126,8 +126,7 @@ static double ReadDouble( char*& text )
|
|||
}
|
||||
|
||||
|
||||
bool GERBER::ReadRS274XCommand( WinEDA_GerberFrame* frame,
|
||||
char buff[GERBER_BUFZ], char*& text )
|
||||
bool GERBER::ReadRS274XCommand( char buff[GERBER_BUFZ], char*& text )
|
||||
{
|
||||
bool ok = true;
|
||||
int code_command;
|
||||
|
@ -366,10 +365,43 @@ bool GERBER::ExecuteRS274XCommand( int command,
|
|||
ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) );
|
||||
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 PLOTTER_FILM:
|
||||
case KNOCKOUT:
|
||||
case STEP_AND_REPEAT:
|
||||
case ROTATE:
|
||||
msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ),
|
||||
(command >> 8) & 0xFF, command & 0xFF );
|
||||
|
@ -706,12 +738,9 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
|
|||
am.name.Append( *text++ );
|
||||
}
|
||||
|
||||
if( g_DebugLevel > 0 )
|
||||
wxMessageBox( am.name, wxT( "macro name" ) );
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
AM_PRIMITIVE prim;
|
||||
AM_PRIMITIVE prim( m_GerbMetric );
|
||||
|
||||
if( *text == '*' )
|
||||
++text;
|
||||
|
@ -797,7 +826,6 @@ bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ],
|
|||
prim.primitive_id, i );
|
||||
ReportMessage( msg );
|
||||
}
|
||||
|
||||
// there are more parameters to read if this is an AMP_OUTLINE
|
||||
if( prim.primitive_id == AMP_OUTLINE )
|
||||
{
|
||||
|
|
|
@ -156,7 +156,6 @@ extern wxString g_ProductName;
|
|||
/* Default user lib path can be left void, if the standard lib path is used */
|
||||
extern wxString g_UserLibDirBuffer;
|
||||
|
||||
extern int g_DebugLevel;
|
||||
extern int g_MouseOldButtons;
|
||||
extern int g_KeyPressed;
|
||||
|
||||
|
|
Loading…
Reference in New Issue