Bugs about fill zones and block delete removed

This commit is contained in:
CHARRAS 2008-01-24 19:51:13 +00:00
parent 8237a9eb89
commit 4195d71fa2
9 changed files with 114 additions and 53 deletions

View File

@ -4,6 +4,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2008-Jan-24 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
Bugs about fill zones removed (not all, of course).
Fixed an old bug in block delete (could crashes pcbnew after deleting footprints).
2008-Jan-23 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew:

View File

@ -203,31 +203,41 @@ void DisplayBoard( WinEDA_DrawPanel* panel, wxDC* DC )
int dcell0, dcell1 = 0, color;
int maxi;
maxi = ( /*ActiveScreen->Lim_XD - 20*/ 500) / Ncols;
maxi = 600 / Ncols;
maxi = (maxi * 3 ) / 4;
if( !maxi )
maxi = 1;
GRSetDrawMode( DC, GR_COPY );
for( col = 0; col < Ncols; col++ )
{
for( row = 0; row < Nrows; row++ )
{
color = 0;
dcell0 = GetCell( row, col, BOTTOM ); if( dcell0 & HOLE )
dcell0 = GetCell( row, col, BOTTOM );
if( dcell0 & HOLE )
color = GREEN;
if( Nb_Sides )
dcell1 = GetCell( row, col, TOP );
// if( Nb_Sides )
// dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE )
color |= RED;
dcell0 |= dcell1;
// dcell0 |= dcell1;
if( !color && (dcell0 & VIA_IMPOSSIBLE) )
color = BLUE;
if( color )
if( dcell0 & CELL_is_EDGE )
color = YELLOW;
else if( dcell0 & CELL_is_ZONE )
color = YELLOW;
#define DRAW_OFFSET_X -20
#define DRAW_OFFSET_Y 20
// if( color )
{
for( i = 0; i < maxi; i++ )
for( j = 0; j < maxi; j++ )
GRSPutPixel( &panel->m_ClipBox, DC,
(col * maxi) + i + 10, (row * maxi) + 60 + j, color );
(col * maxi) + i + DRAW_OFFSET_X,
(row * maxi) + j + DRAW_OFFSET_Y, color );
}
}

View File

@ -579,6 +579,12 @@ void WinEDA_BasePcbFrame::Block_Delete( wxDC* DC )
DrawPanel->Refresh( TRUE );
if( g_Show_Ratsnest )
Compile_Ratsnest( DC, TRUE );
else
{
m_Pcb->m_Status_Pcb = 0; /* we need (later) a full ratnest computation */
build_liste_pads();
}
}

View File

@ -367,6 +367,7 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
/**
* Function HitTestForCorner
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* Choose the nearest corner
* "near" means CORNER_MIN_DIST_IN_PIXELS pixels
* @return -1 if none, corner index in .corner <vector>
* @param refPos : A wxPoint to test
@ -374,27 +375,32 @@ bool ZONE_CONTAINER::HitTest( const wxPoint& refPos )
int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
{
#define CORNER_MIN_DIST 500 // distance (in internal units) to detect a corner in a zone outline
int dist;
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
m_CornerSelection = -1;
min_dist = CORNER_MIN_DIST;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
dist = abs( m_Poly->corner[item_pos].x - refPos.x ) + abs( m_Poly->corner[item_pos].y - refPos.y );
if( dist <= CORNER_MIN_DIST )
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
return item_pos;
min_dist = dist;
}
}
if ( m_CornerSelection >= 0 )
return item_pos;
return -1;
}
/**
* Function HitTestForEdge
* tests if the given wxPoint near a corner, or near the segment define by 2 corners.
* choose the nearest segment
* "near" means EDGE_MIN_DIST_IN_PIXELS pixels
* @return -1 if none, or index of the starting corner in .corner <vector>
* @param refPos : A wxPoint to test
@ -402,13 +408,14 @@ int ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
{
#define EDGE_MIN_DIST 200 // distance (in internal units) to detect a zone outline
int dist;
int dist, min_dist;
unsigned item_pos, lim;
lim = m_Poly->corner.size();
/* Test for an entire segment */
unsigned first_corner_pos = 0, end_segm;
m_CornerSelection = -1;
min_dist = EDGE_MIN_DIST;
for ( item_pos = 0; item_pos < lim; item_pos++ )
{
@ -431,13 +438,16 @@ int ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
m_Poly->corner[item_pos].y,
m_Poly->corner[end_segm].x,
m_Poly->corner[end_segm].y );
if( dist <= EDGE_MIN_DIST )
if( dist <= min_dist )
{
m_CornerSelection = item_pos;
return item_pos;
min_dist = dist;
}
}
if ( m_CornerSelection >= 0 )
return item_pos;
return -1;
}

