Commit 8d4a9b51 authored by dickelbeck's avatar dickelbeck

gerbview polygon erasures added, comment tweaks

parent 0d790e57
......@@ -13,8 +13,10 @@ email address.
polygon code to use wxPoints since that is what the underlying wxWidgets
API uses.
++gerbview
More work on drawing polygons, erasure still work in progress. Will
probably switch to ZONEs from SEG_ZONEs for polygons.
* More work on drawing polygons, erasure of polygons completed.
* Added full support for aperture macro 6, MOIRE.
* Example 2 in RS274xrevd_e.pdf almost draws properly now. Need ARC support
in polygons, and need polygon aperture type support to complete.
2008-Dec-28 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
......
......@@ -38,6 +38,10 @@ asked by: Dick Hollenbeck
4) Expose layer name editing in pcbnew (anyone), should dove tail with net
class editor from a UI perspective.
** Should probably switch gerbview to use ZONE instead of SEGZONE for polygons.
** Need to add ARC support to gerber polygons.
** Need to add polygon aperture type. Then example 2 in RS274xrevd_e.pdf will draw properly.
2008-Feb-8 Assigned To: dick
asked by: dick
......
......@@ -311,8 +311,7 @@ void BASE_SCREEN::AddGrid( const GRID_TYPE& grid )
}
}
wxLogDebug( wxT( "Adding grid ID %d size( %d, %d ) to grid list." ),
grid.m_Id, grid.m_Size.x, grid.m_Size.y );
// wxLogDebug( wxT( "Adding grid ID %d size( %d, %d ) to grid list." ), grid.m_Id, grid.m_Size.x, grid.m_Size.y );
m_GridList.Add( grid );
}
......
......@@ -108,8 +108,9 @@ 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 either a constant or a place holder for a DCODE
* parameter.
* 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 paramters.
*/
class DCODE_PARAM
{
......@@ -145,7 +146,7 @@ public:
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 the value, else not used.
double value; ///< if IsImmediate()==true then use the value, else not used.
};
......@@ -378,8 +379,8 @@ public:
char*& text, int D_commande );
/**
* size of single line of a text line from a gerber file.
* warning: some files can have very long lines, so the buffer must be large
* size of single line of a text from a gerber file.
* warning: some files can have very long lines, so the buffer must be large.
*/
#define GERBER_BUFZ 4000
......
......@@ -238,43 +238,31 @@ static void fillLineTRACK( TRACK* aTrack, int Dcode_index, int aLayer,
}
#if 0 // @todo get it into the doxygen function comment for fillArcTRACK below
/*****************************************************************/
static void Append_1_SEG_ARC_GERBER( int Dcode_index,
WinEDA_GerberFrame* frame, wxDC* DC,
const wxPoint& startpoint, const wxPoint& endpoint,
const wxPoint& rel_center, int largeur,
bool trigo_sens, bool multiquadrant, bool isDark )
/*****************************************************************/
/*
* Creates an arc:
* if multiquadrant == true : arc can be 0 to 360 degres
* and rel_center is the center coordiante relative to startpoint.
*
* if multiquadrant == false arc can be only 0 to 90 deg,
* and only in the same quadrant :
* absolute angle 0 to 90 (quadrant 1) or
* absolute angle 90 to 180 (quadrant 2) or
* absolute angle 180 to 270 (quadrant 3) or
* absolute angle 270 to 0 (quadrant 4)
* rel_center is the center coordiante relative to startpoint,
* given in ABSOLUE VALUE and the signe of values x et y de rel_center
* must be calculated from the previously given constraint: arc only in the same quadrant
*/
#endif
/**
* Function fillArcTRACK
* initializes a given TRACK so that it can draw an arc G code.
*
* @param aTrack The TRACK to fill in.
* @param Dcode_index The DCODE value, like D14
* @param aLayer The layer index to set into the TRACK
* @param aPos The center point of the flash
* <p>
* if multiquadrant == true : arc can be 0 to 360 degres
* and \a rel_center is the center coordiante relative to startpoint.
* <p>
* if multiquadrant == false arc can be only 0 to 90 deg,
* and only in the same quadrant :
* <ul>
* <li> absolute angle 0 to 90 (quadrant 1) or
* <li> absolute angle 90 to 180 (quadrant 2) or
* <li> absolute angle 180 to 270 (quadrant 3) or
* <li> absolute angle 270 to 0 (quadrant 4)
* </ul><p>
* @param aTrack is the TRACK to fill in.
* @param Dcode_index is the DCODE value, like D14
* @param aLayer is the layer index to set into the TRACK
* @param aStart is the starting point
* @param aEnd is the ending point
* @param rel_center is the center coordiante relative to startpoint,
* given in ABSOLUE VALUE and the signe of values x et y de rel_center
* must be calculated from the previously given constraint: arc only in the same quadrant.
* @param aDiameter The diameter of the round flash
* @param aWidth is the pen width.
* @param isDark True if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
......@@ -682,8 +670,9 @@ int GERBER::ReturnDCodeNumber( char*& Text )
/******************************************************************/
bool GERBER::Execute_G_Command( char*& text, int G_commande )
/******************************************************************/
{
D(printf( "%22s: G_CODE<%d>\n", __func__, G_commande );)
switch( G_commande )
{
case GC_PHOTO_MODE: // can starts a D03 flash command: redundant, can be safely ignored
......@@ -858,6 +847,8 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
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) )
......@@ -890,15 +881,15 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
edge_poly->SetLayer( activeLayer );
edge_poly->m_Width = 1;
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 );
// the first track of each polygon has a netcode of zero, otherwise one.
// set the erasure flag in that special track, if a negative polygon.
if( !m_PolygonFillModeState )
......@@ -907,7 +898,7 @@ bool GERBER::Execute_DCODE_Command( WinEDA_GerberFrame* frame, wxDC* DC,
edge_poly->m_Flags |= DRAW_ERASED;
D(printf("\nm_Flags=0x%08X\n", edge_poly->m_Flags );)
}
m_PreviousPos = m_CurrentPos;
m_PolygonFillModeState = 1;
break;
......
......@@ -47,7 +47,7 @@ enum RS274X_PARAMETERS
/**
* Function ReadXCommand
* reads int two bytes of data and assembles them into an int with the first
* reads in two bytes of data and assembles them into an int with the first
* byte in the sequence put into the most significant part of a 16 bit value
* and the second byte put into the least significant part of the 16 bit value.
* @param text A reference to a pointer to read bytes from and to advance as they are read.
......@@ -177,7 +177,7 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
double fcoord;
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT;
//D(printf( "%s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF );)
D(printf( "%22s: Command <%c%c>\n", __func__, (command >> 8) & 0xFF, command & 0xFF );)
switch( command )
{
......@@ -311,28 +311,18 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
case IMAGE_POLARITY:
if( strnicmp( text, "NEG", 3 ) == 0 )
{
D(printf("%s: m_ImageNegative=true\n", __func__);)
m_ImageNegative = TRUE;
}
m_ImageNegative = true;
else
{
D(printf("%s: m_ImageNegative=false\n", __func__);)
m_ImageNegative = FALSE;
}
m_ImageNegative = false;
D(printf("%22s: IMAGE_POLARITY m_ImageNegative=%s\n", __func__, m_ImageNegative ? "true" : "false");)
break;
case LAYER_POLARITY:
if( *text == 'C' )
{
D(printf("%s: m_LayerNegative=true\n", __func__);)
m_LayerNegative = TRUE;
}
m_LayerNegative = true;
else
{
D(printf("%s: m_LayerNegative=false\n", __func__);)
m_LayerNegative = FALSE;
}
m_LayerNegative = false;
D(printf("%22s: LAYER_POLARITY m_LayerNegative=%s\n", __func__, m_LayerNegative ? "true" : "false");)
break;
case INCLUDE_FILE:
......@@ -366,7 +356,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
break;
case AP_DEFINITION:
// input example: %ADD30R,0.081800X0.101500*%
// at this point, text points to 2nd 'D'
......@@ -501,9 +490,6 @@ bool GERBER::ExecuteRS274XCommand( int command, char buff[GERBER_BUFZ], char*& t
}
dcode->m_Shape = APT_MACRO;
D(printf("pam has %d parameters\n", pam->primitives.size() );)
dcode->SetMacro( (APERTURE_MACRO*) pam );
}
break;
......
......@@ -28,37 +28,37 @@ void WinEDA_DrawPanel::PrintPage( wxDC* DC, bool Print_Sheet_Ref, int printmaskl
/* Draw gerbview layers, for printing
*/
{
DISPLAY_OPTIONS save_opt;
int DisplayPolygonsModeImg;
save_opt = DisplayOpt;
if( printmasklayer & ALL_CU_LAYERS )
DisplayOpt.DisplayPadFill = FILLED;
else
DisplayOpt.DisplayPadFill = SKETCH;
DisplayOpt.DisplayPadNum = 0;
DisplayOpt.DisplayPadNoConn = 0;
DisplayOpt.DisplayPadIsol = 0;
DisplayOpt.DisplayModEdge = FILLED;
DisplayOpt.DisplayModText = FILLED;
DisplayOpt.DisplayPcbTrackFill = FILLED;
DisplayOpt.DisplayTrackIsol = 0;
DisplayOpt.DisplayDrawItems = FILLED;
DisplayOpt.DisplayZonesMode = 0;
DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
g_DisplayPolygonsModeSketch = 0;
m_PrintIsMirrored = aPrintMirrorMode;
( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer );
if( Print_Sheet_Ref )
m_Parent->TraceWorkSheet( DC, GetScreen(), 0 );
m_PrintIsMirrored = false;
DisplayOpt = save_opt;
g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg;
DISPLAY_OPTIONS save_opt;
int DisplayPolygonsModeImg;
save_opt = DisplayOpt;
if( printmasklayer & ALL_CU_LAYERS )
DisplayOpt.DisplayPadFill = FILLED;
else
DisplayOpt.DisplayPadFill = SKETCH;
DisplayOpt.DisplayPadNum = 0;
DisplayOpt.DisplayPadNoConn = 0;
DisplayOpt.DisplayPadIsol = 0;
DisplayOpt.DisplayModEdge = FILLED;
DisplayOpt.DisplayModText = FILLED;
DisplayOpt.DisplayPcbTrackFill = FILLED;
DisplayOpt.DisplayTrackIsol = 0;
DisplayOpt.DisplayDrawItems = FILLED;
DisplayOpt.DisplayZonesMode = 0;
DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
g_DisplayPolygonsModeSketch = 0;
m_PrintIsMirrored = aPrintMirrorMode;
( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer );
if( Print_Sheet_Ref )
m_Parent->TraceWorkSheet( DC, GetScreen(), 0 );
m_PrintIsMirrored = false;
DisplayOpt = save_opt;
g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg;
}
......@@ -69,31 +69,31 @@ void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
/* Trace le PCB, et les elements complementaires ( axes, grille .. )
*/
{
PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();
PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen();
if( !m_Pcb )
return;
ActiveScreen = screen;
GRSetDrawMode( DC, GR_COPY );
if( !m_Pcb )
return;
ActiveScreen = screen;
GRSetDrawMode( DC, GR_COPY );
if( EraseBg )
DrawPanel->EraseScreen( DC );
if( EraseBg )
DrawPanel->EraseScreen( DC );
DrawPanel->DrawBackGround( DC );
DrawPanel->DrawBackGround( DC );
Trace_Gerber( DC, GR_COPY, -1 );
TraceWorkSheet( DC, screen, 0 );
Affiche_Status_Box();
Trace_Gerber( DC, GR_COPY, -1 );
TraceWorkSheet( DC, screen, 0 );
Affiche_Status_Box();
if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
if( DrawPanel->ManageCurseur )
DrawPanel->ManageCurseur( DrawPanel, DC, FALSE );
DrawPanel->Trace_Curseur( DC );
DrawPanel->Trace_Curseur( DC );
}
/********************************************************************/
void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* DC,
int aDrawMode, const wxPoint& offset )
int aDrawMode, const wxPoint& offset )
/********************************************************************/
/* Redraw the BOARD items but not cursors, axis or grid */
// @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function
......@@ -110,72 +110,77 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* DC, int draw_mode, int printmasklay
* @param printmasklayer = mask for allowed layer (=-1 to draw all layers)
*/
{
if( !m_Pcb )
return;
if( !m_Pcb )
return;
bool erase;
// Draw filled polygons
std::vector<wxPoint> coords;
int Color;
bool filled;
// Draw filled polygons
std::vector<wxPoint> points;
// minimize reallocations of the vector's internal array by starting with a good sized one.
coords.reserve(20000);
for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() )
{
if( !(track->ReturnMaskLayer() & printmasklayer) )
continue;
if( track->GetNet() == 0 ) // StartPoint
{
if( coords.size() ) // we have found a new polygon: Draw the old polygon
{
int Color;
int filled;
points.reserve(10000);
for( TRACK* track = m_Pcb->m_Zone; track; track = track->Next() )
{
if( !(track->ReturnMaskLayer() & printmasklayer) )
continue;
if( track->GetNet() == 0 ) // StartPoint
{
if( points.size() ) // we have found a new polygon: Draw the old polygon
{
if( erase )
{
D(printf("erase\n");)
Color = g_DrawBgColor;
filled = true;
}
else
{
D(printf("NO erase\n");)
Color = g_DesignSettings.m_LayerColor[track->GetLayer()];
filled = (g_DisplayPolygonsModeSketch == 0) ? 1 : 0;
filled = (g_DisplayPolygonsModeSketch == 0);
}
GRClosedPoly( &DrawPanel->m_ClipBox, DC, coords.size(), &coords[0],
filled, Color, Color );
}
erase = ( track->m_Flags & DRAW_ERASED ) ? true : false;
coords.clear();
coords.push_back( track->m_Start );
coords.push_back( track->m_End );
}
else
{
coords.push_back( track->m_End );
}
if( track->Next() == NULL ) // Last point
{
int Color = g_DesignSettings.m_LayerColor[track->GetLayer()];
int filled = (g_DisplayPolygonsModeSketch == 0) ? 1 : 0;
GRClosedPoly( &DrawPanel->m_ClipBox, DC, coords.size(), &coords[0],
filled, Color, Color );
}
}
// Draw tracks and flashes down here. This will probably not be a final solution to drawing order issues
Draw_Track_Buffer( DrawPanel, DC, m_Pcb, draw_mode, printmasklayer );
if( DisplayOpt.DisplayPadNum )
Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY );
GetScreen()->ClrRefreshReq();
GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
filled, Color, Color );
}
erase = ( track->m_Flags & DRAW_ERASED );
points.clear();
points.push_back( track->m_Start );
points.push_back( track->m_End );
}
else
{
points.push_back( track->m_End );
}
if( track->Next() == NULL ) // Last point
{
if( erase )
{
Color = g_DrawBgColor;
filled = true;
}
else
{
Color = g_DesignSettings.m_LayerColor[track->GetLayer()];
filled = (g_DisplayPolygonsModeSketch == 0);
}
GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0],
filled, Color, Color );
}
}
// Draw tracks and flashes down here. This will probably not be a final solution to drawing order issues
Draw_Track_Buffer( DrawPanel, DC, m_Pcb, draw_mode, printmasklayer );
if( DisplayOpt.DisplayPadNum )
Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY );
GetScreen()->ClrRefreshReq();
}
......@@ -140,7 +140,7 @@ void GRClosedPoly(EDA_Rect * ClipBox, wxDC* aDC, int aPointCount, wxPoint aPoint
* @param aDC the device context into which drawing should occur.
* @param x The x coordinate in user space of the center of the circle.
* @param x The y coordinate in user space of the center of the circle.
* @param aRadius is the radis of the circle.
* @param aRadius is the radius of the circle.
* @param aColor is an index into our color table of RGB colors.
* @see EDA_Colors and colors.h
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment