Encapsulation, bug, context menu string, and, coding policy fixes.

* Complete encapsulation of the ZONE_CONTAINER class.
* Fixed a bug in the EDA_TEXT::Format() default effects behavior due to
  improper conversion to internal units and missing test for default
  thickness.
* Improved grammar of some Pcbnew context menu strings.
* Moved some more cleverly hidden BOARD object methods into class_board.cpp.
* Lots of coding policy and documentation fixes.
This commit is contained in:
Wayne Stambaugh 2013-03-20 10:50:12 -04:00
parent 25b65b2e3b
commit 25e7abec0d
25 changed files with 482 additions and 552 deletions

View File

@ -58,10 +58,10 @@ extern void CheckGLError();
*/ */
static bool Is3DLayerEnabled( int aLayer ); static bool Is3DLayerEnabled( int aLayer );
/* returns the Z orientation parmeter 1.0 or -1.0 for aLayer /* returns the Z orientation parameter 1.0 or -1.0 for aLayer
* Z orientation is 1.0 for all layers but "back" layers: * Z orientation is 1.0 for all layers but "back" layers:
* LAYER_N_BACK , ADHESIVE_N_BACK, SOLDERPASTE_N_BACK ), SILKSCREEN_N_BACK * LAYER_N_BACK , ADHESIVE_N_BACK, SOLDERPASTE_N_BACK ), SILKSCREEN_N_BACK
* used to calculate the Z orientation parmeter for glNormal3f * used to calculate the Z orientation parameter for glNormal3f
*/ */
static GLfloat Get3DLayer_Z_Orientation( int aLayer ); static GLfloat Get3DLayer_Z_Orientation( int aLayer );
@ -110,6 +110,7 @@ void EDA_3D_CANVAS::Redraw( bool finish )
} }
glFlush(); glFlush();
if( finish ) if( finish )
glFinish(); glFinish();
@ -193,6 +194,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
case PCB_LINE_T: case PCB_LINE_T:
{ {
DRAWSEGMENT* segment = (DRAWSEGMENT*) PtStruct; DRAWSEGMENT* segment = (DRAWSEGMENT*) PtStruct;
if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( segment->GetLayer() ) ) if( g_Parm_3D_Visu.m_BoardSettings->IsLayerVisible( segment->GetLayer() ) )
Draw3D_DrawSegment( segment ); Draw3D_DrawSegment( segment );
} }
@ -201,6 +203,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
case PCB_TEXT_T: case PCB_TEXT_T:
{ {
TEXTE_PCB* text = (TEXTE_PCB*) PtStruct; TEXTE_PCB* text = (TEXTE_PCB*) PtStruct;
if( Is3DLayerEnabled( text->GetLayer() ) ) if( Is3DLayerEnabled( text->GetLayer() ) )
Draw3D_DrawText( text ); Draw3D_DrawText( text );
} }
@ -258,9 +261,9 @@ void EDA_3D_CANVAS::Draw3D_Zone( ZONE_CONTAINER* aZone )
else else
{ {
// segments are used to fill areas // segments are used to fill areas
for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ ) for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
Draw3D_SolidSegment( aZone->m_FillSegmList[iseg].m_Start, Draw3D_SolidSegment( aZone->FillSegments()[iseg].m_Start,
aZone->m_FillSegmList[iseg].m_End, aZone->FillSegments()[iseg].m_End,
aZone->GetMinThickness(), thickness, zpos, aZone->GetMinThickness(), thickness, zpos,
g_Parm_3D_Visu.m_BiuTo3Dunits ); g_Parm_3D_Visu.m_BiuTo3Dunits );
} }
@ -426,6 +429,7 @@ void EDA_3D_CANVAS::DrawGrid( double aGriSizeMM )
SetGLColor( gridcolor ); SetGLColor( gridcolor );
else else
SetGLColor( gridcolor_marker ); SetGLColor( gridcolor_marker );
double delta = ii * aGriSizeMM * IU_PER_MM * scale; double delta = ii * aGriSizeMM * IU_PER_MM * scale;
if( delta <= zmax ) if( delta <= zmax )
@ -505,8 +509,9 @@ void EDA_3D_CANVAS::Draw3D_Via( SEGVIA* via )
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_ZaxisCylinder( via->GetStart(), (outer_radius + inner_radius)/2, Draw3D_ZaxisCylinder( via->GetStart(), (outer_radius + inner_radius)/2,
thickness, outer_radius - inner_radius, thickness, outer_radius - inner_radius,
zpos - (thickness/2), biu_to_3Dunits ); zpos - (thickness/2), biu_to_3Dunits );
if( layer >= top_layer ) if( layer >= top_layer )
break; break;
} }
@ -559,8 +564,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
default: default:
Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(),
segment->GetWidth(), thickness, segment->GetWidth(), thickness,
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
break; break;
} }
} }
@ -593,8 +598,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
default: default:
Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(), Draw3D_SolidSegment( segment->GetStart(), segment->GetEnd(),
segment->GetWidth(), thickness, segment->GetWidth(), thickness,
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits ); zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
break; break;
} }
} }
@ -607,12 +612,13 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
// so they are static. // so they are static.
int s_Text3DWidth, s_Text3DZPos, s_thickness; int s_Text3DWidth, s_Text3DZPos, s_thickness;
// This is a call back function, used by DrawGraphicText to draw the 3D text shape: // This is a call back function, used by DrawGraphicText to draw the 3D text shape:
static void Draw3dTextSegm( int x0, int y0, int xf, int yf ) static void Draw3dTextSegm( int x0, int y0, int xf, int yf )
{ {
Draw3D_SolidSegment( wxPoint( x0, y0), wxPoint( xf, yf ), Draw3D_SolidSegment( wxPoint( x0, y0), wxPoint( xf, yf ),
s_Text3DWidth, s_thickness, s_Text3DZPos, s_Text3DWidth, s_thickness, s_Text3DZPos,
g_Parm_3D_Visu.m_BiuTo3Dunits ); g_Parm_3D_Visu.m_BiuTo3Dunits );
} }
@ -681,6 +687,7 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE] ) if( g_Parm_3D_Visu.m_DrawFlags[g_Parm_3D_Visu.FL_MODULE] )
{ {
double zpos; double zpos;
if( IsFlipped() ) if( IsFlipped() )
zpos = g_Parm_3D_Visu.GetModulesZcoord3DIU( true ); zpos = g_Parm_3D_Visu.GetModulesZcoord3DIU( true );
else else
@ -716,6 +723,7 @@ void MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
} }
EDA_ITEM* Struct = m_Drawings; EDA_ITEM* Struct = m_Drawings;
for( ; Struct != NULL; Struct = Struct->Next() ) for( ; Struct != NULL; Struct = Struct->Next() )
{ {
switch( Struct->Type() ) switch( Struct->Type() )
@ -760,6 +768,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
MODULE* module = (MODULE*) m_Parent; MODULE* module = (MODULE*) m_Parent;
CPolyPt corner; CPolyPt corner;
for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ ) for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
{ {
corner.x = m_PolyPoints[ii].x; corner.x = m_PolyPoints[ii].x;
@ -798,7 +807,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
case S_CIRCLE: case S_CIRCLE:
{ {
int radius = KiROUND( hypot( double(m_Start.x - m_End.x), int radius = KiROUND( hypot( double(m_Start.x - m_End.x),
double(m_Start.y - m_End.y) ) double(m_Start.y - m_End.y) )
); );
Draw3D_ZaxisCylinder( m_Start, radius, Draw3D_ZaxisCylinder( m_Start, radius,
thickness, GetWidth(), thickness, GetWidth(),
@ -953,12 +962,13 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
SetGLColor( g_ColorsSettings.GetLayerColor( layer ) ); SetGLColor( g_ColorsSettings.GetLayerColor( layer ) );
int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer );
int ring_radius = (m_Size.x + m_Drill.x) / 4; int ring_radius = (m_Size.x + m_Drill.x) / 4;
if( thickness == 0 ) if( thickness == 0 )
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
Draw3D_ZaxisCylinder(shape_pos, ring_radius, Draw3D_ZaxisCylinder(shape_pos, ring_radius,
thickness, ( m_Size.x - m_Drill.x) / 2, thickness, ( m_Size.x - m_Drill.x) / 2,
zpos - (thickness/2), scale ); zpos - (thickness/2), scale );
} }
break; break;
@ -967,6 +977,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
{ {
wxPoint ends_offset; wxPoint ends_offset;
int width; int width;
if( m_Size.x > m_Size.y ) // Horizontal ellipse if( m_Size.x > m_Size.y ) // Horizontal ellipse
{ {
ends_offset.x = ( m_Size.x - m_Size.y ) / 2; ends_offset.x = ( m_Size.x - m_Size.y ) / 2;
@ -982,9 +993,12 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
wxPoint start = shape_pos + ends_offset; wxPoint start = shape_pos + ends_offset;
wxPoint end = shape_pos - ends_offset; wxPoint end = shape_pos - ends_offset;
TransformRoundedEndsSegmentToPolygon( polyPadShape, start, end, slice, width ); TransformRoundedEndsSegmentToPolygon( polyPadShape, start, end, slice, width );
if( hasHole ) if( hasHole )
polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), holecornersBuffer.end() ); polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(),
holecornersBuffer.end() );
} }
break; break;
case PAD_RECT: case PAD_RECT:
@ -993,14 +1007,17 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
wxPoint coord[5]; wxPoint coord[5];
BuildPadPolygon( coord, wxSize(0,0), m_Orient ); BuildPadPolygon( coord, wxSize(0,0), m_Orient );
for( int ii = 0; ii < 4; ii ++ ) for( int ii = 0; ii < 4; ii ++ )
{ {
CPolyPt pt( coord[ii].x + shape_pos.x, coord[ii].y+ shape_pos.y ); CPolyPt pt( coord[ii].x + shape_pos.x, coord[ii].y+ shape_pos.y );
polyPadShape.push_back( pt ); polyPadShape.push_back( pt );
} }
polyPadShape.back().end_contour = true; polyPadShape.back().end_contour = true;
if( hasHole ) if( hasHole )
polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(), holecornersBuffer.end() ); polyPadShape.insert( polyPadShape.end(), holecornersBuffer.begin(),
holecornersBuffer.end() );
} }
break; break;
@ -1028,16 +1045,16 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
// If not hole: draw a single polygon // If not hole: draw a single polygon
int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer ); int zpos = g_Parm_3D_Visu.GetLayerZcoordBIU( layer );
if( hasHole ) if( hasHole )
{ {
Draw3D_SolidHorizontalPolygonWithHoles( polyPadShape, zpos, Draw3D_SolidHorizontalPolygonWithHoles( polyPadShape, zpos,
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
} }
else else
{ {
Draw3D_SolidHorizontalPolyPolygons( polyPadShape, zpos, Draw3D_SolidHorizontalPolyPolygons( polyPadShape, zpos,
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
} }
} }
} }
@ -1047,6 +1064,7 @@ void D_PAD::Draw3D( EDA_3D_CANVAS* glcanvas )
bool Is3DLayerEnabled( int aLayer ) bool Is3DLayerEnabled( int aLayer )
{ {
int flg = -1; int flg = -1;
// see if layer needs to be shown // see if layer needs to be shown
// check the flags // check the flags
switch (aLayer) switch (aLayer)
@ -1067,6 +1085,7 @@ bool Is3DLayerEnabled( int aLayer )
flg=g_Parm_3D_Visu.FL_ECO2; flg=g_Parm_3D_Visu.FL_ECO2;
break; break;
} }
// the layer was not a layer with a flag, so show it // the layer was not a layer with a flag, so show it
if( flg < 0 ) if( flg < 0 )
return true; return true;

View File

@ -39,9 +39,6 @@
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <class_base_screen.h> #include <class_base_screen.h>
#ifndef DEFAULT_SIZE_TEXT
# define DEFAULT_SIZE_TEXT 50
#endif
#define EDA_DRAWBASE #define EDA_DRAWBASE
#include <newstroke_font.h> #include <newstroke_font.h>

View File

