class SEG_ZONE deprecated

This commit is contained in:
charras 2009-08-06 18:30:46 +00:00
parent 5f198fb0ee
commit e5102715e2
8 changed files with 151 additions and 64 deletions

View File

@ -4,6 +4,13 @@ KiCad ChangeLog 2009
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.
2009-aug-08 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
Work on undo/redo in pcbnew in progress.
SEG_ZONE is now deprecated.
When a zone is fille by segment, the ZONE_CONTAINER handles these segments
2009-july-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> 2009-july-29 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================ ================================================================================
++pcbnew ++pcbnew

View File

@ -8,7 +8,7 @@
#include "appl_wxstruct.h" #include "appl_wxstruct.h"
#define BUILD_VERSION "(20090729-unstable)" #define BUILD_VERSION "(20090808-unstable)"
#ifdef HAVE_SVN_VERSION #ifdef HAVE_SVN_VERSION

View File

@ -407,11 +407,10 @@ public:
/** Function Delete_Zone_Fill /** Function Delete_Zone_Fill
* Remove the zone filling which include the segment aZone, or the zone which have the given time stamp. * Remove the zone filling which include the segment aZone, or the zone which have the given time stamp.
* A zone is a group of segments which have the same TimeStamp * A zone is a group of segments which have the same TimeStamp
* @param DC = current Device Context (can be NULL)
* @param aZone = zone segment within the zone to delete. Can be NULL * @param aZone = zone segment within the zone to delete. Can be NULL
* @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL * @param aTimestamp = Timestamp for the zone to delete, used if aZone == NULL
*/ */
void Delete_Zone_Fill( wxDC* DC, SEGZONE* Track, long aTimestamp = 0 ); void Delete_Zone_Fill( SEGZONE* Track, long aTimestamp = 0 );
/** Function Delete_LastCreatedCorner /** Function Delete_LastCreatedCorner

View File

@ -27,6 +27,7 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
{ {
m_NetCode = -1; // Net number for fast comparisons m_NetCode = -1; // Net number for fast comparisons
m_CornerSelection = -1; m_CornerSelection = -1;
m_IsFilled = false; // fill status : true when the zone is filled
utility = 0; // flags used in polygon calculations utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines m_Poly = new CPolyLine(); // Outlines
@ -165,7 +166,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
return false; return false;
ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_FillMode, m_ArcToSegmentsCount, ret = fprintf( aFile, "ZOptions %d %d %c %d %d\n", m_FillMode, m_ArcToSegmentsCount,
m_Unused ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue ); m_IsFilled ? 'S' : 'F', m_ThermalReliefGapValue, m_ThermalReliefCopperBridgeValue );
if( ret < 3 ) if( ret < 3 )
return false; return false;
@ -184,17 +185,32 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
if( m_FilledPolysList.size() ) if( m_FilledPolysList.size() )
{ {
fprintf( aFile, "$POLYSCORNERS\n" ); fprintf( aFile, "$POLYSCORNERS\n" );
for( item_pos = 0; item_pos < m_FilledPolysList.size(); item_pos++ ) for( unsigned ii = 0; ii < m_FilledPolysList.size(); ii++ )
{ {
const CPolyPt* corner = &m_FilledPolysList[item_pos]; const CPolyPt* corner = &m_FilledPolysList[ii];
ret = fprintf( aFile, "%d %d %d %d\n", corner->x, corner->y, corner->end_contour, corner->utility ); ret = fprintf( aFile, "%d %d %d %d\n", corner->x, corner->y, corner->end_contour, corner->utility );
if( ret < 3 ) if( ret < 4 )
return false; return false;
} }
fprintf( aFile, "$endPOLYSCORNERS\n" ); fprintf( aFile, "$endPOLYSCORNERS\n" );
} }
// Save the filling segments list
if( m_FillSegmList.size() )
{
fprintf( aFile, "$FILLSEGMENTS\n" );
for( unsigned ii = 0; ii < m_FillSegmList.size(); ii++ )
{
ret = fprintf( aFile, "%d %d %d %d\n",
m_FillSegmList[ii].m_Start.x, m_FillSegmList[ii].m_Start.y,
m_FillSegmList[ii].m_End.x, m_FillSegmList[ii].m_End.y );
if( ret < 4 )
return false;
}
fprintf( aFile, "$endFILLSEGMENTS\n" );
}
fprintf( aFile, "$endCZONE_OUTLINE\n" ); fprintf( aFile, "$endCZONE_OUTLINE\n" );
return true; return true;
@ -308,9 +324,9 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
{ {
int fillmode = 1; int fillmode = 1;
int arcsegmentcount = 16; int arcsegmentcount = 16;
char drawopt = 'F'; char fillstate = 'F';
text = Line + 8; text = Line + 8;
ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &drawopt, ret = sscanf( text, "%d %d %c %d %d", &fillmode, &arcsegmentcount, &fillstate,
&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.
@ -321,7 +337,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
if( arcsegmentcount >= 32 ) if( arcsegmentcount >= 32 )
m_ArcToSegmentsCount = 32; m_ArcToSegmentsCount = 32;
m_Unused = 0; // Waiting for a better use m_IsFilled = fillstate == 'F' ? true : false;
} }
else if( strnicmp( Line, "ZClearance", 10 ) == 0 ) // Clearence and pad options info found else if( strnicmp( Line, "ZClearance", 10 ) == 0 ) // Clearence and pad options info found
{ {
@ -376,7 +392,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
int end_contour, utility; int end_contour, utility;
utility = 0; utility = 0;
ret = sscanf( Line, "%d %d %d %d", &corner.x, &corner.y, &end_contour, &utility ); ret = sscanf( Line, "%d %d %d %d", &corner.x, &corner.y, &end_contour, &utility );
if( ret < 3 ) if( ret < 4 )
return false; return false;
corner.end_contour = end_contour ? true : false; corner.end_contour = end_contour ? true : false;
corner.utility = utility; corner.utility = utility;
@ -384,6 +400,19 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
} }
} }
else if( strnicmp( Line, "$FILLSEGMENTS", 13) == 0 )
{
SEGMENT segm;
while( GetLine( aFile, Line, aLineNum, sizeof(Line) - 1 ) != NULL )
{
if( strnicmp( Line, "$endFILLSEGMENTS", 4 ) == 0 )
break;
ret = sscanf( Line, "%d %d %d %d", &segm.m_Start.x, &segm.m_Start.y, &segm.m_End.x, &segm.m_End.y );
if( ret < 4 )
return false;
m_FillSegmList.push_back( segm );
}
}
else if( strnicmp( Line, "$end", 4 ) == 0 ) // end of description else if( strnicmp( Line, "$end", 4 ) == 0 ) // end of description
{ {
break; break;
@ -594,6 +623,19 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel,
CornersBuffer.clear(); CornersBuffer.clear();
} }
} }
if( m_FillMode == 1 && !outline_mode ) // filled with segments
{
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
{
wxPoint start = m_FillSegmList[ic].m_Start + offset;
wxPoint end = m_FillSegmList[ic].m_End + offset;
if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
GRCSegm( &panel->m_ClipBox, DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color );
else
GRFillCSegm( &panel->m_ClipBox, DC, start.x, start.y, end.x, end.y, m_ZoneMinThickness, color );
}
}
} }
@ -962,6 +1004,11 @@ void ZONE_CONTAINER::Move( const wxPoint& offset )
corner->x += offset.x; corner->x += offset.x;
corner->y += offset.y; corner->y += offset.y;
} }
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
{
m_FillSegmList[ic].m_Start += offset;
m_FillSegmList[ic].m_End += offset;
}
} }
@ -1021,6 +1068,11 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, int angle )
corner->x = pos.x; corner->x = pos.x;
corner->y = pos.y; corner->y = pos.y;
} }
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
{
RotatePoint( &m_FillSegmList[ic].m_Start, centre, angle );
RotatePoint( &m_FillSegmList[ic].m_End, centre, angle );
}
} }
/** /**
@ -1059,6 +1111,15 @@ void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
NEGATE(corner->y); NEGATE(corner->y);
corner->y += mirror_ref.y; corner->y += mirror_ref.y;
} }
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
{
m_FillSegmList[ic].m_Start.y -= mirror_ref.y;
NEGATE(m_FillSegmList[ic].m_Start.y);
m_FillSegmList[ic].m_Start.y += mirror_ref.y;
m_FillSegmList[ic].m_End.y -= mirror_ref.y;
NEGATE(m_FillSegmList[ic].m_End.y);
m_FillSegmList[ic].m_End.y += mirror_ref.y;
}
} }
@ -1078,6 +1139,8 @@ void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
m_FillMode = src->m_FillMode; // 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() );
m_FilledPolysList = src->m_FilledPolysList;
m_FillSegmList = src->m_FillSegmList;
} }
/** /**

View File

@ -9,6 +9,20 @@
#include "gr_basic.h" #include "gr_basic.h"
#include "PolyLine.h" #include "PolyLine.h"
/* a small class used when filling areas with segments */
class SEGMENT
{
public:
wxPoint m_Start; // starting point of a segment
wxPoint m_End; // ending point of a segment
public:
SEGMENT() {}
SEGMENT( const wxPoint & aStart, const wxPoint & aEnd)
{
m_Start = aStart;
m_End = aEnd;
}
};
/************************/ /************************/
/* class ZONE_CONTAINER */ /* class ZONE_CONTAINER */
@ -33,13 +47,17 @@ public:
int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
int utility, utility2; // flags used in polygon calculations int utility, utility2; // flags used in polygon calculations
bool m_IsFilled; // true when a zone was filled, false after deleting the filled areas
std::vector <CPolyPt> m_FilledPolysList; /* set of filled polygons used to draw a zone as a filled area. std::vector <CPolyPt> m_FilledPolysList; /* set of filled polygons used to draw a zone as a filled area.
* from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole (they are all in one piece) * from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole (they are all in one piece)
* In very simple cases m_FilledPolysList is same as m_Poly * In very simple cases m_FilledPolysList is same as m_Poly
* In less simple cases (when m_Poly has holes) m_FilledPolysList is a polygon equivalent to m_Poly, without holes * In less simple cases (when m_Poly has holes) m_FilledPolysList is a polygon equivalent to m_Poly, without holes
* In complex cases an ouline decribed by m_Poly can have many filled areas * In complex cases an ouline decribed by m_Poly can have many filled areas
*/ */
int m_Unused; /* waiting for use */ std::vector <SEGMENT> m_FillSegmList; /* set of segments used to fill area, when fill zone by segment is used.
* ( m_FillMode == 1 )
* in this case segments have m_ZoneMinThickness width
*/
private: private:
int m_NetCode; // Net number for fast comparisons int m_NetCode; // Net number for fast comparisons
@ -211,7 +229,8 @@ public:
* @param aGroup = group in kbool engine (GROUP_A or GROUP_B only) * @param aGroup = group in kbool engine (GROUP_A or GROUP_B only)
* @return the corner count * @return the corner count
*/ */
int CopyPolygonsFromFilledPolysListToBoolengine( Bool_Engine* aBoolengine, GroupType aGroup = GROUP_A); int CopyPolygonsFromFilledPolysListToBoolengine( Bool_Engine* aBoolengine,
GroupType aGroup = GROUP_A );
/** /**
* Function HitTestForCorner * Function HitTestForCorner
@ -258,7 +277,7 @@ public:
* @param aFrame = reference to the main frame * @param aFrame = reference to the main frame
* @return number of segments created * @return number of segments created
*/ */
int Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame ); int Fill_Zone_Areas_With_Segments( );
/* Geometric transformations: */ /* Geometric transformations: */
@ -345,6 +364,7 @@ public:
m_Poly->AppendCorner( position.x, position.y ); m_Poly->AppendCorner( position.x, position.y );
} }
int GetHatchStyle() const int GetHatchStyle() const
{ {
return m_Poly->GetHatchStyle(); return m_Poly->GetHatchStyle();

View File

@ -554,7 +554,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
{ {
SEGZONE* zsegm = (SEGZONE*) GetCurItem(); SEGZONE* zsegm = (SEGZONE*) GetCurItem();
int netcode = zsegm->GetNet(); int netcode = zsegm->GetNet();
Delete_Zone_Fill( &dc, zsegm ); Delete_Zone_Fill( zsegm );
SetCurItem( NULL ); SetCurItem( NULL );
test_1_net_connexion( NULL, netcode ); test_1_net_connexion( NULL, netcode );
GetScreen()->SetModify(); GetScreen()->SetModify();
@ -672,7 +672,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
if( ( GetCurItem() )->Type() == TYPE_ZONE_CONTAINER ) if( ( GetCurItem() )->Type() == TYPE_ZONE_CONTAINER )
{ {
ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem(); ZONE_CONTAINER* zone_container = (ZONE_CONTAINER*) GetCurItem();
Delete_Zone_Fill( &dc, NULL, zone_container->m_TimeStamp ); Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
test_1_net_connexion( NULL, zone_container->GetNet() ); test_1_net_connexion( NULL, zone_container->GetNet() );
GetScreen()->SetModify(); GetScreen()->SetModify();
GetBoard()->DisplayInfo( this ); GetBoard()->DisplayInfo( this );
@ -1254,7 +1254,7 @@ void WinEDA_PcbFrame::RemoveStruct( BOARD_ITEM* Item, wxDC* DC )
break; break;
case TYPE_ZONE: case TYPE_ZONE:
Delete_Zone_Fill( DC, (SEGZONE*) Item ); Delete_Zone_Fill( (SEGZONE*) Item );
break; break;
case TYPE_ZONE_EDGE_CORNER: case TYPE_ZONE_EDGE_CORNER:

View File

@ -75,7 +75,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb )
AddClearanceAreasPolygonsToPolysList( aPcb ); AddClearanceAreasPolygonsToPolysList( aPcb );
if ( m_FillMode ) // if fill mode uses segments, create them: if ( m_FillMode ) // if fill mode uses segments, create them:
Fill_Zone_Areas_With_Segments( (WinEDA_PcbFrame*) aPcb->m_PcbFrame ); Fill_Zone_Areas_With_Segments( );
return count; return count;
} }
@ -87,7 +87,7 @@ static bool SortByXValues( const int& a, const int &b)
} }
/***********************************************************************************/ /***********************************************************************************/
int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame ) int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments( )
/***********************************************************************************/ /***********************************************************************************/
/** Function Fill_Zone_Areas_With_Segments() /** Function Fill_Zone_Areas_With_Segments()
@ -112,6 +112,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame )
step = max(step, 2); step = max(step, 2);
// Read all filled areas in m_FilledPolysList // Read all filled areas in m_FilledPolysList
m_FillSegmList.clear();
istart = 0; istart = 0;
int end_list = m_FilledPolysList.size()-1; int end_list = m_FilledPolysList.size()-1;
for( int ic = 0; ic <= end_list; ic++ ) for( int ic = 0; ic <= end_list; ic++ )
@ -197,14 +198,8 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame )
seg_start.y = refy; seg_start.y = refy;
seg_end.x = x_coordinates[ii+1]; seg_end.x = x_coordinates[ii+1];
seg_end.y = refy; seg_end.y = refy;
SEGZONE* segment = new SEGZONE( aFrame->GetBoard() ); SEGMENT segment( seg_start, seg_end );
segment->m_Start = seg_start; m_FillSegmList.push_back( segment );
segment->m_End = seg_end;
segment->SetNet( GetNet() );
segment->m_TimeStamp = m_TimeStamp;
segment->m_Width = m_ZoneMinThickness;
segment->SetLayer( GetLayer() );
aFrame->GetBoard()->Add( segment );
} }
} //End examine segments in one area } //End examine segments in one area
if ( error ) break; if ( error ) break;

View File

@ -92,7 +92,7 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container
/**********************************************************************************/ /**********************************************************************************/
void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestamp ) void WinEDA_PcbFrame::Delete_Zone_Fill( SEGZONE* aZone, long aTimestamp )
/**********************************************************************************/ /**********************************************************************************/
/** Function Delete_Zone_Fill /** Function Delete_Zone_Fill
@ -123,7 +123,7 @@ void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestam
} }
} }
// Now delete the outlines of the corresponding copper areas // Now delete the outlines of the corresponding copper areas (deprecated)
for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ ) for( int ii = 0; ii < GetBoard()->GetAreaCount(); ii++ )
{ {
ZONE_CONTAINER* zone = GetBoard()->GetArea( ii ); ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
@ -131,6 +131,8 @@ void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestam
{ {
modify = TRUE; modify = TRUE;
zone->m_FilledPolysList.clear(); zone->m_FilledPolysList.clear();
zone->m_FillSegmList.clear();
zone->m_IsFilled = false;
} }
} }
@ -352,7 +354,7 @@ void WinEDA_PcbFrame::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* zone_contain
DrawPanel->PostDirtyRect( zone_container->GetBoundingBox() ); DrawPanel->PostDirtyRect( zone_container->GetBoundingBox() );
if( DC ) if( DC )
{ // Remove the full zone because this is no more an area { // Remove the full zone because this is no more an area
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
zone_container->DrawFilledArea( DrawPanel, DC, GR_XOR ); zone_container->DrawFilledArea( DrawPanel, DC, GR_XOR );
} }
GetBoard()->Delete( zone_container ); GetBoard()->Delete( zone_container );
@ -827,7 +829,7 @@ void WinEDA_PcbFrame::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* zone_contai
EDA_Rect dirty = zone_container->GetBoundingBox(); EDA_Rect dirty = zone_container->GetBoundingBox();
Delete_Zone_Fill( DC, NULL, zone_container->m_TimeStamp ); // Remove fill segments Delete_Zone_Fill( NULL, zone_container->m_TimeStamp ); // Remove fill segments
if( ncont == 0 ) // This is the main outline: remove all if( ncont == 0 ) // This is the main outline: remove all
{ {
@ -905,8 +907,9 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v
int error_level = 0; int error_level = 0;
zone_container->m_FilledPolysList.clear(); zone_container->m_FilledPolysList.clear();
Delete_Zone_Fill( NULL, NULL, zone_container->m_TimeStamp ); Delete_Zone_Fill( NULL, zone_container->m_TimeStamp );
zone_container->BuildFilledPolysListData( GetBoard() ); zone_container->BuildFilledPolysListData( GetBoard() );
if ( DC ) if ( DC )
DrawPanel->Refresh(); DrawPanel->Refresh();