Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kicad-source-mirror
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
kicad-source-mirror
Commits
6991b496
Commit
6991b496
authored
Dec 19, 2007
by
raburton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
set eol-style native on new files
parent
fbe30472
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1777 additions
and
1777 deletions
+1777
-1777
dialog_zones_by_polygon.cpp
pcbnew/dialog_zones_by_polygon.cpp
+453
-453
dialog_zones_by_polygon.h
pcbnew/dialog_zones_by_polygon.h
+130
-130
filling_zone_algorithm.cpp
pcbnew/filling_zone_algorithm.cpp
+612
-612
zones_by_polygon.cpp
pcbnew/zones_by_polygon.cpp
+582
-582
No files found.
pcbnew/dialog_zones_by_polygon.cpp
View file @
6991b496
/////////////////////////////////////////////////////////////////////////////
// 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
);
}
pcbnew/dialog_zones_by_polygon.h
View file @
6991b496
/////////////////////////////////////////////////////////////////////////////
// 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_
pcbnew/filling_zone_algorithm.cpp
View file @
6991b496
/* 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 segments
* @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 segments
* @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
;
}
pcbnew/zones_by_polygon.cpp
View file @
6991b496
/////////////////////////////////////////////////////////////////////////////
// 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
,
&
currentEdge
->
m_End
.
x
,
&
currentEdge
->
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
,
&
currentEdge
->
m_End
.
x
,
&
currentEdge
->
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
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment