Gerbview: better support of advanced X2 attributes.

This commit is contained in:
jean-pierre charras 2016-08-01 19:47:35 +02:00
parent 84cfef1de9
commit 984146c37d
8 changed files with 221 additions and 70 deletions

112
gerbview/attributes.h Normal file
View File

@ -0,0 +1,112 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef ATTRIBUTES_H
#define ATTRIBUTES_H
// this class handle info which can be added in a gerber file as attribute
// of an obtect
// the GBR_INFO_TYPE types can be OR'ed to add 2 (or more) attributes
// There are only 3 net attributes attached to an object by the %TO command
// %TO.CN
// %TO.N
// %TO.C
// the .CN attribute can be used only for flashed pads (using the D03 command)
// and only for external copper layers, if the component is on a external copper layer
// for other copper layer items (pads on internal layers, tracks ... ), only .N and .C
// can be used
class GBR_NETLIST_METADATA
{
public:
enum GBR_NETINFO_TYPE
{
GBR_NETINFO_UNSPECIFIED, ///< idle command (no command)
GBR_NETINFO_FLASHED_PAD, ///< print info associated to a flashed pad (TO.CN attribute)
GBR_NETINFO_NET, ///< print info associated to a net (TO.N attribute)
GBR_NETINFO_COMPONENT, ///< print info associated to a footprint (TO.C attribute)
GBR_NETINFO_NET_AND_CMP ///< combine GBR_INFO_NET and GBR_INFO_NET_AND_COMPONENT
///< to add both TO.N and TO.C attributes
};
// these members are used in the %TO object attributes command.
GBR_NETINFO_TYPE m_NetAttribType; ///< the type of net info
///< (used to define the gerber string to create)
wxString m_Padname; ///< for a flashed pad: the pad name ((TO.CN attribute)
wxString m_ComponentRef; ///< the footprint reference parent of the data
wxString m_Netname; ///< for items associated to a net: the netname
GBR_NETLIST_METADATA(): m_NetAttribType( GBR_NETINFO_UNSPECIFIED )
{
}
/*
* remove the net attribute specified by aName
* If aName == NULL or empty, remove all attributes
*/
void ClearAttribute( const wxString* aName )
{
if( m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED )
return;
if( !aName || aName->IsEmpty() )
{
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED;
m_Padname.clear();
m_ComponentRef.clear();
m_Netname.clear();
}
if( aName && *aName == ".CN" )
{
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED;
m_Padname.clear();
m_ComponentRef.clear();
m_Netname.clear();
}
if( aName && *aName == ".C" )
{
if( m_NetAttribType == GBR_NETINFO_COMPONENT )
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED;
else
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET;
m_ComponentRef.clear();
}
if( aName && *aName == ".N" )
{
if( m_NetAttribType == GBR_NETINFO_NET )
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED;
else
m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT;
m_Netname.clear();
}
}
};
#endif // #define ATTRIBUTES_H

View File