@ -36,10 +36,8 @@
// Conversion to application internal units defined at build time. // Conversion to application internal units defined at build time.
#if defined( PCBNEW ) #if defined( PCBNEW )
#include <class_board_item.h> #include <class_board_item.h>
#define MILS_TO_IU( x ) ( x * IU_PER_MILS );
#elif defined( EESCHEMA ) #elif defined( EESCHEMA )
#include <sch_item_struct.h> #include <sch_item_struct.h>
#define MILS_TO_IU( x ) ( x )
#else #else
#error "Cannot resolve units formatting due to no definition of EESCHEMA or PCBNEW." #error "Cannot resolve units formatting due to no definition of EESCHEMA or PCBNEW."
#endif #endif
@ -346,7 +344,8 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
aFormatter->Print( aNestLevel+1, "(effects" ); aFormatter->Print( aNestLevel+1, "(effects" );
if( ( m_Size.x != Mils2iu( DEFAULT_SIZE_TEXT ) ) if( ( m_Size.x != Mils2iu( DEFAULT_SIZE_TEXT ) )
|| ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) ) || m_Bold || m_Italic ) || ( m_Size.y != Mils2iu( DEFAULT_SIZE_TEXT ) )
|| ( m_Thickness != 0 ) || m_Bold || m_Italic )
{ {
aFormatter->Print( 0, " (font" ); aFormatter->Print( 0, " (font" );

View File

@ -1628,12 +1628,14 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
int delta = aPadList.size(); int delta = aPadList.size();
int idx = 0; // Starting index is the beginning of list int idx = 0; // Starting index is the beginning of list
while( delta ) while( delta )
{ {
// Calculate half size of remaining interval to test. // Calculate half size of remaining interval to test.
// Ensure the computed value is not truncated (too small) // Ensure the computed value is not truncated (too small)
if( (delta & 1) && ( delta > 1 ) ) if( (delta & 1) && ( delta > 1 ) )
delta++; delta++;
delta /= 2; delta /= 2;
D_PAD* pad = aPadList[idx]; D_PAD* pad = aPadList[idx];
@ -1651,8 +1653,10 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
for( int ii = idx+1; ii <= idxmax; ii++ ) for( int ii = idx+1; ii <= idxmax; ii++ )
{ {
pad = aPadList[ii]; pad = aPadList[ii];
if( pad->GetPosition() != aPosition ) if( pad->GetPosition() != aPosition )
break; break;
if( (aLayerMask & pad->GetLayerMask()) != 0 ) if( (aLayerMask & pad->GetLayerMask()) != 0 )
return pad; return pad;
} }
@ -1660,8 +1664,10 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
for( int ii = idx-1 ;ii >=0; ii-- ) for( int ii = idx-1 ;ii >=0; ii-- )
{ {
pad = aPadList[ii]; pad = aPadList[ii];
if( pad->GetPosition() != aPosition ) if( pad->GetPosition() != aPosition )
break; break;
if( (aLayerMask & pad->GetLayerMask()) != 0 ) if( (aLayerMask & pad->GetLayerMask()) != 0 )
return pad; return pad;
} }
@ -1675,12 +1681,14 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
if(pad->GetPosition().y < aPosition.y) // Must search after this item if(pad->GetPosition().y < aPosition.y) // Must search after this item
{ {
idx += delta; idx += delta;
if( idx > idxmax ) if( idx > idxmax )
idx = idxmax; idx = idxmax;
} }
else // Must search before this item else // Must search before this item
{ {
idx -= delta; idx -= delta;
if( idx < 0 ) if( idx < 0 )
idx = 0; idx = 0;
} }
@ -1688,12 +1696,14 @@ D_PAD* BOARD::GetPad( std::vector<D_PAD*>& aPadList, const wxPoint& aPosition, i
else if( pad->GetPosition().x < aPosition.x ) // Must search after this item else if( pad->GetPosition().x < aPosition.x ) // Must search after this item
{ {
idx += delta; idx += delta;
if( idx > idxmax ) if( idx > idxmax )
idx = idxmax; idx = idxmax;
} }
else // Must search before this item else // Must search before this item
{ {
idx -= delta; idx -= delta;
if( idx < 0 ) if( idx < 0 )
idx = 0; idx = 0;
} }
@ -2202,6 +2212,106 @@ void BOARD::SetTrackWidthIndex( unsigned aIndex )
} }
ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
int aLayer, wxPoint aStartPointPosition, int aHatch )
{
ZONE_CONTAINER* new_area = InsertArea( aNetcode,
m_ZoneDescriptorList.size( ) - 1,
aLayer, aStartPointPosition.x,
aStartPointPosition.y, aHatch );
if( aNewZonesList )
{
ITEM_PICKER picker( new_area, UR_NEW );
aNewZonesList->PushItem( picker );
}
return new_area;
}
void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
{
if( area_to_remove == NULL )
return;
if( aDeletedList )
{
ITEM_PICKER picker( area_to_remove, UR_DELETED );
aDeletedList->PushItem( picker );
Remove( area_to_remove ); // remove from zone list, but does not delete it
}
else
{
Delete( area_to_remove );
}
}
ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch )
{
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
new_area->SetNet( netcode );
new_area->SetLayer( layer );
new_area->SetTimeStamp( GetNewTimeStamp() );
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
else
m_ZoneDescriptorList.push_back( new_area );
new_area->Outline()->Start( layer, x, y, hatch );
return new_area;
}
bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAINER* aCurrArea )
{
CPolyLine* curr_polygon = aCurrArea->Outline();
// mark all areas as unmodified except this one, if modified
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
m_ZoneDescriptorList[ia]->SetFlags( 0 );
aCurrArea->SetFlags( 1 );
if( curr_polygon->IsPolygonSelfIntersecting() )
{
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
curr_polygon->UnHatch();
int n_poly = aCurrArea->Outline()->NormalizeAreaOutlines( pa );
// If clipping has created some polygons, we must add these new copper areas.
if( n_poly > 1 )
{
ZONE_CONTAINER* NewArea;
for( int ip = 1; ip < n_poly; ip++ )
{
// create new copper area and copy poly into it
CPolyLine* new_p = (*pa)[ip - 1];
NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(),
wxPoint(0, 0), CPolyLine::NO_HATCH );
// remove the poly that was automatically created for the new area
// and replace it with a poly from NormalizeAreaOutlines
delete NewArea->Outline();
NewArea->SetOutline( new_p );
NewArea->Outline()->Hatch();
NewArea->SetFlags( 1 );
}
}
delete pa;
}
curr_polygon->Hatch();
return true;
}
#if defined(DEBUG) #if defined(DEBUG)
void BOARD::Show( int nestLevel, std::ostream& os ) const void BOARD::Show( int nestLevel, std::ostream& os ) const

View File

@ -1109,8 +1109,7 @@ public:
* @return true if changes are made * @return true if changes are made
* Also sets areas->utility1 flags if areas are modified * Also sets areas->utility1 flags if areas are modified
*/ */
bool NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, bool NormalizeAreaPolygon( PICKED_ITEMS_LIST* aNewZonesList, ZONE_CONTAINER* aCurrArea );
ZONE_CONTAINER* aCurrArea );
/** /**
* Function OnAreaPolygonModified * Function OnAreaPolygonModified
@ -1136,8 +1135,8 @@ public:
* @return true if some areas modified * @return true if some areas modified
*/ */
bool CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, bool CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList,
int aNetCode, int aNetCode,
bool aUseUtility ); bool aUseUtility );
/** /**
* Function RemoveArea * Function RemoveArea

View File

@ -164,7 +164,8 @@ void ZONE_CONTAINER::SetNet( int aNetCode )
} }
void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset ) void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
const wxPoint& offset )
{ {
if( DC == NULL ) if( DC == NULL )
return; return;
@ -293,7 +294,8 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
CornersTypeBuffer.push_back( (char) corner->m_utility ); CornersTypeBuffer.push_back( (char) corner->m_utility );
if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it // the last corner of a filled area is found: draw it
if( (corner->end_contour) || (ic == imax) )
{ {
/* Draw the current filled area: draw segments outline first /* Draw the current filled area: draw segments outline first
* Curiously, draw segments outline first and after draw filled polygons * Curiously, draw segments outline first and after draw filled polygons
@ -318,7 +320,8 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
int x1 = CornersBuffer[ie].x; int x1 = CornersBuffer[ie].x;
int y1 = CornersBuffer[ie].y; int y1 = CornersBuffer[ie].y;
if( CornersTypeBuffer[ie] == 0 ) // Draw only basic outlines, not extra segments // Draw only basic outlines, not extra segments.
if( CornersTypeBuffer[ie] == 0 )
{ {
if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) ) if( !DisplayOpt.DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
GRCSegm( panel->GetClipBox(), DC, GRCSegm( panel->GetClipBox(), DC,

View File

@ -159,11 +159,11 @@ public:
int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const; int GetClearance( BOARD_CONNECTED_ITEM* aItem = NULL ) const;
/** /**
* Function Test_For_Copper_Island_And_Remove__Insulated_Islands * Function TestForCopperIslandAndRemoveInsulatedIslands
* Remove insulated copper islands found in m_FilledPolysList. * Remove insulated copper islands found in m_FilledPolysList.
* @param aPcb = the board to analyze * @param aPcb = the board to analyze
*/ */
void Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD* aPcb ); void TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb );
/** /**
* Function CalculateSubAreaBoundaryBox * Function CalculateSubAreaBoundaryBox
@ -239,6 +239,20 @@ public:
int GetMinThickness() const { return m_ZoneMinThickness; } int GetMinThickness() const { return m_ZoneMinThickness; }
void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; } void SetMinThickness( int aMinThickness ) { m_ZoneMinThickness = aMinThickness; }
int GetSelectedCorner() const { return m_CornerSelection; }
void SetSelectedCorner( int aCorner ) { m_CornerSelection = aCorner; }
int GetFlags() const { return utility; }
void SetFlags( int aFlags ) { utility = aFlags; }
std::vector <SEGMENT>& FillSegments() { return m_FillSegmList; }
const std::vector <SEGMENT>& FillSegments() const { return m_FillSegmList; }
CPolyLine* Outline() { return m_Poly; }
const CPolyLine* Outline() const { return const_cast< CPolyLine* >( m_Poly ); }
void SetOutline( CPolyLine* aOutline ) { m_Poly = aOutline; }
/** @copydoc EDA_ITEM::HitTest(const wxPoint&) */ /** @copydoc EDA_ITEM::HitTest(const wxPoint&) */
virtual bool HitTest( const wxPoint& aPosition ); virtual bool HitTest( const wxPoint& aPosition );
@ -277,7 +291,7 @@ public:
* Copy polygons from m_FilledPolysList to aKiPolyList * Copy polygons from m_FilledPolysList to aKiPolyList
* @param aKiPolyList = a KI_POLYGON_SET to fill by polygons. * @param aKiPolyList = a KI_POLYGON_SET to fill by polygons.
*/ */
void CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList ); void CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList );
/** /**
* Function AddClearanceAreasPolygonsToPolysList * Function AddClearanceAreasPolygonsToPolysList
@ -327,14 +341,14 @@ public:
int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true ); int Fill_Zone( PCB_EDIT_FRAME* frame, wxDC* DC, bool verbose = true );
/** /**
* Function Fill_Zone_Areas_With_Segments * Function FillZoneAreasWithSegments
* Fill sub areas in a zone with segments with m_ZoneMinThickness width * Fill sub areas in a zone with segments with m_ZoneMinThickness width
* A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness. * A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness.
* all intersecting points with the horizontal infinite line and polygons to fill are calculated * all intersecting points with the horizontal infinite line and polygons to fill are calculated
* a list of SEGZONE items is built, line per line * a list of SEGZONE items is built, line per line
* @return number of segments created * @return number of segments created
*/ */
int Fill_Zone_Areas_With_Segments(); int FillZoneAreasWithSegments();
/** /**
* Function UnFill * Function UnFill
@ -554,23 +568,10 @@ public:
#endif #endif
CPolyLine* m_Poly; // outlines
// For corner moving, corner index to drag, or -1 if no selection.
int m_CornerSelection;
int utility; // flags used in polygon calculations
/* 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
*/
std::vector <SEGMENT> m_FillSegmList;
private: private:
wxString m_Netname; // Net Name CPolyLine* m_Poly; ///< Outline of the zone.
CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly wxString m_Netname; ///< Name of the net assigned to the zone.
CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly
int m_cornerSmoothingType; int m_cornerSmoothingType;
unsigned int m_cornerRadius; unsigned int m_cornerRadius;
@ -613,6 +614,17 @@ private:
/// How to fill areas: 0 => use filled polygons, 1 => fill with segments. /// How to fill areas: 0 => use filled polygons, 1 => fill with segments.
int m_FillMode; int m_FillMode;
/// The index of the corner being moved or -1 if no corner is selected.
int m_CornerSelection;
int utility; ///< Flags used in polygon calculations.
/** Segments used to fill the zone (#m_FillMode ==1 ), when fill zone by segment is used.
* In this case the segments have #m_ZoneMinThickness width.
*/
std::vector <SEGMENT> m_FillSegmList;
/* set of filled polygons used to draw a zone as a filled area. /* 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 * 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 * (they are all in one piece) In very simple cases m_FilledPolysList is same

View File

@ -51,9 +51,9 @@ ZONE_SETTINGS::ZONE_SETTINGS()
// ARC_APPROX_SEGMENTS_COUNT_LOW_DEF // ARC_APPROX_SEGMENTS_COUNT_LOW_DEF
// or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments // or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments
// tickness of the gap in thermal reliefs: // thickness of the gap in thermal reliefs:
m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL ); m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL );
// tickness of the copper bridge in thermal reliefs: // thickness of the copper bridge in thermal reliefs:
m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL ); m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL );
m_PadConnection = THERMAL_PAD; // How pads are covered by copper in zone m_PadConnection = THERMAL_PAD; // How pads are covered by copper in zone
@ -115,10 +115,10 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.SetPriority( m_ZonePriority ); aTarget.SetPriority( m_ZonePriority );
aTarget.SetNet( m_NetcodeSelection ); aTarget.SetNet( m_NetcodeSelection );
aTarget.SetLayer( m_CurrentZone_Layer ); aTarget.SetLayer( m_CurrentZone_Layer );
aTarget.m_Poly->SetLayer( m_CurrentZone_Layer ); aTarget.Outline()->SetLayer( m_CurrentZone_Layer );
} }
// call SetHatch last, because hatch lines will be rebuilt, // call SetHatch last, because hatch lines will be rebuilt,
// using new parameters values // using new parameters values
aTarget.m_Poly->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true ); aTarget.Outline()->SetHatch( m_Zone_HatchingStyle, Mils2iu( 20 ), true );
} }

View File

@ -44,6 +44,7 @@
#include <drc_stuff.h> #include <drc_stuff.h>
#include <dialog_drc.h> #include <dialog_drc.h>
#include <wx/progdlg.h>
void DRC::ShowDialog() void DRC::ShowDialog()
@ -148,16 +149,6 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
} }
/**
* Function Drc
* tests the outline segment starting at CornerIndex and returns the result and displays the error
* in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* @param aArea The areaparent which contains the corner.
* @param aCornerIndex The starting point of the segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex ) int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
{ {
updatePointers(); updatePointers();
@ -173,11 +164,6 @@ int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
} }
/**
* Function RunTests
* will actually run all the tests specified with a previous call to
* SetSettings()
*/
void DRC::RunTests( wxTextCtrl* aMessages ) void DRC::RunTests( wxTextCtrl* aMessages )
{ {
// Ensure ratsnest is up to date: // Ensure ratsnest is up to date:
@ -227,6 +213,7 @@ void DRC::RunTests( wxTextCtrl* aMessages )
aMessages->AppendText( _( "Track clearances...\n" ) ); aMessages->AppendText( _( "Track clearances...\n" ) );
wxSafeYield(); wxSafeYield();
} }
testTracks( true ); testTracks( true );
// Before testing segments and unconnected, refill all zones: // Before testing segments and unconnected, refill all zones:
@ -295,7 +282,7 @@ void DRC::ListUnconnectedPads()
void DRC::updatePointers() void DRC::updatePointers()
{ {
// update my pointers, m_mainWindow is the only unchangable one // update my pointers, m_mainWindow is the only unchangeable one
m_pcb = m_mainWindow->GetBoard(); m_pcb = m_mainWindow->GetBoard();
if( m_ui ) // Use diag list boxes only in DRC dialog if( m_ui ) // Use diag list boxes only in DRC dialog
@ -466,12 +453,6 @@ void DRC::testPad2Pad()
} }
#include <wx/progdlg.h>
/* Function testTracks
* performs the DRC on all tracks.
* because this test can take a while, a progress bar can be displayed
* (Note: it is shown only if there are many tracks)
*/
void DRC::testTracks( bool aShowProgressBar ) void DRC::testTracks( bool aShowProgressBar )
{ {
wxProgressDialog * progressDialog = NULL; wxProgressDialog * progressDialog = NULL;
@ -482,28 +463,32 @@ void DRC::testTracks( bool aShowProgressBar )
count++; count++;
int deltamax = count/delta; int deltamax = count/delta;
if( aShowProgressBar && deltamax > 3 ) if( aShowProgressBar && deltamax > 3 )
{ {
progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString, progressDialog = new wxProgressDialog( _( "Track clearances" ), wxEmptyString,
deltamax, m_mainWindow, deltamax, m_mainWindow,
wxPD_AUTO_HIDE | wxPD_CAN_ABORT ); wxPD_AUTO_HIDE | wxPD_CAN_ABORT );
progressDialog->Update( 0, wxEmptyString ); progressDialog->Update( 0, wxEmptyString );
} }
int ii = 0; int ii = 0;
count = 0; count = 0;
for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() ) for( TRACK* segm = m_pcb->m_Track; segm && segm->Next(); segm = segm->Next() )
{ {
if ( ii++ > delta ) if ( ii++ > delta )
{ {
ii = 0; ii = 0;
count++; count++;
if( progressDialog ) if( progressDialog )
{ {
if( !progressDialog->Update( count, wxEmptyString ) ) if( !progressDialog->Update( count, wxEmptyString ) )
break; // Aborted by user break; // Aborted by user
} }
} }
if( !doTrackDrc( segm, segm->Next(), true ) ) if( !doTrackDrc( segm, segm->Next(), true ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
@ -511,6 +496,7 @@ void DRC::testTracks( bool aShowProgressBar )
m_currentMarker = 0; m_currentMarker = 0;
} }
} }
if( progressDialog ) if( progressDialog )
progressDialog->Destroy(); progressDialog->Destroy();
} }
@ -528,6 +514,7 @@ void DRC::testUnconnected()
return; return;
wxString msg; wxString msg;
for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii ) for( unsigned ii = 0; ii < m_pcb->GetRatsnestsCount(); ++ii )
{ {
RATSNEST_ITEM& rat = m_pcb->m_FullRatsnest[ii]; RATSNEST_ITEM& rat = m_pcb->m_FullRatsnest[ii];
@ -596,7 +583,8 @@ void DRC::testKeepoutAreas()
if( segm->GetLayer() != area->GetLayer() ) if( segm->GetLayer() != area->GetLayer() )
continue; continue;
if( area->m_Poly->Distance( segm->GetStart(), segm->GetEnd(), segm->GetWidth() ) == 0 ) if( area->Outline()->Distance( segm->GetStart(), segm->GetEnd(),
segm->GetWidth() ) == 0 )
{ {
m_currentMarker = fillMarker( segm, NULL, m_currentMarker = fillMarker( segm, NULL,
DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker );
@ -612,7 +600,7 @@ void DRC::testKeepoutAreas()
if( ! ((SEGVIA*)segm)->IsOnLayer( area->GetLayer() ) ) if( ! ((SEGVIA*)segm)->IsOnLayer( area->GetLayer() ) )
continue; continue;
if( area->m_Poly->Distance( segm->GetPosition() ) < segm->GetWidth()/2 ) if( area->Outline()->Distance( segm->GetPosition() ) < segm->GetWidth()/2 )
{ {
m_currentMarker = fillMarker( segm, NULL, m_currentMarker = fillMarker( segm, NULL,
DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker );
@ -625,12 +613,7 @@ void DRC::testKeepoutAreas()
} }
} }
/*
* Function doTrackKeepoutDrc
* tests the current segment or via.
* aRefSeg is the segment to test
* return true if no DRC err
*/
bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg ) bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
{ {
// Test keepout areas for vias, tracks and pads inside keepout areas // Test keepout areas for vias, tracks and pads inside keepout areas
@ -649,7 +632,8 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
if( aRefSeg->GetLayer() != area->GetLayer() ) if( aRefSeg->GetLayer() != area->GetLayer() )
continue; continue;
if( area->m_Poly->Distance( aRefSeg->GetStart(), aRefSeg->GetEnd(), aRefSeg->GetWidth() ) == 0 ) if( area->Outline()->Distance( aRefSeg->GetStart(), aRefSeg->GetEnd(),
aRefSeg->GetWidth() ) == 0 )
{ {
m_currentMarker = fillMarker( aRefSeg, NULL, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker );
@ -664,7 +648,7 @@ bool DRC::doTrackKeepoutDrc( TRACK* aRefSeg )
if( ! ((SEGVIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) ) if( ! ((SEGVIA*)aRefSeg)->IsOnLayer( area->GetLayer() ) )
continue; continue;
if( area->m_Poly->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 ) if( area->Outline()->Distance( aRefSeg->GetPosition() ) < aRefSeg->GetWidth()/2 )
{ {
m_currentMarker = fillMarker( aRefSeg, NULL, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker );

View File

@ -1487,17 +1487,18 @@ void EAGLE_PLUGIN::loadPlain( CPTREE& aGraphics )
CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE; CPolyLine::HATCH_STYLE outline_hatch = CPolyLine::DIAGONAL_EDGE;
zone->m_Poly->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch ); zone->Outline()->Start( layer, kicad_x( r.x1 ), kicad_y( r.y1 ), outline_hatch );
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) ); zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) ); zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) ); zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
zone->m_Poly->CloseLastContour(); zone->Outline()->CloseLastContour();
// this is not my fault: // this is not my fault:
zone->m_Poly->SetHatch( outline_hatch, zone->Outline()->SetHatch( outline_hatch,
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ),
true ); true );
} }
m_xpath->pop(); m_xpath->pop();
} }
@ -2488,18 +2489,19 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
// the ZONE_CONTAINER API needs work, as you can see: // the ZONE_CONTAINER API needs work, as you can see:
if( first ) if( first )
{ {
zone->m_Poly->Start( layer, kicad_x( v.x ), kicad_y( v.y ), outline_hatch ); zone->Outline()->Start( layer, kicad_x( v.x ), kicad_y( v.y ),
outline_hatch );
first = false; first = false;
} }
else else
zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) ); zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
} }
zone->m_Poly->CloseLastContour(); zone->Outline()->CloseLastContour();
zone->m_Poly->SetHatch( outline_hatch, zone->Outline()->SetHatch( outline_hatch,
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ),
true ); true );
// clearances, etc. // clearances, etc.
zone->SetArcSegmentCount( 32 ); // @todo: should be a constructor default? zone->SetArcSegmentCount( 32 ); // @todo: should be a constructor default?

View File

@ -518,7 +518,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
m_canvas->SetAutoPanRequest( true ); m_canvas->SetAutoPanRequest( true );
Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->m_CornerSelection, false ); Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), false );
break; break;
} }
@ -527,7 +527,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->MoveCursorToCrossHair(); m_canvas->MoveCursorToCrossHair();
ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem(); ZONE_CONTAINER* zone_cont = (ZONE_CONTAINER*) GetCurItem();
m_canvas->SetAutoPanRequest( true ); m_canvas->SetAutoPanRequest( true );
Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->m_CornerSelection ); Start_Move_Zone_Drag_Outline_Edge( &dc, zone_cont, zone_cont->GetSelectedCorner() );
break; break;
} }
@ -551,11 +551,11 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
* and start move the new corner * and start move the new corner
*/ */
zone_cont->Draw( m_canvas, &dc, GR_XOR ); zone_cont->Draw( m_canvas, &dc, GR_XOR );
zone_cont->m_Poly->InsertCorner( zone_cont->m_CornerSelection, pos.x, pos.y ); zone_cont->Outline()->InsertCorner( zone_cont->GetSelectedCorner(), pos.x, pos.y );
zone_cont->m_CornerSelection++; zone_cont->SetSelectedCorner( zone_cont->GetSelectedCorner() + 1 );
zone_cont->Draw( m_canvas, &dc, GR_XOR ); zone_cont->Draw( m_canvas, &dc, GR_XOR );
m_canvas->SetAutoPanRequest( true ); m_canvas->SetAutoPanRequest( true );
Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->m_CornerSelection, true ); Start_Move_Zone_Corner( &dc, zone_cont, zone_cont->GetSelectedCorner(), true );
break; break;
} }

View File

