Gerbview: Added support for complex definitions of parameters (like $3=$2+5/2) in aperture macros and primitives macro.
This commit is contained in:
commit
8c4075216e
|
@ -4,6 +4,20 @@ 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-dec-01, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||||
|
================================================================================
|
||||||
|
Gerbview:
|
||||||
|
Added support for complex definitions of parameters in aperture macros and primitives macro
|
||||||
|
(a complex definition in a parameter that is calculated by an arithmetical expression)
|
||||||
|
Gerbview should now have a decent support of Gerber language.
|
||||||
|
Currently only the obscure knockout command is not supported (I have no motivation to do that)
|
||||||
|
Other "bug":
|
||||||
|
scale in A and B axis is poorly supported: coordinates are scaled, but shapes can have problem:
|
||||||
|
fro instance, a circle is drawn as a circle when A and B scales are different,
|
||||||
|
and perhaps should be an ellipse.
|
||||||
|
On the other hand, Gerber doc is not clear about the meaning of A and B scale.
|
||||||
|
(Alas! Gerber doc is not clear about most of advanced commands)
|
||||||
|
|
||||||
2010-nov-19 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
2010-nov-19 UPDATE Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
================================================================================
|
================================================================================
|
||||||
++EESchema
|
++EESchema
|
||||||
|
|
|
@ -28,39 +28,126 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "class_am_param.h"
|
#include "class_am_param.h"
|
||||||
|
#include "class_aperture_macro.h"
|
||||||
|
|
||||||
extern int ReadInt( char*& text, bool aSkipSeparator = true );
|
extern int ReadInt( char*& text, bool aSkipSeparator = true );
|
||||||
extern double ReadDouble( char*& text, bool aSkipSeparator = true );
|
extern double ReadDouble( char*& text, bool aSkipSeparator = true );
|
||||||
|
|
||||||
/*Class AM_PARAM
|
/* Class AM_PARAM
|
||||||
* holds a parameter for an "aperture macro" as defined within
|
* holds a parameter value for an "aperture macro" as defined within
|
||||||
* standard RS274X. The \a value field can be a constant, i.e. "immediate"
|
* standard RS274X. The parameter can be a constant, i.e. "immediate" parameter,
|
||||||
* parameter or it may not be used if this param is going to defer to the
|
* or depend on some defered values, defined in a D_CODE, by the ADD command.
|
||||||
* referencing aperture macro. In that case, the \a index field is an index
|
* Note the actual value could need an evaluation from an arithmetical expression
|
||||||
* into the aperture macro's parameters.
|
* items in the expression are stored in .
|
||||||
|
* A simple definition is just a value stored in one item in m_paramStack
|
||||||
*/
|
*/
|
||||||
|
AM_PARAM::AM_PARAM( )
|
||||||
|
{
|
||||||
|
m_index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function IsImmediate
|
||||||
|
* tests if this AM_PARAM holds an immediate parameter or has parameter
|
||||||
|
* held by an owning D_CODE.
|
||||||
|
*/
|
||||||
|
bool AM_PARAM::IsImmediate() const
|
||||||
|
{
|
||||||
|
bool isimmediate = true;
|
||||||
|
for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( m_paramStack[ii].IsDefered() )
|
||||||
|
{ // a defered value is found in operand list,
|
||||||
|
// so the parameter is not immediate
|
||||||
|
isimmediate = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isimmediate;
|
||||||
|
}
|
||||||
|
|
||||||
double AM_PARAM::GetValue( const D_CODE* aDcode ) const
|
double AM_PARAM::GetValue( const D_CODE* aDcode ) const
|
||||||
{
|
{
|
||||||
if( IsImmediate() )
|
double paramvalue = 0.0;
|
||||||
return value;
|
double curr_value = 0.0;
|
||||||
else
|
parm_item_type state = POPVALUE;
|
||||||
|
for( unsigned ii = 0; ii < m_paramStack.size(); ii++ )
|
||||||
{
|
{
|
||||||
// the first one was numbered 1, not zero, as in $1, see page 19 of spec.
|
AM_PARAM_ITEM item = m_paramStack[ii];
|
||||||
unsigned ndx = GetIndex();
|
switch( item.GetType() )
|
||||||
wxASSERT( aDcode );
|
{
|
||||||
|
case ADD:
|
||||||
|
case SUB:
|
||||||
|
case MUL:
|
||||||
|
case DIV: // just an operator for next parameter value: store it
|
||||||
|
state = item.GetType();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PUSHPARM:
|
||||||
// get the parameter from the aDcode
|
// get the parameter from the aDcode
|
||||||
if( ndx <= aDcode->GetParamCount() )
|
if( aDcode && item.GetIndex() <= aDcode->GetParamCount() )
|
||||||
return aDcode->GetParam( ndx );
|
curr_value = aDcode->GetParam( item.GetIndex() );
|
||||||
else
|
else // Get parameter from local param definition
|
||||||
{
|
{
|
||||||
wxASSERT( GetIndex() <= aDcode->GetParamCount() );
|
const APERTURE_MACRO * am_parent = aDcode->GetMacro();
|
||||||
return 0.0;
|
curr_value = am_parent->GetLocalParam( aDcode, item.GetIndex() );
|
||||||
|
}
|
||||||
|
// Fall through
|
||||||
|
case PUSHVALUE: // a value is on the stack:
|
||||||
|
if( item.GetType() == PUSHVALUE )
|
||||||
|
curr_value = item.GetValue();
|
||||||
|
switch( state )
|
||||||
|
{
|
||||||
|
case POPVALUE:
|
||||||
|
paramvalue = curr_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ADD:
|
||||||
|
paramvalue += curr_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SUB:
|
||||||
|
paramvalue -= curr_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MUL:
|
||||||
|
paramvalue *= curr_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DIV:
|
||||||
|
paramvalue /= curr_value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxLogDebug( wxT( "AM_PARAM::GetValue() : unexpected operator\n" ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
wxLogDebug( wxT( "AM_PARAM::GetValue(): unexpected type\n" ) );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return paramvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add an operator/operand to the current stack
|
||||||
|
* aType = NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE
|
||||||
|
* aValue required only for PUSHVALUE (double) or PUSHPARM (int) aType.
|
||||||
|
*/
|
||||||
|
void AM_PARAM::PushOperator( parm_item_type aType, double aValue )
|
||||||
|
{
|
||||||
|
AM_PARAM_ITEM item( aType, aValue);
|
||||||
|
m_paramStack.push_back( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AM_PARAM::PushOperator( parm_item_type aType, int aValue )
|
||||||
|
{
|
||||||
|
AM_PARAM_ITEM item( aType, aValue);
|
||||||
|
m_paramStack.push_back( item );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ReadParam
|
* Function ReadParam
|
||||||
|
@ -70,6 +157,7 @@ double AM_PARAM::GetValue( const D_CODE* aDcode ) const
|
||||||
* a reference to an aperture definition parameter value: $1 ot $3 ...
|
* a reference to an aperture definition parameter value: $1 ot $3 ...
|
||||||
* a parameter definition can be complex and have operators between numbers and/or other parameter
|
* a parameter definition can be complex and have operators between numbers and/or other parameter
|
||||||
* like $1+3 or $2x2..
|
* like $1+3 or $2x2..
|
||||||
|
* Note minus sign is not always an operator. It can be the sign of a value.
|
||||||
* Parameters are separated by a comma ( of finish by *)
|
* Parameters are separated by a comma ( of finish by *)
|
||||||
* @param aText = pointer to the parameter to read. Will be modified to point to the next field
|
* @param aText = pointer to the parameter to read. Will be modified to point to the next field
|
||||||
* @return true if a param is read, or false
|
* @return true if a param is read, or false
|
||||||
|
@ -77,25 +165,79 @@ double AM_PARAM::GetValue( const D_CODE* aDcode ) const
|
||||||
bool AM_PARAM::ReadParam( char*& aText )
|
bool AM_PARAM::ReadParam( char*& aText )
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
int ivalue;
|
||||||
|
double dvalue;
|
||||||
|
bool end = false;
|
||||||
|
|
||||||
if( *aText == '$' ) // value defined later, in aperture description
|
while( !end )
|
||||||
{
|
{
|
||||||
|
switch( *aText )
|
||||||
|
{
|
||||||
|
case ',':
|
||||||
|
aText++;
|
||||||
|
// fall through
|
||||||
|
case 0: // EOL
|
||||||
|
case '*': // Terminator in a gerber command
|
||||||
|
end = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
aText++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '$':
|
||||||
|
// defered value defined later, in ADD command which define defered parameters
|
||||||
++aText;
|
++aText;
|
||||||
SetIndex( ReadInt( aText, false ) );
|
ivalue = ReadInt( aText, false );
|
||||||
|
if( m_index < 1 )
|
||||||
|
SetIndex( ivalue );
|
||||||
|
PushOperator( PUSHPARM, ivalue );
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
PushOperator( DIV );
|
||||||
|
aText++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
PushOperator( MUL );
|
||||||
|
aText++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
case '+':
|
||||||
|
// Test if this is an operator between 2 params, or the sign of a value
|
||||||
|
if( m_paramStack.size() > 0 && !m_paramStack.back().IsOperator() )
|
||||||
|
{ // Seems an operator
|
||||||
|
PushOperator( *aText == '+' ? ADD : SUB );
|
||||||
|
aText++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ // seems the sign of a value
|
||||||
SetValue( ReadDouble( aText, false ) );
|
dvalue = ReadDouble( aText, false );
|
||||||
|
PushOperator( PUSHVALUE, dvalue );
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// Skip extra characters and separator
|
case '=': // A local definition found like $4=$3/2
|
||||||
while( *aText && (*aText != ',') && (*aText != '*') )
|
// At this point, one defered parameter is expected to be read.
|
||||||
|
// this parameter value (the index) is stored in m_index.
|
||||||
|
// The list of items is cleared
|
||||||
aText++;
|
aText++;
|
||||||
|
m_paramStack.clear();
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
|
||||||
if( *aText == ',' )
|
default:
|
||||||
aText++;
|
dvalue = ReadDouble( aText, false );
|
||||||
|
PushOperator( PUSHVALUE, dvalue );
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,50 +103,151 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dcode.h"
|
#include "dcode.h"
|
||||||
|
/*
|
||||||
|
Values of a parameter can be the result of an arithmetic operation,
|
||||||
|
between immediate values and defered value.
|
||||||
|
From an idea found in Gerbv, here is the way to evaluate a parameter.
|
||||||
|
a AM_PARAM_ITEM holds info about operands and operators in a parameter definition
|
||||||
|
( a AM_PARAM ) like $2+$2-$3-$3/2
|
||||||
|
|
||||||
|
There is no precedence defined in gerber RS274X, so actual value is calculated step to step.
|
||||||
|
Parameter definition is described by a very primitive assembler.
|
||||||
|
This "program "should describe how to calculate the parameter.
|
||||||
|
The assembler consist of 8 instruction intended for a stackbased machine.
|
||||||
|
The instructions are:
|
||||||
|
NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE
|
||||||
|
|
||||||
|
The instructions
|
||||||
|
----------------
|
||||||
|
NOP : The no operation. This is the default instruction and are
|
||||||
|
added as a security measure.
|
||||||
|
PUSHVALUE : Pushes an arithmetical value on the stack. This machine only works with floats
|
||||||
|
on the stack.
|
||||||
|
PUSHPARM: Pushes a defered parameter onto the stack. Gerber aperture macros accepts
|
||||||
|
parameters to be set when later declared, so the same macro can
|
||||||
|
be used at several instances. Which parameter to be set is an integer
|
||||||
|
and starts with 1. definition is like $1 or $3
|
||||||
|
ADD : The mathematical operation +. Takes the two uppermost values on the
|
||||||
|
the stack, adds them and pushes the result back onto the stack.
|
||||||
|
SUB : Same as ADD, but with -.
|
||||||
|
MUL : Same as ADD, but with *.
|
||||||
|
DIV : Same as ADD, but with /.
|
||||||
|
POPVALUE : used when evaluate the expression: store current calculated value
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum parm_item_type
|
||||||
|
{
|
||||||
|
NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, POPVALUE
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AM_PARAM
|
* Class AM_PARAM
|
||||||
* holds a parameter for an "aperture macro" as defined within
|
* holds an operand for an AM_PARAM as defined within
|
||||||
* standard RS274X. The \a value field can be a constant, i.e. "immediate"
|
* standard RS274X. The \a value field can be a constant, i.e. "immediate"
|
||||||
* parameter or it may not be used if this param is going to defer to the
|
* parameter or it may not be used if this param is going to defer to the
|
||||||
* referencing aperture macro. In that case, the \a index field is an index
|
* referencing aperture macro. In that case, the \a index field is an index
|
||||||
* into the aperture macro's parameters.
|
* into the aperture macro's parameters.
|
||||||
*/
|
*/
|
||||||
class AM_PARAM
|
class AM_PARAM_ITEM
|
||||||
{
|
{
|
||||||
public: AM_PARAM() :
|
private:
|
||||||
index( -1 ),
|
parm_item_type m_type; // the type of item
|
||||||
value( 0.0 )
|
double m_dvalue; // the value, for PUSHVALUE type item
|
||||||
{}
|
int m_ivalue; // the integer value, for PUSHPARM type item
|
||||||
|
|
||||||
double GetValue( const D_CODE* aDcode ) const;
|
public:
|
||||||
|
AM_PARAM_ITEM( parm_item_type aType = NOP, double aValue = 0.0)
|
||||||
|
{
|
||||||
|
m_type = aType;
|
||||||
|
m_dvalue = aValue;
|
||||||
|
m_ivalue = 0;
|
||||||
|
}
|
||||||
|
AM_PARAM_ITEM( parm_item_type aType = NOP, int aValue = 0)
|
||||||
|
{
|
||||||
|
m_type = aType;
|
||||||
|
m_dvalue = 0.0;
|
||||||
|
m_ivalue = aValue;
|
||||||
|
}
|
||||||
|
|
||||||
void SetValue( double aValue )
|
void SetValue( double aValue )
|
||||||
{
|
{
|
||||||
value = aValue;
|
m_dvalue = aValue;
|
||||||
index = -1;
|
|
||||||
}
|
}
|
||||||
|
double GetValue( ) const
|
||||||
|
{
|
||||||
|
return m_dvalue;
|
||||||
|
}
|
||||||
|
parm_item_type GetType() const
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
unsigned GetIndex() const
|
||||||
|
{
|
||||||
|
return (unsigned) m_ivalue;
|
||||||
|
}
|
||||||
|
bool IsOperator() const
|
||||||
|
{
|
||||||
|
return m_type == ADD || m_type == SUB || m_type == MUL || m_type == DIV;
|
||||||
|
}
|
||||||
|
bool IsOperand() const
|
||||||
|
{
|
||||||
|
return m_type == PUSHVALUE || m_type == PUSHPARM;
|
||||||
|
}
|
||||||
|
bool IsDefered() const
|
||||||
|
{
|
||||||
|
return m_type == PUSHPARM;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AM_PARAM
|
||||||
|
* holds a parameter value for an "aperture macro" as defined within
|
||||||
|
* standard RS274X. The parameter can be a constant, i.e. "immediate" parameter,
|
||||||
|
* or depend on some defered values, defined in a D_CODE, by the ADD command.
|
||||||
|
* Note the actual value could need an evaluation from an arithmetical expression
|
||||||
|
* items in the expression are stored in .
|
||||||
|
* A simple definition is just a value stored in one item in m_paramStack
|
||||||
|
*/
|
||||||
|
class AM_PARAM
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int m_index; // has meaning to define parameter local to an aperture macro
|
||||||
|
std::vector<AM_PARAM_ITEM> m_paramStack; // list of operands/operators to evalutate the actual value
|
||||||
|
// if a par def is $3/2, there are 3 items in stack:
|
||||||
|
// 3 (type PUSHPARM) , / (type DIV), 2 (type PUSHVALUE)
|
||||||
|
|
||||||
|
public:
|
||||||
|
AM_PARAM();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function PushOperator
|
||||||
|
* add an operator/operand to the current stack
|
||||||
|
* @param aType = the type of item (NOP, PUSHVALUE, PUSHPARM, ADD, SUB, MUL, DIV, EQUATE)
|
||||||
|
* @param aValue = the item value, double for PUSHVALUE or int for PUSHPARM type.
|
||||||
|
*/
|
||||||
|
void PushOperator( parm_item_type aType, double aValue );
|
||||||
|
void PushOperator( parm_item_type aType, int aValue = 0);
|
||||||
|
|
||||||
|
double GetValue( const D_CODE* aDcode ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function IsImmediate
|
* Function IsImmediate
|
||||||
* tests if this AM_PARAM holds an immediate parameter or is a pointer
|
* tests if this AM_PARAM holds an immediate parameter or is a pointer
|
||||||
* into a parameter held by an owning D_CODE.
|
* into a parameter held by an owning D_CODE.
|
||||||
|
* @return true if the value is immediate, i.e. no defered value in operands used in its definition
|
||||||
*/
|
*/
|
||||||
bool IsImmediate() const { return index == -1; }
|
bool IsImmediate() const;
|
||||||
|
|
||||||
unsigned GetIndex() const
|
unsigned GetIndex() const
|
||||||
{
|
{
|
||||||
return (unsigned) index;
|
return (unsigned) m_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetIndex( int aIndex )
|
void SetIndex( int aIndex )
|
||||||
{
|
{
|
||||||
index = aIndex;
|
m_index = aIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ReadParam
|
* Function ReadParam
|
||||||
* Read one aperture macro parameter
|
* Read one aperture macro parameter
|
||||||
|
@ -160,13 +261,6 @@ public: AM_PARAM() :
|
||||||
* @return true if a param is read, or false
|
* @return true if a param is read, or false
|
||||||
*/
|
*/
|
||||||
bool ReadParam( char*& aText );
|
bool ReadParam( char*& aText );
|
||||||
|
|
||||||
private:
|
|
||||||
int index; ///< if -1, then \a value field is an immediate value,
|
|
||||||
// else this is an index into parent's
|
|
||||||
// D_CODE.m_am_params.
|
|
||||||
double value; ///< if IsImmediate()==true then use the value, else
|
|
||||||
// not used.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<AM_PARAM> AM_PARAMS;
|
typedef std::vector<AM_PARAM> AM_PARAMS;
|
||||||
|
|
|
@ -56,7 +56,6 @@ static wxPoint mapPt( double x, double y, bool isMetric )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function mapExposure
|
* Function mapExposure
|
||||||
* translates the first parameter from an aperture macro into a current
|
* translates the first parameter from an aperture macro into a current
|
||||||
|
@ -762,3 +761,33 @@ int APERTURE_MACRO::GetShapeDim( GERBER_DRAW_ITEM* aParent )
|
||||||
|
|
||||||
return dim;
|
return dim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function GetLocalParam
|
||||||
|
* Usually, parameters are defined inside the aperture primitive
|
||||||
|
* using immediate mode or defered mode.
|
||||||
|
* in defered mode the value is defined in a DCODE that want to use the aperture macro.
|
||||||
|
* But some parameters are defined outside the aperture primitive
|
||||||
|
* and are local to the aperture macro
|
||||||
|
* @return the value of a defered parameter defined inside the aperture macro
|
||||||
|
* @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
|
||||||
|
*/
|
||||||
|
double APERTURE_MACRO::GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const
|
||||||
|
{
|
||||||
|
// find parameter descr.
|
||||||
|
const AM_PARAM * param = NULL;
|
||||||
|
for( unsigned ii = 0; ii < m_localparamStack.size(); ii ++ )
|
||||||
|
{
|
||||||
|
if( m_localparamStack[ii].GetIndex() == aParamId )
|
||||||
|
{
|
||||||
|
param = &m_localparamStack[ii];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( param == NULL ) // not found
|
||||||
|
return 0.0;
|
||||||
|
// Evaluate parameter
|
||||||
|
double value = param->GetValue( aDcode );
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
|
@ -45,6 +45,13 @@
|
||||||
* Each parameter can be an immediate value or a defered value.
|
* Each parameter can be an immediate value or a defered value.
|
||||||
* When value is defered, it is defined when the aperture macro is instancied by
|
* When value is defered, it is defined when the aperture macro is instancied by
|
||||||
* an ADD macro command
|
* an ADD macro command
|
||||||
|
* Note also a defered parameter can be defined in aperture macro,
|
||||||
|
* but outside aperture primitives. Example
|
||||||
|
* %AMRECTHERM*
|
||||||
|
* $4=$3/2* parameter $4 is half value of parameter $3
|
||||||
|
* 21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
|
||||||
|
* For the aperture primitive, parameters $1 to $3 will be defined in ADD command,
|
||||||
|
* and $4 is defined inside the macro
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +90,6 @@ public:
|
||||||
// the primitive
|
// the primitive
|
||||||
bool m_GerbMetric; // units for this primitive:
|
bool m_GerbMetric; // units for this primitive:
|
||||||
// false = Inches, true = metric
|
// false = Inches, true = metric
|
||||||
|
|
||||||
public: AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
|
public: AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
|
||||||
{
|
{
|
||||||
primitive_id = aId;
|
primitive_id = aId;
|
||||||
|
@ -167,6 +173,26 @@ struct APERTURE_MACRO
|
||||||
wxString name; ///< The name of the aperture macro
|
wxString name; ///< The name of the aperture macro
|
||||||
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
||||||
|
|
||||||
|
/* A defered parameter can be defined in aperture macro,
|
||||||
|
* but outside aperture primitives. Example
|
||||||
|
* %AMRECTHERM*
|
||||||
|
* $4=$3/2* parameter $4 is half value of parameter $3
|
||||||
|
* m_localparamStack handle a list of local defered parameters
|
||||||
|
*/
|
||||||
|
AM_PARAMS m_localparamStack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function GetLocalParam
|
||||||
|
* Usually, parameters are defined inside the aperture primitive
|
||||||
|
* using immediate mode or defered mode.
|
||||||
|
* in defered mode the value is defined in a DCODE that want to use the aperture macro.
|
||||||
|
* But some parameters are defined outside the aperture primitive
|
||||||
|
* and are local to the aperture macro
|
||||||
|
* @return the value of a defered parameter defined inside the aperture macro
|
||||||
|
* @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
|
||||||
|
*/
|
||||||
|
double GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DrawApertureMacroShape
|
* Function DrawApertureMacroShape
|
||||||
* Draw the primitive shape for flashed items.
|
* Draw the primitive shape for flashed items.
|
||||||
|
|
|
@ -146,7 +146,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
APERTURE_MACRO* GetMacro() { return m_Macro; }
|
APERTURE_MACRO* GetMacro() const { return m_Macro; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ShowApertureType
|
* Function ShowApertureType
|
||||||
|
|
|
@ -837,12 +837,15 @@ bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
|
||||||
// it can be: a parameter declaration like $1=$2/4
|
// it can be: a parameter declaration like $1=$2/4
|
||||||
// or a digit (macro primitive selection)
|
// or a digit (macro primitive selection)
|
||||||
// all other symbols are illegal.
|
// all other symbols are illegal.
|
||||||
if( *text == '$' ) // parameter declaration, not yet supported
|
if( *text == '$' ) // local parameter declaration, inside the aperture macro
|
||||||
{
|
{
|
||||||
msg.Printf( wxT( "RS274X: Aperture Macro \"%s\": Operator $ not yet supported here, line: \"%s\"" ),
|
am.m_localparamStack.push_back( AM_PARAM() );
|
||||||
GetChars( am.name ), GetChars( CONV_FROM_UTF8( buff ) ) );
|
AM_PARAM& param = am.m_localparamStack.back();
|
||||||
ReportMessage( msg );
|
text = GetNextLine( buff, text, gerber_file );
|
||||||
primitive_type = AMP_COMMENT;
|
if( text == NULL) // End of File
|
||||||
|
return false;
|
||||||
|
param.ReadParam( text );
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if( !isdigit(*text) ) // Ill. symbol
|
else if( !isdigit(*text) ) // Ill. symbol
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,7 +48,7 @@ typedef boost::ulong_long_type polygon_ulong_long_type;
|
||||||
#include <boost/mpl/or.hpp>
|
#include <boost/mpl/or.hpp>
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
#define BOOST_POLYGON_MSVC
|
#define BOOST_POLYGON_MSVC
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ICC
|
#ifdef __ICC
|
||||||
|
@ -290,7 +290,7 @@ namespace boost { namespace polygon{
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct gtl_if {
|
struct gtl_if {
|
||||||
#ifdef WIN32
|
#ifdef BOOST_POLYGON_MSVC
|
||||||
typedef gtl_no type;
|
typedef gtl_no type;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -1170,7 +1170,7 @@ namespace boost { namespace polygon{
|
||||||
//odd count implies boundary condition
|
//odd count implies boundary condition
|
||||||
if(counts[0] % 2 || counts[1] % 2) return consider_touch;
|
if(counts[0] % 2 || counts[1] % 2) return consider_touch;
|
||||||
//an odd number of edges to the left implies interior pt
|
//an odd number of edges to the left implies interior pt
|
||||||
return counts[0] % 4 != 0;
|
return counts[winding(polygon) == COUNTERCLOCKWISE ? 0 : 1] % 4 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: refactor to expose as user APIs
|
//TODO: refactor to expose as user APIs
|
||||||
|
|
Loading…
Reference in New Issue