From b992af3eb3a295d6d6872761475b33edcd247ad5 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 28 Sep 2010 16:42:05 +0200 Subject: [PATCH] Gerbview code redesign --- CHANGELOG.txt | 20 +- common/gr_basic.cpp | 56 +- gerbview/CMakeLists.txt | 3 +- gerbview/block.cpp | 251 ++--- gerbview/class_GERBER.cpp | 190 ++++ gerbview/class_gerber_draw_item.cpp | 426 ++++++++ gerbview/class_gerber_draw_item.h | 183 ++++ gerbview/dcode.cpp | 595 ++++++----- gerbview/dcode.h | 278 +++++ gerbview/deltrack.cpp | 74 +- gerbview/dummy_functions.cpp | 2 +- gerbview/edit.cpp | 28 +- gerbview/export_to_pcbnew.cpp | 55 +- .../aperture-circle-flash-with_hole.gbr | 27 + .../aperture-obround-flash-with_hole.gbr | 27 + .../test-aperture-polygon-flash.gbr | 27 + ...est-aperture-rectangle-flash-with_hole.gbr | 27 + gerbview/gerberframe.cpp | 186 ++-- gerbview/gerbview.h | 232 +---- gerbview/gerbview_config.h | 2 +- gerbview/gerbview_id.h | 2 + gerbview/hotkeys.cpp | 4 +- gerbview/hotkeys.h | 2 +- gerbview/initpcb.cpp | 33 +- gerbview/lay2plot.cpp | 37 - gerbview/locate.cpp | 442 -------- gerbview/onrightclick.cpp | 21 +- gerbview/options.cpp | 16 +- gerbview/protos.h | 11 - gerbview/readgerb.cpp | 12 +- gerbview/rs274d.cpp | 970 ++++++++---------- gerbview/rs274x.cpp | 2 +- gerbview/toolbars_gerber.cpp | 108 +- gerbview/tracepcb.cpp | 303 +----- gerbview/wxGerberFrame.h | 11 - include/base_struct.h | 5 + include/class_board_item.h | 11 +- include/gr_basic.h | 10 +- pcbnew/class_board_item.cpp | 6 - 39 files changed, 2376 insertions(+), 2319 deletions(-) create mode 100644 gerbview/class_GERBER.cpp create mode 100644 gerbview/class_gerber_draw_item.cpp create mode 100644 gerbview/class_gerber_draw_item.h create mode 100644 gerbview/dcode.h create mode 100644 gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr create mode 100644 gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr create mode 100644 gerbview/gerber_test_files/test-aperture-polygon-flash.gbr create mode 100644 gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr delete mode 100644 gerbview/lay2plot.cpp diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 69fd3cfc14..56a69878e7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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 +================================================================================ +++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 ================================================================================ ++CMakeModules: @@ -67,7 +85,7 @@ email address. 2010-jul-27, UPDATE Jean-Pierre Charras ================================================================================ ++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 diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index f8fa9ee205..27cdfcb2c5 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -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; @@ -545,8 +549,8 @@ void GRSetColorPen( wxDC* DC, int Color, int width, int style ) } if( s_DC_lastcolor != Color || - s_DC_lastwidth != width || - s_DC_lastpenstyle != style || + s_DC_lastwidth != width || + s_DC_lastpenstyle != style || s_DC_lastDC != DC ) { wxPen pen; @@ -573,8 +577,8 @@ void GRSetBrush( wxDC* DC, int Color, int fill ) if( ForceBlackPen ) Color = BLACK; - if( s_DC_lastbrushcolor != Color || - s_DC_lastbrushfill != fill || + if( s_DC_lastbrushcolor != Color || + s_DC_lastbrushfill != fill || s_DC_lastDC != DC ) { wxBrush DrawBrush; @@ -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. diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index f702f1431e..486188e814 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -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 diff --git a/gerbview/block.cpp b/gerbview/block.cpp index 6f9fde41af..22bf964ef9 100644 --- a/gerbview/block.cpp +++ b/gerbview/block.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 + * 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,17 +35,18 @@ #include "confirm.h" #include "gerbview.h" +#include "class_gerber_draw_item.h" #include "protos.h" #define BLOCK_COLOR BROWN -static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, - wxDC* DC, - bool erase ); +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 @@ -73,7 +98,7 @@ void WinEDA_GerberFrame::HandleBlockPlace( wxDC* DC ) { err = TRUE; DisplayError( this, - wxT( "Error in HandleBlockPLace : ManageCurseur = NULL" ) ); + wxT( "Error in HandleBlockPLace : ManageCurseur = NULL" ) ); } GetScreen()->m_BlockLocate.m_State = STATE_BLOCK_STOP; @@ -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_ROTATE: /* Unused */ - break; - - case BLOCK_FLIP: /* Flip, unused */ - break; - - case BLOCK_SAVE: /* Save (not used)*/ - break; - + case BLOCK_MIRROR_X: /* Mirror, unused*/ + case BLOCK_ROTATE: /* Unused */ + case BLOCK_FLIP: /* Flip, unused */ + case BLOCK_SAVE: /* Save (not used)*/ 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; } diff --git a/gerbview/class_GERBER.cpp b/gerbview/class_GERBER.cpp new file mode 100644 index 0000000000..e13e7d230f --- /dev/null +++ b/gerbview/class_GERBER.cpp @@ -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 + * 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(); + } +} + + diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp new file mode 100644 index 0000000000..43ab9508ec --- /dev/null +++ b/gerbview/class_gerber_draw_item.cpp @@ -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 + * 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 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 ) << '"' << + "" << + ""; + + os << "\n"; +} + + +#endif diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h new file mode 100644 index 0000000000..b5878d0df5 --- /dev/null +++ b/gerbview/class_gerber_draw_item.h @@ -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 + * 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 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 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 */ diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp index 05fb7c0e5a..57e6df2b84 100644 --- a/gerbview/dcode.cpp +++ b/gerbview/dcode.cpp @@ -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; - 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_Size = dcode->m_Size; + if( // Line Item + (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 + // 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 ); + if( m_DrillShape == 0 ) + GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor ); + else if( m_DrillShape == 1 ) // round hole + { + 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; - for( ii = 0, jj = 1; ii < MAX_TOOLS; ii++ ) + case APT_LINE: + // not used for flashed items + break; + + 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 ) { - 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++; + 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 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; + } } diff --git a/gerbview/dcode.h b/gerbview/dcode.h new file mode 100644 index 0000000000..4ab2484145 --- /dev/null +++ b/gerbview/dcode.h @@ -0,0 +1,278 @@ +/**************/ +/* dcode.h */ +/**************/ + +#ifndef _DCODE_H_ +#define _DCODE_H_ + +#include +#include + +#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_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_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 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_SET; +typedef std::pair 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 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_ diff --git a/gerbview/deltrack.cpp b/gerbview/deltrack.cpp index fe49fb575e..3d0789d850 100644 --- a/gerbview/deltrack.cpp +++ b/gerbview/deltrack.cpp @@ -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* container = (DLIST*)Track->GetList(); - wxASSERT( container ); - container->Remove( Track ); - - GetScreen()->SetModify(); - return NULL; -} diff --git a/gerbview/dummy_functions.cpp b/gerbview/dummy_functions.cpp index 1876ca1cce..68fe8b6d0a 100644 --- a/gerbview/dummy_functions.cpp +++ b/gerbview/dummy_functions.cpp @@ -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; } + diff --git a/gerbview/edit.cpp b/gerbview/edit.cpp index 89806da697..ce8451a539 100644 --- a/gerbview/edit.cpp +++ b/gerbview/edit.cpp @@ -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 ); - GetScreen()->SetCurItem( NULL ); - GetScreen()->SetModify(); - } + /* 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, diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index de7e3d58ff..26ba5b13c6 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -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; diff --git a/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr b/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr new file mode 100644 index 0000000000..91c4bfc295 --- /dev/null +++ b/gerbview/gerber_test_files/aperture-circle-flash-with_hole.gbr @@ -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* diff --git a/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr b/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr new file mode 100644 index 0000000000..b09bf43a55 --- /dev/null +++ b/gerbview/gerber_test_files/aperture-obround-flash-with_hole.gbr @@ -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* diff --git a/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr b/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr new file mode 100644 index 0000000000..788a7551bd --- /dev/null +++ b/gerbview/gerber_test_files/test-aperture-polygon-flash.gbr @@ -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* diff --git a/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr b/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr new file mode 100644 index 0000000000..8aeb79cfa2 --- /dev/null +++ b/gerbview/gerber_test_files/test-aperture-rectangle-flash-with_hole.gbr @@ -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* diff --git a/gerbview/gerberframe.cpp b/gerbview/gerberframe.cpp index 39a40c44ca..4b4f074c54 100644 --- a/gerbview/gerberframe.cpp +++ b/gerbview/gerberframe.cpp @@ -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; +} diff --git a/gerbview/gerbview.h b/gerbview/gerbview.h index d5ee91865f..3bfdedfda7 100644 --- a/gerbview/gerbview.h +++ b/gerbview/gerbview.h @@ -8,6 +8,7 @@ #include #include +#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_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_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 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_SET; -typedef std::pair 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; diff --git a/gerbview/gerbview_config.h b/gerbview/gerbview_config.h index 74ae865ec1..639ea16a57 100644 --- a/gerbview/gerbview_config.h +++ b/gerbview/gerbview_config.h @@ -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 ); diff --git a/gerbview/gerbview_id.h b/gerbview/gerbview_id.h index d35952e436..12cc8b4267 100644 --- a/gerbview/gerbview_id.h +++ b/gerbview/gerbview_id.h @@ -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 }; diff --git a/gerbview/hotkeys.cpp b/gerbview/hotkeys.cpp index 4b7ce2d57e..c58101ae29 100644 --- a/gerbview/hotkeys.cpp +++ b/gerbview/hotkeys.cpp @@ -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; diff --git a/gerbview/hotkeys.h b/gerbview/hotkeys.h index 2b408162a8..9a2c465ac3 100644 --- a/gerbview/hotkeys.h +++ b/gerbview/hotkeys.h @@ -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 }; diff --git a/gerbview/initpcb.cpp b/gerbview/initpcb.cpp index 6b2f52c1ef..e817a7cf2d 100644 --- a/gerbview/initpcb.cpp +++ b/gerbview/initpcb.cpp @@ -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(); diff --git a/gerbview/lay2plot.cpp b/gerbview/lay2plot.cpp deleted file mode 100644 index 3be8c7397e..0000000000 --- a/gerbview/lay2plot.cpp +++ /dev/null @@ -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; -} diff --git a/gerbview/locate.cpp b/gerbview/locate.cpp index 52509f5c42..edb9a2b8c5 100644 --- a/gerbview/locate.cpp +++ b/gerbview/locate.cpp @@ -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; -} diff --git a/gerbview/onrightclick.cpp b/gerbview/onrightclick.cpp index e483262e65..7a7c2894fe 100644 --- a/gerbview/onrightclick.cpp +++ b/gerbview/onrightclick.cpp @@ -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; } diff --git a/gerbview/options.cpp b/gerbview/options.cpp index 8932d566af..0f39420fea 100644 --- a/gerbview/options.cpp +++ b/gerbview/options.cpp @@ -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; diff --git a/gerbview/protos.h b/gerbview/protos.h index 49cddc554e..250d9689dd 100644 --- a/gerbview/protos.h +++ b/gerbview/protos.h @@ -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 ); - - diff --git a/gerbview/readgerb.cpp b/gerbview/readgerb.cpp index 9065fb93ca..5e4ff2e2e2 100644 --- a/gerbview/readgerb.cpp +++ b/gerbview/readgerb.cpp @@ -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() */ diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index d7536e15eb..dc6dbfe407 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -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 @@ -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,171 +101,158 @@ 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, - int Dcode_index, - int aLayer, - const wxPoint& aPos, - int aDiameter, - int aPenWidth, - bool isDark ) +static void fillCircularGBRITEM( GERBER_DRAW_ITEM* aGbrItem, + int Dcode_index, + int aLayer, + const wxPoint& aPos, + int aDiameter, + 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, - int Dcode_index, - int aLayer, - const wxPoint& aPos, - int aDiameter, - bool isDark ) +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, - int Dcode_index, - int aLayer, - const wxPoint& aPos, - const wxSize& aSize, - int aShape, - bool isDark ) +static void fillOvalOrRectFlashGBRITEM( GERBER_DRAW_ITEM* aGbrItem, + int Dcode_index, + int aLayer, + const wxPoint& aPos, + const wxSize& aSize, + 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, - int Dcode_index, - int aLayer, - const wxPoint& aStart, - const wxPoint& aEnd, - int aWidth, - bool isDark ) +static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, + int Dcode_index, + int aLayer, + const wxPoint& aStart, + const wxPoint& aEnd, + 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. *

* 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, *

  • absolute angle 180 to 270 (quadrant 3) or *
  • absolute angle 270 to 0 (quadrant 4) *

    - * @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, - const wxPoint& aStart, const wxPoint& aEnd, - const wxPoint& rel_center, int aWidth, - bool clockwise, bool multiquadrant, bool isDark ) +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; + center = rel_center; + 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, *

  • absolute angle 270 to 0 (quadrant 4) *

    * @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, - const wxPoint& aStart, const wxPoint& aEnd, - const wxPoint& rel_center, - bool clockwise, bool multiquadrant, bool isDark ) +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, - clockwise, multiquadrant, isDark ); + 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(); + wxPoint center; + 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 @@ -469,47 +452,33 @@ static SEGZONE * fillArcPOLY( BOARD * aPcb, int aLayer, for( int ii = 1; ii <= count; ii++ ) { wxPoint end_arc = start; - int rot = 10 * ii * increment_angle; // rot is in 0.1 deg + int rot = 10 * ii * increment_angle; // rot is in 0.1 deg 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 ) @@ -940,7 +875,7 @@ static int scale( double aCoord, bool isMetric ) static wxPoint mapPt( double x, double y, bool isMetric ) { wxPoint ret( scale( x, isMetric ), - scale( y, isMetric ) ); + scale( y, isMetric ) ); return ret; } @@ -985,24 +920,24 @@ static bool mapExposure( int param1, bool curExposure, bool isNegative ) bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, char*& text, int D_commande ) { - wxSize size( 15, 15 ); + wxSize size( 15, 15 ); - APERTURE_T aperture = APT_CIRCLE; - TRACK* track; - BOARD* pcb = frame->GetBoard(); + APERTURE_T aperture = APT_CIRCLE; + GERBER_DRAW_ITEM* gbritem; + BOARD* pcb = frame->GetBoard(); - int activeLayer = frame->GetScreen()->m_Active_Layer; + int activeLayer = frame->GetScreen()->m_Active_Layer; - int dcode = 0; - D_CODE* tool = NULL; - wxString msg; + int dcode = 0; + D_CODE* tool = NULL; + wxString msg; D( printf( "%22s: D_CODE<%d>\n", __func__, D_commande ); ) 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 - m_Exposure = true; + 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, - m_CurrentPos, m_IJPos, - ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? - false : true, m_360Arc_enbl, - !(m_LayerNegative ^ m_ImageNegative) ); - edge_poly->SetNet( m_PolygonFillModeState ); + m_PreviousPos.x, m_PreviousPos.y, m_CurrentPos.x, + m_CurrentPos.y, m_PolygonFillModeState, m_Iterpolation, m_360Arc_enbl ); ) + fillArcPOLY( pcb, gbritem, m_PreviousPos, + m_CurrentPos, m_IJPos, + ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? + false : true, m_360Arc_enbl, + !(m_LayerNegative ^ m_ImageNegative) ); 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 ); ) + 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,12 +1043,12 @@ 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, - m_CurrentPos, size.x, - !(m_LayerNegative ^ m_ImageNegative) ); + 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; case GERB_INTERPOL_LINEAR_01X: @@ -1120,14 +1059,14 @@ 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, - m_CurrentPos, m_IJPos, size.x, - ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? - false : true, m_360Arc_enbl, - !(m_LayerNegative ^ m_ImageNegative) ); + 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, + !(m_LayerNegative ^ m_ImageNegative) ); break; default: @@ -1156,270 +1095,267 @@ 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, - m_CurrentPos, size.x, - !(m_LayerNegative ^ m_ImageNegative) ); + 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, - m_CurrentPos, size, - ( aperture == APT_RECT ) ? - S_SPOT_RECT : S_SPOT_OVALE, - !(m_LayerNegative ^ m_ImageNegative) ); + 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 ) ? + GBR_SPOT_RECT : GBR_SPOT_OVAL, + !(m_LayerNegative ^ m_ImageNegative) ); break; case APT_MACRO: + { + APERTURE_MACRO* macro = tool->GetMacro(); + wxASSERT( macro ); + + // split the macro primitives up into multiple normal GBRITEM + // elements + for( AM_PRIMITIVES::iterator p = macro->primitives.begin(); + p!=macro->primitives.end(); + ++p ) { - APERTURE_MACRO* macro = tool->GetMacro(); - wxASSERT( macro ); + bool exposure; + wxPoint curPos = m_CurrentPos; - // split the macro primitives up into multiple normal TRACK - // elements - for( AM_PRIMITIVES::iterator p = macro->primitives.begin(); - p!=macro->primitives.end(); - ++p ) + switch( p->primitive_id ) { - bool exposure; - wxPoint curPos = m_CurrentPos; + case AMP_CIRCLE: + { + exposure = mapExposure( p->GetExposure(), m_Exposure, + m_ImageNegative ); + curPos += mapPt( p->params[2].GetValue( tool ), + p->params[3].GetValue( tool ), + m_GerbMetric ); + int diameter = scale( p->params[1].GetValue( tool ), + m_GerbMetric ); - switch( p->primitive_id ) + 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; + + case AMP_LINE2: + case AMP_LINE20: + { + exposure = mapExposure( + p->GetExposure(), m_Exposure, m_ImageNegative ); + int width = scale( p->params[1].GetValue( tool ), + m_GerbMetric ); + wxPoint start = mapPt( p->params[2].GetValue( tool ), + p->params[3].GetValue( tool ), + m_GerbMetric ); + wxPoint end = mapPt( p->params[4].GetValue( tool ), + p->params[5].GetValue( tool ), + m_GerbMetric ); + + if( start.x == end.x ) { - case AMP_CIRCLE: - { - exposure = mapExposure( p->GetExposure(), m_Exposure, - m_ImageNegative ); - curPos += mapPt( p->params[2].GetValue( tool ), - p->params[3].GetValue( tool ), - m_GerbMetric ); - 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, - curPos, diameter, exposure ); - } - break; - - case AMP_LINE2: - case AMP_LINE20: - { - exposure = mapExposure( - p->GetExposure(), m_Exposure, m_ImageNegative ); - int width = scale( p->params[1].GetValue( tool ), - m_GerbMetric ); - wxPoint start = mapPt( p->params[2].GetValue( tool ), - p->params[3].GetValue( tool ), - m_GerbMetric ); - wxPoint end = mapPt( p->params[4].GetValue( tool ), - p->params[5].GetValue( tool ), - m_GerbMetric ); - - if( start.x == end.x ) - { - size.x = width; - size.y = ABS( end.y - start.y ) + 1; - } - else - { - size.x = ABS( end.x - start.x ) + 1; - size.y = width; - } - - 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, - exposure ); - } - break; - - case AMP_LINE_CENTER: - { - exposure = mapExposure( p->GetExposure(), m_Exposure, - m_ImageNegative ); - wxPoint msize = mapPt( p->params[1].GetValue( tool ), - p->params[2].GetValue( tool ), - m_GerbMetric ); - size.x = msize.x; - size.y = msize.y; - 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, - exposure ); - } - break; - - case AMP_LINE_LOWER_LEFT: - { - exposure = mapExposure( - p->GetExposure(), m_Exposure, m_ImageNegative ); - wxPoint msize = mapPt( p->params[1].GetValue( tool ), - p->params[2].GetValue( tool ), - m_GerbMetric ); - size.x = msize.x; - size.y = msize.y; - wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ), - p->params[4].GetValue( tool ), - m_GerbMetric ); - curPos += lowerLeft; - - // 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, - exposure ); - } - break; - - case AMP_THERMAL: - { - int outerDiam = scale( p->params[2].GetValue( tool ), - m_GerbMetric ); - int innerDiam = scale( p->params[3].GetValue( tool ), - m_GerbMetric ); - - curPos += mapPt( p->params[0].GetValue( tool ), - 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, - 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, - innerDiam, - ( m_LayerNegative ^ m_ImageNegative ) ); - - // @todo: draw the cross hairs, see page 23 of rs274 - // spec. this might be done with two lines, thickness - // from params[4], and drawing - // darkness "(m_LayerNegative ^ m_ImageNegative)" - } - break; - - case AMP_MOIRE: - { - curPos += mapPt( p->params[0].GetValue( tool ), - p->params[1].GetValue( tool ), - m_GerbMetric ); - - // e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0" - int outerDiam = scale( p->params[2].GetValue( tool ), - m_GerbMetric ); - int penThickness = scale( p->params[3].GetValue( tool ), - m_GerbMetric ); - int gap = scale( p->params[4].GetValue( tool ), - m_GerbMetric ); - int numCircles = (int) p->params[5].GetValue( tool ); - int crossHairThickness = - scale( p->params[6].GetValue( tool ), m_GerbMetric ); - int crossHairLength = - scale( p->params[7].GetValue( tool ), m_GerbMetric ); - - // 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 ) - { - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - fillCircularTRACK( track, 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, - curPos, - wxSize( crossHairThickness, - crossHairLength ), - S_SPOT_RECT, - !( m_LayerNegative ^ m_ImageNegative ) ); - - track = new TRACK( pcb ); - pcb->m_Track.Append( track ); - D( printf( "R:%p\n", track ); ) - - // swap x and y in wxSize() for this one - fillOvalOrRectFlashTRACK( track, dcode, activeLayer, - curPos, - wxSize( crossHairLength, - crossHairThickness ), - S_SPOT_RECT, - !( m_LayerNegative ^ m_ImageNegative ) ); - } - break; - - case AMP_OUTLINE: -#if defined(DEBUG) - { - int numPoints = (int) p->params[1].GetValue( tool ); - - printf( "AMP_OUTLINE:\n" ); - printf( " exposure: %g\n", p->params[0].GetValue( tool ) ); - printf( " # points: %d\n", numPoints ); - - // numPoints does not include the starting point, so add 1. - for( int i=0; iparams[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 ) ); - } -#endif - break; - - case AMP_POLYGON: - case AMP_EOF: - default: - - // not yet supported, waiting for you. - break; + size.x = width; + size.y = ABS( end.y - start.y ) + 1; } + else + { + size.x = ABS( end.x - start.x ) + 1; + size.y = width; + } + + wxPoint midPoint( ( start.x + end.x ) / 2, + ( start.y + end.y ) / 2 ); + curPos += midPoint; + 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; + + case AMP_LINE_CENTER: + { + exposure = mapExposure( p->GetExposure(), m_Exposure, + m_ImageNegative ); + wxPoint msize = mapPt( p->params[1].GetValue( tool ), + p->params[2].GetValue( tool ), + m_GerbMetric ); + size.x = msize.x; + size.y = msize.y; + curPos += mapPt( p->params[3].GetValue( tool ), + p->params[4].GetValue( tool ), + m_GerbMetric ); + 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; + + case AMP_LINE_LOWER_LEFT: + { + exposure = mapExposure( + p->GetExposure(), m_Exposure, m_ImageNegative ); + wxPoint msize = mapPt( p->params[1].GetValue( tool ), + p->params[2].GetValue( tool ), + m_GerbMetric ); + size.x = msize.x; + size.y = msize.y; + wxPoint lowerLeft = mapPt( p->params[3].GetValue( tool ), + p->params[4].GetValue( tool ), + m_GerbMetric ); + curPos += lowerLeft; + + // need the middle, so adjust from the lower left + curPos.y += size.y / 2; + curPos.x += size.x / 2; + 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; + + case AMP_THERMAL: + { + int outerDiam = scale( p->params[2].GetValue( tool ), + m_GerbMetric ); + int innerDiam = scale( p->params[3].GetValue( tool ), + m_GerbMetric ); + + curPos += mapPt( p->params[0].GetValue( tool ), + p->params[1].GetValue( tool ), + m_GerbMetric ); + + 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 ) ); + + 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 ) ); + + // @todo: draw the cross hairs, see page 23 of rs274 + // spec. this might be done with two lines, thickness + // from params[4], and drawing + // darkness "(m_LayerNegative ^ m_ImageNegative)" + } + break; + + case AMP_MOIRE: + { + curPos += mapPt( p->params[0].GetValue( tool ), + p->params[1].GetValue( tool ), + m_GerbMetric ); + + // e.g.: "6,0,0,0.125,.01,0.01,3,0.003,0.150,0" + int outerDiam = scale( p->params[2].GetValue( tool ), + m_GerbMetric ); + int penThickness = scale( p->params[3].GetValue( tool ), + m_GerbMetric ); + int gap = scale( p->params[4].GetValue( tool ), + m_GerbMetric ); + int numCircles = (int) p->params[5].GetValue( tool ); + int crossHairThickness = + scale( p->params[6].GetValue( tool ), m_GerbMetric ); + int crossHairLength = + scale( p->params[7].GetValue( tool ), m_GerbMetric ); + + // 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 ) + { + 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 ) ); + } + + 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 ), + GBR_SPOT_RECT, + !( m_LayerNegative ^ m_ImageNegative ) ); + + 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 + fillOvalOrRectFlashGBRITEM( gbritem, dcode, activeLayer, + curPos, + wxSize( crossHairLength, + crossHairThickness ), + GBR_SPOT_RECT, + !( m_LayerNegative ^ m_ImageNegative ) ); + } + break; + + case AMP_OUTLINE: +#if defined(DEBUG) + { + int numPoints = (int) p->params[1].GetValue( tool ); + + printf( "AMP_OUTLINE:\n" ); + printf( " exposure: %g\n", p->params[0].GetValue( tool ) ); + printf( " # points: %d\n", numPoints ); + + // numPoints does not include the starting point, so add 1. + for( int i = 0; iparams[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 ) ); + } +#endif + break; + + case AMP_POLYGON: + case AMP_EOF: + default: + + // not yet supported, waiting for you. + break; } } - break; + } + break; default: break; diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index d7c85bf06c..b60f65209d 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -448,7 +448,7 @@ bool GERBER::ExecuteRS274XCommand( int command, while( *text == ' ' ) text++; - if( *text == 'Y' ) + if( *text == 'X' ) { text++; dcode->m_Drill.y = diff --git a/gerbview/toolbars_gerber.cpp b/gerbview/toolbars_gerber.cpp index bd55e86d46..3888b01ea2 100644 --- a/gerbview/toolbars_gerber.cpp +++ b/gerbview/toolbars_gerber.cpp @@ -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(); +} + diff --git a/gerbview/tracepcb.cpp b/gerbview/tracepcb.cpp index e0a42ad821..188fef8fa6 100644 --- a/gerbview/tracepcb.cpp +++ b/gerbview/tracepcb.cpp @@ -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 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, diff --git a/gerbview/wxGerberFrame.h b/gerbview/wxGerberFrame.h index 91ce0934dd..1a2f9a6c7f 100644 --- a/gerbview/wxGerberFrame.h +++ b/gerbview/wxGerberFrame.h @@ -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 ); diff --git a/include/base_struct.h b/include/base_struct.h index b3eb1cd02f..521a82843b 100644 --- a/include/base_struct.h +++ b/include/base_struct.h @@ -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 }; diff --git a/include/class_board_item.h b/include/class_board_item.h index 7c24c1fd9c..1ad7fd54ef 100644 --- a/include/class_board_item.h +++ b/include/class_board_item.h @@ -9,18 +9,15 @@ #include -/* 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 */ }; diff --git a/include/gr_basic.h b/include/gr_basic.h index 14be00ba8e..17529c4829 100644 --- a/include/gr_basic.h +++ b/include/gr_basic.h @@ -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, diff --git a/pcbnew/class_board_item.cpp b/pcbnew/class_board_item.cpp index 7aa111036a..655a9ffe51 100644 --- a/pcbnew/class_board_item.cpp +++ b/pcbnew/class_board_item.cpp @@ -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( "??" ); }