@ -1323,7 +1323,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
} }
m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(), m_out->Print( 0, " (hatch %s %s)\n", hatch.c_str(),
FMT_IU( aZone->m_Poly->GetHatchPitch() ).c_str() ); FMT_IU( aZone->Outline()->GetHatchPitch() ).c_str() );
if( aZone->GetPriority() > 0 ) if( aZone->GetPriority() > 0 )
m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() ); m_out->Print( aNestLevel+1, "(priority %d)\n", aZone->GetPriority() );
@ -1405,7 +1405,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
m_out->Print( 0, ")\n" ); m_out->Print( 0, ")\n" );
const std::vector< CPolyPt >& cv = aZone->m_Poly->m_CornersList; const std::vector< CPolyPt >& cv = aZone->Outline()->m_CornersList;
int newLine = 0; int newLine = 0;
if( cv.size() ) if( cv.size() )
@ -1501,7 +1501,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
} }
// Save the filling segments list // Save the filling segments list
const std::vector< SEGMENT >& segs = aZone->m_FillSegmList; const std::vector< SEGMENT >& segs = aZone->FillSegments();
if( segs.size() ) if( segs.size() )
{ {

View File

@ -2167,14 +2167,14 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
int flag = intParse( data ); int flag = intParse( data );
if( !sawCorner ) if( !sawCorner )
zc->m_Poly->Start( zc->GetLayer(), x, y, outline_hatch ); zc->Outline()->Start( zc->GetLayer(), x, y, outline_hatch );
else else
zc->AppendCorner( wxPoint( x, y ) ); zc->AppendCorner( wxPoint( x, y ) );
sawCorner = true; sawCorner = true;
if( flag ) if( flag )
zc->m_Poly->CloseLastContour(); zc->Outline()->CloseLastContour();
} }
else if( TESTLINE( "ZInfo" ) ) // general info found else if( TESTLINE( "ZInfo" ) ) // general info found
@ -2368,9 +2368,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
BIU ex = biuParse( data, &data ); BIU ex = biuParse( data, &data );
BIU ey = biuParse( data ); BIU ey = biuParse( data );
zc->m_FillSegmList.push_back( SEGMENT( zc->FillSegments().push_back( SEGMENT( wxPoint( sx, sy ), wxPoint( ex, ey ) ) );
wxPoint( sx, sy ),
wxPoint( ex, ey ) ) );
} }
} }
@ -2397,9 +2395,9 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
// Hatch here, after outlines corners are read // Hatch here, after outlines corners are read
// Set hatch here, after outlines corners are read // Set hatch here, after outlines corners are read
zc->m_Poly->SetHatch( outline_hatch, zc->Outline()->SetHatch( outline_hatch,
Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ), Mils2iu( CPolyLine::GetDefaultHatchPitchMils() ),
true ); true );
m_board->Add( zc.release() ); m_board->Add( zc.release() );
} }
@ -3682,7 +3680,8 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
typedef std::vector< CPolyPt > CPOLY_PTS; typedef std::vector< CPolyPt > CPOLY_PTS;
// Save the corner list // Save the corner list
const CPOLY_PTS& cv = me->m_Poly->m_CornersList; const CPOLY_PTS& cv = me->Outline()->m_CornersList;
for( CPOLY_PTS::const_iterator it = cv.begin(); it != cv.end(); ++it ) for( CPOLY_PTS::const_iterator it = cv.begin(); it != cv.end(); ++it )
{ {
fprintf( m_fp, "ZCorner %s %d\n", fprintf( m_fp, "ZCorner %s %d\n",
@ -3710,7 +3709,8 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
typedef std::vector< SEGMENT > SEGMENTS; typedef std::vector< SEGMENT > SEGMENTS;
// Save the filling segments list // Save the filling segments list
const SEGMENTS& segs = me->m_FillSegmList; const SEGMENTS& segs = me->FillSegments();
if( segs.size() ) if( segs.size() )
{ {
fprintf( m_fp, "$FILLSEGMENTS\n" ); fprintf( m_fp, "$FILLSEGMENTS\n" );

View File

@ -61,7 +61,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
BOARD_ITEM* item = GetCurItem(); BOARD_ITEM* item = GetCurItem();
m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block coomand when clicking on menu m_canvas->SetCanStartBlock( -1 ); // Avoid to start a block command when clicking on menu
// If a command or a block is in progress: // If a command or a block is in progress:
// Put the Cancel command (if needed) and the End command // Put the Cancel command (if needed) and the End command
@ -167,13 +167,14 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
if( !flags ) if( !flags )
aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE, aPopMenu->Append( ID_POPUP_PCB_AUTOPLACE_CURRENT_MODULE,
_( "Auto Place Module" ) ); _( "Automatically Place Module" ) );
} }
if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
{ {
if( !flags ) if( !flags )
aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE, _( "Autoroute Module" ) ); aPopMenu->Append( ID_POPUP_PCB_AUTOROUTE_MODULE,
_( "Automatically Route Module" ) );
} }
break; break;
@ -205,7 +206,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
if( item->GetLayer() > LAST_COPPER_LAYER ) if( item->GetLayer() > LAST_COPPER_LAYER )
AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER, AddMenuItem( aPopMenu, ID_POPUP_PCB_DELETE_DRAWING_LAYER,
_( "Delete All Drawing on Layer" ), KiBitmap( delete_xpm ) ); _( "Delete All Drawings on Layer" ), KiBitmap( delete_xpm ) );
} }
break; break;
@ -377,7 +378,7 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
{ {
wxMenu* commands = new wxMenu; wxMenu* commands = new wxMenu;
AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS, AddMenuItem( aPopMenu, commands, ID_POPUP_PCB_AUTOPLACE_COMMANDS,
_( "Glob Move and Place" ), KiBitmap( move_xpm ) ); _( "Global Move and Place" ), KiBitmap( move_xpm ) );
AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES, AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FREE_ALL_MODULES,
_( "Unlock All Modules" ), KiBitmap( unlocked_xpm ) ); _( "Unlock All Modules" ), KiBitmap( unlocked_xpm ) );
AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES, AddMenuItem( commands, ID_POPUP_PCB_AUTOPLACE_FIXE_ALL_MODULES,
@ -387,9 +388,12 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
_( "Move All Modules" ), KiBitmap( move_xpm ) ); _( "Move All Modules" ), KiBitmap( move_xpm ) );
commands->Append( ID_POPUP_PCB_AUTOMOVE_NEW_MODULES, _( "Move New Modules" ) ); commands->Append( ID_POPUP_PCB_AUTOMOVE_NEW_MODULES, _( "Move New Modules" ) );
commands->AppendSeparator(); commands->AppendSeparator();
commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES, _( "Autoplace All Modules" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_ALL_MODULES,
commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES, _( "Autoplace New Modules" ) ); _( "Automatically Place All Modules" ) );
commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE, _( "Autoplace Next Module" ) ); commands->Append( ID_POPUP_PCB_AUTOPLACE_NEW_MODULES,
_( "Automatically Place New Modules" ) );
commands->Append( ID_POPUP_PCB_AUTOPLACE_NEXT_MODULE,
_( "Automatically Place Next Module" ) );
commands->AppendSeparator(); commands->AppendSeparator();
AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES, AddMenuItem( commands, ID_POPUP_PCB_REORIENT_ALL_MODULES,
_( "Orient All Modules" ), KiBitmap( rotate_module_pos_xpm ) ); _( "Orient All Modules" ), KiBitmap( rotate_module_pos_xpm ) );
@ -403,16 +407,15 @@ bool PCB_EDIT_FRAME::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR, AddMenuItem( commands, ID_POPUP_PCB_SELECT_LAYER_PAIR,
_( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) ); _( "Select Layer Pair" ), KiBitmap( select_layer_pair_xpm ) );
commands->AppendSeparator(); commands->AppendSeparator();
commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES, _( "Autoroute All Modules" ) ); commands->Append( ID_POPUP_PCB_AUTOROUTE_ALL_MODULES,
_( "Automatically Route All Modules" ) );
commands->AppendSeparator(); commands->AppendSeparator();
commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) ); commands->Append( ID_POPUP_PCB_AUTOROUTE_RESET_UNROUTED, _( "Reset Unrouted" ) );
aPopMenu->AppendSeparator(); aPopMenu->AppendSeparator();
} }
msg = AddHotkeyName( _( "Begin Track" ), msg = AddHotkeyName( _( "Begin Track" ), g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK );
g_Board_Editor_Hokeys_Descr, HK_ADD_NEW_TRACK ); AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK, msg, KiBitmap( add_tracks_xpm ) );
AddMenuItem( aPopMenu, ID_POPUP_PCB_BEGIN_TRACK,
msg, KiBitmap( add_tracks_xpm ) );
if( locate_track ) if( locate_track )
AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ), AddMenuItem( aPopMenu, Append_Track_Width_List( GetBoard() ),
@ -574,7 +577,7 @@ void PCB_EDIT_FRAME::createPopupMenuForTracks( TRACK* Track, wxMenu* PopMenu )
{ {
PopMenu->AppendSeparator(); PopMenu->AppendSeparator();
AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE, AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_ALL_VIAS_AND_TRACK_SIZE,
_( "Global Tracks and Vias Edition" ), KiBitmap( width_track_via_xpm ) ); _( "Edit All Tracks and Vias" ), KiBitmap( width_track_via_xpm ) );
} }
// Add lock/unlock flags menu: // Add lock/unlock flags menu:
@ -671,14 +674,15 @@ void PCB_EDIT_FRAME::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu*
msg = AddHotkeyName( _( "Move Zone" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM ); msg = AddHotkeyName( _( "Move Zone" ), g_Board_Editor_Hokeys_Descr, HK_MOVE_ITEM );
AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES, msg, KiBitmap( move_xpm ) ); AddMenuItem( zones_menu, ID_POPUP_PCB_MOVE_ZONE_OUTLINES, msg, KiBitmap( move_xpm ) );
msg = AddHotkeyName( _( "Edit Zone Params" ), g_Board_Editor_Hokeys_Descr, HK_EDIT_ITEM ); msg = AddHotkeyName( _( "Edit Zone Properties" ), g_Board_Editor_Hokeys_Descr,
HK_EDIT_ITEM );
AddMenuItem( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS, AddMenuItem( zones_menu, ID_POPUP_PCB_EDIT_ZONE_PARAMS,
msg, KiBitmap( edit_xpm ) ); msg, KiBitmap( edit_xpm ) );
zones_menu->AppendSeparator(); zones_menu->AppendSeparator();
if( edge_zone->m_CornerSelection >= 0 && if( edge_zone->GetSelectedCorner() >= 0 &&
edge_zone->m_Poly->IsCutoutContour( edge_zone->m_CornerSelection ) ) edge_zone->Outline()->IsCutoutContour( edge_zone->GetSelectedCorner() ) )
AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT, AddMenuItem( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CUTOUT,
_( "Delete Cutout" ), KiBitmap( delete_xpm ) ); _( "Delete Cutout" ), KiBitmap( delete_xpm ) );
@ -727,7 +731,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForFootprints( MODULE* aModule, wxMenu* menu
AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg, AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg,
KiBitmap( edit_module_xpm ) ); KiBitmap( edit_module_xpm ) );
AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT, AddMenuItem( sub_menu_footprint, ID_POPUP_PCB_EDIT_MODULE_WITH_MODEDIT,
_( "Edit with ModEdit" ), _( "Edit with Module Editor" ),
KiBitmap( module_editor_xpm ) ); KiBitmap( module_editor_xpm ) );
sub_menu_footprint->AppendSeparator(); sub_menu_footprint->AppendSeparator();
msg = AddHotkeyName( _( "Delete Module" ), msg = AddHotkeyName( _( "Delete Module" ),
@ -832,8 +836,8 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
KiBitmap( export_options_pad_xpm ) ); KiBitmap( export_options_pad_xpm ) );
AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS, AddMenuItem( sub_menu_Pad, ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS,
_( "Global Pads Edition" ), _( "Edit All Pads" ),
_( "Copy this pad settings to all pads in this footprint (or similar footprints)" ), _( "Copy this pad's settings to all pads in this footprint (or similar footprints)" ),
KiBitmap( global_options_pad_xpm ) ); KiBitmap( global_options_pad_xpm ) );
sub_menu_Pad->AppendSeparator(); sub_menu_Pad->AppendSeparator();
@ -841,8 +845,8 @@ void PCB_EDIT_FRAME::createPopUpMenuForFpPads( D_PAD* Pad, wxMenu* menu )
if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) ) if( m_mainToolBar->GetToolToggled( ID_TOOLBARH_PCB_MODE_TRACKS ) )
{ {
menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Autoroute Pad" ) ); menu->Append( ID_POPUP_PCB_AUTOROUTE_PAD, _( "Automatically Route Pad" ) );
menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Autoroute Net" ) ); menu->Append( ID_POPUP_PCB_AUTOROUTE_NET, _( "Automatically Route Net" ) );
} }
MODULE* module = (MODULE*) Pad->GetParent(); MODULE* module = (MODULE*) Pad->GetParent();
@ -907,7 +911,7 @@ void PCB_EDIT_FRAME::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aPo
/** /**
* Function Append_Track_Width_List * Function Append_Track_Width_List
* creates a wxMenu * which shows the last used track widths and via diameters * creates a wxMenu * which shows the last used track widths and via diameters
* @return a pointeur to the menu * @return a pointer to the menu
*/ */
static wxMenu* Append_Track_Width_List( BOARD* aBoard ) static wxMenu* Append_Track_Width_List( BOARD* aBoard )
{ {
@ -938,7 +942,7 @@ static wxMenu* Append_Track_Width_List( BOARD* aBoard )
msg.Printf( _( "Track %s" ), GetChars( value ) ); msg.Printf( _( "Track %s" ), GetChars( value ) );
if( ii == 0 ) if( ii == 0 )
msg << _( " (use NetClass)" ); msg << _( " uses NetClass" );
trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, true );
} }
@ -959,11 +963,11 @@ static wxMenu* Append_Track_Width_List( BOARD* aBoard )
} }
else else
{ {
msg.Printf( _( "Via %s; (drl %s)" ), GetChars( value ), GetChars( drill ) ); msg.Printf( _( "Via %s, drill %s" ), GetChars( value ), GetChars( drill ) );
} }
if( ii == 0 ) if( ii == 0 )
msg << _( " (use NetClass)" ); msg << _( " uses NetClass" );
trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, true );
} }

View File

@ -177,8 +177,8 @@ void PCB_POLYGON::AddToBoard()
// add outline // add outline
int outline_hatch = CPolyLine::DIAGONAL_EDGE; int outline_hatch = CPolyLine::DIAGONAL_EDGE;
zone->m_Poly->Start( m_KiCadLayer, KiROUND( m_outline[i]->x ), zone->Outline()->Start( m_KiCadLayer, KiROUND( m_outline[i]->x ),
KiROUND( m_outline[i]->y ), outline_hatch ); KiROUND( m_outline[i]->y ), outline_hatch );
for( i = 1; i < (int) m_outline.GetCount(); i++ ) for( i = 1; i < (int) m_outline.GetCount(); i++ )
{ {
@ -186,15 +186,15 @@ void PCB_POLYGON::AddToBoard()
KiROUND( m_outline[i]->y ) ) ); KiROUND( m_outline[i]->y ) ) );
} }
zone->m_Poly->CloseLastContour(); zone->Outline()->CloseLastContour();
zone->SetZoneClearance( m_width ); zone->SetZoneClearance( m_width );
zone->SetPriority( m_priority ); zone->SetPriority( m_priority );
zone->m_Poly->SetHatch( outline_hatch, zone->Outline()->SetHatch( outline_hatch,
Mils2iu( zone->m_Poly->GetDefaultHatchPitchMils() ), Mils2iu( zone->Outline()->GetDefaultHatchPitchMils() ),
true ); true );
if ( m_objType == wxT( 'K' ) ) if ( m_objType == wxT( 'K' ) )
{ {

View File

@ -2666,7 +2666,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
} }
// Set hatch here, after outlines corners are read // Set hatch here, after outlines corners are read
zone->m_Poly->SetHatch( hatchStyle, hatchPitch, true ); zone->Outline()->SetHatch( hatchStyle, hatchPitch, true );
} }
if( pts.size() ) if( pts.size() )

View File

@ -1,5 +1,29 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/** /**
* @file pcbnew/pcbplot.h * @file pcbnew/pcbplot.h
* @brief Board plot function definition file.
*/ */
#ifndef PCBPLOT_H_ #ifndef PCBPLOT_H_
@ -46,8 +70,8 @@ class BOARD;
class BRDITEMS_PLOTTER: public PCB_PLOT_PARAMS class BRDITEMS_PLOTTER: public PCB_PLOT_PARAMS
{ {
PLOTTER* m_plotter; PLOTTER* m_plotter;
BOARD* m_board; BOARD* m_board;
int m_layerMask; int m_layerMask;
public: public:
@ -62,7 +86,7 @@ public:
/** /**
* @return a 'width adjustment' for the postscript engine * @return a 'width adjustment' for the postscript engine
* (useful for controlling toner bleeding during direct transfer) * (useful for controlling toner bleeding during direct transfer)
* addded to track width and via/pads size * added to track width and via/pads size
*/ */
int getFineWidthAdj() int getFineWidthAdj()
{ {
@ -71,12 +95,22 @@ public:
else else
return 0; return 0;
} }
// Basic functions to plot a board item // Basic functions to plot a board item
void SetLayerMask( int aLayerMask ){ m_layerMask = aLayerMask; } void SetLayerMask( int aLayerMask ){ m_layerMask = aLayerMask; }
void Plot_Edges_Modules(); void Plot_Edges_Modules();
void Plot_1_EdgeModule( EDGE_MODULE* aEdge ); void Plot_1_EdgeModule( EDGE_MODULE* aEdge );
void PlotTextModule( TEXTE_MODULE* aTextMod, EDA_COLOR_T aColor ); void PlotTextModule( TEXTE_MODULE* aTextMod, EDA_COLOR_T aColor );
/*
* Plot field of a module (footprint)
* Reference, Value, and other fields are plotted only if
* the corresponding option is enabled
* Invisible text fields are plotted only if PlotInvisibleText option is set
* usually they are not plotted.
*/
bool PlotAllTextsModule( MODULE* aModule ); bool PlotAllTextsModule( MODULE* aModule );
void PlotDimension( DIMENSION* Dimension ); void PlotDimension( DIMENSION* Dimension );
void PlotPcbTarget( PCB_TARGET* PtMire ); void PlotPcbTarget( PCB_TARGET* PtMire );
void PlotFilledAreas( ZONE_CONTAINER* aZone ); void PlotFilledAreas( ZONE_CONTAINER* aZone );
@ -134,7 +168,7 @@ PLOTTER* StartPlotBoard( BOARD* aBoard,
/** /**
* Function PlotOneBoardLayer * Function PlotOneBoardLayer
* main function to plot one copper or technical layer. * main function to plot one copper or technical layer.
* It prepare options and calls the specilized plot function, * It prepare options and calls the specialized plot function,
* according to the layer type * according to the layer type
* @param aBoard = the board to plot * @param aBoard = the board to plot
* @param aPlotter = the plotter to use * @param aPlotter = the plotter to use
@ -154,8 +188,8 @@ void PlotOneBoardLayer( BOARD* aBoard, PLOTTER* aPlotter, int aLayer,
* @param aLayerMask = the mask to define the layers to plot * @param aLayerMask = the mask to define the layers to plot
* @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only * @param aPlotOpt = the plot options (files, sketch). Has meaning for some formats only
* *
* aPlotOpt has 3 important options to controle this plot, * aPlotOpt has 3 important options to control this plot,
* which are set, depending on the layer typpe to plot * which are set, depending on the layer type to plot
* SetEnablePlotVia( bool aEnable ) * SetEnablePlotVia( bool aEnable )
* aEnable = true to plot vias, false to skip vias (has meaning * aEnable = true to plot vias, false to skip vias (has meaning
* only for solder mask layers). * only for solder mask layers).
@ -188,7 +222,7 @@ void PlotSilkScreen( BOARD* aBoard, PLOTTER* aPlotter, long aLayerMask,
* @param aOutputDir = the wxFileName to modify * @param aOutputDir = the wxFileName to modify
* (contains the absolute or relative to the board path * (contains the absolute or relative to the board path
* @param aBoardFilename = the board full filename * @param aBoardFilename = the board full filename
* @param aMessageBox = a wxMessageBox to show meesage (can be NULL) * @param aMessageBox = a wxMessageBox to show message (can be NULL)
*/ */
bool EnsureOutputDirectory( wxFileName* aOutputDir, bool EnsureOutputDirectory( wxFileName* aOutputDir,
const wxString& aBoardFilename, const wxString& aBoardFilename,
@ -207,9 +241,9 @@ bool EnsureOutputDirectory( wxFileName* aOutputDir,
* @param aExtension = the file extension * @param aExtension = the file extension
*/ */
void BuildPlotFileName( wxFileName* aFilename, void BuildPlotFileName( wxFileName* aFilename,
const wxString& aOutputDir, const wxString& aOutputDir,
const wxString& aSuffix, const wxString& aSuffix,
const wxString& aExtension ); const wxString& aExtension );
// PLOTGERB.CPP // PLOTGERB.CPP
void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize ); void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize );

View File

@ -54,12 +54,6 @@
*/ */
/* Function getColor
* return the layer colorfrom the layer id
* White color is special: cannot be seen on a white paper
* and in B&W mode, is plotted as white but other colors are plotted in BLACK
* so the returned color is LIGHTGRAY when the layer color is WHITE
*/
EDA_COLOR_T BRDITEMS_PLOTTER::getColor( int aLayer ) EDA_COLOR_T BRDITEMS_PLOTTER::getColor( int aLayer )
{ {
EDA_COLOR_T color = m_board->GetLayerColor( aLayer ); EDA_COLOR_T color = m_board->GetLayerColor( aLayer );
@ -68,12 +62,7 @@ EDA_COLOR_T BRDITEMS_PLOTTER::getColor( int aLayer )
return color; return color;
} }
/*
* Plot a pad.
* unlike other items, a pad had not a specific color,
* and be drawn as a non filled item although the plot mode is filled
* color and plot mode are needed by this function
*/
void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode ) void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode )
{ {
wxPoint shape_pos = aPad->ReturnShapePos(); wxPoint shape_pos = aPad->ReturnShapePos();
@ -90,7 +79,7 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T
case PAD_OVAL: case PAD_OVAL:
m_plotter->FlashPadOval( shape_pos, aPad->GetSize(), m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
aPad->GetOrientation(), aPlotMode ); aPad->GetOrientation(), aPlotMode );
break; break;
case PAD_TRAPEZOID: case PAD_TRAPEZOID:
@ -98,25 +87,19 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T
wxPoint coord[4]; wxPoint coord[4];
aPad->BuildPadPolygon( coord, wxSize(0,0), 0 ); aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
m_plotter->FlashPadTrapez( shape_pos, coord, m_plotter->FlashPadTrapez( shape_pos, coord,
aPad->GetOrientation(), aPlotMode ); aPad->GetOrientation(), aPlotMode );
} }
break; break;
case PAD_RECT: case PAD_RECT:
default: default:
m_plotter->FlashPadRect( shape_pos, aPad->GetSize(), m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
aPad->GetOrientation(), aPlotMode ); aPad->GetOrientation(), aPlotMode );
break; break;
} }
} }
/*
* Plot field of a module (footprint)
* Reference, Value, and other fields are plotted only if
* the corresponding option is enabled
* Invisible text fields are plotted only if PlotInvisibleText option is set
* usually they are not plotted.
*/
bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule ) bool BRDITEMS_PLOTTER::PlotAllTextsModule( MODULE* aModule )
{ {
// see if we want to plot VALUE and REF fields // see if we want to plot VALUE and REF fields
@ -221,8 +204,7 @@ void BRDITEMS_PLOTTER::PlotBoardGraphicItems()
} }
} }
void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, EDA_COLOR_T aColor )
EDA_COLOR_T aColor )
{ {
wxSize size; wxSize size;
wxPoint pos; wxPoint pos;
@ -230,6 +212,7 @@ void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte,
if( aColor == WHITE ) if( aColor == WHITE )
aColor = LIGHTGRAY; aColor = LIGHTGRAY;
m_plotter->SetColor( aColor ); m_plotter->SetColor( aColor );
// calculate some text parameters : // calculate some text parameters :
@ -323,6 +306,7 @@ void BRDITEMS_PLOTTER::PlotPcbTarget( PCB_TARGET* aMire )
draw.SetLayer( aMire->GetLayer() ); draw.SetLayer( aMire->GetLayer() );
draw.SetStart( aMire->GetPosition() ); draw.SetStart( aMire->GetPosition() );
radius = aMire->GetSize() / 3; radius = aMire->GetSize() / 3;
if( aMire->GetShape() ) // shape X if( aMire->GetShape() ) // shape X
radius = aMire->GetSize() / 2; radius = aMire->GetSize() / 2;
@ -410,55 +394,53 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
break; break;
case S_ARC: case S_ARC:
{ {
radius = (int) hypot( (double) ( end.x - pos.x ), radius = (int) hypot( (double) ( end.x - pos.x ),
(double) ( end.y - pos.y ) ); (double) ( end.y - pos.y ) );
double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x ); double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
double endAngle = startAngle + aEdge->GetAngle(); double endAngle = startAngle + aEdge->GetAngle();
if ( ( GetFormat() == PLOT_FORMAT_DXF ) && if ( ( GetFormat() == PLOT_FORMAT_DXF ) &&
( m_layerMask & ( SILKSCREEN_LAYER_BACK | DRAW_LAYER | COMMENT_LAYER ) ) ) ( m_layerMask & ( SILKSCREEN_LAYER_BACK | DRAW_LAYER | COMMENT_LAYER ) ) )
m_plotter->ThickArc( pos, -startAngle, -endAngle, radius, m_plotter->ThickArc( pos, -startAngle, -endAngle, radius, thickness, GetMode() );
thickness, GetMode() ); else
else m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetMode() );
m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, }
thickness, GetMode() ); break;
}
break;
case S_POLYGON: case S_POLYGON:
{
const std::vector<wxPoint>& polyPoints = aEdge->GetPolyPoints();
if( polyPoints.size() <= 1 ) // Malformed polygon
break;
// We must compute true coordinates from m_PolyList
// which are relative to module position, orientation 0
MODULE* module = aEdge->GetParentModule();
std::vector< wxPoint > cornerList;
cornerList.reserve( polyPoints.size() );
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
{ {
const std::vector<wxPoint>& polyPoints = aEdge->GetPolyPoints(); wxPoint corner = polyPoints[ii];
if( polyPoints.size() <= 1 ) // Malformed polygon if( module )
break;
// We must compute true coordinates from m_PolyList
// which are relative to module position, orientation 0
MODULE* module = aEdge->GetParentModule();
std::vector< wxPoint > cornerList;
cornerList.reserve( polyPoints.size() );
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
{ {
wxPoint corner = polyPoints[ii]; RotatePoint( &corner, module->GetOrientation() );
corner += module->GetPosition();
if( module )
{
RotatePoint( &corner, module->GetOrientation() );
corner += module->GetPosition();
}
cornerList.push_back( corner );
} }
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness ); cornerList.push_back( corner );
} }
break;
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness );
}
break;
} }
} }
@ -566,10 +548,10 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
} }
else // We are using areas filled by else // We are using areas filled by
{ // segments: plot them ) { // segments: plot them )
for( unsigned iseg = 0; iseg < aZone->m_FillSegmList.size(); iseg++ ) for( unsigned iseg = 0; iseg < aZone->FillSegments().size(); iseg++ )
{ {
wxPoint start = aZone->m_FillSegmList[iseg].m_Start; wxPoint start = aZone->FillSegments()[iseg].m_Start;
wxPoint end = aZone->m_FillSegmList[iseg].m_End; wxPoint end = aZone->FillSegments()[iseg].m_End;
m_plotter->ThickSegment( start, end, m_plotter->ThickSegment( start, end,
aZone->GetMinThickness(), aZone->GetMinThickness(),
GetMode() ); GetMode() );
@ -644,8 +626,8 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
for( unsigned i = 1; i < bezierPoints.size(); i++ ) for( unsigned i = 1; i < bezierPoints.size(); i++ )
m_plotter->ThickSegment( bezierPoints[i - 1], m_plotter->ThickSegment( bezierPoints[i - 1],
bezierPoints[i], bezierPoints[i],
thickness, GetMode() ); thickness, GetMode() );
} }
break; break;
@ -654,6 +636,7 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
} }
} }
/** Helper function to plot a single drill mark. It compensate and clamp /** Helper function to plot a single drill mark. It compensate and clamp
* the drill mark size depending on the current plot options * the drill mark size depending on the current plot options
*/ */
@ -669,6 +652,7 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_SHAPE_T aDrillShape,
// Round holes only have x diameter, slots have both // Round holes only have x diameter, slots have both
aDrillSize.x -= getFineWidthAdj(); aDrillSize.x -= getFineWidthAdj();
aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 ); aDrillSize.x = Clamp( 1, aDrillSize.x, aPadSize.x - 1 );
if( aDrillShape == PAD_OVAL ) if( aDrillShape == PAD_OVAL )
{ {
aDrillSize.y -= getFineWidthAdj(); aDrillSize.y -= getFineWidthAdj();
@ -679,12 +663,7 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_SHAPE_T aDrillShape,
m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetMode() ); m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetMode() );
} }
/* Function PlotDrillMarks
* Draw a drill mark for pads and vias.
* Must be called after all drawings, because it
* redraw the drill mark on a pad or via, as a negative (i.e. white) shape in
* FILLED plot mode (for PS and PDF outputs)
*/
void BRDITEMS_PLOTTER::PlotDrillMarks() void BRDITEMS_PLOTTER::PlotDrillMarks()
{ {
/* If small drills marks were requested prepare a clamp value to pass /* If small drills marks were requested prepare a clamp value to pass
@ -711,9 +690,8 @@ void BRDITEMS_PLOTTER::PlotDrillMarks()
if( pts->Type() != PCB_VIA_T ) if( pts->Type() != PCB_VIA_T )
continue; continue;
plotOneDrillMark(PAD_CIRCLE, plotOneDrillMark( PAD_CIRCLE, pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ),
pts->GetStart(), wxSize( pts->GetDrillValue(), 0 ), wxSize( pts->GetWidth(), 0 ), 0, small_drill );
wxSize( pts->GetWidth(), 0 ), 0, small_drill );
} }
for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() ) for( MODULE *Module = m_board->m_Modules; Module != NULL; Module = Module->Next() )
@ -724,9 +702,9 @@ void BRDITEMS_PLOTTER::PlotDrillMarks()
continue; continue;
plotOneDrillMark( pad->GetDrillShape(), plotOneDrillMark( pad->GetDrillShape(),
pad->GetPosition(), pad->GetDrillSize(), pad->GetPosition(), pad->GetDrillSize(),
pad->GetSize(), pad->GetOrientation(), pad->GetSize(), pad->GetOrientation(),
small_drill ); small_drill );
} }
} }

View File

@ -1171,16 +1171,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
int count = item->m_Poly->m_CornersList.size(); int count = item->Outline()->m_CornersList.size();
int ndx = 0; // used in 2 for() loops below int ndx = 0; // used in 2 for() loops below
for( ; ndx<count; ++ndx ) for( ; ndx<count; ++ndx )
{ {
wxPoint point( item->m_Poly->m_CornersList[ndx].x, wxPoint point( item->Outline()->m_CornersList[ndx].x,
item->m_Poly->m_CornersList[ndx].y ); item->Outline()->m_CornersList[ndx].y );
mainPolygon->AppendPoint( mapPt(point) ); mainPolygon->AppendPoint( mapPt(point) );
// this was the end of the main polygon // this was the end of the main polygon
if( item->m_Poly->m_CornersList[ndx].end_contour ) if( item->Outline()->m_CornersList[ndx].end_contour )
break; break;
} }
@ -1190,7 +1190,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
// handle the cutouts // handle the cutouts
for( ++ndx; ndx<count; ++ndx ) for( ++ndx; ndx<count; ++ndx )
{ {
if( item->m_Poly->m_CornersList[ndx-1].end_contour ) if( item->Outline()->m_CornersList[ndx-1].end_contour )
{ {
window = new WINDOW( plane ); window = new WINDOW( plane );
plane->AddWindow( window ); plane->AddWindow( window );
@ -1204,8 +1204,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
wxASSERT( window ); wxASSERT( window );
wxASSERT( cutout ); wxASSERT( cutout );
wxPoint point(item->m_Poly->m_CornersList[ndx].x, wxPoint point(item->Outline()->m_CornersList[ndx].x,
item->m_Poly->m_CornersList[ndx].y ); item->Outline()->m_CornersList[ndx].y );
cutout->AppendPoint( mapPt(point) ); cutout->AppendPoint( mapPt(point) );
} }
} }
@ -1246,16 +1246,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ];
int count = item->m_Poly->m_CornersList.size(); int count = item->Outline()->m_CornersList.size();
int ndx = 0; // used in 2 for() loops below int ndx = 0; // used in 2 for() loops below
for( ; ndx<count; ++ndx ) for( ; ndx<count; ++ndx )
{ {
wxPoint point( item->m_Poly->m_CornersList[ndx].x, wxPoint point( item->Outline()->m_CornersList[ndx].x,
item->m_Poly->m_CornersList[ndx].y ); item->Outline()->m_CornersList[ndx].y );
mainPolygon->AppendPoint( mapPt(point) ); mainPolygon->AppendPoint( mapPt(point) );
// this was the end of the main polygon // this was the end of the main polygon
if( item->m_Poly->m_CornersList[ndx].end_contour ) if( item->Outline()->m_CornersList[ndx].end_contour )
break; break;
} }
@ -1265,7 +1265,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
// handle the cutouts // handle the cutouts
for( ++ndx; ndx<count; ++ndx ) for( ++ndx; ndx<count; ++ndx )
{ {
if( item->m_Poly->m_CornersList[ndx-1].end_contour ) if( item->Outline()->m_CornersList[ndx-1].end_contour )
{ {
window = new WINDOW( keepout ); window = new WINDOW( keepout );
keepout->AddWindow( window ); keepout->AddWindow( window );
@ -1279,8 +1279,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
wxASSERT( window ); wxASSERT( window );
wxASSERT( cutout ); wxASSERT( cutout );
wxPoint point(item->m_Poly->m_CornersList[ndx].x, wxPoint point(item->Outline()->m_CornersList[ndx].x,
item->m_Poly->m_CornersList[ndx].y ); item->Outline()->m_CornersList[ndx].y );
cutout->AppendPoint( mapPt(point) ); cutout->AppendPoint( mapPt(point) );
} }
} }

View File

@ -38,23 +38,7 @@
#include <pcbnew.h> #include <pcbnew.h>
#include <zones.h> #include <zones.h>
/* Local functions */
/* Local variables */
/**
* Function BuildFilledPolysListData
* Build m_FilledPolysList data from real outlines (m_Poly)
* in order to have drawable (and plottable) filled polygons
* drawable filled polygons are polygons without hole
* @param aPcb: the current board (can be NULL for non copper zones)
* @param aCornerBuffer: A reference to a buffer to put polygon corners, or NULL
* if NULL (default), uses m_FilledPolysList and fill current zone.
* @return number of polygons
* This function does not add holes for pads and tracks but calls
* AddClearanceAreasPolygonsToPolysList() to do that for copper layers
*/
int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer ) int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>* aCornerBuffer )
{ {
if( aCornerBuffer == NULL ) if( aCornerBuffer == NULL )
@ -125,12 +109,13 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>
CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas );
} }
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( ); FillZoneAreasWithSegments( );
} }
return 1; return 1;
} }
// Sort function to build filled zones // Sort function to build filled zones
static bool SortByXValues( const int& a, const int &b) static bool SortByXValues( const int& a, const int &b)
{ {
@ -138,22 +123,14 @@ static bool SortByXValues( const int& a, const int &b)
} }
/** int ZONE_CONTAINER::FillZoneAreasWithSegments()
* Function Fill_Zone_Areas_With_Segments
* Fill sub areas in a zone with segments with m_ZoneMinThickness width
* A scan is made line per line, on the whole filled areas, with a step of m_ZoneMinThickness.
* all intersecting points with the horizontal infinite line and polygons to fill are calculated
* a list of SEGZONE items is built, line per line
* @return number of segments created
*/
int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments()
{ {
int ics, ice; int ics, ice;
int count = 0; int count = 0;
std::vector <int> x_coordinates; std::vector <int> x_coordinates;
bool error = false; bool error = false;
int istart, iend; // index od the starting and the endif corner of one filled area in m_FilledPolysList int istart, iend; // index of the starting and the endif corner of one filled area in m_FilledPolysList
int margin = m_ZoneMinThickness * 2 / 10; int margin = m_ZoneMinThickness * 2 / 10;
int minwidth = Mils2iu( 2 ); int minwidth = Mils2iu( 2 );
@ -165,6 +142,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments()
m_FillSegmList.clear(); 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++ )
{ {
CPolyPt* corner = &m_FilledPolysList[ic]; CPolyPt* corner = &m_FilledPolysList[ic];
@ -181,10 +159,12 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments()
{ {
// find all intersection points of an infinite line with polyline sides // find all intersection points of an infinite line with polyline sides
x_coordinates.clear(); x_coordinates.clear();
for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ )
{ {
if ( m_FilledPolysList[ice].m_utility ) if ( m_FilledPolysList[ice].m_utility )
continue; continue;
int seg_startX = m_FilledPolysList[ics].x; int seg_startX = m_FilledPolysList[ics].x;
int seg_startY = m_FilledPolysList[ics].y; int seg_startY = m_FilledPolysList[ics].y;
int seg_endX = m_FilledPolysList[ice].x; int seg_endX = m_FilledPolysList[ice].x;
@ -202,20 +182,25 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments()
/* at this point refy is between seg_startY and seg_endY /* at this point refy is between seg_startY and seg_endY
* see if an horizontal line at Y = refy is intersecting this segment * see if an horizontal line at Y = refy is intersecting this segment
*/ */
// calculate the x position of the intersection of this segment and the infinite line // calculate the x position of the intersection of this segment and the
// this is more easier if we move the X,Y axis origin to the segment start point: // infinite line this is more easier if we move the X,Y axis origin to
// the segment start point:
seg_endX -= seg_startX; seg_endX -= seg_startX;
seg_endY -= seg_startY; seg_endY -= seg_startY;
double newrefy = (double) (refy - seg_startY); double newrefy = (double) (refy - seg_startY);
double intersec_x; double intersec_x;
if ( seg_endY == 0 ) // horizontal segment on the same line: skip if ( seg_endY == 0 ) // horizontal segment on the same line: skip
continue; continue;
// Now calculate the x intersection coordinate of the horizontal line at y = newrefy
// and the segment from (0,0) to (seg_endX,seg_endY) // Now calculate the x intersection coordinate of the horizontal line at
// with the horizontal line at the new refy position // y = newrefy and the segment from (0,0) to (seg_endX,seg_endY) with the
// the line slope is slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY // horizontal line at the new refy position the line slope is:
// and the x pos relative to the new origin is intersec_x = refy/slope = refy * inv_slope // slope = seg_endY/seg_endX; and inv_slope = seg_endX/seg_endY
// Note: because horizontal segments are already tested and skipped, slope exists (seg_end_y not O) // and the x pos relative to the new origin is:
// intersec_x = refy/slope = refy * inv_slope
// Note: because horizontal segments are already tested and skipped, slope
// exists (seg_end_y not O)
double inv_slope = (double)seg_endX / seg_endY; double inv_slope = (double)seg_endX / seg_endY;
intersec_x = newrefy * inv_slope; intersec_x = newrefy * inv_slope;
x_coordinates.push_back((int) intersec_x + seg_startX); x_coordinates.push_back((int) intersec_x + seg_startX);

View File

@ -126,7 +126,7 @@ void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone )
if( success ) if( success )
{ {
zoneSettings.ExportSetting( *newZone ); zoneSettings.ExportSetting( *newZone );
newZone->m_Poly->Hatch(); newZone->Outline()->Hatch();
s_AuxiliaryList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems();
s_PickedList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems();
@ -176,7 +176,7 @@ int PCB_EDIT_FRAME::Delete_LastCreatedCorner( wxDC* DC )
if( zone->GetNumCorners() > 2 ) if( zone->GetNumCorners() > 2 )
{ {
zone->m_Poly->DeleteCorner( zone->GetNumCorners() - 1 ); zone->Outline()->DeleteCorner( zone->GetNumCorners() - 1 );
if( m_canvas->IsMouseCaptured() ) if( m_canvas->IsMouseCaptured() )
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
@ -239,11 +239,11 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone,
// Prepare copy of old zones, for undo/redo. // Prepare copy of old zones, for undo/redo.
// if the corner is new, remove it from list, save and insert it in list // if the corner is new, remove it from list, save and insert it in list
int cx = aZone->m_Poly->GetX( corner_id ); int cx = aZone->Outline()->GetX( corner_id );
int cy = aZone->m_Poly->GetY( corner_id ); int cy = aZone->Outline()->GetY( corner_id );
if ( IsNewCorner ) if ( IsNewCorner )
aZone->m_Poly->DeleteCorner( corner_id ); aZone->Outline()->DeleteCorner( corner_id );
s_AuxiliaryList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems();
s_PickedList.ClearListAndDeleteItems(); s_PickedList.ClearListAndDeleteItems();
@ -252,7 +252,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone,
aZone->GetLayer() ); aZone->GetLayer() );
if ( IsNewCorner ) if ( IsNewCorner )
aZone->m_Poly->InsertCorner(corner_id-1, cx, cy ); aZone->Outline()->InsertCorner(corner_id-1, cx, cy );
aZone->SetFlags( IN_EDIT ); aZone->SetFlags( IN_EDIT );
m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
@ -269,7 +269,7 @@ void PCB_EDIT_FRAME::Start_Move_Zone_Drag_Outline_Edge( wxDC* DC,
int corner_id ) int corner_id )
{ {
aZone->SetFlags( IS_DRAGGED ); aZone->SetFlags( IS_DRAGGED );
aZone->m_CornerSelection = corner_id; aZone->SetSelectedCorner( corner_id );
m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse, m_canvas->SetMouseCapture( Show_Zone_Corner_Or_Outline_While_Move_Mouse,
Abort_Zone_Move_Corner_Or_Outlines ); Abort_Zone_Move_Corner_Or_Outlines );
s_CursorLastPosition = s_CornerInitialPosition = GetScreen()->GetCrossHairPosition(); s_CursorLastPosition = s_CornerInitialPosition = GetScreen()->GetCrossHairPosition();
@ -358,7 +358,7 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone )
{ {
OnModify(); OnModify();
if( aZone->m_Poly->GetNumCorners() <= 3 ) if( aZone->Outline()->GetNumCorners() <= 3 )
{ {
m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() ); m_canvas->RefreshDrawingRect( aZone->GetBoundingBox() );
@ -382,9 +382,8 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone )
s_AuxiliaryList.ClearListAndDeleteItems(); s_AuxiliaryList.ClearListAndDeleteItems();
s_PickedList. ClearListAndDeleteItems(); s_PickedList. ClearListAndDeleteItems();
SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), SaveCopyOfZones( s_PickedList, GetBoard(), aZone->GetNet(), aZone->GetLayer() );
aZone->GetLayer() ); aZone->Outline()->DeleteCorner( aZone->GetSelectedCorner() );
aZone->m_Poly->DeleteCorner( aZone->m_CornerSelection );
// modify zones outlines according to the new aZone shape // modify zones outlines according to the new aZone shape
GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone ); GetBoard()->OnAreaPolygonModified( &s_AuxiliaryList, aZone );
@ -438,12 +437,12 @@ void Abort_Zone_Move_Corner_Or_Outlines( EDA_DRAW_PANEL* Panel, wxDC* DC )
{ {
if( s_CornerIsNew ) if( s_CornerIsNew )
{ {
zone->m_Poly->DeleteCorner( zone->m_CornerSelection ); zone->Outline()->DeleteCorner( zone->GetSelectedCorner() );
} }
else else
{ {
wxPoint pos = s_CornerInitialPosition; wxPoint pos = s_CornerInitialPosition;
zone->m_Poly->MoveCorner( zone->m_CornerSelection, pos.x, pos.y ); zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y );
} }
} }
@ -489,7 +488,7 @@ void Show_Zone_Corner_Or_Outline_While_Move_Mouse( EDA_DRAW_PANEL* aPanel, wxDC*
} }
else else
{ {
zone->m_Poly->MoveCorner( zone->m_CornerSelection, pos.x, pos.y ); zone->Outline()->MoveCorner( zone->GetSelectedCorner(), pos.x, pos.y );
} }
zone->Draw( aPanel, aDC, GR_XOR ); zone->Draw( aPanel, aDC, GR_XOR );
@ -651,10 +650,10 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
zoneInfo.ExportSetting( *zone ); zoneInfo.ExportSetting( *zone );
zone->m_Poly->Start( zoneInfo.m_CurrentZone_Layer, zone->Outline()->Start( zoneInfo.m_CurrentZone_Layer,
GetScreen()->GetCrossHairPosition().x, GetScreen()->GetCrossHairPosition().x,
GetScreen()->GetCrossHairPosition().y, GetScreen()->GetCrossHairPosition().y,
zone->GetHatchStyle() ); zone->GetHatchStyle() );
zone->AppendCorner( GetScreen()->GetCrossHairPosition() ); zone->AppendCorner( GetScreen()->GetCrossHairPosition() );
@ -715,7 +714,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
} }
// Remove the last corner if is is at the same location as the prevoius corner // Remove the last corner if is is at the same location as the prevoius corner
zone->m_Poly->RemoveNullSegments(); zone->Outline()->RemoveNullSegments();
// Validate the current edge: // Validate the current edge:
int icorner = zone->GetNumCorners() - 1; int icorner = zone->GetNumCorners() - 1;
@ -752,7 +751,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
// Put new zone in list // Put new zone in list
if( !s_CurrentZone ) if( !s_CurrentZone )
{ {
zone->m_Poly->CloseLastContour(); // Close the current corner list zone->Outline()->CloseLastContour(); // Close the current corner list
GetBoard()->Add( zone ); GetBoard()->Add( zone );
GetBoard()->m_CurrentZoneContour = NULL; GetBoard()->m_CurrentZoneContour = NULL;
@ -767,7 +766,7 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) ); s_CurrentZone->AppendCorner( zone->GetCornerPosition( ii ) );
} }
s_CurrentZone->m_Poly->CloseLastContour(); // Close the current corner list s_CurrentZone->Outline()->CloseLastContour(); // Close the current corner list
zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list. zone->RemoveAllContours(); // All corners are copied in s_CurrentZone. Free corner list.
zone = s_CurrentZone; zone = s_CurrentZone;
} }
@ -924,7 +923,7 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone ) void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone )
{ {
int ncont = aZone->m_Poly->GetContour( aZone->m_CornerSelection ); int ncont = aZone->Outline()->GetContour( aZone->GetSelectedCorner() );
EDA_RECT dirty = aZone->GetBoundingBox(); EDA_RECT dirty = aZone->GetBoundingBox();
@ -943,7 +942,7 @@ void PCB_EDIT_FRAME::Delete_Zone_Contour( wxDC* DC, ZONE_CONTAINER* aZone )
else else
{ {
SaveCopyInUndoList( aZone, UR_CHANGED ); SaveCopyInUndoList( aZone, UR_CHANGED );
aZone->m_Poly->RemoveContour( ncont ); aZone->Outline()->RemoveContour( ncont );
} }
m_canvas->RefreshDrawingRect( dirty ); m_canvas->RefreshDrawingRect( dirty );

View File

@ -437,7 +437,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
// Remove insulated islands: // Remove insulated islands:
if( GetNet() > 0 ) if( GetNet() > 0 )
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); TestForCopperIslandAndRemoveInsulatedIslands( aPcb );
// Now we remove all unused thermal stubs. // Now we remove all unused thermal stubs.
cornerBufferPolysToSubstract.clear(); cornerBufferPolysToSubstract.clear();
@ -462,7 +462,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas ); CopyPolygonsFromKiPolygonListToFilledPolysList( polyset_zone_solid_areas );
if( GetNet() > 0 ) if( GetNet() > 0 )
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); TestForCopperIslandAndRemoveInsulatedIslands( aPcb );
} }
cornerBufferPolysToSubstract.clear(); cornerBufferPolysToSubstract.clear();

View File

@ -113,9 +113,9 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
// Compare outlines // Compare outlines
wxASSERT( m_Poly ); // m_Poly == NULL Should never happen wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
wxASSERT( aZoneToCompare.m_Poly ); wxASSERT( aZoneToCompare.Outline() );
if( m_Poly->m_CornersList != aZoneToCompare.m_Poly->m_CornersList ) // Compare vector if( Outline()->m_CornersList != aZoneToCompare.Outline()->m_CornersList ) // Compare vector
return false; return false;
return true; return true;

View File

@ -38,12 +38,7 @@
#include <polygon_test_point_inside.h> #include <polygon_test_point_inside.h>
/** void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb )
* Function Test_For_Copper_Island_And_Remove__Insulated_Islands
* Remove insulated copper islands found in m_FilledPolysList.
* @param aPcb = the board to analyse
*/
void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD * aPcb )
{ {
if( m_FilledPolysList.size() == 0 ) if( m_FilledPolysList.size() == 0 )
return; return;
@ -124,15 +119,6 @@ void ZONE_CONTAINER::Test_For_Copper_Island_And_Remove_Insulated_Islands( BOARD
} }
/**
* Function CalculateSubAreaBoundaryBox
* Calculates the bounding box of a a filled area ( list of CPolyPt )
* use m_FilledPolysList as list of CPolyPt (that are the corners of one or more polygons or
* filled areas )
* @return an EDA_RECT as bounding box
* @param aIndexStart = index of the first corner of a polygon (filled area) in m_FilledPolysList
* @param aIndexEnd = index of the last corner of a polygon in m_FilledPolysList
*/
EDA_RECT ZONE_CONTAINER::CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd ) EDA_RECT ZONE_CONTAINER::CalculateSubAreaBoundaryBox( int aIndexStart, int aIndexEnd )
{ {
CPolyPt start_point, end_point; CPolyPt start_point, end_point;

View File

@ -45,149 +45,9 @@
#define STRAIGHT 0 // To be remove after math_for_graphics code cleanup #define STRAIGHT 0 // To be remove after math_for_graphics code cleanup
/**
* Function AddArea
* Add an empty copper area to board areas list
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new areas pickers (useful
* in undo commands) can be NULL
* @param aNetcode = the necode of the copper area (0 = no net)
* @param aLayer = the layer of area
* @param aStartPointPosition = position of the first point of the polygon outline of this area
* @param aHatch = hacth option
* @return pointer to the new area
*/
ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
int aLayer, wxPoint aStartPointPosition, int aHatch )
{
ZONE_CONTAINER* new_area = InsertArea( aNetcode,
m_ZoneDescriptorList.size( ) - 1,
aLayer, aStartPointPosition.x,
aStartPointPosition.y, aHatch );
if( aNewZonesList )
{
ITEM_PICKER picker( new_area, UR_NEW );
aNewZonesList->PushItem( picker );
}
return new_area;
}
/**
* Function RemoveArea
* remove copper area from net, and put it in a deleted list (if exists)
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo
* commands) can be NULL
* @param area_to_remove = area to delete or put in deleted list
*/
void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to_remove )
{
if( area_to_remove == NULL )
return;
if( aDeletedList )
{
ITEM_PICKER picker( area_to_remove, UR_DELETED );
aDeletedList->PushItem( picker );
Remove( area_to_remove ); // remove from zone list, but does not delete it
}
else
{
Delete( area_to_remove );
}
}
/**
* Function InsertArea
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
* @return pointer to the new area
*/
ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch )
{
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
new_area->SetNet( netcode );
new_area->SetLayer( layer );
new_area->SetTimeStamp( GetNewTimeStamp() );
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
else
m_ZoneDescriptorList.push_back( new_area );
new_area->m_Poly->Start( layer, x, y, hatch );
return new_area;
}
/**
* Function NormalizeAreaPolygon
* Process an area that has been modified, by normalizing its polygon against itself.
* i.e. convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s)
* This may change the number and order of copper areas in the net.
* @param aNewZonesList = a PICKED_ITEMS_LIST * where to store new created areas
* @param aCurrArea = the zone to process
* @return true if changes are made
* Also sets areas->utility1 flags if areas are modified
*/
bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
ZONE_CONTAINER* aCurrArea )
{
CPolyLine* curr_polygon = aCurrArea->m_Poly;
// mark all areas as unmodified except this one, if modified
for( unsigned ia = 0; ia < m_ZoneDescriptorList.size(); ia++ )
m_ZoneDescriptorList[ia]->utility = 0;
aCurrArea->utility = 1;
if( curr_polygon->IsPolygonSelfIntersecting() )
{
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
curr_polygon->UnHatch();
int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa );
// If clipping has created some polygons, we must add these new copper areas.
if( n_poly > 1 )
{
ZONE_CONTAINER* NewArea;
for( int ip = 1; ip < n_poly; ip++ )
{
// create new copper area and copy poly into it
CPolyLine* new_p = (*pa)[ip - 1];
NewArea = AddArea( aNewZonesList, aCurrArea->GetNet(), aCurrArea->GetLayer(),
wxPoint(0, 0), CPolyLine::NO_HATCH );
// remove the poly that was automatically created for the new area
// and replace it with a poly from NormalizeAreaOutlines
delete NewArea->m_Poly;
NewArea->m_Poly = new_p;
NewArea->m_Poly->Hatch();
NewArea->utility = 1;
}
}
delete pa;
}
curr_polygon->Hatch();
return true;
}
/**
* Process an area that has been modified, by normalizing its polygon
* and merging the intersecting polygons for any other areas on the same net.
* This may change the number and order of copper areas in the net.
* @param aModifiedZonesList = a PICKED_ITEMS_LIST * where to store deleted or added areas
* (useful in undo commands can be NULL
* @param modified_area = area to test
* @return true if some areas modified
*/
bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList, bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
ZONE_CONTAINER* modified_area ) ZONE_CONTAINER* modified_area )
{ {
// clip polygon against itself // clip polygon against itself
bool modified = NormalizeAreaPolygon( aModifiedZonesList, modified_area ); bool modified = NormalizeAreaPolygon( aModifiedZonesList, modified_area );
@ -225,18 +85,8 @@ bool BOARD::OnAreaPolygonModified( PICKED_ITEMS_LIST* aModifiedZonesList,
} }
/**
* Function CombineAllAreasInNet
* Checks all copper areas in net for intersections, combining them if found
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful
* in undo commands can be NULL
* @param aNetCode = net to consider
* @param aUseUtility : if true, don't check areas if both utility flags are 0
* Sets utility flag = 1 for any areas modified
* @return true if some areas modified
*/
bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode, bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
bool aUseUtility ) bool aUseUtility )
{ {
if( m_ZoneDescriptorList.size() <= 1 ) if( m_ZoneDescriptorList.size() <= 1 )
return false; return false;
@ -247,11 +97,12 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ ) for( unsigned ia1 = 0; ia1 < m_ZoneDescriptorList.size() - 1; ia1++ )
{ {
ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1]; ZONE_CONTAINER* curr_area = m_ZoneDescriptorList[ia1];
if( curr_area->GetNet() != aNetCode ) if( curr_area->GetNet() != aNetCode )
continue; continue;
// legal polygon // legal polygon
CRect b1 = curr_area->m_Poly->GetCornerBounds(); CRect b1 = curr_area->Outline()->GetCornerBounds();
bool mod_ia1 = false; bool mod_ia1 = false;
for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- ) for( unsigned ia2 = m_ZoneDescriptorList.size() - 1; ia2 > ia1; ia2-- )
@ -270,12 +121,13 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
if( curr_area->GetLayer() != area2->GetLayer() ) if( curr_area->GetLayer() != area2->GetLayer() )
continue; continue;
CRect b2 = area2->m_Poly->GetCornerBounds(); CRect b2 = area2->Outline()->GetCornerBounds();
if( !( b1.left > b2.right || b1.right < b2.left if( !( b1.left > b2.right || b1.right < b2.left
|| b1.bottom > b2.top || b1.top < b2.bottom ) ) || b1.bottom > b2.top || b1.top < b2.bottom ) )
{ {
// check area2 against curr_area // check area2 against curr_area
if( curr_area->utility || area2->utility || aUseUtility == false ) if( curr_area->GetFlags() || area2->GetFlags() || aUseUtility == false )
{ {
bool ret = TestAreaIntersection( curr_area, area2 ); bool ret = TestAreaIntersection( curr_area, area2 );
@ -299,11 +151,6 @@ bool BOARD::CombineAllAreasInNet( PICKED_ITEMS_LIST* aDeletedList, int aNetCode,
} }
/**
* Function TestAreaIntersections
* Check for intersection of a given copper area with other areas in same net
* @param area_to_test = area to compare to all other areas in the same net
*/
bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
{ {
for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ ) for( unsigned ia2 = 0; ia2 < m_ZoneDescriptorList.size(); ia2++ )
@ -336,22 +183,14 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
} }
/**
* Function TestAreaIntersection
* Test for intersection of 2 copper areas
* area_to_test must be after area_ref in m_ZoneDescriptorList
* @param area_ref = area reference
* @param area_to_test = area to compare for intersection calculations
* @return : false if no intersection, true if intersection
*/
bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test ) bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_test )
{ {
// see if areas are on same layer // see if areas are on same layer
if( area_ref->GetLayer() != area_to_test->GetLayer() ) if( area_ref->GetLayer() != area_to_test->GetLayer() )
return false; return false;
CPolyLine* poly1 = area_ref->m_Poly; CPolyLine* poly1 = area_ref->Outline();
CPolyLine* poly2 = area_to_test->m_Poly; CPolyLine* poly2 = area_to_test->Outline();
// test bounding rects // test bounding rects
CRect b1 = poly1->GetCornerBounds(); CRect b1 = poly1->GetCornerBounds();
@ -443,20 +282,8 @@ bool BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area
} }
/**
* Function CombineAreas
* Merge 2 copper areas (which are expected intersecting)
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas
* (useful for undo command)
* @param area_ref = the main area (zone)
* @param area_to_combine = the zone that can be merged with area_ref
* area_ref must be BEFORE area_to_combine
* area_to_combine will be deleted, if areas are combined
* @return : true if area_to_combine is combined with area_ref (and therefore be deleted)
*/
bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref,
ZONE_CONTAINER* area_to_combine ) ZONE_CONTAINER* area_to_combine )
{ {
if( area_ref == area_to_combine ) if( area_ref == area_to_combine )
{ {
@ -467,8 +294,8 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_
// polygons intersect, combine them // polygons intersect, combine them
KI_POLYGON_WITH_HOLES areaRefPoly; KI_POLYGON_WITH_HOLES areaRefPoly;
KI_POLYGON_WITH_HOLES areaToMergePoly; KI_POLYGON_WITH_HOLES areaToMergePoly;
CopyPolysListToKiPolygonWithHole( area_ref->m_Poly->m_CornersList, areaRefPoly ); CopyPolysListToKiPolygonWithHole( area_ref->Outline()->m_CornersList, areaRefPoly );
CopyPolysListToKiPolygonWithHole( area_to_combine->m_Poly->m_CornersList, areaToMergePoly ); CopyPolysListToKiPolygonWithHole( area_to_combine->Outline()->m_CornersList, areaToMergePoly );
KI_POLYGON_WITH_HOLES_SET mergedOutlines; KI_POLYGON_WITH_HOLES_SET mergedOutlines;
mergedOutlines.push_back( areaRefPoly ); mergedOutlines.push_back( areaRefPoly );
@ -488,47 +315,48 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_
return false; return false;
areaRefPoly = mergedOutlines[0]; areaRefPoly = mergedOutlines[0];
area_ref->m_Poly->RemoveAllContours(); area_ref->Outline()->RemoveAllContours();
KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin(); KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin();
// create area with external contour: Recreate only area edges, NOT holes // create area with external contour: Recreate only area edges, NOT holes
area_ref->m_Poly->Start( area_ref->GetLayer(), corner->x(), corner->y(), area_ref->Outline()->Start( area_ref->GetLayer(), corner->x(), corner->y(),
area_ref->m_Poly->GetHatchStyle() ); area_ref->Outline()->GetHatchStyle() );
while( ++corner != areaRefPoly.end() ) while( ++corner != areaRefPoly.end() )
{ {
area_ref->m_Poly->AppendCorner( corner->x(), corner->y() ); area_ref->Outline()->AppendCorner( corner->x(), corner->y() );
} }
area_ref->m_Poly->CloseLastContour(); area_ref->Outline()->CloseLastContour();
// add holes (set of polygons) // add holes (set of polygons)
KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes(); KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes();
while( hole != areaRefPoly.end_holes() ) while( hole != areaRefPoly.end_holes() )
{ {
KI_POLYGON::iterator_type hole_corner = hole->begin(); KI_POLYGON::iterator_type hole_corner = hole->begin();
// create area with external contour: Recreate only area edges, NOT holes // create area with external contour: Recreate only area edges, NOT holes
while( hole_corner != hole->end() ) while( hole_corner != hole->end() )
{ {
area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() ); area_ref->Outline()->AppendCorner( hole_corner->x(), hole_corner->y() );
hole_corner++; hole_corner++;
} }
area_ref->m_Poly->CloseLastContour();
area_ref->Outline()->CloseLastContour();
hole++; hole++;
} }
RemoveArea( aDeletedList, area_to_combine ); RemoveArea( aDeletedList, area_to_combine );
area_ref->utility = 1; area_ref->SetFlags( 1 );
area_ref->m_Poly->Hatch(); area_ref->Outline()->Hatch();
return true; return true;
} }
/* Tests area outlines for DRC: areas inside other areas or too close.
* aArea_To_Examine: area to compare with other areas,
* or if NULL then all areas are compared to all others.
*/
int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine, int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
bool aCreate_Markers ) bool aCreate_Markers )
{ {
@ -713,15 +541,6 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
} }
/* tests a segment in ZONE_CONTAINER * aArea:
* Test Edge inside other areas
* Test Edge too close other areas
* aArea is the current area.
* aCornerIndex is the index of the first corner (starting point)
* of the edge segment to test.
* return false if DRC error or true if OK
*/
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
{ {
if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer
@ -733,7 +552,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
wxPoint end; wxPoint end;
// Search the end point of the edge starting at aCornerIndex // Search the end point of the edge starting at aCornerIndex
if( aArea->m_Poly->m_CornersList[aCornerIndex].end_contour == false if( aArea->Outline()->m_CornersList[aCornerIndex].end_contour == false
&& aCornerIndex < (aArea->GetNumCorners() - 1) ) && aCornerIndex < (aArea->GetNumCorners() - 1) )
{ {
end = aArea->GetCornerPosition( aCornerIndex + 1 ); end = aArea->GetCornerPosition( aCornerIndex + 1 );
@ -746,7 +565,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
while( ii >= 0 ) while( ii >= 0 )
{ {
if( aArea->m_Poly->m_CornersList[ii].end_contour ) if( aArea->Outline()->m_CornersList[ii].end_contour )
break; break;
end = aArea->GetCornerPosition( ii ); end = aArea->GetCornerPosition( ii );
@ -783,7 +602,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
zone_clearance = 1; zone_clearance = 1;
// test for ending line inside area_to_test // test for ending line inside area_to_test
if( area_to_test->m_Poly->TestPointInside( end.x, end.y ) ) if( area_to_test->Outline()->TestPointInside( end.x, end.y ) )
{ {
// COPPERAREA_COPPERAREA error: corner inside copper area // COPPERAREA_COPPERAREA error: corner inside copper area
m_currentMarker = fillMarker( aArea, end, m_currentMarker = fillMarker( aArea, end,
@ -798,26 +617,26 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
int ax2 = end.x; int ax2 = end.x;
int ay2 = end.y; int ay2 = end.y;
for( int icont2 = 0; icont2 < area_to_test->m_Poly->GetContoursCount(); icont2++ ) for( int icont2 = 0; icont2 < area_to_test->Outline()->GetContoursCount(); icont2++ )
{ {
int ic_start2 = area_to_test->m_Poly->GetContourStart( icont2 ); int ic_start2 = area_to_test->Outline()->GetContourStart( icont2 );
int ic_end2 = area_to_test->m_Poly->GetContourEnd( icont2 ); int ic_end2 = area_to_test->Outline()->GetContourEnd( icont2 );
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ ) for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
{ {
int bx1 = area_to_test->m_Poly->GetX( ic2 ); int bx1 = area_to_test->Outline()->GetX( ic2 );
int by1 = area_to_test->m_Poly->GetY( ic2 ); int by1 = area_to_test->Outline()->GetY( ic2 );
int bx2, by2; int bx2, by2;
if( ic2 == ic_end2 ) if( ic2 == ic_end2 )
{ {
bx2 = area_to_test->m_Poly->GetX( ic_start2 ); bx2 = area_to_test->Outline()->GetX( ic_start2 );
by2 = area_to_test->m_Poly->GetY( ic_start2 ); by2 = area_to_test->Outline()->GetY( ic_start2 );
} }
else else
{ {
bx2 = area_to_test->m_Poly->GetX( ic2 + 1 ); bx2 = area_to_test->Outline()->GetX( ic2 + 1 );
by2 = area_to_test->m_Poly->GetY( ic2 + 1 ); by2 = area_to_test->Outline()->GetY( ic2 + 1 );
} }
int x, y; // variables containing the intersecting point coordinates int x, y; // variables containing the intersecting point coordinates