Gerbview: Add %TO (Netlist attribute) support in X2 format. Fix a bug in a not previously very used method.

This commit is contained in:
jean-pierre charras 2016-07-27 15:27:19 +02:00
parent 62bf20271b
commit ff246f6365
7 changed files with 188 additions and 16 deletions

View File

@ -74,13 +74,13 @@ const wxString& X2_ATTRIBUTE::GetPrm( int aIdx)
{
static const wxString dummy;
if( GetPrmCount() < aIdx && aIdx >= 0 )
if( GetPrmCount() > aIdx && aIdx >= 0 )
return m_Prms.Item( aIdx );
return dummy;
}
// Debug function: pring using wxLogMessage le list of parameters
// Debug function: pring using wxLogMessage the list of parameters
void X2_ATTRIBUTE::DbgListPrms()
{
wxLogMessage( wxT("prms count %d"), GetPrmCount() );

View File

@ -516,6 +516,35 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
// Display AB axis swap (item specific)
msg = m_swapAxis ? wxT( "A=Y B=X" ) : wxT( "A=X B=Y" );
aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) );
// Display net info, if exists
switch( m_NetAttribute.m_TypeNetAttribute )
{
default:
case 0:
break;
case 1: // .CN attribute
{
msg = _( "Net:" );
msg << " " << m_NetAttribute.m_NetAttrNetname;
wxString text;
text.Printf( _( "Pad: '%s' (Cmp: '%s')" ), GetChars( m_NetAttribute.m_NetAttrPadname ),
GetChars( m_NetAttribute.m_NetAttrCmpReference ) );
aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) );
}
break;
case 2: // .N attribute
aList.push_back( MSG_PANEL_ITEM( _( "Net name:" ),
m_NetAttribute.m_NetAttrNetname, CYAN ) );
break;
case 3: // .C attribute
aList.push_back( MSG_PANEL_ITEM( _( "Cmp reference:" ),
m_NetAttribute.m_NetAttrCmpReference, CYAN ) );
break;
}
}

View File

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

View File

@ -1,9 +1,9 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
* 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

View File

