Gerbview code redesign
This commit is contained in:
parent
3ae0df15ee
commit
b992af3eb3
|
@ -4,6 +4,24 @@ KiCad ChangeLog 2010
|
|||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++gerbview:
|
||||
Important changes:
|
||||
graphic functions rewritten.
|
||||
graphics items are now specific to gerbview (added a GERBER_DRAW_ITEM class)
|
||||
and do not use tracks from pcbnew.
|
||||
The way used to draw them is also new.
|
||||
Apertures are now correctly drawn for round, oval and rectangular shapes
|
||||
(with or without holes)
|
||||
Aperture definition type Polygon is not yet handle.
|
||||
Polygons are correctly drawn.
|
||||
TODO:
|
||||
Draw functions for aperture definition type Polygon.
|
||||
Draw functions for aperture macros.
|
||||
Work in progress.
|
||||
|
||||
|
||||
2010-Aug-9 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
++CMakeModules:
|
||||
|
@ -67,7 +85,7 @@ email address.
|
|||
2010-jul-27, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
++all:
|
||||
Updated boost to version 1.43
|
||||
Updated boost to version 1.44
|
||||
Added boost::polygon (experimental)
|
||||
++pcbnew:
|
||||
Added experimental zone fill calculations with boost::polygon
|
||||
|
|
|
@ -58,6 +58,10 @@ int g_DrawBgColor = WHITE;
|
|||
void ClipAndDrawFilledPoly( EDA_Rect* ClipBox, wxDC * DC, wxPoint Points[], int n );
|
||||
#endif
|
||||
|
||||
static void GRSCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int width, int Color );
|
||||
static void GRSFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r,
|
||||
int width, int Color, int BgColor );
|
||||
|
||||
|
||||
extern BASE_SCREEN* ActiveScreen;
|
||||
|
||||
|
@ -1333,6 +1337,26 @@ void GRCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int Color )
|
|||
GRSCircle( ClipBox, DC, cx, cy, radius, 0, Color );
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a circle in object space.
|
||||
*/
|
||||
void GRCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int width, int Color )
|
||||
{
|
||||
r = ZoomValue( r );
|
||||
width = ZoomValue( width );
|
||||
GRSCircle( ClipBox, DC, GRMapX( x ), GRMapY( y ), r, width, Color );
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a circle in object space.
|
||||
*/
|
||||
void GRCircle( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aWidth, int aColor )
|
||||
{
|
||||
aRadius = ZoomValue( aRadius );
|
||||
aWidth = ZoomValue( aWidth );
|
||||
GRSCircle( aClipBox, aDC, GRMapX( aPos.x ), GRMapY( aPos.y ), aRadius, aWidth, aColor );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Draw a filled circle, in object space.
|
||||
|
@ -1346,6 +1370,14 @@ void GRFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r,
|
|||
Color, BgColor );
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a filled circle, in object space.
|
||||
*/
|
||||
void GRFilledCircle( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aColor )
|
||||
{
|
||||
aRadius = ZoomValue( aRadius );
|
||||
GRSFilledCircle( aClipBox, aDC, GRMapX( aPos.x ), GRMapY( aPos.y ), aRadius, 0, aColor, aColor );
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a filled circle, in drawing space.
|
||||
|
@ -1377,22 +1409,6 @@ void GRSFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Draw a circle in object space.
|
||||
*/
|
||||
void GRCircle( EDA_Rect* ClipBox,
|
||||
wxDC* DC,
|
||||
int x,
|
||||
int y,
|
||||
int r,
|
||||
int width,
|
||||
int Color )
|
||||
{
|
||||
r = ZoomValue( r );
|
||||
width = ZoomValue( width );
|
||||
GRSCircle( ClipBox, DC, GRMapX( x ), GRMapY( y ), r, width, Color );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Draw a circle in drawing space.
|
||||
|
|
|
@ -15,6 +15,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
|
|||
###
|
||||
set(GERBVIEW_SRCS
|
||||
block.cpp
|
||||
class_GERBER.cpp
|
||||
class_gerber_draw_item.cpp
|
||||
class_gerbview_layer_widget.cpp
|
||||
controle.cpp
|
||||
dcode.cpp
|
||||
|
@ -32,7 +34,6 @@ set(GERBVIEW_SRCS
|
|||
gerbview.cpp
|
||||
hotkeys.cpp
|
||||
initpcb.cpp
|
||||
lay2plot.cpp
|
||||
locate.cpp
|
||||
menubar.cpp
|
||||
onrightclick.cpp
|
||||
|
|
|
@ -2,6 +2,30 @@
|
|||
/* Block operations: displacement, rotation, deletion ... */
|
||||
/**********************************************************/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 <Jean-Pierre Charras>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.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
|
||||
*/
|
||||
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "gr_basic.h"
|
||||
|
@ -11,6 +35,7 @@
|
|||
#include "confirm.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
#include "protos.h"
|
||||
|
||||
|
||||
|
@ -21,7 +46,7 @@ static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel,
|
|||
wxDC* DC,
|
||||
bool erase );
|
||||
|
||||
static TRACK* IsSegmentInBox( BLOCK_SELECTOR& blocklocate, TRACK* PtSegm );
|
||||
static bool IsGbrItemInBox( BLOCK_SELECTOR& aBlocklocate, GERBER_DRAW_ITEM* aItem );
|
||||
|
||||
|
||||
/* Return the block command (BLOCK_MOVE, BLOCK_COPY...) corresponding to
|
||||
|
@ -168,21 +193,10 @@ int WinEDA_GerberFrame::HandleBlockEnd( wxDC* DC )
|
|||
Block_Delete( DC );
|
||||
break;
|
||||
|
||||
case BLOCK_MIRROR_X: /* Mirror*/
|
||||
GetScreen()->m_BlockLocate.m_State = STATE_BLOCK_STOP;
|
||||
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
|
||||
Block_Mirror_X( DC );
|
||||
break;
|
||||
|
||||
case BLOCK_MIRROR_X: /* Mirror, unused*/
|
||||
case BLOCK_ROTATE: /* Unused */
|
||||
break;
|
||||
|
||||
case BLOCK_FLIP: /* Flip, unused */
|
||||
break;
|
||||
|
||||
case BLOCK_SAVE: /* Save (not used)*/
|
||||
break;
|
||||
|
||||
case BLOCK_PASTE:
|
||||
break;
|
||||
|
||||
|
@ -273,28 +287,14 @@ void WinEDA_GerberFrame::Block_Delete( wxDC* DC )
|
|||
GetScreen()->m_BlockLocate.Normalize();
|
||||
GetScreen()->SetCurItem( NULL );
|
||||
|
||||
TRACK* pt_segm, * NextS;
|
||||
for( pt_segm = m_Pcb->m_Track; pt_segm != NULL; pt_segm = NextS )
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
BOARD_ITEM* nextitem;
|
||||
for( ; item; item = nextitem )
|
||||
{
|
||||
NextS = pt_segm->Next();
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, pt_segm ) )
|
||||
{
|
||||
/* the track here is good to be cleared */
|
||||
pt_segm->Draw( DrawPanel, DC, GR_XOR );
|
||||
pt_segm->DeleteStructure();
|
||||
}
|
||||
}
|
||||
|
||||
/* Erasing areas. */
|
||||
for( pt_segm = m_Pcb->m_Zone; pt_segm != NULL; pt_segm = NextS )
|
||||
{
|
||||
NextS = pt_segm->Next();
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, pt_segm ) )
|
||||
{
|
||||
/* The track here is good to be cleared. */
|
||||
pt_segm->Draw( DrawPanel, DC, GR_XOR );
|
||||
pt_segm->DeleteStructure();
|
||||
}
|
||||
nextitem = item->Next();
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
|
||||
gerb_item->DeleteStructure();
|
||||
}
|
||||
|
||||
Refresh();
|
||||
|
@ -320,106 +320,13 @@ void WinEDA_GerberFrame::Block_Move( wxDC* DC )
|
|||
/* Calculate displacement vectors. */
|
||||
delta = GetScreen()->m_BlockLocate.m_MoveVector;
|
||||
|
||||
/* Move the Track segments in block */
|
||||
TRACK* track = m_Pcb->m_Track;
|
||||
while( track )
|
||||
/* Move items in block */
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, track ) )
|
||||
{
|
||||
m_Pcb->m_Status_Pcb = 0;
|
||||
track->Draw( DrawPanel, DC, GR_XOR ); // erase the display
|
||||
track->m_Start += delta;
|
||||
track->m_End += delta;
|
||||
|
||||
// the two parameters are used in gerbview to store center
|
||||
// coordinates for arcs. Move this center.
|
||||
track->m_Param += delta.x;
|
||||
track->SetSubNet( track->GetSubNet() + delta.y );
|
||||
|
||||
track->Draw( DrawPanel, DC, GR_OR ); // redraw the moved track
|
||||
}
|
||||
track = track->Next();
|
||||
}
|
||||
|
||||
/* Move the Zone segments in block */
|
||||
SEGZONE* zsegment = m_Pcb->m_Zone;
|
||||
while( zsegment )
|
||||
{
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, zsegment ) )
|
||||
{
|
||||
zsegment->Draw( DrawPanel, DC, GR_XOR ); // erase the display
|
||||
zsegment->m_Start += delta;
|
||||
zsegment->m_End += delta;
|
||||
|
||||
// the two parameters are used in gerbview to store center
|
||||
// coordinates for arcs. Move this center
|
||||
zsegment->m_Param += delta.x;
|
||||
zsegment->SetSubNet( zsegment->GetSubNet() + delta.y );
|
||||
zsegment->Draw( DrawPanel, DC, GR_OR ); // redraw the moved zone
|
||||
// segment
|
||||
}
|
||||
zsegment = zsegment->Next();
|
||||
}
|
||||
|
||||
DrawPanel->Refresh( TRUE );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function to mirror items in the current selected block
|
||||
*/
|
||||
void WinEDA_GerberFrame::Block_Mirror_X( wxDC* DC )
|
||||
{
|
||||
int xoffset = 0;
|
||||
wxPoint oldpos;
|
||||
|
||||
oldpos = GetScreen()->m_Curseur;
|
||||
DrawPanel->ManageCurseur = NULL;
|
||||
|
||||
GetScreen()->m_Curseur = oldpos;
|
||||
DrawPanel->MouseToCursorSchema();
|
||||
GetScreen()->SetModify();
|
||||
GetScreen()->m_BlockLocate.Normalize();
|
||||
|
||||
/* Calculate offset to mirror track points from block edges */
|
||||
xoffset = GetScreen()->m_BlockLocate.m_Pos.x
|
||||
+ GetScreen()->m_BlockLocate.m_Pos.x
|
||||
+ GetScreen()->m_BlockLocate.m_Size.x;
|
||||
|
||||
/* Move the Track segments in block */
|
||||
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
|
||||
{
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, track ) )
|
||||
{
|
||||
m_Pcb->m_Status_Pcb = 0;
|
||||
track->Draw( DrawPanel, DC, GR_XOR ); // erase the display
|
||||
track->m_Start.x = xoffset - track->m_Start.x;
|
||||
track->m_End.x = xoffset - track->m_End.x;
|
||||
|
||||
// the two parameters are used in gerbview to store center
|
||||
// coordinates for arcs. Move this center
|
||||
track->m_Param = xoffset - track->m_Param;
|
||||
track->Draw( DrawPanel, DC, GR_OR ); // redraw the moved track
|
||||
}
|
||||
}
|
||||
|
||||
/* Move the Zone segments in block */
|
||||
for( SEGZONE* zsegment = m_Pcb->m_Zone;
|
||||
zsegment;
|
||||
zsegment = zsegment->Next() )
|
||||
{
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, zsegment ) )
|
||||
{
|
||||
zsegment->Draw( DrawPanel, DC, GR_XOR ); // erase the display
|
||||
zsegment->m_Start.x = xoffset - zsegment->m_Start.x;
|
||||
zsegment->m_End.x = xoffset - zsegment->m_End.x;
|
||||
|
||||
// the two parameters are used in gerbview to store center
|
||||
// coordinates for arcs. Move this center
|
||||
zsegment->m_Param = xoffset - zsegment->m_Param;
|
||||
zsegment->Draw( DrawPanel, DC, GR_OR ); // redraw the moved zone
|
||||
// segment
|
||||
}
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
|
||||
gerb_item->Move( delta );
|
||||
}
|
||||
|
||||
DrawPanel->Refresh( TRUE );
|
||||
|
@ -444,62 +351,34 @@ void WinEDA_GerberFrame::Block_Duplicate( wxDC* DC )
|
|||
|
||||
delta = GetScreen()->m_BlockLocate.m_MoveVector;
|
||||
|
||||
/* Copy selected track segments and move the new track its new location */
|
||||
TRACK* track = m_Pcb->m_Track;
|
||||
while( track )
|
||||
/* Copy items in block */
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
TRACK* next_track = track->Next();
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, track ) )
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( IsGbrItemInBox( GetScreen()->m_BlockLocate, gerb_item ) )
|
||||
{
|
||||
/* this track segment must be duplicated */
|
||||
m_Pcb->m_Status_Pcb = 0;
|
||||
TRACK* new_track = track->Copy();
|
||||
|
||||
m_Pcb->Add( new_track );
|
||||
|
||||
new_track->m_Start += delta;
|
||||
new_track->m_End += delta;
|
||||
|
||||
new_track->Draw( DrawPanel, DC, GR_OR ); // draw the new created
|
||||
// segment
|
||||
/* this item must be duplicated */
|
||||
BOARD_ITEM* new_item = gerb_item->Copy();
|
||||
new_item->Move( delta );
|
||||
GetBoard()->m_Drawings.PushFront( new_item );
|
||||
}
|
||||
track = next_track;
|
||||
}
|
||||
|
||||
/* Copy the Zone segments and move the new segment to its new location */
|
||||
SEGZONE* zsegment = m_Pcb->m_Zone;
|
||||
while( zsegment )
|
||||
{
|
||||
SEGZONE* next_zsegment = zsegment->Next();
|
||||
if( IsSegmentInBox( GetScreen()->m_BlockLocate, zsegment ) )
|
||||
{
|
||||
/* this zone segment must be duplicated */
|
||||
SEGZONE* new_zsegment = (SEGZONE*) zsegment->Copy();
|
||||
|
||||
m_Pcb->Add( new_zsegment );
|
||||
|
||||
new_zsegment->m_Start += delta;
|
||||
new_zsegment->m_End += delta;
|
||||
|
||||
new_zsegment->Draw( DrawPanel, DC, GR_OR ); // draw the new created
|
||||
// segment
|
||||
}
|
||||
zsegment = next_zsegment;
|
||||
}
|
||||
DrawPanel->Refresh();
|
||||
}
|
||||
|
||||
|
||||
/* Test if the structure PtStruct is listed in the block selects
|
||||
* Returns whether PtSegm
|
||||
* NULL if not
|
||||
/* Test if the structure PtStruct is inside the block
|
||||
* Returns true or false
|
||||
*/
|
||||
static TRACK* IsSegmentInBox( BLOCK_SELECTOR& blocklocate, TRACK* PtSegm )
|
||||
bool IsGbrItemInBox( BLOCK_SELECTOR& aBlocklocate, GERBER_DRAW_ITEM* aItem )
|
||||
{
|
||||
if( blocklocate.Inside( PtSegm->m_Start.x, PtSegm->m_Start.y ) )
|
||||
return PtSegm;
|
||||
if( aBlocklocate.Inside( aItem->m_Start ) )
|
||||
return true;
|
||||
|
||||
if( blocklocate.Inside( PtSegm->m_End.x, PtSegm->m_End.y ) )
|
||||
return PtSegm;
|
||||
if( aBlocklocate.Inside( aItem->m_End ) )
|
||||
return true;
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
/** @file class_GERBER.cpp
|
||||
* a GERBER class handle for a given layer info about used D_CODES and how the layer is drawn
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 <Jean-Pierre Charras>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.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
|
||||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
#include "confirm.h"
|
||||
#include "macros.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
|
||||
/* Format Gerber: NOTES:
|
||||
* Tools and D_CODES
|
||||
* tool number (identification of shapes)
|
||||
* 1 to 999
|
||||
*
|
||||
* D_CODES:
|
||||
* D01 ... D9 = action codes:
|
||||
* D01 = activating light (lower pen) when di ¿½ placement
|
||||
* D02 = light extinction (lift pen) when di ¿½ placement
|
||||
* D03 Flash
|
||||
* D09 = VAPE Flash
|
||||
* D10 ... = Indentification Tool (Opening)
|
||||
*
|
||||
* For tools:
|
||||
* DCode min = D10
|
||||
* DCode max = 999
|
||||
*/
|
||||
|
||||
|
||||
GERBER::GERBER( int aLayer )
|
||||
{
|
||||
m_Layer = aLayer; // Layer Number
|
||||
|
||||
m_Selected_Tool = FIRST_DCODE;
|
||||
|
||||
ResetDefaultValues();
|
||||
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
m_Aperture_List[ii] = 0;
|
||||
|
||||
m_Pcb = 0;
|
||||
}
|
||||
|
||||
|
||||
GERBER::~GERBER()
|
||||
{
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
{
|
||||
delete m_Aperture_List[ii];
|
||||
|
||||
// m_Aperture_List[ii] = NULL;
|
||||
}
|
||||
|
||||
delete m_Pcb;
|
||||
}
|
||||
|
||||
|
||||
D_CODE* GERBER::GetDCODE( int aDCODE, bool create )
|
||||
{
|
||||
unsigned ndx = aDCODE - FIRST_DCODE;
|
||||
|
||||
if( ndx < (unsigned) DIM( m_Aperture_List ) )
|
||||
{
|
||||
// lazily create the D_CODE if it does not exist.
|
||||
if( create )
|
||||
{
|
||||
if( m_Aperture_List[ndx] == NULL )
|
||||
m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
|
||||
}
|
||||
|
||||
return m_Aperture_List[ndx];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
APERTURE_MACRO* GERBER::FindApertureMacro( const APERTURE_MACRO& aLookup )
|
||||
{
|
||||
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
|
||||
|
||||
if( iter != m_aperture_macros.end() )
|
||||
{
|
||||
APERTURE_MACRO* pam = (APERTURE_MACRO*) &(*iter);
|
||||
return pam;
|
||||
}
|
||||
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
|
||||
void GERBER::ResetDefaultValues()
|
||||
{
|
||||
m_FileName.Empty();
|
||||
m_Name = wxT( "no name" ); // Layer name
|
||||
m_LayerNegative = FALSE; // TRUE = Negative Layer
|
||||
m_ImageNegative = FALSE; // TRUE = Negative image
|
||||
m_GerbMetric = FALSE; // FALSE = Inches, TRUE = metric
|
||||
m_Relative = FALSE; // FALSE = absolute Coord, RUE =
|
||||
// relative Coord
|
||||
m_NoTrailingZeros = FALSE; // True: trailing zeros deleted
|
||||
m_MirorA = FALSE; // True: miror / axe A (X)
|
||||
m_MirorB = FALSE; // True: miror / axe B (Y)
|
||||
m_Has_DCode = FALSE; // TRUE = DCodes in file (FALSE = no
|
||||
// DCode->
|
||||
// separate DCode file
|
||||
|
||||
m_Offset.x = m_Offset.y = 0; // Coord Offset
|
||||
|
||||
m_FmtScale.x = m_FmtScale.y = g_Default_GERBER_Format % 10;
|
||||
m_FmtLen.x = m_FmtLen.y = m_FmtScale.x + (g_Default_GERBER_Format / 10);
|
||||
|
||||
m_LayerScale.x = m_LayerScale.y = 1.0; // scale (X and Y) this
|
||||
// layer
|
||||
m_Rotation = 0;
|
||||
m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
|
||||
m_360Arc_enbl = FALSE; // 360 deg circular
|
||||
// interpolation disable
|
||||
m_Current_Tool = 0; // Current Tool (Dcode)
|
||||
// number selected
|
||||
m_CommandState = 0; // gives tate of the
|
||||
// stacking order analysis
|
||||
m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
|
||||
// for plot
|
||||
m_PreviousPos.x = m_PreviousPos.y = 0; // old current specified
|
||||
// coord for plot
|
||||
m_IJPos.x = m_IJPos.y = 0; // current centre coord for
|
||||
// plot arcs & circles
|
||||
m_Current_File = NULL; // File to read
|
||||
m_FilesPtr = 0;
|
||||
m_Transform[0][0] = m_Transform[1][1] = 1;
|
||||
m_Transform[0][1] = m_Transform[1][0] = 0; // Rotation/mirror = Normal
|
||||
m_PolygonFillMode = FALSE;
|
||||
m_PolygonFillModeState = 0;
|
||||
}
|
||||
|
||||
|
||||
int GERBER::ReturnUsedDcodeNumber()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
{
|
||||
if( m_Aperture_List[ii] )
|
||||
if( m_Aperture_List[ii]->m_InUse || m_Aperture_List[ii]->m_Defined )
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void GERBER::InitToolTable()
|
||||
{
|
||||
for( int count = 0; count < TOOLS_MAX_COUNT; count++ )
|
||||
{
|
||||
if( m_Aperture_List[count] == NULL )
|
||||
continue;
|
||||
|
||||
m_Aperture_List[count]->m_Num_Dcode = count + FIRST_DCODE;
|
||||
m_Aperture_List[count]->Clear_D_CODE_Data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,426 @@
|
|||
/*************************************
|
||||
* file class_gerber_draw_item.cpp
|
||||
*************************************/
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 <Jean-Pierre Charras>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.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
|
||||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "polygons_defs.h"
|
||||
#include "gr_basic.h"
|
||||
#include "common.h"
|
||||
#include "trigo.h"
|
||||
#include "class_drawpanel.h"
|
||||
#include "drawtxt.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "class_board_design_settings.h"
|
||||
#include "colors_selection.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent ) :
|
||||
BOARD_ITEM( aParent, TYPE_GERBER_DRAW_ITEM )
|
||||
/**********************************************************/
|
||||
{
|
||||
m_Layer = 0;
|
||||
m_Shape = GBR_SEGMENT;
|
||||
m_Flashed = false;
|
||||
m_DCode = 0;
|
||||
}
|
||||
|
||||
|
||||
// Copy constructor
|
||||
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
|
||||
BOARD_ITEM( aSource )
|
||||
{
|
||||
m_Shape = aSource.m_Shape;
|
||||
|
||||
m_Flags = aSource.m_Flags;
|
||||
m_TimeStamp = aSource.m_TimeStamp;
|
||||
|
||||
SetStatus( aSource.ReturnStatus() );
|
||||
m_Start = aSource.m_Start;
|
||||
m_End = aSource.m_End;
|
||||
m_Size = aSource.m_Size;
|
||||
m_Layer = aSource.m_Layer;
|
||||
m_Shape = aSource.m_Shape;
|
||||
m_Flashed = aSource.m_Flashed;
|
||||
m_DCode = aSource.m_DCode;
|
||||
m_PolyCorners = aSource.m_PolyCorners;
|
||||
}
|
||||
|
||||
|
||||
GERBER_DRAW_ITEM::~GERBER_DRAW_ITEM()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
GERBER_DRAW_ITEM* GERBER_DRAW_ITEM::Copy() const
|
||||
{
|
||||
return new GERBER_DRAW_ITEM( *this );
|
||||
}
|
||||
|
||||
|
||||
wxString GERBER_DRAW_ITEM::ShowGBRShape()
|
||||
{
|
||||
switch( m_Shape )
|
||||
{
|
||||
case GBR_SEGMENT:
|
||||
return _( "Line" );
|
||||
|
||||
case GBR_ARC:
|
||||
return _( "Arc" );
|
||||
|
||||
case GBR_CIRCLE:
|
||||
return _( "Circle" );
|
||||
|
||||
case GBR_SPOT_OVAL:
|
||||
return wxT( "spot_oval" );
|
||||
|
||||
case GBR_SPOT_CIRCLE:
|
||||
return wxT( "spot_circle" );
|
||||
|
||||
case GBR_SPOT_RECT:
|
||||
return wxT( "spot_rect" );
|
||||
|
||||
case GBR_POLYGON:
|
||||
return wxT( "polygon" );
|
||||
|
||||
case GBR_MACRO:
|
||||
return wxT( "apt_macro" ); // TODO: add aperture macro name
|
||||
|
||||
default:
|
||||
return wxT( "??" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function GetDcodeDescr
|
||||
* returns the GetDcodeDescr of this object, or NULL.
|
||||
* @return D_CODE* - a pointer to the DCode description (for flashed items).
|
||||
*/
|
||||
D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
|
||||
{
|
||||
if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
|
||||
return NULL;
|
||||
GERBER* gerber = g_GERBER_List[m_Layer];
|
||||
if( gerber == NULL )
|
||||
return NULL;
|
||||
|
||||
D_CODE* d_code = gerber->GetDCODE( m_DCode, false );
|
||||
|
||||
return d_code;
|
||||
}
|
||||
|
||||
|
||||
EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
|
||||
{
|
||||
// return a rectangle which is (pos,dim) in nature. therefore the +1
|
||||
EDA_Rect bbox( m_Start, wxSize( 1, 1 ) );
|
||||
|
||||
bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Move
|
||||
* move this object.
|
||||
* @param const wxPoint& aMoveVector - the move vector for this object.
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::Move( 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
|
||||
* of the basic class
|
||||
*/
|
||||
bool GERBER_DRAW_ITEM::Save( FILE* aFile ) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
|
||||
const wxPoint& aOffset )
|
||||
/*********************************************************************/
|
||||
{
|
||||
static D_CODE dummyD_CODE( 0 ); // used when a D_CODE is not found. default D_CODE to draw a flashed item
|
||||
int color;
|
||||
bool isFilled;
|
||||
int radius;
|
||||
int halfPenWidth;
|
||||
static bool show_err;
|
||||
BOARD* brd = GetBoard();
|
||||
D_CODE* d_codeDescr = GetDcodeDescr();
|
||||
|
||||
if( d_codeDescr == NULL )
|
||||
d_codeDescr = &dummyD_CODE;
|
||||
|
||||
if( m_Flags & DRAW_ERASED ) // draw in background color ("negative" color)
|
||||
{
|
||||
color = g_DrawBgColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( brd->IsLayerVisible( GetLayer() ) == false )
|
||||
return;
|
||||
|
||||
color = brd->GetLayerColor( GetLayer() );
|
||||
|
||||
if( draw_mode & GR_SURBRILL )
|
||||
{
|
||||
if( draw_mode & GR_AND )
|
||||
color &= ~HIGHT_LIGHT_FLAG;
|
||||
else
|
||||
color |= HIGHT_LIGHT_FLAG;
|
||||
}
|
||||
if( color & HIGHT_LIGHT_FLAG )
|
||||
color = ColorRefs[color & MASKCOLOR].m_LightColor;
|
||||
}
|
||||
|
||||
GRSetDrawMode( DC, draw_mode );
|
||||
|
||||
isFilled = DisplayOpt.DisplayPcbTrackFill ? true : false;
|
||||
|
||||
switch( m_Shape )
|
||||
{
|
||||
case GBR_POLYGON:
|
||||
isFilled = (g_DisplayPolygonsModeSketch == false);
|
||||
if( m_Flags & DRAW_ERASED )
|
||||
isFilled = true;
|
||||
DrawGbrPoly( &panel->m_ClipBox, DC, color, aOffset, isFilled );
|
||||
break;
|
||||
|
||||
case GBR_CIRCLE:
|
||||
radius = (int) hypot( (double) ( m_End.x - m_Start.x ),
|
||||
(double) ( m_End.y - m_Start.y ) );
|
||||
|
||||
halfPenWidth = m_Size.x >> 1;
|
||||
|
||||
if( isFilled == SKETCH )
|
||||
{
|
||||
// draw the border of the pen's path using two circles, each as narrow as possible
|
||||
#ifdef USE_WX_ZOOM
|
||||
if( DC->LogicalToDeviceXRel( halfPenWidth ) < L_MIN_DESSIN )
|
||||
#else
|
||||
if( panel->GetScreen()->Scale( halfPenWidth ) < L_MIN_DESSIN )
|
||||
#endif
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x,
|
||||
m_Start.y, radius, 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
radius - halfPenWidth, 0, color );
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
radius + halfPenWidth, 0, color );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
radius, m_Size.x, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case GBR_ARC:
|
||||
if( !isFilled )
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y,
|
||||
m_ArcCentre.x, m_ArcCentre.y, 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y,
|
||||
m_ArcCentre.x, m_ArcCentre.y,
|
||||
m_Size.x, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case GBR_SPOT_CIRCLE:
|
||||
case GBR_SPOT_RECT:
|
||||
case GBR_SPOT_OVAL:
|
||||
isFilled = DisplayOpt.DisplayPadFill ? true : false;
|
||||
d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color,
|
||||
m_Start, isFilled );
|
||||
break;
|
||||
|
||||
case GBR_SEGMENT:
|
||||
if( !isFilled )
|
||||
GRCSegm( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
|
||||
m_End.x, m_End.y, m_Size.x, color );
|
||||
else
|
||||
GRFillCSegm( &panel->m_ClipBox, DC, m_Start.x,
|
||||
m_Start.y, m_End.x, m_End.y, m_Size.x, color );
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !show_err )
|
||||
{
|
||||
wxMessageBox( wxT( "Trace_Segment() type error" ) );
|
||||
show_err = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** function DrawGbrPoly
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* Draw filled polygons
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect* aClipBox,
|
||||
wxDC* aDC,
|
||||
int aColor,
|
||||
const wxPoint& aOffset,
|
||||
bool aFilledShape )
|
||||
{
|
||||
std::vector<wxPoint> points;
|
||||
|
||||
points = m_PolyCorners;
|
||||
if( aOffset != wxPoint( 0, 0 ) )
|
||||
{
|
||||
for( unsigned ii = 0; ii < points.size(); ii++ )
|
||||
{
|
||||
points[ii] += aOffset;
|
||||
}
|
||||
}
|
||||
|
||||
GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilledShape, aColor, aColor );
|
||||
}
|
||||
|
||||
|
||||
/** Function DisplayInfoBase
|
||||
* has knowledge about the frame and how and where to put status information
|
||||
* about this object into the frame's message panel.
|
||||
* Display info about the track segment only, and does not calculate the full track length
|
||||
* @param frame A WinEDA_DrawFrame in which to print status information.
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
|
||||
{
|
||||
wxString msg;
|
||||
BOARD* board = ( (WinEDA_BasePcbFrame*) frame )->GetBoard();
|
||||
|
||||
frame->ClearMsgPanel();
|
||||
|
||||
msg = ShowGBRShape();
|
||||
frame->AppendMsgPanel( _( "Type" ), msg, DARKCYAN );
|
||||
|
||||
/* Display layer */
|
||||
msg = board->GetLayerName( m_Layer );
|
||||
frame->AppendMsgPanel( _( "Layer" ), msg, BROWN );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function HitTest
|
||||
* tests if the given wxPoint is within the bounds of this object.
|
||||
* @param ref_pos A wxPoint to test
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
bool GERBER_DRAW_ITEM::HitTest( const wxPoint& ref_pos )
|
||||
{
|
||||
// TODO: a better analyse od the shape (perhaps create a D_CODE::HitTest for flashed items)
|
||||
int radius = MIN( m_Size.x, m_Size.y) >> 1;
|
||||
|
||||
// delta is a vector from m_Start to m_End (an origin of m_Start)
|
||||
wxPoint delta = m_End - m_Start;
|
||||
|
||||
// dist is a vector from m_Start to ref_pos (an origin of m_Start)
|
||||
wxPoint dist = ref_pos - m_Start;
|
||||
|
||||
if( m_Flashed )
|
||||
{
|
||||
return (double) dist.x * dist.x + (double) dist.y * dist.y <=
|
||||
(double) radius * radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( DistanceTest( radius, delta.x, delta.y, dist.x, dist.y ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function HitTest (overlayed)
|
||||
* tests if the given EDA_Rect intersect this object.
|
||||
* For now, an ending point must be inside this rect.
|
||||
* @param refArea : the given EDA_Rect
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
bool GERBER_DRAW_ITEM::HitTest( EDA_Rect& refArea )
|
||||
{
|
||||
if( refArea.Inside( m_Start ) )
|
||||
return true;
|
||||
if( refArea.Inside( m_End ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
/**
|
||||
* Function Show
|
||||
* is used to output the object tree, currently for debugging only.
|
||||
* @param nestLevel An aid to prettier tree indenting, and is the level
|
||||
* of nesting of this object within the overall tree.
|
||||
* @param os The ostream& to output to.
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::Show( int nestLevel, std::ostream& os )
|
||||
{
|
||||
NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
|
||||
|
||||
" shape=\"" << m_Shape << '"' <<
|
||||
" addr=\"" << std::hex << this << std::dec << '"' <<
|
||||
" layer=\"" << m_Layer << '"' <<
|
||||
" size=\"" << m_Size << '"' <<
|
||||
" flags=\"" << m_Flags << '"' <<
|
||||
" status=\"" << GetState( -1 ) << '"' <<
|
||||
"<start" << m_Start << "/>" <<
|
||||
"<end" << m_End << "/>";
|
||||
|
||||
os << "</" << GetClass().Lower().mb_str() << ">\n";
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,183 @@
|
|||
/*******************************************************************/
|
||||
/* class_gerber_draw_item.h: definitions relatives to tracks, vias and zones */
|
||||
/*******************************************************************/
|
||||
|
||||
#ifndef CLASS_GERBER_DRAW_ITEM_H
|
||||
#define CLASS_GERBER_DRAW_ITEM_H
|
||||
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2010 <Jean-Pierre Charras>
|
||||
* Copyright (C) 1992-2010 Kicad Developers, see change_log.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
|
||||
*/
|
||||
|
||||
#include "base_struct.h"
|
||||
|
||||
/* Shapes id for basic shapes ( .m_Shape member ) */
|
||||
enum Gbr_Basic_Shapes {
|
||||
GBR_SEGMENT = 0, // usual segment : line with rounded ends
|
||||
GBR_ARC, // Arcs (with rounded ends)
|
||||
GBR_CIRCLE, // ring
|
||||
GBR_POLYGON, // polygonal shape
|
||||
GBR_SPOT_CIRCLE, // flashed shape: round shape (can have hole)
|
||||
GBR_SPOT_RECT, // flashed shape: rectangular shape can have hole)
|
||||
GBR_SPOT_OVAL, // flashed shape: oval shape
|
||||
GBR_MACRO, // complex shape described by a macro
|
||||
GBR_LAST // last value for this list
|
||||
};
|
||||
|
||||
/***/
|
||||
|
||||
class GERBER_DRAW_ITEM : public BOARD_ITEM
|
||||
{
|
||||
// make SetNext() and SetBack() private so that they may not be called from anywhere.
|
||||
// list management is done on GERBER_DRAW_ITEMs using DLIST<GERBER_DRAW_ITEM> only.
|
||||
private:
|
||||
void SetNext( EDA_BaseStruct* aNext ) { Pnext = aNext; }
|
||||
void SetBack( EDA_BaseStruct* aBack ) { Pback = aBack; }
|
||||
|
||||
|
||||
public:
|
||||
int m_Layer;
|
||||
int m_Shape; // Shape and type of this gerber item
|
||||
wxPoint m_Start; // Line or arc start point or position of the shape
|
||||
// for flashed items
|
||||
wxPoint m_End; // Line or arc end point
|
||||
wxPoint m_ArcCentre; // for arcs only: Centre of arc
|
||||
std::vector <wxPoint> m_PolyCorners; // list of corners for polygons (G36 to G37 coordinates)
|
||||
// or for complex shapes which are converted to polygon
|
||||
wxSize m_Size; // Flashed shapes size of the shape
|
||||
// Lines : m_Size.x = m_Size.y = line width
|
||||
bool m_Flashed; // True for flashed items
|
||||
int m_DCode; // DCode used to draw this item.
|
||||
// 0 for items that do not use DCodes (polygons)
|
||||
// or when unknown and normal values are 10 to 999
|
||||
// values 0 to 9 can be used for special purposes
|
||||
|
||||
public:
|
||||
GERBER_DRAW_ITEM( BOARD_ITEM* aParent );
|
||||
GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource );
|
||||
~GERBER_DRAW_ITEM();
|
||||
|
||||
/**
|
||||
* Function Copy
|
||||
* will copy this object
|
||||
* the corresponding type.
|
||||
* @return - GERBER_DRAW_ITEM*
|
||||
*/
|
||||
GERBER_DRAW_ITEM* Copy() const;
|
||||
|
||||
GERBER_DRAW_ITEM* Next() const { return (GERBER_DRAW_ITEM*) Pnext; }
|
||||
GERBER_DRAW_ITEM* Back() const { return (GERBER_DRAW_ITEM*) Pback; }
|
||||
|
||||
int ReturnMaskLayer()
|
||||
{
|
||||
return 1 << m_Layer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Move
|
||||
* move this object.
|
||||
* @param const wxPoint& aMoveVector - the move vector for this object.
|
||||
*/
|
||||
void Move( const wxPoint& aMoveVector );
|
||||
|
||||
/**
|
||||
* Function GetPosition
|
||||
* returns the position of this object.
|
||||
* @return const wxPoint& - The position of this object.
|
||||
*/
|
||||
wxPoint& GetPosition()
|
||||
{
|
||||
return m_Start; // it had to be start or end.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function GetDcodeDescr
|
||||
* returns the GetDcodeDescr of this object, or NULL.
|
||||
* @return D_CODE* - a pointer to the DCode description (for flashed items).
|
||||
*/
|
||||
D_CODE* GetDcodeDescr();
|
||||
|
||||
EDA_Rect GetBoundingBox();
|
||||
|
||||
/* Display on screen: */
|
||||
void Draw( WinEDA_DrawPanel* aPanel,
|
||||
wxDC* aDC,
|
||||
int aDrawMode,
|
||||
const wxPoint& aOffset = ZeroOffset );
|
||||
|
||||
/** function DrawGbrPoly
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
*/
|
||||
void DrawGbrPoly( EDA_Rect* aClipBox,
|
||||
wxDC* aDC, int aColor,
|
||||
const wxPoint& aOffset, bool aFilledShape );
|
||||
|
||||
/* divers */
|
||||
int Shape() const { return m_Shape; }
|
||||
|
||||
/**
|
||||
* Function DisplayInfo
|
||||
* has knowledge about the frame and how and where to put status information
|
||||
* about this object into the frame's message panel.
|
||||
* Is virtual from EDA_BaseStruct.
|
||||
* Display info about the track segment and the full track length
|
||||
* @param frame A WinEDA_DrawFrame in which to print status information.
|
||||
*/
|
||||
void DisplayInfo( WinEDA_DrawFrame* frame );
|
||||
|
||||
wxString ShowGBRShape();
|
||||
|
||||
/**
|
||||
* Function HitTest
|
||||
* tests if the given wxPoint is within the bounds of this object.
|
||||
* @param refPos A wxPoint to test
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
bool HitTest( const wxPoint& refPos );
|
||||
|
||||
/**
|
||||
* Function HitTest (overlayed)
|
||||
* tests if the given wxRect intersect this object.
|
||||
* For now, an ending point must be inside this rect.
|
||||
* @param refPos A wxPoint to test
|
||||
* @return bool - true if a hit, else false
|
||||
*/
|
||||
bool HitTest( EDA_Rect& refArea );
|
||||
|
||||
/**
|
||||
* Function GetClass
|
||||
* returns the class name.
|
||||
* @return wxString
|
||||
*/
|
||||
wxString GetClass() const
|
||||
{
|
||||
return wxT( "GERBER_DRAW_ITEM" );
|
||||
}
|
||||
|
||||
|
||||
bool Save( FILE* aFile ) const;
|
||||
};
|
||||
|
||||
#endif /* CLASS_GERBER_DRAW_ITEM_H */
|
|
@ -1,5 +1,5 @@
|
|||
/***************************/
|
||||
/**** Read GERBER files ****/
|
||||
/**** class D_CODE ****/
|
||||
/***************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
|
@ -7,53 +7,16 @@
|
|||
#include "class_drawpanel.h"
|
||||
#include "confirm.h"
|
||||
#include "macros.h"
|
||||
#include "trigo.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "pcbplot.h"
|
||||
#include "protos.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
|
||||
#define DEFAULT_SIZE 100
|
||||
|
||||
|
||||
/* Format Gerber: NOTES:
|
||||
* Features history:
|
||||
* Gn =
|
||||
* G01 linear interpolation (right trace)
|
||||
* G02, G20, G21 Circular interpolation, meaning trig < 0
|
||||
* G03, G30, G31 Circular interpolation, meaning trig > 0
|
||||
* G04 review
|
||||
* G06 parabolic interpolation
|
||||
* G07 Cubic Interpolation
|
||||
* G10 linear interpolation (scale x10)
|
||||
* G11 linear interpolation (0.1x range)
|
||||
* G12 linear interpolation (0.01x scale)
|
||||
* G52 plot symbol reference code by Dnn
|
||||
* G53 plot symbol reference by Dnn; symbol rotates from -90 degrees
|
||||
* G54 Selection Tool
|
||||
* G55 Fashion photo exhibition
|
||||
* G56 plot symbol reference code for DNN
|
||||
* G57 displays the symbol link to the console
|
||||
* G58 plot displays the symbol and link to the console
|
||||
* G60 linear interpolation (scale x100)
|
||||
* G70 Units = Inches
|
||||
* G71 Units = Millimeters
|
||||
* G74 circular interpolation removes 360 degree, has returned G01
|
||||
* G75 circular interpolation Active 360 degree
|
||||
* G90 mode absolute coordinates
|
||||
* G91 Fashion Related Contacts
|
||||
*
|
||||
* Coordinates X, Y
|
||||
* X and Y are followed by + or - and m + n digits (not separated)
|
||||
* m = integer part
|
||||
* n = part after the comma
|
||||
* conventional formats: m = 2, n = 3 (size 2.3)
|
||||
* m = 3, n = 4 (size 3.4)
|
||||
* eg
|
||||
* G__ X00345Y-06123 * D__
|
||||
*
|
||||
* Tools and D_CODES
|
||||
* tool number (identification of shapes)
|
||||
* 1 to 99 (Classical)
|
||||
* 1 to 999
|
||||
*
|
||||
* D_CODES:
|
||||
|
@ -62,145 +25,14 @@
|
|||
* D02 = light extinction (lift pen) when di ¿½ placement
|
||||
* D03 Flash
|
||||
* D09 = VAPE Flash
|
||||
* D10 ... = Indentification Tool (Opening)
|
||||
* D10 ... = Indentification Tool (Shape id)
|
||||
*
|
||||
* For tools:
|
||||
* DCode min = D10
|
||||
* DCode max = 999
|
||||
*/
|
||||
|
||||
|
||||
GERBER::GERBER( int aLayer )
|
||||
{
|
||||
m_Layer = aLayer; // Layer Number
|
||||
|
||||
m_Selected_Tool = FIRST_DCODE;
|
||||
|
||||
ResetDefaultValues();
|
||||
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
m_Aperture_List[ii] = 0;
|
||||
|
||||
m_Pcb = 0;
|
||||
}
|
||||
|
||||
|
||||
GERBER::~GERBER()
|
||||
{
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
{
|
||||
delete m_Aperture_List[ii];
|
||||
|
||||
// m_Aperture_List[ii] = NULL;
|
||||
}
|
||||
|
||||
delete m_Pcb;
|
||||
}
|
||||
|
||||
|
||||
D_CODE* GERBER::GetDCODE( int aDCODE, bool create )
|
||||
{
|
||||
unsigned ndx = aDCODE - FIRST_DCODE;
|
||||
|
||||
if( ndx < (unsigned) DIM( m_Aperture_List ) )
|
||||
{
|
||||
// lazily create the D_CODE if it does not exist.
|
||||
if( create )
|
||||
{
|
||||
if( m_Aperture_List[ndx] == NULL )
|
||||
m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
|
||||
}
|
||||
|
||||
return m_Aperture_List[ndx];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
APERTURE_MACRO* GERBER::FindApertureMacro( const APERTURE_MACRO& aLookup )
|
||||
{
|
||||
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
|
||||
|
||||
if( iter != m_aperture_macros.end() )
|
||||
{
|
||||
APERTURE_MACRO* pam = (APERTURE_MACRO*) &(*iter);
|
||||
return pam;
|
||||
}
|
||||
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
|
||||
void GERBER::ResetDefaultValues()
|
||||
{
|
||||
m_FileName.Empty();
|
||||
m_Name = wxT( "no name" ); // Layer name
|
||||
m_LayerNegative = FALSE; // TRUE = Negative Layer
|
||||
m_ImageNegative = FALSE; // TRUE = Negative image
|
||||
m_GerbMetric = FALSE; // FALSE = Inches, TRUE = metric
|
||||
m_Relative = FALSE; // FALSE = absolute Coord, RUE =
|
||||
// relative Coord
|
||||
m_NoTrailingZeros = FALSE; // True: trailing zeros deleted
|
||||
m_MirorA = FALSE; // True: miror / axe A (X)
|
||||
m_MirorB = FALSE; // True: miror / axe B (Y)
|
||||
m_Has_DCode = FALSE; // TRUE = DCodes in file (FALSE = no
|
||||
// DCode->
|
||||
// separate DCode file
|
||||
|
||||
m_Offset.x = m_Offset.y = 0; // Coord Offset
|
||||
|
||||
m_FmtScale.x = m_FmtScale.y = g_Default_GERBER_Format % 10;
|
||||
m_FmtLen.x = m_FmtLen.y = m_FmtScale.x + (g_Default_GERBER_Format / 10);
|
||||
|
||||
m_LayerScale.x = m_LayerScale.y = 1.0; // scale (X and Y) this
|
||||
// layer
|
||||
m_Rotation = 0;
|
||||
m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
|
||||
m_360Arc_enbl = FALSE; // 360 deg circular
|
||||
// interpolation disable
|
||||
m_Current_Tool = 0; // Current Tool (Dcode)
|
||||
// number selected
|
||||
m_CommandState = 0; // gives tate of the
|
||||
// stacking order analysis
|
||||
m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
|
||||
// for plot
|
||||
m_PreviousPos.x = m_PreviousPos.y = 0; // old current specified
|
||||
// coord for plot
|
||||
m_IJPos.x = m_IJPos.y = 0; // current centre coord for
|
||||
// plot arcs & circles
|
||||
m_Current_File = NULL; // File to read
|
||||
m_FilesPtr = 0;
|
||||
m_Transform[0][0] = m_Transform[1][1] = 1;
|
||||
m_Transform[0][1] = m_Transform[1][0] = 0; // Rotation/mirror = Normal
|
||||
m_PolygonFillMode = FALSE;
|
||||
m_PolygonFillModeState = 0;
|
||||
}
|
||||
|
||||
|
||||
int GERBER::ReturnUsedDcodeNumber()
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
|
||||
{
|
||||
if( m_Aperture_List[ii] )
|
||||
if( m_Aperture_List[ii]->m_InUse || m_Aperture_List[ii]->m_Defined )
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void GERBER::InitToolTable()
|
||||
{
|
||||
for( int count = 0; count < MAX_TOOLS; count++ )
|
||||
{
|
||||
if( m_Aperture_List[count] == NULL )
|
||||
continue;
|
||||
|
||||
m_Aperture_List[count]->m_Num_Dcode = count + FIRST_DCODE;
|
||||
m_Aperture_List[count]->Clear_D_CODE_Data();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************/
|
||||
/* Class DCODE */
|
||||
/***************/
|
||||
|
@ -228,6 +60,7 @@ void D_CODE::Clear_D_CODE_Data()
|
|||
m_InUse = FALSE;
|
||||
m_Defined = FALSE;
|
||||
m_Macro = 0;
|
||||
m_Rotation = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -370,7 +203,7 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
|
|||
if( current_Dcode < FIRST_DCODE )
|
||||
continue;
|
||||
|
||||
if( current_Dcode >= MAX_TOOLS )
|
||||
if( current_Dcode >= TOOLS_MAX_COUNT )
|
||||
continue;
|
||||
|
||||
dcode = gerber->GetDCODE( current_Dcode );
|
||||
|
@ -393,134 +226,358 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
|
|||
{
|
||||
static D_CODE dummy( 999 ); //Used if D_CODE not found in list
|
||||
|
||||
for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
|
||||
{
|
||||
GERBER* gerber = g_GERBER_List[track->GetLayer()];
|
||||
wxASSERT( gerber );
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
|
||||
D_CODE* dcode = gerber->GetDCODE( track->GetNet(), false );
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
D_CODE* dcode = gerb_item->GetDcodeDescr();
|
||||
wxASSERT( dcode );
|
||||
if( dcode == NULL )
|
||||
dcode = &dummy;
|
||||
|
||||
dcode->m_InUse = TRUE;
|
||||
|
||||
gerb_item->m_Size = dcode->m_Size;
|
||||
if( // Line Item
|
||||
(track->m_Shape == S_SEGMENT ) /* rectilinear segment */
|
||||
|| (track->m_Shape == S_RECT ) /* rect segment form (i.e.
|
||||
* non-rounded ends) */
|
||||
|| (track->m_Shape == S_ARC ) /* segment arc (rounded tips) */
|
||||
|| (track->m_Shape == S_CIRCLE ) /* segment in a circle (ring) */
|
||||
|| (track->m_Shape == S_ARC_RECT ) /* segment arc (stretches)
|
||||
* (GERBER)*/
|
||||
(gerb_item->m_Shape == GBR_SEGMENT ) /* rectilinear segment */
|
||||
|| (gerb_item->m_Shape == GBR_ARC ) /* segment arc (rounded tips) */
|
||||
|| (gerb_item->m_Shape == GBR_CIRCLE ) /* segment in a circle (ring) */
|
||||
)
|
||||
{
|
||||
track->m_Width = dcode->m_Size.x;
|
||||
}
|
||||
else // Spots ( Flashed Items )
|
||||
{
|
||||
int width, len;
|
||||
wxSize size = dcode->m_Size;
|
||||
|
||||
width = MIN( size.x, size.y );
|
||||
len = MAX( size.x, size.y ) - width;
|
||||
|
||||
track->m_Width = width;
|
||||
|
||||
track->m_Start.x = (track->m_Start.x + track->m_End.x) / 2;
|
||||
track->m_Start.y = (track->m_Start.y + track->m_End.y) / 2;
|
||||
track->m_End = track->m_Start; // m_Start = m_End = Spot center
|
||||
|
||||
switch( dcode->m_Shape )
|
||||
{
|
||||
case APT_LINE: // might not appears here, but some broken
|
||||
// gerber files use it
|
||||
case APT_CIRCLE: /* spot round (for GERBER) */
|
||||
track->m_Shape = S_SPOT_CIRCLE;
|
||||
gerb_item->m_Shape = GBR_SPOT_CIRCLE;
|
||||
break;
|
||||
|
||||
case APT_OVAL: /* spot oval (for GERBER)*/
|
||||
track->m_Shape = S_SPOT_OVALE;
|
||||
gerb_item->m_Shape = GBR_SPOT_OVAL;
|
||||
break;
|
||||
|
||||
default: /* spot rect (for GERBER)*/
|
||||
track->m_Shape = S_SPOT_RECT;
|
||||
gerb_item->m_Shape = GBR_SPOT_RECT;
|
||||
break;
|
||||
}
|
||||
|
||||
len >>= 1;
|
||||
if( size.x > size.y )
|
||||
{
|
||||
track->m_Start.x -= len;
|
||||
track->m_End.x += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
track->m_Start.y -= len;
|
||||
track->m_End.y += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WinEDA_GerberFrame::Liste_D_Codes( )
|
||||
/** function DrawFlashedShape
|
||||
* Draw the dcode shape for flashed items.
|
||||
* When an item is flashed, the DCode shape is the shape of the item
|
||||
*/
|
||||
void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
wxPoint aShapePos, bool aFilledShape )
|
||||
{
|
||||
int ii, jj;
|
||||
D_CODE* pt_D_code;
|
||||
wxString Line;
|
||||
WinEDA_TextFrame* List;
|
||||
int scale = 10000;
|
||||
int curr_layer = GetScreen()->m_Active_Layer;
|
||||
int radius;
|
||||
|
||||
List = new WinEDA_TextFrame( this, _( "List D codes" ) );
|
||||
|
||||
for( int layer = 0; layer < 32; layer++ )
|
||||
switch( m_Shape )
|
||||
{
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
if( gerber == NULL )
|
||||
continue;
|
||||
|
||||
if( gerber->ReturnUsedDcodeNumber() == 0 )
|
||||
continue;
|
||||
|
||||
if( layer == curr_layer )
|
||||
Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
|
||||
case APT_CIRCLE:
|
||||
radius = m_Size.x >> 1;
|
||||
if( !aFilledShape )
|
||||
GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor );
|
||||
else
|
||||
Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
|
||||
List->Append( Line );
|
||||
|
||||
for( ii = 0, jj = 1; ii < MAX_TOOLS; ii++ )
|
||||
if( m_DrillShape == 0 )
|
||||
GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor );
|
||||
else if( m_DrillShape == 1 ) // round hole
|
||||
{
|
||||
pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE, false );
|
||||
if( pt_D_code == NULL )
|
||||
continue;
|
||||
int width = (m_Size.x - m_Drill.x ) / 2;
|
||||
GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor );
|
||||
}
|
||||
else // rectangular hole
|
||||
{
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
ConvertShapeToPolygon();
|
||||
DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
|
||||
}
|
||||
break;
|
||||
|
||||
if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
|
||||
continue;
|
||||
case APT_LINE:
|
||||
// not used for flashed items
|
||||
break;
|
||||
|
||||
Line.Printf( wxT(
|
||||
"tool %2.2d: D%2.2d V %2.4f H %2.4f %s" ),
|
||||
jj,
|
||||
pt_D_code->m_Num_Dcode,
|
||||
(float) pt_D_code->m_Size.y / scale,
|
||||
(float) pt_D_code->m_Size.x / scale,
|
||||
D_CODE::ShowApertureType( pt_D_code->m_Shape )
|
||||
);
|
||||
|
||||
if( !pt_D_code->m_Defined )
|
||||
Line += wxT( " ?" );
|
||||
|
||||
if( !pt_D_code->m_InUse )
|
||||
Line += wxT( " *" );
|
||||
|
||||
List->Append( Line );
|
||||
jj++;
|
||||
case APT_RECT:
|
||||
{
|
||||
wxPoint start;
|
||||
start.x = aShapePos.x - m_Size.x/2;
|
||||
start.y = aShapePos.y - m_Size.y/2;
|
||||
wxPoint end = start + m_Size;
|
||||
if( !aFilledShape )
|
||||
{
|
||||
GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y ,
|
||||
0, aColor );
|
||||
}
|
||||
else if( m_DrillShape == 0 )
|
||||
{
|
||||
GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
|
||||
0, aColor, aColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
ConvertShapeToPolygon();
|
||||
DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
ii = List->ShowModal();
|
||||
List->Destroy();
|
||||
if( ii < 0 )
|
||||
return;
|
||||
case APT_OVAL:
|
||||
{
|
||||
wxPoint start = aShapePos;
|
||||
wxPoint end = aShapePos;
|
||||
if( m_Size.x > m_Size.y ) // horizontal oval
|
||||
{
|
||||
int delta = (m_Size.x - m_Size.y) / 2;
|
||||
start.x -= delta;
|
||||
end.x += delta;
|
||||
radius = m_Size.y;
|
||||
}
|
||||
else // horizontal oval
|
||||
{
|
||||
int delta = (m_Size.y - m_Size.x) / 2;
|
||||
start.y -= delta;
|
||||
end.y += delta;
|
||||
radius = m_Size.x;
|
||||
}
|
||||
if( !aFilledShape )
|
||||
{
|
||||
GRCSegm( aClipBox, aDC, start.x, start.y,
|
||||
end.x, end.y, radius, aColor );
|
||||
}
|
||||
else if( m_DrillShape == 0 )
|
||||
{
|
||||
GRFillCSegm( aClipBox, aDC, start.x,
|
||||
start.y, end.x, end.y, radius, aColor );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
ConvertShapeToPolygon();
|
||||
DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case APT_POLYGON:
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
ConvertShapeToPolygon();
|
||||
DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
|
||||
break;
|
||||
|
||||
case APT_MACRO:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** function DrawFlashedPolygon
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* Draw some Apertures shapes when they are defined as filled polygons.
|
||||
* APT_POLYGON is always a polygon, but some complex shapes are also converted to
|
||||
* polygons (shapes with holes)
|
||||
*/
|
||||
void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
|
||||
int aColor, bool aFilled,
|
||||
const wxPoint& aPosition )
|
||||
{
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
return;
|
||||
|
||||
std::vector<wxPoint> points;
|
||||
points = m_PolyCorners;
|
||||
for( unsigned ii = 0; ii < points.size(); ii++ )
|
||||
{
|
||||
points[ii] += aPosition;
|
||||
}
|
||||
|
||||
GRClosedPoly( aClipBox, aDC, points.size(), &points[0], aFilled, aColor, aColor );
|
||||
}
|
||||
|
||||
|
||||
/** function ConvertShapeToPolygon
|
||||
* convert a shape to an equivalent polygon.
|
||||
* Arcs and circles are approximated by segments
|
||||
* Useful when a shape is not a graphic primitive (shape with hole,
|
||||
* Rotated shape ... ) and cannot be easily drawn.
|
||||
*/
|
||||
void D_CODE::ConvertShapeToPolygon()
|
||||
{
|
||||
#define SEGS_CNT 32 // number of segments to approximate a circle
|
||||
wxPoint initialpos;
|
||||
wxPoint currpos;;
|
||||
m_PolyCorners.clear();
|
||||
|
||||
switch( m_Shape )
|
||||
{
|
||||
case APT_CIRCLE: // creates only a circle with rectangular hole
|
||||
currpos.x = m_Size.x >> 1;
|
||||
initialpos = currpos;
|
||||
for( unsigned ii = 0; ii <= SEGS_CNT; ii++ )
|
||||
{
|
||||
currpos = initialpos;
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
if( m_DrillShape == 1 )
|
||||
{
|
||||
for( unsigned ii = 0 ; ii <= SEGS_CNT; ii++ )
|
||||
{
|
||||
currpos.x = m_Drill.x / 2;
|
||||
currpos.y = 0;
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
if( m_DrillShape == 2 ) // Create rectangular hole
|
||||
{
|
||||
currpos.x = m_Drill.x / 2;
|
||||
currpos.y = m_Drill.y / 2;
|
||||
m_PolyCorners.push_back( currpos ); // link to hole and begin hole
|
||||
currpos.x -= m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y -= m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.x += m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y += m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos ); // close hole
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
break;
|
||||
|
||||
case APT_LINE:
|
||||
// Not used for flashed shapes
|
||||
break;
|
||||
|
||||
case APT_RECT:
|
||||
currpos.x = m_Size.x / 2;
|
||||
currpos.y = m_Size.y / 2;
|
||||
initialpos = currpos;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.x -= m_Size.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y -= m_Size.y;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.x += m_Size.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y += m_Size.y;
|
||||
m_PolyCorners.push_back( currpos ); // close polygon
|
||||
if( m_DrillShape == 1 ) // build a round hole
|
||||
{
|
||||
for( int ii = 0 ; ii <= SEGS_CNT; ii++ )
|
||||
{
|
||||
currpos.x = 0;
|
||||
currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
if( m_DrillShape == 2 ) // Create rectangular hole
|
||||
{
|
||||
currpos.x = m_Drill.x / 2;
|
||||
currpos.y = m_Drill.y / 2;
|
||||
m_PolyCorners.push_back( currpos ); // link to hole and begin hole
|
||||
currpos.x -= m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y -= m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.x += m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y += m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos ); // close hole
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
break;
|
||||
|
||||
case APT_OVAL:
|
||||
{
|
||||
int delta, radius;
|
||||
|
||||
// we create an horizontal oval shape. then rotate if needed
|
||||
if( m_Size.x > m_Size.y ) // horizontal oval
|
||||
{
|
||||
delta = (m_Size.x - m_Size.y) / 2;
|
||||
radius = m_Size.y / 2;
|
||||
}
|
||||
else // vertical oval
|
||||
{
|
||||
delta = (m_Size.y - m_Size.x) / 2;
|
||||
radius = m_Size.x / 2;
|
||||
}
|
||||
currpos.y = radius;
|
||||
initialpos = currpos;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
|
||||
// build the right arc of the shape
|
||||
unsigned ii = 0;
|
||||
for( ; ii <= SEGS_CNT / 2; ii++ )
|
||||
{
|
||||
currpos = initialpos;
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
currpos.x += delta;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
|
||||
// build the left arc of the shape
|
||||
for( ii = SEGS_CNT / 2; ii <= SEGS_CNT; ii++ )
|
||||
{
|
||||
currpos = initialpos;
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
currpos.x -= delta;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
m_PolyCorners.push_back( initialpos ); // close outline
|
||||
if( m_Size.y > m_Size.x ) // vertical oval, rotate polygon.
|
||||
{
|
||||
for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
|
||||
RotatePoint( &m_PolyCorners[jj], 900 );
|
||||
}
|
||||
if( m_DrillShape == 1 ) // build a round hole
|
||||
{
|
||||
for( ii = 0 ; ii <= SEGS_CNT; ii++ )
|
||||
{
|
||||
currpos.x = 0;
|
||||
currpos.y = m_Drill.x / 2; // m_Drill.x / 2 is the radius of the hole
|
||||
RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
|
||||
m_PolyCorners.push_back( currpos );
|
||||
}
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
if( m_DrillShape == 2 ) // Create rectangular hole
|
||||
{
|
||||
currpos.x = m_Drill.x / 2;
|
||||
currpos.y = m_Drill.y / 2;
|
||||
m_PolyCorners.push_back( currpos ); // link to hole and begin hole
|
||||
currpos.x -= m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y -= m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.x += m_Drill.x;
|
||||
m_PolyCorners.push_back( currpos );
|
||||
currpos.y += m_Drill.y;
|
||||
m_PolyCorners.push_back( currpos ); // close hole
|
||||
m_PolyCorners.push_back( initialpos ); // link to outline
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case APT_POLYGON:
|
||||
// TODO
|
||||
break;
|
||||
|
||||
case APT_MACRO:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/**************/
|
||||
/* dcode.h */
|
||||
/**************/
|
||||
|
||||
#ifndef _DCODE_H_
|
||||
#define _DCODE_H_
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "base_struct.h"
|
||||
|
||||
|
||||
/**
|
||||
* Enum APERTURE_T
|
||||
* is the set of all gerber aperture types allowed, according to page 16 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
enum APERTURE_T
|
||||
{
|
||||
APT_CIRCLE = 'C',
|
||||
APT_LINE = 'L',
|
||||
APT_RECT = 'R',
|
||||
APT_OVAL = '0',
|
||||
APT_POLYGON = 'P',
|
||||
APT_MACRO = 'M'
|
||||
};
|
||||
|
||||
|
||||
#define FIRST_DCODE 10
|
||||
#define LAST_DCODE 999 // dcodes values are from 10 to 999
|
||||
#define TOOLS_MAX_COUNT (LAST_DCODE+1)
|
||||
|
||||
class D_CODE;
|
||||
|
||||
|
||||
/**
|
||||
* Class DCODE_PARAM
|
||||
* holds a parameter for a DCODE or an "aperture macro" as defined within
|
||||
* 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
|
||||
* referencing aperture macro. In that case, the \a index field is an index
|
||||
* into the aperture macro's parameters.
|
||||
*/
|
||||
class DCODE_PARAM
|
||||
{
|
||||
public:
|
||||
DCODE_PARAM() :
|
||||
index(-1),
|
||||
value(0.0)
|
||||
{}
|
||||
|
||||
double GetValue( const D_CODE* aDcode ) const;
|
||||
void SetValue( double aValue )
|
||||
{
|
||||
value = aValue;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsImmediate
|
||||
* tests if this DCODE_PARAM holds an immediate parameter or is a pointer
|
||||
* into a parameter held by an owning D_CODE.
|
||||
*/
|
||||
bool IsImmediate() const { return index == -1; }
|
||||
|
||||
unsigned GetIndex() const
|
||||
{
|
||||
return (unsigned) index;
|
||||
}
|
||||
|
||||
void SetIndex( int aIndex )
|
||||
{
|
||||
index = aIndex;
|
||||
}
|
||||
|
||||
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.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum AM_PRIMITIVE_ID
|
||||
* is the set of all "aperture macro primitives" (primitive numbers). See
|
||||
* Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
enum AM_PRIMITIVE_ID
|
||||
{
|
||||
AMP_CIRCLE = 1,
|
||||
AMP_LINE2 = 2,
|
||||
AMP_LINE20 = 20,
|
||||
AMP_LINE_CENTER = 21,
|
||||
AMP_LINE_LOWER_LEFT = 22,
|
||||
AMP_EOF = 3,
|
||||
AMP_OUTLINE = 4,
|
||||
AMP_POLYGON = 5,
|
||||
AMP_MOIRE = 6,
|
||||
AMP_THERMAL = 7,
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<DCODE_PARAM> DCODE_PARAMS;
|
||||
|
||||
/**
|
||||
* Struct AM_PRIMITIVE
|
||||
* holds an aperture macro primitive as given in Table 3 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
struct AM_PRIMITIVE
|
||||
{
|
||||
AM_PRIMITIVE_ID primitive_id; ///< The primitive type
|
||||
DCODE_PARAMS params; ///< A sequence of parameters used by
|
||||
// the primitive
|
||||
|
||||
/**
|
||||
* Function GetExposure
|
||||
* returns the first parameter in integer form. Some but not all primitives
|
||||
* use the first parameter as an exposure control.
|
||||
*/
|
||||
int GetExposure() const
|
||||
{
|
||||
// No D_CODE* for GetValue()
|
||||
wxASSERT( params.size() && params[0].IsImmediate() );
|
||||
return (int) params[0].GetValue( NULL );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO
|
||||
* helps support the "aperture macro" defined within standard RS274X.
|
||||
*/
|
||||
struct APERTURE_MACRO
|
||||
{
|
||||
wxString name; ///< The name of the aperture macro
|
||||
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO_less_than
|
||||
* is used by std:set<APERTURE_MACRO> instantiation which uses
|
||||
* APERTURE_MACRO.name as its key.
|
||||
*/
|
||||
struct APERTURE_MACRO_less_than
|
||||
{
|
||||
// a "less than" test on two APERTURE_MACROs (.name wxStrings)
|
||||
bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2) const
|
||||
{
|
||||
return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type APERTURE_MACRO_SET
|
||||
* is a sorted collection of APERTURE_MACROS whose key is the name field in
|
||||
* the APERTURE_MACRO.
|
||||
*/
|
||||
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
|
||||
typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
|
||||
|
||||
|
||||
/**
|
||||
* Class D_CODE
|
||||
* holds a gerber DCODE definition.
|
||||
*/
|
||||
class D_CODE
|
||||
{
|
||||
friend class DCODE_PARAM;
|
||||
|
||||
APERTURE_MACRO* m_Macro; ///< no ownership, points to
|
||||
// GERBER.m_aperture_macros element
|
||||
|
||||
/**
|
||||
* parameters used only when this D_CODE holds a reference to an aperture
|
||||
* macro, and these parameters would customize the macro.
|
||||
*/
|
||||
DCODE_PARAMS m_am_params;
|
||||
|
||||
std::vector <wxPoint> m_PolyCorners; /* Polygon used to draw AMP_POLYGON shape and some other
|
||||
* complex shapes which are converted to polygon
|
||||
* (shapes with hole, rotated rectangles ...
|
||||
*/
|
||||
|
||||
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) */
|
||||
int m_DrillShape; /* shape of the hole (round = 1, rect = 2) */
|
||||
double m_Rotation; /* shape rotation in degrees */
|
||||
bool m_InUse; /* FALSE if not used */
|
||||
bool m_Defined; /* FALSE if not defined */
|
||||
wxString m_SpecialDescr;
|
||||
|
||||
public:
|
||||
D_CODE( int num_dcode );
|
||||
~D_CODE();
|
||||
void Clear_D_CODE_Data();
|
||||
|
||||
void AppendParam( double aValue )
|
||||
{
|
||||
DCODE_PARAM param;
|
||||
|
||||
param.SetValue( aValue );
|
||||
|
||||
m_am_params.push_back( param );
|
||||
}
|
||||
|
||||
void SetMacro( APERTURE_MACRO* aMacro )
|
||||
{
|
||||
m_Macro = aMacro;
|
||||
}
|
||||
APERTURE_MACRO* GetMacro() { return m_Macro; }
|
||||
|
||||
/**
|
||||
* Function ShowApertureType
|
||||
* returns a character string telling what type of aperture type \a aType is.
|
||||
* @param aType The aperture type to show.
|
||||
*/
|
||||
static const wxChar* ShowApertureType( APERTURE_T aType );
|
||||
|
||||
/** function DrawFlashedShape
|
||||
* Draw the dcode shape for flashed items.
|
||||
* When an item is flashed, the DCode shape is the shape of the item
|
||||
*/
|
||||
void DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
wxPoint aShapePos, bool aFilledShape );
|
||||
|
||||
/** function DrawFlashedPolygon
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* Draw some Apertures shapes when they are defined as filled polygons.
|
||||
* APT_POLYGON is always a polygon, but some complex shapes are also converted to
|
||||
* polygons (shapes with holes, some rotated shapes)
|
||||
*/
|
||||
void DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
|
||||
bool aFilled, const wxPoint& aPosition );
|
||||
|
||||
/** function ConvertShapeToPolygon
|
||||
* convert a shape to an equivalent polygon.
|
||||
* Arcs and circles are approximated by segments
|
||||
* Useful when a shape is not a graphic primitive (shape with hole,
|
||||
* rotated shape ... ) and cannot be easily drawn.
|
||||
*/
|
||||
void ConvertShapeToPolygon( );
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline double DCODE_PARAM::GetValue( const D_CODE* aDcode ) const
|
||||
{
|
||||
if( IsImmediate() )
|
||||
return value;
|
||||
else
|
||||
{
|
||||
// the first one was numbered 1, not zero, as in $1, see page 19 of spec.
|
||||
unsigned ndx = GetIndex() - 1;
|
||||
wxASSERT(aDcode);
|
||||
// get the parameter from the aDcode
|
||||
if( ndx < aDcode->m_am_params.size() )
|
||||
return aDcode->m_am_params[ndx].GetValue( NULL );
|
||||
else
|
||||
{
|
||||
wxASSERT( GetIndex()-1 < aDcode->m_am_params.size() );
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // ifndef _DCODE_H_
|
|
@ -1,14 +1,13 @@
|
|||
/*********************************************/
|
||||
/* Edit Track: Erase Routines */
|
||||
/* Drop the segment, track, and net area */
|
||||
/* Edit Track: Erase functions */
|
||||
/*********************************************/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
//#include "class_drawpanel.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "protos.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
|
||||
|
||||
void WinEDA_GerberFrame::Delete_DCode_Items( wxDC* DC,
|
||||
|
@ -18,73 +17,22 @@ void WinEDA_GerberFrame::Delete_DCode_Items( wxDC* DC,
|
|||
if( dcode_value < FIRST_DCODE ) // No tool selected
|
||||
return;
|
||||
|
||||
TRACK* next;
|
||||
for( TRACK* track = GetBoard()->m_Track; track; track = next )
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
BOARD_ITEM * next;
|
||||
for( ; item; item = next )
|
||||
{
|
||||
next = track->Next();
|
||||
next = item->Next();
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
|
||||
if( dcode_value != track->GetNet() )
|
||||
if( dcode_value != gerb_item->m_DCode )
|
||||
continue;
|
||||
|
||||
if( layer_number >= 0 && layer_number != track->GetLayer() )
|
||||
if( layer_number >= 0 && layer_number != gerb_item->m_Layer )
|
||||
continue;
|
||||
|
||||
Delete_Segment( DC, track );
|
||||
// TODO: Delete_Item( DC, item );
|
||||
}
|
||||
|
||||
GetScreen()->SetCurItem( NULL );
|
||||
}
|
||||
|
||||
|
||||
/* Removes 1 segment of track.
|
||||
*
|
||||
* If There is evidence of new track: erase segment
|
||||
* Otherwise: Delete segment under the cursor.
|
||||
*/
|
||||
TRACK* WinEDA_GerberFrame::Delete_Segment( wxDC* DC, TRACK* Track )
|
||||
{
|
||||
if( Track == NULL )
|
||||
return NULL;
|
||||
|
||||
if( Track->m_Flags & IS_NEW ) // Trace in progress, delete the last
|
||||
// segment
|
||||
{
|
||||
if( g_CurrentTrackList.GetCount() > 0 )
|
||||
{
|
||||
// Change track.
|
||||
delete g_CurrentTrackList.PopBack();
|
||||
|
||||
if( g_CurrentTrackList.GetCount()
|
||||
&& g_CurrentTrackSegment->Type() == TYPE_VIA )
|
||||
{
|
||||
delete g_CurrentTrackList.PopBack();
|
||||
}
|
||||
|
||||
UpdateStatusBar();
|
||||
|
||||
if( g_CurrentTrackList.GetCount() == 0 )
|
||||
{
|
||||
DrawPanel->ManageCurseur = NULL;
|
||||
DrawPanel->ForceCloseManageCurseur = NULL;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( DrawPanel->ManageCurseur )
|
||||
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
|
||||
return g_CurrentTrackSegment;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Trace_Segment( GetBoard(), DrawPanel, DC, Track, GR_XOR );
|
||||
|
||||
DLIST<TRACK>* container = (DLIST<TRACK>*)Track->GetList();
|
||||
wxASSERT( container );
|
||||
container->Remove( Track );
|
||||
|
||||
GetScreen()->SetModify();
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "common.h"
|
||||
#include "pcbnew.h"
|
||||
|
||||
|
||||
TRACK* Marque_Une_Piste( BOARD* aPcb,
|
||||
TRACK* aStartSegm,
|
||||
int* aSegmCount,
|
||||
|
@ -19,3 +18,4 @@ TRACK* Marque_Une_Piste( BOARD* aPcb,
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,12 +53,11 @@ void WinEDA_GerberFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|
|||
DrawStruct = GerberGeneralLocateAndDisplay();
|
||||
if( DrawStruct == NULL )
|
||||
break;
|
||||
if( DrawStruct->Type() == TYPE_TRACK )
|
||||
{
|
||||
Delete_Segment( DC, (TRACK*) DrawStruct );
|
||||
/* TODO:
|
||||
Delete_Item( DC, (GERBER_DRAW_ITEM*) DrawStruct );
|
||||
GetScreen()->SetCurItem( NULL );
|
||||
GetScreen()->SetModify();
|
||||
}
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -85,13 +84,9 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
{
|
||||
case wxID_CUT:
|
||||
case wxID_COPY:
|
||||
case ID_POPUP_MIRROR_X_BLOCK:
|
||||
case ID_POPUP_DELETE_BLOCK:
|
||||
case ID_POPUP_PLACE_BLOCK:
|
||||
case ID_POPUP_ZOOM_BLOCK:
|
||||
case ID_POPUP_FLIP_BLOCK:
|
||||
case ID_POPUP_ROTATE_BLOCK:
|
||||
case ID_POPUP_COPY_BLOCK:
|
||||
break;
|
||||
|
||||
case ID_POPUP_CANCEL_CURRENT_COMMAND:
|
||||
|
@ -196,13 +191,6 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
HandleBlockPlace( &dc );
|
||||
break;
|
||||
|
||||
case ID_POPUP_COPY_BLOCK:
|
||||
GetScreen()->m_BlockLocate.m_Command = BLOCK_COPY;
|
||||
GetScreen()->m_BlockLocate.SetMessageBlock( this );
|
||||
DrawPanel->m_AutoPAN_Request = FALSE;
|
||||
HandleBlockEnd( &dc );
|
||||
break;
|
||||
|
||||
case ID_POPUP_ZOOM_BLOCK:
|
||||
GetScreen()->m_BlockLocate.m_Command = BLOCK_ZOOM;
|
||||
GetScreen()->m_BlockLocate.SetMessageBlock( this );
|
||||
|
@ -216,12 +204,6 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
|
|||
HandleBlockEnd( &dc );
|
||||
break;
|
||||
|
||||
case ID_POPUP_MIRROR_X_BLOCK:
|
||||
GetScreen()->m_BlockLocate.m_Command = BLOCK_MIRROR_X;
|
||||
GetScreen()->m_BlockLocate.SetMessageBlock( this );
|
||||
HandleBlockEnd( &dc );
|
||||
break;
|
||||
|
||||
case ID_GERBVIEW_POPUP_DELETE_DCODE_ITEMS:
|
||||
if( gerber_layer )
|
||||
Delete_DCode_Items( &dc, gerber_layer->m_Selected_Tool,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "gerbview.h"
|
||||
#include "class_board_design_settings.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
#include "protos.h"
|
||||
|
||||
static int SavePcbFormatAscii( WinEDA_GerberFrame* frame,
|
||||
|
@ -128,7 +129,6 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
|
|||
int* LayerLookUpTable )
|
||||
{
|
||||
char line[256];
|
||||
TRACK* track;
|
||||
BOARD* gerberPcb = frame->GetBoard();
|
||||
BOARD* pcb;
|
||||
|
||||
|
@ -136,10 +136,11 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
|
|||
|
||||
// create an image of gerber data
|
||||
pcb = new BOARD( NULL, frame );
|
||||
|
||||
for( track = gerberPcb->m_Track; track; track = track->Next() )
|
||||
BOARD_ITEM* item = gerberPcb->m_Drawings;
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
int layer = track->GetLayer();
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
int layer = gerb_item->m_Layer;
|
||||
int pcb_layer_number = LayerLookUpTable[layer];
|
||||
if( pcb_layer_number < 0 || pcb_layer_number > LAST_NO_COPPER_LAYER )
|
||||
continue;
|
||||
|
@ -149,17 +150,17 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
|
|||
DRAWSEGMENT* drawitem = new DRAWSEGMENT( pcb, TYPE_DRAWSEGMENT );
|
||||
|
||||
drawitem->SetLayer( pcb_layer_number );
|
||||
drawitem->m_Start = track->m_Start;
|
||||
drawitem->m_End = track->m_End;
|
||||
drawitem->m_Width = track->m_Width;
|
||||
drawitem->m_Start = gerb_item->m_Start;
|
||||
drawitem->m_End = gerb_item->m_End;
|
||||
drawitem->m_Width = gerb_item->m_Size.x;
|
||||
|
||||
if( track->m_Shape == S_ARC )
|
||||
if( gerb_item->m_Shape == GBR_ARC )
|
||||
{
|
||||
double cx = track->m_Param;
|
||||
double cy = track->GetSubNet();
|
||||
double a = atan2( track->m_Start.y - cy,
|
||||
track->m_Start.x - cx );
|
||||
double b = atan2( track->m_End.y - cy, track->m_End.x - cx );
|
||||
double cx = gerb_item->m_ArcCentre.x;
|
||||
double cy = gerb_item->m_ArcCentre.y;
|
||||
double a = atan2( gerb_item->m_Start.y - cy,
|
||||
gerb_item->m_Start.x - cx );
|
||||
double b = atan2( gerb_item->m_End.y - cy, gerb_item->m_End.x - cx );
|
||||
|
||||
drawitem->m_Shape = S_ARC;
|
||||
drawitem->m_Angle = (int) fmod(
|
||||
|
@ -175,34 +176,28 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
|
|||
TRACK* newtrack;
|
||||
|
||||
// replace spots with vias when possible
|
||||
if( track->m_Shape == S_SPOT_CIRCLE
|
||||
|| track->m_Shape == S_SPOT_RECT
|
||||
|| track->m_Shape == S_SPOT_OVALE )
|
||||
if( gerb_item->m_Shape == GBR_SPOT_CIRCLE
|
||||
|| gerb_item->m_Shape == GBR_SPOT_RECT
|
||||
|| gerb_item->m_Shape == GBR_SPOT_OVAL )
|
||||
{
|
||||
newtrack = new SEGVIA( (const SEGVIA &) * track );
|
||||
newtrack = new SEGVIA( pcb );
|
||||
|
||||
// A spot is found, and can be a via: change it to via, and
|
||||
// delete other
|
||||
// spots at same location
|
||||
newtrack->m_Shape = VIA_THROUGH;
|
||||
|
||||
newtrack->SetLayer( 0x0F ); // Layers are 0 to 15 (Cu/Cmp)
|
||||
|
||||
newtrack->SetDrillDefault();
|
||||
|
||||
// Compute the via position from track position ( Via position
|
||||
// is the
|
||||
// position of the middle of the track segment )
|
||||
newtrack->m_Start.x =
|
||||
(newtrack->m_Start.x + newtrack->m_End.x) / 2;
|
||||
newtrack->m_Start.y =
|
||||
(newtrack->m_Start.y + newtrack->m_End.y) / 2;
|
||||
newtrack->m_End = newtrack->m_Start;
|
||||
newtrack->m_Start = newtrack->m_End = gerb_item->m_Start;
|
||||
newtrack->m_Width = (gerb_item->m_Size.x + gerb_item->m_Size.y) / 2;
|
||||
}
|
||||
else // a true TRACK
|
||||
{
|
||||
newtrack = track->Copy();
|
||||
newtrack = new TRACK( pcb );
|
||||
newtrack->SetLayer( pcb_layer_number );
|
||||
newtrack->m_Start = gerb_item->m_Start;
|
||||
newtrack->m_End = gerb_item->m_End;
|
||||
newtrack->m_Width = gerb_item->m_Size.x;
|
||||
}
|
||||
|
||||
pcb->Add( newtrack );
|
||||
|
@ -210,7 +205,7 @@ static int SavePcbFormatAscii( WinEDA_GerberFrame* frame, FILE* aFile,
|
|||
}
|
||||
|
||||
// delete redundant vias
|
||||
for( track = pcb->m_Track; track; track = track->Next() )
|
||||
for( TRACK * track = pcb->m_Track; track; track = track->Next() )
|
||||
{
|
||||
if( track->m_Shape != VIA_THROUGH )
|
||||
continue;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
G04 Test flashing of circular apertures*
|
||||
G04 Four groups of circular apertures are arranged in a square*
|
||||
G04 Handcoded by Julian Lamb *
|
||||
%MOIN*%
|
||||
%FSLAX23Y23*%
|
||||
%ADD10C,0.050*%
|
||||
%ADD11C,0.050X0.025*%
|
||||
%ADD12C,0.050X0.025X0.030*%
|
||||
|
||||
G04 No hole, centered at 0,0 *
|
||||
G54D10*
|
||||
X0Y0D03*
|
||||
|
||||
G04 Round hole, centered at 0.1,0 *
|
||||
G54D11*
|
||||
X00100Y0D03*
|
||||
|
||||
G04 Square hole, centered at 0,0.1 *
|
||||
G54D12*
|
||||
X0Y00100D03*
|
||||
|
||||
G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
|
||||
G54D11*
|
||||
X00100Y00090D03*
|
||||
X00100Y00110D03*
|
||||
|
||||
M02*
|
|
@ -0,0 +1,27 @@
|
|||
G04 Test flashing of obround apertures*
|
||||
G04 Four groups of obround apertures are arranged in a square*
|
||||
G04 Handcoded by Julian Lamb *
|
||||
%MOIN*%
|
||||
%FSLAX23Y23*%
|
||||
%ADD10O,0.050X0.080*%
|
||||
%ADD11O,0.080X0.050X0.025*%
|
||||
%ADD12O,0.050X0.025X0.025X0.0150*%
|
||||
|
||||
G04 No hole, centered at 0,0 *
|
||||
G54D10*
|
||||
X0Y0D03*
|
||||
|
||||
G04 Round hole, centered at 0.1,0 *
|
||||
G54D11*
|
||||
X00100Y0D03*
|
||||
|
||||
G04 Square hole, centered at 0,0.1 *
|
||||
G54D12*
|
||||
X0Y00100D03*
|
||||
|
||||
G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
|
||||
G54D11*
|
||||
X00100Y00090D03*
|
||||
X00100Y00110D03*
|
||||
|
||||
M02*
|
|
@ -0,0 +1,27 @@
|
|||
G04 Test flashing of polygon apertures*
|
||||
G04 Four groups of polygon apertures are arranged in a square*
|
||||
G04 Handcoded by Julian Lamb *
|
||||
%MOIN*%
|
||||
%FSLAX23Y23*%
|
||||
%ADD10P,0.050X3*%
|
||||
%ADD11P,0.050X6X-45X0.035*%
|
||||
%ADD12P,0.040X10X25X0.025X0.025X0.0150*%
|
||||
|
||||
G04 Triangle, centered at 0,0 *
|
||||
G54D10*
|
||||
X0Y0D03*
|
||||
|
||||
G04 Hexagon with round hole rotate 45 degreed ccwise, centered at 0.1,0 *
|
||||
G54D11*
|
||||
X00100Y0D03*
|
||||
|
||||
G04 10-sided with square hole rotated 25 degrees, centered at 0,0.1 *
|
||||
G54D12*
|
||||
X0Y00100D03*
|
||||
|
||||
G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
|
||||
G54D11*
|
||||
X00100Y00090D03*
|
||||
X00100Y00110D03*
|
||||
|
||||
M02*
|
|
@ -0,0 +1,27 @@
|
|||
G04 Test flashing of rectangular apertures*
|
||||
G04 Four groups of rectangular apertures are arranged in a square*
|
||||
G04 Handcoded by Julian Lamb *
|
||||
%MOIN*%
|
||||
%FSLAX23Y23*%
|
||||
%ADD10R,0.050X0.080*%
|
||||
%ADD11R,0.080X0.050X0.025*%
|
||||
%ADD12R,0.050X0.025X0.025X0.0150*%
|
||||
|
||||
G04 No hole, centered at 0,0 *
|
||||
G54D10*
|
||||
X0Y0D03*
|
||||
|
||||
G04 Round hole, centered at 0.1,0 *
|
||||
G54D11*
|
||||
X00100Y0D03*
|
||||
|
||||
G04 Square hole, centered at 0,0.1 *
|
||||
G54D12*
|
||||
X0Y00100D03*
|
||||
|
||||
G04 Two, with round holes, slightly overlapping, centered at 0.1,0.1 *
|
||||
G54D11*
|
||||
X00100Y00090D03*
|
||||
X00100Y00110D03*
|
||||
|
||||
M02*
|
|
@ -13,6 +13,7 @@
|
|||
#include "class_drawpanel.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
#include "pcbplot.h"
|
||||
#include "bitmaps.h"
|
||||
#include "protos.h"
|
||||
|
@ -113,6 +114,10 @@ BEGIN_EVENT_TABLE( WinEDA_GerberFrame, WinEDA_BasePcbFrame )
|
|||
// Option toolbar
|
||||
EVT_TOOL_RANGE( ID_TB_OPTIONS_START, ID_TB_OPTIONS_END,
|
||||
WinEDA_GerberFrame::OnSelectOptionToolbar )
|
||||
EVT_TOOL( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
|
||||
WinEDA_GerberFrame::OnSelectOptionToolbar )
|
||||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LINES_SKETCH,
|
||||
WinEDA_GerberFrame::OnSelectOptionToolbar )
|
||||
EVT_TOOL( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
||||
WinEDA_GerberFrame::OnSelectOptionToolbar )
|
||||
EVT_TOOL( ID_TB_OPTIONS_SHOW_DCODES,
|
||||
|
@ -236,117 +241,22 @@ void WinEDA_GerberFrame::OnCloseWindow( wxCloseEvent& Event )
|
|||
}
|
||||
|
||||
|
||||
/** Function SetToolbars()
|
||||
* Set the tools state for the toolbars, according to display options
|
||||
*/
|
||||
void WinEDA_GerberFrame::SetToolbars()
|
||||
{
|
||||
PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen();
|
||||
int layer = screen->m_Active_Layer;
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
|
||||
if( m_HToolBar == NULL )
|
||||
return;
|
||||
|
||||
if( GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE )
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, true );
|
||||
m_HToolBar->EnableTool( wxID_COPY, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, false );
|
||||
m_HToolBar->EnableTool( wxID_COPY, false );
|
||||
}
|
||||
|
||||
if( m_SelLayerBox && (m_SelLayerBox->GetSelection() != screen->m_Active_Layer) )
|
||||
{
|
||||
m_SelLayerBox->SetSelection( screen->m_Active_Layer );
|
||||
}
|
||||
|
||||
if( m_SelLayerTool )
|
||||
{
|
||||
if( gerber )
|
||||
{
|
||||
int sel_index;
|
||||
m_SelLayerTool->Enable( true );
|
||||
if( gerber->m_Selected_Tool < FIRST_DCODE ) // No tool selected
|
||||
sel_index = 0;
|
||||
else
|
||||
sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1;
|
||||
|
||||
if( sel_index != m_SelLayerTool->GetSelection() )
|
||||
{
|
||||
m_SelLayerTool->SetSelection( sel_index );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SelLayerTool->SetSelection( 0 );
|
||||
m_SelLayerTool->Enable( false );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_OptionsToolBar )
|
||||
{
|
||||
m_OptionsToolBar->ToggleTool(
|
||||
ID_TB_OPTIONS_SELECT_UNIT_MM,
|
||||
g_UserUnit ==
|
||||
MILLIMETRES ? true : false );
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SELECT_UNIT_INCH,
|
||||
g_UserUnit == INCHES ? true : false );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_POLAR_COORD,
|
||||
DisplayOpt.DisplayPolarCood );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_GRID,
|
||||
IsGridVisible() );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SELECT_CURSOR,
|
||||
m_CursorShape );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH,
|
||||
!m_DisplayPadFill );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH,
|
||||
!m_DisplayPcbTrackFill );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH,
|
||||
g_DisplayPolygonsModeSketch == 0 ? 0 : 1 );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_DCODES,
|
||||
IsElementVisible( DCODES_VISIBLE ) );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
||||
m_show_layer_manager_tools );
|
||||
if( m_show_layer_manager_tools )
|
||||
GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
_("Hide &Layers Manager" ) );
|
||||
else
|
||||
GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
_("Show &Layers Manager" ) );
|
||||
|
||||
}
|
||||
|
||||
DisplayUnitsMsg();
|
||||
|
||||
if( m_auimgr.GetManagedWindow() )
|
||||
m_auimgr.Update();
|
||||
}
|
||||
|
||||
|
||||
int WinEDA_GerberFrame::BestZoom()
|
||||
{
|
||||
double x, y;
|
||||
wxSize size;
|
||||
EDA_Rect bbox;
|
||||
|
||||
GetBoard()->ComputeBoundaryBox();
|
||||
size = DrawPanel->GetClientSize();
|
||||
x = ( (double) GetBoard()->m_BoundaryBox.GetWidth() +
|
||||
GetScreen()->GetGridSize().x ) / (double) size.x;
|
||||
y = ( (double) GetBoard()->m_BoundaryBox.GetHeight() +
|
||||
GetScreen()->GetGridSize().y ) / (double) size.y;
|
||||
GetScreen()->m_Curseur = GetBoard()->m_BoundaryBox.Centre();
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
bbox.Merge( gerb_item->GetBoundingBox() );
|
||||
}
|
||||
|
||||
wxSize size = DrawPanel->GetClientSize();
|
||||
x = ( bbox.GetWidth() + GetScreen()->GetGridSize().x ) / (double) size.x;
|
||||
y = ( bbox.GetHeight() + GetScreen()->GetGridSize().y ) / (double) size.y;
|
||||
GetScreen()->m_Curseur = bbox.Centre();
|
||||
|
||||
return wxRound( MAX( x, y ) * (double) GetScreen()->m_ZoomScalar );
|
||||
}
|
||||
|
@ -506,3 +416,65 @@ void WinEDA_GerberFrame::SetLanguage( wxCommandEvent& event )
|
|||
|
||||
ReFillLayerWidget();
|
||||
}
|
||||
|
||||
|
||||
void WinEDA_GerberFrame::Liste_D_Codes( )
|
||||
{
|
||||
int ii, jj;
|
||||
D_CODE* pt_D_code;
|
||||
wxString Line;
|
||||
WinEDA_TextFrame* List;
|
||||
int scale = 10000;
|
||||
int curr_layer = GetScreen()->m_Active_Layer;
|
||||
|
||||
List = new WinEDA_TextFrame( this, _( "List D codes" ) );
|
||||
|
||||
for( int layer = 0; layer < 32; layer++ )
|
||||
{
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
if( gerber == NULL )
|
||||
continue;
|
||||
|
||||
if( gerber->ReturnUsedDcodeNumber() == 0 )
|
||||
continue;
|
||||
|
||||
if( layer == curr_layer )
|
||||
Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
|
||||
else
|
||||
Line.Printf( wxT( "*** layer %2.2d ***" ), layer + 1 );
|
||||
List->Append( Line );
|
||||
|
||||
for( ii = 0, jj = 1; ii < TOOLS_MAX_COUNT; ii++ )
|
||||
{
|
||||
pt_D_code = gerber->GetDCODE( ii + FIRST_DCODE, false );
|
||||
if( pt_D_code == NULL )
|
||||
continue;
|
||||
|
||||
if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
|
||||
continue;
|
||||
|
||||
Line.Printf( wxT(
|
||||
"tool %2.2d: D%2.2d V %2.4f H %2.4f %s" ),
|
||||
jj,
|
||||
pt_D_code->m_Num_Dcode,
|
||||
(float) pt_D_code->m_Size.y / scale,
|
||||
(float) pt_D_code->m_Size.x / scale,
|
||||
D_CODE::ShowApertureType( pt_D_code->m_Shape )
|
||||
);
|
||||
|
||||
if( !pt_D_code->m_Defined )
|
||||
Line += wxT( " ?" );
|
||||
|
||||
if( !pt_D_code->m_InUse )
|
||||
Line += wxT( " *" );
|
||||
|
||||
List->Append( Line );
|
||||
jj++;
|
||||
}
|
||||
}
|
||||
|
||||
ii = List->ShowModal();
|
||||
List->Destroy();
|
||||
if( ii < 0 )
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "dcode.h"
|
||||
|
||||
class WinEDA_GerberFrame;
|
||||
class BOARD;
|
||||
|
@ -54,22 +55,6 @@ extern Ki_PageDescr* g_GerberPageSizeList[];
|
|||
extern const wxString GerbviewShowPageSizeOption;
|
||||
extern const wxString GerbviewShowDCodes;
|
||||
|
||||
/**
|
||||
* Enum APERTURE_T
|
||||
* is the set of all gerber aperture types allowed, according to page 16 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
enum APERTURE_T
|
||||
{
|
||||
APT_CIRCLE = 'C',
|
||||
APT_LINE = 'L',
|
||||
APT_RECT = 'R',
|
||||
APT_OVAL = '0',
|
||||
APT_POLYGON = 'P',
|
||||
APT_MACRO = 'M'
|
||||
};
|
||||
|
||||
|
||||
// Interpolation type
|
||||
enum Gerb_Interpolation
|
||||
{
|
||||
|
@ -106,9 +91,6 @@ enum Gerb_GCommand
|
|||
};
|
||||
|
||||
|
||||
#define MAX_TOOLS 2048
|
||||
#define FIRST_DCODE 10
|
||||
|
||||
enum Gerb_Analyse_Cmd
|
||||
{
|
||||
CMD_IDLE = 0,
|
||||
|
@ -119,223 +101,13 @@ enum Gerb_Analyse_Cmd
|
|||
class D_CODE;
|
||||
|
||||
|
||||
/**
|
||||
* Class DCODE_PARAM
|
||||
* holds a parameter for a DCODE or an "aperture macro" as defined within
|
||||
* 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
|
||||
* referencing aperture macro. In that case, the \a index field is an index
|
||||
* into the aperture macro's parameters.
|
||||
*/
|
||||
class DCODE_PARAM
|
||||
{
|
||||
public:
|
||||
DCODE_PARAM() :
|
||||
index(-1),
|
||||
value(0.0)
|
||||
{}
|
||||
|
||||
double GetValue( const D_CODE* aDcode ) const;
|
||||
void SetValue( double aValue )
|
||||
{
|
||||
value = aValue;
|
||||
index = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IsImmediate
|
||||
* tests if this DCODE_PARAM holds an immediate parameter or is a pointer
|
||||
* into a parameter held by an owning D_CODE.
|
||||
*/
|
||||
bool IsImmediate() const { return index == -1; }
|
||||
|
||||
unsigned GetIndex() const
|
||||
{
|
||||
return (unsigned) index;
|
||||
}
|
||||
|
||||
void SetIndex( int aIndex )
|
||||
{
|
||||
index = aIndex;
|
||||
}
|
||||
|
||||
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.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum AM_PRIMITIVE_ID
|
||||
* is the set of all "aperture macro primitives" (primitive numbers). See
|
||||
* Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
enum AM_PRIMITIVE_ID
|
||||
{
|
||||
AMP_CIRCLE = 1,
|
||||
AMP_LINE2 = 2,
|
||||
AMP_LINE20 = 20,
|
||||
AMP_LINE_CENTER = 21,
|
||||
AMP_LINE_LOWER_LEFT = 22,
|
||||
AMP_EOF = 3,
|
||||
AMP_OUTLINE = 4,
|
||||
AMP_POLYGON = 5,
|
||||
AMP_MOIRE = 6,
|
||||
AMP_THERMAL = 7,
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<DCODE_PARAM> DCODE_PARAMS;
|
||||
|
||||
/**
|
||||
* Struct AM_PRIMITIVE
|
||||
* holds an aperture macro primitive as given in Table 3 of
|
||||
* http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
|
||||
*/
|
||||
struct AM_PRIMITIVE
|
||||
{
|
||||
AM_PRIMITIVE_ID primitive_id; ///< The primitive type
|
||||
DCODE_PARAMS params; ///< A sequence of parameters used by
|
||||
// the primitive
|
||||
|
||||
/**
|
||||
* Function GetExposure
|
||||
* returns the first parameter in integer form. Some but not all primitives
|
||||
* use the first parameter as an exposure control.
|
||||
*/
|
||||
int GetExposure() const
|
||||
{
|
||||
// No D_CODE* for GetValue()
|
||||
wxASSERT( params.size() && params[0].IsImmediate() );
|
||||
return (int) params[0].GetValue( NULL );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO
|
||||
* helps support the "aperture macro" defined within standard RS274X.
|
||||
*/
|
||||
struct APERTURE_MACRO
|
||||
{
|
||||
wxString name; ///< The name of the aperture macro
|
||||
AM_PRIMITIVES primitives; ///< A sequence of AM_PRIMITIVEs
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Struct APERTURE_MACRO_less_than
|
||||
* is used by std:set<APERTURE_MACRO> instantiation which uses
|
||||
* APERTURE_MACRO.name as its key.
|
||||
*/
|
||||
struct APERTURE_MACRO_less_than
|
||||
{
|
||||
// a "less than" test on two APERTURE_MACROs (.name wxStrings)
|
||||
bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2) const
|
||||
{
|
||||
return am1.name.Cmp( am2.name ) < 0; // case specific wxString compare
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type APERTURE_MACRO_SET
|
||||
* is a sorted collection of APERTURE_MACROS whose key is the name field in
|
||||
* the APERTURE_MACRO.
|
||||
*/
|
||||
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
|
||||
typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;
|
||||
|
||||
|
||||
/**
|
||||
* Class D_CODE
|
||||
* holds a gerber DCODE definition.
|
||||
*/
|
||||
class D_CODE
|
||||
{
|
||||
friend class DCODE_PARAM;
|
||||
|
||||
APERTURE_MACRO* m_Macro; ///< no ownership, points to
|
||||
// GERBER.m_aperture_macros element
|
||||
|
||||
/**
|
||||
* parameters used only when this D_CODE holds a reference to an aperture
|
||||
* macro, and these parameters would customize the macro.
|
||||
*/
|
||||
DCODE_PARAMS m_am_params;
|
||||
|
||||
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) */
|
||||
int m_DrillShape; /* shape of the hole (round = 1, rect = 2) */
|
||||
bool m_InUse; /* FALSE if not used */
|
||||
bool m_Defined; /* FALSE if not defined */
|
||||
wxString m_SpecialDescr;
|
||||
|
||||
public:
|
||||
D_CODE( int num_dcode );
|
||||
~D_CODE();
|
||||
void Clear_D_CODE_Data();
|
||||
|
||||
void AppendParam( double aValue )
|
||||
{
|
||||
DCODE_PARAM param;
|
||||
|
||||
param.SetValue( aValue );
|
||||
|
||||
m_am_params.push_back( param );
|
||||
}
|
||||
|
||||
void SetMacro( APERTURE_MACRO* aMacro )
|
||||
{
|
||||
m_Macro = aMacro;
|
||||
}
|
||||
APERTURE_MACRO* GetMacro() { return m_Macro; }
|
||||
|
||||
/**
|
||||
* Function ShowApertureType
|
||||
* returns a character string telling what type of aperture type \a aType is.
|
||||
* @param aType The aperture type to show.
|
||||
*/
|
||||
static const wxChar* ShowApertureType( APERTURE_T aType );
|
||||
};
|
||||
|
||||
|
||||
inline double DCODE_PARAM::GetValue( const D_CODE* aDcode ) const
|
||||
{
|
||||
if( IsImmediate() )
|
||||
return value;
|
||||
else
|
||||
{
|
||||
// the first one was numbered 1, not zero, as in $1, see page 19 of spec.
|
||||
unsigned ndx = GetIndex() - 1;
|
||||
wxASSERT(aDcode);
|
||||
// get the parameter from the aDcode
|
||||
if( ndx < aDcode->m_am_params.size() )
|
||||
return aDcode->m_am_params[ndx].GetValue( NULL );
|
||||
else
|
||||
{
|
||||
wxASSERT( GetIndex()-1 < aDcode->m_am_params.size() );
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class GERBER
|
||||
* holds the data for one gerber file or layer
|
||||
*/
|
||||
class GERBER
|
||||
{
|
||||
D_CODE* m_Aperture_List[MAX_TOOLS]; ///< Dcode (Aperture) List for this layer
|
||||
D_CODE* m_Aperture_List[TOOLS_MAX_COUNT]; ///< Dcode (Aperture) List for this layer
|
||||
bool m_Exposure; ///< whether an aperture macro tool is flashed on or off
|
||||
|
||||
BOARD* m_Pcb;
|
||||
|
|
|
@ -35,7 +35,7 @@ static PARAM_CFG_WXSTRING DrillExtBufCfg
|
|||
|
||||
static PARAM_CFG_INT UnitCfg // Units; 0 inches, 1 mm
|
||||
(
|
||||
wxT("Unite"),
|
||||
wxT("Units"),
|
||||
(int*)&g_UserUnit,
|
||||
MILLIMETRES
|
||||
);
|
||||
|
|
|
@ -24,6 +24,8 @@ enum gerbview_ids
|
|||
ID_GERBVIEW_DISPLAY_OPTIONS_SETUP,
|
||||
ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
||||
ID_TB_OPTIONS_SHOW_DCODES,
|
||||
ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
|
||||
ID_TB_OPTIONS_SHOW_LINES_SKETCH,
|
||||
|
||||
ID_GERBER_END_LIST
|
||||
};
|
||||
|
|
|
@ -39,7 +39,7 @@ static Ki_HotkeyInfo HkHelp( wxT( "Help: this message" ), HK_HELP, '?' );
|
|||
static Ki_HotkeyInfo HkSwitchUnits( wxT( "Switch Units" ), HK_SWITCH_UNITS, 'U' );
|
||||
static Ki_HotkeyInfo HkTrackDisplayMode( wxT(
|
||||
"Track Display Mode" ),
|
||||
HK_SWITCH_TRACK_DISPLAY_MODE, 'F' );
|
||||
HK_SWITCH_GBR_ITEMS_DISPLAY_MODE, 'F' );
|
||||
|
||||
static Ki_HotkeyInfo HkSwitch2NextCopperLayer( wxT(
|
||||
"Switch to Next Layer" ),
|
||||
|
@ -134,7 +134,7 @@ void WinEDA_GerberFrame::OnHotKey( wxDC* DC, int hotkey,
|
|||
g_UserUnit = (g_UserUnit == INCHES ) ? MILLIMETRES : INCHES;
|
||||
break;
|
||||
|
||||
case HK_SWITCH_TRACK_DISPLAY_MODE:
|
||||
case HK_SWITCH_GBR_ITEMS_DISPLAY_MODE:
|
||||
DisplayOpt.DisplayPcbTrackFill ^= 1; DisplayOpt.DisplayPcbTrackFill &= 1;
|
||||
DrawPanel->Refresh();
|
||||
break;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// for shared hotkeys id
|
||||
enum hotkey_id_commnand {
|
||||
HK_SWITCH_UNITS = HK_COMMON_END,
|
||||
HK_SWITCH_TRACK_DISPLAY_MODE,
|
||||
HK_SWITCH_GBR_ITEMS_DISPLAY_MODE,
|
||||
HK_SWITCH_LAYER_TO_NEXT,
|
||||
HK_SWITCH_LAYER_TO_PREVIOUS
|
||||
};
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#include "confirm.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "protos.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
//#include "protos.h"
|
||||
|
||||
|
||||
bool WinEDA_GerberFrame::Clear_Pcb( bool query )
|
||||
|
@ -24,13 +25,8 @@ bool WinEDA_GerberFrame::Clear_Pcb( bool query )
|
|||
if( !IsOK( this, _( "Current data will be lost?" ) ) )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GetBoard()->m_Drawings.DeleteAll();
|
||||
|
||||
GetBoard()->m_Track.DeleteAll();
|
||||
|
||||
GetBoard()->m_Zone.DeleteAll();
|
||||
|
||||
for( layer = 0; layer < 32; layer++ )
|
||||
{
|
||||
if( g_GERBER_List[layer] )
|
||||
|
@ -60,26 +56,15 @@ void WinEDA_GerberFrame::Erase_Current_Layer( bool query )
|
|||
if( query && !IsOK( this, msg ) )
|
||||
return;
|
||||
|
||||
/* Delete tracks (spots and lines) */
|
||||
TRACK* PtNext;
|
||||
for( TRACK* pt_segm = GetBoard()->m_Track;
|
||||
pt_segm != NULL;
|
||||
pt_segm = (TRACK*) PtNext )
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
BOARD_ITEM * next;
|
||||
for( ; item; item = next )
|
||||
{
|
||||
PtNext = pt_segm->Next();
|
||||
if( pt_segm->GetLayer() != layer )
|
||||
next = item->Next();
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( gerb_item->m_Layer != layer )
|
||||
continue;
|
||||
pt_segm->DeleteStructure();
|
||||
}
|
||||
|
||||
/* Delete polygons */
|
||||
SEGZONE* Nextzone;
|
||||
for( SEGZONE* zone = GetBoard()->m_Zone; zone != NULL; zone = Nextzone )
|
||||
{
|
||||
Nextzone = zone->Next();
|
||||
if( zone->GetLayer() != layer )
|
||||
continue;
|
||||
zone->DeleteStructure();
|
||||
gerb_item->DeleteStructure();
|
||||
}
|
||||
|
||||
ScreenPcb->SetModify();
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/****************/
|
||||
/* lay2plot.cpp */
|
||||
/****************/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
|
||||
#include "gerbview.h"
|
||||
#include "protos.h"
|
||||
|
||||
|
||||
/* Routine to plot the pcb, by selected layers. */
|
||||
void Print_PcbItems(BOARD * Pcb, wxDC *DC, int drawmode, int printmasklayer)
|
||||
{
|
||||
DISPLAY_OPTIONS save_opt;
|
||||
TRACK * pt_piste;
|
||||
|
||||
save_opt = DisplayOpt;
|
||||
DisplayOpt.DisplayPadFill = FILLED;
|
||||
DisplayOpt.DisplayViaFill = FILLED;
|
||||
DisplayOpt.DisplayPadNum = 0;
|
||||
DisplayOpt.DisplayPadIsol = 0;
|
||||
DisplayOpt.DisplayPcbTrackFill = FILLED;
|
||||
DisplayOpt.ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
|
||||
DisplayOpt.DisplayDrawItems = FILLED;
|
||||
DisplayOpt.DisplayZonesMode = 0;
|
||||
|
||||
pt_piste = Pcb->m_Track;
|
||||
for( ; pt_piste != NULL ; pt_piste = pt_piste->Next() )
|
||||
{
|
||||
// if( (printmasklayer & ReturnMaskLayer(pt_piste) ) == 0 ) continue;
|
||||
Trace_Segment(Pcb, NULL, DC, pt_piste, drawmode);
|
||||
}
|
||||
|
||||
DisplayOpt = save_opt;
|
||||
}
|
|
@ -12,454 +12,12 @@
|
|||
#include "protos.h"
|
||||
|
||||
|
||||
int ux0, uy0, dx, dy, spot_cX, spot_cY;
|
||||
|
||||
|
||||
static TRACK* Locate_Zone( TRACK* start_adresse, int layer, int typeloc );
|
||||
static TRACK* Locate_Zone( TRACK* start_adresse, wxPoint ref, int layer );
|
||||
static TRACK* Locate_Pistes( TRACK* start_adresse,
|
||||
int Layer,
|
||||
int typeloc );
|
||||
static TRACK* Locate_Pistes( TRACK* start_adresse,
|
||||
wxPoint ref,
|
||||
int Layer );
|
||||
static DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int typeloc );
|
||||
static TEXTE_PCB* Locate_Texte_Pcb( TEXTE_PCB* pt_txt_pcb, int typeloc );
|
||||
static int distance( int seuil );
|
||||
|
||||
|
||||
/* Macro for calculating the coordinates of the cursor position.
|
||||
*/
|
||||
#define SET_REF_POS( ref ) if( typeloc == CURSEUR_ON_GRILLE ) \
|
||||
{ ref = ActiveScreen->m_Curseur; } \
|
||||
else { ref = ActiveScreen->m_MousePosition; }
|
||||
|
||||
|
||||
/* Display the character of the localized STRUCTURE and return a pointer
|
||||
* to it.
|
||||
*/
|
||||
BOARD_ITEM* WinEDA_GerberFrame::Locate( int typeloc )
|
||||
{
|
||||
TEXTE_PCB* pt_texte_pcb;
|
||||
TRACK* Track, * TrackLocate;
|
||||
DRAWSEGMENT* DrawSegm;
|
||||
int layer;
|
||||
|
||||
/* Locate tracks and vias, with priority to vias */
|
||||
layer = GetScreen()->m_Active_Layer;
|
||||
Track = Locate_Pistes( GetBoard()->m_Track, -1, typeloc );
|
||||
if( Track != NULL )
|
||||
{
|
||||
TrackLocate = Track;
|
||||
|
||||
while( ( TrackLocate = Locate_Pistes( TrackLocate,
|
||||
layer, typeloc ) ) != NULL )
|
||||
{
|
||||
Track = TrackLocate;
|
||||
if( TrackLocate->Type() == TYPE_VIA )
|
||||
break;
|
||||
TrackLocate = TrackLocate->Next();
|
||||
}
|
||||
|
||||
Track->DisplayInfo( this );
|
||||
return Track;
|
||||
}
|
||||
|
||||
|
||||
pt_texte_pcb = Locate_Texte_Pcb(
|
||||
(TEXTE_PCB*) GetBoard()->m_Drawings.GetFirst(), typeloc );
|
||||
|
||||
if( pt_texte_pcb )
|
||||
{
|
||||
pt_texte_pcb->DisplayInfo( this );
|
||||
return pt_texte_pcb;
|
||||
}
|
||||
|
||||
if( ( DrawSegm = Locate_Segment_Pcb( GetBoard(), typeloc ) ) != NULL )
|
||||
{
|
||||
return DrawSegm;
|
||||
}
|
||||
|
||||
if( ( TrackLocate = Locate_Zone( GetBoard()->m_Zone,
|
||||
GetScreen()->m_Active_Layer,
|
||||
typeloc ) ) != NULL )
|
||||
{
|
||||
TrackLocate->DisplayInfo( this );
|
||||
return TrackLocate;
|
||||
}
|
||||
|
||||
MsgPanel->EraseMsgBox();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Locate of segments of pcb edge or draw as active layer.
|
||||
* Returns:
|
||||
* Pointer to START segment if found
|
||||
* NULL if nothing found
|
||||
*/
|
||||
DRAWSEGMENT* Locate_Segment_Pcb( BOARD* Pcb, int typeloc )
|
||||
{
|
||||
BOARD_ITEM* PtStruct;
|
||||
DRAWSEGMENT* pts;
|
||||
wxPoint ref;
|
||||
PCB_SCREEN* screen = (PCB_SCREEN*) ActiveScreen;
|
||||
|
||||
SET_REF_POS( ref );
|
||||
|
||||
PtStruct = Pcb->m_Drawings;
|
||||
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
|
||||
{
|
||||
if( PtStruct->Type() != TYPE_DRAWSEGMENT )
|
||||
continue;
|
||||
pts = (DRAWSEGMENT*) PtStruct;
|
||||
ux0 = pts->m_Start.x;
|
||||
uy0 = pts->m_Start.y;
|
||||
|
||||
dx = pts->m_End.x - ux0;
|
||||
dy = pts->m_End.y - uy0;
|
||||
spot_cX = ref.x - ux0;
|
||||
spot_cY = ref.y - uy0;
|
||||
|
||||
if( pts->GetLayer() != screen->m_Active_Layer )
|
||||
continue;
|
||||
|
||||
if( ( pts->m_Shape == S_CIRCLE ) || ( pts->m_Shape == S_ARC ) )
|
||||
{
|
||||
int rayon, dist, StAngle, EndAngle, MouseAngle;
|
||||
rayon = (int) hypot( (double) (dx), (double) (dy) );
|
||||
dist = (int) hypot( (double) (spot_cX), (double) (spot_cY) );
|
||||
if( abs( rayon - dist ) <= ( pts->m_Width / 2 ) )
|
||||
{
|
||||
if( pts->m_Shape == S_CIRCLE )
|
||||
return pts;
|
||||
|
||||
MouseAngle = (int) ArcTangente( spot_cY, spot_cX );
|
||||
StAngle = (int) ArcTangente( dy, dx );
|
||||
EndAngle = StAngle + pts->m_Angle;
|
||||
|
||||
if( EndAngle > 3600 )
|
||||
{
|
||||
StAngle -= 3600; EndAngle -= 3600;
|
||||
}
|
||||
if( ( MouseAngle >= StAngle ) && ( MouseAngle <= EndAngle ) )
|
||||
return pts;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( distance( pts->m_Width / 2 ) )
|
||||
return pts;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 1 - Locate segment of track at current cursor position.
|
||||
* 2 - Locate segment of track point by point.
|
||||
* Ref_pX, ref_pY.r
|
||||
*
|
||||
* The search begins to address start_adresse
|
||||
*/
|
||||
TRACK* Locate_Pistes( TRACK* start_adresse, int Layer, int typeloc )
|
||||
{
|
||||
wxPoint ref;
|
||||
|
||||
SET_REF_POS( ref );
|
||||
|
||||
return Locate_Pistes( start_adresse, ref, Layer );
|
||||
}
|
||||
|
||||
|
||||
TRACK* Locate_Pistes( TRACK* start_adresse, wxPoint ref, int Layer )
|
||||
{
|
||||
TRACK* Track;
|
||||
int l_piste; /* half-width of the track */
|
||||
|
||||
for( Track = start_adresse; Track != NULL; Track = Track->Next() )
|
||||
{
|
||||
if( Track->GetState( BUSY | DELETED ) )
|
||||
continue;
|
||||
/* Calculate coordinates of the test segment. */
|
||||
l_piste = Track->m_Width >> 1;
|
||||
ux0 = Track->m_Start.x;
|
||||
uy0 = Track->m_Start.y;
|
||||
dx = Track->m_End.x;
|
||||
dy = Track->m_End.y;
|
||||
|
||||
dx -= ux0;
|
||||
dy -= uy0;
|
||||
spot_cX = ref.x - ux0;
|
||||
spot_cY = ref.y - uy0;
|
||||
|
||||
if( Track->Type() == TYPE_VIA )
|
||||
{
|
||||
if( ( abs( spot_cX ) <= l_piste ) && ( abs( spot_cY ) <=l_piste ) )
|
||||
{
|
||||
return Track;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( Layer >= 0 )
|
||||
if( Track->GetLayer() != Layer )
|
||||
continue;
|
||||
if( distance( l_piste ) )
|
||||
return Track;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate zone area at the cursor position.
|
||||
*
|
||||
* The search begins to address start_adresse
|
||||
*/
|
||||
TRACK* Locate_Zone( TRACK* start_adresse, int layer, int typeloc )
|
||||
{
|
||||
wxPoint ref;
|
||||
|
||||
SET_REF_POS( ref );
|
||||
|
||||
return Locate_Zone( start_adresse, ref, layer );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate zone area at point.
|
||||
*
|
||||
* The search begins to address start_adresse
|
||||
*/
|
||||
TRACK* Locate_Zone( TRACK* start_adresse, wxPoint ref, int layer )
|
||||
{
|
||||
TRACK* Zone;
|
||||
int l_segm;
|
||||
|
||||
for( Zone = start_adresse; Zone != NULL; Zone = Zone->Next() )
|
||||
{
|
||||
l_segm = Zone->m_Width >> 1;
|
||||
ux0 = Zone->m_Start.x;
|
||||
uy0 = Zone->m_Start.y;
|
||||
dx = Zone->m_End.x;
|
||||
dy = Zone->m_End.y;
|
||||
|
||||
dx -= ux0;
|
||||
dy -= uy0;
|
||||
spot_cX = ref.x - ux0;
|
||||
spot_cY = ref.y - uy0;
|
||||
|
||||
if( ( layer != -1 ) && ( Zone->GetLayer() != layer ) )
|
||||
continue;
|
||||
if( distance( l_segm ) )
|
||||
return Zone;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Location of text on the PCB:
|
||||
* INPUT: char pointer to the beginning of the search area
|
||||
* Return: pointer to the text description located.
|
||||
*/
|
||||
TEXTE_PCB* Locate_Texte_Pcb( TEXTE_PCB* pt_txt_pcb, int typeloc )
|
||||
{
|
||||
int angle;
|
||||
EDA_BaseStruct* PtStruct;
|
||||
wxPoint ref;
|
||||
|
||||
SET_REF_POS( ref );
|
||||
PtStruct = (EDA_BaseStruct*) pt_txt_pcb;
|
||||
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
|
||||
{
|
||||
if( PtStruct->Type() != TYPE_TEXTE )
|
||||
continue;
|
||||
pt_txt_pcb = (TEXTE_PCB*) PtStruct;
|
||||
|
||||
angle = pt_txt_pcb->m_Orient;
|
||||
ux0 = pt_txt_pcb->m_Pos.x;
|
||||
uy0 = pt_txt_pcb->m_Pos.y;
|
||||
dx = ( pt_txt_pcb->m_Size.x * pt_txt_pcb->GetLength() ) / 2;
|
||||
dy = pt_txt_pcb->m_Size.y / 2;
|
||||
|
||||
dx *= 13;
|
||||
dx /= 9; /* Character for factor 13/9. */
|
||||
|
||||
/* Cursor in the rectangle around the center. */
|
||||
spot_cX = ref.x - ux0;
|
||||
spot_cY = ref.y - uy0;
|
||||
RotatePoint( &spot_cX, &spot_cY, -angle );
|
||||
if( ( abs( spot_cX ) <= abs( dx ) ) && ( abs( spot_cY ) <= abs( dy ) ) )
|
||||
return pt_txt_pcb;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Calculate the distance from the cursor to a line segment:
|
||||
* (Track, edge, contour module ..
|
||||
* Returns:
|
||||
* 0 if distance > threshold
|
||||
* 1 if distance <= threshold
|
||||
* Variables used (must be initialized before use, and
|
||||
* are brought to the mark center on the origin of the segment)
|
||||
* dx, dy = coord of extremity segment.
|
||||
* spot_cX, spot_cY = coord of mouse cursor
|
||||
* Search 4 cases:
|
||||
* Horizontal segment
|
||||
* Vertical segment
|
||||
* Segment 45
|
||||
* Any segment
|
||||
*/
|
||||
int distance( int seuil )
|
||||
{
|
||||
int cXrot, cYrot, segX, segY;
|
||||
int pointX, pointY;
|
||||
|
||||
segX = dx;
|
||||
segY = dy;
|
||||
pointX = spot_cX;
|
||||
pointY = spot_cY;
|
||||
|
||||
/* Reroute coordinate for the segment in 1st quadrant (coord> = 0). */
|
||||
if( segX < 0 ) /* Set > 0 if symmetrical about the axis Y. */
|
||||
{
|
||||
segX = -segX;
|
||||
pointX = -pointX;
|
||||
}
|
||||
if( segY < 0 ) /* Set > 0 if symmetrical about the axis X. */
|
||||
{
|
||||
segY = -segY;
|
||||
pointY = -pointY;
|
||||
}
|
||||
|
||||
|
||||
if( segY == 0 ) /* Horizontal track. */
|
||||
{
|
||||
if( abs( pointY ) <= seuil )
|
||||
{
|
||||
if( ( pointX >= 0 ) && ( pointX <= segX ) )
|
||||
return 1;
|
||||
|
||||
if( ( pointX < 0 ) && ( pointX >= -seuil ) )
|
||||
{
|
||||
if( ( ( pointX * pointX ) + ( pointY * pointY ) ) <=
|
||||
( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
if( ( pointX > segX ) && ( pointX <= ( segX + seuil ) ) )
|
||||
{
|
||||
if( ( ( ( pointX - segX ) * ( pointX - segX ) ) +
|
||||
( pointY * pointY ) ) <= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( segX == 0 ) /* Vertical track. */
|
||||
{
|
||||
if( abs( pointX ) <= seuil )
|
||||
{
|
||||
if( ( pointY >= 0 ) && ( pointY <= segY ) )
|
||||
return 1;
|
||||
if( ( pointY < 0 ) && ( pointY >= -seuil ) )
|
||||
{
|
||||
if( ( (pointY * pointY ) + ( pointX * pointX ) ) <=
|
||||
( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
if( ( pointY > segY ) && ( pointY <= ( segY + seuil ) ) )
|
||||
{
|
||||
if( ( ( ( pointY - segY ) * ( pointY - segY ) ) +
|
||||
( pointX * pointX ) ) <= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( segX == segY ) /* 45 degree track. */
|
||||
{
|
||||
/* You spin axes of 45 degrees. mouse was then
|
||||
* coord: x1 = x * y * cos45 + sin45
|
||||
* y1 = y * cos45 - sin45 x *
|
||||
* And the segment of track is horizontal.
|
||||
* coord recalculation of the mouse (sin45 = cos45 = .707 = 7 / 10
|
||||
* Note: sin or cos45 = .707, and when recalculating coord
|
||||
* dX45 and dy45, lect coeff .707 is neglected, dx and dy are both
|
||||
* actually .707
|
||||
* too big. (security hole too small)
|
||||
* spot_cX *, Y * must be by .707 * .707 = 0.5
|
||||
*/
|
||||
|
||||
cXrot = (pointX + pointY) >> 1;
|
||||
cYrot = (pointY - pointX) >> 1;
|
||||
|
||||
/* Recalculate coordinates of extremity segment, which will be vertical
|
||||
* following the orientation of axes on the screen: DX45 = pointx
|
||||
* (or pointy) and 1.414 is actually greater, and dy45 = 0
|
||||
*
|
||||
* Threshold should be .707 to reflect the difference in coeff dx, dy
|
||||
*/
|
||||
seuil *= 7; seuil /= 10;
|
||||
if( abs( cYrot ) <= seuil )
|
||||
{
|
||||
if( ( cXrot >= 0 ) && ( cXrot <= segX ) )
|
||||
return 1;
|
||||
|
||||
if( ( cXrot < 0 ) && ( cXrot >= -seuil ) )
|
||||
{
|
||||
if( ( ( cXrot * cXrot ) + ( cYrot * cYrot ) )
|
||||
<= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
if( ( cXrot > segX ) && ( cXrot <= ( segX + seuil ) ) )
|
||||
{
|
||||
if( ( ( ( cXrot - segX ) * ( cXrot - segX ) ) +
|
||||
( cYrot * cYrot ) ) <= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* Any orientation. */
|
||||
{
|
||||
/* There is a change of axis (rotation), so that the segment
|
||||
* track is horizontal in the new reference, */
|
||||
int angle;
|
||||
|
||||
angle = (int) ( atan2( (double) segY, (double) segX ) * 1800 / M_PI);
|
||||
cXrot = pointX;
|
||||
cYrot = pointY;
|
||||
RotatePoint( &cXrot, &cYrot, angle ); /* Rotate test point. */
|
||||
RotatePoint( &segX, &segY, angle ); /* Rotate segment. */
|
||||
|
||||
/* The track is horizontal, following the changes to coordinate
|
||||
* axis and, therefore segX = length of segment
|
||||
*/
|
||||
|
||||
if( abs( cYrot ) <= seuil )
|
||||
{
|
||||
if( ( cXrot >= 0 ) && ( cXrot <= segX ) )
|
||||
return 1;
|
||||
|
||||
if( ( cXrot < 0 ) && ( cXrot >= -seuil ) )
|
||||
{
|
||||
if( ( ( cXrot * cXrot ) + ( cYrot * cYrot ) )
|
||||
<= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
if( ( cXrot > segX ) && ( cXrot <= ( segX + seuil ) ) )
|
||||
{
|
||||
if( ( ( ( cXrot - segX ) * ( cXrot - segX ) ) +
|
||||
( cYrot * cYrot ) ) <= ( seuil * seuil ) )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -47,17 +47,11 @@ bool WinEDA_GerberFrame::OnRightClick( const wxPoint& MousePos,
|
|||
{
|
||||
if( BlockActive )
|
||||
{
|
||||
PopMenu->Append( ID_POPUP_CANCEL_CURRENT_COMMAND,
|
||||
_( "Cancel Block" ) );
|
||||
PopMenu->Append( ID_POPUP_ZOOM_BLOCK,
|
||||
_( "Zoom Block (drag middle mouse)" ) );
|
||||
PopMenu->Append( ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ) );
|
||||
PopMenu->AppendSeparator();
|
||||
PopMenu->Append( ID_POPUP_PLACE_BLOCK, _( "Place Block" ) );
|
||||
PopMenu->Append( ID_POPUP_COPY_BLOCK,
|
||||
_( "Copy Block (shift mouse)" ) );
|
||||
PopMenu->Append( ID_POPUP_DELETE_BLOCK,
|
||||
_( "Delete Block (ctrl + drag mouse)" ) );
|
||||
PopMenu->Append( ID_POPUP_MIRROR_X_BLOCK, _( "Mirror Block" ) );
|
||||
}
|
||||
else
|
||||
PopMenu->Append( ID_POPUP_CANCEL_CURRENT_COMMAND,
|
||||
|
@ -77,19 +71,6 @@ bool WinEDA_GerberFrame::OnRightClick( const wxPoint& MousePos,
|
|||
|
||||
GetScreen()->SetCurItem( DrawStruct );
|
||||
|
||||
switch( DrawStruct->Type() )
|
||||
{
|
||||
case TYPE_TRACK:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
msg.Printf( wxT( "WinEDA_GerberFrame::OnRightClick Error: illegal or unknown DrawType %d" ),
|
||||
DrawStruct->Type() );
|
||||
DisplayError( this, msg );
|
||||
break;
|
||||
}
|
||||
|
||||
PopMenu->AppendSeparator();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ void WinEDA_GerberFrame::OnSelectOptionToolbar( wxCommandEvent& event )
|
|||
DrawPanel->Refresh( TRUE );
|
||||
break;
|
||||
|
||||
case ID_TB_OPTIONS_SHOW_PADS_SKETCH:
|
||||
case ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH:
|
||||
if( state )
|
||||
{
|
||||
DisplayOpt.DisplayPadFill = m_DisplayPadFill = false;
|
||||
|
@ -78,19 +78,7 @@ void WinEDA_GerberFrame::OnSelectOptionToolbar( wxCommandEvent& event )
|
|||
DrawPanel->Refresh( TRUE );
|
||||
break;
|
||||
|
||||
case ID_TB_OPTIONS_SHOW_VIAS_SKETCH:
|
||||
if( state )
|
||||
{
|
||||
DisplayOpt.DisplayViaFill = m_DisplayViaFill = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayOpt.DisplayViaFill = m_DisplayViaFill = true;
|
||||
}
|
||||
DrawPanel->Refresh( TRUE );
|
||||
break;
|
||||
|
||||
case ID_TB_OPTIONS_SHOW_TRACKS_SKETCH:
|
||||
case ID_TB_OPTIONS_SHOW_LINES_SKETCH:
|
||||
if(state )
|
||||
{
|
||||
m_DisplayPcbTrackFill = FALSE;
|
||||
|
|
|
@ -1,15 +1,4 @@
|
|||
/* declarations prototype */
|
||||
|
||||
int* InstallDialogLayerPairChoice( WinEDA_GerberFrame* parent );
|
||||
|
||||
bool Read_Config();
|
||||
|
||||
void Print_PcbItems( BOARD* Pcb, wxDC* DC, int drawmode, int printmasklayer );
|
||||
|
||||
void DisplayColorSetupFrame( WinEDA_GerberFrame* parent, const wxPoint& framepos );
|
||||
void Trace_Segment( BOARD* aBrd, WinEDA_DrawPanel* panel,
|
||||
wxDC* DC,
|
||||
TRACK* pt_piste,
|
||||
int draw_mode );
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
*
|
||||
* Tools and D_CODES
|
||||
* Tool number (identification of shapes)
|
||||
* 1 to 99 (Classical)
|
||||
* 1 to 999
|
||||
* D_CODES:
|
||||
*
|
||||
|
@ -60,8 +59,7 @@
|
|||
* D09 = VAPE Flash
|
||||
* D51 = G54 preceded by -> Select VAPE
|
||||
*
|
||||
* D10 ... D255 = Identification Tool (Opening)
|
||||
* Not in order (see table in PCBPLOT.H)
|
||||
* D10 ... D999 = Identification Tool (shapes id)
|
||||
*/
|
||||
|
||||
|
||||
|
@ -83,14 +81,6 @@
|
|||
* -1 = File not found
|
||||
* -2 = Error reading file
|
||||
* Rank D_code max lu (nbr of dCode)
|
||||
*
|
||||
* Internal Representation:
|
||||
*
|
||||
* Lines are represented as standard TRACKS
|
||||
* The flash is represented as DRAWSEGMENTS
|
||||
* - Round or oval: DRAWSEGMENTS
|
||||
* - Rectangles DRAWSEGMENTS
|
||||
* Reference to the D-CODE is set in the member Getnet()
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "polygons_defs.h"
|
||||
#include "common.h"
|
||||
#include "confirm.h"
|
||||
#include "macros.h"
|
||||
|
@ -11,6 +12,7 @@
|
|||
#include "pcbplot.h"
|
||||
#include "trigo.h"
|
||||
#include "protos.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
@ -79,18 +81,18 @@ static wxPoint LastPosition;
|
|||
|
||||
|
||||
/* Local Functions (are lower case since they are private to this source file)
|
||||
**/
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Function fillCircularTRACK
|
||||
* initializes a given TRACK so that it can draw a circle which is not filled
|
||||
* Function fillCircularGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw a circle which is not filled
|
||||
* and
|
||||
* has a given pen width (\a aPenWidth ).
|
||||
*
|
||||
* @param aTrack The TRACK to fill in.
|
||||
* @param aGbrItem The GBRITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the TRACK
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aPenWidth The width of the pen used to draw the circle's
|
||||
|
@ -99,7 +101,7 @@ static wxPoint LastPosition;
|
|||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
static void fillCircularTRACK( TRACK* aTrack,
|
||||
static void fillCircularGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
|
@ -107,79 +109,80 @@ static void fillCircularTRACK( TRACK* aTrack,
|
|||
int aPenWidth,
|
||||
bool isDark )
|
||||
{
|
||||
aTrack->m_Shape = S_CIRCLE;
|
||||
aTrack->m_Width = aPenWidth;
|
||||
aGbrItem->m_Shape = GBR_CIRCLE;
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aPenWidth;
|
||||
|
||||
aTrack->SetLayer( aLayer );
|
||||
aTrack->SetNet( Dcode_index );
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
|
||||
// When drawing a TRACK with shape S_CIRCLE, the hypotenuse (i.e. distance)
|
||||
// When drawing a GBRITEM with shape GBR_CIRCLE, the hypotenuse (i.e. distance)
|
||||
// between the Start and End points gives the radius of the circle.
|
||||
aTrack->m_Start = aTrack->m_End = aPos;
|
||||
aTrack->m_End.x += max( 0, (aDiameter + 1) / 2 );
|
||||
aGbrItem->m_Start = aGbrItem->m_End = aPos;
|
||||
aGbrItem->m_End.x += max( 0, (aDiameter + 1) / 2 );
|
||||
|
||||
NEGATE( aTrack->m_Start.y );
|
||||
NEGATE( aTrack->m_End.y );
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
NEGATE( aGbrItem->m_End.y );
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aTrack->m_Flags |= DRAW_ERASED;
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function fillRoundFlashTRACK
|
||||
* initializes a given TRACK so that it can draw a circle which is filled and
|
||||
* Function fillRoundFlashGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw a circle which is filled and
|
||||
* has no pen border.
|
||||
*
|
||||
* @param aTrack The TRACK to fill in.
|
||||
* @param aGbrItem The GBRITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the TRACK
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @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.
|
||||
*/
|
||||
static void fillRoundFlashTRACK( TRACK* aTrack,
|
||||
static void fillRoundFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
int aDiameter,
|
||||
bool isDark )
|
||||
{
|
||||
aTrack->SetLayer( aLayer );
|
||||
aTrack->m_Width = aDiameter;
|
||||
aTrack->m_Start = aTrack->m_End = aPos;
|
||||
NEGATE( aTrack->m_Start.y );
|
||||
NEGATE( aTrack->m_End.y );
|
||||
aTrack->SetNet( Dcode_index );
|
||||
aTrack->m_Shape = S_SPOT_CIRCLE;
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aDiameter;
|
||||
aGbrItem->m_Start = aPos;
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
aGbrItem->m_End = aGbrItem->m_Start;
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_Shape = GBR_SPOT_CIRCLE;
|
||||
aGbrItem->m_Flashed = true;
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aTrack->m_Flags |= DRAW_ERASED;
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function fillOvalOrRectFlashTRACK
|
||||
* initializes a given TRACK so that it can draw an oval or rectangular
|
||||
* Function fillOvalOrRectFlashGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw an oval or rectangular
|
||||
* filled rectangle.
|
||||
*
|
||||
* @param aTrack The TRACK to fill in.
|
||||
* @param aGbrItem The GERBER_DRAW_ITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the TRACK
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the rectangle
|
||||
* @param aSize The size of the flash
|
||||
* @param aShape What type of flash, S_SPOT_OVALE or S_SPOT_RECT
|
||||
* @param aShape What type of flash, GBR_SPOT_OVALE or GBR_SPOT_RECT
|
||||
* @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.
|
||||
*/
|
||||
static void fillOvalOrRectFlashTRACK( TRACK* aTrack,
|
||||
static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aPos,
|
||||
|
@ -187,54 +190,39 @@ static void fillOvalOrRectFlashTRACK( TRACK* aTrack,
|
|||
int aShape,
|
||||
bool isDark )
|
||||
{
|
||||
int width = MIN( aSize.x, aSize.y );
|
||||
int len = MAX( aSize.x, aSize.y ) - width;
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Flashed = true;
|
||||
|
||||
aTrack->SetLayer( aLayer );
|
||||
aGbrItem->m_Size = aSize;
|
||||
|
||||
aTrack->m_Width = width;
|
||||
aGbrItem->m_Start = aPos;
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
aGbrItem->m_End = aGbrItem->m_Start;
|
||||
|
||||
aTrack->m_Start = aTrack->m_End = aPos;
|
||||
NEGATE( aTrack->m_Start.y );
|
||||
NEGATE( aTrack->m_End.y );
|
||||
|
||||
aTrack->SetNet( Dcode_index );
|
||||
|
||||
aTrack->m_Shape = aShape;
|
||||
|
||||
len >>= 1;
|
||||
if( aSize.x > aSize.y ) // oval or rectangle is horizontal
|
||||
{
|
||||
aTrack->m_Start.x -= len;
|
||||
aTrack->m_End.x += len;
|
||||
}
|
||||
else // oval or rectangle is vertical
|
||||
{
|
||||
aTrack->m_Start.y -= len;
|
||||
aTrack->m_End.y += len;
|
||||
}
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_Shape = aShape;
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aTrack->m_Flags |= DRAW_ERASED;
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function fillLineTRACK
|
||||
* initializes a given TRACK so that it can draw a linear D code.
|
||||
* Function fillLineGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw a linear D code.
|
||||
*
|
||||
* @param aTrack The TRACK to fill in.
|
||||
* @param aGbrItem The GERBER_DRAW_ITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the TRACK
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @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.
|
||||
*/
|
||||
static void fillLineTRACK( TRACK* aTrack,
|
||||
static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aStart,
|
||||
|
@ -242,28 +230,29 @@ static void fillLineTRACK( TRACK* aTrack,
|
|||
int aWidth,
|
||||
bool isDark )
|
||||
{
|
||||
aTrack->SetLayer( aLayer );
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
||||
aTrack->m_Width = aWidth;
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
|
||||
aTrack->m_Start = aStart;
|
||||
NEGATE( aTrack->m_Start.y );
|
||||
aGbrItem->m_Start = aStart;
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
|
||||
aTrack->m_End = aEnd;
|
||||
NEGATE( aTrack->m_End.y );
|
||||
aGbrItem->m_End = aEnd;
|
||||
NEGATE( aGbrItem->m_End.y );
|
||||
|
||||
aTrack->SetNet( Dcode_index );
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aTrack->m_Flags |= DRAW_ERASED;
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function fillArcTRACK
|
||||
* initializes a given TRACK so that it can draw an arc G code.
|
||||
* Function fillArcGBRITEM
|
||||
* initializes a given GBRITEM so that it can draw an arc G code.
|
||||
* <p>
|
||||
* if multiquadrant == true : arc can be 0 to 360 degrees
|
||||
* and \a rel_center is the center coordinate relative to start point.
|
||||
|
@ -276,9 +265,9 @@ static void fillLineTRACK( TRACK* aTrack,
|
|||
* <li> absolute angle 180 to 270 (quadrant 3) or
|
||||
* <li> absolute angle 270 to 0 (quadrant 4)
|
||||
* </ul><p>
|
||||
* @param aTrack is the TRACK to fill in.
|
||||
* @param GERBER_DRAW_ITEM is the GBRITEM to fill in.
|
||||
* @param Dcode_index is the DCODE value, like D14
|
||||
* @param aLayer is the layer index to set into the TRACK
|
||||
* @param aLayer is the layer index to set into the GBRITEM
|
||||
* @param aStart is the starting point
|
||||
* @param aEnd is the ending point
|
||||
* @param rel_center is the center coordinate relative to start point,
|
||||
|
@ -291,16 +280,17 @@ static void fillLineTRACK( TRACK* aTrack,
|
|||
* color other than the background color, else use the background color
|
||||
* when drawing so that an erasure happens.
|
||||
*/
|
||||
static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
||||
static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
|
||||
const wxPoint& aStart, const wxPoint& aEnd,
|
||||
const wxPoint& rel_center, int aWidth,
|
||||
bool clockwise, bool multiquadrant, bool isDark )
|
||||
{
|
||||
wxPoint center, delta;
|
||||
|
||||
aTrack->m_Shape = S_ARC;
|
||||
aTrack->SetLayer( aLayer );
|
||||
aTrack->m_Width = aWidth;
|
||||
aGbrItem->m_Shape = GBR_ARC;
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
||||
if( multiquadrant )
|
||||
{
|
||||
|
@ -309,20 +299,19 @@ static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
|||
|
||||
if( clockwise )
|
||||
{
|
||||
aTrack->m_Start = aStart;
|
||||
aTrack->m_End = aEnd;
|
||||
aGbrItem->m_Start = aStart;
|
||||
aGbrItem->m_End = aEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
aTrack->m_Start = aEnd;
|
||||
aTrack->m_End = aStart;
|
||||
aGbrItem->m_Start = aEnd;
|
||||
aGbrItem->m_End = aStart;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
center = rel_center;
|
||||
delta.x = aEnd.x - aStart.x;
|
||||
delta.y = aEnd.y - aStart.y;
|
||||
delta = aEnd - aStart;
|
||||
|
||||
if( (delta.x >= 0) && (delta.y >= 0) )
|
||||
{
|
||||
|
@ -350,28 +339,26 @@ static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
|||
|
||||
if( clockwise )
|
||||
{
|
||||
aTrack->m_Start = aStart;
|
||||
aTrack->m_End = aEnd;
|
||||
aGbrItem->m_Start = aStart;
|
||||
aGbrItem->m_End = aEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
aTrack->m_Start = aEnd;
|
||||
aTrack->m_End = aStart;
|
||||
aGbrItem->m_Start = aEnd;
|
||||
aGbrItem->m_End = aStart;
|
||||
}
|
||||
}
|
||||
|
||||
aTrack->SetNet( Dcode_index );
|
||||
aTrack->m_Param = center.x;
|
||||
aTrack->SetSubNet( center.y );
|
||||
aGbrItem->m_DCode = Dcode_index;
|
||||
aGbrItem->m_ArcCentre = center;
|
||||
|
||||
NEGATE( aTrack->m_Start.y );
|
||||
NEGATE( aTrack->m_End.y );
|
||||
|
||||
aTrack->SetSubNet( -aTrack->GetSubNet() );
|
||||
NEGATE( aGbrItem->m_Start.y );
|
||||
NEGATE( aGbrItem->m_End.y );
|
||||
NEGATE( aGbrItem->m_ArcCentre.y );
|
||||
|
||||
if( !isDark )
|
||||
{
|
||||
aTrack->m_Flags |= DRAW_ERASED;
|
||||
aGbrItem->m_Flags |= DRAW_ERASED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,7 +379,7 @@ static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
|||
* <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 aLayer is the layer index to set into the GBRITEM
|
||||
* @param aStart is the starting point
|
||||
* @param aEnd is the ending point
|
||||
* @param rel_center is the center coordinate relative to start point,
|
||||
|
@ -404,44 +391,38 @@ static void fillArcTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
|
|||
* @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,
|
||||
static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGrbrItem,
|
||||
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
|
||||
/* in order to calculate arc parameters, we use fillArcGBRITEM
|
||||
* so we muse create a dummy track and use its geometric parameters
|
||||
*/
|
||||
static TRACK dummyTrack(NULL);
|
||||
SEGZONE * firstSegment = NULL;
|
||||
static GERBER_DRAW_ITEM dummyGbrItem( NULL );
|
||||
|
||||
fillArcTRACK( &dummyTrack, 0, aLayer,
|
||||
aStart, aEnd,
|
||||
rel_center, 0,
|
||||
fillArcGBRITEM( &dummyGbrItem, 0, 0,
|
||||
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;
|
||||
const int increment_angle = 360 / 36;
|
||||
|
||||
wxPoint center;
|
||||
center.x = dummyTrack.m_Param;
|
||||
center.y = dummyTrack.GetSubNet();
|
||||
center = dummyGbrItem.m_ArcCentre;
|
||||
|
||||
// Calculate relative coordinates;
|
||||
wxPoint start = dummyTrack.m_Start - center;
|
||||
wxPoint end = dummyTrack.m_End - center;
|
||||
wxPoint start = dummyGbrItem.m_Start - center;
|
||||
wxPoint end = dummyGbrItem.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 );
|
||||
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 );
|
||||
double end_angle = atan2( (double) end.y, (double) end.x );
|
||||
end_angle = 180 * end_angle / M_PI;
|
||||
double angle = start_angle - end_angle;
|
||||
|
||||
|
@ -449,19 +430,21 @@ static SEGZONE * fillArcPOLY( BOARD * aPcb, int aLayer,
|
|||
// start.x, start.y, start_angle, end.x, end.y, end_angle, angle ) );
|
||||
if( !clockwise )
|
||||
{
|
||||
EXCHG(start, end);
|
||||
D( printf( " >>>> reverse arc\n") );
|
||||
EXCHG( start, end );
|
||||
D( printf( " >>>> reverse arc\n" ) );
|
||||
}
|
||||
|
||||
// Normalize angle
|
||||
while ( angle > 360.0 )
|
||||
while( angle > 360.0 )
|
||||
angle -= 360.0;
|
||||
while ( angle < 0.0 )
|
||||
|
||||
while( angle < 0.0 )
|
||||
angle += 360.0;
|
||||
|
||||
int count = (int) (angle / increment_angle );
|
||||
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
|
||||
|
@ -473,43 +456,29 @@ static SEGZONE * fillArcPOLY( BOARD * aPcb, int aLayer,
|
|||
if( ii < count )
|
||||
{
|
||||
if( clockwise )
|
||||
RotatePoint(&end_arc, rot);
|
||||
RotatePoint( &end_arc, rot );
|
||||
else
|
||||
RotatePoint(&end_arc, -rot);
|
||||
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;
|
||||
if( aGrbrItem->m_PolyCorners.size() == 0 )
|
||||
aGrbrItem->m_PolyCorners.push_back( start_arc + center );
|
||||
aGrbrItem->m_PolyCorners.push_back( end_arc + center );
|
||||
|
||||
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;
|
||||
aGrbrItem->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
|
||||
*/
|
||||
|
@ -574,48 +543,14 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
|
|||
}
|
||||
current_coord = atoi( line );
|
||||
double real_scale = 1.0;
|
||||
|
||||
switch( fmt_scale )
|
||||
{
|
||||
case 0:
|
||||
real_scale = 10000.0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
real_scale = 1000.0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
real_scale = 100.0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
real_scale = 10.0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
break;
|
||||
|
||||
case 5:
|
||||
real_scale = 0.1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
real_scale = 0.01;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
real_scale = 0.001;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
real_scale = 0.0001;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
real_scale = 0.00001;
|
||||
break;
|
||||
}
|
||||
if( fmt_scale < 0 || fmt_scale > 9 )
|
||||
fmt_scale = 4;
|
||||
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;
|
||||
|
@ -855,8 +790,8 @@ bool GERBER::Execute_G_Command( char*& text, int G_commande )
|
|||
int D_commande = ReturnDCodeNumber( text );
|
||||
if( D_commande < FIRST_DCODE )
|
||||
return false;
|
||||
if( D_commande > (MAX_TOOLS - 1) )
|
||||
D_commande = MAX_TOOLS - 1;
|
||||
if( D_commande > (TOOLS_MAX_COUNT - 1) )
|
||||
D_commande = TOOLS_MAX_COUNT - 1;
|
||||
m_Current_Tool = D_commande;
|
||||
D_CODE* pt_Dcode = GetDCODE( D_commande, false );
|
||||
if( pt_Dcode )
|
||||
|
@ -988,7 +923,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
wxSize size( 15, 15 );
|
||||
|
||||
APERTURE_T aperture = APT_CIRCLE;
|
||||
TRACK* track;
|
||||
GERBER_DRAW_ITEM* gbritem;
|
||||
BOARD* pcb = frame->GetBoard();
|
||||
|
||||
int activeLayer = frame->GetScreen()->m_Active_Layer;
|
||||
|
@ -1001,8 +936,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
|
||||
if( D_commande >= FIRST_DCODE ) // This is a "Set tool" command
|
||||
{
|
||||
if( D_commande > (MAX_TOOLS - 1) )
|
||||
D_commande = MAX_TOOLS - 1;
|
||||
if( D_commande > (TOOLS_MAX_COUNT - 1) )
|
||||
D_commande = TOOLS_MAX_COUNT - 1;
|
||||
|
||||
// remember which tool is selected, nothing is done with it in this
|
||||
// call
|
||||
|
@ -1021,44 +956,48 @@ 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
|
||||
if( !m_Exposure )
|
||||
{
|
||||
m_Exposure = true;
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
gbritem->m_Shape = GBR_POLYGON;
|
||||
gbritem->SetLayer( activeLayer );
|
||||
gbritem->m_Flashed = false;
|
||||
}
|
||||
|
||||
switch( m_Iterpolation )
|
||||
{
|
||||
case GERB_INTERPOL_ARC_NEG:
|
||||
case GERB_INTERPOL_ARC_POS:
|
||||
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
|
||||
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,
|
||||
fillArcPOLY( pcb, gbritem, 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 );
|
||||
gbritem = (GERBER_DRAW_ITEM*)( pcb->m_Drawings.GetLast() );
|
||||
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;
|
||||
gbritem->m_Start = m_PreviousPos; // m_Start is used as temporary storage
|
||||
NEGATE( gbritem->m_Start.y );
|
||||
if( gbritem->m_PolyCorners.size() == 0 )
|
||||
gbritem->m_PolyCorners.push_back( gbritem->m_Start );
|
||||
|
||||
edge_poly->m_Start = m_PreviousPos;
|
||||
NEGATE( edge_poly->m_Start.y );
|
||||
|
||||
edge_poly->m_End = m_CurrentPos;
|
||||
NEGATE( edge_poly->m_End.y );
|
||||
|
||||
edge_poly->SetNet( m_PolygonFillModeState );
|
||||
gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
|
||||
NEGATE( gbritem->m_End.y );
|
||||
gbritem->m_PolyCorners.push_back( gbritem->m_End );
|
||||
|
||||
// the first track of each polygon has a netcode of zero,
|
||||
// otherwise one. Set the erasure flag in that special track,
|
||||
|
@ -1066,7 +1005,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
if( !m_PolygonFillModeState )
|
||||
{
|
||||
if( m_LayerNegative ^ m_ImageNegative )
|
||||
edge_poly->m_Flags |= DRAW_ERASED;
|
||||
gbritem->m_Flags |= DRAW_ERASED;
|
||||
D( printf( "\nm_Flags=0x%08X\n", edge_poly->m_Flags ); )
|
||||
}
|
||||
break;
|
||||
|
@ -1104,10 +1043,10 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
switch( m_Iterpolation )
|
||||
{
|
||||
case GERB_INTERPOL_LINEAR_1X:
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillLineTRACK( track, dcode, activeLayer, m_PreviousPos,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, size.x,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
break;
|
||||
|
@ -1120,10 +1059,10 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
|
||||
case GERB_INTERPOL_ARC_NEG:
|
||||
case GERB_INTERPOL_ARC_POS:
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillArcTRACK( track, dcode, activeLayer, m_PreviousPos,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, m_IJPos, size.x,
|
||||
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
|
||||
false : true, m_360Arc_enbl,
|
||||
|
@ -1156,26 +1095,24 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
|
||||
switch( aperture )
|
||||
{
|
||||
case APT_LINE: // APT_LINE is not in the spec, don't know why it's
|
||||
// here
|
||||
case APT_CIRCLE:
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillRoundFlashTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
m_CurrentPos, size.x,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
break;
|
||||
|
||||
case APT_OVAL:
|
||||
case APT_RECT:
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
m_CurrentPos, size,
|
||||
( aperture == APT_RECT ) ?
|
||||
S_SPOT_RECT : S_SPOT_OVALE,
|
||||
GBR_SPOT_RECT : GBR_SPOT_OVAL,
|
||||
!(m_LayerNegative ^ m_ImageNegative) );
|
||||
break;
|
||||
|
||||
|
@ -1184,7 +1121,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
APERTURE_MACRO* macro = tool->GetMacro();
|
||||
wxASSERT( macro );
|
||||
|
||||
// split the macro primitives up into multiple normal TRACK
|
||||
// split the macro primitives up into multiple normal GBRITEM
|
||||
// elements
|
||||
for( AM_PRIMITIVES::iterator p = macro->primitives.begin();
|
||||
p!=macro->primitives.end();
|
||||
|
@ -1205,10 +1142,10 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
int diameter = scale( p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillRoundFlashTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, diameter, exposure );
|
||||
}
|
||||
break;
|
||||
|
@ -1241,11 +1178,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
wxPoint midPoint( ( start.x + end.x ) / 2,
|
||||
( start.y + end.y ) / 2 );
|
||||
curPos += midPoint;
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
curPos, size, S_SPOT_RECT,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
@ -1262,11 +1199,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
curPos += mapPt( p->params[3].GetValue( tool ),
|
||||
p->params[4].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
curPos, size, S_SPOT_RECT,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
@ -1288,11 +1225,11 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
// need the middle, so adjust from the lower left
|
||||
curPos.y += size.y / 2;
|
||||
curPos.x += size.x / 2;
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
curPos, size, S_SPOT_RECT,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, size, GBR_SPOT_RECT,
|
||||
exposure );
|
||||
}
|
||||
break;
|
||||
|
@ -1308,17 +1245,17 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
p->params[1].GetValue( tool ),
|
||||
m_GerbMetric );
|
||||
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillRoundFlashTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, outerDiam,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillRoundFlashTRACK( track, dcode, activeLayer, curPos,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillRoundFlashGBRITEM( gbritem, dcode, activeLayer, curPos,
|
||||
innerDiam,
|
||||
( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
|
@ -1351,39 +1288,37 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
// ignore rotation, not supported
|
||||
// adjust outerDiam by this on each nested circle
|
||||
int diamAdjust = 2 * (gap + penThickness);
|
||||
for( int i = 0;
|
||||
i < numCircles;
|
||||
++i, outerDiam -= diamAdjust )
|
||||
for( int i = 0; i < numCircles; ++i, outerDiam -= diamAdjust )
|
||||
{
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillCircularTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillCircularGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos, outerDiam,
|
||||
penThickness,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
}
|
||||
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos,
|
||||
wxSize( crossHairThickness,
|
||||
crossHairLength ),
|
||||
S_SPOT_RECT,
|
||||
GBR_SPOT_RECT,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
|
||||
track = new TRACK( pcb );
|
||||
pcb->m_Track.Append( track );
|
||||
D( printf( "R:%p\n", track ); )
|
||||
gbritem = new GERBER_DRAW_ITEM( pcb );
|
||||
pcb->m_Drawings.Append( gbritem );
|
||||
D( printf( "R:%p\n", gbritem ); )
|
||||
|
||||
// swap x and y in wxSize() for this one
|
||||
fillOvalOrRectFlashTRACK( track, dcode, activeLayer,
|
||||
fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer,
|
||||
curPos,
|
||||
wxSize( crossHairLength,
|
||||
crossHairThickness ),
|
||||
S_SPOT_RECT,
|
||||
GBR_SPOT_RECT,
|
||||
!( m_LayerNegative ^ m_ImageNegative ) );
|
||||
}
|
||||
break;
|
||||
|
@ -1398,14 +1333,15 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame,
|
|||
printf( " # points: %d\n", numPoints );
|
||||
|
||||
// numPoints does not include the starting point, so add 1.
|
||||
for( int i=0; i<numPoints+1; ++i )
|
||||
for( int i = 0; i<numPoints + 1; ++i )
|
||||
{
|
||||
printf( " [%d]: X=%g Y=%g\n", i,
|
||||
p->params[i*2+2+0].GetValue( tool ),
|
||||
p->params[i*2+2+1].GetValue( tool )
|
||||
p->params[i * 2 + 2 + 0].GetValue( tool ),
|
||||
p->params[i * 2 + 2 + 1].GetValue( tool )
|
||||
);
|
||||
}
|
||||
printf( " rotation: %g\n", p->params[numPoints*2+4].GetValue( tool ) );
|
||||
|
||||
printf( " rotation: %g\n", p->params[numPoints * 2 + 4].GetValue( tool ) );
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -448,7 +448,7 @@ bool GERBER::ExecuteRS274XCommand( int command,
|
|||
while( *text == ' ' )
|
||||
text++;
|
||||
|
||||
if( *text == 'Y' )
|
||||
if( *text == 'X' )
|
||||
{
|
||||
text++;
|
||||
dcode->m_Drill.y =
|
||||
|
|
|
@ -107,10 +107,10 @@ void WinEDA_GerberFrame::ReCreateHToolbar( void )
|
|||
m_HToolBar->AddSeparator();
|
||||
choices.Clear();
|
||||
|
||||
choices.Alloc(MAX_TOOLS+1);
|
||||
choices.Alloc(TOOLS_MAX_COUNT+1);
|
||||
choices.Add( _( "No tool" ) );
|
||||
|
||||
for( ii = 0; ii < MAX_TOOLS; ii++ )
|
||||
for( ii = 0; ii < TOOLS_MAX_COUNT; ii++ )
|
||||
{
|
||||
wxString msg;
|
||||
msg = _( "Tool " ); msg << ii + FIRST_DCODE;
|
||||
|
@ -187,11 +187,11 @@ void WinEDA_GerberFrame::ReCreateOptToolbar( void )
|
|||
_( "Change cursor shape" ), wxITEM_CHECK );
|
||||
|
||||
m_OptionsToolBar->AddSeparator();
|
||||
m_OptionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_PADS_SKETCH, wxEmptyString,
|
||||
m_OptionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH, wxEmptyString,
|
||||
wxBitmap( pad_sketch_xpm ),
|
||||
_( "Show spots in sketch mode" ), wxITEM_CHECK );
|
||||
|
||||
m_OptionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_TRACKS_SKETCH, wxEmptyString,
|
||||
m_OptionsToolBar->AddTool( ID_TB_OPTIONS_SHOW_LINES_SKETCH, wxEmptyString,
|
||||
wxBitmap( showtrack_xpm ),
|
||||
_( "Show lines in sketch mode" ), wxITEM_CHECK );
|
||||
|
||||
|
@ -215,3 +215,103 @@ void WinEDA_GerberFrame::ReCreateOptToolbar( void )
|
|||
|
||||
m_OptionsToolBar->Realize();
|
||||
}
|
||||
|
||||
|
||||
/** Function SetToolbars()
|
||||
* Set the tools state for the toolbars, according to display options
|
||||
*/
|
||||
void WinEDA_GerberFrame::SetToolbars()
|
||||
{
|
||||
PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen();
|
||||
int layer = screen->m_Active_Layer;
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
|
||||
if( m_HToolBar == NULL )
|
||||
return;
|
||||
|
||||
if( GetScreen()->m_BlockLocate.m_Command == BLOCK_MOVE )
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, true );
|
||||
m_HToolBar->EnableTool( wxID_COPY, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HToolBar->EnableTool( wxID_CUT, false );
|
||||
m_HToolBar->EnableTool( wxID_COPY, false );
|
||||
}
|
||||
|
||||
if( m_SelLayerBox && (m_SelLayerBox->GetSelection() != screen->m_Active_Layer) )
|
||||
{
|
||||
m_SelLayerBox->SetSelection( screen->m_Active_Layer );
|
||||
}
|
||||
|
||||
if( m_SelLayerTool )
|
||||
{
|
||||
if( gerber )
|
||||
{
|
||||
int sel_index;
|
||||
m_SelLayerTool->Enable( true );
|
||||
if( gerber->m_Selected_Tool < FIRST_DCODE ) // No tool selected
|
||||
sel_index = 0;
|
||||
else
|
||||
sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1;
|
||||
|
||||
if( sel_index != m_SelLayerTool->GetSelection() )
|
||||
{
|
||||
m_SelLayerTool->SetSelection( sel_index );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SelLayerTool->SetSelection( 0 );
|
||||
m_SelLayerTool->Enable( false );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_OptionsToolBar )
|
||||
{
|
||||
m_OptionsToolBar->ToggleTool(
|
||||
ID_TB_OPTIONS_SELECT_UNIT_MM,
|
||||
g_UserUnit ==
|
||||
MILLIMETRES ? true : false );
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SELECT_UNIT_INCH,
|
||||
g_UserUnit == INCHES ? true : false );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_POLAR_COORD,
|
||||
DisplayOpt.DisplayPolarCood );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_GRID,
|
||||
IsGridVisible() );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SELECT_CURSOR,
|
||||
m_CursorShape );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_FLASHED_ITEMS_SKETCH,
|
||||
!m_DisplayPadFill );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_LINES_SKETCH,
|
||||
!m_DisplayPcbTrackFill );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_POLYGONS_SKETCH,
|
||||
g_DisplayPolygonsModeSketch == 0 ? 0 : 1 );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_DCODES,
|
||||
IsElementVisible( DCODES_VISIBLE ) );
|
||||
|
||||
m_OptionsToolBar->ToggleTool( ID_TB_OPTIONS_SHOW_LAYERS_MANAGER_VERTICAL_TOOLBAR,
|
||||
m_show_layer_manager_tools );
|
||||
if( m_show_layer_manager_tools )
|
||||
GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
_("Hide &Layers Manager" ) );
|
||||
else
|
||||
GetMenuBar()->SetLabel( ID_MENU_GERBVIEW_SHOW_HIDE_LAYERS_MANAGER_DIALOG,
|
||||
_("Show &Layers Manager" ) );
|
||||
|
||||
}
|
||||
|
||||
DisplayUnitsMsg();
|
||||
|
||||
if( m_auimgr.GetManagedWindow() )
|
||||
m_auimgr.Update();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include "fctsys.h"
|
||||
#include "polygons_defs.h"
|
||||
#include "gr_basic.h"
|
||||
#include "common.h"
|
||||
#include "class_drawpanel.h"
|
||||
|
@ -17,12 +18,13 @@
|
|||
#include "protos.h"
|
||||
#include "class_board_design_settings.h"
|
||||
#include "colors_selection.h"
|
||||
#include "class_gerber_draw_item.h"
|
||||
|
||||
/***************/
|
||||
/* tracepcb.cpp */
|
||||
/***************/
|
||||
|
||||
static void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC,
|
||||
static void Show_Items_DCode_Value( WinEDA_DrawPanel* panel, wxDC* DC,
|
||||
BOARD* Pcb, int drawmode );
|
||||
|
||||
/** virtual Function PrintPage
|
||||
|
@ -95,8 +97,7 @@ void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
|
|||
}
|
||||
|
||||
/********************************************************************/
|
||||
void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC,
|
||||
int aDrawMode, const wxPoint& offset )
|
||||
void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, const wxPoint& aOffset )
|
||||
/********************************************************************/
|
||||
/* Redraw the BOARD items but not cursors, axis or grid */
|
||||
// @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function
|
||||
|
@ -116,315 +117,71 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* aDC, int aDraw_mode, int aPrintMask
|
|||
if( !GetBoard() )
|
||||
return;
|
||||
|
||||
bool erase = false;
|
||||
int color;
|
||||
bool filled;
|
||||
int layer = GetScreen()->m_Active_Layer;
|
||||
|
||||
// Draw filled polygons
|
||||
std::vector<wxPoint> points;
|
||||
|
||||
// minimize reallocations of the vector's internal array by starting with a good sized one.
|
||||
points.reserve(10000);
|
||||
|
||||
TRACK* next_track;
|
||||
for( TRACK* track = GetBoard()->m_Zone; track; track = next_track )
|
||||
{
|
||||
next_track = track->Next();
|
||||
|
||||
if( !(track->ReturnMaskLayer() & aPrintMasklayer) )
|
||||
continue;
|
||||
|
||||
if( (points.size() == 0) && (track->GetNet() == 0) ) // first point of a new polygon
|
||||
{
|
||||
erase = ( track->m_Flags & DRAW_ERASED );
|
||||
points.push_back( track->m_Start );
|
||||
}
|
||||
|
||||
points.push_back( track->m_End );
|
||||
|
||||
if( (next_track == NULL ) || (next_track->GetNet() == 0) ) // EndPoint of the current polygon
|
||||
{
|
||||
color = g_ColorsSettings.GetLayerColor( track->GetLayer() );
|
||||
filled = (g_DisplayPolygonsModeSketch == 0);
|
||||
if( erase )
|
||||
{
|
||||
color = g_DrawBgColor;
|
||||
filled = true;
|
||||
}
|
||||
|
||||
GRClosedPoly( &DrawPanel->m_ClipBox, aDC, points.size(), &points[0],
|
||||
filled, color, color );
|
||||
points.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw tracks and flashes down here.
|
||||
// This will probably not be a final solution to drawing order issues
|
||||
GERBER* gerber = g_GERBER_List[layer];
|
||||
int dcode_hightlight = 0;
|
||||
|
||||
if( gerber )
|
||||
dcode_hightlight = gerber->m_Selected_Tool;
|
||||
|
||||
for( TRACK* track = GetBoard()->m_Track; track; track = track->Next() )
|
||||
BOARD_ITEM* item = GetBoard()->m_Drawings;
|
||||
for( ; item; item = item->Next() )
|
||||
{
|
||||
if( !(track->ReturnMaskLayer() & aPrintMasklayer) )
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( !(gerb_item->ReturnMaskLayer() & aPrintMasklayer) )
|
||||
continue;
|
||||
if( dcode_hightlight == track->GetNet() && track->GetLayer()==layer )
|
||||
Trace_Segment( GetBoard(), DrawPanel, aDC, track, aDraw_mode | GR_SURBRILL );
|
||||
if( dcode_hightlight == gerb_item->m_DCode && item->GetLayer()==layer )
|
||||
gerb_item->Draw( DrawPanel, aDC, aDraw_mode | GR_SURBRILL );
|
||||
else
|
||||
Trace_Segment( GetBoard(), DrawPanel, aDC, track, aDraw_mode );
|
||||
gerb_item->Draw( DrawPanel, aDC, aDraw_mode );
|
||||
}
|
||||
|
||||
if( IsElementVisible( DCODES_VISIBLE) )
|
||||
Affiche_DCodes_Pistes( DrawPanel, aDC, GetBoard(), GR_COPY );
|
||||
Show_Items_DCode_Value( DrawPanel, aDC, GetBoard(), GR_COPY );
|
||||
|
||||
GetScreen()->ClrRefreshReq();
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
/***********************************************************************************/
|
||||
void Trace_Segment( BOARD* aBrd, WinEDA_DrawPanel* panel, wxDC* DC, TRACK* track, int draw_mode )
|
||||
/***********************************************************************************/
|
||||
|
||||
/* Trace 1 segment of track (segment, spot...).
|
||||
* Parameters :
|
||||
* Track = a pointer on of the description of the track
|
||||
* draw_mode = mode ( GR_XOR, GR_OR..)
|
||||
*/
|
||||
{
|
||||
int l_piste;
|
||||
int color;
|
||||
int fillopt;
|
||||
int radius;
|
||||
int halfPenWidth;
|
||||
static bool show_err;
|
||||
|
||||
if( track->m_Flags & DRAW_ERASED ) // draw in background color, used by classs TRACK in gerbview
|
||||
{
|
||||
color = g_DrawBgColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aBrd->IsLayerVisible( track->GetLayer() ) == false )
|
||||
return;
|
||||
|
||||
color = aBrd->GetLayerColor( track->GetLayer() );
|
||||
|
||||
if( draw_mode & GR_SURBRILL )
|
||||
{
|
||||
if( draw_mode & GR_AND )
|
||||
color &= ~HIGHT_LIGHT_FLAG;
|
||||
else
|
||||
color |= HIGHT_LIGHT_FLAG;
|
||||
}
|
||||
if( color & HIGHT_LIGHT_FLAG )
|
||||
color = ColorRefs[color & MASKCOLOR].m_LightColor;
|
||||
}
|
||||
|
||||
GRSetDrawMode( DC, draw_mode );
|
||||
|
||||
|
||||
fillopt = DisplayOpt.DisplayPcbTrackFill ? FILLED : SKETCH;
|
||||
|
||||
switch( track->m_Shape )
|
||||
{
|
||||
case S_CIRCLE:
|
||||
radius = (int) hypot( (double) (track->m_End.x - track->m_Start.x),
|
||||
(double) (track->m_End.y - track->m_Start.y) );
|
||||
|
||||
halfPenWidth = track->m_Width >> 1;
|
||||
|
||||
#ifdef USE_WX_ZOOM
|
||||
if( DC->LogicalToDeviceXRel( halfPenWidth ) < L_MIN_DESSIN )
|
||||
#else
|
||||
if( panel->GetScreen()->Scale( halfPenWidth ) < L_MIN_DESSIN )
|
||||
#endif
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
|
||||
track->m_Start.y, radius, 0, color );
|
||||
}
|
||||
|
||||
if( fillopt == SKETCH )
|
||||
{
|
||||
// draw the border of the pen's path using two circles, each as narrow as possible
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
radius - halfPenWidth, 0, color );
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
radius + halfPenWidth, 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
radius, track->m_Width, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
if( fillopt == SKETCH )
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
track->m_End.x, track->m_End.y,
|
||||
track->m_Param, track->GetSubNet(), 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRArc1( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
track->m_End.x, track->m_End.y,
|
||||
track->m_Param, track->GetSubNet(),
|
||||
track->m_Width, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_SPOT_CIRCLE:
|
||||
radius = track->m_Width >> 1;
|
||||
|
||||
fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
|
||||
|
||||
#ifdef USE_WX_ZOOM
|
||||
if( DC->LogicalToDeviceXRel( radius ) < L_MIN_DESSIN )
|
||||
#else
|
||||
if( panel->GetScreen()->Scale( radius ) < L_MIN_DESSIN )
|
||||
#endif
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
|
||||
track->m_Start.y, radius, 0, color );
|
||||
}
|
||||
else if( fillopt == SKETCH )
|
||||
{
|
||||
GRCircle( &panel->m_ClipBox, DC, track->m_Start.x,
|
||||
track->m_Start.y, radius, 0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFilledCircle( &panel->m_ClipBox, DC, track->m_Start.x,
|
||||
track->m_Start.y, radius, 0, color, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_SPOT_RECT:
|
||||
case S_RECT:
|
||||
|
||||
l_piste = track->m_Width >> 1;
|
||||
|
||||
fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
|
||||
|
||||
#ifdef USE_WX_ZOOM
|
||||
if( DC->LogicalToDeviceXRel( l_piste ) < L_MIN_DESSIN )
|
||||
#else
|
||||
if( panel->GetScreen()->Scale( l_piste ) < L_MIN_DESSIN )
|
||||
#endif
|
||||
{
|
||||
GRLine( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
track->m_End.x, track->m_End.y, 0, color );
|
||||
}
|
||||
else if( fillopt == SKETCH )
|
||||
{
|
||||
GRRect( &panel->m_ClipBox, DC,
|
||||
track->m_Start.x - l_piste,
|
||||
track->m_Start.y - l_piste,
|
||||
track->m_End.x + l_piste,
|
||||
track->m_End.y + l_piste,
|
||||
0, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFilledRect( &panel->m_ClipBox, DC,
|
||||
track->m_Start.x - l_piste,
|
||||
track->m_Start.y - l_piste,
|
||||
track->m_End.x + l_piste,
|
||||
track->m_End.y + l_piste,
|
||||
0, color, color );
|
||||
}
|
||||
break;
|
||||
|
||||
case S_SPOT_OVALE:
|
||||
fillopt = DisplayOpt.DisplayPadFill ? FILLED : SKETCH;
|
||||
|
||||
case S_SEGMENT:
|
||||
l_piste = track->m_Width >> 1;
|
||||
|
||||
#ifdef USE_WX_ZOOM
|
||||
if( DC->LogicalToDeviceXRel( l_piste ) < L_MIN_DESSIN )
|
||||
#else
|
||||
if( panel->GetScreen()->Scale( l_piste ) < L_MIN_DESSIN )
|
||||
#endif
|
||||
{
|
||||
GRLine( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
track->m_End.x, track->m_End.y, 0, color );
|
||||
break;
|
||||
}
|
||||
|
||||
if( fillopt == SKETCH )
|
||||
{
|
||||
GRCSegm( &panel->m_ClipBox, DC, track->m_Start.x, track->m_Start.y,
|
||||
track->m_End.x, track->m_End.y, track->m_Width, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFillCSegm( &panel->m_ClipBox, DC, track->m_Start.x,
|
||||
track->m_Start.y, track->m_End.x, track->m_End.y,
|
||||
track->m_Width, color );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if( !show_err )
|
||||
{
|
||||
wxMessageBox( wxT( "Trace_Segment() type error" ) );
|
||||
show_err = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************************/
|
||||
void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int drawmode )
|
||||
void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, int aDrawMode )
|
||||
/*****************************************************************************************/
|
||||
{
|
||||
TRACK* track;
|
||||
wxPoint pos;
|
||||
int width, orient;
|
||||
wxString Line;
|
||||
|
||||
GRSetDrawMode( DC, drawmode );
|
||||
track = Pcb->m_Track;
|
||||
for( ; track != NULL; track = track->Next() )
|
||||
GRSetDrawMode( aDC, aDrawMode );
|
||||
BOARD_ITEM* item = aPcb->m_Drawings;
|
||||
for( ; item != NULL; item = item->Next() )
|
||||
{
|
||||
if( Pcb->IsLayerVisible( track->GetLayer() ) == false )
|
||||
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
|
||||
if( aPcb->IsLayerVisible( gerb_item->GetLayer() ) == false )
|
||||
continue;
|
||||
if( gerb_item->m_DCode <= 0 )
|
||||
continue;
|
||||
|
||||
if( (track->m_Shape == S_ARC)
|
||||
|| (track->m_Shape == S_CIRCLE)
|
||||
|| (track->m_Shape == S_ARC_RECT) )
|
||||
{
|
||||
pos.x = track->m_Start.x;
|
||||
pos.y = track->m_Start.y;
|
||||
}
|
||||
if( gerb_item->m_Flashed )
|
||||
pos = gerb_item->m_Start;
|
||||
else
|
||||
{
|
||||
pos.x = (track->m_Start.x + track->m_End.x) / 2;
|
||||
pos.y = (track->m_Start.y + track->m_End.y) / 2;
|
||||
pos.x = (gerb_item->m_Start.x + gerb_item->m_End.x) / 2;
|
||||
pos.y = (gerb_item->m_Start.y + gerb_item->m_End.y) / 2;
|
||||
}
|
||||
|
||||
Line.Printf( wxT( "D%d" ), track->GetNet() );
|
||||
Line.Printf( wxT( "D%d" ), gerb_item->m_DCode );
|
||||
|
||||
width = track->m_Width;
|
||||
width = MIN( gerb_item->m_Size.x, gerb_item->m_Size.y );
|
||||
orient = TEXT_ORIENT_HORIZ;
|
||||
if( track->m_Shape >= S_SPOT_CIRCLE ) // forme flash
|
||||
if( gerb_item->m_Flashed )
|
||||
{
|
||||
width /= 3;
|
||||
}
|
||||
else // lines
|
||||
{
|
||||
int dx, dy;
|
||||
dx = track->m_Start.x - track->m_End.x;
|
||||
dy = track->m_Start.y - track->m_End.y;
|
||||
dx = gerb_item->m_Start.x - gerb_item->m_End.x;
|
||||
dy = gerb_item->m_Start.y - gerb_item->m_End.y;
|
||||
if( abs( dx ) < abs( dy ) )
|
||||
orient = TEXT_ORIENT_VERT;
|
||||
width /= 2;
|
||||
|
@ -432,7 +189,7 @@ void Affiche_DCodes_Pistes( WinEDA_DrawPanel* panel, wxDC* DC, BOARD* Pcb, int d
|
|||
|
||||
int color = g_ColorsSettings.GetItemColor(DCODES_VISIBLE);
|
||||
|
||||
DrawGraphicText( panel, DC,
|
||||
DrawGraphicText( aPanel, aDC,
|
||||
pos, (EDA_Colors) color, Line,
|
||||
orient, wxSize( width, width ),
|
||||
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
|
||||
|
|
|
@ -223,8 +223,6 @@ public:
|
|||
* @param DC A device context to draw on.
|
||||
*/
|
||||
void Block_Delete( wxDC* DC );
|
||||
void Block_Rotate( wxDC* DC );
|
||||
void Block_Invert( wxDC* DC );
|
||||
|
||||
/**
|
||||
* Function Block_Move
|
||||
|
@ -237,14 +235,6 @@ public:
|
|||
*/
|
||||
void Block_Move( wxDC* DC );
|
||||
|
||||
/**
|
||||
* Function Block_Mirror_X
|
||||
* mirrors all tracks and segments within the currently selected block
|
||||
* in the X axis.
|
||||
*
|
||||
* @param DC A device context to draw on.
|
||||
*/
|
||||
void Block_Mirror_X( wxDC* DC );
|
||||
/**
|
||||
* Function Block_Duplicate
|
||||
* copies-and-moves all tracks and segments within the selected block.
|
||||
|
@ -339,7 +329,6 @@ public:
|
|||
bool Clear_Pcb( bool query );
|
||||
void Erase_Current_Layer( bool query );
|
||||
void Delete_DCode_Items( wxDC* DC, int dcode_value, int layer_number );
|
||||
TRACK* Delete_Segment( wxDC* DC, TRACK* Track );
|
||||
|
||||
// Conversion function
|
||||
void ExportDataInPcbnewFormat( wxCommandEvent& event );
|
||||
|
|
|
@ -87,6 +87,11 @@ enum KICAD_T {
|
|||
*/
|
||||
COMPONENT_FIELD_DRAW_TYPE,
|
||||
|
||||
/*
|
||||
* For Gerbview: items type:
|
||||
*/
|
||||
TYPE_GERBER_DRAW_ITEM,
|
||||
|
||||
// End value
|
||||
MAX_STRUCT_TYPE_ID
|
||||
};
|
||||
|
|
|
@ -9,18 +9,15 @@
|
|||
#include <boost/ptr_container/ptr_vector.hpp>
|
||||
|
||||
|
||||
/* Shapes for segments (graphic segments and tracks) ( .shape member ) */
|
||||
/* Shapes for segments (graphic segments and tracks) ( .m_Shape member ) */
|
||||
enum Track_Shapes {
|
||||
S_SEGMENT = 0, /* usual segment : line with rounded ends */
|
||||
S_RECT, /* segment with non rounded ends */
|
||||
S_ARC, /* Arcs (with rounded ends)*/
|
||||
S_CIRCLE, /* ring*/
|
||||
S_ARC_RECT, /* Arcs (with non rounded ends) (GERBER)*/
|
||||
S_SPOT_OVALE, /* Oblong spot (for GERBER)*/
|
||||
S_SPOT_CIRCLE, /* rounded spot (for GERBER)*/
|
||||
S_SPOT_RECT, /* Rectangular spott (for GERBER)*/
|
||||
S_POLYGON, /* polygonal shape */
|
||||
S_CURVE /* Bezier Curve*/
|
||||
S_POLYGON, /* polygonal shape (not yet used for tracks, but could be in microwave apps) */
|
||||
S_CURVE, /* Bezier Curve*/
|
||||
S_LAST /* last value for this list */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -171,12 +171,10 @@ void GRCircle( EDA_Rect* ClipBox, wxDC* aDC, int x, int y, int aRadius,
|
|||
|
||||
void GRCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int width,
|
||||
int Color );
|
||||
void GRFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r,
|
||||
int width, int Color, int BgColor );
|
||||
void GRSCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int width,
|
||||
int Color );
|
||||
void GRSFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r,
|
||||
int width, int Color, int BgColor );
|
||||
void GRFilledCircle( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int r, int width, int Color, int BgColor );
|
||||
void GRFilledCircle( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aColor );
|
||||
void GRCircle( EDA_Rect* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aWidth, int aColor );
|
||||
|
||||
void GRArc( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int StAngle,
|
||||
int EndAngle, int r, int Color );
|
||||
void GRArc( EDA_Rect* ClipBox, wxDC* DC, int x, int y, int StAngle,
|
||||
|
|
|
@ -25,12 +25,6 @@ wxString BOARD_ITEM::ShowShape( Track_Shapes aShape )
|
|||
case S_ARC: return _( "Arc" );
|
||||
case S_CIRCLE: return _( "Circle" );
|
||||
case S_CURVE: return _( "Bezier Curve" );
|
||||
|
||||
// used in Gerbview:
|
||||
case S_ARC_RECT: return wxT( "arc_rect" );
|
||||
case S_SPOT_OVALE: return wxT( "spot_oval" );
|
||||
case S_SPOT_CIRCLE: return wxT( "spot_circle" );
|
||||
case S_SPOT_RECT: return wxT( "spot_rect" );
|
||||
case S_POLYGON: return wxT( "polygon" );
|
||||
default: return wxT( "??" );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue