From 6991b49691cee03c8e55ffb54fc0dca842768090 Mon Sep 17 00:00:00 2001 From: raburton Date: Wed, 19 Dec 2007 16:44:53 +0000 Subject: [PATCH] set eol-style native on new files --- pcbnew/dialog_zones_by_polygon.cpp | 906 ++++++++++---------- pcbnew/dialog_zones_by_polygon.h | 260 +++--- pcbnew/filling_zone_algorithm.cpp | 1224 ++++++++++++++-------------- pcbnew/zones_by_polygon.cpp | 1164 +++++++++++++------------- 4 files changed, 1777 insertions(+), 1777 deletions(-) diff --git a/pcbnew/dialog_zones_by_polygon.cpp b/pcbnew/dialog_zones_by_polygon.cpp index bd4421e3a6..8fc239fee6 100644 --- a/pcbnew/dialog_zones_by_polygon.cpp +++ b/pcbnew/dialog_zones_by_polygon.cpp @@ -1,453 +1,453 @@ -///////////////////////////////////////////////////////////////////////////// - -// Name: zones.cpp -// Purpose: -// Author: jean-pierre Charras -// Modified by: -// Created: 25/01/2006 11:35:19 -// RCS-ID: -// Copyright: GNU License -// Licence: GNU License -///////////////////////////////////////////////////////////////////////////// - -// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 - -#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA) -#pragma implementation "zones.h" -#endif - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -////@begin includes -////@end includes - -#include "dialog_zones_by_polygon.h" - -////@begin XPM images -////@end XPM images - -/*! - * WinEDA_ZoneFrame type definition - */ - -IMPLEMENT_DYNAMIC_CLASS( WinEDA_ZoneFrame, wxDialog ) - -/*! - * WinEDA_ZoneFrame event table definition - */ - -BEGIN_EVENT_TABLE( WinEDA_ZoneFrame, wxDialog ) - -////@begin WinEDA_ZoneFrame event table entries - EVT_BUTTON( ID_BUTTON, WinEDA_ZoneFrame::ExecFillZone ) - - EVT_BUTTON( wxID_CANCEL, WinEDA_ZoneFrame::OnCancelClick ) - - EVT_RADIOBOX( ID_NET_SORTING_OPTION, WinEDA_ZoneFrame::OnNetSortingOptionSelected ) - -////@end WinEDA_ZoneFrame event table entries - -END_EVENT_TABLE() - -/*! - * WinEDA_ZoneFrame constructors - */ - -WinEDA_ZoneFrame::WinEDA_ZoneFrame() -{ -} - - -WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, - wxWindowID id, - const wxString& caption, - const wxPoint& pos, - const wxSize& size, - long style ) -{ - m_Parent = parent; - Create( parent, id, caption, pos, size, style ); -} - - -/*! - * WinEDA_ZoneFrame creator - */ - -bool WinEDA_ZoneFrame::Create( wxWindow* parent, - wxWindowID id, - const wxString& caption, - const wxPoint& pos, - const wxSize& size, - long style ) -{ -////@begin WinEDA_ZoneFrame member initialisation - m_GridCtrl = NULL; - m_ClearanceValueTitle = NULL; - m_ZoneClearanceCtrl = NULL; - m_FillOpt = NULL; - m_OrientEdgesOpt = NULL; - m_NetSortingOption = NULL; - m_ListNetNameSelection = NULL; - m_LayerSelectionCtrl = NULL; -////@end WinEDA_ZoneFrame member initialisation - -////@begin WinEDA_ZoneFrame creation - SetExtraStyle(wxWS_EX_BLOCK_EVENTS); - wxDialog::Create( parent, id, caption, pos, size, style ); - - CreateControls(); - if (GetSizer()) - { - GetSizer()->SetSizeHints(this); - } - Centre(); -////@end WinEDA_ZoneFrame creation - - return true; -} - - -/*! - * Control creation for WinEDA_ZoneFrame - */ - -void WinEDA_ZoneFrame::CreateControls() -{ - SetFont( *g_DialogFont ); - -////@begin WinEDA_ZoneFrame content construction - // Generated by DialogBlocks, 17/12/2007 20:46:19 (unregistered) - - WinEDA_ZoneFrame* itemDialog1 = this; - - wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); - itemDialog1->SetSizer(itemBoxSizer2); - - wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL); - itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); - - wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxVERTICAL); - itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW|wxALL, 5); - - wxArrayString m_GridCtrlStrings; - 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_RADIOBOX3, _("Grid Size for Filling:"), wxDefaultPosition, wxDefaultSize, m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS ); - m_GridCtrl->SetSelection(0); - itemBoxSizer4->Add(m_GridCtrl, 0, wxGROW|wxALL, 5); - - m_ClearanceValueTitle = new wxStaticText( itemDialog1, wxID_STATIC, _("Zone clearance value (mm):"), wxDefaultPosition, wxDefaultSize, 0 ); - itemBoxSizer4->Add(m_ClearanceValueTitle, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); - - m_ZoneClearanceCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL1, _T(""), wxDefaultPosition, wxDefaultSize, 0 ); - itemBoxSizer4->Add(m_ZoneClearanceCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); - - itemBoxSizer3->Add(5, 5, 0, wxGROW|wxALL, 5); - - wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL); - itemBoxSizer3->Add(itemBoxSizer9, 0, wxGROW|wxALL, 5); - - wxArrayString m_FillOptStrings; - m_FillOptStrings.Add(_("Include Pads")); - m_FillOptStrings.Add(_("Thermal")); - m_FillOptStrings.Add(_("Exclude Pads")); - m_FillOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX4, _("Pad options:"), wxDefaultPosition, wxDefaultSize, m_FillOptStrings, 1, wxRA_SPECIFY_COLS ); - m_FillOpt->SetSelection(0); - itemBoxSizer9->Add(m_FillOpt, 0, wxGROW|wxALL, 5); - - wxArrayString m_OrientEdgesOptStrings; - m_OrientEdgesOptStrings.Add(_("Any")); - m_OrientEdgesOptStrings.Add(_("H , V and 45 deg")); - m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX5, _("Zone edges orient:"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptStrings, 1, wxRA_SPECIFY_COLS ); - m_OrientEdgesOpt->SetSelection(0); - itemBoxSizer9->Add(m_OrientEdgesOpt, 0, wxGROW|wxALL, 5); - - itemBoxSizer3->Add(5, 5, 0, wxGROW|wxALL, 5); - - wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxVERTICAL); - itemBoxSizer3->Add(itemBoxSizer13, 0, wxGROW|wxALL, 5); - - wxButton* itemButton14 = new wxButton( itemDialog1, ID_BUTTON, _("Fill"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton14->SetDefault(); - itemButton14->SetForegroundColour(wxColour(204, 0, 0)); - itemBoxSizer13->Add(itemButton14, 0, wxGROW|wxALL, 5); - - wxButton* itemButton15 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); - itemButton15->SetForegroundColour(wxColour(0, 0, 255)); - itemBoxSizer13->Add(itemButton15, 0, wxGROW|wxALL, 5); - - itemBoxSizer13->Add(5, 5, 1, wxGROW|wxALL, 5); - - wxArrayString m_NetSortingOptionStrings; - m_NetSortingOptionStrings.Add(_("Alphabetic")); - m_NetSortingOptionStrings.Add(_("Advanced")); - m_NetSortingOption = new wxRadioBox( itemDialog1, ID_NET_SORTING_OPTION, _("Net sorting:"), wxDefaultPosition, wxDefaultSize, m_NetSortingOptionStrings, 1, wxRA_SPECIFY_COLS ); - m_NetSortingOption->SetSelection(0); - itemBoxSizer13->Add(m_NetSortingOption, 0, wxGROW|wxALL, 5); - - wxBoxSizer* itemBoxSizer18 = new wxBoxSizer(wxVERTICAL); - itemBoxSizer2->Add(itemBoxSizer18, 0, wxGROW|wxALL, 5); - - wxStaticText* itemStaticText19 = new wxStaticText( itemDialog1, wxID_STATIC, _("Net:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemBoxSizer18->Add(itemStaticText19, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - - wxArrayString m_ListNetNameSelectionStrings; - m_ListNetNameSelection = new wxListBox( itemDialog1, ID_NETNAME_SELECTION, wxDefaultPosition, wxDefaultSize, m_ListNetNameSelectionStrings, wxLB_SINGLE|wxSUNKEN_BORDER ); - itemBoxSizer18->Add(m_ListNetNameSelection, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); - - wxStaticText* itemStaticText21 = new wxStaticText( itemDialog1, wxID_LAYER_SELECTION, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); - itemBoxSizer18->Add(itemStaticText21, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); - - wxArrayString m_LayerSelectionCtrlStrings; - m_LayerSelectionCtrl = new wxListBox( itemDialog1, ID_LAYER_CHOICE, wxDefaultPosition, wxDefaultSize, m_LayerSelectionCtrlStrings, wxLB_SINGLE ); - itemBoxSizer18->Add(m_LayerSelectionCtrl, 0, wxGROW|wxALL, 5); - - // Set validators - m_NetSortingOption->SetValidator( wxGenericValidator(& s_NetSortingOpt) ); -////@end WinEDA_ZoneFrame content construction - wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric ); - m_ClearanceValueTitle->SetLabel( title ); - - title = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );; - m_GridCtrl->SetLabel( title ); - - if( g_DesignSettings.m_ZoneClearence == 0 ) - g_DesignSettings.m_ZoneClearence = g_DesignSettings.m_TrackClearence; - title = ReturnStringFromValue( g_UnitMetric, - g_DesignSettings.m_ZoneClearence, - m_Parent->m_InternalUnits ); - m_ZoneClearanceCtrl->SetValue( title ); - - if( Zone_45_Only ) - m_OrientEdgesOpt->SetSelection( 1 ); - - static const int GridList[4] = { 50, 100, 250, 500 }; - int selection = 0; - - for( unsigned ii = 0; ii < (unsigned) m_GridCtrl->GetCount(); ii++ ) - { - wxString msg = ReturnStringFromValue( g_UnitMetric, - GridList[ii], - m_Parent->m_InternalUnits ); - m_GridCtrl->SetString( ii, msg ); - if( g_GridRoutingSize == GridList[ii] ) - selection = ii; - } - - // Initialise options - m_GridCtrl->SetSelection( selection ); - - if( Zone_Exclude_Pads ) - { - if( s_Zone_Create_Thermal_Relief ) - m_FillOpt->SetSelection( 1 ); - else - m_FillOpt->SetSelection( 2 ); - } - - m_NetSortingOption->SetSelection(s_NetSortingOpt == 0 ? : 1 ); - - int layer_cnt = g_DesignSettings.m_CopperLayerCount; - for( int ii = 0; ii < g_DesignSettings.m_CopperLayerCount; ii++ ) - { - wxString msg; - int layer_number; - if( layer_cnt == 0 || ii < layer_cnt - 1 ) - layer_number = ii; - else if( ii == layer_cnt - 1 ) - layer_number = LAYER_CMP_N; - m_LayerId[ii] = layer_number; - msg = ReturnPcbLayerName( layer_number ).Trim(); - m_LayerSelectionCtrl->InsertItems( 1, &msg, ii ); - if( m_Parent->GetScreen()->m_Active_Layer == layer_number ) - m_LayerSelectionCtrl->SetSelection( ii ); - } - - wxArrayString ListNetName; - m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, - s_NetSortingOpt == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); - m_ListNetNameSelection->InsertItems( ListNetName, 0 ); - - // Select net: - if( g_HightLigth_NetCode > 0 ) - { - EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( g_HightLigth_NetCode ); - if( equipot ) // Search net in list and select it - { - for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ ) - { - if( ListNetName[ii] == equipot->m_Netname ) - { - m_ListNetNameSelection->SetSelection( ii ); - break; - } - } - } - } -} - - -/*! - * Should we show tooltips? - */ - -bool WinEDA_ZoneFrame::ShowToolTips() -{ - return true; -} - - -/*! - * Get bitmap resources - */ - -wxBitmap WinEDA_ZoneFrame::GetBitmapResource( const wxString& name ) -{ - // Bitmap retrieval -////@begin WinEDA_ZoneFrame bitmap retrieval - wxUnusedVar(name); - return wxNullBitmap; -////@end WinEDA_ZoneFrame bitmap retrieval -} - - -/*! - * Get icon resources - */ - -wxIcon WinEDA_ZoneFrame::GetIconResource( const wxString& name ) -{ - // Icon retrieval -////@begin WinEDA_ZoneFrame icon retrieval - wxUnusedVar(name); - return wxNullIcon; -////@end WinEDA_ZoneFrame icon retrieval -} - - -/*! - * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL - */ - -void WinEDA_ZoneFrame::OnCancelClick( wxCommandEvent& event ) -{ -////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. - // Before editing this code, remove the block markers. - event.Skip(); -////@end wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. -} - - -/*! - * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON2 - */ -/***********************************************************/ -void WinEDA_ZoneFrame::ExecFillZone( wxCommandEvent& event ) -/***********************************************************/ -{ - switch( m_FillOpt->GetSelection() ) - { - case 0: - Zone_Exclude_Pads = FALSE; - s_Zone_Create_Thermal_Relief = FALSE; - break; - - case 1: - Zone_Exclude_Pads = TRUE; - s_Zone_Create_Thermal_Relief = TRUE; - break; - - case 2: - Zone_Exclude_Pads = TRUE; - s_Zone_Create_Thermal_Relief = FALSE; - break; - } - - switch( m_GridCtrl->GetSelection() ) - { - case 0: - g_GridRoutingSize = 50; - break; - - case 1: - g_GridRoutingSize = 100; - break; - - case 2: - g_GridRoutingSize = 250; - break; - - case 3: - g_GridRoutingSize = 500; - break; - } - - wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); - g_DesignSettings.m_ZoneClearence = - ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits ); - if( m_OrientEdgesOpt->GetSelection() == 0 ) - Zone_45_Only = FALSE; - else - Zone_45_Only = TRUE; - - /* Get the layer selection for this zone */ - int ii = m_LayerSelectionCtrl->GetSelection(); - if( ii < 0 ) - { - DisplayError( this, _( "Error : you must choose a layer" ) ); - return; - } - s_Zone_Layer = m_LayerId[ii]; - - /* Get the net name selection for this zone */ - ii = m_ListNetNameSelection->GetSelection(); - if( ii < 0 ) - { - DisplayError( this, _( "Error : you must choose a net name" ) ); - return; - } - - wxString net_name = m_ListNetNameSelection->GetString( ii ); - - /* Search net_code for this net */ - EQUIPOT* net; - s_NetcodeSelection = 0; - for( net = m_Parent->m_Pcb->m_Equipots; net; net = net->Next() ) - { - if( net->m_Netname == net_name ) - { - s_NetcodeSelection = net->GetNet(); - break; - } - } - - EndModal( 0 ); -} - - -/*! - * wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_NET_SORTING_OPTION - */ - -void WinEDA_ZoneFrame::OnNetSortingOptionSelected( wxCommandEvent& event ) -{ - wxArrayString ListNetName; - s_NetSortingOpt = m_NetSortingOption->GetSelection(); - m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, - s_NetSortingOpt == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); - m_ListNetNameSelection->Clear(); - m_ListNetNameSelection->InsertItems( ListNetName, 0 ); -} - +///////////////////////////////////////////////////////////////////////////// + +// Name: zones.cpp +// Purpose: +// Author: jean-pierre Charras +// Modified by: +// Created: 25/01/2006 11:35:19 +// RCS-ID: +// Copyright: GNU License +// Licence: GNU License +///////////////////////////////////////////////////////////////////////////// + +// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 + +#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA) +#pragma implementation "zones.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + +#include "dialog_zones_by_polygon.h" + +////@begin XPM images +////@end XPM images + +/*! + * WinEDA_ZoneFrame type definition + */ + +IMPLEMENT_DYNAMIC_CLASS( WinEDA_ZoneFrame, wxDialog ) + +/*! + * WinEDA_ZoneFrame event table definition + */ + +BEGIN_EVENT_TABLE( WinEDA_ZoneFrame, wxDialog ) + +////@begin WinEDA_ZoneFrame event table entries + EVT_BUTTON( ID_BUTTON, WinEDA_ZoneFrame::ExecFillZone ) + + EVT_BUTTON( wxID_CANCEL, WinEDA_ZoneFrame::OnCancelClick ) + + EVT_RADIOBOX( ID_NET_SORTING_OPTION, WinEDA_ZoneFrame::OnNetSortingOptionSelected ) + +////@end WinEDA_ZoneFrame event table entries + +END_EVENT_TABLE() + +/*! + * WinEDA_ZoneFrame constructors + */ + +WinEDA_ZoneFrame::WinEDA_ZoneFrame() +{ +} + + +WinEDA_ZoneFrame::WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, + wxWindowID id, + const wxString& caption, + const wxPoint& pos, + const wxSize& size, + long style ) +{ + m_Parent = parent; + Create( parent, id, caption, pos, size, style ); +} + + +/*! + * WinEDA_ZoneFrame creator + */ + +bool WinEDA_ZoneFrame::Create( wxWindow* parent, + wxWindowID id, + const wxString& caption, + const wxPoint& pos, + const wxSize& size, + long style ) +{ +////@begin WinEDA_ZoneFrame member initialisation + m_GridCtrl = NULL; + m_ClearanceValueTitle = NULL; + m_ZoneClearanceCtrl = NULL; + m_FillOpt = NULL; + m_OrientEdgesOpt = NULL; + m_NetSortingOption = NULL; + m_ListNetNameSelection = NULL; + m_LayerSelectionCtrl = NULL; +////@end WinEDA_ZoneFrame member initialisation + +////@begin WinEDA_ZoneFrame creation + SetExtraStyle(wxWS_EX_BLOCK_EVENTS); + wxDialog::Create( parent, id, caption, pos, size, style ); + + CreateControls(); + if (GetSizer()) + { + GetSizer()->SetSizeHints(this); + } + Centre(); +////@end WinEDA_ZoneFrame creation + + return true; +} + + +/*! + * Control creation for WinEDA_ZoneFrame + */ + +void WinEDA_ZoneFrame::CreateControls() +{ + SetFont( *g_DialogFont ); + +////@begin WinEDA_ZoneFrame content construction + // Generated by DialogBlocks, 17/12/2007 20:46:19 (unregistered) + + WinEDA_ZoneFrame* itemDialog1 = this; + + wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL); + itemDialog1->SetSizer(itemBoxSizer2); + + wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW|wxALL, 5); + + wxArrayString m_GridCtrlStrings; + 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_RADIOBOX3, _("Grid Size for Filling:"), wxDefaultPosition, wxDefaultSize, m_GridCtrlStrings, 1, wxRA_SPECIFY_COLS ); + m_GridCtrl->SetSelection(0); + itemBoxSizer4->Add(m_GridCtrl, 0, wxGROW|wxALL, 5); + + m_ClearanceValueTitle = new wxStaticText( itemDialog1, wxID_STATIC, _("Zone clearance value (mm):"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer4->Add(m_ClearanceValueTitle, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP|wxADJUST_MINSIZE, 5); + + m_ZoneClearanceCtrl = new wxTextCtrl( itemDialog1, ID_TEXTCTRL1, _T(""), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer4->Add(m_ZoneClearanceCtrl, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); + + itemBoxSizer3->Add(5, 5, 0, wxGROW|wxALL, 5); + + wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer3->Add(itemBoxSizer9, 0, wxGROW|wxALL, 5); + + wxArrayString m_FillOptStrings; + m_FillOptStrings.Add(_("Include Pads")); + m_FillOptStrings.Add(_("Thermal")); + m_FillOptStrings.Add(_("Exclude Pads")); + m_FillOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX4, _("Pad options:"), wxDefaultPosition, wxDefaultSize, m_FillOptStrings, 1, wxRA_SPECIFY_COLS ); + m_FillOpt->SetSelection(0); + itemBoxSizer9->Add(m_FillOpt, 0, wxGROW|wxALL, 5); + + wxArrayString m_OrientEdgesOptStrings; + m_OrientEdgesOptStrings.Add(_("Any")); + m_OrientEdgesOptStrings.Add(_("H , V and 45 deg")); + m_OrientEdgesOpt = new wxRadioBox( itemDialog1, ID_RADIOBOX5, _("Zone edges orient:"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptStrings, 1, wxRA_SPECIFY_COLS ); + m_OrientEdgesOpt->SetSelection(0); + itemBoxSizer9->Add(m_OrientEdgesOpt, 0, wxGROW|wxALL, 5); + + itemBoxSizer3->Add(5, 5, 0, wxGROW|wxALL, 5); + + wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer3->Add(itemBoxSizer13, 0, wxGROW|wxALL, 5); + + wxButton* itemButton14 = new wxButton( itemDialog1, ID_BUTTON, _("Fill"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton14->SetDefault(); + itemButton14->SetForegroundColour(wxColour(204, 0, 0)); + itemBoxSizer13->Add(itemButton14, 0, wxGROW|wxALL, 5); + + wxButton* itemButton15 = new wxButton( itemDialog1, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); + itemButton15->SetForegroundColour(wxColour(0, 0, 255)); + itemBoxSizer13->Add(itemButton15, 0, wxGROW|wxALL, 5); + + itemBoxSizer13->Add(5, 5, 1, wxGROW|wxALL, 5); + + wxArrayString m_NetSortingOptionStrings; + m_NetSortingOptionStrings.Add(_("Alphabetic")); + m_NetSortingOptionStrings.Add(_("Advanced")); + m_NetSortingOption = new wxRadioBox( itemDialog1, ID_NET_SORTING_OPTION, _("Net sorting:"), wxDefaultPosition, wxDefaultSize, m_NetSortingOptionStrings, 1, wxRA_SPECIFY_COLS ); + m_NetSortingOption->SetSelection(0); + itemBoxSizer13->Add(m_NetSortingOption, 0, wxGROW|wxALL, 5); + + wxBoxSizer* itemBoxSizer18 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer2->Add(itemBoxSizer18, 0, wxGROW|wxALL, 5); + + wxStaticText* itemStaticText19 = new wxStaticText( itemDialog1, wxID_STATIC, _("Net:"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer18->Add(itemStaticText19, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); + + wxArrayString m_ListNetNameSelectionStrings; + m_ListNetNameSelection = new wxListBox( itemDialog1, ID_NETNAME_SELECTION, wxDefaultPosition, wxDefaultSize, m_ListNetNameSelectionStrings, wxLB_SINGLE|wxSUNKEN_BORDER ); + itemBoxSizer18->Add(m_ListNetNameSelection, 0, wxGROW|wxLEFT|wxRIGHT|wxBOTTOM, 5); + + wxStaticText* itemStaticText21 = new wxStaticText( itemDialog1, wxID_LAYER_SELECTION, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer18->Add(itemStaticText21, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5); + + wxArrayString m_LayerSelectionCtrlStrings; + m_LayerSelectionCtrl = new wxListBox( itemDialog1, ID_LAYER_CHOICE, wxDefaultPosition, wxDefaultSize, m_LayerSelectionCtrlStrings, wxLB_SINGLE ); + itemBoxSizer18->Add(m_LayerSelectionCtrl, 0, wxGROW|wxALL, 5); + + // Set validators + m_NetSortingOption->SetValidator( wxGenericValidator(& s_NetSortingOpt) ); +////@end WinEDA_ZoneFrame content construction + wxString title = _( "Zone clearance value:" ) + ReturnUnitSymbol( g_UnitMetric ); + m_ClearanceValueTitle->SetLabel( title ); + + title = _( "Grid :" ) + ReturnUnitSymbol( g_UnitMetric );; + m_GridCtrl->SetLabel( title ); + + if( g_DesignSettings.m_ZoneClearence == 0 ) + g_DesignSettings.m_ZoneClearence = g_DesignSettings.m_TrackClearence; + title = ReturnStringFromValue( g_UnitMetric, + g_DesignSettings.m_ZoneClearence, + m_Parent->m_InternalUnits ); + m_ZoneClearanceCtrl->SetValue( title ); + + if( Zone_45_Only ) + m_OrientEdgesOpt->SetSelection( 1 ); + + static const int GridList[4] = { 50, 100, 250, 500 }; + int selection = 0; + + for( unsigned ii = 0; ii < (unsigned) m_GridCtrl->GetCount(); ii++ ) + { + wxString msg = ReturnStringFromValue( g_UnitMetric, + GridList[ii], + m_Parent->m_InternalUnits ); + m_GridCtrl->SetString( ii, msg ); + if( g_GridRoutingSize == GridList[ii] ) + selection = ii; + } + + // Initialise options + m_GridCtrl->SetSelection( selection ); + + if( Zone_Exclude_Pads ) + { + if( s_Zone_Create_Thermal_Relief ) + m_FillOpt->SetSelection( 1 ); + else + m_FillOpt->SetSelection( 2 ); + } + + m_NetSortingOption->SetSelection(s_NetSortingOpt == 0 ? : 1 ); + + int layer_cnt = g_DesignSettings.m_CopperLayerCount; + for( int ii = 0; ii < g_DesignSettings.m_CopperLayerCount; ii++ ) + { + wxString msg; + int layer_number; + if( layer_cnt == 0 || ii < layer_cnt - 1 ) + layer_number = ii; + else if( ii == layer_cnt - 1 ) + layer_number = LAYER_CMP_N; + m_LayerId[ii] = layer_number; + msg = ReturnPcbLayerName( layer_number ).Trim(); + m_LayerSelectionCtrl->InsertItems( 1, &msg, ii ); + if( m_Parent->GetScreen()->m_Active_Layer == layer_number ) + m_LayerSelectionCtrl->SetSelection( ii ); + } + + wxArrayString ListNetName; + m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, + s_NetSortingOpt == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); + m_ListNetNameSelection->InsertItems( ListNetName, 0 ); + + // Select net: + if( g_HightLigth_NetCode > 0 ) + { + EQUIPOT* equipot = m_Parent->m_Pcb->FindNet( g_HightLigth_NetCode ); + if( equipot ) // Search net in list and select it + { + for( unsigned ii = 0; ii < ListNetName.GetCount(); ii++ ) + { + if( ListNetName[ii] == equipot->m_Netname ) + { + m_ListNetNameSelection->SetSelection( ii ); + break; + } + } + } + } +} + + +/*! + * Should we show tooltips? + */ + +bool WinEDA_ZoneFrame::ShowToolTips() +{ + return true; +} + + +/*! + * Get bitmap resources + */ + +wxBitmap WinEDA_ZoneFrame::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin WinEDA_ZoneFrame bitmap retrieval + wxUnusedVar(name); + return wxNullBitmap; +////@end WinEDA_ZoneFrame bitmap retrieval +} + + +/*! + * Get icon resources + */ + +wxIcon WinEDA_ZoneFrame::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin WinEDA_ZoneFrame icon retrieval + wxUnusedVar(name); + return wxNullIcon; +////@end WinEDA_ZoneFrame icon retrieval +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL + */ + +void WinEDA_ZoneFrame::OnCancelClick( wxCommandEvent& event ) +{ +////@begin wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. + // Before editing this code, remove the block markers. + event.Skip(); +////@end wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL in WinEDA_ZoneFrame. +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON2 + */ +/***********************************************************/ +void WinEDA_ZoneFrame::ExecFillZone( wxCommandEvent& event ) +/***********************************************************/ +{ + switch( m_FillOpt->GetSelection() ) + { + case 0: + Zone_Exclude_Pads = FALSE; + s_Zone_Create_Thermal_Relief = FALSE; + break; + + case 1: + Zone_Exclude_Pads = TRUE; + s_Zone_Create_Thermal_Relief = TRUE; + break; + + case 2: + Zone_Exclude_Pads = TRUE; + s_Zone_Create_Thermal_Relief = FALSE; + break; + } + + switch( m_GridCtrl->GetSelection() ) + { + case 0: + g_GridRoutingSize = 50; + break; + + case 1: + g_GridRoutingSize = 100; + break; + + case 2: + g_GridRoutingSize = 250; + break; + + case 3: + g_GridRoutingSize = 500; + break; + } + + wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); + g_DesignSettings.m_ZoneClearence = + ReturnValueFromString( g_UnitMetric, txtvalue, m_Parent->m_InternalUnits ); + if( m_OrientEdgesOpt->GetSelection() == 0 ) + Zone_45_Only = FALSE; + else + Zone_45_Only = TRUE; + + /* Get the layer selection for this zone */ + int ii = m_LayerSelectionCtrl->GetSelection(); + if( ii < 0 ) + { + DisplayError( this, _( "Error : you must choose a layer" ) ); + return; + } + s_Zone_Layer = m_LayerId[ii]; + + /* Get the net name selection for this zone */ + ii = m_ListNetNameSelection->GetSelection(); + if( ii < 0 ) + { + DisplayError( this, _( "Error : you must choose a net name" ) ); + return; + } + + wxString net_name = m_ListNetNameSelection->GetString( ii ); + + /* Search net_code for this net */ + EQUIPOT* net; + s_NetcodeSelection = 0; + for( net = m_Parent->m_Pcb->m_Equipots; net; net = net->Next() ) + { + if( net->m_Netname == net_name ) + { + s_NetcodeSelection = net->GetNet(); + break; + } + } + + EndModal( 0 ); +} + + +/*! + * wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_NET_SORTING_OPTION + */ + +void WinEDA_ZoneFrame::OnNetSortingOptionSelected( wxCommandEvent& event ) +{ + wxArrayString ListNetName; + s_NetSortingOpt = m_NetSortingOption->GetSelection(); + m_Parent->m_Pcb->ReturnSortedNetnamesList( ListNetName, + s_NetSortingOpt == 0 ? BOARD::ALPHA_SORT : BOARD::PAD_CNT_SORT ); + m_ListNetNameSelection->Clear(); + m_ListNetNameSelection->InsertItems( ListNetName, 0 ); +} + diff --git a/pcbnew/dialog_zones_by_polygon.h b/pcbnew/dialog_zones_by_polygon.h index 03a586b311..5ed9c26b58 100644 --- a/pcbnew/dialog_zones_by_polygon.h +++ b/pcbnew/dialog_zones_by_polygon.h @@ -1,130 +1,130 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: dialog_zones_by_polygon.h -// Purpose: -// Author: jean-pierre Charras -// Modified by: -// Created: 25/01/2006 11:35:19 -// RCS-ID: -// Copyright: GNU License -// Licence: -///////////////////////////////////////////////////////////////////////////// - -// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 - -#ifndef DIALOG_ZONES_H_ -#define DIALOG_ZONES_H_ - -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma interface "dialog_zones_by_polygon.h" -#endif - -/*! - * Includes - */ - -////@begin includes -#include "wx/valgen.h" -////@end includes - -/*! - * Forward declarations - */ - -////@begin forward declarations -////@end forward declarations - -/*! - * Control identifiers - */ - -////@begin control identifiers -#define ID_DIALOG 10000 -#define ID_RADIOBOX3 10003 -#define ID_TEXTCTRL1 10007 -#define ID_RADIOBOX4 10008 -#define ID_RADIOBOX5 10009 -#define ID_BUTTON 10010 -#define ID_NET_SORTING_OPTION 10005 -#define ID_NETNAME_SELECTION 10001 -#define wxID_LAYER_SELECTION 10004 -#define ID_LAYER_CHOICE 10002 -#define SYMBOL_WINEDA_ZONEFRAME_STYLE wxCAPTION|wxSYSTEM_MENU|wxCLOSE_BOX|MAYBE_RESIZE_BORDER -#define SYMBOL_WINEDA_ZONEFRAME_TITLE _("Fill Zones Options") -#define SYMBOL_WINEDA_ZONEFRAME_IDNAME ID_DIALOG -#define SYMBOL_WINEDA_ZONEFRAME_SIZE wxSize(400, 300) -#define SYMBOL_WINEDA_ZONEFRAME_POSITION wxDefaultPosition -////@end control identifiers - -/*! - * Compatibility - */ - -#ifndef wxCLOSE_BOX -#define wxCLOSE_BOX 0x1000 -#endif - -/*! - * WinEDA_ZoneFrame class declaration - */ - -class WinEDA_ZoneFrame: public wxDialog -{ - DECLARE_DYNAMIC_CLASS( WinEDA_ZoneFrame ) - DECLARE_EVENT_TABLE() - -public: - /// Constructors - WinEDA_ZoneFrame( ); - WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE ); - - /// Creation - bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE ); - - /// Creates the controls and sizers - void CreateControls(); - -////@begin WinEDA_ZoneFrame event handler declarations - - /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON - void ExecFillZone( wxCommandEvent& event ); - - /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL - void OnCancelClick( wxCommandEvent& event ); - - /// wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_NET_SORTING_OPTION - void OnNetSortingOptionSelected( wxCommandEvent& event ); - -////@end WinEDA_ZoneFrame event handler declarations - -////@begin WinEDA_ZoneFrame member function declarations - - /// Retrieves bitmap resources - wxBitmap GetBitmapResource( const wxString& name ); - - /// Retrieves icon resources - wxIcon GetIconResource( const wxString& name ); -////@end WinEDA_ZoneFrame member function declarations - - /// Should we show tooltips? - static bool ShowToolTips(); - - - -////@begin WinEDA_ZoneFrame member variables - wxRadioBox* m_GridCtrl; - wxStaticText* m_ClearanceValueTitle; - wxTextCtrl* m_ZoneClearanceCtrl; - wxRadioBox* m_FillOpt; - wxRadioBox* m_OrientEdgesOpt; - wxRadioBox* m_NetSortingOption; - wxListBox* m_ListNetNameSelection; - wxListBox* m_LayerSelectionCtrl; -////@end WinEDA_ZoneFrame member variables - - WinEDA_PcbFrame * m_Parent; - - int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl -}; - -#endif // DIALOG_ZONES_H_ - +///////////////////////////////////////////////////////////////////////////// +// Name: dialog_zones_by_polygon.h +// Purpose: +// Author: jean-pierre Charras +// Modified by: +// Created: 25/01/2006 11:35:19 +// RCS-ID: +// Copyright: GNU License +// Licence: +///////////////////////////////////////////////////////////////////////////// + +// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 + +#ifndef DIALOG_ZONES_H_ +#define DIALOG_ZONES_H_ + +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) +#pragma interface "dialog_zones_by_polygon.h" +#endif + +/*! + * Includes + */ + +////@begin includes +#include "wx/valgen.h" +////@end includes + +/*! + * Forward declarations + */ + +////@begin forward declarations +////@end forward declarations + +/*! + * Control identifiers + */ + +////@begin control identifiers +#define ID_DIALOG 10000 +#define ID_RADIOBOX3 10003 +#define ID_TEXTCTRL1 10007 +#define ID_RADIOBOX4 10008 +#define ID_RADIOBOX5 10009 +#define ID_BUTTON 10010 +#define ID_NET_SORTING_OPTION 10005 +#define ID_NETNAME_SELECTION 10001 +#define wxID_LAYER_SELECTION 10004 +#define ID_LAYER_CHOICE 10002 +#define SYMBOL_WINEDA_ZONEFRAME_STYLE wxCAPTION|wxSYSTEM_MENU|wxCLOSE_BOX|MAYBE_RESIZE_BORDER +#define SYMBOL_WINEDA_ZONEFRAME_TITLE _("Fill Zones Options") +#define SYMBOL_WINEDA_ZONEFRAME_IDNAME ID_DIALOG +#define SYMBOL_WINEDA_ZONEFRAME_SIZE wxSize(400, 300) +#define SYMBOL_WINEDA_ZONEFRAME_POSITION wxDefaultPosition +////@end control identifiers + +/*! + * Compatibility + */ + +#ifndef wxCLOSE_BOX +#define wxCLOSE_BOX 0x1000 +#endif + +/*! + * WinEDA_ZoneFrame class declaration + */ + +class WinEDA_ZoneFrame: public wxDialog +{ + DECLARE_DYNAMIC_CLASS( WinEDA_ZoneFrame ) + DECLARE_EVENT_TABLE() + +public: + /// Constructors + WinEDA_ZoneFrame( ); + WinEDA_ZoneFrame( WinEDA_PcbFrame* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE ); + + /// Creation + bool Create( wxWindow* parent, wxWindowID id = SYMBOL_WINEDA_ZONEFRAME_IDNAME, const wxString& caption = SYMBOL_WINEDA_ZONEFRAME_TITLE, const wxPoint& pos = SYMBOL_WINEDA_ZONEFRAME_POSITION, const wxSize& size = SYMBOL_WINEDA_ZONEFRAME_SIZE, long style = SYMBOL_WINEDA_ZONEFRAME_STYLE ); + + /// Creates the controls and sizers + void CreateControls(); + +////@begin WinEDA_ZoneFrame event handler declarations + + /// wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON + void ExecFillZone( wxCommandEvent& event ); + + /// wxEVT_COMMAND_BUTTON_CLICKED event handler for wxID_CANCEL + void OnCancelClick( wxCommandEvent& event ); + + /// wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_NET_SORTING_OPTION + void OnNetSortingOptionSelected( wxCommandEvent& event ); + +////@end WinEDA_ZoneFrame event handler declarations + +////@begin WinEDA_ZoneFrame member function declarations + + /// Retrieves bitmap resources + wxBitmap GetBitmapResource( const wxString& name ); + + /// Retrieves icon resources + wxIcon GetIconResource( const wxString& name ); +////@end WinEDA_ZoneFrame member function declarations + + /// Should we show tooltips? + static bool ShowToolTips(); + + + +////@begin WinEDA_ZoneFrame member variables + wxRadioBox* m_GridCtrl; + wxStaticText* m_ClearanceValueTitle; + wxTextCtrl* m_ZoneClearanceCtrl; + wxRadioBox* m_FillOpt; + wxRadioBox* m_OrientEdgesOpt; + wxRadioBox* m_NetSortingOption; + wxListBox* m_ListNetNameSelection; + wxListBox* m_LayerSelectionCtrl; +////@end WinEDA_ZoneFrame member variables + + WinEDA_PcbFrame * m_Parent; + + int m_LayerId[LAYER_COUNT]; // Handle the real layer number from layer name position in m_LayerSelectionCtrl +}; + +#endif // DIALOG_ZONES_H_ + diff --git a/pcbnew/filling_zone_algorithm.cpp b/pcbnew/filling_zone_algorithm.cpp index 724a65cbd2..c77538c225 100644 --- a/pcbnew/filling_zone_algorithm.cpp +++ b/pcbnew/filling_zone_algorithm.cpp @@ -1,612 +1,612 @@ -/* filling_zone_algorithm: -Algos used to fill a zone defined by a polygon and a filling starting point -*/ - -#include "fctsys.h" -#include "gr_basic.h" - -#include "common.h" -#include "pcbnew.h" - -#include "autorout.h" -#include "cell.h" -#include "trigo.h" -#include "protos.h" - -/* Local functions */ -static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code ); - -/* Local variables */ -static bool Zone_Debug = FALSE; -static unsigned long s_TimeStamp; /* Time stamp common to all segments relative to the new created zone */ - -/****************************************************************************************/ -void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, - bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief ) -/****************************************************************************************/ - -/** Function Build_Zone() - * Init the zone filling - * If a zone edge is found, it is used. - * Otherwise the whole board is filled by the zone - * The zone edge is a frontier, and can be complex. So non filled zones can be achieved - * The zone is put on the active layer - * If a net is hightlighted, the zone will be attached to this net - * The filling start from a starting point. - * If a net is selected, all tracks attached to this net are also starting points - */ -{ - int ii, jj; - EDGE_ZONE* PtLim; - int lp_tmp, lay_tmp_TOP, lay_tmp_BOTTOM; - int save_isol = g_DesignSettings.m_TrackClearence; - wxPoint ZoneStartFill; - wxString msg; - PCB_SCREEN * Screen = frame->GetScreen(); - BOARD * Pcb = frame->m_Pcb; - - - g_DesignSettings.m_TrackClearence = g_DesignSettings.m_ZoneClearence; - - - s_TimeStamp = time( NULL ); - - // calculate the fixed step of the routing matrix as 5 mils or more - E_scale = g_GridRoutingSize / 50; - - if( g_GridRoutingSize < 1 ) - g_GridRoutingSize = 1; - - // calculate the Ncols and Nrows, size of the routing matrix - ComputeMatriceSize( frame, g_GridRoutingSize ); - - // Determine the cell pointed to by the mouse - ZoneStartFill.x = ( Screen->m_Curseur.x - Pcb->m_BoundaryBox.m_Pos.x + - (g_GridRoutingSize / 2) ) / g_GridRoutingSize; - - ZoneStartFill.y = ( Screen->m_Curseur.y - Pcb->m_BoundaryBox.m_Pos.y + - (g_GridRoutingSize / 2) ) / g_GridRoutingSize; - - if( ZoneStartFill.x < 0 ) - ZoneStartFill.x = 0; - - if( ZoneStartFill.x >= Ncols ) - ZoneStartFill.x = Ncols - 1; - - if( ZoneStartFill.y < 0 ) - ZoneStartFill.y = 0; - - if( ZoneStartFill.y >= Nrows ) - ZoneStartFill.y = Nrows - 1; - - // create the routing matrix in autorout.h's eda_global BOARDHEAD Board - Nb_Sides = ONE_SIDE; - if( Board.InitBoard() < 0 ) - { - DisplayError( frame, wxT( "Mo memory for creating zones" ) ); - return; - } - - msg.Printf( wxT( "%d" ), Ncols ); - Affiche_1_Parametre( frame, 1, wxT( "Cols" ), msg, GREEN ); - - msg.Printf( wxT( "%d" ), Nrows ); - Affiche_1_Parametre( frame, 7, wxT( "Lines" ), msg, GREEN ); - - msg.Printf( wxT( "%d" ), Board.m_MemSize / 1024 ); - Affiche_1_Parametre( frame, 14, wxT( "Mem(Ko)" ), msg, CYAN ); - - lay_tmp_BOTTOM = Route_Layer_BOTTOM; - lay_tmp_TOP = Route_Layer_TOP; - - Route_Layer_BOTTOM = Route_Layer_TOP = Screen->m_Active_Layer; - lp_tmp = g_DesignSettings.m_CurrentTrackWidth; - g_DesignSettings.m_CurrentTrackWidth = g_GridRoutingSize; - - - /* Create the starting point for thz zone: - * The starting point and all the tracks are suitable "starting points" */ - TRACK* pt_segm = Pcb->m_Track; - for( ; pt_segm != NULL; pt_segm = pt_segm->Next() ) - { - if( g_HightLigth_NetCode != pt_segm->GetNet() ) - continue; - - if( pt_segm->GetLayer() != Screen->m_Active_Layer ) - 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 = Screen->m_Active_Layer; - - // trace the zone edges into the routing matrix - for( PtLim = Pcb->m_CurrentLimitZone; PtLim; PtLim=PtLim->Next() ) - { - int ux0, uy0, ux1, uy1; - ux0 = PtLim->m_Start.x - Pcb->m_BoundaryBox.m_Pos.x; - uy0 = PtLim->m_Start.y - Pcb->m_BoundaryBox.m_Pos.y; - ux1 = PtLim->m_End.x - Pcb->m_BoundaryBox.m_Pos.x; - uy1 = PtLim->m_End.y - Pcb->m_BoundaryBox.m_Pos.y; - TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); - } - - OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE ); - - // mark the cells forming part of the zone - ii = 1; jj = 1; - while( ii ) - { - msg.Printf( wxT( "%d" ), jj++ ); - Affiche_1_Parametre( frame, 50, wxT( "Iter." ), msg, CYAN ); - ii = Propagation( frame ); - } - - // selection of the suitable cells for the points of anchoring of the zone - for( ii = 0; ii < Nrows; ii++ ) - { - for( jj = 0; jj < Ncols; jj++ ) - { - long cell = GetCell( ii, jj, BOTTOM ); - if( (cell & CELL_is_ZONE) ) - { - if( (cell & CELL_is_FRIEND) == 0 ) - AndCell( ii, jj, BOTTOM, (BoardCell) ~(CELL_is_FRIEND | CELL_is_ZONE) ); - } - } - } - - // now, all the cell candidates are marked - - // place all the obstacles into the matrix, such as (pads, tracks, vias, - // pcb edges or segments) - ii = 0; - if( Zone_Exclude_Pads ) - ii = FORCE_PADS; - - Affiche_1_Parametre( frame, 42, wxT( "GenZone" ), wxEmptyString, RED ); - PlaceCells( Pcb, g_HightLigth_NetCode, ii ); - Affiche_1_Parametre( frame, -1, wxEmptyString, _( "Ok" ), RED ); - - /* Create zone limits on the routing matrix - * (colud be deleted by PlaceCells()) : */ - for( PtLim = Pcb->m_CurrentLimitZone; PtLim; PtLim = PtLim->Next() ) - { - int ux0, uy0, ux1, uy1; - ux0 = PtLim->m_Start.x - Pcb->m_BoundaryBox.m_Pos.x; - uy0 = PtLim->m_Start.y - Pcb->m_BoundaryBox.m_Pos.y; - ux1 = PtLim->m_End.x - Pcb->m_BoundaryBox.m_Pos.x; - uy1 = PtLim->m_End.y - Pcb->m_BoundaryBox.m_Pos.y; - TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); - } - - /* Init the starting point for zone filling : this is the mouse position - * (could be deleted by PlaceCells()) : */ - OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE ); - - if( Zone_Debug ) - DisplayBoard( frame->DrawPanel, DC ); - - /* Filling the cells of the matrix (tjis is the zone building)*/ - ii = 1; jj = 1; - while( ii ) - { - msg.Printf( wxT( "%d" ), jj++ ); - Affiche_1_Parametre( frame, 50, wxT( "Iter." ), msg, CYAN ); - ii = Propagation( frame ); - } - - if( Zone_Debug ) - DisplayBoard( frame->DrawPanel, DC ); - - /* Convert the matrix information (cells) to segments which are actually the zone */ - if( g_HightLigth_NetCode < 0 ) - Genere_Segments_Zone( frame, DC, 0 ); - else - Genere_Segments_Zone( frame, DC, g_HightLigth_NetCode ); - - /* Create the thermal reliefs */ - g_DesignSettings.m_CurrentTrackWidth = lp_tmp; - if( Zone_Exclude_Pads && Zone_Create_Thermal_Relief ) - frame->Genere_Pad_Connexion( DC, Screen->m_Active_Layer ); - - g_DesignSettings.m_TrackClearence = save_isol; - - // free the memory - Board.UnInitBoard(); - - // restore original values unchanged - Route_Layer_TOP = lay_tmp_TOP; - Route_Layer_BOTTOM = lay_tmp_BOTTOM; -} - - - -/*******************************************************************************/ -static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code ) -/*******************************************************************************/ - -/** Function Genere_Segments_Zone() - * Create the zone segments from the routing matrix structure - * Algorithm: - * Search for consecutive cells (flagged "zone") , and create segments -* from the first cell to the last cell in the matrix - * 2 searchs are made - * 1 - From left to right and create horizontal zone segments - * 2 - From top to bottom, and create vertical zone segmùents - * @param net_code = net_code common to all segment zone created - * @param DC = current device context - * @param frame = current WinEDA_PcbFrame - * global: parameter TimeStamp: time stamp common to all segment zone created - */ -{ - int row, col; - long current_cell, old_cell; - int ux0 = 0, uy0 = 0, ux1 = 0, uy1 = 0; - int Xmin = frame->m_Pcb->m_BoundaryBox.m_Pos.x; - int Ymin = frame->m_Pcb->m_BoundaryBox.m_Pos.y; - SEGZONE* pt_track; - int layer = frame->GetScreen()->m_Active_Layer; - int nbsegm = 0; - wxString msg; - - /* balayage Gauche-> droite */ - Affiche_1_Parametre( frame, 64, wxT( "Segm H" ), wxT( "0" ), BROWN ); - for( row = 0; row < Nrows; row++ ) - { - old_cell = 0; - uy0 = uy1 = (row * g_GridRoutingSize) + Ymin; - for( col = 0; col < Ncols; col++ ) - { - current_cell = GetCell( row, col, BOTTOM ) & CELL_is_ZONE; - if( current_cell ) /* ce point doit faire partie d'un segment */ - { - ux1 = (col * g_GridRoutingSize) + Xmin; - if( old_cell == 0 ) - ux0 = ux1; - } - - if( !current_cell || (col == Ncols - 1) ) /* peut etre fin d'un segment */ - { - if( (old_cell) && (ux0 != ux1) ) - { - /* un segment avait debute de longueur > 0 */ - pt_track = new SEGZONE( frame->m_Pcb ); - pt_track->SetLayer( layer ); - pt_track->SetNet( net_code ); - - pt_track->m_Width = g_GridRoutingSize; - - pt_track->m_Start.x = ux0; - pt_track->m_Start.y = uy0; - - pt_track->m_End.x = ux1; - pt_track->m_End.y = uy1; - - pt_track->m_TimeStamp = s_TimeStamp; - - pt_track->Insert( frame->m_Pcb, NULL ); - pt_track->Draw( frame->DrawPanel, DC, GR_OR ); - nbsegm++; - } - } - old_cell = current_cell; - } - - msg.Printf( wxT( "%d" ), nbsegm ); - Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN ); - } - - Affiche_1_Parametre( frame, 72, wxT( "Segm V" ), wxT( "0" ), BROWN ); - for( col = 0; col < Ncols; col++ ) - { - old_cell = 0; - ux0 = ux1 = (col * g_GridRoutingSize) + Xmin; - for( row = 0; row < Nrows; row++ ) - { - current_cell = GetCell( row, col, BOTTOM ) & CELL_is_ZONE; - if( current_cell ) /* ce point doit faire partie d'un segment */ - { - uy1 = (row * g_GridRoutingSize) + Ymin; - if( old_cell == 0 ) - uy0 = uy1; - } - if( !current_cell || (row == Nrows - 1) ) /* peut etre fin d'un segment */ - { - if( (old_cell) && (uy0 != uy1) ) - { - /* un segment avait debute de longueur > 0 */ - pt_track = new SEGZONE( frame->m_Pcb ); - pt_track->SetLayer( layer ); - pt_track->m_Width = g_GridRoutingSize; - pt_track->SetNet( net_code ); - - pt_track->m_Start.x = ux0; - pt_track->m_Start.y = uy0; - - pt_track->m_End.x = ux1; - pt_track->m_End.y = uy1; - - pt_track->m_TimeStamp = s_TimeStamp; - pt_track->Insert( frame->m_Pcb, NULL ); - pt_track->Draw( frame->DrawPanel, DC, GR_OR ); - nbsegm++; - } - } - old_cell = current_cell; - } - - msg.Printf( wxT( "%d" ), nbsegm ); - Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN ); - } -} - - -/********************************************/ -int Propagation( WinEDA_PcbFrame* frame ) -/********************************************/ - -/** Function Propagation() - * An important function to calculate zones - * Uses the routing matrix to fill the cells within the zone - * Search and mark cells within the zone, and agree with DRC options. - * Requirements: - * Start from an initial point, to fill zone - * The zone must have no "copper island" - * Algorithm: - * If the current cell has a neightbour flagged as "cell in the zone", it - * become a cell in the zone - * The first point in the zone is the starting point - * 4 searches within the matrix are made: - * 1 - Left to right and top to bottom - * 2 - Right to left and top to bottom - * 3 - bottom to top and Right to left - * 4 - bottom to top and Left to right - * Given the current cell, for each search, we consider the 2 neightbour cells - * the previous cell on the same line and the previous cell on the same column. - * - * This funtion can request some iterations - * Iterations are made until no cell is added to the zone. - * @return: added cells count (i.e. which the attribute CELL_is_ZONE is set) - */ -{ - int row, col, nn; - long current_cell, old_cell_H; - int long* pt_cell_V; - int nbpoints = 0; - -#define NO_CELL_ZONE (HOLE | CELL_is_EDGE | CELL_is_ZONE) - wxString msg; - - Affiche_1_Parametre( frame, 57, wxT( "Detect" ), msg, CYAN ); - Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "1" ), CYAN ); - - // Alloc memory to handle 1 line or 1 colunmn on the routing matrix - nn = MAX( Nrows, Ncols ) * sizeof(*pt_cell_V); - pt_cell_V = (long*) MyMalloc( nn ); - - /* search 1 : from left to right and top to bottom */ - memset( pt_cell_V, 0, nn ); - for( row = 0; row < Nrows; row++ ) - { - old_cell_H = 0; - for( col = 0; col < Ncols; col++ ) - { - current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; - if( current_cell == 0 ) /* a free cell is found */ - { - if( (old_cell_H & CELL_is_ZONE) - || (pt_cell_V[col] & CELL_is_ZONE) ) - { - OrCell( row, col, BOTTOM, CELL_is_ZONE ); - current_cell = CELL_is_ZONE; - nbpoints++; - } - } - pt_cell_V[col] = old_cell_H = current_cell; - } - } - - /* search 2 : from right to left and top to bottom */ - Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "2" ), CYAN ); - memset( pt_cell_V, 0, nn ); - for( row = 0; row < Nrows; row++ ) - { - old_cell_H = 0; - for( col = Ncols - 1; col >= 0; col-- ) - { - current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; - if( current_cell == 0 ) /* a free cell is found */ - { - if( (old_cell_H & CELL_is_ZONE) - || (pt_cell_V[col] & CELL_is_ZONE) ) - { - OrCell( row, col, BOTTOM, CELL_is_ZONE ); - current_cell = CELL_is_ZONE; - nbpoints++; - } - } - pt_cell_V[col] = old_cell_H = current_cell; - } - } - - /* search 3 : from bottom to top and right to left balayage */ - Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "3" ), CYAN ); - memset( pt_cell_V, 0, nn ); - for( col = Ncols - 1; col >= 0; col-- ) - { - old_cell_H = 0; - for( row = Nrows - 1; row >= 0; row-- ) - { - current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; - if( current_cell == 0 ) /* a free cell is found */ - { - if( (old_cell_H & CELL_is_ZONE) - || (pt_cell_V[row] & CELL_is_ZONE) ) - { - OrCell( row, col, BOTTOM, CELL_is_ZONE ); - current_cell = CELL_is_ZONE; - nbpoints++; - } - } - pt_cell_V[row] = old_cell_H = current_cell; - } - } - - /* search 4 : from bottom to top and left to right */ - Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "4" ), CYAN ); - memset( pt_cell_V, 0, nn ); - for( col = 0; col < Ncols; col++ ) - { - old_cell_H = 0; - for( row = Nrows - 1; row >= 0; row-- ) - { - current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; - if( current_cell == 0 ) /* a free cell is found */ - { - if( (old_cell_H & CELL_is_ZONE) - || (pt_cell_V[row] & CELL_is_ZONE) ) - { - OrCell( row, col, BOTTOM, CELL_is_ZONE ); - current_cell = CELL_is_ZONE; - nbpoints++; - } - } - pt_cell_V[row] = old_cell_H = current_cell; - } - } - - MyFree( pt_cell_V ); - - return nbpoints; -} - - -/*****************************************************************************/ -bool WinEDA_PcbFrame::Genere_Pad_Connexion( wxDC* DC, int layer ) -/*****************************************************************************/ - -/* Create the thermal relief for each pad in the zone: - * this is 4 small segments from the pad to the zone - */ -{ - int ii, jj, Npads; - D_PAD* pt_pad; - LISTE_PAD* pt_liste_pad; - TRACK* pt_track, * loctrack; - int angle; - int cX, cY, dx, dy; - int sommet[4][2]; - wxString msg; - - if( m_Pcb->m_Zone == NULL ) - return FALSE; /* error: no zone */ - - if( m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */ - return FALSE; - - /* Count the pads, i.e. the thermal relief to create count, and displays it */ - Affiche_1_Parametre( this, 50, wxT( "NPads" ), wxT( " " ), CYAN ); - pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; - for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) - { - pt_pad = *pt_liste_pad; - - /* Search pads relative to the selected net code */ - if( pt_pad->GetNet() != g_HightLigth_NetCode ) - continue; - - /* Is the pad on the active layer ? */ - if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) - continue; - Npads++; - } - - msg.Printf( wxT( "%d" ), Npads ); - Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); - - /* Create the thermal reliefs */ - Affiche_1_Parametre( this, 57, wxT( "Pads" ), wxT( " " ), CYAN ); - pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; - for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) - { - pt_pad = *pt_liste_pad; - - /* Search pads relative to the selected net code */ - if( pt_pad->GetNet() != g_HightLigth_NetCode ) - continue; - /* Is the pad on the active layer ? */ - if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) - continue; - - /* Create the theram relief for the current pad */ - Npads++; - - msg.Printf( wxT( "%d" ), Npads ); - Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); - - cX = pt_pad->GetPosition().x; - cY = pt_pad->GetPosition().y; - - dx = pt_pad->m_Size.x / 2; - dy = pt_pad->m_Size.y / 2; - - dx += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; - dy += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; - - if( pt_pad->m_PadShape == TRAPEZE ) - { - dx += abs( pt_pad->m_DeltaSize.y ) / 2; - dy += abs( pt_pad->m_DeltaSize.x ) / 2; - } - - /* calculate the 4 segment coordintes (starting from the pad centre cX,cY) */ - sommet[0][0] = 0; sommet[0][1] = -dy; - sommet[1][0] = -dx; sommet[1][1] = 0; - sommet[2][0] = 0; sommet[2][1] = dy; - sommet[3][0] = dx; sommet[3][1] = 0; - - angle = pt_pad->m_Orient; - for( jj = 0; jj < 4; jj++ ) - { - RotatePoint( &sommet[jj][0], &sommet[jj][1], angle ); - - pt_track = new SEGZONE( m_Pcb ); - - pt_track->SetLayer( layer ); - pt_track->m_Width = g_DesignSettings.m_CurrentTrackWidth; - pt_track->SetNet( g_HightLigth_NetCode ); - pt_track->start = pt_pad; - pt_track->m_Start.x = cX; pt_track->m_Start.y = cY; - pt_track->m_End.x = cX + sommet[jj][0]; - pt_track->m_End.y = cY + sommet[jj][1]; - pt_track->m_TimeStamp = s_TimeStamp; - - /* Test if the segment is allowed */ - if( BAD_DRC==m_drc->DrcBlind( pt_track, m_Pcb->m_Track ) ) - { - delete pt_track; - continue; - } - - /* Search for a zone segment */ - loctrack = Locate_Zone( m_Pcb->m_Zone, pt_track->m_End, layer ); - if( (loctrack == NULL) || (loctrack->m_TimeStamp != s_TimeStamp) ) - { - delete pt_track; - continue; - } - - pt_track->Insert( m_Pcb, NULL ); - pt_track->Draw( DrawPanel, DC, GR_OR ); - } - } - - return TRUE; -} +/* filling_zone_algorithm: +Algos used to fill a zone defined by a polygon and a filling starting point +*/ + +#include "fctsys.h" +#include "gr_basic.h" + +#include "common.h" +#include "pcbnew.h" + +#include "autorout.h" +#include "cell.h" +#include "trigo.h" +#include "protos.h" + +/* Local functions */ +static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code ); + +/* Local variables */ +static bool Zone_Debug = FALSE; +static unsigned long s_TimeStamp; /* Time stamp common to all segments relative to the new created zone */ + +/****************************************************************************************/ +void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, + bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief ) +/****************************************************************************************/ + +/** Function Build_Zone() + * Init the zone filling + * If a zone edge is found, it is used. + * Otherwise the whole board is filled by the zone + * The zone edge is a frontier, and can be complex. So non filled zones can be achieved + * The zone is put on the active layer + * If a net is hightlighted, the zone will be attached to this net + * The filling start from a starting point. + * If a net is selected, all tracks attached to this net are also starting points + */ +{ + int ii, jj; + EDGE_ZONE* PtLim; + int lp_tmp, lay_tmp_TOP, lay_tmp_BOTTOM; + int save_isol = g_DesignSettings.m_TrackClearence; + wxPoint ZoneStartFill; + wxString msg; + PCB_SCREEN * Screen = frame->GetScreen(); + BOARD * Pcb = frame->m_Pcb; + + + g_DesignSettings.m_TrackClearence = g_DesignSettings.m_ZoneClearence; + + + s_TimeStamp = time( NULL ); + + // calculate the fixed step of the routing matrix as 5 mils or more + E_scale = g_GridRoutingSize / 50; + + if( g_GridRoutingSize < 1 ) + g_GridRoutingSize = 1; + + // calculate the Ncols and Nrows, size of the routing matrix + ComputeMatriceSize( frame, g_GridRoutingSize ); + + // Determine the cell pointed to by the mouse + ZoneStartFill.x = ( Screen->m_Curseur.x - Pcb->m_BoundaryBox.m_Pos.x + + (g_GridRoutingSize / 2) ) / g_GridRoutingSize; + + ZoneStartFill.y = ( Screen->m_Curseur.y - Pcb->m_BoundaryBox.m_Pos.y + + (g_GridRoutingSize / 2) ) / g_GridRoutingSize; + + if( ZoneStartFill.x < 0 ) + ZoneStartFill.x = 0; + + if( ZoneStartFill.x >= Ncols ) + ZoneStartFill.x = Ncols - 1; + + if( ZoneStartFill.y < 0 ) + ZoneStartFill.y = 0; + + if( ZoneStartFill.y >= Nrows ) + ZoneStartFill.y = Nrows - 1; + + // create the routing matrix in autorout.h's eda_global BOARDHEAD Board + Nb_Sides = ONE_SIDE; + if( Board.InitBoard() < 0 ) + { + DisplayError( frame, wxT( "Mo memory for creating zones" ) ); + return; + } + + msg.Printf( wxT( "%d" ), Ncols ); + Affiche_1_Parametre( frame, 1, wxT( "Cols" ), msg, GREEN ); + + msg.Printf( wxT( "%d" ), Nrows ); + Affiche_1_Parametre( frame, 7, wxT( "Lines" ), msg, GREEN ); + + msg.Printf( wxT( "%d" ), Board.m_MemSize / 1024 ); + Affiche_1_Parametre( frame, 14, wxT( "Mem(Ko)" ), msg, CYAN ); + + lay_tmp_BOTTOM = Route_Layer_BOTTOM; + lay_tmp_TOP = Route_Layer_TOP; + + Route_Layer_BOTTOM = Route_Layer_TOP = Screen->m_Active_Layer; + lp_tmp = g_DesignSettings.m_CurrentTrackWidth; + g_DesignSettings.m_CurrentTrackWidth = g_GridRoutingSize; + + + /* Create the starting point for thz zone: + * The starting point and all the tracks are suitable "starting points" */ + TRACK* pt_segm = Pcb->m_Track; + for( ; pt_segm != NULL; pt_segm = pt_segm->Next() ) + { + if( g_HightLigth_NetCode != pt_segm->GetNet() ) + continue; + + if( pt_segm->GetLayer() != Screen->m_Active_Layer ) + 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 = Screen->m_Active_Layer; + + // trace the zone edges into the routing matrix + for( PtLim = Pcb->m_CurrentLimitZone; PtLim; PtLim=PtLim->Next() ) + { + int ux0, uy0, ux1, uy1; + ux0 = PtLim->m_Start.x - Pcb->m_BoundaryBox.m_Pos.x; + uy0 = PtLim->m_Start.y - Pcb->m_BoundaryBox.m_Pos.y; + ux1 = PtLim->m_End.x - Pcb->m_BoundaryBox.m_Pos.x; + uy1 = PtLim->m_End.y - Pcb->m_BoundaryBox.m_Pos.y; + TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); + } + + OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE ); + + // mark the cells forming part of the zone + ii = 1; jj = 1; + while( ii ) + { + msg.Printf( wxT( "%d" ), jj++ ); + Affiche_1_Parametre( frame, 50, wxT( "Iter." ), msg, CYAN ); + ii = Propagation( frame ); + } + + // selection of the suitable cells for the points of anchoring of the zone + for( ii = 0; ii < Nrows; ii++ ) + { + for( jj = 0; jj < Ncols; jj++ ) + { + long cell = GetCell( ii, jj, BOTTOM ); + if( (cell & CELL_is_ZONE) ) + { + if( (cell & CELL_is_FRIEND) == 0 ) + AndCell( ii, jj, BOTTOM, (BoardCell) ~(CELL_is_FRIEND | CELL_is_ZONE) ); + } + } + } + + // now, all the cell candidates are marked + + // place all the obstacles into the matrix, such as (pads, tracks, vias, + // pcb edges or segments) + ii = 0; + if( Zone_Exclude_Pads ) + ii = FORCE_PADS; + + Affiche_1_Parametre( frame, 42, wxT( "GenZone" ), wxEmptyString, RED ); + PlaceCells( Pcb, g_HightLigth_NetCode, ii ); + Affiche_1_Parametre( frame, -1, wxEmptyString, _( "Ok" ), RED ); + + /* Create zone limits on the routing matrix + * (colud be deleted by PlaceCells()) : */ + for( PtLim = Pcb->m_CurrentLimitZone; PtLim; PtLim = PtLim->Next() ) + { + int ux0, uy0, ux1, uy1; + ux0 = PtLim->m_Start.x - Pcb->m_BoundaryBox.m_Pos.x; + uy0 = PtLim->m_Start.y - Pcb->m_BoundaryBox.m_Pos.y; + ux1 = PtLim->m_End.x - Pcb->m_BoundaryBox.m_Pos.x; + uy1 = PtLim->m_End.y - Pcb->m_BoundaryBox.m_Pos.y; + TraceLignePcb( ux0, uy0, ux1, uy1, -1, HOLE | CELL_is_EDGE, WRITE_CELL ); + } + + /* Init the starting point for zone filling : this is the mouse position + * (could be deleted by PlaceCells()) : */ + OrCell( ZoneStartFill.y, ZoneStartFill.x, BOTTOM, CELL_is_ZONE ); + + if( Zone_Debug ) + DisplayBoard( frame->DrawPanel, DC ); + + /* Filling the cells of the matrix (tjis is the zone building)*/ + ii = 1; jj = 1; + while( ii ) + { + msg.Printf( wxT( "%d" ), jj++ ); + Affiche_1_Parametre( frame, 50, wxT( "Iter." ), msg, CYAN ); + ii = Propagation( frame ); + } + + if( Zone_Debug ) + DisplayBoard( frame->DrawPanel, DC ); + + /* Convert the matrix information (cells) to segments which are actually the zone */ + if( g_HightLigth_NetCode < 0 ) + Genere_Segments_Zone( frame, DC, 0 ); + else + Genere_Segments_Zone( frame, DC, g_HightLigth_NetCode ); + + /* Create the thermal reliefs */ + g_DesignSettings.m_CurrentTrackWidth = lp_tmp; + if( Zone_Exclude_Pads && Zone_Create_Thermal_Relief ) + frame->Genere_Pad_Connexion( DC, Screen->m_Active_Layer ); + + g_DesignSettings.m_TrackClearence = save_isol; + + // free the memory + Board.UnInitBoard(); + + // restore original values unchanged + Route_Layer_TOP = lay_tmp_TOP; + Route_Layer_BOTTOM = lay_tmp_BOTTOM; +} + + + +/*******************************************************************************/ +static void Genere_Segments_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code ) +/*******************************************************************************/ + +/** Function Genere_Segments_Zone() + * Create the zone segments from the routing matrix structure + * Algorithm: + * Search for consecutive cells (flagged "zone") , and create segments +* from the first cell to the last cell in the matrix + * 2 searchs are made + * 1 - From left to right and create horizontal zone segments + * 2 - From top to bottom, and create vertical zone segmùents + * @param net_code = net_code common to all segment zone created + * @param DC = current device context + * @param frame = current WinEDA_PcbFrame + * global: parameter TimeStamp: time stamp common to all segment zone created + */ +{ + int row, col; + long current_cell, old_cell; + int ux0 = 0, uy0 = 0, ux1 = 0, uy1 = 0; + int Xmin = frame->m_Pcb->m_BoundaryBox.m_Pos.x; + int Ymin = frame->m_Pcb->m_BoundaryBox.m_Pos.y; + SEGZONE* pt_track; + int layer = frame->GetScreen()->m_Active_Layer; + int nbsegm = 0; + wxString msg; + + /* balayage Gauche-> droite */ + Affiche_1_Parametre( frame, 64, wxT( "Segm H" ), wxT( "0" ), BROWN ); + for( row = 0; row < Nrows; row++ ) + { + old_cell = 0; + uy0 = uy1 = (row * g_GridRoutingSize) + Ymin; + for( col = 0; col < Ncols; col++ ) + { + current_cell = GetCell( row, col, BOTTOM ) & CELL_is_ZONE; + if( current_cell ) /* ce point doit faire partie d'un segment */ + { + ux1 = (col * g_GridRoutingSize) + Xmin; + if( old_cell == 0 ) + ux0 = ux1; + } + + if( !current_cell || (col == Ncols - 1) ) /* peut etre fin d'un segment */ + { + if( (old_cell) && (ux0 != ux1) ) + { + /* un segment avait debute de longueur > 0 */ + pt_track = new SEGZONE( frame->m_Pcb ); + pt_track->SetLayer( layer ); + pt_track->SetNet( net_code ); + + pt_track->m_Width = g_GridRoutingSize; + + pt_track->m_Start.x = ux0; + pt_track->m_Start.y = uy0; + + pt_track->m_End.x = ux1; + pt_track->m_End.y = uy1; + + pt_track->m_TimeStamp = s_TimeStamp; + + pt_track->Insert( frame->m_Pcb, NULL ); + pt_track->Draw( frame->DrawPanel, DC, GR_OR ); + nbsegm++; + } + } + old_cell = current_cell; + } + + msg.Printf( wxT( "%d" ), nbsegm ); + Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN ); + } + + Affiche_1_Parametre( frame, 72, wxT( "Segm V" ), wxT( "0" ), BROWN ); + for( col = 0; col < Ncols; col++ ) + { + old_cell = 0; + ux0 = ux1 = (col * g_GridRoutingSize) + Xmin; + for( row = 0; row < Nrows; row++ ) + { + current_cell = GetCell( row, col, BOTTOM ) & CELL_is_ZONE; + if( current_cell ) /* ce point doit faire partie d'un segment */ + { + uy1 = (row * g_GridRoutingSize) + Ymin; + if( old_cell == 0 ) + uy0 = uy1; + } + if( !current_cell || (row == Nrows - 1) ) /* peut etre fin d'un segment */ + { + if( (old_cell) && (uy0 != uy1) ) + { + /* un segment avait debute de longueur > 0 */ + pt_track = new SEGZONE( frame->m_Pcb ); + pt_track->SetLayer( layer ); + pt_track->m_Width = g_GridRoutingSize; + pt_track->SetNet( net_code ); + + pt_track->m_Start.x = ux0; + pt_track->m_Start.y = uy0; + + pt_track->m_End.x = ux1; + pt_track->m_End.y = uy1; + + pt_track->m_TimeStamp = s_TimeStamp; + pt_track->Insert( frame->m_Pcb, NULL ); + pt_track->Draw( frame->DrawPanel, DC, GR_OR ); + nbsegm++; + } + } + old_cell = current_cell; + } + + msg.Printf( wxT( "%d" ), nbsegm ); + Affiche_1_Parametre( frame, -1, wxEmptyString, msg, BROWN ); + } +} + + +/********************************************/ +int Propagation( WinEDA_PcbFrame* frame ) +/********************************************/ + +/** Function Propagation() + * An important function to calculate zones + * Uses the routing matrix to fill the cells within the zone + * Search and mark cells within the zone, and agree with DRC options. + * Requirements: + * Start from an initial point, to fill zone + * The zone must have no "copper island" + * Algorithm: + * If the current cell has a neightbour flagged as "cell in the zone", it + * become a cell in the zone + * The first point in the zone is the starting point + * 4 searches within the matrix are made: + * 1 - Left to right and top to bottom + * 2 - Right to left and top to bottom + * 3 - bottom to top and Right to left + * 4 - bottom to top and Left to right + * Given the current cell, for each search, we consider the 2 neightbour cells + * the previous cell on the same line and the previous cell on the same column. + * + * This funtion can request some iterations + * Iterations are made until no cell is added to the zone. + * @return: added cells count (i.e. which the attribute CELL_is_ZONE is set) + */ +{ + int row, col, nn; + long current_cell, old_cell_H; + int long* pt_cell_V; + int nbpoints = 0; + +#define NO_CELL_ZONE (HOLE | CELL_is_EDGE | CELL_is_ZONE) + wxString msg; + + Affiche_1_Parametre( frame, 57, wxT( "Detect" ), msg, CYAN ); + Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "1" ), CYAN ); + + // Alloc memory to handle 1 line or 1 colunmn on the routing matrix + nn = MAX( Nrows, Ncols ) * sizeof(*pt_cell_V); + pt_cell_V = (long*) MyMalloc( nn ); + + /* search 1 : from left to right and top to bottom */ + memset( pt_cell_V, 0, nn ); + for( row = 0; row < Nrows; row++ ) + { + old_cell_H = 0; + for( col = 0; col < Ncols; col++ ) + { + current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; + if( current_cell == 0 ) /* a free cell is found */ + { + if( (old_cell_H & CELL_is_ZONE) + || (pt_cell_V[col] & CELL_is_ZONE) ) + { + OrCell( row, col, BOTTOM, CELL_is_ZONE ); + current_cell = CELL_is_ZONE; + nbpoints++; + } + } + pt_cell_V[col] = old_cell_H = current_cell; + } + } + + /* search 2 : from right to left and top to bottom */ + Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "2" ), CYAN ); + memset( pt_cell_V, 0, nn ); + for( row = 0; row < Nrows; row++ ) + { + old_cell_H = 0; + for( col = Ncols - 1; col >= 0; col-- ) + { + current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; + if( current_cell == 0 ) /* a free cell is found */ + { + if( (old_cell_H & CELL_is_ZONE) + || (pt_cell_V[col] & CELL_is_ZONE) ) + { + OrCell( row, col, BOTTOM, CELL_is_ZONE ); + current_cell = CELL_is_ZONE; + nbpoints++; + } + } + pt_cell_V[col] = old_cell_H = current_cell; + } + } + + /* search 3 : from bottom to top and right to left balayage */ + Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "3" ), CYAN ); + memset( pt_cell_V, 0, nn ); + for( col = Ncols - 1; col >= 0; col-- ) + { + old_cell_H = 0; + for( row = Nrows - 1; row >= 0; row-- ) + { + current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; + if( current_cell == 0 ) /* a free cell is found */ + { + if( (old_cell_H & CELL_is_ZONE) + || (pt_cell_V[row] & CELL_is_ZONE) ) + { + OrCell( row, col, BOTTOM, CELL_is_ZONE ); + current_cell = CELL_is_ZONE; + nbpoints++; + } + } + pt_cell_V[row] = old_cell_H = current_cell; + } + } + + /* search 4 : from bottom to top and left to right */ + Affiche_1_Parametre( frame, -1, wxEmptyString, wxT( "4" ), CYAN ); + memset( pt_cell_V, 0, nn ); + for( col = 0; col < Ncols; col++ ) + { + old_cell_H = 0; + for( row = Nrows - 1; row >= 0; row-- ) + { + current_cell = GetCell( row, col, BOTTOM ) & NO_CELL_ZONE; + if( current_cell == 0 ) /* a free cell is found */ + { + if( (old_cell_H & CELL_is_ZONE) + || (pt_cell_V[row] & CELL_is_ZONE) ) + { + OrCell( row, col, BOTTOM, CELL_is_ZONE ); + current_cell = CELL_is_ZONE; + nbpoints++; + } + } + pt_cell_V[row] = old_cell_H = current_cell; + } + } + + MyFree( pt_cell_V ); + + return nbpoints; +} + + +/*****************************************************************************/ +bool WinEDA_PcbFrame::Genere_Pad_Connexion( wxDC* DC, int layer ) +/*****************************************************************************/ + +/* Create the thermal relief for each pad in the zone: + * this is 4 small segments from the pad to the zone + */ +{ + int ii, jj, Npads; + D_PAD* pt_pad; + LISTE_PAD* pt_liste_pad; + TRACK* pt_track, * loctrack; + int angle; + int cX, cY, dx, dy; + int sommet[4][2]; + wxString msg; + + if( m_Pcb->m_Zone == NULL ) + return FALSE; /* error: no zone */ + + if( m_Pcb->m_Zone->m_TimeStamp != s_TimeStamp ) /* error: this is not the new zone */ + return FALSE; + + /* Count the pads, i.e. the thermal relief to create count, and displays it */ + Affiche_1_Parametre( this, 50, wxT( "NPads" ), wxT( " " ), CYAN ); + pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; + for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) + { + pt_pad = *pt_liste_pad; + + /* Search pads relative to the selected net code */ + if( pt_pad->GetNet() != g_HightLigth_NetCode ) + continue; + + /* Is the pad on the active layer ? */ + if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) + continue; + Npads++; + } + + msg.Printf( wxT( "%d" ), Npads ); + Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); + + /* Create the thermal reliefs */ + Affiche_1_Parametre( this, 57, wxT( "Pads" ), wxT( " " ), CYAN ); + pt_liste_pad = (LISTE_PAD*) m_Pcb->m_Pads; + for( ii = 0, Npads = 0; ii < m_Pcb->m_NbPads; ii++, pt_liste_pad++ ) + { + pt_pad = *pt_liste_pad; + + /* Search pads relative to the selected net code */ + if( pt_pad->GetNet() != g_HightLigth_NetCode ) + continue; + /* Is the pad on the active layer ? */ + if( (pt_pad->m_Masque_Layer & g_TabOneLayerMask[layer]) == 0 ) + continue; + + /* Create the theram relief for the current pad */ + Npads++; + + msg.Printf( wxT( "%d" ), Npads ); + Affiche_1_Parametre( this, -1, wxEmptyString, msg, CYAN ); + + cX = pt_pad->GetPosition().x; + cY = pt_pad->GetPosition().y; + + dx = pt_pad->m_Size.x / 2; + dy = pt_pad->m_Size.y / 2; + + dx += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; + dy += g_DesignSettings.m_TrackClearence + g_GridRoutingSize; + + if( pt_pad->m_PadShape == TRAPEZE ) + { + dx += abs( pt_pad->m_DeltaSize.y ) / 2; + dy += abs( pt_pad->m_DeltaSize.x ) / 2; + } + + /* calculate the 4 segment coordintes (starting from the pad centre cX,cY) */ + sommet[0][0] = 0; sommet[0][1] = -dy; + sommet[1][0] = -dx; sommet[1][1] = 0; + sommet[2][0] = 0; sommet[2][1] = dy; + sommet[3][0] = dx; sommet[3][1] = 0; + + angle = pt_pad->m_Orient; + for( jj = 0; jj < 4; jj++ ) + { + RotatePoint( &sommet[jj][0], &sommet[jj][1], angle ); + + pt_track = new SEGZONE( m_Pcb ); + + pt_track->SetLayer( layer ); + pt_track->m_Width = g_DesignSettings.m_CurrentTrackWidth; + pt_track->SetNet( g_HightLigth_NetCode ); + pt_track->start = pt_pad; + pt_track->m_Start.x = cX; pt_track->m_Start.y = cY; + pt_track->m_End.x = cX + sommet[jj][0]; + pt_track->m_End.y = cY + sommet[jj][1]; + pt_track->m_TimeStamp = s_TimeStamp; + + /* Test if the segment is allowed */ + if( BAD_DRC==m_drc->DrcBlind( pt_track, m_Pcb->m_Track ) ) + { + delete pt_track; + continue; + } + + /* Search for a zone segment */ + loctrack = Locate_Zone( m_Pcb->m_Zone, pt_track->m_End, layer ); + if( (loctrack == NULL) || (loctrack->m_TimeStamp != s_TimeStamp) ) + { + delete pt_track; + continue; + } + + pt_track->Insert( m_Pcb, NULL ); + pt_track->Draw( DrawPanel, DC, GR_OR ); + } + } + + return TRUE; +} diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 11649214e1..b71a6f17ba 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -1,582 +1,582 @@ -///////////////////////////////////////////////////////////////////////////// - -// Name: zones_by_polygon.cpp -// Purpose: -// Author: jean-pierre Charras -// Modified by: -// Created: 25/01/2006 11:35:19 -// RCS-ID: -// Copyright: GNU License -// Licence: GNU License -///////////////////////////////////////////////////////////////////////////// - -// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 - -#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA) -#pragma implementation "dialog_zones_by_polygon.h" -#endif - -#include "fctsys.h" -#include "gr_basic.h" - -#include "common.h" -#include "pcbnew.h" - -#include "autorout.h" -#include "cell.h" -#include "trigo.h" - -#include "protos.h" - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#include "wx/wx.h" -#endif - -////@begin includes -////@end includes - - -////@begin XPM images -////@end XPM images - -/* Imported functions */ -void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, - bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief ); - -/* Local functions */ -static void Display_Zone_Netname( WinEDA_PcbFrame* frame ); -static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ); -static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); - -/* Local variables */ -static bool Zone_45_Only = FALSE; -static bool Zone_Exclude_Pads = TRUE; -static bool s_Zone_Create_Thermal_Relief = TRUE; -static int s_Zone_Layer; // Layer used to put the current zone -static int s_NetcodeSelection; // Net code selection for the current zone -static int s_NetSortingOpt; // For the net list: sort option (by alphabetic order or bay pad count order - -#define ZONE_NET_SORT_OPTION_KEY wxT("Zone_NetSort_Opt") - - -#include "dialog_zones_by_polygon.cpp" - - -/**************************************************************/ -void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* aZone ) -/**************************************************************/ - -/* Edite (change la largeur des segments) la zone Zone. - * La zone est constituee des segments zones de meme TimeStamp - */ -{ - bool modify = FALSE; - double f_new_width; - int w_tmp; - wxString Line; - wxString Msg( _( "New zone segment width: " ) ); - - if( aZone == NULL ) - return; - - f_new_width = To_User_Unit( g_UnitMetric, aZone->m_Width, GetScreen()->GetInternalUnits() ); - - Line.Printf( wxT( "%.4f" ), f_new_width ); - - Msg += g_UnitMetric ? wxT( "(mm)" ) : wxT( "(\")" ); - if( Get_Message( Msg, Line, this ) != 0 ) - return; - - w_tmp = g_DesignSettings.m_CurrentTrackWidth; - Line.ToDouble( &f_new_width ); - - g_DesignSettings.m_CurrentTrackWidth = From_User_Unit( g_UnitMetric, - f_new_width, GetScreen( - )->GetInternalUnits() ); - - for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() ) - { - if( zone->m_TimeStamp == aZone->m_TimeStamp ) - { - modify = TRUE; - Edit_TrackSegm_Width( DC, zone ); - } - } - - g_DesignSettings.m_CurrentTrackWidth = w_tmp; - if( modify ) - { - GetScreen()->SetModify(); - DrawPanel->Refresh(); - } -} - - -/**********************************************************/ -void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone ) -/**********************************************************/ - -/* Remove the zone which include the segment aZone. - * A zone is a group of segments which have the same TimeStamp - */ -{ - if( aZone == NULL ) - return; - - int nb_segm = 0; - bool modify = FALSE; - unsigned long TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted) - - SEGZONE* next; - for( SEGZONE* zone = m_Pcb->m_Zone; zone != NULL; zone = next ) - { - next = zone->Next(); - if( zone->m_TimeStamp == TimeStamp ) - { - modify = TRUE; - - /* Erase segment from screen */ - Trace_Une_Piste( DrawPanel, DC, zone, nb_segm, GR_XOR ); - /* remove item from linked list and free memory */ - zone->DeleteStructure(); - } - } - - if( modify ) - { - GetScreen()->SetModify(); - GetScreen()->SetRefreshReq(); - } -} - - -/*****************************************************************************/ -EDGE_ZONE* WinEDA_PcbFrame::Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone ) -/*****************************************************************************/ -/* Routine d'effacement du segment de limite zone en cours de trace */ -{ - EDGE_ZONE* segm; - - if( m_Pcb->m_CurrentLimitZone ) - segm = m_Pcb->m_CurrentLimitZone; - else - segm = edge_zone; - - if( segm == NULL ) - return NULL; - - Trace_DrawSegmentPcb( DrawPanel, DC, segm, GR_XOR ); - - m_Pcb->m_CurrentLimitZone = segm->Next(); - delete segm; - - segm = m_Pcb->m_CurrentLimitZone; - SetCurItem( segm ); - - if( segm ) - { - segm->Pback = NULL; - if( DrawPanel->ManageCurseur ) - DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); - } - else - { - DrawPanel->ManageCurseur = NULL; - DrawPanel->ForceCloseManageCurseur = NULL; - SetCurItem( NULL ); - } - return segm; -} - - -/*********************************************/ -void WinEDA_PcbFrame::CaptureNetName( wxDC* DC ) -/*********************************************/ - -/* routine permettant de capturer le nom net net (netcode) d'un pad - * ou d'une piste pour l'utiliser comme netcode de zone - */ -{ - D_PAD* pt_pad = 0; - TRACK* adrpiste; - MODULE* Module; - int masquelayer = g_TabOneLayerMask[GetScreen()->m_Active_Layer]; - int netcode; - - netcode = -1; - MsgPanel->EraseMsgBox(); - adrpiste = Locate_Pistes( m_Pcb->m_Track, masquelayer, CURSEUR_OFF_GRILLE ); - if( adrpiste == NULL ) - { - pt_pad = Locate_Any_Pad( m_Pcb, CURSEUR_OFF_GRILLE ); - - if( pt_pad ) /* Verif qu'il est bien sur la couche active */ - { - Module = (MODULE*) pt_pad->m_Parent; - pt_pad = Locate_Pads( Module, g_TabOneLayerMask[GetScreen()->m_Active_Layer], - CURSEUR_OFF_GRILLE ); - } - if( pt_pad ) - { - pt_pad->Display_Infos( this ); - netcode = pt_pad->GetNet(); - } - } - else - { - adrpiste->Display_Infos( this ); - netcode = adrpiste->GetNet(); - } - - // Mise en surbrillance du net - if( g_HightLigt_Status ) - Hight_Light( DC ); - - g_HightLigth_NetCode = netcode; - if( g_HightLigth_NetCode >= 0 ) - { - Hight_Light( DC ); - } - - /* Affichage du net selectionne pour la zone a tracer */ - Display_Zone_Netname( this ); -} - - -/*******************************************************/ -static void Display_Zone_Netname( WinEDA_PcbFrame* frame ) -/*******************************************************/ - -/* - * Affiche le net_code et le nom de net couramment selectionne - */ -{ - EQUIPOT* pt_equipot; - wxString line; - - pt_equipot = frame->m_Pcb->m_Equipots; - - if( g_HightLigth_NetCode > 0 ) - { - for( ; pt_equipot != NULL; pt_equipot = (EQUIPOT*) pt_equipot->Pnext ) - { - if( pt_equipot->GetNet() == g_HightLigth_NetCode ) - break; - } - - if( pt_equipot ) - { - line.Printf( wxT( "Zone: Net[%d] <%s>" ), g_HightLigth_NetCode, - pt_equipot->m_Netname.GetData() ); - } - else - line.Printf( wxT( "Zone: NetCode[%d], Equipot not found" ), - g_HightLigth_NetCode ); - } - - line = _( "Zone: No net selected" ); - - frame->Affiche_Message( line ); -} - - -/********************************************************/ -static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ) -/********************************************************/ - -/** - * Function Exit_Zones - * cancels the Begin_Zone state if at least one EDGE_ZONE has been created. - */ -{ - WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent; - - if( pcbframe->m_Pcb->m_CurrentLimitZone ) - { - if( Panel->ManageCurseur ) // trace in progress - { - Panel->ManageCurseur( Panel, DC, 0 ); - } - pcbframe->DelLimitesZone( DC, TRUE ); - } - - Panel->ManageCurseur = NULL; - Panel->ForceCloseManageCurseur = NULL; - pcbframe->SetCurItem( NULL ); -} - - -/**************************************************************/ -void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw ) -/**************************************************************/ -{ - EDGE_ZONE* segment; - EDGE_ZONE* next; - - if( m_Pcb->m_CurrentLimitZone == NULL ) - return; - - if( !IsOK( this, _( "Delete Current Zone Edges" ) ) ) - return; - - // erase the old zone border, one segment at a time - for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next ) - { - next = segment->Next(); - - if( Redraw && DC ) - Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR ); - - delete segment; - } - - m_Pcb->m_CurrentLimitZone = NULL; - - SetCurItem( NULL ); -} - - -/** - * Function Begin_Zone - * either initializes the first segment of a new zone, or adds an - * intermediate segment. - */ -EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone() -{ - EDGE_ZONE* oldedge; - EDGE_ZONE* newedge = NULL; - - oldedge = m_Pcb->m_CurrentLimitZone; - - // if first segment - if( (m_Pcb->m_CurrentLimitZone == NULL ) /* debut reel du trace */ - || (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */ - { - newedge = new EDGE_ZONE( m_Pcb ); - newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED; - newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur; - newedge->SetLayer( GetScreen()->m_Active_Layer ); - - // link into list: - newedge->Pnext = oldedge; - - if( oldedge ) - oldedge->Pback = newedge; - - m_Pcb->m_CurrentLimitZone = newedge; - - DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse; - DrawPanel->ForceCloseManageCurseur = Exit_Zones; - } - // edge in progress: - else /* piste en cours : les coord du point d'arrivee ont ete mises - * a jour par la routine Show_Zone_Edge_While_MoveMouse*/ - { - if( oldedge->m_Start != oldedge->m_End ) - { - oldedge->m_Flags &= ~(IS_NEW | IS_MOVED); - - newedge = new EDGE_ZONE( oldedge ); - newedge->m_Flags = IS_NEW | IS_MOVED; - newedge->m_Start = newedge->m_End = oldedge->m_End; - newedge->SetLayer( GetScreen()->m_Active_Layer ); - - // link into list: - newedge->Pnext = oldedge; - oldedge->Pback = newedge; - m_Pcb->m_CurrentLimitZone = newedge; - } - } - - return newedge; -} - - -/*********************************************/ -void WinEDA_PcbFrame::End_Zone( wxDC* DC ) -/*********************************************/ - -/* - * Routine de fin de trace d'une zone (succession de segments) - */ -{ - EDGE_ZONE* edge; - - if( m_Pcb->m_CurrentLimitZone ) - { - Begin_Zone(); - - /* le dernier point genere est de longueur tj nulle donc inutile. */ - /* il sera raccorde au point de depart */ - edge = m_Pcb->m_CurrentLimitZone; - edge->m_Flags &= ~(IS_NEW | IS_MOVED); - - while( edge && edge->Next() ) - { - edge = edge->Next(); - if( edge->m_Flags & STARTPOINT ) - break; - - edge->m_Flags &= ~(IS_NEW | IS_MOVED); - } - - if( edge ) - { - edge->m_Flags &= ~(IS_NEW | IS_MOVED); - m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start; - } - Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR ); - } - - DrawPanel->ManageCurseur = NULL; - DrawPanel->ForceCloseManageCurseur = NULL; -} - - -/******************************************************************************************/ -static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) -/******************************************************************************************/ - -/* redessin du contour de la piste lors des deplacements de la souris - */ -{ - EDGE_ZONE* edge; - EDGE_ZONE* currentEdge; - WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent; - - if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL ) - return; - - /* efface ancienne position si elle a ete deja dessinee */ - if( erase ) - { - edge = pcbframe->m_Pcb->m_CurrentLimitZone; - - // for( ; edge; edge = edge->Next() ) - { - Trace_DrawSegmentPcb( panel, DC, edge, GR_XOR ); - } - } - - /* mise a jour de la couche */ - for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() ) - { - edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer ); - } - - /* dessin de la nouvelle piste : mise a jour du point d'arrivee */ - currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone; - if( Zone_45_Only ) - { - // Calcul de l'extremite de la piste pour orientations permises: - // horiz,vertical ou 45 degre - currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; - Calcule_Coord_Extremite_45( currentEdge->m_Start.x, currentEdge->m_Start.y, - ¤tEdge->m_End.x, ¤tEdge->m_End.y ); - } - else /* ici l'angle d'inclinaison est quelconque */ - { - currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; - } - - // for( ; currentEdge; currentEdge = currentEdge->Next() ) - { - Trace_DrawSegmentPcb( panel, DC, currentEdge, GR_XOR ); - } -} - - -/**********************************************/ -void WinEDA_PcbFrame::Fill_Zone( wxDC* DC ) -/**********************************************/ - -/** Function Fill_Zone() - * Init the zone filling - * If a zone edge is found, it is used. - * Otherwise the whole board is filled by the zone - * The zone edge is a frontier, and can be complex. So non filled zones can be achieved - * The zone is put on the active layer - * If a net is hightlighted, the zone will be attached to this net - * The filling start from a starting point. - * If a net is selected, all tracks attached to this net are also starting points - */ -{ - EQUIPOT* pt_equipot; - wxPoint ZoneStartFill; - wxString msg; - - MsgPanel->EraseMsgBox(); - if( m_Pcb->ComputeBoundaryBox() == FALSE ) - { - DisplayError( this, wxT( "Board is empty!" ), 10 ); - return; - } - - if( m_Parent && m_Parent->m_EDA_Config ) - { - s_NetSortingOpt = m_Parent->m_EDA_Config->Read( ZONE_NET_SORT_OPTION_KEY, (long) BOARD::PAD_CNT_SORT ); - } - int NetSortingOptImg = s_NetSortingOpt; - DrawPanel->m_IgnoreMouseEvents = TRUE; - WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this ); - - int abrd = frame->ShowModal(); - frame->Destroy(); - DrawPanel->MouseToCursorSchema(); - DrawPanel->m_IgnoreMouseEvents = FALSE; - - if( (NetSortingOptImg != s_NetSortingOpt ) && m_Parent && m_Parent->m_EDA_Config ) - { - m_Parent->m_EDA_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) s_NetSortingOpt ); - } - - if( abrd ) - return; - - // set all the EDGE_ZONEs to the currently active layer and redraw them - // on that layer. - GetScreen()->m_Active_Layer = s_Zone_Layer; - EDGE_ZONE* PtLim = m_Pcb->m_CurrentLimitZone; - for( ; PtLim != NULL; PtLim = PtLim->Next() ) - { - Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); - PtLim->SetLayer( s_Zone_Layer ); - Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); - } - - /* Show the NetName */ - if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) ) - { - Hight_Light( DC ); - g_HightLigth_NetCode = s_NetcodeSelection; - Hight_Light( DC ); - } - g_HightLigth_NetCode = s_NetcodeSelection; - - if( g_HightLigth_NetCode > 0 ) - { - pt_equipot = m_Pcb->FindNet( g_HightLigth_NetCode ); - if( pt_equipot == NULL ) - { - if( g_HightLigth_NetCode > 0 ) - DisplayError( this, wxT( "Unable to find Net name" ) ); - } - else - msg = pt_equipot->m_Netname; - } - else - msg = _( "No Net" ); - - Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED ); - - Build_Zone( this, DC, g_HightLigth_NetCode, Zone_Exclude_Pads, s_Zone_Create_Thermal_Relief ); - - GetScreen()->SetModify(); -} +///////////////////////////////////////////////////////////////////////////// + +// Name: zones_by_polygon.cpp +// Purpose: +// Author: jean-pierre Charras +// Modified by: +// Created: 25/01/2006 11:35:19 +// RCS-ID: +// Copyright: GNU License +// Licence: GNU License +///////////////////////////////////////////////////////////////////////////// + +// Generated by DialogBlocks (unregistered), 25/01/2006 11:35:19 + +#if defined (__GNUG__) && !defined (NO_GCC_PRAGMA) +#pragma implementation "dialog_zones_by_polygon.h" +#endif + +#include "fctsys.h" +#include "gr_basic.h" + +#include "common.h" +#include "pcbnew.h" + +#include "autorout.h" +#include "cell.h" +#include "trigo.h" + +#include "protos.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + + +////@begin XPM images +////@end XPM images + +/* Imported functions */ +void Build_Zone( WinEDA_PcbFrame* frame, wxDC* DC, int net_code, + bool Zone_Exclude_Pads, bool Zone_Create_Thermal_Relief ); + +/* Local functions */ +static void Display_Zone_Netname( WinEDA_PcbFrame* frame ); +static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ); +static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ); + +/* Local variables */ +static bool Zone_45_Only = FALSE; +static bool Zone_Exclude_Pads = TRUE; +static bool s_Zone_Create_Thermal_Relief = TRUE; +static int s_Zone_Layer; // Layer used to put the current zone +static int s_NetcodeSelection; // Net code selection for the current zone +static int s_NetSortingOpt; // For the net list: sort option (by alphabetic order or bay pad count order + +#define ZONE_NET_SORT_OPTION_KEY wxT("Zone_NetSort_Opt") + + +#include "dialog_zones_by_polygon.cpp" + + +/**************************************************************/ +void WinEDA_PcbFrame::Edit_Zone_Width( wxDC* DC, SEGZONE* aZone ) +/**************************************************************/ + +/* Edite (change la largeur des segments) la zone Zone. + * La zone est constituee des segments zones de meme TimeStamp + */ +{ + bool modify = FALSE; + double f_new_width; + int w_tmp; + wxString Line; + wxString Msg( _( "New zone segment width: " ) ); + + if( aZone == NULL ) + return; + + f_new_width = To_User_Unit( g_UnitMetric, aZone->m_Width, GetScreen()->GetInternalUnits() ); + + Line.Printf( wxT( "%.4f" ), f_new_width ); + + Msg += g_UnitMetric ? wxT( "(mm)" ) : wxT( "(\")" ); + if( Get_Message( Msg, Line, this ) != 0 ) + return; + + w_tmp = g_DesignSettings.m_CurrentTrackWidth; + Line.ToDouble( &f_new_width ); + + g_DesignSettings.m_CurrentTrackWidth = From_User_Unit( g_UnitMetric, + f_new_width, GetScreen( + )->GetInternalUnits() ); + + for( SEGZONE* zone = m_Pcb->m_Zone; zone; zone = zone->Next() ) + { + if( zone->m_TimeStamp == aZone->m_TimeStamp ) + { + modify = TRUE; + Edit_TrackSegm_Width( DC, zone ); + } + } + + g_DesignSettings.m_CurrentTrackWidth = w_tmp; + if( modify ) + { + GetScreen()->SetModify(); + DrawPanel->Refresh(); + } +} + + +/**********************************************************/ +void WinEDA_PcbFrame::Delete_Zone( wxDC* DC, SEGZONE* aZone ) +/**********************************************************/ + +/* Remove the zone which include the segment aZone. + * A zone is a group of segments which have the same TimeStamp + */ +{ + if( aZone == NULL ) + return; + + int nb_segm = 0; + bool modify = FALSE; + unsigned long TimeStamp = aZone->m_TimeStamp; // Save reference time stamp (aZone will be deleted) + + SEGZONE* next; + for( SEGZONE* zone = m_Pcb->m_Zone; zone != NULL; zone = next ) + { + next = zone->Next(); + if( zone->m_TimeStamp == TimeStamp ) + { + modify = TRUE; + + /* Erase segment from screen */ + Trace_Une_Piste( DrawPanel, DC, zone, nb_segm, GR_XOR ); + /* remove item from linked list and free memory */ + zone->DeleteStructure(); + } + } + + if( modify ) + { + GetScreen()->SetModify(); + GetScreen()->SetRefreshReq(); + } +} + + +/*****************************************************************************/ +EDGE_ZONE* WinEDA_PcbFrame::Del_SegmEdgeZone( wxDC* DC, EDGE_ZONE* edge_zone ) +/*****************************************************************************/ +/* Routine d'effacement du segment de limite zone en cours de trace */ +{ + EDGE_ZONE* segm; + + if( m_Pcb->m_CurrentLimitZone ) + segm = m_Pcb->m_CurrentLimitZone; + else + segm = edge_zone; + + if( segm == NULL ) + return NULL; + + Trace_DrawSegmentPcb( DrawPanel, DC, segm, GR_XOR ); + + m_Pcb->m_CurrentLimitZone = segm->Next(); + delete segm; + + segm = m_Pcb->m_CurrentLimitZone; + SetCurItem( segm ); + + if( segm ) + { + segm->Pback = NULL; + if( DrawPanel->ManageCurseur ) + DrawPanel->ManageCurseur( DrawPanel, DC, TRUE ); + } + else + { + DrawPanel->ManageCurseur = NULL; + DrawPanel->ForceCloseManageCurseur = NULL; + SetCurItem( NULL ); + } + return segm; +} + + +/*********************************************/ +void WinEDA_PcbFrame::CaptureNetName( wxDC* DC ) +/*********************************************/ + +/* routine permettant de capturer le nom net net (netcode) d'un pad + * ou d'une piste pour l'utiliser comme netcode de zone + */ +{ + D_PAD* pt_pad = 0; + TRACK* adrpiste; + MODULE* Module; + int masquelayer = g_TabOneLayerMask[GetScreen()->m_Active_Layer]; + int netcode; + + netcode = -1; + MsgPanel->EraseMsgBox(); + adrpiste = Locate_Pistes( m_Pcb->m_Track, masquelayer, CURSEUR_OFF_GRILLE ); + if( adrpiste == NULL ) + { + pt_pad = Locate_Any_Pad( m_Pcb, CURSEUR_OFF_GRILLE ); + + if( pt_pad ) /* Verif qu'il est bien sur la couche active */ + { + Module = (MODULE*) pt_pad->m_Parent; + pt_pad = Locate_Pads( Module, g_TabOneLayerMask[GetScreen()->m_Active_Layer], + CURSEUR_OFF_GRILLE ); + } + if( pt_pad ) + { + pt_pad->Display_Infos( this ); + netcode = pt_pad->GetNet(); + } + } + else + { + adrpiste->Display_Infos( this ); + netcode = adrpiste->GetNet(); + } + + // Mise en surbrillance du net + if( g_HightLigt_Status ) + Hight_Light( DC ); + + g_HightLigth_NetCode = netcode; + if( g_HightLigth_NetCode >= 0 ) + { + Hight_Light( DC ); + } + + /* Affichage du net selectionne pour la zone a tracer */ + Display_Zone_Netname( this ); +} + + +/*******************************************************/ +static void Display_Zone_Netname( WinEDA_PcbFrame* frame ) +/*******************************************************/ + +/* + * Affiche le net_code et le nom de net couramment selectionne + */ +{ + EQUIPOT* pt_equipot; + wxString line; + + pt_equipot = frame->m_Pcb->m_Equipots; + + if( g_HightLigth_NetCode > 0 ) + { + for( ; pt_equipot != NULL; pt_equipot = (EQUIPOT*) pt_equipot->Pnext ) + { + if( pt_equipot->GetNet() == g_HightLigth_NetCode ) + break; + } + + if( pt_equipot ) + { + line.Printf( wxT( "Zone: Net[%d] <%s>" ), g_HightLigth_NetCode, + pt_equipot->m_Netname.GetData() ); + } + else + line.Printf( wxT( "Zone: NetCode[%d], Equipot not found" ), + g_HightLigth_NetCode ); + } + + line = _( "Zone: No net selected" ); + + frame->Affiche_Message( line ); +} + + +/********************************************************/ +static void Exit_Zones( WinEDA_DrawPanel* Panel, wxDC* DC ) +/********************************************************/ + +/** + * Function Exit_Zones + * cancels the Begin_Zone state if at least one EDGE_ZONE has been created. + */ +{ + WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) Panel->m_Parent; + + if( pcbframe->m_Pcb->m_CurrentLimitZone ) + { + if( Panel->ManageCurseur ) // trace in progress + { + Panel->ManageCurseur( Panel, DC, 0 ); + } + pcbframe->DelLimitesZone( DC, TRUE ); + } + + Panel->ManageCurseur = NULL; + Panel->ForceCloseManageCurseur = NULL; + pcbframe->SetCurItem( NULL ); +} + + +/**************************************************************/ +void WinEDA_BasePcbFrame::DelLimitesZone( wxDC* DC, bool Redraw ) +/**************************************************************/ +{ + EDGE_ZONE* segment; + EDGE_ZONE* next; + + if( m_Pcb->m_CurrentLimitZone == NULL ) + return; + + if( !IsOK( this, _( "Delete Current Zone Edges" ) ) ) + return; + + // erase the old zone border, one segment at a time + for( segment = m_Pcb->m_CurrentLimitZone; segment; segment = next ) + { + next = segment->Next(); + + if( Redraw && DC ) + Trace_DrawSegmentPcb( DrawPanel, DC, segment, GR_XOR ); + + delete segment; + } + + m_Pcb->m_CurrentLimitZone = NULL; + + SetCurItem( NULL ); +} + + +/** + * Function Begin_Zone + * either initializes the first segment of a new zone, or adds an + * intermediate segment. + */ +EDGE_ZONE* WinEDA_PcbFrame::Begin_Zone() +{ + EDGE_ZONE* oldedge; + EDGE_ZONE* newedge = NULL; + + oldedge = m_Pcb->m_CurrentLimitZone; + + // if first segment + if( (m_Pcb->m_CurrentLimitZone == NULL ) /* debut reel du trace */ + || (DrawPanel->ManageCurseur == NULL) ) /* reprise d'un trace complementaire */ + { + newedge = new EDGE_ZONE( m_Pcb ); + newedge->m_Flags = IS_NEW | STARTPOINT | IS_MOVED; + newedge->m_Start = newedge->m_End = GetScreen()->m_Curseur; + newedge->SetLayer( GetScreen()->m_Active_Layer ); + + // link into list: + newedge->Pnext = oldedge; + + if( oldedge ) + oldedge->Pback = newedge; + + m_Pcb->m_CurrentLimitZone = newedge; + + DrawPanel->ManageCurseur = Show_Zone_Edge_While_MoveMouse; + DrawPanel->ForceCloseManageCurseur = Exit_Zones; + } + // edge in progress: + else /* piste en cours : les coord du point d'arrivee ont ete mises + * a jour par la routine Show_Zone_Edge_While_MoveMouse*/ + { + if( oldedge->m_Start != oldedge->m_End ) + { + oldedge->m_Flags &= ~(IS_NEW | IS_MOVED); + + newedge = new EDGE_ZONE( oldedge ); + newedge->m_Flags = IS_NEW | IS_MOVED; + newedge->m_Start = newedge->m_End = oldedge->m_End; + newedge->SetLayer( GetScreen()->m_Active_Layer ); + + // link into list: + newedge->Pnext = oldedge; + oldedge->Pback = newedge; + m_Pcb->m_CurrentLimitZone = newedge; + } + } + + return newedge; +} + + +/*********************************************/ +void WinEDA_PcbFrame::End_Zone( wxDC* DC ) +/*********************************************/ + +/* + * Routine de fin de trace d'une zone (succession de segments) + */ +{ + EDGE_ZONE* edge; + + if( m_Pcb->m_CurrentLimitZone ) + { + Begin_Zone(); + + /* le dernier point genere est de longueur tj nulle donc inutile. */ + /* il sera raccorde au point de depart */ + edge = m_Pcb->m_CurrentLimitZone; + edge->m_Flags &= ~(IS_NEW | IS_MOVED); + + while( edge && edge->Next() ) + { + edge = edge->Next(); + if( edge->m_Flags & STARTPOINT ) + break; + + edge->m_Flags &= ~(IS_NEW | IS_MOVED); + } + + if( edge ) + { + edge->m_Flags &= ~(IS_NEW | IS_MOVED); + m_Pcb->m_CurrentLimitZone->m_End = edge->m_Start; + } + Trace_DrawSegmentPcb( DrawPanel, DC, m_Pcb->m_CurrentLimitZone, GR_XOR ); + } + + DrawPanel->ManageCurseur = NULL; + DrawPanel->ForceCloseManageCurseur = NULL; +} + + +/******************************************************************************************/ +static void Show_Zone_Edge_While_MoveMouse( WinEDA_DrawPanel* panel, wxDC* DC, bool erase ) +/******************************************************************************************/ + +/* redessin du contour de la piste lors des deplacements de la souris + */ +{ + EDGE_ZONE* edge; + EDGE_ZONE* currentEdge; + WinEDA_PcbFrame* pcbframe = (WinEDA_PcbFrame*) panel->m_Parent; + + if( pcbframe->m_Pcb->m_CurrentLimitZone == NULL ) + return; + + /* efface ancienne position si elle a ete deja dessinee */ + if( erase ) + { + edge = pcbframe->m_Pcb->m_CurrentLimitZone; + + // for( ; edge; edge = edge->Next() ) + { + Trace_DrawSegmentPcb( panel, DC, edge, GR_XOR ); + } + } + + /* mise a jour de la couche */ + for( edge = pcbframe->m_Pcb->m_CurrentLimitZone; edge; edge = edge->Next() ) + { + edge->SetLayer( pcbframe->GetScreen()->m_Active_Layer ); + } + + /* dessin de la nouvelle piste : mise a jour du point d'arrivee */ + currentEdge = pcbframe->m_Pcb->m_CurrentLimitZone; + if( Zone_45_Only ) + { + // Calcul de l'extremite de la piste pour orientations permises: + // horiz,vertical ou 45 degre + currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; + Calcule_Coord_Extremite_45( currentEdge->m_Start.x, currentEdge->m_Start.y, + ¤tEdge->m_End.x, ¤tEdge->m_End.y ); + } + else /* ici l'angle d'inclinaison est quelconque */ + { + currentEdge->m_End = pcbframe->GetScreen()->m_Curseur; + } + + // for( ; currentEdge; currentEdge = currentEdge->Next() ) + { + Trace_DrawSegmentPcb( panel, DC, currentEdge, GR_XOR ); + } +} + + +/**********************************************/ +void WinEDA_PcbFrame::Fill_Zone( wxDC* DC ) +/**********************************************/ + +/** Function Fill_Zone() + * Init the zone filling + * If a zone edge is found, it is used. + * Otherwise the whole board is filled by the zone + * The zone edge is a frontier, and can be complex. So non filled zones can be achieved + * The zone is put on the active layer + * If a net is hightlighted, the zone will be attached to this net + * The filling start from a starting point. + * If a net is selected, all tracks attached to this net are also starting points + */ +{ + EQUIPOT* pt_equipot; + wxPoint ZoneStartFill; + wxString msg; + + MsgPanel->EraseMsgBox(); + if( m_Pcb->ComputeBoundaryBox() == FALSE ) + { + DisplayError( this, wxT( "Board is empty!" ), 10 ); + return; + } + + if( m_Parent && m_Parent->m_EDA_Config ) + { + s_NetSortingOpt = m_Parent->m_EDA_Config->Read( ZONE_NET_SORT_OPTION_KEY, (long) BOARD::PAD_CNT_SORT ); + } + int NetSortingOptImg = s_NetSortingOpt; + DrawPanel->m_IgnoreMouseEvents = TRUE; + WinEDA_ZoneFrame* frame = new WinEDA_ZoneFrame( this ); + + int abrd = frame->ShowModal(); + frame->Destroy(); + DrawPanel->MouseToCursorSchema(); + DrawPanel->m_IgnoreMouseEvents = FALSE; + + if( (NetSortingOptImg != s_NetSortingOpt ) && m_Parent && m_Parent->m_EDA_Config ) + { + m_Parent->m_EDA_Config->Write( ZONE_NET_SORT_OPTION_KEY, (long) s_NetSortingOpt ); + } + + if( abrd ) + return; + + // set all the EDGE_ZONEs to the currently active layer and redraw them + // on that layer. + GetScreen()->m_Active_Layer = s_Zone_Layer; + EDGE_ZONE* PtLim = m_Pcb->m_CurrentLimitZone; + for( ; PtLim != NULL; PtLim = PtLim->Next() ) + { + Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); + PtLim->SetLayer( s_Zone_Layer ); + Trace_DrawSegmentPcb( DrawPanel, DC, PtLim, GR_XOR ); + } + + /* Show the NetName */ + if( (g_HightLigth_NetCode > 0) && (g_HightLigth_NetCode != s_NetcodeSelection) ) + { + Hight_Light( DC ); + g_HightLigth_NetCode = s_NetcodeSelection; + Hight_Light( DC ); + } + g_HightLigth_NetCode = s_NetcodeSelection; + + if( g_HightLigth_NetCode > 0 ) + { + pt_equipot = m_Pcb->FindNet( g_HightLigth_NetCode ); + if( pt_equipot == NULL ) + { + if( g_HightLigth_NetCode > 0 ) + DisplayError( this, wxT( "Unable to find Net name" ) ); + } + else + msg = pt_equipot->m_Netname; + } + else + msg = _( "No Net" ); + + Affiche_1_Parametre( this, 22, _( "NetName" ), msg, RED ); + + Build_Zone( this, DC, g_HightLigth_NetCode, Zone_Exclude_Pads, s_Zone_Create_Thermal_Relief ); + + GetScreen()->SetModify(); +}