@ -484,13 +484,21 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_RECT* aClipBox,
void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{ {
wxString msg; wxString msg;
wxString text;
msg = ShowGBRShape(); msg = ShowGBRShape();
aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
// Display D_Code value: // Display D_Code value:
msg.Printf( wxT( "%d" ), m_DCode ); msg.Printf( _( "D Code %d" ), m_DCode );
aList.push_back( MSG_PANEL_ITEM( _( "D Code" ), msg, RED ) ); D_CODE* apertDescr = GetDcodeDescr();
if( apertDescr->m_AperFunction.IsEmpty() )
text = _( "No attribute" );
else
text = apertDescr->m_AperFunction;
aList.push_back( MSG_PANEL_ITEM( msg, text, RED ) );
// Display graphic layer number // Display graphic layer number
msg.Printf( wxT( "%d" ), GetLayer() + 1 ); msg.Printf( wxT( "%d" ), GetLayer() + 1 );
@ -518,31 +526,36 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) ); aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) );
// Display net info, if exists // Display net info, if exists
switch( m_NetAttribute.m_TypeNetAttribute ) switch( m_NetAttribute.m_NetAttribType )
{ {
default: default:
case 0: case GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED:
break; break;
case 1: // .CN attribute case GBR_NETLIST_METADATA::GBR_NETINFO_FLASHED_PAD: // .CN attribute
{
msg = _( "Net:" ); msg = _( "Net:" );
msg << " " << m_NetAttribute.m_NetAttrNetname; msg << " " << m_NetAttribute.m_Netname;
wxString text; text.Printf( _( "Pad: '%s' (Cmp: '%s')" ), GetChars( m_NetAttribute.m_Padname ),
text.Printf( _( "Pad: '%s' (Cmp: '%s')" ), GetChars( m_NetAttribute.m_NetAttrPadname ), GetChars( m_NetAttribute.m_ComponentRef ) );
GetChars( m_NetAttribute.m_NetAttrCmpReference ) );
aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) ); aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) );
}
break; break;
case 2: // .N attribute case GBR_NETLIST_METADATA::GBR_NETINFO_NET: // .N attribute
aList.push_back( MSG_PANEL_ITEM( _( "Net name:" ), aList.push_back( MSG_PANEL_ITEM( _( "Net:" ),
m_NetAttribute.m_NetAttrNetname, CYAN ) ); m_NetAttribute.m_Netname, CYAN ) );
break; break;
case 3: // .C attribute case GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT: // .C attribute
aList.push_back( MSG_PANEL_ITEM( _( "Cmp reference:" ), aList.push_back( MSG_PANEL_ITEM( _( "Ref:" ),
m_NetAttribute.m_NetAttrCmpReference, CYAN ) ); m_NetAttribute.m_ComponentRef, CYAN ) );
break;
case GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP: // .C and .N attribute
msg = _( "Net:" );
msg << " " << m_NetAttribute.m_Netname;
text =_( "Ref:" );
text << m_NetAttribute.m_ComponentRef;
aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) );
break; break;
} }
} }

View File

@ -33,6 +33,7 @@
#include <dlist.h> #include <dlist.h>
#include <layers_id_colors_and_visibility.h> #include <layers_id_colors_and_visibility.h>
#include <gr_basic.h> #include <gr_basic.h>
#include <attributes.h>
#include <dcode.h> #include <dcode.h>
class GERBER_FILE_IMAGE; class GERBER_FILE_IMAGE;
@ -91,9 +92,9 @@ public:
* so they are stored inside this item if there is no * so they are stored inside this item if there is no
* redundancy for these parameters * redundancy for these parameters
*/ */
NET_ATTRIBUTES m_NetAttribute; ///< the string given by a %TO attribute set in aperture GBR_NETLIST_METADATA m_NetAttribute; ///< the string given by a %TO attribute set in aperture
///< (dcode). Stored in each item, because %TO is ///< (dcode). Stored in each item, because %TO is
///< a dynamic attribute ///< a dynamic object attribute
private: private:
// These values are used to draw this item, according to gerber layers parameters // These values are used to draw this item, according to gerber layers parameters

View File

@ -358,3 +358,19 @@ void GERBER_FILE_IMAGE::DisplayImageInfo( GERBVIEW_FRAME* aMainFrame )
aMainFrame->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED ); aMainFrame->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED );
} }
void GERBER_FILE_IMAGE::RemoveAttribute( X2_ATTRIBUTE& aAttribute )
{
/* Called when a %TD command is found
* Remove the attribute specified by the %TD command.
* is no attribute, all current attributes specified by the %TO and the %TA
* commands are cleared.
* if a attribute name is specified (for instance %TD.CN*%) is specified,
* only this attribute is cleared
*/
m_NetAttributeDict.ClearAttribute( &aAttribute.GetPrm( 1 ) );
if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" )
m_AperFunction.Clear();
}

View File

