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
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>
================================================================================
++pcbnew

View File

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

View File

@ -407,11 +407,10 @@ public:
/** Function Delete_Zone_Fill
* 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
* @param DC = current Device Context (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
*/
void Delete_Zone_Fill( wxDC* DC, SEGZONE* Track, long aTimestamp = 0 );
void Delete_Zone_Fill( SEGZONE* Track, long aTimestamp = 0 );
/** Function Delete_LastCreatedCorner

View File

@ -25,11 +25,12 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* parent ) :
BOARD_ITEM( parent, TYPE_ZONE_CONTAINER )
{
m_NetCode = -1; // Net number for fast comparisons
m_NetCode = -1; // Net number for fast comparisons
m_CornerSelection = -1;
utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines
m_IsFilled = false; // fill status : true when the zone is filled
utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines
g_Zone_Default_Setting.ExportSetting(*this);
}
@ -165,7 +166,7 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
return false;
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 )
return false;
@ -184,17 +185,32 @@ bool ZONE_CONTAINER::Save( FILE* aFile ) const
if( m_FilledPolysList.size() )
{
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 );
if( ret < 3 )
if( ret < 4 )
return false;
}
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" );
return true;
@ -308,9 +324,9 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
{
int fillmode = 1;
int arcsegmentcount = 16;
char drawopt = 'F';
char fillstate = 'F';
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 );
if( ret < 1 ) // Must find 1 or more args.
@ -321,7 +337,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
if( arcsegmentcount >= 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
{
@ -376,7 +392,7 @@ int ZONE_CONTAINER::ReadDescr( FILE* aFile, int* aLineNum )
int end_contour, utility;
utility = 0;
ret = sscanf( Line, "%d %d %d %d", &corner.x, &corner.y, &end_contour, &utility );
if( ret < 3 )
if( ret < 4 )
return false;
corner.end_contour = end_contour ? true : false;
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
{
break;
@ -594,6 +623,19 @@ void ZONE_CONTAINER::DrawFilledArea( WinEDA_DrawPanel* panel,
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->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->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);
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_PadOption = src->m_PadOption;
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 "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 */
@ -33,28 +47,32 @@ public:
int m_ThermalReliefGapValue; // tickness of the gap in thermal reliefs
int m_ThermalReliefCopperBridgeValue; // tickness of the copper bridge in thermal reliefs
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.
* 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 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
*/
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:
int m_NetCode; // Net number for fast comparisons
int m_ZoneSubnet; // variable used in rastnest computations:handle block number in zone connection calculations
int m_NetCode; // Net number for fast comparisons
int m_ZoneSubnet; // variable used in rastnest computations:handle block number in zone connection calculations
public:
ZONE_CONTAINER( BOARD* parent );
~ZONE_CONTAINER();
bool Save( FILE* aFile ) const;
int ReadDescr( FILE* aFile, int* aLineNum = NULL );
bool Save( FILE* aFile ) const;
int ReadDescr( FILE* aFile, int* aLineNum = NULL );
/** virtual function GetPosition
* @return a wxPoint, position of the first point of the outline
*/
* @return a wxPoint, position of the first point of the outline
*/
wxPoint& GetPosition();
@ -63,9 +81,9 @@ public:
* copy usefull data from the source.
* flags and linked list pointers are NOT copied
*/
void Copy( ZONE_CONTAINER* src );
void Copy( ZONE_CONTAINER* src );
void DisplayInfo( WinEDA_DrawFrame* frame );
void DisplayInfo( WinEDA_DrawFrame* frame );
/**
* Function Draw
@ -75,10 +93,10 @@ public:
* @param offset = Draw offset (usually wxPoint(0,0))
* @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
*/
void Draw( WinEDA_DrawPanel* panel,
wxDC* DC,
int aDrawMode,
const wxPoint& offset = ZeroOffset );
void Draw( WinEDA_DrawPanel* panel,
wxDC* DC,
int aDrawMode,
const wxPoint& offset = ZeroOffset );
/**
* Function DrawDrawFilledArea
@ -88,10 +106,10 @@ public:
* @param offset = Draw offset (usually wxPoint(0,0))
* @param aDrawMode = GR_OR, GR_XOR, GR_COPY ..
*/
void DrawFilledArea( WinEDA_DrawPanel* panel,
wxDC* DC,
int aDrawMode,
const wxPoint& offset = ZeroOffset );
void DrawFilledArea( WinEDA_DrawPanel* panel,
wxDC* DC,
int aDrawMode,
const wxPoint& offset = ZeroOffset );
/**
* Function DrawWhileCreateOutline
@ -115,7 +133,7 @@ public:
* Remove insulated copper islands found in m_FilledPolysList.
* @param aPcb = the board to analyse
*/
void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb );
void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb );
/** function CalculateSubAreaBoundaryBox
* Calculates the bounding box of a a filled area ( list of CPolyPt )
@ -156,7 +174,7 @@ public:
* Fin the nat name corresponding to the net code.
* @return bool - true if net found, else false
*/
bool SetNetNameFromNetCode( void);
bool SetNetNameFromNetCode( void );
/**
* Function HitTest
@ -173,7 +191,7 @@ public:
* @param aRefPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTestFilledArea( const wxPoint& aRefPos );
bool HitTestFilledArea( const wxPoint& aRefPos );
/** function BuildFilledPolysListData
* Build m_FilledPolysList data from real outlines (m_Poly)
@ -202,18 +220,19 @@ public:
* Copy (Add) polygons created by kbool (after Do_Operation) to m_FilledPolysList
* @param aBoolengine = the kbool engine used in Do_Operation
* @return the corner count
*/
int CopyPolygonsFromBoolengineToFilledPolysList( Bool_Engine* aBoolengine );
*/
int CopyPolygonsFromBoolengineToFilledPolysList( Bool_Engine* aBoolengine );
/** Function CopyPolygonsFromFilledPolysListToBoolengine
* Copy (Add) polygons created by kbool (after Do_Operation) to m_FilledPolysList
* @param aBoolengine = kbool engine
* @param aGroup = group in kbool engine (GROUP_A or GROUP_B only)
* @return the corner count
*/
int CopyPolygonsFromFilledPolysListToBoolengine( Bool_Engine* aBoolengine, GroupType aGroup = GROUP_A);
*/
int CopyPolygonsFromFilledPolysListToBoolengine( Bool_Engine* aBoolengine,
GroupType aGroup = GROUP_A );
/**
/**
* Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* @return -1 if none, corner index in .corner <vector>
@ -258,7 +277,7 @@ public:
* @param aFrame = reference to the main frame
* @return number of segments created
*/
int Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame );
int Fill_Zone_Areas_With_Segments( );
/* Geometric transformations: */
@ -268,14 +287,14 @@ public:
* Move the outlines
* @param offset = moving vector
*/
void Move( const wxPoint& offset );
void Move( const wxPoint& offset );
/**
* Function MoveEdge
* Move the outline Edge. m_CornerSelection is the start point of the outline edge
* @param offset = moving vector
*/
void MoveEdge( const wxPoint& offset );
void MoveEdge( const wxPoint& offset );
/**
* Function Rotate
@ -283,7 +302,7 @@ public:
* @param centre = rot centre
* @param angle = in 0.1 degree
*/
void Rotate( const wxPoint& centre, int angle );
void Rotate( const wxPoint& centre, int angle );
/**
* Function Flip
@ -291,7 +310,7 @@ public:
* (like Mirror() but changes layer)
* @param const wxPoint& aCentre - the rotation point.
*/
virtual void Flip(const wxPoint& aCentre );
virtual void Flip( const wxPoint& aCentre );
/**
* Function Mirror
@ -299,7 +318,7 @@ public:
* the layer is not changed
* @param mirror_ref = vertical axis position
*/
void Mirror( const wxPoint& mirror_ref );
void Mirror( const wxPoint& mirror_ref );
/**
* Function GetClass
@ -345,6 +364,7 @@ public:
m_Poly->AppendCorner( position.x, position.y );
}
int GetHatchStyle() const
{
return m_Poly->GetHatchStyle();

View File

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

View File

@ -75,7 +75,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb )
AddClearanceAreasPolygonsToPolysList( aPcb );
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;
}
@ -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()
@ -112,6 +112,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments( WinEDA_PcbFrame* aFrame )
step = max(step, 2);
// Read all filled areas in m_FilledPolysList
m_FillSegmList.clear();
istart = 0;
int end_list = m_FilledPolysList.size()-1;
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_end.x = x_coordinates[ii+1];
seg_end.y = refy;
SEGZONE* segment = new SEGZONE( aFrame->GetBoard() );
segment->m_Start = seg_start;
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 );
SEGMENT segment( seg_start, seg_end );
m_FillSegmList.push_back( segment );
}
} //End examine segments in one area
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
@ -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++ )
{
ZONE_CONTAINER* zone = GetBoard()->GetArea( ii );
@ -131,6 +131,8 @@ void WinEDA_PcbFrame::Delete_Zone_Fill( wxDC* DC, SEGZONE* aZone, long aTimestam
{
modify = TRUE;
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() );
if( DC )
{ // 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 );
}
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();
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
{
@ -905,8 +907,9 @@ int WinEDA_PcbFrame::Fill_Zone( wxDC* DC, ZONE_CONTAINER* zone_container, bool v
int error_level = 0;
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() );
if ( DC )
DrawPanel->Refresh();