Loading change_log.txt +8 −0 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with email address. email address. 2008-Dec-03 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ ++pcbnew Switch to polygons in zones (old way no more supported) areas can be now filled using solid polygons, or using segments to fill areas inside polygons. results are same, but using segments can be better (faster redraw time) for polygons having a lot of segments (more than 10000) 2008-Dec-02 UPDATE Wayne Stambaugh <stambaughw@verizon.net> 2008-Dec-02 UPDATE Wayne Stambaugh <stambaughw@verizon.net> ================================================================================ ================================================================================ ++build fixes ++build fixes Loading common/gr_basic.cpp +6 −6 Original line number Original line Diff line number Diff line Loading @@ -866,7 +866,7 @@ static bool IsGRSPolyDrawable( EDA_Rect* ClipBox, int n, int* Points ) /************************************************************************/ /************************************************************************/ /* Routine to draw a new polyline and fill it if Fill, in screen space. */ /* Routine to draw a new polyline and fill it if Fill, in screen space. */ /************************************************************************/ /************************************************************************/ void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, bool Fill, int width, int Color, int BgColor ) int width, int Color, int BgColor ) { { if( !IsGRSPolyDrawable( ClipBox, n, Points ) ) if( !IsGRSPolyDrawable( ClipBox, n, Points ) ) Loading Loading @@ -898,14 +898,14 @@ void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, /* Routine to draw a new closed polyline and fill it if Fill, in screen space */ /* Routine to draw a new closed polyline and fill it if Fill, in screen space */ /******************************************************************************/ /******************************************************************************/ void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int Color, int BgColor ) bool Fill, int Color, int BgColor ) { { GRSClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); GRSClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); } } void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int startx, starty; int startx, starty; Loading Loading @@ -939,7 +939,7 @@ void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, /* Routine to draw a new polyline and fill it if Fill, in drawing space. */ /* Routine to draw a new polyline and fill it if Fill, in drawing space. */ /************************************************************************/ /************************************************************************/ void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int ii, jj; int ii, jj; Loading @@ -960,14 +960,14 @@ void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, /* Routine to draw a closed polyline and fill it if Fill, in object space */ /* Routine to draw a closed polyline and fill it if Fill, in object space */ /**************************************************************************/ /**************************************************************************/ void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int Color, int BgColor ) bool Fill, int Color, int BgColor ) { { GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); } } void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int ii, jj; int ii, jj; Loading include/gr_basic.h +5 −9 Original line number Original line Diff line number Diff line Loading @@ -96,15 +96,11 @@ void GRSMoveRel(int x, int y); void GRLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); bool Fill, int width, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int Color, int BgColor); int Fill, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRSPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); int Fill, int width, int Color, int BgColor); void GRSClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); void GRSPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); void GRSClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int width, int Color); 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, void GRFilledCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, Loading pcbnew/class_board.cpp +22 −3 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) : m_Pads = NULL; // pointeur liste d'acces aux pads m_Pads = NULL; // pointeur liste d'acces aux pads m_Ratsnest = NULL; // pointeur liste rats m_Ratsnest = NULL; // pointeur liste rats m_LocalRatsnest = NULL; // pointeur liste rats local m_LocalRatsnest = NULL; // pointeur liste rats local m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the zone contour cuurently in progress m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the zone contour currently in progress // de determination des contours de zone // de determination des contours de zone for( int layer=0; layer<NB_COPPER_LAYERS; ++layer ) for( int layer=0; layer<NB_COPPER_LAYERS; ++layer ) Loading Loading @@ -84,6 +84,13 @@ BOARD::~BOARD() m_Zone->DeleteStructList(); m_Zone->DeleteStructList(); m_Zone = 0; m_Zone = 0; while ( m_ZoneDescriptorList.size() ) { ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; Delete( area_to_remove ); } MyFree( m_Pads ); MyFree( m_Pads ); m_Pads = 0; m_Pads = 0; Loading Loading @@ -264,6 +271,18 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) } } break; break; case TYPEZONE: { // Add item to head of list (starting in m_Zone) aBoardItem->SetParent( this ); aBoardItem->SetBack( this ); // item will be the first item: back chain to the board BOARD_ITEM* next_item = m_Zone; // Remember old the first item aBoardItem->SetNext( next_item ); // Chain the new one ton the old item if( next_item ) // Back chain the old item to the new one next_item->SetBack( aBoardItem ); m_Zone = (SEGZONE*) aBoardItem; // Add to head of list } break; case TYPEMODULE: case TYPEMODULE: // this is an insert, not an append which may also be needed. // this is an insert, not an append which may also be needed. { { Loading @@ -278,7 +297,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) // other types may use linked list // other types may use linked list default: default: wxFAIL_MSG( wxT("BOARD::Add() needs work") ); wxFAIL_MSG( wxT("BOARD::Add() needs work: BOARD_ITEM type not handled") ); } } } } Loading pcbnew/class_zone.cpp +85 −55 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const if( ret < 1 ) if( ret < 1 ) return false; return false; ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_GridFillValue, m_ArcToSegmentsCount, ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_FillMode, m_ArcToSegmentsCount, m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); if( ret < 3 ) if( ret < 3 ) return false; return false; Loading @@ -176,7 +176,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const for( item_pos = 0; item_pos < m_FilledPolysList.size(); item_pos++ ) for( item_pos = 0; item_pos < m_FilledPolysList.size(); item_pos++ ) { { const CPolyPt* corner = &m_FilledPolysList[item_pos]; const CPolyPt* corner = &m_FilledPolysList[item_pos]; ret = fprintf( aFile, "%d %d %d\n", corner->x, corner->y, corner->end_contour ); ret = fprintf( aFile, "%d %d %d %d\n", corner->x, corner->y, corner->end_contour, corner->utility ); if( ret < 3 ) if( ret < 3 ) return false; return false; } } Loading Loading @@ -287,16 +287,16 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) } } if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found { { int gridsize = 50; int fillmode = 1; int arcsegmentcount = 16; int arcsegmentcount = 16; char drawopt = 'F'; char drawopt = 'F'; text = Line + 8; text = Line + 8; ret = sscanf( text, "%d %d %c %d %d", &gridsize, &arcsegmentcount, &drawopt, ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &drawopt, &m_ThermalReliefGapValue, &m_ThermalReliefCopperBridgeValue ); &m_ThermalReliefGapValue, &m_ThermalReliefCopperBridgeValue ); if( ret < 1 ) // Must find 1 or more args. if( ret < 1 ) // Must find 1 or more args. return false; return false; else else m_GridFillValue = gridsize; m_FillMode = fillmode ? 1 : 0; if( arcsegmentcount >= 32 ) if( arcsegmentcount >= 32 ) m_ArcToSegmentsCount = 32; m_ArcToSegmentsCount = 32; Loading Loading @@ -354,11 +354,13 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0 ) if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0 ) break; break; CPolyPt corner; CPolyPt corner; int itmp; int end_contour, utility; ret = sscanf( Line, "%d %d %d", &corner.x, &corner.y, &itmp ); utility = 0; ret = sscanf( Line, "%d %d %d %d", &corner.x, &corner.y, &end_contour, &utility ); if( ret < 3 ) if( ret < 3 ) return false; return false; corner.end_contour = itmp ? true : false; corner.end_contour = end_contour ? true : false; corner.utility = utility; m_FilledPolysList.push_back( corner ); m_FilledPolysList.push_back( corner ); } } } } Loading @@ -371,7 +373,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) if( !IsOnCopperLayer() ) if( !IsOnCopperLayer() ) { { m_GridFillValue = 0; m_FillMode = 0; SetNet( 0 ); SetNet( 0 ); } } Loading Loading @@ -424,6 +426,8 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG ) color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor; SetAlpha( &color, 150 ); // draw the lines // draw the lines int i_start_contour = 0; int i_start_contour = 0; for( int ic = 0; ic < GetNumCorners(); ic++ ) for( int ic = 0; ic < GetNumCorners(); ic++ ) Loading Loading @@ -452,6 +456,19 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con } } } } /* this is local class to handle 2 integers that are a corner coordinate * One could use wxPoint insteed. * However, this class has only 2 integers * if changes happen in wxPoint ( like virtual functions) they will be not suitable * So i prefer use this simple class to handle a coordinate. */ class corner_coord { public: int x; int y; }; /************************************************************************************/ /************************************************************************************/ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, Loading @@ -467,9 +484,10 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, * @param aDrawMode = GR_OR, GR_XOR, GR_COPY .. * @param aDrawMode = GR_OR, GR_XOR, GR_COPY .. */ */ { { static int* CornersBuffer = NULL; static vector < char > CornersTypeBuffer; static unsigned CornersBufferSize = 0; static vector < corner_coord > CornersBuffer; bool sketch_mode = m_DrawOptions; // false to show filled polys, true to show polygons outlines only (test and debug purposes) bool outline_mode = m_DrawOptions; // false to show filled polys, true to show polygons outlines only (test and debug purposes) if( DC == NULL ) if( DC == NULL ) return; return; Loading @@ -477,9 +495,7 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, if( !DisplayOpt.DisplayZones ) if( !DisplayOpt.DisplayZones ) return; return; unsigned imax = m_FilledPolysList.size(); if( m_FilledPolysList.size() == 0 ) // Nothing to draw if( imax == 0 ) // Nothing to draw return; return; int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; Loading Loading @@ -509,55 +525,60 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG ) color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor; // We need a buffer to store corners coordinates: SetAlpha( &color, 150 ); if( CornersBuffer == NULL ) { CornersBufferSize = imax * 4; CornersBuffer = (int*) MyMalloc( CornersBufferSize * sizeof(int) ); } if( (imax * 4) > CornersBufferSize ) CornersTypeBuffer.clear(); { CornersBuffer.clear(); CornersBufferSize = imax * 4; CornersBuffer = (int*) realloc( CornersBuffer, CornersBufferSize * sizeof(int) ); } // Draw all filled areas // Draw all filled areas int corners_count = 0; int imax = m_FilledPolysList.size() - 1; for( unsigned ic = 0, ii = 0; ic < imax; ic++ ) for( int ic = 0; ic <= imax; ic++ ) { { CPolyPt* corner = &m_FilledPolysList[ic]; CPolyPt* corner = &m_FilledPolysList[ic]; CornersBuffer[ii++] = corner->x + offset.x; corner_coord coord; CornersBuffer[ii++] = corner->y + offset.y; coord.x = corner->x + offset.x; corners_count++; coord.y = corner->y + offset.y; if( corner->end_contour ) CornersBuffer.push_back(coord); { // Draw the current filled area CornersTypeBuffer.push_back((char) corner->utility); if( sketch_mode ) if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it GRClosedPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, { /* Draw the current filled area: draw segments ouline first false, 0, color, color ); * Curiously, draw segments ouline first and after draw filled polygons else * with oulines thickness = 0 is a faster than * just draw filled polygons but with oulines thickness = m_ZoneMinThickness * So DO NOT use draw filled polygons with oulines having a thickness > 0 * Note: Extra segments ( added by kbool to joint holes with external outline) are not drawn */ { { // Draw outlines: // Draw outlines: if ( m_ZoneMinThickness > 1 ) if ( (m_ZoneMinThickness > 1) || outline_mode ) { int ilim = CornersBuffer.size()-1; for ( int is = 0, ie = ilim; is <= ilim; ie = is, is++ ) { { int ilim = corners_count * 2; int x0 = CornersBuffer[is].x; for ( int is = 0, ie = ilim-2; is < ilim; ie = is, is+=2 ) int y0 = CornersBuffer[is].y; int x1 = CornersBuffer[ie].x; int y1 = CornersBuffer[ie].y; if ( CornersTypeBuffer[ie] == 0 ) // Draw only basic outlines, not extra segments { { int x0 = CornersBuffer[is]; if( (!DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) int y0 = CornersBuffer[is+1]; GRCSegm( &panel->m_ClipBox, DC, int x1 = CornersBuffer[ie]; x0, y0, x1 , y1, int y1 = CornersBuffer[ie+1]; m_ZoneMinThickness, color ); else GRFillCSegm( &panel->m_ClipBox, DC, GRFillCSegm( &panel->m_ClipBox, DC, x0, y0, x1 , y1, x0, y0, x1 , y1, m_ZoneMinThickness, color ); m_ZoneMinThickness, color ); } } } } } // Draw areas: // Draw areas: GRPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, if( (m_FillMode == 0 ) && ! outline_mode ) GRPoly( &panel->m_ClipBox, DC, CornersBuffer.size(), (int*)&CornersBuffer[0].x, true, 0, color, color ); true, 0, color, color ); } } corners_count = 0; CornersTypeBuffer.clear(); ii = 0; CornersBuffer.clear(); } } } } } } Loading Loading @@ -884,11 +905,11 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE ); Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE ); text_pos += 6; text_pos += 6; if( m_GridFillValue ) if( m_FillMode ) msg.Printf( wxT( "%d" ), m_GridFillValue ); msg.Printf( _( "Segments" ), m_FillMode ); else else msg = _( "No Grid" ); msg = _( "Polygons" ); Affiche_1_Parametre( frame, text_pos, _( "Fill Grid" ), msg, BROWN ); Affiche_1_Parametre( frame, text_pos, _( "Fill mode" ), msg, BROWN ); // Useful for statistics : // Useful for statistics : text_pos += 9; text_pos += 9; Loading @@ -913,12 +934,21 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) */ */ void ZONE_CONTAINER::Move( const wxPoint& offset ) void ZONE_CONTAINER::Move( const wxPoint& offset ) { { /* move outlines */ for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) { { SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); } } m_Poly->Hatch(); m_Poly->Hatch(); /* move filled areas: */ for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ ) { CPolyPt* corner = &m_FilledPolysList[ic]; corner->x += offset.x; corner->y += offset.y; } } } Loading Loading @@ -1001,7 +1031,7 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src ) m_Poly->Copy( src->m_Poly ); // copy outlines m_Poly->Copy( src->m_Poly ); // copy outlines m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection m_ZoneClearance = src->m_ZoneClearance; // clearance value m_ZoneClearance = src->m_ZoneClearance; // clearance value m_GridFillValue = src->m_GridFillValue; // Grid used for filling m_FillMode = src->m_FillMode; // Grid used for filling m_PadOption = src->m_PadOption; m_PadOption = src->m_PadOption; m_Poly->SetHatch( src->m_Poly->GetHatchStyle() ); m_Poly->SetHatch( src->m_Poly->GetHatchStyle() ); } } Loading Loading
change_log.txt +8 −0 Original line number Original line Diff line number Diff line Loading @@ -5,6 +5,14 @@ Started 2007-June-11 Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with email address. email address. 2008-Dec-03 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> ================================================================================ ++pcbnew Switch to polygons in zones (old way no more supported) areas can be now filled using solid polygons, or using segments to fill areas inside polygons. results are same, but using segments can be better (faster redraw time) for polygons having a lot of segments (more than 10000) 2008-Dec-02 UPDATE Wayne Stambaugh <stambaughw@verizon.net> 2008-Dec-02 UPDATE Wayne Stambaugh <stambaughw@verizon.net> ================================================================================ ================================================================================ ++build fixes ++build fixes Loading
common/gr_basic.cpp +6 −6 Original line number Original line Diff line number Diff line Loading @@ -866,7 +866,7 @@ static bool IsGRSPolyDrawable( EDA_Rect* ClipBox, int n, int* Points ) /************************************************************************/ /************************************************************************/ /* Routine to draw a new polyline and fill it if Fill, in screen space. */ /* Routine to draw a new polyline and fill it if Fill, in screen space. */ /************************************************************************/ /************************************************************************/ void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, bool Fill, int width, int Color, int BgColor ) int width, int Color, int BgColor ) { { if( !IsGRSPolyDrawable( ClipBox, n, Points ) ) if( !IsGRSPolyDrawable( ClipBox, n, Points ) ) Loading Loading @@ -898,14 +898,14 @@ void GRSPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, /* Routine to draw a new closed polyline and fill it if Fill, in screen space */ /* Routine to draw a new closed polyline and fill it if Fill, in screen space */ /******************************************************************************/ /******************************************************************************/ void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int Color, int BgColor ) bool Fill, int Color, int BgColor ) { { GRSClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); GRSClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); } } void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int startx, starty; int startx, starty; Loading Loading @@ -939,7 +939,7 @@ void GRSClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, /* Routine to draw a new polyline and fill it if Fill, in drawing space. */ /* Routine to draw a new polyline and fill it if Fill, in drawing space. */ /************************************************************************/ /************************************************************************/ void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int ii, jj; int ii, jj; Loading @@ -960,14 +960,14 @@ void GRPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, /* Routine to draw a closed polyline and fill it if Fill, in object space */ /* Routine to draw a closed polyline and fill it if Fill, in object space */ /**************************************************************************/ /**************************************************************************/ void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int Color, int BgColor ) bool Fill, int Color, int BgColor ) { { GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); } } void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, void GRClosedPoly( EDA_Rect* ClipBox, wxDC* DC, int n, int* Points, int Fill, int width, int Color, int BgColor ) bool Fill, int width, int Color, int BgColor ) { { int ii, jj; int ii, jj; Loading
include/gr_basic.h +5 −9 Original line number Original line Diff line number Diff line Loading @@ -96,15 +96,11 @@ void GRSMoveRel(int x, int y); void GRLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRSLineRel(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int width, int Color); void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); bool Fill, int width, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int Color, int BgColor); int Fill, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); void GRClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, void GRSPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); int Fill, int width, int Color, int BgColor); void GRSClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, bool Fill, int width, int Color, int BgColor); void GRSPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); void GRSClosedPoly(EDA_Rect * ClipBox, wxDC * DC, int n, int *Points, int Fill, int width, int Color, int BgColor); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int Color); void GRCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, int width, int Color); 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, void GRFilledCircle(EDA_Rect * ClipBox, wxDC * DC, int x, int y, int r, Loading
pcbnew/class_board.cpp +22 −3 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) : m_Pads = NULL; // pointeur liste d'acces aux pads m_Pads = NULL; // pointeur liste d'acces aux pads m_Ratsnest = NULL; // pointeur liste rats m_Ratsnest = NULL; // pointeur liste rats m_LocalRatsnest = NULL; // pointeur liste rats local m_LocalRatsnest = NULL; // pointeur liste rats local m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the zone contour cuurently in progress m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the zone contour currently in progress // de determination des contours de zone // de determination des contours de zone for( int layer=0; layer<NB_COPPER_LAYERS; ++layer ) for( int layer=0; layer<NB_COPPER_LAYERS; ++layer ) Loading Loading @@ -84,6 +84,13 @@ BOARD::~BOARD() m_Zone->DeleteStructList(); m_Zone->DeleteStructList(); m_Zone = 0; m_Zone = 0; while ( m_ZoneDescriptorList.size() ) { ZONE_CONTAINER* area_to_remove = m_ZoneDescriptorList[0]; Delete( area_to_remove ); } MyFree( m_Pads ); MyFree( m_Pads ); m_Pads = 0; m_Pads = 0; Loading Loading @@ -264,6 +271,18 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) } } break; break; case TYPEZONE: { // Add item to head of list (starting in m_Zone) aBoardItem->SetParent( this ); aBoardItem->SetBack( this ); // item will be the first item: back chain to the board BOARD_ITEM* next_item = m_Zone; // Remember old the first item aBoardItem->SetNext( next_item ); // Chain the new one ton the old item if( next_item ) // Back chain the old item to the new one next_item->SetBack( aBoardItem ); m_Zone = (SEGZONE*) aBoardItem; // Add to head of list } break; case TYPEMODULE: case TYPEMODULE: // this is an insert, not an append which may also be needed. // this is an insert, not an append which may also be needed. { { Loading @@ -278,7 +297,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl ) // other types may use linked list // other types may use linked list default: default: wxFAIL_MSG( wxT("BOARD::Add() needs work") ); wxFAIL_MSG( wxT("BOARD::Add() needs work: BOARD_ITEM type not handled") ); } } } } Loading
pcbnew/class_zone.cpp +85 −55 Original line number Original line Diff line number Diff line Loading @@ -153,7 +153,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const if( ret < 1 ) if( ret < 1 ) return false; return false; ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_GridFillValue, m_ArcToSegmentsCount, ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_FillMode, m_ArcToSegmentsCount, m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); m_DrawOptions ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); if( ret < 3 ) if( ret < 3 ) return false; return false; Loading @@ -176,7 +176,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const for( item_pos = 0; item_pos < m_FilledPolysList.size(); item_pos++ ) for( item_pos = 0; item_pos < m_FilledPolysList.size(); item_pos++ ) { { const CPolyPt* corner = &m_FilledPolysList[item_pos]; const CPolyPt* corner = &m_FilledPolysList[item_pos]; ret = fprintf( aFile, "%d %d %d\n", corner->x, corner->y, corner->end_contour ); ret = fprintf( aFile, "%d %d %d %d\n", corner->x, corner->y, corner->end_contour, corner->utility ); if( ret < 3 ) if( ret < 3 ) return false; return false; } } Loading Loading @@ -287,16 +287,16 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) } } if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found if( strnicmp( Line, "ZOptions", 8 ) == 0 ) // Options info found { { int gridsize = 50; int fillmode = 1; int arcsegmentcount = 16; int arcsegmentcount = 16; char drawopt = 'F'; char drawopt = 'F'; text = Line + 8; text = Line + 8; ret = sscanf( text, "%d %d %c %d %d", &gridsize, &arcsegmentcount, &drawopt, ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &drawopt, &m_ThermalReliefGapValue, &m_ThermalReliefCopperBridgeValue ); &m_ThermalReliefGapValue, &m_ThermalReliefCopperBridgeValue ); if( ret < 1 ) // Must find 1 or more args. if( ret < 1 ) // Must find 1 or more args. return false; return false; else else m_GridFillValue = gridsize; m_FillMode = fillmode ? 1 : 0; if( arcsegmentcount >= 32 ) if( arcsegmentcount >= 32 ) m_ArcToSegmentsCount = 32; m_ArcToSegmentsCount = 32; Loading Loading @@ -354,11 +354,13 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0 ) if( strnicmp( Line, "$endPOLYSCORNERS", 4 ) == 0 ) break; break; CPolyPt corner; CPolyPt corner; int itmp; int end_contour, utility; ret = sscanf( Line, "%d %d %d", &corner.x, &corner.y, &itmp ); utility = 0; ret = sscanf( Line, "%d %d %d %d", &corner.x, &corner.y, &end_contour, &utility ); if( ret < 3 ) if( ret < 3 ) return false; return false; corner.end_contour = itmp ? true : false; corner.end_contour = end_contour ? true : false; corner.utility = utility; m_FilledPolysList.push_back( corner ); m_FilledPolysList.push_back( corner ); } } } } Loading @@ -371,7 +373,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum ) if( !IsOnCopperLayer() ) if( !IsOnCopperLayer() ) { { m_GridFillValue = 0; m_FillMode = 0; SetNet( 0 ); SetNet( 0 ); } } Loading Loading @@ -424,6 +426,8 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG ) color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor; SetAlpha( &color, 150 ); // draw the lines // draw the lines int i_start_contour = 0; int i_start_contour = 0; for( int ic = 0; ic < GetNumCorners(); ic++ ) for( int ic = 0; ic < GetNumCorners(); ic++ ) Loading Loading @@ -452,6 +456,19 @@ void ZONE_CONTAINER::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, con } } } } /* this is local class to handle 2 integers that are a corner coordinate * One could use wxPoint insteed. * However, this class has only 2 integers * if changes happen in wxPoint ( like virtual functions) they will be not suitable * So i prefer use this simple class to handle a coordinate. */ class corner_coord { public: int x; int y; }; /************************************************************************************/ /************************************************************************************/ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, Loading @@ -467,9 +484,10 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, * @param aDrawMode = GR_OR, GR_XOR, GR_COPY .. * @param aDrawMode = GR_OR, GR_XOR, GR_COPY .. */ */ { { static int* CornersBuffer = NULL; static vector < char > CornersTypeBuffer; static unsigned CornersBufferSize = 0; static vector < corner_coord > CornersBuffer; bool sketch_mode = m_DrawOptions; // false to show filled polys, true to show polygons outlines only (test and debug purposes) bool outline_mode = m_DrawOptions; // false to show filled polys, true to show polygons outlines only (test and debug purposes) if( DC == NULL ) if( DC == NULL ) return; return; Loading @@ -477,9 +495,7 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, if( !DisplayOpt.DisplayZones ) if( !DisplayOpt.DisplayZones ) return; return; unsigned imax = m_FilledPolysList.size(); if( m_FilledPolysList.size() == 0 ) // Nothing to draw if( imax == 0 ) // Nothing to draw return; return; int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; int curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer; Loading Loading @@ -509,55 +525,60 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel, if( color & HIGHT_LIGHT_FLAG ) if( color & HIGHT_LIGHT_FLAG ) color = ColorRefs[color & MASKCOLOR].m_LightColor; color = ColorRefs[color & MASKCOLOR].m_LightColor; // We need a buffer to store corners coordinates: SetAlpha( &color, 150 ); if( CornersBuffer == NULL ) { CornersBufferSize = imax * 4; CornersBuffer = (int*) MyMalloc( CornersBufferSize * sizeof(int) ); } if( (imax * 4) > CornersBufferSize ) CornersTypeBuffer.clear(); { CornersBuffer.clear(); CornersBufferSize = imax * 4; CornersBuffer = (int*) realloc( CornersBuffer, CornersBufferSize * sizeof(int) ); } // Draw all filled areas // Draw all filled areas int corners_count = 0; int imax = m_FilledPolysList.size() - 1; for( unsigned ic = 0, ii = 0; ic < imax; ic++ ) for( int ic = 0; ic <= imax; ic++ ) { { CPolyPt* corner = &m_FilledPolysList[ic]; CPolyPt* corner = &m_FilledPolysList[ic]; CornersBuffer[ii++] = corner->x + offset.x; corner_coord coord; CornersBuffer[ii++] = corner->y + offset.y; coord.x = corner->x + offset.x; corners_count++; coord.y = corner->y + offset.y; if( corner->end_contour ) CornersBuffer.push_back(coord); { // Draw the current filled area CornersTypeBuffer.push_back((char) corner->utility); if( sketch_mode ) if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it GRClosedPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, { /* Draw the current filled area: draw segments ouline first false, 0, color, color ); * Curiously, draw segments ouline first and after draw filled polygons else * with oulines thickness = 0 is a faster than * just draw filled polygons but with oulines thickness = m_ZoneMinThickness * So DO NOT use draw filled polygons with oulines having a thickness > 0 * Note: Extra segments ( added by kbool to joint holes with external outline) are not drawn */ { { // Draw outlines: // Draw outlines: if ( m_ZoneMinThickness > 1 ) if ( (m_ZoneMinThickness > 1) || outline_mode ) { int ilim = CornersBuffer.size()-1; for ( int is = 0, ie = ilim; is <= ilim; ie = is, is++ ) { { int ilim = corners_count * 2; int x0 = CornersBuffer[is].x; for ( int is = 0, ie = ilim-2; is < ilim; ie = is, is+=2 ) int y0 = CornersBuffer[is].y; int x1 = CornersBuffer[ie].x; int y1 = CornersBuffer[ie].y; if ( CornersTypeBuffer[ie] == 0 ) // Draw only basic outlines, not extra segments { { int x0 = CornersBuffer[is]; if( (!DisplayOpt.DisplayPcbTrackFill) || GetState( FORCE_SKETCH ) ) int y0 = CornersBuffer[is+1]; GRCSegm( &panel->m_ClipBox, DC, int x1 = CornersBuffer[ie]; x0, y0, x1 , y1, int y1 = CornersBuffer[ie+1]; m_ZoneMinThickness, color ); else GRFillCSegm( &panel->m_ClipBox, DC, GRFillCSegm( &panel->m_ClipBox, DC, x0, y0, x1 , y1, x0, y0, x1 , y1, m_ZoneMinThickness, color ); m_ZoneMinThickness, color ); } } } } } // Draw areas: // Draw areas: GRPoly( &panel->m_ClipBox, DC, corners_count, CornersBuffer, if( (m_FillMode == 0 ) && ! outline_mode ) GRPoly( &panel->m_ClipBox, DC, CornersBuffer.size(), (int*)&CornersBuffer[0].x, true, 0, color, color ); true, 0, color, color ); } } corners_count = 0; CornersTypeBuffer.clear(); ii = 0; CornersBuffer.clear(); } } } } } } Loading Loading @@ -884,11 +905,11 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE ); Affiche_1_Parametre( frame, text_pos, _( "Corners" ), msg, BLUE ); text_pos += 6; text_pos += 6; if( m_GridFillValue ) if( m_FillMode ) msg.Printf( wxT( "%d" ), m_GridFillValue ); msg.Printf( _( "Segments" ), m_FillMode ); else else msg = _( "No Grid" ); msg = _( "Polygons" ); Affiche_1_Parametre( frame, text_pos, _( "Fill Grid" ), msg, BROWN ); Affiche_1_Parametre( frame, text_pos, _( "Fill mode" ), msg, BROWN ); // Useful for statistics : // Useful for statistics : text_pos += 9; text_pos += 9; Loading @@ -913,12 +934,21 @@ void ZONE_CONTAINER::Display_Infos( WinEDA_DrawFrame* frame ) */ */ void ZONE_CONTAINER::Move( const wxPoint& offset ) void ZONE_CONTAINER::Move( const wxPoint& offset ) { { /* move outlines */ for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) { { SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); } } m_Poly->Hatch(); m_Poly->Hatch(); /* move filled areas: */ for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ ) { CPolyPt* corner = &m_FilledPolysList[ic]; corner->x += offset.x; corner->y += offset.y; } } } Loading Loading @@ -1001,7 +1031,7 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src ) m_Poly->Copy( src->m_Poly ); // copy outlines m_Poly->Copy( src->m_Poly ); // copy outlines m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection m_CornerSelection = -1; // For corner moving, corner index to drag, or -1 if no selection m_ZoneClearance = src->m_ZoneClearance; // clearance value m_ZoneClearance = src->m_ZoneClearance; // clearance value m_GridFillValue = src->m_GridFillValue; // Grid used for filling m_FillMode = src->m_FillMode; // Grid used for filling m_PadOption = src->m_PadOption; m_PadOption = src->m_PadOption; m_Poly->SetHatch( src->m_Poly->GetHatchStyle() ); m_Poly->SetHatch( src->m_Poly->GetHatchStyle() ); } } Loading