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
0cf91f46
Commit
0cf91f46
authored
Nov 30, 2014
by
Garth Corral
Browse files
Options
Browse Files
Download
Plain Diff
Merge trunk @ 5308
parents
668c3b76
cf9a885c
Changes
48
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
1295 additions
and
387 deletions
+1295
-387
CMakeLists.txt
CMakeLists.txt
+8
-2
download_boost.cmake
CMakeModules/download_boost.cmake
+2
-5
mac-osx.txt
Documentation/compiling/mac-osx.txt
+29
-14
hotkeys_basic.cpp
common/hotkeys_basic.cpp
+3
-0
dialog_netlist.cpp
eeschema/dialogs/dialog_netlist.cpp
+8
-47
tool_sch.cpp
eeschema/tool_sch.cpp
+1
-1
CMakeLists.txt
gerbview/CMakeLists.txt
+1
-0
class_GERBER.cpp
gerbview/class_GERBER.cpp
+180
-3
class_GERBER.h
gerbview/class_GERBER.h
+68
-0
class_X2_gerber_attributes.cpp
gerbview/class_X2_gerber_attributes.cpp
+253
-0
class_X2_gerber_attributes.h
gerbview/class_X2_gerber_attributes.h
+171
-0
class_gbr_layer_box_selector.cpp
gerbview/class_gbr_layer_box_selector.cpp
+7
-2
class_gbr_layout.cpp
gerbview/class_gbr_layout.cpp
+0
-1
class_gbr_layout.h
gerbview/class_gbr_layout.h
+3
-2
class_gerber_draw_item.cpp
gerbview/class_gerber_draw_item.cpp
+3
-1
class_gerbview_layer_widget.cpp
gerbview/class_gerbview_layer_widget.cpp
+25
-17
class_gerbview_layer_widget.h
gerbview/class_gerbview_layer_widget.h
+12
-5
dialog_print_using_printer.cpp
gerbview/dialogs/dialog_print_using_printer.cpp
+2
-1
draw_gerber_screen.cpp
gerbview/draw_gerber_screen.cpp
+5
-3
events_called_functions.cpp
gerbview/events_called_functions.cpp
+2
-2
excellon_read_drill_file.cpp
gerbview/excellon_read_drill_file.cpp
+34
-11
export_to_pcbnew.cpp
gerbview/export_to_pcbnew.cpp
+2
-1
files.cpp
gerbview/files.cpp
+3
-0
gerbview.cpp
gerbview/gerbview.cpp
+0
-4
gerbview.h
gerbview/gerbview.h
+0
-2
gerbview_frame.cpp
gerbview/gerbview_frame.cpp
+14
-4
init_gbr_drawlayers.cpp
gerbview/init_gbr_drawlayers.cpp
+2
-15
onleftclick.cpp
gerbview/onleftclick.cpp
+1
-1
readgerb.cpp
gerbview/readgerb.cpp
+7
-6
rs274d.cpp
gerbview/rs274d.cpp
+18
-3
rs274x.cpp
gerbview/rs274x.cpp
+30
-1
select_layers_to_pcb.cpp
gerbview/select_layers_to_pcb.cpp
+2
-2
toolbars_gerber.cpp
gerbview/toolbars_gerber.cpp
+1
-1
pcb_calculator_frame_base.cpp
pcb_calculator/dialogs/pcb_calculator_frame_base.cpp
+2
-2
pcb_calculator_frame_base.fbp
pcb_calculator/dialogs/pcb_calculator_frame_base.fbp
+3
-3
pcb_calculator_frame_base.h
pcb_calculator/dialogs/pcb_calculator_frame_base.h
+1
-1
regulators_funct.cpp
pcb_calculator/regulators_funct.cpp
+2
-2
board_items_to_polygon_shape_transform.cpp
pcbnew/board_items_to_polygon_shape_transform.cpp
+120
-70
class_board.cpp
pcbnew/class_board.cpp
+4
-2
class_board_connected_item.cpp
pcbnew/class_board_connected_item.cpp
+4
-11
class_zone.h
pcbnew/class_zone.h
+12
-10
pns_router.cpp
pcbnew/router/pns_router.cpp
+7
-2
zone_filling_algorithm.cpp
pcbnew/zone_filling_algorithm.cpp
+12
-29
zones_convert_brd_items_to_polygons_with_Boost.cpp
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
+31
-12
zones_convert_to_polygons_aux_functions.cpp
pcbnew/zones_convert_to_polygons_aux_functions.cpp
+9
-48
PolyLine.cpp
polygon/PolyLine.cpp
+125
-14
PolyLine.h
polygon/PolyLine.h
+57
-15
osx_build_wx.sh
scripts/osx_build_wx.sh
+9
-9
No files found.
CMakeLists.txt
View file @
0cf91f46
...
...
@@ -226,8 +226,8 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
if
(
APPLE
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-D__ASSERTMACROS__
-mmacosx-version-min=10.5
"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-D__ASSERTMACROS__
-mmacosx-version-min=10.5
"
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-D__ASSERTMACROS__"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-D__ASSERTMACROS__"
)
# Allows .dylib relocation in the future - needed by fixbundle
set
(
CMAKE_LD_FLAGS
"
${
CMAKE_LD_FLAGS
}
-headerpad_max_install_names"
)
...
...
@@ -240,6 +240,12 @@ if( CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
EXEC_PROGRAM
(
wx-config ARGS --cxx OUTPUT_VARIABLE CMAKE_CXX_COMPILER
)
endif
()
# There seems to be no consistent behavior when -mmacosx-min-version is
# not specified, so force user to set minimum OSX version to build for
if
(
NOT CMAKE_OSX_DEPLOYMENT_TARGET
)
message
(
FATAL_ERROR
"Please specify target OS X version using -DCMAKE_OSX_DEPLOYMENT_TARGET=10.x"
)
endif
()
endif
()
endif
(
CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
...
...
CMakeModules/download_boost.cmake
View file @
0cf91f46
...
...
@@ -140,11 +140,8 @@ endif()
if
(
APPLE
)
# I set this to being compatible with wxWidgets
# wxWidgets still using libstdc++ (gcc), meanwhile OSX
# has switched to libc++ (llvm) by default
set
(
BOOST_CXXFLAGS
"cxxflags=-mmacosx-version-min=10.5 -fno-common"
)
set
(
BOOST_LINKFLAGS
"linkflags=-mmacosx-version-min=10.5 -fno-common"
)
set
(
BOOST_CXXFLAGS
"cxxflags=-mmacosx-version-min=
${
CMAKE_OSX_DEPLOYMENT_TARGET
}
-fno-common"
)
set
(
BOOST_LINKFLAGS
"linkflags=-mmacosx-version-min=
${
CMAKE_OSX_DEPLOYMENT_TARGET
}
-fno-common"
)
set
(
BOOST_TOOLSET
"toolset=darwin"
)
if
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
...
...
Documentation/compiling/mac-osx.txt
View file @
0cf91f46
Compiling KiCad on Apple Mac OS X
=================================
Building on OSX is very similar to building on Linux. This document will provide
a complete walk-through on what to do but it will focus on OSX specific things.
See general documentation on non
-OS
X specific KiCad build switches, etc.
Building on OS
X is very similar to building on Linux. This document will provide
a complete walk-through on what to do but it will focus on OS
X specific things.
See general documentation on non
OS
X specific KiCad build switches, etc.
Prerequisites
...
...
@@ -24,6 +24,7 @@ Mandatory library dependencies needed to compile KiCad:
OR
wxPython - A blending of the wxWidgets C++ class library with the Python
programming language
* SWIG - Interface compiler (only needed for scripting/wxPython builds)
Optional library dependencies, depends on used KiCad features
* OpenSSL - The Open Source toolkit for SSL/TLS
...
...
@@ -31,7 +32,7 @@ Optional library dependencies, depends on used KiCad features
All tools (except XCode, of course) and all dependencies except wxWidgets/wxPython
can be compiled manually, but it is advised to install them using your favorite
package manager for OSX like MacPorts or Homebrew.
package manager for OS
X like MacPorts or Homebrew.
Depending on the package manager the development packages of the library
dependencies may have to be installed (usually something like <pkg>-dev or
<pkg>-devel).
...
...
@@ -44,7 +45,7 @@ automatically by KiCad build process.
IMPORTANT:
At the moment you *must not* use a wxWidgets/wxPython version installed by any
package manager.
KiCad on OSX needs overlay support and some other fixes, which are not yet
KiCad on OS
X needs overlay support and some other fixes, which are not yet
contained in mainline wxWidgets/wxPython sources and builds.
If you don't use a patched wxWidgets you will get graphical artifacts (something
like a magnifying glass effect in the upper left corner of KiCad windows) or
...
...
@@ -92,13 +93,15 @@ It is recommended to use the latest stable version. As of this writing this is
There is a little helper script osx_build_wx.sh in kicad/scripts that does all
the patching/configuring/compiling of wxWidgets or wxPython for you.
Go to your working root "KiCad" and run:
# kicad/scripts/osx_build_wx.sh wx-src wx-bin kicad "-j4"
Go to your working root "KiCad" and
for example
run:
# kicad/scripts/osx_build_wx.sh wx-src wx-bin kicad
10.7
"-j4"
First parameter is the source folder of wxWidgets/wxPython, second parameter the
target folder for compiled binaries, third parameter is the kicad folder, and
the last optional parameter are make options used during the build (in this
case for building with 4 jobs in parallel).
target folder for compiled binaries, and third parameter is the kicad folder.
The fourth parameter is the minimum OS X version you are building for (see the
section about compiling KiCad for further notes on minimum OS X version).
The last parameter is optional and contains make options used during the build
(in this example for building with 4 jobs in parallel).
The script will automatically detect if you are compiling wxWidgets or wxPython.
NOTE: All paths are assumed to be relative to the current directory, i.e., the
working root you are in.
...
...
@@ -137,10 +140,8 @@ work:
--with-zlib=builtin \
--with-expat=builtin \
--without-liblzma \
--with-macosx-version-min=
10.5
\
--with-macosx-version-min=
<osxtarget>
\
--enable-universal-binary=i386,x86_64 \
CPPFLAGS="-stdlib=libstdc++" \
LDFLAGS="-stdlib=libstdc++" \
CC=clang \
CXX=clang++
If you know what you are doing, you can of course use different settings.
...
...
@@ -157,6 +158,7 @@ Now, configure KiCad without scripting support:
# cmake ../kicad \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \
-DwxWidgets_CONFIG_EXECUTABLE=../wx-bin/bin/wx-config \
-DKICAD_SCRIPTING=OFF \
-DKICAD_SCRIPTING_MODULES=OFF \
...
...
@@ -168,6 +170,7 @@ or, configure KiCad with scripting support:
# cmake ../kicad \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 \
-DwxWidgets_CONFIG_EXECUTABLE=../wx-bin/bin/wx-config \
-DPYTHON_EXECUTABLE=`which python` \
-DPYTHON_SITE_PACKAGE_PATH=`pwd`/../wx-bin/lib/python2.7/site-packages \
...
...
@@ -182,7 +185,19 @@ been generated when compiling/installing wxPython. If you want to use a specific
python, you can also specify it via "-DPYTHON_EXECUTABLE" instead of using
`which python` (this one will just detect/use you default python).
Now KiCad is configured using default features/build-switches. To add Magic
The parameter "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.x" is mandatory, you have to
specify the (minimum) OS X version you intend to build for. It is important that
at least wxWidgets/wxPython and KiCad (and boost, if you use an external build)
are built using the same or compatible settings. If not, you might get linker
errors, because this parameter influences which standard C++ library is being
used (libstdc++ vs. libc++).
If you don't know what to use and you are only building for your machine, just
set it to your current OS X version (e.g., MacPorts always builds this way).
Binaries built with a target OS X version <10.7 are known to show strange
behavior in some situations on recent systems (maybe because libc++ is standard
on everything >= 10.7 and problems arise due to mixing libstdc++/libc++).
Now KiCad is configured using default features/build-switches. To add Magic
Trackpad pinch-to-zoom support, add -DUSE_OSX_MAGNIFY_EVENT=ON to the above.
See Documentation/compiling/build-config.txt for a list of all CMake options
available when compiling KiCad.
...
...
common/hotkeys_basic.cpp
View file @
0cf91f46
...
...
@@ -548,6 +548,9 @@ int EDA_BASE_FRAME::ReadHotkeyConfigFile( const wxString& aFilename,
{
wxFile
cfgfile
(
aFilename
);
if
(
!
cfgfile
.
IsOpened
()
)
// There is a problem to open file
return
0
;
// get length
cfgfile
.
SeekEnd
();
wxFileOffset
size
=
cfgfile
.
Tell
();
...
...
eeschema/dialogs/dialog_netlist.cpp
View file @
0cf91f46
...
...
@@ -86,7 +86,7 @@ public:
wxBoxSizer
*
m_RightBoxSizer
;
wxBoxSizer
*
m_RightOptionsBoxSizer
;
wxBoxSizer
*
m_LowBoxSizer
;
wxRadioBox
*
m_NetOption
;
private
:
wxString
m_pageNetFmtName
;
...
...
@@ -104,14 +104,12 @@ public:
/**
* function GetPageNetFmtName
* @return the name of the netlist format for this page
* This is usually the page label.
* For the pcbnew netlist, this is "LegacyPcbnew"
* when the "old" format is selected
* and "PcbnewAdvanced" when the advanced format (S expr fmt)is selected
* This is also the page label.
*/
const
wxString
GetPageNetFmtName
();
void
SetPageNetFmtName
(
const
wxString
&
aName
)
{
m_pageNetFmtName
=
aName
;
}
const
wxString
GetPageNetFmtName
()
{
return
m_pageNetFmtName
;
}
};
...
...
@@ -242,9 +240,6 @@ enum id_netlist {
#define NETLIST_USE_DEFAULT_NETNAME wxT( "NetlistUseDefaultNetname" )
#define NETLIST_PSPICE_USE_NETNAME wxT( "SpiceUseNetNames" )
#define NETLIST_PCBNEW_LEGACY wxT("LegacyPcbnew" )
#define NETLIST_PCBNEW_NEWFMT wxT("PcbnewAdvanced" )
BEGIN_EVENT_TABLE
(
NETLIST_DIALOG
,
NETLIST_DIALOG_BASE
)
EVT_BUTTON
(
ID_CREATE_NETLIST
,
NETLIST_DIALOG
::
GenNetlist
)
...
...
@@ -269,23 +264,15 @@ NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* parent,
m_AddSubPrefix
=
NULL
;
m_SpiceUseNetcodeAsNetname
=
NULL
;
m_ButtonCancel
=
NULL
;
m_NetOption
=
NULL
;
wxString
netfmtName
=
((
NETLIST_DIALOG
*
)
parent
->
GetParent
())
->
m_NetFmtName
;
int
fmtOption
=
1
;
// Default Pcbnew netlist fmt is advanced fmt
bool
selected
=
m_pageNetFmtName
==
netfmtName
;
// PCBNEW Format is a special type:
if
(
id_NetType
==
NET_TYPE_PCBNEW
)
{
if
(
netfmtName
.
IsEmpty
()
||
netfmtName
==
NETLIST_PCBNEW_NEWFMT
)
selected
=
true
;
if
(
netfmtName
==
NETLIST_PCBNEW_LEGACY
)
{
selected
=
true
;
fmtOption
=
0
;
}
selected
=
true
;
}
...
...
@@ -312,34 +299,9 @@ NETLIST_PAGE_DIALOG::NETLIST_PAGE_DIALOG( wxNotebook* parent,
_
(
"Default format"
)
);
m_LeftBoxSizer
->
Add
(
m_IsCurrentFormat
,
0
,
wxGROW
|
wxALL
,
5
);
m_IsCurrentFormat
->
SetValue
(
selected
);
if
(
id_NetType
==
NET_TYPE_PCBNEW
)
{
wxString
netlist_opt
[
2
]
=
{
_
(
"Legacy Format"
),
_
(
"Advanced Format"
)
};
m_NetOption
=
new
wxRadioBox
(
this
,
-
1
,
_
(
"Netlist Options:"
),
wxDefaultPosition
,
wxDefaultSize
,
2
,
netlist_opt
,
1
,
wxRA_SPECIFY_COLS
);
m_NetOption
->
SetSelection
(
fmtOption
);
m_LeftBoxSizer
->
Add
(
m_NetOption
,
0
,
wxGROW
|
wxALL
,
5
);
}
}
const
wxString
NETLIST_PAGE_DIALOG
::
GetPageNetFmtName
()
{
// PCBNEW Format is a special type:
if
(
m_IdNetType
==
NET_TYPE_PCBNEW
)
{
if
(
m_NetOption
->
GetSelection
()
)
return
NETLIST_PCBNEW_NEWFMT
;
else
return
NETLIST_PCBNEW_LEGACY
;
}
return
m_pageNetFmtName
;
}
NETLIST_DIALOG
::
NETLIST_DIALOG
(
SCH_EDIT_FRAME
*
parent
)
:
NETLIST_DIALOG_BASE
(
parent
)
...
...
@@ -599,8 +561,7 @@ void NETLIST_DIALOG::GenNetlist( wxCommandEvent& event )
break
;
case
NET_TYPE_PCBNEW
:
if
(
currPage
->
m_NetOption
->
GetSelection
()
!=
0
)
netlist_opt
=
NET_PCBNEW_USE_NEW_FORMAT
;
netlist_opt
=
NET_PCBNEW_USE_NEW_FORMAT
;
break
;
case
NET_TYPE_ORCADPCB2
:
...
...
eeschema/tool_sch.cpp
View file @
0cf91f46
...
...
@@ -146,7 +146,7 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
HELP_ANNOTATE
);
m_mainToolBar
->
AddTool
(
ID_GET_ERC
,
wxEmptyString
,
KiBitmap
(
erc_xpm
),
_
(
"Perform electric
rules
check"
)
);
_
(
"Perform electric
al rule
check"
)
);
m_mainToolBar
->
AddTool
(
ID_GET_NETLIST
,
wxEmptyString
,
KiBitmap
(
netlist_xpm
),
_
(
"Generate netlist"
)
);
...
...
gerbview/CMakeLists.txt
View file @
0cf91f46
...
...
@@ -40,6 +40,7 @@ set( GERBVIEW_SRCS
class_gerber_draw_item.cpp
class_gerbview_layer_widget.cpp
class_gbr_layer_box_selector.cpp
class_X2_gerber_attributes.cpp
controle.cpp
dcode.cpp
draw_gerber_screen.cpp
...
...
gerbview/class_GERBER.cpp
View file @
0cf91f46
...
...
@@ -36,6 +36,9 @@
#include <gerbview.h>
#include <gerbview_frame.h>
#include <class_GERBER.h>
#include <class_X2_gerber_attributes.h>
#include <algorithm>
/**
...
...
@@ -88,9 +91,10 @@ void GERBER_LAYER::ResetDefaultValues()
GERBER_IMAGE
::
GERBER_IMAGE
(
GERBVIEW_FRAME
*
aParent
,
int
aLayer
)
{
m_Parent
=
aParent
;
m_GraphicLayer
=
aLayer
;
// Graphic layer Number
m_GraphicLayer
=
aLayer
;
// Graphic layer Number
m_Selected_Tool
=
FIRST_DCODE
;
m_FileFunction
=
NULL
;
// file function parameters
ResetDefaultValues
();
...
...
@@ -104,9 +108,9 @@ GERBER_IMAGE::~GERBER_IMAGE()
for
(
unsigned
ii
=
0
;
ii
<
DIM
(
m_Aperture_List
);
ii
++
)
{
delete
m_Aperture_List
[
ii
];
// m_Aperture_List[ii] = NULL;
}
delete
m_FileFunction
;
}
/*
...
...
@@ -158,6 +162,11 @@ void GERBER_IMAGE::ResetDefaultValues()
m_FileName
.
Empty
();
m_ImageName
=
wxT
(
"no name"
);
// Image name from the IN command
m_ImageNegative
=
false
;
// true = Negative image
m_IsX2_file
=
false
;
// true only if a %TF, %TA or %TD command
delete
m_FileFunction
;
// file function parameters
m_FileFunction
=
NULL
;
m_MD5_value
.
Empty
();
// MD5 value found in a %TF.MD5 command
m_PartString
.
Empty
();
// string found in a %TF.Part command
m_hasNegativeItems
=
-
1
;
// set to uninitialized
m_ImageJustifyOffset
=
wxPoint
(
0
,
0
);
// Image justify Offset
m_ImageJustifyXCenter
=
false
;
// Image Justify Center on X axis (default = false)
...
...
@@ -361,3 +370,171 @@ void GERBER_IMAGE::DisplayImageInfo( void )
m_Parent
->
AppendMsgPanel
(
_
(
"Image Justify Offset"
),
msg
,
DARKRED
);
}
// GERBER_IMAGE_LIST is a helper class to handle a list of GERBER_IMAGE files
GERBER_IMAGE_LIST
::
GERBER_IMAGE_LIST
()
{
m_GERBER_List
.
reserve
(
GERBER_DRAWLAYERS_COUNT
);
for
(
unsigned
layer
=
0
;
layer
<
GERBER_DRAWLAYERS_COUNT
;
++
layer
)
m_GERBER_List
.
push_back
(
NULL
);
}
GERBER_IMAGE_LIST
::~
GERBER_IMAGE_LIST
()
{
ClearList
();
for
(
unsigned
layer
=
0
;
layer
<
m_GERBER_List
.
size
();
++
layer
)
{
delete
m_GERBER_List
[
layer
];
m_GERBER_List
[
layer
]
=
NULL
;
}
}
GERBER_IMAGE
*
GERBER_IMAGE_LIST
::
GetGbrImage
(
int
aIdx
)
{
if
(
(
unsigned
)
aIdx
<
m_GERBER_List
.
size
()
)
return
m_GERBER_List
[
aIdx
];
return
NULL
;
}
/**
* creates a new, empty GERBER_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int
GERBER_IMAGE_LIST
::
AddGbrImage
(
GERBER_IMAGE
*
aGbrImage
,
int
aIdx
)
{
int
idx
=
aIdx
;
if
(
idx
<
0
)
{
for
(
idx
=
0
;
idx
<
(
int
)
m_GERBER_List
.
size
();
idx
++
)
{
if
(
!
IsUsed
(
idx
)
)
break
;
}
}
if
(
idx
>=
(
int
)
m_GERBER_List
.
size
()
)
return
-
1
;
// No room
m_GERBER_List
[
idx
]
=
aGbrImage
;
return
idx
;
}
// remove all loaded data in list, but do not delete empty images
// (can be reused)
void
GERBER_IMAGE_LIST
::
ClearList
()
{
for
(
unsigned
layer
=
0
;
layer
<
m_GERBER_List
.
size
();
++
layer
)
ClearImage
(
layer
);
}
// remove the loaded data of image aIdx, but do not delete it
void
GERBER_IMAGE_LIST
::
ClearImage
(
int
aIdx
)
{
if
(
aIdx
>=
0
&&
aIdx
<
(
int
)
m_GERBER_List
.
size
()
&&
m_GERBER_List
[
aIdx
]
)
{
m_GERBER_List
[
aIdx
]
->
InitToolTable
();
m_GERBER_List
[
aIdx
]
->
ResetDefaultValues
();
m_GERBER_List
[
aIdx
]
->
m_InUse
=
false
;
}
}
// Build a name for image aIdx which can be used in layers manager
const
wxString
GERBER_IMAGE_LIST
::
GetDisplayName
(
int
aIdx
)
{
wxString
name
;
GERBER_IMAGE
*
gerber
=
NULL
;
if
(
aIdx
>=
0
&&
aIdx
<
(
int
)
m_GERBER_List
.
size
()
)
gerber
=
m_GERBER_List
[
aIdx
];
if
(
IsUsed
(
aIdx
)
)
{
if
(
gerber
->
m_FileFunction
)
name
.
Printf
(
_
(
"Layer %d (%s, %s)"
),
aIdx
+
1
,
GetChars
(
gerber
->
m_FileFunction
->
GetFileType
()
),
GetChars
(
gerber
->
m_FileFunction
->
GetBrdLayerId
()
)
);
else
name
.
Printf
(
_
(
"Layer %d *"
),
aIdx
+
1
);
}
else
name
.
Printf
(
_
(
"Layer %d"
),
aIdx
+
1
);
return
name
;
}
// return true if image is used (loaded and not cleared)
bool
GERBER_IMAGE_LIST
::
IsUsed
(
int
aIdx
)
{
if
(
aIdx
>=
0
&&
aIdx
<
(
int
)
m_GERBER_List
.
size
()
)
return
m_GERBER_List
[
aIdx
]
!=
NULL
&&
m_GERBER_List
[
aIdx
]
->
m_InUse
;
return
false
;
}
// Helper function, for std::sort.
// Sort loaded images by Z order priority, if they have the X2 FileFormat info
// returns true if the first argument (ref) is ordered before the second (test).
static
bool
sortZorder
(
const
GERBER_IMAGE
*
const
&
ref
,
const
GERBER_IMAGE
*
const
&
test
)
{
if
(
!
ref
&&
!
test
)
return
false
;
// do not change order: no criteria to sort items
if
(
!
ref
||
!
ref
->
m_InUse
)
return
false
;
// Not used: ref ordered after
if
(
!
test
||
!
test
->
m_InUse
)
return
true
;
// Not used: ref ordered before
if
(
!
ref
->
m_FileFunction
&&
!
test
->
m_FileFunction
)
return
false
;
// do not change order: no criteria to sort items
if
(
!
ref
->
m_FileFunction
)
return
false
;
if
(
!
test
->
m_FileFunction
)
return
true
;
if
(
ref
->
m_FileFunction
->
GetZOrder
()
!=
test
->
m_FileFunction
->
GetZOrder
()
)
return
ref
->
m_FileFunction
->
GetZOrder
()
>
test
->
m_FileFunction
->
GetZOrder
();
return
ref
->
m_FileFunction
->
GetZSubOrder
()
>
test
->
m_FileFunction
->
GetZSubOrder
();
}
void
GERBER_IMAGE_LIST
::
SortImagesByZOrder
(
GERBER_DRAW_ITEM
*
aDrawList
)
{
std
::
sort
(
m_GERBER_List
.
begin
(),
m_GERBER_List
.
end
(),
sortZorder
);
// The image order has changed.
// Graphic layer numbering must be updated to match the widgets layer order
// Store the old/new graphic layer info:
std
::
map
<
int
,
int
>
tab_lyr
;
for
(
unsigned
layer
=
0
;
layer
<
m_GERBER_List
.
size
();
++
layer
)
{
if
(
m_GERBER_List
[
layer
]
)
{
tab_lyr
[
m_GERBER_List
[
layer
]
->
m_GraphicLayer
]
=
layer
;
m_GERBER_List
[
layer
]
->
m_GraphicLayer
=
layer
;
}
}
// update the graphic layer in items to draw
for
(
GERBER_DRAW_ITEM
*
item
=
aDrawList
;
item
;
item
=
item
->
Next
()
)
{
int
layer
=
item
->
GetLayer
();
item
->
SetLayer
(
tab_lyr
[
layer
]
);
}
}
// The global image list:
GERBER_IMAGE_LIST
g_GERBER_List
;
gerbview/class_GERBER.h
View file @
0cf91f46
...
...
@@ -61,6 +61,7 @@ class D_CODE;
*/
class
GERBER_IMAGE
;
class
X2_ATTRIBUTE_FILEFUNCTION
;
class
GERBER_LAYER
{
...
...
@@ -104,6 +105,11 @@ public:
// (a file is loaded in it)
wxString
m_FileName
;
// Full File Name for this layer
wxString
m_ImageName
;
// Image name, from IN <name>* command
bool
m_IsX2_file
;
// true if a X2 gerber attribute was found in file
X2_ATTRIBUTE_FILEFUNCTION
*
m_FileFunction
;
// file function parameters, found in a %TF command
// or a G04
wxString
m_MD5_value
;
// MD5 value found in a %TF.MD5 command
wxString
m_PartString
;
// string found in a %TF.Part command
int
m_GraphicLayer
;
// Graphic layer Number
bool
m_ImageNegative
;
// true = Negative image
bool
m_ImageJustifyXCenter
;
// Image Justify Center on X axis (default = false)
...
...
@@ -306,5 +312,67 @@ public:
void
DisplayImageInfo
(
void
);
};
/**
* @brief GERBER_IMAGE_LIST is a helper class to handle a list of GERBER_IMAGE files
* which are loaded and can be displayed
* there are 32 images max which can be loaded
*/
class
GERBER_IMAGE_LIST
{
// the list of loaded images (1 image = 1 gerber file)
std
::
vector
<
GERBER_IMAGE
*>
m_GERBER_List
;
public
:
GERBER_IMAGE_LIST
();
~
GERBER_IMAGE_LIST
();
//Accessor
GERBER_IMAGE
*
GetGbrImage
(
int
aIdx
);
/**
* Add a GERBER_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aGbrImage = the image to add
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int
AddGbrImage
(
GERBER_IMAGE
*
aGbrImage
,
int
aIdx
);
/**
* remove all loaded data in list
*/
void
ClearList
();
/**
* remove the loaded data of image aIdx
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
void
ClearImage
(
int
aIdx
);
/**
* @return a name for image aIdx which can be used in layers manager
* and layer selector
* is is "Layer n" (n = aIdx+1), followed by file attribute info (if X2 format)
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
const
wxString
GetDisplayName
(
int
aIdx
);
/**
* @return true if image is used (loaded and with items)
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
bool
IsUsed
(
int
aIdx
);
/**
* Sort loaded images by Z order priority, if they have the X2 FileFormat info
* @param aDrawList: the draw list associated to the gerber images
* (SortImagesByZOrder updates the graphic layer of these items)
*/
void
SortImagesByZOrder
(
GERBER_DRAW_ITEM
*
aDrawList
);
};
extern
GERBER_IMAGE_LIST
g_GERBER_List
;
#endif // ifndef _CLASS_GERBER_H_
gerbview/class_X2_gerber_attributes.cpp
0 → 100644
View file @
0cf91f46
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_X2_gerber_attributes.cpp
*/
/*
* Manage the gerber extensions (attributes) in the new X2 version
* only few extensions are handled
* See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
*
* gerber attributes in the new X2 version look like:
* %TF.FileFunction,Copper,L1,Top*%
*
* Currently:
* .FileFunction .FileFunction Identifies the file’s function in the PCB.
* Other Standard Attributes, not yet used in Gerbview:
* .Part Identifies the part the file represents, e.g. a single PCB
* .MD5 Sets the MD5 file signature or checksum.
*/
#include <wx/log.h>
#include <class_X2_gerber_attributes.h>
/*
* class X2_ATTRIBUTE
* The attribute value consists of a number of substrings separated by a “,”
*/
X2_ATTRIBUTE
::
X2_ATTRIBUTE
()
{
}
X2_ATTRIBUTE
::~
X2_ATTRIBUTE
()
{
}
/* return the attribute name (for instance .FileFunction)
* which is given by TF command.
*/
const
wxString
&
X2_ATTRIBUTE
::
GetAttribute
()
{
return
m_Prms
.
Item
(
0
);
}
/* return a parameter
* aIdx = the index of the parameter
* aIdx = 0 is the parameter read after the TF function
* (the same as GetAttribute())
*/
const
wxString
&
X2_ATTRIBUTE
::
GetPrm
(
int
aIdx
)
{
static
const
wxString
dummy
;
if
(
GetPrmCount
()
<
aIdx
&&
aIdx
>=
0
)
return
m_Prms
.
Item
(
aIdx
);
return
dummy
;
}
// Debug function: pring using wxLogMessage le list of parameters
void
X2_ATTRIBUTE
::
DbgListPrms
()
{
wxLogMessage
(
wxT
(
"prms count %d"
),
GetPrmCount
()
);
for
(
int
ii
=
0
;
ii
<
GetPrmCount
();
ii
++
)
wxLogMessage
(
m_Prms
.
Item
(
ii
)
);
}
/*
* parse a TF command and fill m_Prms by the parameters found.
* aFile = a FILE* ptr to the current Gerber file.
* buff = the buffer containing current Gerber data (GERBER_BUFZ size)
* text = a pointer to the first char to read in Gerber data
*/
bool
X2_ATTRIBUTE
::
ParseAttribCmd
(
FILE
*
aFile
,
char
*
aBuffer
,
int
aBuffSize
,
char
*
&
aText
)
{
bool
ok
=
true
;
wxString
data
;
for
(
;
;
)
{
while
(
*
aText
)
{
switch
(
*
aText
)
{
case
'%'
:
// end of command
return
ok
;
// success completion
case
' '
:
case
'\r'
:
case
'\n'
:
aText
++
;
break
;
case
'*'
:
// End of block
m_Prms
.
Add
(
data
);
data
.
Empty
();
aText
++
;
break
;
case
','
:
// End of parameter
aText
++
;
m_Prms
.
Add
(
data
);
data
.
Empty
();
break
;
default
:
data
.
Append
(
*
aText
);
aText
++
;
break
;
}
}
// end of current line, read another one.
if
(
aBuffer
)
{
if
(
fgets
(
aBuffer
,
aBuffSize
,
aFile
)
==
NULL
)
{
// end of file
ok
=
false
;
break
;
}
aText
=
aBuffer
;
}
else
return
ok
;
}
return
ok
;
}
/*
* class X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file)
* Example file function:
* %TF.FileFunction,Copper,L1,Top*%
* - Type. Such as copper, solder mask etc.
* - Position. Specifies where the file appears in the PCB layer structure.
* Corresponding position substring:
* Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or
* Bot. L1 is always the top copper layer. E.g. L2,Inr.
* Extra layer, e.g. solder mask: Top or Bot – defines the attachment of the layer.
* Drill/rout layer: E.g. 1,4 – where 1 is the start and 4 is the end copper layer. The
* pair 1,4 defines the span of the drill/rout file
* Optional index. This can be used in instances where for example there are two solder
* masks on the same side. The index counts from the PCB surface outwards.
*/
X2_ATTRIBUTE_FILEFUNCTION
::
X2_ATTRIBUTE_FILEFUNCTION
(
X2_ATTRIBUTE
&
aAttributeBase
)
:
X2_ATTRIBUTE
()
{
m_Prms
=
aAttributeBase
.
GetPrms
();
m_z_order
=
0
;
//ensure at least 5 parameters
while
(
GetPrmCount
()
<
5
)
m_Prms
.
Add
(
wxEmptyString
);
set_Z_Order
();
}
const
wxString
&
X2_ATTRIBUTE_FILEFUNCTION
::
GetFileType
()
{
// the type of layer (Copper , Soldermask ... )
return
m_Prms
.
Item
(
1
);
}
const
wxString
&
X2_ATTRIBUTE_FILEFUNCTION
::
GetBrdLayerId
()
{
// the brd layer identifier: Top, Bot, Ln
return
m_Prms
.
Item
(
2
);
}
const
wxString
&
X2_ATTRIBUTE_FILEFUNCTION
::
GetLabel
()
{
// the filefunction label, if any
return
m_Prms
.
Item
(
3
);
}
// Initialize the z order priority of the current file, from its attributes
// this priority is the order of layers from top to bottom to draw/display gerber images
// Stack up is( from external copper layer to external)
// copper, then solder paste, then solder mask, then silk screen.
// and global stackup is Front (top) layers then internal copper layers then Back (bottom) layers
void
X2_ATTRIBUTE_FILEFUNCTION
::
set_Z_Order
()
{
m_z_order
=
-
100
;
// low level
m_z_sub_order
=
0
;
if
(
GetFileType
().
IsSameAs
(
wxT
(
"Copper"
),
false
)
)
{
// Copper layer: the priority is the layer Id
m_z_order
=
0
;
wxString
num
=
GetBrdLayerId
().
Mid
(
1
);
long
lnum
;
if
(
num
.
ToLong
(
&
lnum
)
)
m_z_sub_order
=
-
lnum
;
}
if
(
GetFileType
().
IsSameAs
(
wxT
(
"Paste"
),
false
)
)
{
// solder paste layer: the priority is top then bottom
m_z_order
=
1
;
// for top
if
(
GetBrdLayerId
().
IsSameAs
(
wxT
(
"Bot"
),
false
)
)
m_z_order
=
-
m_z_order
;
}
if
(
GetFileType
().
IsSameAs
(
wxT
(
"Soldermask"
),
false
)
)
{
// solder mask layer: the priority is top then bottom
m_z_order
=
2
;
// for top
if
(
GetBrdLayerId
().
IsSameAs
(
wxT
(
"Bot"
),
false
)
)
m_z_order
=
-
m_z_order
;
}
if
(
GetFileType
().
IsSameAs
(
wxT
(
"Legend"
),
false
)
)
{
// Silk screen layer: the priority is top then bottom
m_z_order
=
3
;
// for top
if
(
GetFileType
().
IsSameAs
(
wxT
(
"Legend"
),
false
)
)
if
(
GetBrdLayerId
().
IsSameAs
(
wxT
(
"Bot"
),
false
)
)
m_z_order
=
-
m_z_order
;
}
}
gerbview/class_X2_gerber_attributes.h
0 → 100644
View file @
0cf91f46
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2014 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file class_X2_gerber_attributes.h
*/
#ifndef _CLASS_X2_GERBER_ATTRIBUTE_H_
#define _CLASS_X2_GERBER_ATTRIBUTE_H_
/*
* Manage the gerber extensions (attributes) in the new X2 version
* only few extensions are handled
* See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
*
* gerber attributes in the new X2 version look like:
* %TF.FileFunction,Copper,L1,Top*%
*
* Currently:
* .FileFunction .FileFunction Identifies the file’s function in the PCB.
* Other Standard Attributes, not yet used in Gerbview:
* .Part Identifies the part the file represents, e.g. a single PCB
* .MD5 Sets the MD5 file signature or checksum.
*/
#include <wx/arrstr.h>
/**
* class X2_ATTRIBUTE
* The attribute value consists of a number of substrings separated by a “,”
*/
class
X2_ATTRIBUTE
{
protected
:
wxArrayString
m_Prms
;
///< the list of parameters (after TF) in gbr file
///< the first one is the attribute name,
///< if starting by '.'
public
:
X2_ATTRIBUTE
();
~
X2_ATTRIBUTE
();
/**
* @return the parameters list read in TF command.
*/
wxArrayString
&
GetPrms
()
{
return
m_Prms
;
}
/**
* @return a parameter read in TF command.
* @param aIdx = the index of the parameter
* aIdx = 0 is the parameter read after the TF function
* (the same as GetAttribute())
*/
const
wxString
&
GetPrm
(
int
aIdx
);
/**
* @return the attribute name (for instance .FileFunction)
* which is given by TF command (i.e. the first parameter read).
*/
const
wxString
&
GetAttribute
();
/**
* @return the number of parameters read in TF command.
*/
int
GetPrmCount
()
{
return
int
(
m_Prms
.
GetCount
()
);
}
/**
* parse a TF command terminated with a % and fill m_Prms
* by the parameters found.
* @param aFile = a FILE* ptr to the current Gerber file.
* @param aBuffer = the buffer containing current Gerber data (can be null)
* @param aBuffSize = the size of the buffer
* @param aText = a pointer to the first char to read from Gerber data stored in aBuffer
* After parsing, text points the last char of the command line ('%') (X2 mode)
* or the end of line if the line does not contain '%' or aBuffer == NULL (X1 mode)
* @return true if no error.
*/
bool
ParseAttribCmd
(
FILE
*
aFile
,
char
*
aBuffer
,
int
aBuffSize
,
char
*
&
aText
);
/**
* Debug function: pring using wxLogMessage le list of parameters
*/
void
DbgListPrms
();
/**
* return true if the attribute is .FileFunction
*/
bool
IsFileFunction
()
{
return
GetAttribute
().
IsSameAs
(
wxT
(
".FileFunction"
),
false
);
}
/**
* return true if the attribute is .MD5
*/
bool
IsFileMD5
()
{
return
GetAttribute
().
IsSameAs
(
wxT
(
".MD5"
),
false
);
}
/**
* return true if the attribute is .Part
*/
bool
IsFilePart
()
{
return
GetAttribute
().
IsSameAs
(
wxT
(
".Part"
),
false
);
}
};
/**
* class X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file)
* Example file function:
* %TF.FileFunction,Copper,L1,Top*%
* - Type. Such as copper, solder mask etc.
* - Position. Specifies where the file appears in the PCB layer structure.
* Corresponding position substring:
* Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or
* Bot. L1 is always the top copper layer. E.g. L2,Inr.
* Extra layer, e.g. solder mask: Top or Bot – defines the attachment of the layer.
* Drill/rout layer: E.g. 1,4 – where 1 is the start and 4 is the end copper layer. The
* pair 1,4 defines the span of the drill/rout file
* Optional index. This can be used in instances where for example there are two solder
* masks on the same side. The index counts from the PCB surface outwards.
*/
class
X2_ATTRIBUTE_FILEFUNCTION
:
public
X2_ATTRIBUTE
{
int
m_z_order
;
// the z order of the layer for a board
int
m_z_sub_order
;
// the z sub_order of the copper layer for a board
public
:
X2_ATTRIBUTE_FILEFUNCTION
(
X2_ATTRIBUTE
&
aAttributeBase
);
const
wxString
&
GetFileType
();
///< the type of layer (Copper , Soldermask ... )
const
wxString
&
GetBrdLayerId
();
///< the brd layer identifier: Top, Bot, Ln
const
wxString
&
GetLabel
();
///< the filefunction label, if any
int
GetZOrder
()
{
return
m_z_order
;
}
///< the Order of the bdr layer, from front (Top side) to back side
int
GetZSubOrder
()
{
return
m_z_sub_order
;
}
///< the Order of the bdr copper layer, from front (Top side) to back side
private
:
/**
* Initialize the z order priority of the current file, from its attributes
*/
void
set_Z_Order
();
};
#endif // _CLASS_X2_GERBER_ATTRIBUTE_H_
gerbview/class_gbr_layer_box_selector.cpp
View file @
0cf91f46
...
...
@@ -33,11 +33,14 @@
#include <colors_selection.h>
#include <layers_id_colors_and_visibility.h>
#include <gerbview_frame.h>
#include <class_GERBER.h>
#include <class_X2_gerber_attributes.h>
#include <class_gbr_layer_box_selector.h>
void
GBR_LAYER_BOX_SELECTOR
::
Resync
()
{
Freeze
();
Clear
();
for
(
int
layerid
=
0
;
layerid
<
GERBER_DRAWLAYERS_COUNT
;
++
layerid
)
...
...
@@ -55,6 +58,8 @@ void GBR_LAYER_BOX_SELECTOR::Resync()
Append
(
layername
,
layerbmp
,
(
void
*
)(
intptr_t
)
layerid
);
}
Thaw
();
}
...
...
@@ -70,7 +75,7 @@ EDA_COLOR_T GBR_LAYER_BOX_SELECTOR::GetLayerColor( int aLayer ) const
// Returns the name of the layer id
wxString
GBR_LAYER_BOX_SELECTOR
::
GetLayerName
(
int
aLayer
)
const
{
wxString
name
;
name
.
Printf
(
_
(
"Layer %d"
),
aLayer
+
1
);
wxString
name
=
g_GERBER_List
.
GetDisplayName
(
aLayer
)
;
return
name
;
}
gerbview/class_gbr_layout.cpp
View file @
0cf91f46
...
...
@@ -39,7 +39,6 @@ GBR_LAYOUT::GBR_LAYOUT()
PAGE_INFO
pageInfo
(
wxT
(
"GERBER"
)
);
SetPageSettings
(
pageInfo
);
// no m_printLayersMask = -1;
m_printLayersMask
.
set
();
}
...
...
gerbview/class_gbr_layout.h
View file @
0cf91f46
...
...
@@ -24,7 +24,8 @@
/**
* @file class_gbr_layout.h
* @brief Class CLASS_GBR_LAYOUT to handle a board.
* @brief Class CLASS_GBR_LAYOUT to handle info to draw/print loaded Gerber images
* and page frame reference
*/
#ifndef CLASS_GBR_LAYOUT_H
...
...
@@ -55,7 +56,7 @@ private:
std
::
bitset
<
GERBER_DRAWLAYERS_COUNT
>
m_printLayersMask
;
// When printing: the list of layers to print
public
:
DLIST
<
GERBER_DRAW_ITEM
>
m_Drawings
;
// linked list of Gerber Items
DLIST
<
GERBER_DRAW_ITEM
>
m_Drawings
;
// linked list of Gerber Items
to draw
GBR_LAYOUT
();
~
GBR_LAYOUT
();
...
...
gerbview/class_gerber_draw_item.cpp
View file @
0cf91f46
...
...
@@ -225,7 +225,9 @@ D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
{
if
(
(
m_DCode
<
FIRST_DCODE
)
||
(
m_DCode
>
LAST_DCODE
)
)
return
NULL
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
m_Layer
];
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
m_Layer
);
if
(
gerber
==
NULL
)
return
NULL
;
...
...
gerbview/class_gerbview_layer_widget.cpp
View file @
0cf91f46
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004-2010 Jean-Pierre Charras, j
ean-pierre.charras@gpisa-lab.inpg
.fr
* Copyright (C) 2004-2010 Jean-Pierre Charras, j
p.charras at wanadoo
.fr
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2010 KiCad Developers, see change_log.txt for contributors.
*
...
...
@@ -41,6 +41,7 @@
#include <class_GERBER.h>
#include <layer_widget.h>
#include <class_gerbview_layer_widget.h>
#include <class_X2_gerber_attributes.h>
/*
...
...
@@ -70,7 +71,7 @@ GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFo
// since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
// and not m_LayerScrolledWindow->Connect()
Connect
(
ID_
SHOW_ALL_LAYERS
,
ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE
,
Connect
(
ID_
LAYER_MANAGER_START
,
ID_LAYER_MANAGER_END
,
wxEVT_COMMAND_MENU_SELECTED
,
wxCommandEventHandler
(
GERBER_LAYER_WIDGET
::
onPopupSelection
),
NULL
,
this
);
...
...
@@ -146,8 +147,7 @@ void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
{
wxMenu
menu
;
// menu text is capitalized:
// http://library.gnome.org/devel/hig-book/2.20/design-text-labels.html.en#layout-capitalization
// Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_ALL_LAYERS
,
_
(
"Show All Layers"
)
)
);
...
...
@@ -160,6 +160,9 @@ void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SHOW_NO_LAYERS
,
_
(
"Hide All Layers"
)
)
);
menu
.
AppendSeparator
();
menu
.
Append
(
new
wxMenuItem
(
&
menu
,
ID_SORT_GBR_LAYERS
,
_
(
"Sort Layers if X2 Mode"
)
)
);
PopupMenu
(
&
menu
);
passOnFocus
();
...
...
@@ -204,6 +207,13 @@ void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
myframe
->
SetVisibleLayers
(
visibleLayers
);
myframe
->
GetCanvas
()
->
Refresh
();
break
;
case
ID_SORT_GBR_LAYERS
:
g_GERBER_List
.
SortImagesByZOrder
(
myframe
->
GetItemsList
()
);
myframe
->
ReFillLayerWidget
();
myframe
->
syncLayerBox
();
myframe
->
GetCanvas
()
->
Refresh
();
break
;
}
}
...
...
@@ -212,7 +222,7 @@ bool GERBER_LAYER_WIDGET::OnLayerSelected()
if
(
!
m_alwaysShowActiveLayer
)
return
false
;
// postprocess after a
n a
ctive layer selection
// postprocess after active layer selection
// ensure active layer visible
wxCommandEvent
event
;
event
.
SetId
(
ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE
);
...
...
@@ -223,16 +233,20 @@ bool GERBER_LAYER_WIDGET::OnLayerSelected()
void
GERBER_LAYER_WIDGET
::
ReFill
()
{
Freeze
();
ClearLayerRows
();
for
(
int
layer
=
0
;
layer
<
GERBER_DRAWLAYERS_COUNT
;
++
layer
)
{
wxString
msg
;
msg
.
Printf
(
_
(
"Layer %d"
),
layer
+
1
);
wxString
msg
=
g_GERBER_List
.
GetDisplayName
(
layer
)
;
AppendLayerRow
(
LAYER_WIDGET
::
ROW
(
msg
,
layer
,
myframe
->
GetLayerColor
(
layer
),
wxEmptyString
,
true
)
);
}
Thaw
();
installRightLayerClickHandler
();
}
...
...
@@ -298,17 +312,10 @@ void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
*/
bool
GERBER_LAYER_WIDGET
::
useAlternateBitmap
(
int
aRow
)
{
bool
inUse
=
false
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
aRow
];
if
(
gerber
!=
NULL
&&
gerber
->
m_InUse
)
inUse
=
true
;
return
inUse
;
return
g_GERBER_List
.
IsUsed
(
aRow
);
}
/**
* Function UpdateLayerIcons
/*
* Update the layer manager icons (layers only)
* Useful when loading a file or clearing a layer because they change
*/
...
...
@@ -322,7 +329,8 @@ void GERBER_LAYER_WIDGET::UpdateLayerIcons()
continue
;
if
(
row
==
m_CurrentRow
)
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_RightArrowAlternateBitmap
:
*
m_RightArrowBitmap
);
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_RightArrowAlternateBitmap
:
*
m_RightArrowBitmap
);
else
bm
->
SetBitmap
(
useAlternateBitmap
(
row
)
?
*
m_BlankAlternateBitmap
:
*
m_BlankBitmap
);
}
...
...
gerbview/class_gerbview_layer_widget.h
View file @
0cf91f46
...
...
@@ -33,6 +33,18 @@
#include <layer_widget.h>
// popup menu ids. in layer manager
enum
LAYER_MANAGER
{
ID_LAYER_MANAGER_START
=
wxID_HIGHEST
+
1
,
ID_SHOW_ALL_LAYERS
=
ID_LAYER_MANAGER_START
,
ID_SHOW_NO_LAYERS
,
ID_SHOW_NO_LAYERS_BUT_ACTIVE
,
ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE
,
ID_SORT_GBR_LAYERS
,
ID_LAYER_MANAGER_END
=
ID_SORT_GBR_LAYERS
,
};
/**
* Class GERBER_LAYER_WIDGET
* is here to implement the abtract functions of LAYER_WIDGET so they
...
...
@@ -45,11 +57,6 @@ class GERBER_LAYER_WIDGET : public LAYER_WIDGET
bool
m_alwaysShowActiveLayer
;
// If true: Only shows the current active layer
// even if it is changed
// popup menu ids.
#define ID_SHOW_ALL_LAYERS wxID_HIGHEST
#define ID_SHOW_NO_LAYERS (wxID_HIGHEST+1)
#define ID_SHOW_NO_LAYERS_BUT_ACTIVE (wxID_HIGHEST+2)
#define ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE (wxID_HIGHEST+3)
/**
* Function OnRightDownLayers
...
...
gerbview/dialogs/dialog_print_using_printer.cpp
View file @
0cf91f46
...
...
@@ -37,6 +37,7 @@
#include <gerbview.h>
#include <gerbview_frame.h>
#include <class_GERBER.h>
#include <pcbplot.h>
static
double
s_ScaleList
[]
=
...
...
@@ -163,7 +164,7 @@ void DIALOG_PRINT_USING_PRINTER::InitValues( )
msg
<<
wxT
(
" "
)
<<
ii
+
1
;
m_BoxSelectLayer
[
ii
]
=
new
wxCheckBox
(
this
,
-
1
,
msg
);
if
(
g_GERBER_List
[
ii
]
==
NULL
)
// Nothing loaded on this draw layer
if
(
g_GERBER_List
.
GetGbrImage
(
ii
)
==
NULL
)
// Nothing loaded on this draw layer
m_BoxSelectLayer
[
ii
]
->
Enable
(
false
);
if
(
ii
<
16
)
...
...
gerbview/draw_gerber_screen.cpp
View file @
0cf91f46
...
...
@@ -214,14 +214,16 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
bool
end
=
false
;
for
(
int
layer
=
0
;
!
end
;
++
layer
)
// Draw layers from bottom to top, and active layer last
// in non transparent modes, the last layer drawn mask mask previously drawn layer
for
(
int
layer
=
GERBER_DRAWLAYERS_COUNT
-
1
;
!
end
;
--
layer
)
{
int
active_layer
=
gerbFrame
->
getActiveLayer
();
if
(
layer
==
active_layer
)
// active layer will be drawn after other layers
continue
;
if
(
layer
==
GERBER_DRAWLAYERS_COUNT
)
// last loop: draw active layer
if
(
layer
<
0
)
// last loop: draw active layer
{
end
=
true
;
layer
=
active_layer
;
...
...
@@ -230,7 +232,7 @@ void GBR_LAYOUT::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
if
(
!
gerbFrame
->
IsLayerVisible
(
layer
)
)
continue
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
layer
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
layer
)
;
if
(
gerber
==
NULL
)
// Graphic layer not yet used
continue
;
...
...
gerbview/events_called_functions.cpp
View file @
0cf91f46
...
...
@@ -234,7 +234,7 @@ void GERBVIEW_FRAME::Process_Special_Functions( wxCommandEvent& event )
void
GERBVIEW_FRAME
::
OnSelectActiveDCode
(
wxCommandEvent
&
event
)
{
GERBER_IMAGE
*
gerber_image
=
g_GERBER_List
[
getActiveLayer
()]
;
GERBER_IMAGE
*
gerber_image
=
g_GERBER_List
.
GetGbrImage
(
getActiveLayer
()
)
;
if
(
gerber_image
)
{
...
...
@@ -266,7 +266,7 @@ void GERBVIEW_FRAME::OnSelectActiveLayer( wxCommandEvent& event )
void
GERBVIEW_FRAME
::
OnShowGerberSourceFile
(
wxCommandEvent
&
event
)
{
int
layer
=
getActiveLayer
();
GERBER_IMAGE
*
gerber_layer
=
g_GERBER_List
[
layer
]
;
GERBER_IMAGE
*
gerber_layer
=
g_GERBER_List
.
GetGbrImage
(
layer
)
;
if
(
gerber_layer
)
{
...
...
gerbview/excellon_read_drill_file.cpp
View file @
0cf91f46
...
...
@@ -8,8 +8,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-201
1 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg
.fr>
* Copyright (C) 1992-201
1
KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 1992-201
4 Jean-Pierre Charras <jp.charras at wanadoo
.fr>
* Copyright (C) 1992-201
4
KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -75,6 +75,7 @@
#include <class_GERBER.h>
#include <class_excellon.h>
#include <kicad_string.h>
#include <class_X2_gerber_attributes.h>
#include <cmath>
...
...
@@ -93,18 +94,24 @@ extern double ReadDouble( char*& text, bool aSkipSeparator = true );
extern
void
fillFlashedGBRITEM
(
GERBER_DRAW_ITEM
*
aGbrItem
,
APERTURE_T
aAperture
,
int
Dcode_index
,
int
aLayer
,
int
aLayer
,
const
wxPoint
&
aPos
,
wxSize
aSize
,
bool
aLayerNegative
);
void
fillLineGBRITEM
(
GERBER_DRAW_ITEM
*
aGbrItem
,
int
Dcode_index
,
int
aLayer
,
int
aLayer
,
const
wxPoint
&
aStart
,
const
wxPoint
&
aEnd
,
wxSize
aPenSize
,
bool
aLayerNegative
);
// Getber X2 files have a file attribute which specify the type of image
// (copper, solder paste ... and sides tpo, bottom or inner copper layers)
// Excellon drill files do not have attributes, so, just to identify the image
// In gerbview, we add this attribute, like a Gerber drill file
static
const
char
file_attribute
[]
=
".FileFunction,Other,Drill*"
;
static
EXCELLON_CMD
excellonHeaderCmdList
[]
=
{
{
"M0"
,
DRILL_M_END
,
-
1
},
// End of Program - No Rewind
...
...
@@ -168,14 +175,21 @@ static EXCELLON_CMD excellon_G_CmdList[] =
bool
GERBVIEW_FRAME
::
Read_EXCELLON_File
(
const
wxString
&
aFullFileName
)
{
wxString
msg
;
int
layer
=
getActiveLayer
();
// current layer used in GerbView
int
layerId
=
getActiveLayer
();
// current layer used in GerbView
EXCELLON_IMAGE
*
drill_Layer
=
(
EXCELLON_IMAGE
*
)
g_GERBER_List
.
GetGbrImage
(
layerId
);
if
(
drill_Layer
==
NULL
)
{
drill_Layer
=
new
EXCELLON_IMAGE
(
this
,
layerId
);
layerId
=
g_GERBER_List
.
AddGbrImage
(
drill_Layer
,
layerId
);
}
if
(
g_GERBER_List
[
layer
]
==
NULL
)
if
(
layerId
<
0
)
{
g_GERBER_List
[
layer
]
=
new
EXCELLON_IMAGE
(
this
,
layer
);
DisplayError
(
this
,
_
(
"No room to load file"
)
);
return
false
;
}
EXCELLON_IMAGE
*
drill_Layer
=
(
EXCELLON_IMAGE
*
)
g_GERBER_List
[
layer
];
ClearMessageList
();
/* Read the gerber file */
...
...
@@ -183,7 +197,7 @@ bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName )
if
(
file
==
NULL
)
{
msg
.
Printf
(
_
(
"File %s not found"
),
GetChars
(
aFullFileName
)
);
DisplayError
(
this
,
msg
,
10
);
DisplayError
(
this
,
msg
);
return
false
;
}
...
...
@@ -213,7 +227,7 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
m_FileName
=
aFullFileName
;
m_Current_File
=
aFile
;
SetLocaleTo_C_standard
()
;
LOCALE_IO
toggleIo
;
// FILE_LINE_READER will close the file.
if
(
m_Current_File
==
NULL
)
...
...
@@ -282,7 +296,16 @@ bool EXCELLON_IMAGE::Read_EXCELLON_File( FILE * aFile,
}
// End switch
}
}
SetLocaleTo_Default
();
// Add our file attribute, to identify the drill file
X2_ATTRIBUTE
dummy
;
char
*
text
=
(
char
*
)
file_attribute
;
dummy
.
ParseAttribCmd
(
m_Current_File
,
NULL
,
0
,
text
);
delete
m_FileFunction
;
m_FileFunction
=
new
X2_ATTRIBUTE_FILEFUNCTION
(
dummy
);
m_InUse
=
true
;
return
true
;
}
...
...
gerbview/export_to_pcbnew.cpp
View file @
0cf91f46
...
...
@@ -39,6 +39,7 @@
#include <gerbview.h>
#include <gerbview_frame.h>
#include <class_gerber_draw_item.h>
#include <class_GERBER.h>
#include <select_layers_to_pcb.h>
#include <build_version.h>
#include <wildcards_and_files_ext.h>
...
...
@@ -159,7 +160,7 @@ void GERBVIEW_FRAME::ExportDataInPcbnewFormat( wxCommandEvent& event )
// Count the Gerber layers which are actually currently used
for
(
LAYER_NUM
ii
=
0
;
ii
<
GERBER_DRAWLAYERS_COUNT
;
++
ii
)
{
if
(
g_GERBER_List
[
ii
]
!=
NULL
)
if
(
g_GERBER_List
.
GetGbrImage
(
ii
)
)
layercount
++
;
}
...
...
gerbview/files.cpp
View file @
0cf91f46
...
...
@@ -84,6 +84,7 @@ void GERBVIEW_FRAME::Files_io( wxCommandEvent& event )
Zoom_Automatique
(
false
);
m_canvas
->
Refresh
();
ClearMsgPanel
();
ReFillLayerWidget
();
break
;
case
ID_GERBVIEW_LOAD_DRILL_FILE
:
...
...
@@ -200,6 +201,7 @@ bool GERBVIEW_FRAME::LoadGerberFiles( const wxString& aFullFileName )
Zoom_Automatique
(
false
);
// Synchronize layers tools with actual active layer:
ReFillLayerWidget
();
setActiveLayer
(
getActiveLayer
()
);
m_LayersManager
->
UpdateLayerIcons
();
syncLayerBox
();
...
...
@@ -282,6 +284,7 @@ bool GERBVIEW_FRAME::LoadExcellonFiles( const wxString& aFullFileName )
Zoom_Automatique
(
false
);
// Synchronize layers tools with actual active layer:
ReFillLayerWidget
();
setActiveLayer
(
getActiveLayer
()
);
m_LayersManager
->
UpdateLayerIcons
();
syncLayerBox
();
...
...
gerbview/gerbview.cpp
View file @
0cf91f46
...
...
@@ -45,7 +45,6 @@
// Colors for layers and items
COLORS_DESIGN_SETTINGS
g_ColorsSettings
;
int
g_Default_GERBER_Format
;
const
wxChar
*
g_GerberPageSizeList
[]
=
{
...
...
@@ -60,9 +59,6 @@ const wxChar* g_GerberPageSizeList[] = {
};
GERBER_IMAGE
*
g_GERBER_List
[
32
];
namespace
GERBV
{
static
struct
IFACE
:
public
KIFACE_I
...
...
gerbview/gerbview.h
View file @
0cf91f46
...
...
@@ -109,6 +109,4 @@ enum Gerb_Analyse_Cmd
ENTER_RS274X_CMD
};
extern
GERBER_IMAGE
*
g_GERBER_List
[
GERBER_DRAWLAYERS_COUNT
];
#endif // ifndef GERBVIEW_H
gerbview/gerbview_frame.cpp
View file @
0cf91f46
...
...
@@ -348,7 +348,7 @@ int GERBVIEW_FRAME::getNextAvailableLayer( int aLayer ) const
for
(
int
i
=
0
;
i
<
GERBER_DRAWLAYERS_COUNT
;
++
i
)
{
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
layer
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
layer
)
;
if
(
gerber
==
NULL
||
gerber
->
m_FileName
.
IsEmpty
()
)
return
layer
;
...
...
@@ -378,9 +378,11 @@ void GERBVIEW_FRAME::syncLayerWidget()
*/
void
GERBVIEW_FRAME
::
syncLayerBox
()
{
m_SelLayerBox
->
Resync
();
m_SelLayerBox
->
SetSelection
(
getActiveLayer
()
);
int
dcodeSelected
=
-
1
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
getActiveLayer
()]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
getActiveLayer
()
)
;
if
(
gerber
)
dcodeSelected
=
gerber
->
m_Selected_Tool
;
...
...
@@ -406,7 +408,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
for
(
int
layer
=
0
;
layer
<
GERBER_DRAWLAYERS_COUNT
;
++
layer
)
{
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
layer
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
layer
)
;
if
(
gerber
==
NULL
)
continue
;
...
...
@@ -474,7 +476,7 @@ void GERBVIEW_FRAME::Liste_D_Codes()
*/
void
GERBVIEW_FRAME
::
UpdateTitleAndInfo
()
{
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
getActiveLayer
()
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
getActiveLayer
()
)
;
wxString
text
;
// Display the gerber filename
...
...
@@ -491,6 +493,8 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
text
=
_
(
"File:"
);
text
<<
wxT
(
" "
)
<<
gerber
->
m_FileName
;
if
(
gerber
->
m_IsX2_file
)
text
<<
wxT
(
" "
)
<<
_
(
"(with X2 Attributes)"
);
SetTitle
(
text
);
gerber
->
DisplayImageInfo
();
...
...
@@ -508,7 +512,13 @@ void GERBVIEW_FRAME::UpdateTitleAndInfo()
gerber
->
m_FmtLen
.
y
-
gerber
->
m_FmtScale
.
y
,
gerber
->
m_FmtScale
.
y
,
gerber
->
m_NoTrailingZeros
?
'T'
:
'L'
);
if
(
gerber
->
m_IsX2_file
)
text
<<
wxT
(
" "
)
<<
_
(
"X2 attr"
);
m_TextInfo
->
SetValue
(
text
);
if
(
EnsureTextCtrlWidth
(
m_TextInfo
,
&
text
)
)
// Resized
m_auimgr
.
Update
();
}
/*
...
...
gerbview/init_gbr_drawlayers.cpp
View file @
0cf91f46
...
...
@@ -40,8 +40,6 @@
bool
GERBVIEW_FRAME
::
Clear_DrawLayers
(
bool
query
)
{
int
layer
;
if
(
GetGerberLayout
()
==
NULL
)
return
false
;
...
...
@@ -53,14 +51,7 @@ bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )
GetGerberLayout
()
->
m_Drawings
.
DeleteAll
();
for
(
layer
=
0
;
layer
<
GERBER_DRAWLAYERS_COUNT
;
++
layer
)
{
if
(
g_GERBER_List
[
layer
]
)
{
g_GERBER_List
[
layer
]
->
InitToolTable
();
g_GERBER_List
[
layer
]
->
ResetDefaultValues
();
}
}
g_GERBER_List
.
ClearList
();
GetGerberLayout
()
->
SetBoundingBox
(
EDA_RECT
()
);
...
...
@@ -98,11 +89,7 @@ void GERBVIEW_FRAME::Erase_Current_DrawLayer( bool query )
item
->
DeleteStructure
();
}
if
(
g_GERBER_List
[
layer
]
)
{
g_GERBER_List
[
layer
]
->
InitToolTable
();
g_GERBER_List
[
layer
]
->
ResetDefaultValues
();
}
g_GERBER_List
.
ClearImage
(
layer
);
GetScreen
()
->
SetModify
();
m_canvas
->
Refresh
();
...
...
gerbview/onleftclick.cpp
View file @
0cf91f46
...
...
@@ -56,7 +56,7 @@ void GERBVIEW_FRAME::OnLeftClick( wxDC* DC, const wxPoint& aPosition )
GetScreen
()
->
SetCurItem
(
DrawStruct
);
if
(
DrawStruct
==
NULL
)
{
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
getActiveLayer
()
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
getActiveLayer
()
)
;
if
(
gerber
)
gerber
->
DisplayImageInfo
(
);
}
...
...
gerbview/readgerb.cpp
View file @
0cf91f46
...
...
@@ -34,7 +34,7 @@
#include <html_messagebox.h>
#include <macros.h>
/* Read a gerber file, RS274D
or RS274X
format.
/* Read a gerber file, RS274D
, RS274X or RS274X2
format.
*/
bool
GERBVIEW_FRAME
::
Read_GERBER_File
(
const
wxString
&
GERBER_FullFileName
,
const
wxString
&
D_Code_FullFileName
)
...
...
@@ -49,13 +49,14 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName,
int
layer
;
// current layer used in GerbView
layer
=
getActiveLayer
();
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
layer
);
if
(
g
_GERBER_List
[
layer
]
==
NULL
)
if
(
g
erber
==
NULL
)
{
g_GERBER_List
[
layer
]
=
new
GERBER_IMAGE
(
this
,
layer
);
gerber
=
new
GERBER_IMAGE
(
this
,
layer
);
g_GERBER_List
.
AddGbrImage
(
gerber
,
layer
);
}
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
layer
];
ClearMessageList
(
);
/* Set the gerber scale: */
...
...
@@ -76,7 +77,7 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName,
if
(
path
!=
wxEmptyString
)
wxSetWorkingDirectory
(
path
);
SetLocaleTo_C_standard
()
;
LOCALE_IO
toggleIo
;
while
(
true
)
{
...
...
@@ -170,8 +171,8 @@ bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName,
}
}
}
fclose
(
gerber
->
m_Current_File
);
SetLocaleTo_Default
();
gerber
->
m_InUse
=
true
;
...
...
gerbview/rs274d.cpp
View file @
0cf91f46
...
...
@@ -35,6 +35,7 @@
#include <macros.h>
#include <class_gerber_draw_item.h>
#include <class_GERBER.h>
#include <class_X2_gerber_attributes.h>
#include <cmath>
...
...
@@ -43,7 +44,8 @@
* G01 linear interpolation (right trace)
* G02, G20, G21 Circular interpolation, meaning trig <0 (clockwise)
* G03, G30, G31 Circular interpolation, meaning trigo> 0 (counterclockwise)
* G04 = comment
* G04 = comment. Since Sept 2014, file attributes can be found here
* if the line starts by G04 #@!
* G06 parabolic interpolation
* G07 Cubic Interpolation
* G10 linear interpolation (scale x10)
...
...
@@ -473,9 +475,22 @@ bool GERBER_IMAGE::Execute_G_Command( char*& text, int G_command )
break
;
case
GC_COMMENT
:
// Skip comment
// Skip comment, but only if the line does not start by "G04 #@! TF"
// which is a metadata
if
(
strncmp
(
text
,
" #@! TF"
,
7
)
==
0
)
{
text
+=
7
;
X2_ATTRIBUTE
dummy
;
dummy
.
ParseAttribCmd
(
m_Current_File
,
NULL
,
0
,
text
);
if
(
dummy
.
IsFileFunction
()
)
{
delete
m_FileFunction
;
m_FileFunction
=
new
X2_ATTRIBUTE_FILEFUNCTION
(
dummy
);
}
}
while
(
*
text
&&
(
*
text
!=
'*'
)
)
text
++
;
text
++
;
break
;
case
GC_LINEAR_INTERPOL_10X
:
...
...
gerbview/rs274x.cpp
View file @
0cf91f46
...
...
@@ -33,6 +33,7 @@
#include <gerbview.h>
#include <class_GERBER.h>
#include <class_X2_gerber_attributes.h>
extern
int
ReadInt
(
char
*&
text
,
bool
aSkipSeparator
=
true
);
extern
double
ReadDouble
(
char
*&
text
,
bool
aSkipSeparator
=
true
);
...
...
@@ -78,6 +79,13 @@ enum RS274X_PARAMETERS {
AP_DEFINITION
=
CODE
(
'A'
,
'D'
),
AP_MACRO
=
CODE
(
'A'
,
'M'
),
// X2 extention attribute commands
// Mainly are found standard attributes and user attributes
// standard attributes commands are:
// TF (file attribute)
// TA (aperture attribute) and TD (delete aperture attribute)
FILE_ATTRIBUTE
=
CODE
(
'T'
,
'F'
),
// Layer specific parameters
// May be used singly or may be layer specfic
// theses parameters are at the beginning of the file or layer
...
...
@@ -307,7 +315,7 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
m_SwapAxis
=
true
;
break
;
case
MIRROR_IMAGE
:
// comman
f
%MIA0B0*%, %MIA0B1*%, %MIA1B0*%, %MIA1B1*%
case
MIRROR_IMAGE
:
// comman
d
%MIA0B0*%, %MIA0B1*%, %MIA1B0*%, %MIA1B1*%
m_MirrorA
=
m_MirrorB
=
0
;
while
(
*
text
&&
*
text
!=
'*'
)
{
...
...
@@ -341,6 +349,27 @@ bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
conv_scale
=
m_GerbMetric
?
IU_PER_MILS
/
25.4
:
IU_PER_MILS
;
break
;
case
FILE_ATTRIBUTE
:
// Command %TF ...
m_IsX2_file
=
true
;
{
X2_ATTRIBUTE
dummy
;
dummy
.
ParseAttribCmd
(
m_Current_File
,
buff
,
GERBER_BUFZ
,
text
);
if
(
dummy
.
IsFileFunction
()
)
{
delete
m_FileFunction
;
m_FileFunction
=
new
X2_ATTRIBUTE_FILEFUNCTION
(
dummy
);
}
else
if
(
dummy
.
IsFileMD5
()
)
{
m_MD5_value
=
dummy
.
GetPrm
(
1
);
}
else
if
(
dummy
.
IsFilePart
()
)
{
m_PartString
=
dummy
.
GetPrm
(
1
);
}
}
break
;
case
OFFSET
:
// command: OFAnnBnn (nn = float number) = layer Offset
m_Offset
.
x
=
m_Offset
.
y
=
0
;
while
(
*
text
!=
'*'
)
...
...
gerbview/select_layers_to_pcb.cpp
View file @
0cf91f46
...
...
@@ -121,7 +121,7 @@ void LAYERS_MAP_DIALOG::initDialog()
m_gerberActiveLayersCount
=
0
;
for
(
int
ii
=
0
;
ii
<
GERBER_DRAWLAYERS_COUNT
;
++
ii
)
{
if
(
g_GERBER_List
[
ii
]
==
NULL
)
if
(
g_GERBER_List
.
GetGbrImage
(
ii
)
==
NULL
)
break
;
if
(
(
pcb_layer_num
==
m_exportBoardCopperLayersCount
-
1
)
...
...
@@ -189,7 +189,7 @@ void LAYERS_MAP_DIALOG::initDialog()
wxRIGHT
|
wxLEFT
,
5
);
/* Add file name and extension without path. */
wxFileName
fn
(
g_GERBER_List
[
ii
]
->
m_FileName
);
wxFileName
fn
(
g_GERBER_List
.
GetGbrImage
(
ii
)
->
m_FileName
);
label
=
new
wxStaticText
(
this
,
wxID_STATIC
,
fn
.
GetFullName
(),
wxDefaultPosition
,
wxDefaultSize
);
flexColumnBoxSizer
->
Add
(
label
,
0
,
...
...
gerbview/toolbars_gerber.cpp
View file @
0cf91f46
...
...
@@ -294,7 +294,7 @@ void GERBVIEW_FRAME::OnUpdateShowLayerManager( wxUpdateUIEvent& aEvent )
void
GERBVIEW_FRAME
::
OnUpdateSelectDCode
(
wxUpdateUIEvent
&
aEvent
)
{
int
layer
=
getActiveLayer
();
GERBER_IMAGE
*
gerber
=
g_GERBER_List
[
layer
]
;
GERBER_IMAGE
*
gerber
=
g_GERBER_List
.
GetGbrImage
(
layer
)
;
int
selected
=
(
gerber
)
?
gerber
->
m_Selected_Tool
:
0
;
if
(
m_DCodeSelector
&&
m_DCodeSelector
->
GetSelectedDCodeId
()
!=
selected
)
...
...
pcb_calculator/dialogs/pcb_calculator_frame_base.cpp
View file @
0cf91f46
...
...
@@ -333,7 +333,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow
bSizeRight
=
new
wxBoxSizer
(
wxVERTICAL
);
wxStaticBoxSizer
*
sbSizerTW_Result
;
sbSizerTW_Result
=
new
wxStaticBoxSizer
(
new
wxStaticBox
(
m_panelTrackWidth
,
wxID_ANY
,
_
(
"Track
s C
aracteristics (External Layers):"
)
),
wxVERTICAL
);
sbSizerTW_Result
=
new
wxStaticBoxSizer
(
new
wxStaticBox
(
m_panelTrackWidth
,
wxID_ANY
,
_
(
"Track
Ch
aracteristics (External Layers):"
)
),
wxVERTICAL
);
wxFlexGridSizer
*
fgSizerTW_Results
;
fgSizerTW_Results
=
new
wxFlexGridSizer
(
5
,
3
,
0
,
0
);
...
...
@@ -409,7 +409,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow
bSizeRight
->
Add
(
sbSizerTW_Result
,
1
,
wxEXPAND
|
wxALL
,
5
);
wxStaticBoxSizer
*
sbSizerTW_Result1
;
sbSizerTW_Result1
=
new
wxStaticBoxSizer
(
new
wxStaticBox
(
m_panelTrackWidth
,
wxID_ANY
,
_
(
"Track
s C
aracteristics (Internal Layers):"
)
),
wxVERTICAL
);
sbSizerTW_Result1
=
new
wxStaticBoxSizer
(
new
wxStaticBox
(
m_panelTrackWidth
,
wxID_ANY
,
_
(
"Track
Ch
aracteristics (Internal Layers):"
)
),
wxVERTICAL
);
wxFlexGridSizer
*
fgSizerTW_Results1
;
fgSizerTW_Results1
=
new
wxFlexGridSizer
(
6
,
3
,
0
,
0
);
...
...
pcb_calculator/dialogs/pcb_calculator_frame_base.fbp
View file @
0cf91f46
...
...
@@ -47,7 +47,7 @@
<property name="size">670,489</property>
<property name="style">wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">KIWAY_PLAYER; kiway_player.h</property>
<property name="title">P
cb
Calculator</property>
<property name="title">P
CB
Calculator</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
...
...
@@ -4687,7 +4687,7 @@
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Track
s C
aracteristics (External Layers):</property>
<property name="label">Track
Ch
aracteristics (External Layers):</property>
<property name="minimum_size"></property>
<property name="name">sbSizerTW_Result</property>
<property name="orient">wxVERTICAL</property>
...
...
@@ -6009,7 +6009,7 @@
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Track
s C
aracteristics (Internal Layers):</property>
<property name="label">Track
Ch
aracteristics (Internal Layers):</property>
<property name="minimum_size"></property>
<property name="name">sbSizerTW_Result1</property>
<property name="orient">wxVERTICAL</property>
pcb_calculator/dialogs/pcb_calculator_frame_base.h
View file @
0cf91f46
...
...
@@ -293,7 +293,7 @@ class PCB_CALCULATOR_FRAME_BASE : public KIWAY_PLAYER
public
:
PCB_CALCULATOR_FRAME_BASE
(
wxWindow
*
parent
,
wxWindowID
id
=
wxID_ANY
,
const
wxString
&
title
=
_
(
"P
cb
Calculator"
),
const
wxPoint
&
pos
=
wxDefaultPosition
,
const
wxSize
&
size
=
wxSize
(
670
,
489
),
long
style
=
wxDEFAULT_FRAME_STYLE
|
wxRESIZE_BORDER
|
wxFULL_REPAINT_ON_RESIZE
|
wxTAB_TRAVERSAL
);
PCB_CALCULATOR_FRAME_BASE
(
wxWindow
*
parent
,
wxWindowID
id
=
wxID_ANY
,
const
wxString
&
title
=
_
(
"P
CB
Calculator"
),
const
wxPoint
&
pos
=
wxDefaultPosition
,
const
wxSize
&
size
=
wxSize
(
670
,
489
),
long
style
=
wxDEFAULT_FRAME_STYLE
|
wxRESIZE_BORDER
|
wxFULL_REPAINT_ON_RESIZE
|
wxTAB_TRAVERSAL
);
~
PCB_CALCULATOR_FRAME_BASE
();
...
...
pcb_calculator/regulators_funct.cpp
View file @
0cf91f46
...
...
@@ -223,12 +223,12 @@ void PCB_CALCULATOR_FRAME::OnDataFileSelection( wxCommandEvent& event )
wxString
fullfilename
=
GetDataFilename
();
wxString
wildcard
;
wildcard
.
Printf
(
_
(
"P
cb
Calculator data file (*.%s)|*.%s"
),
wildcard
.
Printf
(
_
(
"P
CB
Calculator data file (*.%s)|*.%s"
),
GetChars
(
DataFileNameExt
),
GetChars
(
DataFileNameExt
)
);
wxFileDialog
dlg
(
m_panelRegulators
,
_
(
"Select a P
cb
Calculator data file"
),
_
(
"Select a P
CB
Calculator data file"
),
wxEmptyString
,
fullfilename
,
wildcard
,
wxFD_OPEN
);
...
...
pcbnew/board_items_to_polygon_shape_transform.cpp
View file @
0cf91f46
...
...
@@ -27,8 +27,8 @@
* @brief function to convert shapes of items ( pads, tracks... ) to polygons
*/
/* Function to convert pad
s and tran
ck shapes to polygons
* Used to fill zones areas
/* Function to convert pad
and tra
ck shapes to polygons
* Used to fill zones areas
and in 3D viewer
*/
#include <vector>
...
...
@@ -520,22 +520,19 @@ void TRACK:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
*/
#include <clipper.hpp>
void
D_PAD
::
TransformShapeWithClearanceToPolygon
(
CPOLYGONS_LIST
&
aCornerBuffer
,
int
aClearanceValue
,
int
aCircleToSegmentsCount
,
double
aCorrectionFactor
)
const
{
wxPoint
corner_position
;
double
angle
;
double
angle
=
m_Orient
;
int
dx
=
(
m_Size
.
x
/
2
)
+
aClearanceValue
;
int
dy
=
(
m_Size
.
y
/
2
)
+
aClearanceValue
;
double
delta
=
3600.0
/
aCircleToSegmentsCount
;
// rot angle in 0.1 degree
wxPoint
PadShapePos
=
ShapePos
();
/* Note: for pad having a shape offset,
wxPoint
PadShapePos
=
ShapePos
();
/* Note: for pad having a shape offset,
* the pad position is NOT the shape position */
wxSize
psize
=
m_Size
;
/* pad size unsed in RECT and TRAPEZOIDAL pads
* trapezoidal pads are considered as rect
* pad shape having they boudary box size */
switch
(
GetShape
()
)
{
...
...
@@ -547,7 +544,6 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
case
PAD_OVAL
:
// An oval pad has the same shape as a segment with rounded ends
angle
=
m_Orient
;
{
int
width
;
wxPoint
shape_offset
;
...
...
@@ -573,77 +569,51 @@ void D_PAD:: TransformShapeWithClearanceToPolygon( CPOLYGONS_LIST& aCornerBuffer
break
;
case
PAD_TRAPEZOID
:
psize
.
x
+=
std
::
abs
(
m_DeltaSize
.
y
);
psize
.
y
+=
std
::
abs
(
m_DeltaSize
.
x
);
// fall through
case
PAD_RECT
:
// Easy implementation for rectangular cutouts with rounded corners
angle
=
m_Orient
;
// Corner rounding radius
int
rounding_radius
=
KiROUND
(
aClearanceValue
*
aCorrectionFactor
);
double
angle_pg
;
// Polygon increment angle
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
0
,
-
rounding_radius
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
// Start at half increment offset
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
// Rounding vector rotation
corner_position
-=
psize
/
2
;
// Rounding vector + Pad corner offset
RotatePoint
(
&
corner_position
,
angle
);
// Rotate according to module orientation
corner_position
+=
PadShapePos
;
// Shift origin to position
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
{
wxPoint
corners
[
4
];
BuildPadPolygon
(
corners
,
wxSize
(
0
,
0
),
angle
);
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
-
rounding_radius
,
0
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
-=
wxPoint
(
psize
.
x
/
2
,
-
psize
.
y
/
2
);
RotatePoint
(
&
corner_position
,
angle
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
// We are using ClipperLib to inflate the polygon shape, using
// arcs to connect moved segments.
ClipperLib
::
Path
outline
;
ClipperLib
::
Paths
shapeWithClearance
;
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
{
corner_position
=
wxPoint
(
0
,
rounding_radius
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
+=
psize
/
2
;
RotatePoint
(
&
corner_position
,
angle
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
for
(
int
i
=
0
;
i
<
aCircleToSegmentsCount
/
4
+
1
;
i
++
)
for
(
int
ii
=
0
;
ii
<
4
;
ii
++
)
outline
<<
ClipperLib
::
IntPoint
(
corners
[
ii
].
x
,
corners
[
ii
].
y
);
ClipperLib
::
ClipperOffset
offset_engine
;
// Prepare an offset (inflate) transform, with edges connected by arcs
offset_engine
.
AddPath
(
outline
,
ClipperLib
::
jtRound
,
ClipperLib
::
etClosedPolygon
);
// Clipper approximates arcs by segments
// It uses a value called ArcTolerance which is the max error between the arc
// and segments created to approximate this arc
// the number of segm per circle is:
// n = PI / acos(1 - arc_tolerance / (arc radius))
// the arc radius is aClearanceValue
// because arc_tolerance is << aClearanceValue and aClearanceValue >= 0
// n = PI / (arc_tolerance / aClearanceValue )
offset_engine
.
ArcTolerance
=
(
double
)
aClearanceValue
/
3.14
/
aCircleToSegmentsCount
;
double
rounding_radius
=
aClearanceValue
*
aCorrectionFactor
;
offset_engine
.
Execute
(
shapeWithClearance
,
rounding_radius
);
// get new outline (only one polygon is expected)
// For info, ClipperLib uses long long to handle integer coordinates
ClipperLib
::
Path
&
polygon
=
shapeWithClearance
[
0
];
for
(
unsigned
jj
=
0
;
jj
<
polygon
.
size
();
jj
++
)
{
corner_position
=
wxPoint
(
rounding_radius
,
0
);
RotatePoint
(
&
corner_position
,
(
1800.0
/
aCircleToSegmentsCount
)
);
angle_pg
=
i
*
delta
;
RotatePoint
(
&
corner_position
,
angle_pg
);
corner_position
-=
wxPoint
(
-
psize
.
x
/
2
,
psize
.
y
/
2
);
RotatePoint
(
&
corner_position
,
angle
);
corner_position
.
x
=
int
(
polygon
[
jj
].
X
);
corner_position
.
y
=
int
(
polygon
[
jj
].
Y
);
corner_position
+=
PadShapePos
;
CPolyPt
polypoint
(
corner_position
.
x
,
corner_position
.
y
);
aCornerBuffer
.
Append
(
polypoint
);
}
aCornerBuffer
.
CloseLastContour
();
}
break
;
}
}
...
...
@@ -1090,9 +1060,89 @@ void CreateThermalReliefPadPolygon( CPOLYGONS_LIST& aCornerBuffer,
aCornerBuffer
.
CloseLastContour
();
angle
=
AddAngles
(
angle
,
1800
);
}
}
break
;
case
PAD_TRAPEZOID
:
{
CPOLYGONS_LIST
cbuffer
;
// We need a length to build the stubs of the thermal reliefs
// the value is not very important. The pad bounding box gives a reasonable value
EDA_RECT
bbox
=
aPad
.
GetBoundingBox
();
int
stub_len
=
std
::
max
(
bbox
.
GetWidth
(),
bbox
.
GetHeight
()
);
aPad
.
TransformShapeWithClearanceToPolygon
(
cbuffer
,
aThermalGap
,
aCircleToSegmentsCount
,
aCorrectionFactor
);
// We are using ClipperLib to substract stubs to clearance area (antipad area).
ClipperLib
::
Path
antipad
;
// The full antipad area
ClipperLib
::
Path
stub
;
// A basic stub ( a rectangle)
ClipperLib
::
Paths
stubs
;
// the full stubs shape
ClipperLib
::
Paths
thermalShape
;
// the holes in copper zone
// cbuffer is expected to contain only one polygon, which is
// area of the pad + the thermal gap (the antipad)
for
(
unsigned
ii
=
0
;
ii
<
cbuffer
.
GetCornersCount
();
ii
++
)
antipad
<<
ClipperLib
::
IntPoint
(
cbuffer
.
GetPos
(
ii
).
x
,
cbuffer
.
GetPos
(
ii
).
y
);
// We now substract the stubs (connections to the copper zone)
ClipperLib
::
Clipper
clip_engine
;
// Prepare a clipping transform
clip_engine
.
AddPath
(
antipad
,
ClipperLib
::
ptSubject
,
true
);
// Create stubs and add them to clipper engine
wxPoint
stubBuffer
[
4
];
stubBuffer
[
0
].
x
=
stub_len
;
stubBuffer
[
0
].
y
=
copper_thickness
.
y
/
2
;
stubBuffer
[
1
]
=
stubBuffer
[
0
];
stubBuffer
[
1
].
y
=
-
copper_thickness
.
y
/
2
;
stubBuffer
[
2
]
=
stubBuffer
[
1
];
stubBuffer
[
2
].
x
=
-
stub_len
;
stubBuffer
[
3
]
=
stubBuffer
[
2
];
stubBuffer
[
3
].
y
=
copper_thickness
.
y
/
2
;
for
(
unsigned
ii
=
0
;
ii
<
DIM
(
stubBuffer
);
ii
++
)
{
wxPoint
cpos
=
stubBuffer
[
ii
];
RotatePoint
(
&
cpos
,
aPad
.
GetOrientation
()
);
cpos
+=
PadShapePos
;
stub
<<
ClipperLib
::
IntPoint
(
cpos
.
x
,
cpos
.
y
);
}
ClipperLib
::
Clipper
stubs_engine
;
stubs_engine
.
AddPath
(
stub
,
ClipperLib
::
ptSubject
,
true
);
stubBuffer
[
0
].
y
=
stub_len
;
stubBuffer
[
0
].
x
=
copper_thickness
.
x
/
2
;
stubBuffer
[
1
]
=
stubBuffer
[
0
];
stubBuffer
[
1
].
x
=
-
copper_thickness
.
x
/
2
;
stubBuffer
[
2
]
=
stubBuffer
[
1
];
stubBuffer
[
2
].
y
=
-
stub_len
;
stubBuffer
[
3
]
=
stubBuffer
[
2
];
stubBuffer
[
3
].
x
=
copper_thickness
.
x
/
2
;
stub
.
clear
();
for
(
unsigned
ii
=
0
;
ii
<
DIM
(
stubBuffer
);
ii
++
)
{
wxPoint
cpos
=
stubBuffer
[
ii
];
RotatePoint
(
&
cpos
,
aPad
.
GetOrientation
()
);
cpos
+=
PadShapePos
;
stub
<<
ClipperLib
::
IntPoint
(
cpos
.
x
,
cpos
.
y
);
}
stubs_engine
.
AddPath
(
stub
,
ClipperLib
::
ptClip
,
true
);
// Build the full stubs shape:
stubs_engine
.
Execute
(
ClipperLib
::
ctUnion
,
stubs
);
// remove stubs to antipad area (i.e. add copper stubs)
clip_engine
.
AddPath
(
stubs
[
0
],
ClipperLib
::
ptClip
,
true
);
clip_engine
.
Execute
(
ClipperLib
::
ctDifference
,
thermalShape
);
// put thermal shapes (holes) to list:
aCornerBuffer
.
ImportFrom
(
thermalShape
);
break
;
}
default
:
;
...
...
pcbnew/class_board.cpp
View file @
0cf91f46
...
...
@@ -1214,9 +1214,11 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
// the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
// zero is reserved for "no connection" and is not used.
// NULL is returned for non valid netcodes
NETINFO_ITEM
*
net
=
m_NetInfo
.
GetNetItem
(
aNetcode
);
return
net
;
if
(
aNetcode
==
NETINFO_LIST
::
UNCONNECTED
)
return
&
NETINFO_LIST
::
ORPHANED
;
else
return
m_NetInfo
.
GetNetItem
(
aNetcode
);
}
...
...
pcbnew/class_board_connected_item.cpp
View file @
0cf91f46
...
...
@@ -38,8 +38,6 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype
BOARD_ITEM
(
aParent
,
idtype
),
m_netinfo
(
&
NETINFO_LIST
::
ORPHANED
),
m_Subnet
(
0
),
m_ZoneSubnet
(
0
)
{
// The unconnected net is set only in case the item belongs to a BOARD
SetNetCode
(
NETINFO_LIST
::
UNCONNECTED
);
}
...
...
@@ -52,20 +50,15 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem )
void
BOARD_CONNECTED_ITEM
::
SetNetCode
(
int
aNetCode
)
{
assert
(
aNetCode
>=
0
);
BOARD
*
board
=
GetBoard
();
if
(
board
)
{
m_netinfo
=
board
->
FindNet
(
aNetCode
);
// The requested net does not exist, mark it as unconnected
if
(
m_netinfo
==
NULL
)
m_netinfo
=
board
->
FindNet
(
NETINFO_LIST
::
UNCONNECTED
);
}
else
{
// There is no board that contains list of nets, the item is orphaned
m_netinfo
=
&
NETINFO_LIST
::
ORPHANED
;
}
assert
(
m_netinfo
);
}
...
...
pcbnew/class_zone.h
View file @
0cf91f46
...
...
@@ -272,14 +272,15 @@ public:
* keep arc radius when approximated by segments
*/
void
TransformSolidAreasShapesToPolygonSet
(
CPOLYGONS_LIST
&
aCornerBuffer
,
int
aCircleToSegmentsCount
,
double
aCorrectionFactor
);
int
aCircleToSegmentsCount
,
double
aCorrectionFactor
);
/**
* Function BuildFilledSolidAreasPolygons
* Build the filled solid areas data from real outlines (stored in m_Poly)
* The solid areas can be more th
na
one on copper layers, and do not have holes
* The solid areas can be more th
an
one on copper layers, and do not have holes
( holes are linked by overlapping segments to the main outline)
* in order to have drawable (and plottable) filled polygons
* @return true if OK, false if the solid polygons cannot be built
* @param aPcb: the current board (can be NULL for non copper zones)
* @param aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
* if NULL (default:
...
...
@@ -287,13 +288,14 @@ public:
* - on copper layers, tracks and other items shapes of other nets are
* removed from solid areas
* if not null:
* Only the zone outline (with holes, if any) are stored in aCornerBuffer
* with holes linked. Therfore only one polygon is created
* @return true if OK, false if the solid areas cannot be calculated
* This function calls AddClearanceAreasPolygonsToPolysList()
* to add holes for pads and tracks and other items not in net.
*/
bool
BuildFilledSolidAreasPolygons
(
BOARD
*
aPcb
,
CPOLYGONS_LIST
*
aCornerBuffer
=
NULL
);
* Only the zone outline (with holes, if any) is stored in aOutlineBuffer
* with holes linked. Therefore only one polygon is created
*
* When aOutlineBuffer is not null, his function calls
* AddClearanceAreasPolygonsToPolysList() to add holes for pads and tracks
* and other items not in net.
*/
bool
BuildFilledSolidAreasPolygons
(
BOARD
*
aPcb
,
CPOLYGONS_LIST
*
aOutlineBuffer
=
NULL
);
/**
* Function CopyPolygonsFromKiPolygonListToFilledPolysList
...
...
pcbnew/router/pns_router.cpp
View file @
0cf91f46
...
...
@@ -127,15 +127,20 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
case
PAD_CONN
:
{
LSET
lmsk
=
aPad
->
GetLayerSet
();
bool
is_copper
=
false
;
for
(
int
i
=
0
;
i
<
MAX_CU_LAYERS
;
i
++
)
{
if
(
lmsk
[
i
]
)
{
is_copper
=
true
;
layers
=
PNS_LAYERSET
(
i
);
break
;
}
}
if
(
!
is_copper
)
return
NULL
;
}
break
;
...
...
@@ -693,7 +698,7 @@ void PNS_ROUTER::CommitRouting( PNS_NODE* aNode )
track
->
SetEnd
(
wxPoint
(
s
.
B
.
x
,
s
.
B
.
y
)
);
track
->
SetWidth
(
seg
->
Width
()
);
track
->
SetLayer
(
ToLAYER_ID
(
seg
->
Layers
().
Start
()
)
);
track
->
SetNetCode
(
seg
->
Net
()
);
track
->
SetNetCode
(
seg
->
Net
()
>
0
?
seg
->
Net
()
:
0
);
newBI
=
track
;
break
;
}
...
...
@@ -705,7 +710,7 @@ void PNS_ROUTER::CommitRouting( PNS_NODE* aNode )
via_board
->
SetPosition
(
wxPoint
(
via
->
Pos
().
x
,
via
->
Pos
().
y
)
);
via_board
->
SetWidth
(
via
->
Diameter
()
);
via_board
->
SetDrill
(
via
->
Drill
()
);
via_board
->
SetNetCode
(
via
->
Net
()
);
via_board
->
SetNetCode
(
via
->
Net
()
>
0
?
via
->
Net
()
:
0
);
via_board
->
SetViaType
(
via
->
ViaType
()
);
// MUST be before SetLayerPair()
via_board
->
SetLayerPair
(
ToLAYER_ID
(
via
->
Layers
().
Start
()
),
ToLAYER_ID
(
via
->
Layers
().
End
()
)
);
...
...
pcbnew/zone_filling_algorithm.cpp
View file @
0cf91f46
...
...
@@ -43,22 +43,19 @@
( holes are linked by overlapping segments to the main outline)
* aPcb: the current board (can be NULL for non copper zones)
* aCornerBuffer: A reference to a buffer to store polygon corners, or NULL
* if NULL:
* if
aCornerBuffer ==
NULL:
* - m_FilledPolysList is used to store solid areas polygons.
* - on copper layers, tracks and other items shapes of other nets are
* removed from solid areas
* if not null:
* Only the zone outline (with holes, if any) are stored in aCornerBuffer
* with holes linked. Therfore only one polygon is created
* with holes linked. Ther
e
fore only one polygon is created
* This function calls AddClearanceAreasPolygonsToPolysList()
* to add holes for pads and tracks and other items not in net.
*/
bool
ZONE_CONTAINER
::
BuildFilledSolidAreasPolygons
(
BOARD
*
aPcb
,
CPOLYGONS_LIST
*
a
Corner
Buffer
)
bool
ZONE_CONTAINER
::
BuildFilledSolidAreasPolygons
(
BOARD
*
aPcb
,
CPOLYGONS_LIST
*
a
Outline
Buffer
)
{
if
(
aCornerBuffer
==
NULL
)
m_FilledPolysList
.
RemoveAllContours
();
/* convert outlines + holes to outlines without holes (adding extra segments if necessary)
* m_Poly data is expected normalized, i.e. NormalizeAreaOutlines was used after building
* this zone
...
...
@@ -90,47 +87,33 @@ bool ZONE_CONTAINER::BuildFilledSolidAreasPolygons( BOARD* aPcb, CPOLYGONS_LIST*
break
;
}
if
(
aCornerBuffer
)
ConvertPolysListWithHolesToOnePolygon
(
m_smoothedPoly
->
m_CornersList
,
*
aCornerBuffer
);
else
ConvertPolysListWithHolesToOnePolygon
(
m_smoothedPoly
->
m_CornersList
,
m_FilledPolysList
);
if
(
aOutlineBuffer
)
aOutlineBuffer
->
Append
(
m_smoothedPoly
->
m_CornersList
);
/* For copper layers, we now must add holes in the Polygon list.
* holes are pads and tracks with their clearance area
* for non copper layers just recalculate the m_FilledPolysList
* with m_ZoneMinThickness taken in account
*/
if
(
!
aCornerBuffer
)
else
{
m_FilledPolysList
.
RemoveAllContours
();
if
(
IsOnCopperLayer
()
)
AddClearanceAreasPolygonsToPolysList
(
aPcb
);
else
{
// This KI_POLYGON_SET is the area(s) to fill, with m_ZoneMinThickness/2
KI_POLYGON_SET
polyset_zone_solid_areas
;
int
margin
=
m_ZoneMinThickness
/
2
;
/* First, creates the main polygon (i.e. the filled area using only one outline)
* to reserve a m_ZoneMinThickness/2 margin around the outlines and holes
* this margin is the room to redraw outlines with segments having a width set to
* m_ZoneMinThickness
* so m_ZoneMinThickness is the min thickness of the filled zones areas
* the polygon is stored in polyset_zone_solid_areas
*/
CopyPolygonsFromFilledPolysListToKiPolygonList
(
polyset_zone_solid_areas
);
polyset_zone_solid_areas
-=
margin
;
// put solid area in m_FilledPolysList:
m_FilledPolysList
.
RemoveAllContours
();
CopyPolygonsFromKiPolygonListToFilledPolysList
(
polyset_zone_solid_areas
);
m_smoothedPoly
->
m_CornersList
.
InflateOutline
(
m_FilledPolysList
,
margin
,
true
);
}
if
(
m_FillMode
)
// if fill mode uses segments, create them:
FillZoneAreasWithSegments
();
}
m_IsFilled
=
true
;
m_IsFilled
=
true
;
}
return
1
;
return
true
;
}
...
...
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
View file @
0cf91f46
...
...
@@ -138,6 +138,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
*/
s_Correction
=
1.0
/
cos
(
M_PI
/
s_CircleToSegmentsCount
);
// this is a place to store holes (i.e. tracks, pads ... areas as polygons outlines)
// static to avoid unnecessary memory allocation when filling many zones.
static
CPOLYGONS_LIST
cornerBufferPolysToSubstract
;
cornerBufferPolysToSubstract
.
RemoveAllContours
();
// This KI_POLYGON_SET is the area(s) to fill, with m_ZoneMinThickness/2
KI_POLYGON_SET
polyset_zone_solid_areas
;
int
margin
=
m_ZoneMinThickness
/
2
;
...
...
@@ -149,13 +154,35 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
* so m_ZoneMinThickness is the min thickness of the filled zones areas
* the main polygon is stored in polyset_zone_solid_areas
*/
CopyPolygonsFromFilledPolysListToKiPolygonList
(
polyset_zone_solid_areas
);
polyset_zone_solid_areas
-=
margin
;
#if 1
m_smoothedPoly
->
m_CornersList
.
ExportTo
(
polyset_zone_solid_areas
);
if
(
polyset_zone_solid_areas
.
size
()
==
0
)
return
;
// Extract holes (cutout areas) and add them to the hole buffer
KI_POLYGON_SET
outlineHoles
;
while
(
polyset_zone_solid_areas
.
size
()
>
1
)
{
outlineHoles
.
push_back
(
polyset_zone_solid_areas
.
back
()
);
polyset_zone_solid_areas
.
pop_back
();
}
// deflate main outline reserve room for thick outline
polyset_zone_solid_areas
-=
margin
;
// inflate outline holes
if
(
outlineHoles
.
size
()
)
outlineHoles
+=
margin
;
if
(
outlineHoles
.
size
()
)
cornerBufferPolysToSubstract
.
ImportFrom
(
outlineHoles
);
#else
CPOLYGONS_LIST
tmp
;
m_smoothedPoly
->
m_CornersList
.
InflateOutline
(
tmp
,
-
margin
,
true
);
tmp
.
ExportTo
(
polyset_zone_solid_areas
);
#endif
/* Calculates the clearance value that meet DRC requirements
* from m_ZoneClearance and clearance from the corresponding netclass
* We have a "local" clearance in zones because most of time
...
...
@@ -186,10 +213,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
*/
int
item_clearance
;
// static to avoid unnecessary memory allocation when filling many zones.
static
CPOLYGONS_LIST
cornerBufferPolysToSubstract
;
cornerBufferPolysToSubstract
.
RemoveAllContours
();
/* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers
* and this pad has a hole
* This dummy pad has the size and shape of the hole
...
...
@@ -249,11 +272,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
continue
;
}
if
(
(
GetPadConnection
(
pad
)
==
PAD_NOT_IN_ZONE
)
||
(
pad
->
GetShape
()
==
PAD_TRAPEZOID
)
)
// PAD_TRAPEZOID shapes are not in zones because they are used in microwave apps
// and i think it is good that shapes are not changed by thermal pads or others
if
(
GetPadConnection
(
pad
)
==
PAD_NOT_IN_ZONE
)
{
int
gap
=
zone_clearance
;
int
thermalGap
=
GetThermalReliefGap
(
pad
);
...
...
pcbnew/zones_convert_to_polygons_aux_functions.cpp
View file @
0cf91f46
...
...
@@ -51,12 +51,13 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
CPOLYGONS_LIST
&
aCornerBuffer
,
int
aClearanceValue
,
bool
aAddClearance
)
{
// Creates the zone outline
s
polygon (with linked holes if any)
CPOLYGONS_LIST
zoneOut
ines
;
BuildFilledSolidAreasPolygons
(
NULL
,
&
zoneOut
ines
);
// Creates the zone outline polygon (with linked holes if any)
CPOLYGONS_LIST
zoneOut
line
;
BuildFilledSolidAreasPolygons
(
NULL
,
&
zoneOut
line
);
// add clearance to outline
int
clearance
=
0
;
if
(
aAddClearance
)
{
clearance
=
GetClearance
();
...
...
@@ -64,51 +65,11 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
clearance
=
aClearanceValue
;
}
// Calculate the polygon with clearance
// holes are linked to the main outline, so only one polygon should be created.
KI_POLYGON_SET
polyset_zone_solid_areas
;
std
::
vector
<
KI_POLY_POINT
>
cornerslist
;
unsigned
ic
=
0
;
unsigned
corners_count
=
zoneOutines
.
GetCornersCount
();
while
(
ic
<
corners_count
)
{
cornerslist
.
clear
();
KI_POLYGON
poly
;
{
for
(
;
ic
<
corners_count
;
ic
++
)
{
CPolyPt
*
corner
=
&
zoneOutines
[
ic
];
cornerslist
.
push_back
(
KI_POLY_POINT
(
corner
->
x
,
corner
->
y
)
);
if
(
corner
->
end_contour
)
{
ic
++
;
break
;
}
}
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
polyset_zone_solid_areas
.
push_back
(
poly
);
}
}
polyset_zone_solid_areas
+=
clearance
;
// Put the resulting polygon in aCornerBuffer corners list
for
(
unsigned
ii
=
0
;
ii
<
polyset_zone_solid_areas
.
size
();
ii
++
)
{
KI_POLYGON
&
poly
=
polyset_zone_solid_areas
[
ii
];
CPolyPt
corner
(
0
,
0
,
false
);
for
(
unsigned
jj
=
0
;
jj
<
poly
.
size
();
jj
++
)
{
KI_POLY_POINT
point
=
*
(
poly
.
begin
()
+
jj
);
corner
.
x
=
point
.
x
();
corner
.
y
=
point
.
y
();
corner
.
end_contour
=
false
;
aCornerBuffer
.
Append
(
corner
);
}
aCornerBuffer
.
CloseLastContour
();
}
// holes are linked to the main outline, so only one polygon is created.
if
(
clearance
)
zoneOutline
.
InflateOutline
(
aCornerBuffer
,
clearance
,
true
);
else
ConvertPolysListWithHolesToOnePolygon
(
zoneOutline
,
aCornerBuffer
);
}
...
...
polygon/PolyLine.cpp
View file @
0cf91f46
...
...
@@ -1347,6 +1347,44 @@ void CPOLYGONS_LIST::ExportTo( KI_POLYGON_SET& aPolygons ) const
}
}
/*
* Copy all contours to a ClipperLib::Paths& aPolygons
* Each contour is copied into a ClipperLib::Path, and each ClipperLib::Path
* is append to aPolygons
*/
void
CPOLYGONS_LIST
::
ExportTo
(
ClipperLib
::
Paths
&
aPolygons
)
const
{
unsigned
corners_count
=
GetCornersCount
();
// Count the number of polygons in aCornersBuffer
int
polycount
=
0
;
for
(
unsigned
ii
=
0
;
ii
<
corners_count
;
ii
++
)
{
if
(
IsEndContour
(
ii
)
)
polycount
++
;
}
aPolygons
.
reserve
(
polycount
);
for
(
unsigned
icnt
=
0
;
icnt
<
corners_count
;
)
{
ClipperLib
::
Path
poly
;
unsigned
ii
;
for
(
ii
=
icnt
;
ii
<
corners_count
;
ii
++
)
{
poly
<<
ClipperLib
::
IntPoint
(
GetX
(
ii
),
GetY
(
ii
)
);
if
(
IsEndContour
(
ii
)
)
break
;
}
aPolygons
.
push_back
(
poly
);
icnt
=
ii
+
1
;
}
}
/* Imports all polygons found in a KI_POLYGON_SET in list
*/
...
...
@@ -1372,6 +1410,72 @@ void CPOLYGONS_LIST::ImportFrom( KI_POLYGON_SET& aPolygons )
}
/* Imports all polygons found in a ClipperLib::Paths in list
*/
void
CPOLYGONS_LIST
::
ImportFrom
(
ClipperLib
::
Paths
&
aPolygons
)
{
CPolyPt
corner
;
for
(
unsigned
ii
=
0
;
ii
<
aPolygons
.
size
();
ii
++
)
{
ClipperLib
::
Path
&
polygon
=
aPolygons
[
ii
];
for
(
unsigned
jj
=
0
;
jj
<
polygon
.
size
();
jj
++
)
{
corner
.
x
=
int
(
polygon
[
jj
].
X
);
corner
.
y
=
int
(
polygon
[
jj
].
Y
);
corner
.
end_contour
=
false
;
AddCorner
(
corner
);
}
CloseLastContour
();
}
}
/* Inflate the outline stored in m_cornersList.
* The first polygon is the external outline. It is inflated
* The other polygons are holes. they are deflated
* aResult = the Inflated outline
* aInflateValue = the Inflate value. when < 0, this is a deflate transform
* aLinkHoles = if true, aResult contains only one polygon,
* with holes linked by overlapping segments
*/
void
CPOLYGONS_LIST
::
InflateOutline
(
CPOLYGONS_LIST
&
aResult
,
int
aInflateValue
,
bool
aLinkHoles
)
{
KI_POLYGON_SET
polyset_outline
;
ExportTo
(
polyset_outline
);
// Extract holes (cutout areas) and add them to the hole buffer
KI_POLYGON_SET
outlineHoles
;
while
(
polyset_outline
.
size
()
>
1
)
{
outlineHoles
.
push_back
(
polyset_outline
.
back
()
);
polyset_outline
.
pop_back
();
}
// inflate main outline
if
(
polyset_outline
.
size
()
)
polyset_outline
+=
aInflateValue
;
// deflate outline holes
if
(
outlineHoles
.
size
()
)
outlineHoles
-=
aInflateValue
;
// Copy modified polygons
if
(
!
aLinkHoles
)
{
aResult
.
ImportFrom
(
polyset_outline
);
if
(
outlineHoles
.
size
()
)
aResult
.
ImportFrom
(
outlineHoles
);
}
else
{
polyset_outline
-=
outlineHoles
;
aResult
.
ImportFrom
(
polyset_outline
);
}
}
/**
* Function ConvertPolysListWithHolesToOnePolygon
...
...
@@ -1438,26 +1542,14 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith
polysholes
.
push_back
(
poly_tmp
);
}
}
mainpoly
-=
polysholes
;
// copy polygon with no holes to destination
// Because all holes are now linked to the main outline
// by overlapping segments, we should have only one polygon in list
wxASSERT
(
mainpoly
.
size
()
==
1
);
KI_POLYGON
&
poly_nohole
=
mainpoly
[
0
];
CPolyPt
corner
(
0
,
0
,
false
);
for
(
unsigned
jj
=
0
;
jj
<
poly_nohole
.
size
();
jj
++
)
{
KI_POLY_POINT
point
=
*
(
poly_nohole
.
begin
()
+
jj
);
corner
.
x
=
point
.
x
();
corner
.
y
=
point
.
y
();
corner
.
end_contour
=
false
;
aOnePolyList
.
AddCorner
(
corner
);
}
aOnePolyList
.
CloseLastContour
();
aOnePolyList
.
ImportFrom
(
mainpoly
);
}
/**
...
...
@@ -1553,3 +1645,22 @@ bool CPolyLine::IsPolygonSelfIntersecting()
return
false
;
}
/* converts the outline aOnePolyList (only one contour,
* holes are linked by overlapping segments) to
* to one main polygon and holes (polygons inside main polygon)
* aOnePolyList = a only one polygon ( holes are linked )
* aPolysListWithHoles = the list of corners of contours
* (main outline and holes)
*/
void
ConvertOnePolygonToPolysListWithHoles
(
const
CPOLYGONS_LIST
&
aOnePolyList
,
CPOLYGONS_LIST
&
aPolysListWithHoles
)
{
ClipperLib
::
Paths
initialPoly
;
ClipperLib
::
Paths
modifiedPoly
;
aOnePolyList
.
ExportTo
(
initialPoly
);
SimplifyPolygon
(
initialPoly
[
0
],
modifiedPoly
);
aPolysListWithHoles
.
ImportFrom
(
modifiedPoly
);
}
polygon/PolyLine.h
View file @
0cf91f46
...
...
@@ -54,6 +54,7 @@
#include <layers_id_colors_and_visibility.h> // for LAYER_NUM definition
#include <class_eda_rect.h> // for EDA_RECT definition
#include <polygons_defs.h>
#include <clipper.hpp>
class
CSegment
{
...
...
@@ -186,10 +187,30 @@ public:
m_cornersList
.
insert
(
m_cornersList
.
begin
()
+
aPosition
+
1
,
aItem
);
}
/**
* function AddCorner
* add a corner to the list
*/
void
AddCorner
(
const
CPolyPt
&
aCorner
)
{
m_cornersList
.
push_back
(
aCorner
);
}
/**
* function CloseLastContour
* Set the .end_contour member of the last corner in list to true
*/
void
CloseLastContour
()
{
if
(
m_cornersList
.
size
()
>
0
)
m_cornersList
.
back
().
end_contour
=
true
;
}
/**
* Function ExportTo
* Copy all contours to a KI_POLYGON_SET
* @param aPolygons = the KI_POLYGON_WITH_HOLES to populate
* Copy all contours to a KI_POLYGON_SET, each contour is exported
* to a KI_POLYGON
* @param aPolygons = the KI_POLYGON_SET to populate
*/
void
ExportTo
(
KI_POLYGON_SET
&
aPolygons
)
const
;
...
...
@@ -201,6 +222,14 @@ public:
*/
void
ExportTo
(
KI_POLYGON_WITH_HOLES
&
aPolygoneWithHole
)
const
;
/**
* Function ExportTo
* Copy all contours to a ClipperLib::Paths, each contour is exported
* to a ClipperLib::Path
* @param aPolygons = the ClipperLib::Paths to populate
*/
void
ExportTo
(
ClipperLib
::
Paths
&
aPolygons
)
const
;
/**
* Function ImportFrom
* Copy all polygons from a KI_POLYGON_SET in list
...
...
@@ -209,23 +238,23 @@ public:
void
ImportFrom
(
KI_POLYGON_SET
&
aPolygons
);
/**
* function AddCorner
* add a corner to the list
* Function ImportFrom
* Copy all polygons from a ClipperLib::Paths in list
* @param aPolygons = the ClipperLib::Paths to import
*/
void
AddCorner
(
const
CPolyPt
&
aCorner
)
{
m_cornersList
.
push_back
(
aCorner
);
}
void
ImportFrom
(
ClipperLib
::
Paths
&
aPolygons
);
/**
* function CloseLastContour
* Set the .end_contour member of the last corner in list to true
* Function InflateOutline
* Inflate the outline stored in m_cornersList.
* The first polygon is the external outline. It is inflated
* The other polygons are holes. they are deflated
* @param aResult = the Inflated outline
* @param aInflateValue = the Inflate value. when < 0, this is a deflate transform
* @param aLinkHoles = if true, aResult contains only one polygon,
* with holes linked by overlapping segments
*/
void
CloseLastContour
()
{
if
(
m_cornersList
.
size
()
>
0
)
m_cornersList
.
back
().
end_contour
=
true
;
}
void
InflateOutline
(
CPOLYGONS_LIST
&
aResult
,
int
aInflateValue
,
bool
aLinkHoles
);
};
class
CPolyLine
...
...
@@ -489,4 +518,17 @@ public:
void
ConvertPolysListWithHolesToOnePolygon
(
const
CPOLYGONS_LIST
&
aPolysListWithHoles
,
CPOLYGONS_LIST
&
aOnePolyList
);
/**
* Function ConvertOnePolygonToPolysListWithHoles
* converts the outline aOnePolyList (only one contour,
* holes are linked by overlapping segments) to
* to one main polygon and holes (polygons inside main polygon)
* @param aOnePolyList = a polygon with no holes
* @param aPolysListWithHoles = the list of corners of contours
* (main outline and holes)
*/
void
ConvertOnePolygonToPolysListWithHoles
(
const
CPOLYGONS_LIST
&
aOnePolyList
,
CPOLYGONS_LIST
&
aPolysListWithHoles
);
#endif // #ifndef POLYLINE_H
scripts/osx_build_wx.sh
View file @
0cf91f46
...
...
@@ -6,7 +6,8 @@
# $1 wxWidgets/wxPython source folder (relative to current dir)
# $2 Target bin folder
# $3 KiCad source folder (relative to current dir)
# $4 Make options (e.g., "-j4")
# $4 OSX target version (e.g., "10.8")
# $5 Extra make options (e.g., "-j4")
createPaths
()
{
echo
"*** Creating/wiping build and bin folder..."
...
...
@@ -59,10 +60,8 @@ wxWidgets_configure() {
--with-zlib
=
builtin
\
--with-expat
=
builtin
\
--without-liblzma
\
--with-macosx-version-min
=
10.5
\
--with-macosx-version-min
=
$3
\
--enable-universal-binary
=
i386,x86_64
\
CPPFLAGS
=
"-stdlib=libstdc++"
\
LDFLAGS
=
"-stdlib=libstdc++"
\
CC
=
clang
\
CXX
=
clang++
if
[
$?
-ne
0
]
;
...
...
@@ -119,16 +118,17 @@ wxPython_buildInst() {
# check parameters
if
[
"$#"
-lt
3
]
;
if
[
"$#"
-lt
4
]
;
then
echo
"OSX wxWidgets/wxPython build script"
echo
echo
"Usage:"
echo
" osx_build_wx.sh <src> <bin> <kicad> <
makeopts>
"
echo
" osx_build_wx.sh <src> <bin> <kicad> <
osxtarget> [makeopts]
"
echo
" <src> wxWidgets/wxPython source folder"
echo
" <bin> Destination folder"
echo
" <kicad> KiCad folder"
echo
" <makeopts> Optional: make options for building wxWidgets (e.g., -j4)"
echo
" <osxtarget> OSX target (e.g., 10.7)"
echo
" [makeopts] Optional: make options for building wxWidgets (e.g., -j4)"
exit
1
fi
...
...
@@ -142,8 +142,8 @@ doPatch "$1" "$3/patches/wxwidgets-3.0.0_macosx_bug_15908.patch"
doPatch
"
$1
"
"
$3
/patches/wxwidgets-3.0.0_macosx_soname.patch"
# configure and build wxWidgets
wxWidgets_configure
"
$1
"
"
$2
"
wxWidgets_buildInst
"
$
4
"
wxWidgets_configure
"
$1
"
"
$2
"
"
$4
"
wxWidgets_buildInst
"
$
5
"
# check if source is wxPython
if
[
-d
$1
/wxPython
]
;
...
...
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