diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e1bf9f1bd7..d7cd1b9a66 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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> diff --git a/TODO.txt b/TODO.txt index b2d41ec5f5..dfa64c5c56 100644 --- a/TODO.txt +++ b/TODO.txt @@ -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 diff --git a/common/base_screen.cpp b/common/base_screen.cpp index b2aceb5bd4..3e0b70a0c0 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -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 ); } diff --git a/gerbview/gerbview.h b/gerbview/gerbview.h index 73c26873a7..8500f9ac28 100644 --- a/gerbview/gerbview.h +++ b/gerbview/gerbview.h @@ -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 diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 2abed1888c..91588aa4eb 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -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; diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index 0d84106388..05bb428557 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -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; diff --git a/gerbview/tracepcb.cpp b/gerbview/tracepcb.cpp index 087b04d732..0f4b375902 100644 --- a/gerbview/tracepcb.cpp +++ b/gerbview/tracepcb.cpp @@ -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; + 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; + 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; + m_PrintIsMirrored = aPrintMirrorMode; - ( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer ); + ( (WinEDA_GerberFrame*) m_Parent )->Trace_Gerber( DC, GR_COPY, printmasklayer ); - if( Print_Sheet_Ref ) - m_Parent->TraceWorkSheet( DC, GetScreen(), 0 ); + if( Print_Sheet_Ref ) + m_Parent->TraceWorkSheet( DC, GetScreen(), 0 ); - m_PrintIsMirrored = false; + m_PrintIsMirrored = false; - DisplayOpt = save_opt; - g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg; + 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; + points.reserve(10000); - if( track->GetNet() == 0 ) // StartPoint - { - if( coords.size() ) // we have found a new polygon: Draw the old polygon - { - int Color; - int filled; - + 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 ); - } + GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[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 ); - } + erase = ( track->m_Flags & DRAW_ERASED ); - if( track->Next() == NULL ) // Last point - { - int Color = g_DesignSettings.m_LayerColor[track->GetLayer()]; - int filled = (g_DisplayPolygonsModeSketch == 0) ? 1 : 0; + points.clear(); + points.push_back( track->m_Start ); + points.push_back( track->m_End ); + } + else + { + points.push_back( track->m_End ); + } - GRClosedPoly( &DrawPanel->m_ClipBox, DC, coords.size(), &coords[0], - filled, Color, Color ); - } - } + 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); + } - // 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 ); + GRClosedPoly( &DrawPanel->m_ClipBox, DC, points.size(), &points[0], + filled, Color, Color ); + } + } - if( DisplayOpt.DisplayPadNum ) - Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY ); + // 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 ); - GetScreen()->ClrRefreshReq(); + if( DisplayOpt.DisplayPadNum ) + Affiche_DCodes_Pistes( DrawPanel, DC, m_Pcb, GR_COPY ); + + GetScreen()->ClrRefreshReq(); } diff --git a/include/gr_basic.h b/include/gr_basic.h index cba141a70f..7f047dcc99 100644 --- a/include/gr_basic.h +++ b/include/gr_basic.h @@ -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 */