View File

@ -136,7 +136,7 @@ void WinEDA_ZoneFrame::CreateControls()
SetFont( *g_DialogFont );
////@begin WinEDA_ZoneFrame content construction
// Generated by DialogBlocks, 06/01/2008 15:03:35 (unregistered)
// Generated by DialogBlocks, 24/01/2008 11:39:58 (unregistered)
WinEDA_ZoneFrame* itemDialog1 = this;
@ -153,6 +153,7 @@ void WinEDA_ZoneFrame::CreateControls()
m_GridCtrlStrings.Add(_("0.00000"));
m_GridCtrlStrings.Add(_("0.00000"));
m_GridCtrlStrings.Add(_("0.00000"));
m_GridCtrlStrings.Add(_("0.00000"));
m_GridCtrl = new wxRadioBox( itemDialog1, ID_RADIOBOX_GRID_SELECTION, _("Grid Size for Filling:"), wxDefaultPosition, wxDefaultSize, m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS );
m_GridCtrl->SetSelection(0);
itemBoxSizer4->Add(m_GridCtrl, 0, wxGROW|wxALL, 5);
@ -260,7 +261,7 @@ void WinEDA_ZoneFrame::CreateControls()
if( Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
static const int GridList[3] = { 50, 100, 250 };
static const int GridList[4] = { 25, 50, 100, 250 };
int selection = 0;
for( unsigned ii = 0; ii < (unsigned) m_GridCtrl->GetCount(); ii++ )
@ -473,15 +474,19 @@ bool WinEDA_ZoneFrame::AcceptOptions(bool aPromptForErrors)
switch( m_GridCtrl->GetSelection() )
{
case 0:
g_GridRoutingSize = 50;
g_GridRoutingSize = 25;
break;
case 1:
g_GridRoutingSize = 100;
g_GridRoutingSize = 50;
break;
default:
case 2:
g_GridRoutingSize = 100;
break;
case 3:
g_GridRoutingSize = 250;
break;
}

View File

@ -248,6 +248,7 @@
<bool name="proxy-wxDEFAULT_DIALOG_STYLE">0</bool>
<bool name="proxy-wxCAPTION">1</bool>
<bool name="proxy-wxRESIZE_BORDER">0</bool>
<bool name="proxy-wxTHICK_FRAME">0</bool>
<bool name="proxy-wxSYSTEM_MENU">1</bool>
<bool name="proxy-wxSTAY_ON_TOP">0</bool>
<bool name="proxy-wxDIALOG_NO_PARENT">0</bool>
@ -368,7 +369,7 @@
<string name="proxy-Member variable name">"m_GridCtrl"</string>
<string name="proxy-Label">"Grid Size for Filling:"</string>
<long name="proxy-Major dimension count">1</long>
<string name="proxy-Items">"0.00000|0.00000|0.00000"</string>
<string name="proxy-Items">"0.00000|0.00000|0.00000|0.00000"</string>
<long name="proxy-Initial value">0</long>
<string name="proxy-Help text">""</string>
<string name="proxy-Tooltip text">""</string>

View File

@ -1,7 +1,7 @@
#makefile for pcbnew, Windows
WXDIR = $(WXWIN)
BOOST_LIB = /f/boost/boost_1_34_1
TARGET=pcbnew
include ../libs.win

View File

@ -1,6 +1,7 @@
EXTRALIBS = ../common/common.a ../polygon/lib_polygon.a
EXTRACPPFLAGS += -DPCBNEW -fno-strict-aliasing -I./ -Ibitmaps -I../include -I../share\
-I../pcbnew -I../3d-viewer -I../polygon
-I../pcbnew -I../3d-viewer -I../polygon -I$(BOOST_LIB)
#COMMON = pcbnew.h struct.h class_pad.h class_module.h class_text_mod.h \
# class_edge_mod.h class_equipot.h
@ -10,9 +11,11 @@ LIBVIEWER3D = ../3d-viewer/3d-viewer.a
ZONE_FILES = zones_by_polygon.o
#ZONE_FILES = zones.o
SPECCTRA_TOOLS = specctra.o specctra_export.o dsn.o
OBJECTS= $(TARGET).o classpcb.o\
$(ZONE_FILES)\
$(SPECCTRA_TOOLS)\
zones_test_and_combine_areas.o\
zone_filling_algorithm.o\
lay2plot.o\

View File

@ -17,7 +17,7 @@
static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, int layer );
/* Local variables */
static bool Zone_Debug = FALSE;
static bool Zone_Debug = false;
static unsigned long s_TimeStamp; /* Time stamp common to all segments relative to the new created zone */
/*****************************************************************************/
@ -42,7 +42,13 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
wxString msg;
BOARD* Pcb = frame->m_Pcb;
g_DesignSettings.m_TrackClearence = g_DesignSettings.m_ZoneClearence;
// Set the g_DesignSettings.m_TrackClearence (used to fill board map) to the max of m_TrackClearence and m_ZoneClearence
g_DesignSettings.m_TrackClearence = max ( g_DesignSettings.m_TrackClearence, g_DesignSettings.m_ZoneClearence);
// In order to avoid ends of segments used to fill the zone, and to the clearence the radius of ends
// which is g_GridRoutingSize/2
g_DesignSettings.m_TrackClearence += g_GridRoutingSize/2;
g_HightLigth_NetCode = m_NetCode;
s_TimeStamp = m_TimeStamp;
@ -50,8 +56,8 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
// Delete the old filling, if any :
frame->Delete_Zone_Fill( DC, NULL, m_TimeStamp );
// calculate the fixed step of the routing matrix as 5 mils or more
E_scale = g_GridRoutingSize / 50;
// calculate the fixed step of the routing matrix as 25 mils or more
E_scale = g_GridRoutingSize / 25;
if( g_GridRoutingSize < 1 )
g_GridRoutingSize = 1;
@ -59,8 +65,6 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
// calculate the Ncols and Nrows, size of the routing matrix
ComputeMatriceSize( frame, g_GridRoutingSize );
// Determine the cell pointed to by the mouse
// create the routing matrix in autorout.h's eda_global BOARDHEAD Board
Nb_Sides = ONE_SIDE;
if( Board.InitBoard() < 0 )
@ -88,6 +92,11 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
g_DesignSettings.m_CurrentTrackWidth = g_GridRoutingSize;
// trace the pcb edges (pcb contour) into the routing matrix
Route_Layer_BOTTOM = Route_Layer_TOP = EDGE_N;
PlaceCells( Pcb, -1, 0 );
Route_Layer_BOTTOM = Route_Layer_TOP = m_Layer;
/* Create the starting point for the zone:
* The starting point and all the tracks are suitable "starting points" */
TRACK* pt_segm = Pcb->m_Track;
@ -96,20 +105,14 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
if( g_HightLigth_NetCode != pt_segm->GetNet() )
continue;
if( pt_segm->GetLayer() != m_Layer )
if( ! pt_segm->IsOnLayer( m_Layer ) )
continue;
if( pt_segm->Type() != TYPETRACK )
continue;
// if( pt_segm->Type() != TYPETRACK )
// continue;
TraceSegmentPcb( Pcb, pt_segm, CELL_is_FRIEND, 0, WRITE_CELL );
}
// trace the pcb edges (pcb contour) into the routing matrix
Route_Layer_BOTTOM = Route_Layer_TOP = EDGE_N;
PlaceCells( Pcb, -1, 0 );
Route_Layer_BOTTOM = Route_Layer_TOP = m_Layer;
// trace the zone edges into the routing matrix
int i_start_contour = 0;
for( unsigned ic = 0; ic < m_Poly->corner.size(); ic++ )
@ -136,16 +139,21 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
int cells_count = 0;
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
{
wxPoint pos;
if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
if ( ! (*pad)->IsOnLayer( GetLayer() ) ) continue;
if ( (*pad)->GetNet() != GetNet() ) continue;
wxPoint pos = (*pad)->m_Pos;
if( m_Poly->TestPointInside( pos.x, pos.y ) )
{
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
pos -= Pcb->m_BoundaryBox.m_Pos;
ZoneStartFill.x = ( pos.x + (g_GridRoutingSize / 2) ) / g_GridRoutingSize;
ZoneStartFill.y = ( (*pad)->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
cells_count++;
ZoneStartFill.y = ( pos.y + (g_GridRoutingSize / 2) ) / g_GridRoutingSize;
BoardCell cell = GetCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM );
if ( (cell & CELL_is_EDGE) == 0 )
{
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
cells_count++;
}
}
}
@ -180,6 +188,10 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
}
}
if( Zone_Debug && DC )
{
DisplayBoard( frame->DrawPanel, DC );
}
// now, all the cell candidates are marked
// place all the obstacles into the matrix, such as (pads, tracks, vias,
@ -218,20 +230,21 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
* (could be deleted by PlaceCells()) : */
for( ii = 0, pad = frame->m_Pcb->m_Pads; ii < frame->m_Pcb->m_NbPads; ii++, pad++ )
{
wxPoint pos;
if( m_Poly->TestPointInside( (*pad)->m_Pos.x, (*pad)->m_Pos.y ) )
if ( ! (*pad)->IsOnLayer( GetLayer() ) ) continue;
if ( (*pad)->GetNet() != GetNet() ) continue;
wxPoint pos = (*pad)->m_Pos;
if( m_Poly->TestPointInside( pos.x, pos.y ) )
{
ZoneStartFill.x = ( (*pad)->m_Pos.x - Pcb->m_BoundaryBox.m_Pos.x +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
pos -= Pcb->m_BoundaryBox.m_Pos;
ZoneStartFill.x = ( pos.x + (g_GridRoutingSize / 2) ) / g_GridRoutingSize;
ZoneStartFill.y = ( (*pad)->m_Pos.y - Pcb->m_BoundaryBox.m_Pos.y +
(g_GridRoutingSize / 2) ) / g_GridRoutingSize;
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
ZoneStartFill.y = ( pos.y + (g_GridRoutingSize / 2) ) / g_GridRoutingSize;
BoardCell cell = GetCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM );
if ( (cell & CELL_is_EDGE) == 0 )
OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE );
}
}
if( Zone_Debug && DC )
DisplayBoard( frame->DrawPanel, DC );
/* Filling the cells of the matrix (this is the zone building)*/
ii = 1; jj = 1;
@ -242,6 +255,11 @@ int ZONE_CONTAINER::Fill_Zone( WinEDA_PcbFrame* frame, wxDC* DC, bool verbose )
ii = Propagation( frame );
}
if( Zone_Debug && DC )
{
DisplayBoard( frame->DrawPanel, DC );
}
// replace obstacles into the matrix(pads)
if( m_PadOption == THERMAL_PAD )
PlaceCells( Pcb, g_HightLigth_NetCode, FORCE_PADS );