Gerbview: Added support of arcs in polygons outlines. Need more tests, but works.

This commit is contained in:
charras 2010-01-08 12:28:13 +00:00
parent 32dfdb4844
commit c4b37d77bd
13 changed files with 4423 additions and 49 deletions

View File

@ -3,6 +3,15 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with
email address.
2010-Jan-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++Gerbview
Added support of arcs in polygons outlines.
Needed to show copper areas in some gerber files
Not fully tested but works better than without this support...
2010-Jan-03 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew

View File

@ -6,7 +6,7 @@
#endif
#ifndef KICAD_BUILD_VERSION
#define KICAD_BUILD_VERSION "(2010-01-05)"
#define KICAD_BUILD_VERSION "(2010-01-08)"
#endif
#define VERSION_STABILITY "unstable"

View File

@ -166,7 +166,7 @@ void DIALOG_EESCHEMA_CONFIG::OnOkClick( wxCommandEvent& event )
WinEDA_LibeditFrame::EnsureActiveLibExists();
}
m_Parent->SaveProjectFile( this );
m_Parent->SaveProjectFile( this, false );
EndModal( wxID_OK );
}

View File

@ -43,7 +43,7 @@ void WinEDA_SchematicFrame::Process_Config( wxCommandEvent& event )
break;
case ID_CONFIG_SAVE:
SaveProjectFile( this );
SaveProjectFile( this, false );
break;
case ID_CONFIG_READ:
@ -316,16 +316,18 @@ bool WinEDA_SchematicFrame::LoadProjectFile( const wxString& CfgFileName,
/*
* Save the Kicad project file (*.pro) settings specific to EESchema.
*/
void WinEDA_SchematicFrame::SaveProjectFile( wxWindow* displayframe )
void WinEDA_SchematicFrame::SaveProjectFile( wxWindow* displayframe, bool askoverwrite )
{
wxFileName fn;
fn = g_RootSheet->m_AssociatedScreen->m_FileName /*ConfigFileName*/;
fn.SetExt( ProjectFileExtension );
int options = wxFD_SAVE;
if( askoverwrite )
options |= wxFD_OVERWRITE_PROMPT;
wxFileDialog dlg( this, _( "Save Project Settings" ), wxGetCwd(),
fn.GetFullName(), ProjectFileWildcard,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
fn.GetFullName(), ProjectFileWildcard, options );
if( dlg.ShowModal() == wxID_CANCEL )
return;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
*
%FSLAX35Y35*%
%MOMM*%
%ADD10C,0.085000*%
%ADD11C,1.000000*%
%IPPOS*%
%LNl2p*%
%LPD*%
%SRX1Y1I0J0*%
G01*
G75*
G36*
X-824649Y824737D02*
X-824642Y824746D01*
X-824637Y824748D01*
X-600285Y824596D01*
G02X-596337Y813997I0J-6035D01*
G01X-596759Y813502D01*
X-599070Y812402D01*
X-599079Y812403D01*
X-600633Y812842D01*
G03X-591714Y760887I-18257J-29877D01*
G01X-589396Y761987D01*
X-587850Y761553D01*
G03X-543350Y814584I18275J29851D01*
G02X-538846Y824554I4504J3968D01*
G01X-387906Y824445D01*
X-387901Y824439D01*
X-387898Y718310D01*
X-387892Y718296D01*
X-387887Y718290D01*
X-337968Y678268D01*
X-337966Y678263D01*
X-337746Y625972D01*
G02X-347743Y621473I-6001J-23D01*
G03X-394478Y621365I-23307J-26119D01*
G02X-402955Y621809I-4016J4477D01*
G01X-407368Y626784D01*
X-409076Y628288D01*
G02X-406164Y638849I3817J4630D01*
G03X-421754Y706900I-5285J34600D01*
G01X-699601D01*
G03X-766967Y720229I-35002J0D01*
G02X-771614Y718929I-2844J1211D01*
G03X-817118Y687087I-10523J-33398D01*
G03X-817151Y685566I34972J-1522D01*
G01X-823562D01*
X-824649Y824737D01*
G37*
M02*

View File

@ -19,15 +19,11 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
if( GetBoard() == NULL )
return FALSE;
if( query )
{
if( GetBoard()->m_Drawings || GetBoard()->m_Track
|| GetBoard()->m_Zone )
if( query && GetScreen()->IsModify() )
{
if( !IsOK( this, _( "Current data will be lost?" ) ) )
return FALSE;
}
}
GetBoard()->m_Drawings.DeleteAll();

View File

@ -115,7 +115,6 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
char* text;
int layer; /* current layer used in gerbview */
GERBER* gerber;
wxPoint pos;
int error = 0;
layer = GetScreen()->m_Active_Layer;
@ -201,7 +200,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
case 'X':
case 'Y': /* Move or draw command */
pos = gerber->ReadXYCoord( text );
gerber->m_CurrentPos = gerber->ReadXYCoord( text );
if( *text == '*' ) // command like X12550Y19250*
{
gerber->Execute_DCODE_Command( this, text,
@ -211,7 +210,7 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
case 'I':
case 'J': /* Auxiliary Move command */
pos = gerber->ReadIJCoord( text );
gerber->m_IJPos = gerber->ReadIJCoord( text );
break;
case '%':

View File

@ -9,8 +9,11 @@
#include "macros.h"
#include "gerbview.h"
#include "pcbplot.h"
#include "trigo.h"
#include "protos.h"
#include <math.h>
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
|| ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) )
@ -373,13 +376,143 @@ static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
}
/**
* Function fillArcPOLY
* creates an arc G code when found in poly outlines.
* <p>
* if multiquadrant == true : arc can be 0 to 360 degrees
* and \a rel_center is the center coordinate relative to start point.
* <p>
* if multiquadrant == false arc can be only 0 to 90 deg,
* and only in the same quadrant :
* <ul>
* <li> absolute angle 0 to 90 (quadrant 1) or
* <li> absolute angle 90 to 180 (quadrant 2) or
* <li> absolute angle 180 to 270 (quadrant 3) or
* <li> absolute angle 270 to 0 (quadrant 4)
* </ul><p>
* @param aPcb is the board.
* @param aLayer is the layer index to set into the TRACK
* @param aStart is the starting point
* @param aEnd is the ending point
* @param rel_center is the center coordinate relative to start point,
* given in ABSOLUTE VALUE and the sign of values x et y de rel_center
* must be calculated from the previously given constraint: arc only in the
* same quadrant.
* @param aDiameter The diameter of the round flash
* @param aWidth is the pen width.
* @param isDark True if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
* @return a pointer to the first segment created
*/
static SEGZONE * fillArcPOLY( BOARD * aPcb, int aLayer,
const wxPoint& aStart, const wxPoint& aEnd,
const wxPoint& rel_center,
bool clockwise, bool multiquadrant, bool isDark )
{
/* in order to calculate arc parameters, we use fillArcTRACK
* so we muse create a dummy track and use its geometric parmeters
*/
static TRACK dummyTrack(NULL);
SEGZONE * firstSegment = NULL;
fillArcTRACK( &dummyTrack, 0, aLayer,
aStart, aEnd,
rel_center, 0,
clockwise, multiquadrant, isDark );
// dummyTrack has right geometric parameters, and has its Y coordinates negated (to match the pcbnew Y axis).
// Approximate arc by 36 segments per 360 degree
const int increment_angle = 360/36;
wxPoint center;
center.x = dummyTrack.m_Param;
center.y = dummyTrack.GetSubNet();
// Calculate relative coordinates;
wxPoint start = dummyTrack.m_Start - center;
wxPoint end = dummyTrack.m_End - center;
/* Calculate angle arc
* angle is here clockwise because Y axis is reversed
*/
double start_angle =
atan2( (double)start.y, (double)start.x );
start_angle = 180 * start_angle / M_PI;
double end_angle =
atan2( (double)end.y , (double)end.x );
end_angle = 180 * end_angle / M_PI;
double angle = start_angle - end_angle;
// D( printf( " >>>> st %d,%d angle %f, end %d,%d angle %f delta %f\n",
// start.x, start.y, start_angle, end.x, end.y, end_angle, angle ) );
if( !clockwise )
{
EXCHG(start, end);
D( printf( " >>>> reverse arc\n") );
}
// Normalize angle
while ( angle > 360.0 )
angle -= 360.0;
while ( angle < 0.0 )
angle += 360.0;
int count = (int) (angle / increment_angle );
if( count <= 0 )
count = 1;
// D( printf( " >>>> angle %f, cnt %d sens %d\n", angle, count, clockwise ) );
// calculate segments
wxPoint start_arc = start;
for( int ii = 1; ii <= count; ii++ )
{
wxPoint end_arc = start;
int rot = 10 * ii * increment_angle; // rot is in 0.1 deg
if( ii < count )
{
if( clockwise )
RotatePoint(&end_arc, rot);
else
RotatePoint(&end_arc, -rot);
}
else
end_arc = end;
SEGZONE * edge_poly = new SEGZONE( aPcb );
if( firstSegment == NULL )
firstSegment = edge_poly;
aPcb->m_Zone.Append( edge_poly );
// D( printf( " >> Add arc %d rot %d, edge poly item %d,%d to %d,%d\n",
// ii, rot, start_arc.x, start_arc.y,end_arc.x, end_arc.y ); )
edge_poly->SetLayer( aLayer );
edge_poly->m_Width = 1;
edge_poly->m_Start = start_arc + center;
edge_poly->m_End = end_arc + center;
// the first track of each polygon has a netcode of zero,
// otherwise one.
// set netcode to 1. the calling function is responsible
// to set the first point to 0
edge_poly->SetNet( 1 );
if( !isDark )
{
edge_poly->m_Flags |= DRAW_ERASED;
}
start_arc = end_arc;
}
return firstSegment;
}
/* These routines read the text string point from Text.
* After use, advanced Text the beginning of the sequence unread
*/
/* Returns the current coord pointed to by Text (XnnnnYmmmm)
*/
wxPoint GERBER::ReadXYCoord( char*& Text )
{
wxPoint pos = m_CurrentPos;
@ -748,12 +881,12 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
break;
case GC_SPECIFY_ABSOLUES_COORD:
m_Relative = false; // false = absolute Coord, RUE = relative
m_Relative = false; // false = absolute Coord, true = relative
// Coord
break;
case GC_SPECIFY_RELATIVEES_COORD:
m_Relative = true; // false = absolute Coord, RUE = relative
m_Relative = true; // false = absolute Coord, true = relative
// Coord
break;
@ -888,15 +1021,33 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
if( m_PolygonFillMode ) // Enter a polygon description:
{
SEGZONE* edge_poly;
switch( D_commande )
{
case 1: // code D01 Draw line, exposure ON
m_Exposure = true;
SEGZONE* edge_poly;
switch( m_Iterpolation )
{
case GERB_INTERPOL_ARC_NEG:
case GERB_INTERPOL_ARC_POS:
D( printf( "Add arc poly %d,%d to %d,%d fill %d interpol %d 360_enb %d\n",
m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x,
m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); )
edge_poly = fillArcPOLY( pcb, activeLayer, m_PreviousPos,
m_CurrentPos, m_IJPos,
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
false : true, m_360Arc_enbl,
!(m_LayerNegative ^ m_ImageNegative) );
edge_poly->SetNet( m_PolygonFillModeState );
break;
default:
edge_poly = new SEGZONE( pcb );
pcb->m_Zone.Append( edge_poly );
D( printf( "R:%p\n", edge_poly ); )
D( printf( "Add poly edge %d,%d to %d,%d fill %d\n",
m_PreviousPos.x, m_PreviousPos.y,
m_CurrentPos.x, m_CurrentPos.y, m_Iterpolation ); )
edge_poly->SetLayer( activeLayer );
edge_poly->m_Width = 1;
@ -918,6 +1069,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
edge_poly->m_Flags |= DRAW_ERASED;
D( printf( "\nm_Flags=0x%08X\n", edge_poly->m_Flags ); )
}
break;
}
m_PreviousPos = m_CurrentPos;
m_PolygonFillModeState = 1;

View File

@ -89,7 +89,7 @@ public:
void GeneralControle( wxDC* DC, wxPoint MousePositionInPixels );
PARAM_CFG_ARRAY& GetProjectFileParameters( void );
void SaveProjectFile( wxWindow* displayframe );
void SaveProjectFile( wxWindow* displayframe, bool askoverwrite = true );
bool LoadProjectFile( const wxString& CfgFileName, bool ForceRereadConfig );
PARAM_CFG_ARRAY& GetConfigurationSettings( void );

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 29 2008)
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -50,6 +50,7 @@ DIALOG_LAYERS_SETUP_BASE::DIALOG_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID
bCaptionsSizer = new wxBoxSizer( wxHORIZONTAL );
m_TitlePanel = new wxPanel( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxRAISED_BORDER|wxTAB_TRAVERSAL );
m_TitlePanel->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_CAPTIONTEXT ) );
m_TitlePanel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVECAPTION ) );
bCaptionsSizer->Add( m_TitlePanel, 1, wxEXPAND, 5 );

View File

@ -245,7 +245,7 @@
<property name="bg">wxSYS_COLOUR_ACTIVECAPTION</property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="fg">wxSYS_COLOUR_CAPTIONTEXT</property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 29 2008)
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!