@ -70,10 +70,32 @@ enum APERTURE_DEF_HOLETYPE {
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
* holds a gerber DCODE definition.
* holds a gerber DCODE (also called Aperture) definition.
*/
class D_CODE
{
@ -92,16 +114,19 @@ private:
*/
public:
wxSize m_Size; /* Horizontal and vertical dimensions. */
APERTURE_T m_Shape; /* shape ( Line, rectangle, circle , oval .. ) */
int m_Num_Dcode; /* D code ( >= 10 ) */
wxSize m_Drill; /* dimension of the hole (if any) */
APERTURE_DEF_HOLETYPE m_DrillShape; /* shape of the hole (0 = no hole, round = 1, rect = 2) */
double m_Rotation; /* shape rotation in degrees */
int m_EdgesCount; /* in aperture definition Polygon only: number of edges for the polygon */
bool m_InUse; /* false if not used */
bool m_Defined; /* false if not defined */
wxString m_SpecialDescr;
wxSize m_Size; ///< Horizontal and vertical dimensions.
APERTURE_T m_Shape; ///< shape ( Line, rectangle, circle , oval .. )
int m_Num_Dcode; ///< D code value ( >= 10 )
wxSize m_Drill; ///< dimension of the hole (if any) (draill file)
APERTURE_DEF_HOLETYPE m_DrillShape; ///< shape of the hole (0 = no hole, round = 1, rect = 2) */
double m_Rotation; ///< shape rotation in degrees
int m_EdgesCount; ///< in aperture definition Polygon only:
///< number of edges for the polygon
bool m_InUse; ///< false if the aperure (previously defined)
///< is not used to draw something
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
public:
D_CODE( int num_dcode );

View File

@ -118,6 +118,12 @@ void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_DCode = Dcode_index;
aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_Flashed = true;
D_CODE* aperture = aGbrItem->GetDcodeDescr();
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
switch( aAperture )
{
case APT_POLYGON: // flashed regular polygon
@ -172,6 +178,11 @@ void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_DCode = Dcode_index;
aGbrItem->SetLayerPolarity( aLayerNegative );
D_CODE* aperture = aGbrItem->GetDcodeDescr();
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
}
@ -217,6 +228,11 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index,
aGbrItem->m_Size = aPenSize;
aGbrItem->m_Flashed = false;
D_CODE* aperture = aGbrItem->GetDcodeDescr();
if( aperture )
aGbrItem->m_NetAttribute = aperture->m_NetAttribute;
if( aMultiquadrant )
center = aStart + aRelCenter;
else

View File

@ -82,10 +82,23 @@ enum RS274X_PARAMETERS {
// X2 extention attribute commands
// Mainly are found standard attributes and user attributes
// standard attributes commands are:
// TF (file attribute)
// TF (file attribute) TO (net attribute)
// TA (aperture attribute) and TD (delete aperture attribute)
FILE_ATTRIBUTE = CODE( 'T', 'F' ),
// X2 extention Net attribute info
// Net attribute options are:
// TO (net attribute data): TO.CN ot TO.N or TO.C
NET_ATTRIBUTE = CODE( 'T', 'O' ),
// X2 extention Aperture attribute TA
APERTURE_ATTRIBUTE = CODE( 'T', 'A' ),
// TD (delete aperture attribute): TD (delete all) or TD.CN or TD.N or TD.C ...
// due to not yet fully defined,
// TD TD.CNr TD.N TD.C are delete all
REMOVE_APERTURE_ATTRIBUTE = CODE( 'T', 'D' ),
// Layer specific parameters
// May be used singly or may be layer specfic
// theses parameters are at the beginning of the file or layer
@ -127,6 +140,46 @@ static int ReadXCommand( char*& text )
return result;
}
/**
* convert a string read from a gerber file to an unicode string
* usual chars are just copied. \hhhh values are converted to
* the unicoade char value
*/
static const wxString fromGerberString( const wxString& aGbrString )
{
wxString text;
for( unsigned ii = 0; ii < aGbrString.size(); ++ii )
{
if( aGbrString[ii] == '\\' )
{
unsigned value = 0;
for( int jj = 0; jj < 4; jj++ )
{
ii++;
value <<= 4;
int digit = aGbrString[ii];
if( digit >= '0' && digit <= '9' )
digit -= '0';
else if( digit >= 'A' && digit <= 'F' )
digit -= 'A';
else if( digit >= 'a' && digit <= 'f' )
digit -= 'a';
else digit = 0;
value += digit && 0xFF;
}
text.Append( wxUniChar( value ) );
}
else
text.Append( aGbrString[ii] );
}
return text;
}
bool GERBER_FILE_IMAGE::ReadRS274XCommand( char* buff, char*& text )
{
@ -352,6 +405,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
{
X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
if( dummy.IsFileFunction() )
{
delete m_FileFunction;
@ -368,6 +422,49 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te
}
break;
case APERTURE_ATTRIBUTE: // Command %TA ... Not yet supported
{
X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
}
break;
case NET_ATTRIBUTE: // Command %TO ...
{
X2_ATTRIBUTE dummy;
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" )
{
tool->m_NetAttribute.m_TypeNetAttribute = 1;
tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) );
tool->m_NetAttribute.m_NetAttrPadname = fromGerberString( dummy.GetPrm( 2 ) );
tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 3 ) );
}
else if( dummy.GetAttribute() == ".N" )
{
tool->m_NetAttribute.m_TypeNetAttribute = 2;
tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 1 ) );
}
else if( dummy.GetAttribute() == ".C" )
{
tool->m_NetAttribute.m_TypeNetAttribute = 3;
tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) );
}
}
break;
case REMOVE_APERTURE_ATTRIBUTE: // Command %TD ...
{
X2_ATTRIBUTE dummy;
dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text );
D_CODE* tool = GetDCODE( m_Current_Tool, false );
tool->m_NetAttribute.RemoveAttribute();
}
break;
case OFFSET: // command: OFAnnBnn (nn = float number) = layer Offset
m_Offset.x = m_Offset.y = 0;
while( *text != '*' )