@ -31,6 +31,7 @@
#include <dcode.h> #include <dcode.h>
#include <class_gerber_draw_item.h> #include <class_gerber_draw_item.h>
#include <class_aperture_macro.h> #include <class_aperture_macro.h>
#include <attributes.h>
// An useful macro used when reading gerber files; // An useful macro used when reading gerber files;
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \ #define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
@ -61,8 +62,10 @@ class D_CODE;
*/ */
class GERBER_FILE_IMAGE; class GERBER_FILE_IMAGE;
class X2_ATTRIBUTE;
class X2_ATTRIBUTE_FILEFUNCTION; class X2_ATTRIBUTE_FILEFUNCTION;
class GERBER_LAYER class GERBER_LAYER
{ {
friend class GERBER_FILE_IMAGE; friend class GERBER_FILE_IMAGE;
@ -158,6 +161,10 @@ public:
APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name
GBR_NETLIST_METADATA m_NetAttributeDict; // the net attributes set by a %TO.CN, %TO.C and/or %TO.N
// add object attribute command.
wxString m_AperFunction; // the aperture function set by a %TA.AperFunction, xxx
// (stores thre xxx value).
private: private:
wxArrayString m_messagesList; // A list of messages created when reading a file wxArrayString m_messagesList; // A list of messages created when reading a file
int m_hasNegativeItems; // true if the image is negative or has some negative items int m_hasNegativeItems; // true if the image is negative or has some negative items
@ -330,6 +337,18 @@ public:
* @param aMainFrame = the GERBVIEW_FRAME to display messages * @param aMainFrame = the GERBVIEW_FRAME to display messages
*/ */
void DisplayImageInfo( GERBVIEW_FRAME* aMainFrame ); void DisplayImageInfo( GERBVIEW_FRAME* aMainFrame );
/**
* Function RemoveAttribute.
* Called when a %TD command is found the Gerber file
* @param aAttribute is the X2_ATTRIBUTE which stores the full command
* Remove the attribute specified by the %TD command.
* is no attribute, all current attributes specified by the %TO and the %TA
* commands are cleared.
* if a attribute name is specified (for instance %TD.CN*%) is specified,
* only this attribute is cleared
*/
void RemoveAttribute( X2_ATTRIBUTE& aAttribute );
}; };
#endif // ifndef CLASS_GERBER_FILE_IMAGE_H #endif // ifndef CLASS_GERBER_FILE_IMAGE_H

View File

@ -70,28 +70,6 @@ enum APERTURE_DEF_HOLETYPE {
struct APERTURE_MACRO; struct APERTURE_MACRO;
// helper class to handle a net attribute for a given D_CODE
// net attributesare given by the %TO command following a Dn command (n >= 10)
// This net attribute is dynamic, so it need to be also stored in each gerber item
struct NET_ATTRIBUTES
{
int m_TypeNetAttribute; ///< identify %TO.N %TO.C or TO.CN net attribute
///< 0 = no attribute, 1 = .CN, 2 =.N 3=.C
wxString m_NetAttrNetname;
wxString m_NetAttrPadname;
wxString m_NetAttrCmpReference;
NET_ATTRIBUTES(): m_TypeNetAttribute( 0 ) {}
void RemoveAttribute() ///< Clear all strings
{
m_TypeNetAttribute = 0; // no attribute
m_NetAttrNetname.Empty();
m_NetAttrPadname.Empty();
m_NetAttrCmpReference.Empty();
}
};
/** /**
* Class D_CODE * Class D_CODE
@ -125,7 +103,8 @@ public:
bool m_InUse; ///< false if the aperure (previously defined) bool m_InUse; ///< false if the aperure (previously defined)
///< is not used to draw something ///< is not used to draw something
bool m_Defined; ///< false if the aperture is not defined in the header bool m_Defined; ///< false if the aperture is not defined in the header
NET_ATTRIBUTES m_NetAttribute; ///< the dynamic net info currently attached to the D_CODE wxString m_AperFunction; ///< the aperture attribute (created by a %TA.AperFunction command)
///< attached to the D_CODE
public: public:

View File

@ -118,11 +118,7 @@ void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->SetLayerPolarity( aLayerNegative ); aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_Flashed = true; aGbrItem->m_Flashed = true;
aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict;
D_CODE* aperture = aGbrItem->GetDcodeDescr();
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
switch( aAperture ) switch( aAperture )
{ {
@ -179,10 +175,7 @@ void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->SetLayerPolarity( aLayerNegative ); aGbrItem->SetLayerPolarity( aLayerNegative );
D_CODE* aperture = aGbrItem->GetDcodeDescr(); aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict;
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
} }
@ -228,10 +221,7 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index,
aGbrItem->m_Size = aPenSize; aGbrItem->m_Size = aPenSize;
aGbrItem->m_Flashed = false; aGbrItem->m_Flashed = false;
D_CODE* aperture = aGbrItem->GetDcodeDescr(); aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict;
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
if( aMultiquadrant ) if( aMultiquadrant )
center = aStart + aRelCenter; center = aStart + aRelCenter;
@ -362,6 +352,8 @@ static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
aStart, aEnd, rel_center, wxSize(0, 0), aStart, aEnd, rel_center, wxSize(0, 0),
aClockwise, aMultiquadrant, aLayerNegative ); aClockwise, aMultiquadrant, aLayerNegative );
aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict;
wxPoint center; wxPoint center;
center = dummyGbrItem.m_ArcCentre; center = dummyGbrItem.m_ArcCentre;

View File

@ -126,14 +126,21 @@ enum RS274X_PARAMETERS {
static int ReadXCommand( char*& text ) static int ReadXCommand( char*& text )
{ {
int result; int result;
int currbyte;
if( text && *text ) if( text && *text )
result = *text++ << 8; {
currbyte = *text++;
result = ( currbyte & 0xFF ) << 8;
}
else else
return -1; return -1;
if( text && *text ) if( text && *text )
result += *text++; {
currbyte = *text++;
result += currbyte & 0xFF;
}
else else
return -1; return -1;
@ -426,32 +433,42 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
{ {
X2_ATTRIBUTE dummy; X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
if( dummy.GetAttribute() == ".AperFunction" )
m_AperFunction = dummy.GetPrm( 1 );
} }
break; break;
case NET_ATTRIBUTE: // Command %TO ... case NET_ATTRIBUTE: // Command %TO currently %TO.CN %TO.N and %TO.C
{ {
X2_ATTRIBUTE dummy; X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
D_CODE* tool = GetDCODE( m_Current_Tool, false );
tool->m_NetAttribute.RemoveAttribute();
if( dummy.GetAttribute() == ".CN" ) if( dummy.GetAttribute() == ".CN" )
{ {
tool->m_NetAttribute.m_TypeNetAttribute = 1; m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_FLASHED_PAD;
tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) ); m_NetAttributeDict.m_ComponentRef = fromGerberString( dummy.GetPrm( 1 ) );
tool->m_NetAttribute.m_NetAttrPadname = fromGerberString( dummy.GetPrm( 2 ) ); m_NetAttributeDict.m_Padname = fromGerberString( dummy.GetPrm( 2 ) );
tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 3 ) ); m_NetAttributeDict.m_Netname = fromGerberString( dummy.GetPrm( 3 ) );
} }
else if( dummy.GetAttribute() == ".N" ) else if( dummy.GetAttribute() == ".N" )
{ {
tool->m_NetAttribute.m_TypeNetAttribute = 2; if( m_NetAttributeDict.m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT )
tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 1 ) ); m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP;
else
m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET;
m_NetAttributeDict.m_Netname = fromGerberString( dummy.GetPrm( 1 ) );
} }
else if( dummy.GetAttribute() == ".C" ) else if( dummy.GetAttribute() == ".C" )
{ {
tool->m_NetAttribute.m_TypeNetAttribute = 3; if( m_NetAttributeDict.m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_NET )
tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) ); m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP;
else
m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT;
m_NetAttributeDict.m_ComponentRef = fromGerberString( dummy.GetPrm( 1 ) );
} }
} }
break; break;
@ -460,8 +477,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
{ {
X2_ATTRIBUTE dummy; X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
D_CODE* tool = GetDCODE( m_Current_Tool, false ); RemoveAttribute( dummy );
tool->m_NetAttribute.RemoveAttribute();
} }
break; break;
@ -739,9 +755,12 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
D_CODE* dcode; D_CODE* dcode;
dcode = GetDCODE( code ); dcode = GetDCODE( code );
if( dcode == NULL ) if( dcode == NULL )
break; break;
dcode->m_AperFunction = m_AperFunction;
// at this point, text points to character after the ADD<num>, // at this point, text points to character after the ADD<num>,
// i.e. R in example above. If text[0] is one of the usual // i.e. R in example above. If text[0] is one of the usual
// apertures: (C,R,O,P), there is a comma after it. // apertures: (C,R,O,P), there is a comma after it.