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
1c9433fb
Commit
1c9433fb
authored
Jul 29, 2012
by
Miguel Angel Ajo
Browse files
Options
Browse Files
Download
Plain Diff
merged divertion
parents
a8e4f8b0
99b90d2f
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1058 additions
and
947 deletions
+1058
-947
3d_draw.cpp
3d-viewer/3d_draw.cpp
+2
-2
lib_arc.cpp
eeschema/lib_arc.cpp
+6
-6
lib_arc.h
eeschema/lib_arc.h
+5
-5
Thumbs.db
pcb_calculator/bitmaps/Thumbs.db
+0
-0
solve.cpp
pcbnew/autorouter/solve.cpp
+2
-2
board_items_to_polygon_shape_transform.cpp
pcbnew/board_items_to_polygon_shape_transform.cpp
+6
-6
class_board.cpp
pcbnew/class_board.cpp
+2
-2
class_track.cpp
pcbnew/class_track.cpp
+1
-1
class_zone.cpp
pcbnew/class_zone.cpp
+25
-25
class_zone.h
pcbnew/class_zone.h
+1
-1
clean.cpp
pcbnew/clean.cpp
+18
-17
editrack.cpp
pcbnew/editrack.cpp
+2
-2
kicad_plugin.cpp
pcbnew/kicad_plugin.cpp
+1
-1
legacy_plugin.cpp
pcbnew/legacy_plugin.cpp
+3
-3
move_or_drag_track.cpp
pcbnew/move_or_drag_track.cpp
+4
-4
pcbnew.h
pcbnew/pcbnew.h
+2
-2
polygons_defs.h
pcbnew/polygons_defs.h
+0
-21
specctra_export.cpp
pcbnew/specctra_export.cpp
+14
-14
zone_filling_algorithm.cpp
pcbnew/zone_filling_algorithm.cpp
+8
-35
zones_convert_brd_items_to_polygons_with_Boost.cpp
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
+40
-47
zones_functions_for_undo_redo.cpp
pcbnew/zones_functions_for_undo_redo.cpp
+1
-1
zones_test_and_combine_areas.cpp
pcbnew/zones_test_and_combine_areas.cpp
+53
-111
PolyLine.cpp
polygon/PolyLine.cpp
+677
-501
PolyLine.h
polygon/PolyLine.h
+119
-138
polygons_defs.h
polygon/polygons_defs.h
+66
-0
No files found.
3d-viewer/3d_draw.cpp
View file @
1c9433fb
...
...
@@ -305,7 +305,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
{
CPolyPt
*
endcorner
=
&
polysList
[
ic
];
if
(
begincorner
->
utility
==
0
)
if
(
begincorner
->
m_
utility
==
0
)
{
// Draw only basic outlines, not extra segments
dummysegment
.
m_Start
.
x
=
begincorner
->
x
;
...
...
@@ -318,7 +318,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List()
if
(
(
endcorner
->
end_contour
)
||
(
ic
==
imax
)
)
{
// the last corner of a filled area is found: draw it
if
(
endcorner
->
utility
==
0
)
if
(
endcorner
->
m_
utility
==
0
)
{
// Draw only basic outlines, not extra segments
dummysegment
.
m_Start
.
x
=
endcorner
->
x
;
...
...
eeschema/lib_arc.cpp
View file @
1c9433fb
...
...
@@ -561,15 +561,15 @@ void LIB_ARC::BeginEdit( int aEditMode, const wxPoint aPosition )
// Drag either the start, end point or the outline
if
(
HitTestPoints
(
m_ArcStart
,
aPosition
,
MINIMUM_SELECTION_DISTANCE
)
)
{
m_editSelectPoint
=
START
;
m_editSelectPoint
=
ARC_STATUS_
START
;
}
else
if
(
HitTestPoints
(
m_ArcEnd
,
aPosition
,
MINIMUM_SELECTION_DISTANCE
)
)
{
m_editSelectPoint
=
END
;
m_editSelectPoint
=
ARC_STATUS_
END
;
}
else
{
m_editSelectPoint
=
OUTLINE
;
m_editSelectPoint
=
ARC_STATUS_
OUTLINE
;
}
m_editState
=
0
;
...
...
@@ -619,12 +619,12 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition )
wxPoint
newCenterPoint
,
startPos
,
endPos
;
// Choose the point of the arc to be adjusted
if
(
m_editSelectPoint
==
START
)
if
(
m_editSelectPoint
==
ARC_STATUS_
START
)
{
startPos
=
aPosition
;
endPos
=
m_ArcEnd
;
}
else
if
(
m_editSelectPoint
==
END
)
else
if
(
m_editSelectPoint
==
ARC_STATUS_
END
)
{
endPos
=
aPosition
;
startPos
=
m_ArcStart
;
...
...
@@ -658,7 +658,7 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition )
newCenterPoint
=
m_Pos
;
}
if
(
m_editSelectPoint
==
START
||
m_editSelectPoint
==
END
)
if
(
m_editSelectPoint
==
ARC_STATUS_START
||
m_editSelectPoint
==
ARC_STATUS_
END
)
{
// Compute the new center point when the start/end points are modified
wxPoint
middlePoint
=
wxPoint
(
(
startPos
.
x
+
endPos
.
x
)
/
2
,
...
...
eeschema/lib_arc.h
View file @
1c9433fb
...
...
@@ -37,15 +37,15 @@ class TRANSFORM;
class
LIB_ARC
:
public
LIB_ITEM
{
enum
SELECT_T
enum
SELECT_T
// When creating an arc: status of arc
{
START
,
END
,
OUTLINE
,
ARC_STATUS_
START
,
ARC_STATUS_
END
,
ARC_STATUS_
OUTLINE
,
};
int
m_Radius
;
int
m_t1
;
/
* First radius angle of the arc in 0.1 degrees. */
int
m_t1
;
/
/ First radius angle of the arc in 0.1 degrees.
int
m_t2
;
/* Second radius angle of the arc in 0.1 degrees. */
wxPoint
m_ArcStart
;
wxPoint
m_ArcEnd
;
/* Arc end position. */
...
...
pcb_calculator/bitmaps/Thumbs.db
deleted
100644 → 0
View file @
a8e4f8b0
File deleted
pcbnew/autorouter/solve.cpp
View file @
1c9433fb
...
...
@@ -1302,12 +1302,12 @@ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC )
g_CurrentTrackList
.
PushBack
(
newTrack
);
}
g_FirstTrackSegment
->
start
=
pcbframe
->
GetBoard
()
->
GetPad
(
g_FirstTrackSegment
,
START
);
g_FirstTrackSegment
->
start
=
pcbframe
->
GetBoard
()
->
GetPad
(
g_FirstTrackSegment
,
FLG_
START
);
if
(
g_FirstTrackSegment
->
start
)
g_FirstTrackSegment
->
SetState
(
BEGIN_ONPAD
,
ON
);
g_CurrentTrackSegment
->
end
=
pcbframe
->
GetBoard
()
->
GetPad
(
g_CurrentTrackSegment
,
END
);
g_CurrentTrackSegment
->
end
=
pcbframe
->
GetBoard
()
->
GetPad
(
g_CurrentTrackSegment
,
FLG_
END
);
if
(
g_CurrentTrackSegment
->
end
)
g_CurrentTrackSegment
->
SetState
(
END_ONPAD
,
ON
);
...
...
pcbnew/board_items_to_polygon_shape_transform.cpp
View file @
1c9433fb
...
...
@@ -167,19 +167,19 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>
// Calculate the polygon with clearance and holes
// holes are linked to the main outline, so only one polygon should be created.
K
PolygonSet
polyset_zone_solid_areas
;
std
::
vector
<
K
PolyPoint
>
cornerslist
;
K
I_POLYGON_SET
polyset_zone_solid_areas
;
std
::
vector
<
K
I_POLY_POINT
>
cornerslist
;
unsigned
ic
=
0
;
unsigned
corners_count
=
zoneOutines
.
size
();
while
(
ic
<
corners_count
)
{
cornerslist
.
clear
();
K
Polygon
poly
;
K
I_POLYGON
poly
;
{
for
(
;
ic
<
corners_count
;
ic
++
)
{
CPolyPt
*
corner
=
&
zoneOutines
[
ic
];
cornerslist
.
push_back
(
K
PolyPoint
(
corner
->
x
,
corner
->
y
)
);
cornerslist
.
push_back
(
K
I_POLY_POINT
(
corner
->
x
,
corner
->
y
)
);
if
(
corner
->
end_contour
)
{
ic
++
;
...
...
@@ -197,12 +197,12 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>
// Put the resultng polygon in buffer
for
(
unsigned
ii
=
0
;
ii
<
polyset_zone_solid_areas
.
size
();
ii
++
)
{
K
Polygon
&
poly
=
polyset_zone_solid_areas
[
ii
];
K
I_POLYGON
&
poly
=
polyset_zone_solid_areas
[
ii
];
CPolyPt
corner
(
0
,
0
,
false
);
for
(
unsigned
jj
=
0
;
jj
<
poly
.
size
();
jj
++
)
{
K
PolyPoint
point
=
*
(
poly
.
begin
()
+
jj
);
K
I_POLY_POINT
point
=
*
(
poly
.
begin
()
+
jj
);
corner
.
x
=
point
.
x
();
corner
.
y
=
point
.
y
();
corner
.
end_contour
=
false
;
...
...
pcbnew/class_board.cpp
View file @
1c9433fb
...
...
@@ -1681,7 +1681,7 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint )
int
aLayerMask
=
GetLayerMask
(
aTrace
->
GetLayer
()
);
if
(
aEndPoint
==
START
)
if
(
aEndPoint
==
FLG_
START
)
{
aPosition
=
aTrace
->
m_Start
;
}
...
...
@@ -2271,7 +2271,7 @@ TRACK* BOARD::CreateLockPoint( wxPoint& aPosition, TRACK* aSegment, PICKED_ITEMS
aSegment
->
end
=
newTrack
;
aSegment
->
SetState
(
END_ONPAD
,
OFF
);
D_PAD
*
pad
=
GetPad
(
newTrack
,
START
);
D_PAD
*
pad
=
GetPad
(
newTrack
,
FLG_
START
);
if
(
pad
)
{
...
...
pcbnew/class_track.cpp
View file @
1c9433fb
...
...
@@ -1282,7 +1282,7 @@ TRACK* TRACK::GetTrace( TRACK* aStartTrace, TRACK* aEndTrace, int aEndPoint )
int
ii
;
int
max_dist
;
if
(
aEndPoint
==
START
)
if
(
aEndPoint
==
FLG_
START
)
position
=
m_Start
;
else
position
=
m_End
;
...
...
pcbnew/class_zone.cpp
View file @
1c9433fb
...
...
@@ -210,7 +210,7 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const
{
seg_start
=
GetCornerPosition
(
ic
)
+
offset
;
if
(
m_Poly
->
corner
[
ic
].
end_contour
==
false
&&
ic
<
GetNumCorners
()
-
1
)
if
(
m_Poly
->
m_CornersList
[
ic
].
end_contour
==
false
&&
ic
<
GetNumCorners
()
-
1
)
{
seg_end
=
GetCornerPosition
(
ic
+
1
)
+
offset
;
}
...
...
@@ -306,7 +306,7 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
CornersBuffer
.
push_back
(
coord
);
CornersTypeBuffer
.
push_back
(
(
char
)
corner
->
utility
);
CornersTypeBuffer
.
push_back
(
(
char
)
corner
->
m_
utility
);
if
(
(
corner
->
end_contour
)
||
(
ic
==
imax
)
)
// the last corner of a filled area is found: draw it
{
...
...
@@ -432,13 +432,13 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in
int
yi
=
GetCornerPosition
(
ic
).
y
;
int
xf
,
yf
;
if
(
m_Poly
->
corner
[
ic
].
end_contour
==
false
&&
ic
<
icmax
)
if
(
m_Poly
->
m_CornersList
[
ic
].
end_contour
==
false
&&
ic
<
icmax
)
{
is_close_segment
=
false
;
xf
=
GetCornerPosition
(
ic
+
1
).
x
;
yf
=
GetCornerPosition
(
ic
+
1
).
y
;
if
(
(
m_Poly
->
corner
[
ic
+
1
].
end_contour
)
||
(
ic
==
icmax
-
1
)
)
if
(
(
m_Poly
->
m_CornersList
[
ic
+
1
].
end_contour
)
||
(
ic
==
icmax
-
1
)
)
current_gr_mode
=
GR_XOR
;
else
current_gr_mode
=
draw_mode
;
...
...
@@ -507,12 +507,12 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
int
min_dist
=
MIN_DIST_IN_MILS
*
IU_PER_MILS
;
wxPoint
delta
;
unsigned
lim
=
m_Poly
->
corner
.
size
();
unsigned
lim
=
m_Poly
->
m_CornersList
.
size
();
for
(
unsigned
item_pos
=
0
;
item_pos
<
lim
;
item_pos
++
)
{
delta
.
x
=
refPos
.
x
-
m_Poly
->
corner
[
item_pos
].
x
;
delta
.
y
=
refPos
.
y
-
m_Poly
->
corner
[
item_pos
].
y
;
delta
.
x
=
refPos
.
x
-
m_Poly
->
m_CornersList
[
item_pos
].
x
;
delta
.
y
=
refPos
.
y
-
m_Poly
->
m_CornersList
[
item_pos
].
y
;
// Calculate a distance:
int
dist
=
MAX
(
abs
(
delta
.
x
),
abs
(
delta
.
y
)
);
...
...
@@ -530,7 +530,7 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
bool
ZONE_CONTAINER
::
HitTestForEdge
(
const
wxPoint
&
refPos
)
{
unsigned
lim
=
m_Poly
->
corner
.
size
();
unsigned
lim
=
m_Poly
->
m_CornersList
.
size
();
m_CornerSelection
=
-
1
;
// Set to not found
...
...
@@ -547,7 +547,7 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
* the last segment of the current outline starts at current corner, and ends
* at the first corner of the outline
*/
if
(
m_Poly
->
corner
[
item_pos
].
end_contour
||
end_segm
>=
lim
)
if
(
m_Poly
->
m_CornersList
[
item_pos
].
end_contour
||
end_segm
>=
lim
)
{
unsigned
tmp
=
first_corner_pos
;
first_corner_pos
=
end_segm
;
// first_corner_pos is now the beginning of the next outline
...
...
@@ -557,10 +557,10 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
/* test the dist between segment and ref point */
int
dist
=
(
int
)
GetPointToLineSegmentDistance
(
refPos
.
x
,
refPos
.
y
,
m_Poly
->
corner
[
item_pos
].
x
,
m_Poly
->
corner
[
item_pos
].
y
,
m_Poly
->
corner
[
end_segm
].
x
,
m_Poly
->
corner
[
end_segm
].
y
);
m_Poly
->
m_CornersList
[
item_pos
].
x
,
m_Poly
->
m_CornersList
[
item_pos
].
y
,
m_Poly
->
m_CornersList
[
end_segm
].
x
,
m_Poly
->
m_CornersList
[
end_segm
].
y
);
if
(
dist
<
min_dist
)
{
...
...
@@ -703,7 +703,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame )
msg
=
board
->
GetLayerName
(
m_Layer
);
frame
->
AppendMsgPanel
(
_
(
"Layer"
),
msg
,
BROWN
);
msg
.
Printf
(
wxT
(
"%d"
),
(
int
)
m_Poly
->
corner
.
size
()
);
msg
.
Printf
(
wxT
(
"%d"
),
(
int
)
m_Poly
->
m_CornersList
.
size
()
);
frame
->
AppendMsgPanel
(
_
(
"Corners"
),
msg
,
BLUE
);
if
(
m_FillMode
)
...
...
@@ -730,7 +730,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame )
void
ZONE_CONTAINER
::
Move
(
const
wxPoint
&
offset
)
{
/* move outlines */
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
corner
.
size
();
ii
++
)
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
m_CornersList
.
size
();
ii
++
)
{
SetCornerPosition
(
ii
,
GetCornerPosition
(
ii
)
+
offset
);
}
...
...
@@ -761,7 +761,7 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset )
SetCornerPosition
(
ii
,
GetCornerPosition
(
ii
)
+
offset
);
// Move the end point of the selected edge:
if
(
m_Poly
->
corner
[
ii
].
end_contour
||
ii
==
GetNumCorners
()
-
1
)
if
(
m_Poly
->
m_CornersList
[
ii
].
end_contour
||
ii
==
GetNumCorners
()
-
1
)
{
int
icont
=
m_Poly
->
GetContour
(
ii
);
ii
=
m_Poly
->
GetContourStart
(
icont
);
...
...
@@ -781,13 +781,13 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
{
wxPoint
pos
;
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
corner
.
size
();
ii
++
)
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
m_CornersList
.
size
();
ii
++
)
{
pos
.
x
=
m_Poly
->
corner
[
ii
].
x
;
pos
.
y
=
m_Poly
->
corner
[
ii
].
y
;
pos
.
x
=
m_Poly
->
m_CornersList
[
ii
].
x
;
pos
.
y
=
m_Poly
->
m_CornersList
[
ii
].
y
;
RotatePoint
(
&
pos
,
centre
,
angle
);
m_Poly
->
corner
[
ii
].
x
=
pos
.
x
;
m_Poly
->
corner
[
ii
].
y
=
pos
.
y
;
m_Poly
->
m_CornersList
[
ii
].
x
=
pos
.
x
;
m_Poly
->
m_CornersList
[
ii
].
y
=
pos
.
y
;
}
m_Poly
->
Hatch
();
...
...
@@ -820,11 +820,11 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
void
ZONE_CONTAINER
::
Mirror
(
const
wxPoint
&
mirror_ref
)
{
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
corner
.
size
();
ii
++
)
for
(
unsigned
ii
=
0
;
ii
<
m_Poly
->
m_CornersList
.
size
();
ii
++
)
{
m_Poly
->
corner
[
ii
].
y
-=
mirror_ref
.
y
;
NEGATE
(
m_Poly
->
corner
[
ii
].
y
);
m_Poly
->
corner
[
ii
].
y
+=
mirror_ref
.
y
;
m_Poly
->
m_CornersList
[
ii
].
y
-=
mirror_ref
.
y
;
NEGATE
(
m_Poly
->
m_CornersList
[
ii
].
y
);
m_Poly
->
m_CornersList
[
ii
].
y
+=
mirror_ref
.
y
;
}
m_Poly
->
Hatch
();
...
...
pcbnew/class_zone.h
View file @
1c9433fb
...
...
@@ -613,7 +613,7 @@ private:
/* set of filled polygons used to draw a zone as a filled area.
* from outlines (m_Poly) but unlike m_Poly these filled polygons have no hole
* (they are
*
all in one piece) In very simple cases m_FilledPolysList is same
* (they are all in one piece) In very simple cases m_FilledPolysList is same
* as m_Poly. In less simple cases (when m_Poly has holes) m_FilledPolysList is
* a polygon equivalent to m_Poly, without holes but with extra outline segment
* connecting "holes" with external main outline. In complex cases an outline
...
...
pcbnew/clean.cpp
View file @
1c9433fb
...
...
@@ -272,7 +272,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
if
(
(
type_end
&
START_ON_PAD
)
==
0
)
{
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
START
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
);
if
(
other
==
NULL
)
// Test a connection to zones
{
...
...
@@ -306,7 +306,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
segment
->
SetState
(
BUSY
,
ON
);
SEGVIA
*
via
=
(
SEGVIA
*
)
other
;
other
=
via
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
START
);
other
=
via
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
);
if
(
other
==
NULL
)
{
...
...
@@ -327,7 +327,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
// if not connected to a pad, test if segment's END is connected to another track
if
(
(
type_end
&
END_ON_PAD
)
==
0
)
{
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
END
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
);
if
(
other
==
NULL
)
// Test a connection to zones
{
...
...
@@ -362,7 +362,7 @@ static void DeleteUnconnectedTracks( PCB_EDIT_FRAME* aFrame )
segment
->
SetState
(
BUSY
,
ON
);
SEGVIA
*
via
=
(
SEGVIA
*
)
other
;
other
=
via
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
END
);
other
=
via
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
);
if
(
other
==
NULL
)
{
...
...
@@ -486,7 +486,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// search for a possible point that connects on the START point of the segment
for
(
segStart
=
segment
->
Next
();
;
)
{
segStart
=
segment
->
GetTrace
(
segStart
,
NULL
,
START
);
segStart
=
segment
->
GetTrace
(
segStart
,
NULL
,
FLG_
START
);
if
(
segStart
)
{
...
...
@@ -500,7 +500,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// We must have only one segment connected
segStart
->
SetState
(
BUSY
,
ON
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
START
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
);
segStart
->
SetState
(
BUSY
,
OFF
);
if
(
other
==
NULL
)
...
...
@@ -514,7 +514,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
if
(
flag
)
// We have the starting point of the segment is connected to an other segment
{
segDelete
=
MergeColinearSegmentIfPossible
(
aFrame
->
GetBoard
(),
segment
,
segStart
,
START
);
FLG_
START
);
if
(
segDelete
)
{
...
...
@@ -526,7 +526,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// search for a possible point that connects on the END point of the segment:
for
(
segEnd
=
segment
->
Next
();
;
)
{
segEnd
=
segment
->
GetTrace
(
segEnd
,
NULL
,
END
);
segEnd
=
segment
->
GetTrace
(
segEnd
,
NULL
,
FLG_
END
);
if
(
segEnd
)
{
...
...
@@ -538,7 +538,7 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
// We must have only one segment connected
segEnd
->
SetState
(
BUSY
,
ON
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
END
);
other
=
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
);
segEnd
->
SetState
(
BUSY
,
OFF
);
if
(
other
==
NULL
)
...
...
@@ -554,7 +554,8 @@ static void clean_segments( PCB_EDIT_FRAME* aFrame )
if
(
flag
&
2
)
// We have the ending point of the segment is connected to an other segment
{
segDelete
=
MergeColinearSegmentIfPossible
(
aFrame
->
GetBoard
(),
segment
,
segEnd
,
END
);
segDelete
=
MergeColinearSegmentIfPossible
(
aFrame
->
GetBoard
(),
segment
,
segEnd
,
FLG_END
);
if
(
segDelete
)
{
...
...
@@ -643,7 +644,7 @@ TRACK* MergeColinearSegmentIfPossible( BOARD* aPcb, TRACK* aTrackRef, TRACK* aCa
* (this function) is called when there is only 2 connected segments,
*and if this point is not on a pad, it can be removed and the 2 segments will be merged
*/
if
(
aEndType
==
START
)
if
(
aEndType
==
FLG_
START
)
{
// We must not have a pad, which is a always terminal point for a track
if
(
aPcb
->
GetPadFast
(
aTrackRef
->
m_Start
,
aTrackRef
->
ReturnMaskLayer
()
)
)
...
...
@@ -712,7 +713,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
}
else
{
other
=
segment
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
START
);
other
=
segment
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
);
if
(
other
)
net_code_s
=
other
->
GetNet
();
...
...
@@ -730,7 +731,7 @@ bool PCB_EDIT_FRAME::RemoveMisConnectedTracks()
}
else
{
other
=
segment
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
END
);
other
=
segment
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
);
if
(
other
)
net_code_e
=
other
->
GetNet
();
...
...
@@ -871,14 +872,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame )
if
(
aFrame
->
GetCanvas
()
->
GetAbortRequest
()
)
return
;
pad
=
aFrame
->
GetBoard
()
->
GetPad
(
segment
,
START
);
pad
=
aFrame
->
GetBoard
()
->
GetPad
(
segment
,
FLG_
START
);
if
(
pad
)
{
// test if the track start point is not exactly starting on the pad
if
(
segment
->
m_Start
!=
pad
->
GetPosition
()
)
{
if
(
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
START
)
==
NULL
)
if
(
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
)
==
NULL
)
{
TRACK
*
newTrack
=
(
TRACK
*
)
segment
->
Clone
();
...
...
@@ -893,14 +894,14 @@ void ConnectDanglingEndToPad( PCB_EDIT_FRAME* aFrame )
}
}
pad
=
aFrame
->
GetBoard
()
->
GetPad
(
segment
,
END
);
pad
=
aFrame
->
GetBoard
()
->
GetPad
(
segment
,
FLG_
END
);
if
(
pad
)
{
// test if the track end point is not exactly on the pad
if
(
segment
->
m_End
!=
pad
->
GetPosition
()
)
{
if
(
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
END
)
==
NULL
)
if
(
segment
->
GetTrace
(
aFrame
->
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
)
==
NULL
)
{
TRACK
*
newTrack
=
(
TRACK
*
)
segment
->
Clone
();
...
...
pcbnew/editrack.cpp
View file @
1c9433fb
...
...
@@ -263,7 +263,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
newTrack
->
SetState
(
BEGIN_ONPAD
|
END_ONPAD
,
OFF
);
D_PAD
*
pad
=
GetBoard
()
->
GetPad
(
previousTrack
,
END
);
D_PAD
*
pad
=
GetBoard
()
->
GetPad
(
previousTrack
,
FLG_
END
);
if
(
pad
)
{
...
...
@@ -1042,7 +1042,7 @@ void DeleteNullTrackSegments( BOARD* pcb, DLIST<TRACK>& aTrackList )
while
(
track
!=
NULL
)
{
TRACK
*
next_track
=
track
->
Next
();
LockPoint
=
pcb
->
GetPad
(
track
,
END
);
LockPoint
=
pcb
->
GetPad
(
track
,
FLG_
END
);
if
(
LockPoint
)
{
...
...
pcbnew/kicad_plugin.cpp
View file @
1c9433fb
...
...
@@ -1059,7 +1059,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
m_out
->
Print
(
0
,
")
\n
"
);
const
std
::
vector
<
CPolyPt
>&
cv
=
aZone
->
m_Poly
->
corner
;
const
std
::
vector
<
CPolyPt
>&
cv
=
aZone
->
m_Poly
->
m_CornersList
;
int
newLine
=
0
;
if
(
cv
.
size
()
)
...
...
pcbnew/legacy_plugin.cpp
View file @
1c9433fb
...
...
@@ -3609,7 +3609,7 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
typedef
std
::
vector
<
CPolyPt
>
CPOLY_PTS
;
// Save the corner list
const
CPOLY_PTS
&
cv
=
me
->
m_Poly
->
corner
;
const
CPOLY_PTS
&
cv
=
me
->
m_Poly
->
m_CornersList
;
for
(
CPOLY_PTS
::
const_iterator
it
=
cv
.
begin
();
it
!=
cv
.
end
();
++
it
)
{
fprintf
(
m_fp
,
"ZCorner %s %d
\n
"
,
...
...
@@ -3623,12 +3623,12 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
{
fprintf
(
m_fp
,
"$POLYSCORNERS
\n
"
);
for
(
CPOLY_PTS
::
const_iterator
it
=
fv
.
begin
();
it
!=
fv
.
end
();
++
it
)
for
(
CPOLY_PTS
::
const_iterator
it
=
fv
.
begin
();
it
!=
fv
.
end
();
++
it
)
{
fprintf
(
m_fp
,
"%s %d %d
\n
"
,
fmtBIUPair
(
it
->
x
,
it
->
y
).
c_str
(),
it
->
end_contour
,
it
->
utility
);
it
->
m_
utility
);
}
fprintf
(
m_fp
,
"$endPOLYSCORNERS
\n
"
);
...
...
pcbnew/move_or_drag_track.cpp
View file @
1c9433fb
...
...
@@ -887,7 +887,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
s_StartSegmentPresent
=
s_EndSegmentPresent
=
true
;
if
(
(
track
->
start
==
NULL
)
||
(
track
->
start
->
Type
()
==
PCB_TRACE_T
)
)
TrackToStartPoint
=
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
START
);
TrackToStartPoint
=
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
);
// Test if more than one segment is connected to this point
if
(
TrackToStartPoint
)
...
...
@@ -895,14 +895,14 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
TrackToStartPoint
->
SetState
(
BUSY
,
ON
);
if
(
(
TrackToStartPoint
->
Type
()
==
PCB_VIA_T
)
||
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
START
)
)
||
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
START
)
)
error
=
true
;
TrackToStartPoint
->
SetState
(
BUSY
,
OFF
);
}
if
(
(
track
->
end
==
NULL
)
||
(
track
->
end
->
Type
()
==
PCB_TRACE_T
)
)
TrackToEndPoint
=
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
END
);
TrackToEndPoint
=
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
);
// Test if more than one segment is connected to this point
if
(
TrackToEndPoint
)
...
...
@@ -910,7 +910,7 @@ void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC
TrackToEndPoint
->
SetState
(
BUSY
,
ON
);
if
(
(
TrackToEndPoint
->
Type
()
==
PCB_VIA_T
)
||
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
END
)
)
||
track
->
GetTrace
(
GetBoard
()
->
m_Track
,
NULL
,
FLG_
END
)
)
error
=
true
;
TrackToEndPoint
->
SetState
(
BUSY
,
OFF
);
...
...
pcbnew/pcbnew.h
View file @
1c9433fb
...
...
@@ -25,8 +25,8 @@
#define VISIBLE_ONLY (1 << 3) ///< if module not on a visible layer, do not select
#define
START 0
/* Flag used in locate routines */
#define
END 1
#define
FLG_START 0 // Flag used in locate routines
#define
FLG_END 1 // Flag used in locate routines
#define DIM_ANCRE_MODULE 3
/* Anchor size (footprint center) */
#define DIM_ANCRE_TEXTE 2
/* Anchor size (Text center) */
...
...
pcbnew/polygons_defs.h
deleted
100644 → 0
View file @
a8e4f8b0
/*
* file polygons_defs.h
* definitions to use boost::polygon in KiCad.
*/
#ifndef _POLYGONS_DEFS_H_
#define _POLYGONS_DEFS_H_
#include <boost/polygon/polygon.hpp>
// Define some types used here from boost::polygon
namespace
bpl
=
boost
::
polygon
;
// bpl = boost polygon library
using
namespace
bpl
::
operators
;
// +, -, =, ...
typedef
int
coordinate_type
;
typedef
bpl
::
polygon_data
<
int
>
KPolygon
;
typedef
std
::
vector
<
KPolygon
>
KPolygonSet
;
typedef
bpl
::
point_data
<
int
>
KPolyPoint
;
#endif // #ifndef _POLYGONS_DEFS_H_
pcbnew/specctra_export.cpp
View file @
1c9433fb
...
...
@@ -1178,16 +1178,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
mainPolygon
->
layer_id
=
layerIds
[
kicadLayer2pcb
[
item
->
GetLayer
()
]
];
int
count
=
item
->
m_Poly
->
corner
.
size
();
int
count
=
item
->
m_Poly
->
m_CornersList
.
size
();
int
ndx
=
0
;
// used in 2 for() loops below
for
(
;
ndx
<
count
;
++
ndx
)
{
wxPoint
point
(
item
->
m_Poly
->
corner
[
ndx
].
x
,
item
->
m_Poly
->
corner
[
ndx
].
y
);
wxPoint
point
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
x
,
item
->
m_Poly
->
m_CornersList
[
ndx
].
y
);
mainPolygon
->
AppendPoint
(
mapPt
(
point
)
);
// this was the end of the main polygon
if
(
item
->
m_Poly
->
corner
[
ndx
].
end_contour
)
if
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
end_contour
)
break
;
}
...
...
@@ -1197,7 +1197,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
// handle the cutouts
for
(
++
ndx
;
ndx
<
count
;
++
ndx
)
{
if
(
item
->
m_Poly
->
corner
[
ndx
-
1
].
end_contour
)
if
(
item
->
m_Poly
->
m_CornersList
[
ndx
-
1
].
end_contour
)
{
window
=
new
WINDOW
(
plane
);
plane
->
AddWindow
(
window
);
...
...
@@ -1211,8 +1211,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
wxASSERT
(
window
);
wxASSERT
(
cutout
);
wxPoint
point
(
item
->
m_Poly
->
corner
[
ndx
].
x
,
item
->
m_Poly
->
corner
[
ndx
].
y
);
wxPoint
point
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
x
,
item
->
m_Poly
->
m_CornersList
[
ndx
].
y
);
cutout
->
AppendPoint
(
mapPt
(
point
)
);
}
}
...
...
@@ -1253,16 +1253,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
mainPolygon
->
layer_id
=
layerIds
[
kicadLayer2pcb
[
item
->
GetLayer
()
]
];
int
count
=
item
->
m_Poly
->
corner
.
size
();
int
count
=
item
->
m_Poly
->
m_CornersList
.
size
();
int
ndx
=
0
;
// used in 2 for() loops below
for
(
;
ndx
<
count
;
++
ndx
)
{
wxPoint
point
(
item
->
m_Poly
->
corner
[
ndx
].
x
,
item
->
m_Poly
->
corner
[
ndx
].
y
);
wxPoint
point
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
x
,
item
->
m_Poly
->
m_CornersList
[
ndx
].
y
);
mainPolygon
->
AppendPoint
(
mapPt
(
point
)
);
// this was the end of the main polygon
if
(
item
->
m_Poly
->
corner
[
ndx
].
end_contour
)
if
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
end_contour
)
break
;
}
...
...
@@ -1272,7 +1272,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
// handle the cutouts
for
(
++
ndx
;
ndx
<
count
;
++
ndx
)
{
if
(
item
->
m_Poly
->
corner
[
ndx
-
1
].
end_contour
)
if
(
item
->
m_Poly
->
m_CornersList
[
ndx
-
1
].
end_contour
)
{
window
=
new
WINDOW
(
keepout
);
keepout
->
AddWindow
(
window
);
...
...
@@ -1286,8 +1286,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
wxASSERT
(
window
);
wxASSERT
(
cutout
);
wxPoint
point
(
item
->
m_Poly
->
corner
[
ndx
].
x
,
item
->
m_Poly
->
corner
[
ndx
].
y
);
wxPoint
point
(
item
->
m_Poly
->
m_CornersList
[
ndx
].
x
,
item
->
m_Poly
->
m_CornersList
[
ndx
].
y
);
cutout
->
AppendPoint
(
mapPt
(
point
)
);
}
}
...
...
pcbnew/zone_filling_algorithm.cpp
View file @
1c9433fb
...
...
@@ -89,39 +89,12 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>
break
;
}
m_smoothedPoly
->
MakeKboolPoly
(
-
1
,
-
1
,
NULL
,
true
);
int
count
=
0
;
while
(
m_smoothedPoly
->
GetKboolEngine
()
->
StartPolygonGet
()
)
{
CPolyPt
corner
(
0
,
0
,
false
);
while
(
m_smoothedPoly
->
GetKboolEngine
()
->
PolygonHasMorePoints
()
)
{
corner
.
x
=
(
int
)
m_smoothedPoly
->
GetKboolEngine
()
->
GetPolygonXPoint
();
corner
.
y
=
(
int
)
m_smoothedPoly
->
GetKboolEngine
()
->
GetPolygonYPoint
();
corner
.
end_contour
=
false
;
if
(
aCornerBuffer
)
aCornerBuffer
->
push_back
(
corner
);
else
m_FilledPolysList
.
push_back
(
corner
);
count
++
;
}
corner
.
end_contour
=
true
;
if
(
aCornerBuffer
)
{
aCornerBuffer
->
pop_back
();
aCornerBuffer
->
push_back
(
corner
);
}
else
{
m_FilledPolysList
.
pop_back
();
m_FilledPolysList
.
push_back
(
corner
);
}
m_smoothedPoly
->
GetKboolEngine
()
->
EndPolygonGet
();
}
m_smoothedPoly
->
FreeKboolEngine
();
if
(
aCornerBuffer
)
ConvertPolysListWithHolesToOnePolygon
(
m_smoothedPoly
->
m_CornersList
,
*
aCornerBuffer
);
else
ConvertPolysListWithHolesToOnePolygon
(
m_smoothedPoly
->
m_CornersList
,
m_FilledPolysList
);
/* For copper layers, we now must add holes in the Polygon list.
* holes are pads and tracks with their clearance area
*/
...
...
@@ -134,7 +107,7 @@ int ZONE_CONTAINER::BuildFilledPolysListData( BOARD* aPcb, std::vector <CPolyPt>
Fill_Zone_Areas_With_Segments
(
);
}
return
count
;
return
1
;
}
// Sort function to build filled zones
...
...
@@ -188,7 +161,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments()
x_coordinates
.
clear
();
for
(
ics
=
istart
,
ice
=
iend
;
ics
<=
iend
;
ice
=
ics
,
ics
++
)
{
if
(
m_FilledPolysList
[
ice
].
utility
)
if
(
m_FilledPolysList
[
ice
].
m_
utility
)
continue
;
int
seg_startX
=
m_FilledPolysList
[
ics
].
x
;
int
seg_startY
=
m_FilledPolysList
[
ics
].
y
;
...
...
pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp
View file @
1c9433fb
...
...
@@ -81,14 +81,14 @@ extern void CreateThermalReliefPadPolygon( std::vector<CPolyPt>& aCornerBuffer,
int
aThermalRot
);
// Local Functions: helper function to calculate solid areas
static
void
AddPolygonCornersToKPolygonList
(
std
::
vector
<
CPolyPt
>&
aCornersBuffer
,
K
PolygonSet
&
aK
PolyList
);
static
void
AddPolygonCornersToK
i
PolygonList
(
std
::
vector
<
CPolyPt
>&
aCornersBuffer
,
K
I_POLYGON_SET
&
aKi
PolyList
);
static
int
CopyPolygonsFromKPolygonListToFilledPolysList
(
ZONE_CONTAINER
*
aZone
,
K
PolygonSet
&
aK
PolyList
);
static
int
CopyPolygonsFromK
i
PolygonListToFilledPolysList
(
ZONE_CONTAINER
*
aZone
,
K
I_POLYGON_SET
&
aKi
PolyList
);
static
int
CopyPolygonsFromFilledPolysListTo
tK
PolygonList
(
ZONE_CONTAINER
*
aZone
,
K
PolygonSet
&
aK
PolyList
);
static
int
CopyPolygonsFromFilledPolysListTo
Ki
PolygonList
(
ZONE_CONTAINER
*
aZone
,
K
I_POLYGON_SET
&
aKi
PolyList
);
// Local Variables:
...
...
@@ -148,8 +148,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
*/
s_Correction
=
1.0
/
cos
(
3.14159265
/
s_CircleToSegmentsCount
);
// This K
PolygonSet
is the area(s) to fill, with m_ZoneMinThickness/2
K
PolygonSet
polyset_zone_solid_areas
;
// This K
I_POLYGON_SET
is the area(s) to fill, with m_ZoneMinThickness/2
K
I_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)
...
...
@@ -160,7 +160,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
* the main polygon is stored in polyset_zone_solid_areas
*/
CopyPolygonsFromFilledPolysListTo
tK
PolygonList
(
this
,
polyset_zone_solid_areas
);
CopyPolygonsFromFilledPolysListTo
Ki
PolygonList
(
this
,
polyset_zone_solid_areas
);
polyset_zone_solid_areas
-=
margin
;
if
(
polyset_zone_solid_areas
.
size
()
==
0
)
...
...
@@ -431,15 +431,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
// Calculate now actual solid areas
if
(
cornerBufferPolysToSubstract
.
size
()
>
0
)
{
K
PolygonSet
polyset_holes
;
AddPolygonCornersToKPolygonList
(
cornerBufferPolysToSubstract
,
polyset_holes
);
K
I_POLYGON_SET
polyset_holes
;
AddPolygonCornersToK
i
PolygonList
(
cornerBufferPolysToSubstract
,
polyset_holes
);
// Remove holes from initial area.:
polyset_zone_solid_areas
-=
polyset_holes
;
}
// put solid areas in m_FilledPolysList:
m_FilledPolysList
.
clear
();
CopyPolygonsFromKPolygonListToFilledPolysList
(
this
,
polyset_zone_solid_areas
);
CopyPolygonsFromK
i
PolygonListToFilledPolysList
(
this
,
polyset_zone_solid_areas
);
// Remove insulated islands:
if
(
GetNet
()
>
0
)
...
...
@@ -455,13 +455,13 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
// remove copper areas
if
(
cornerBufferPolysToSubstract
.
size
()
)
{
K
PolygonSet
polyset_holes
;
AddPolygonCornersToKPolygonList
(
cornerBufferPolysToSubstract
,
polyset_holes
);
K
I_POLYGON_SET
polyset_holes
;
AddPolygonCornersToK
i
PolygonList
(
cornerBufferPolysToSubstract
,
polyset_holes
);
polyset_zone_solid_areas
-=
polyset_holes
;
// put these areas in m_FilledPolysList
m_FilledPolysList
.
clear
();
CopyPolygonsFromKPolygonListToFilledPolysList
(
this
,
polyset_zone_solid_areas
);
CopyPolygonsFromK
i
PolygonListToFilledPolysList
(
this
,
polyset_zone_solid_areas
);
if
(
GetNet
()
>
0
)
Test_For_Copper_Island_And_Remove_Insulated_Islands
(
aPcb
);
...
...
@@ -470,12 +470,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
cornerBufferPolysToSubstract
.
clear
();
}
void
AddPolygonCornersToKPolygonList
(
std
::
vector
<
CPolyPt
>&
aCornersBuffer
,
K
PolygonSet
&
aK
PolyList
)
void
AddPolygonCornersToK
i
PolygonList
(
std
::
vector
<
CPolyPt
>&
aCornersBuffer
,
K
I_POLYGON_SET
&
aKi
PolyList
)
{
unsigned
ii
;
std
::
vector
<
K
PolyPoint
>
cornerslist
;
std
::
vector
<
K
I_POLY_POINT
>
cornerslist
;
int
polycount
=
0
;
...
...
@@ -485,49 +485,45 @@ void AddPolygonCornersToKPolygonList( std::vector <CPolyPt>& aCornersBuffer,
polycount
++
;
}
aKPolyList
.
reserve
(
polycount
);
aK
i
PolyList
.
reserve
(
polycount
);
for
(
unsigned
icnt
=
0
;
icnt
<
aCornersBuffer
.
size
();
)
{
K
Polygon
poly
;
K
I_POLYGON
poly
;
cornerslist
.
clear
();
for
(
ii
=
icnt
;
ii
<
aCornersBuffer
.
size
();
ii
++
)
{
cornerslist
.
push_back
(
K
PolyPoint
(
aCornersBuffer
[
ii
].
x
,
aCornersBuffer
[
ii
].
y
)
);
cornerslist
.
push_back
(
K
I_POLY_POINT
(
aCornersBuffer
[
ii
].
x
,
aCornersBuffer
[
ii
].
y
)
);
if
(
aCornersBuffer
[
ii
].
end_contour
)
break
;
}
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
aKPolyList
.
push_back
(
poly
);
aK
i
PolyList
.
push_back
(
poly
);
icnt
=
ii
+
1
;
}
}
int
CopyPolygonsFromKPolygonListToFilledPolysList
(
ZONE_CONTAINER
*
aZone
,
K
PolygonSet
&
aK
PolyList
)
int
CopyPolygonsFromK
i
PolygonListToFilledPolysList
(
ZONE_CONTAINER
*
aZone
,
K
I_POLYGON_SET
&
aKi
PolyList
)
{
int
count
=
0
;
std
::
vector
<
CPolyPt
>
polysList
;
for
(
unsigned
ii
=
0
;
ii
<
aKPolyList
.
size
();
ii
++
)
for
(
unsigned
ii
=
0
;
ii
<
aK
i
PolyList
.
size
();
ii
++
)
{
K
Polygon
&
poly
=
aK
PolyList
[
ii
];
K
I_POLYGON
&
poly
=
aKi
PolyList
[
ii
];
CPolyPt
corner
(
0
,
0
,
false
);
for
(
unsigned
jj
=
0
;
jj
<
poly
.
size
();
jj
++
)
{
K
PolyPoint
point
=
*
(
poly
.
begin
()
+
jj
);
K
I_POLY_POINT
point
=
*
(
poly
.
begin
()
+
jj
);
corner
.
x
=
point
.
x
();
corner
.
y
=
point
.
y
();
corner
.
end_contour
=
false
;
// Flag this corner if starting a hole connection segment:
// This is used by draw functions to draw only useful segments (and not extra segments)
// corner.utility = (aBoolengine->GetPolygonPointEdgeType() == KB_FALSE_EDGE) ? 1 : 0;
polysList
.
push_back
(
corner
);
count
++
;
}
...
...
@@ -542,10 +538,10 @@ int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone,
}
int
CopyPolygonsFromFilledPolysListTo
tK
PolygonList
(
ZONE_CONTAINER
*
aZone
,
K
PolygonSet
&
aK
PolyList
)
int
CopyPolygonsFromFilledPolysListTo
Ki
PolygonList
(
ZONE_CONTAINER
*
aZone
,
K
I_POLYGON_SET
&
aKi
PolyList
)
{
std
::
vector
<
CPolyPt
>
polysList
=
aZone
->
GetFilledPolysList
();
const
std
::
vector
<
CPolyPt
>&
polysList
=
aZone
->
GetFilledPolysList
();
unsigned
corners_count
=
polysList
.
size
();
int
count
=
0
;
unsigned
ic
=
0
;
...
...
@@ -554,35 +550,32 @@ int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone,
for
(
unsigned
ii
=
0
;
ii
<
corners_count
;
ii
++
)
{
CPolyPt
*
corner
=
&
polysList
[
ic
];
const
CPolyPt
&
corner
=
polysList
[
ii
];
if
(
corner
->
end_contour
)
if
(
corner
.
end_contour
)
polycount
++
;
}
aKPolyList
.
reserve
(
polycount
);
std
::
vector
<
K
PolyPoint
>
cornerslist
;
aK
i
PolyList
.
reserve
(
polycount
);
std
::
vector
<
K
I_POLY_POINT
>
cornerslist
;
while
(
ic
<
corners_count
)
{
cornerslist
.
clear
();
K
Polygon
poly
;
K
I_POLYGON
poly
;
{
for
(
;
ic
<
corners_count
;
ic
++
)
while
(
ic
<
corners_count
)
{
CPolyPt
*
corner
=
&
polysList
[
ic
];
cornerslist
.
push_back
(
K
PolyPoint
(
corner
->
x
,
corner
->
y
)
);
const
CPolyPt
&
corner
=
polysList
[
ic
++
];
cornerslist
.
push_back
(
K
I_POLY_POINT
(
corner
.
x
,
corner
.
y
)
);
count
++
;
if
(
corner
->
end_contour
)
{
ic
++
;
if
(
corner
.
end_contour
)
break
;
}
}
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
aKPolyList
.
push_back
(
poly
);
aK
i
PolyList
.
push_back
(
poly
);
}
}
...
...
pcbnew/zones_functions_for_undo_redo.cpp
View file @
1c9433fb
...
...
@@ -115,7 +115,7 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
wxASSERT
(
m_Poly
);
// m_Poly == NULL Should never happen
wxASSERT
(
aZoneToCompare
.
m_Poly
);
if
(
m_Poly
->
corner
!=
aZoneToCompare
.
m_Poly
->
corner
)
// Compare vector
if
(
m_Poly
->
m_CornersList
!=
aZoneToCompare
.
m_Poly
->
m_CornersList
)
// Compare vector
return
false
;
return
true
;
...
...
pcbnew/zones_test_and_combine_areas.cpp
View file @
1c9433fb
...
...
@@ -142,7 +142,7 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea )
// first, check for sides intersecting other sides, especially arcs
bool
bInt
=
false
;
bool
bArcInt
=
false
;
int
n_cont
=
p
->
Get
NumContours
();
int
n_cont
=
p
->
Get
ContoursCount
();
// make bounding rect for each contour
std
::
vector
<
CRect
>
cr
;
...
...
@@ -550,7 +550,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
continue
;
// test for intersecting segments
for
(
int
icont1
=
0
;
icont1
<
poly1
->
Get
NumContours
();
icont1
++
)
for
(
int
icont1
=
0
;
icont1
<
poly1
->
Get
ContoursCount
();
icont1
++
)
{
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
...
...
@@ -574,7 +574,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test )
style1
=
poly1
->
GetSideStyle
(
ic1
);
for
(
int
icont2
=
0
;
icont2
<
poly2
->
Get
NumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
poly2
->
Get
ContoursCount
();
icont2
++
)
{
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
...
...
@@ -668,7 +668,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
bool
bInt
=
false
;
bool
bArcInt
=
false
;
for
(
int
icont1
=
0
;
icont1
<
poly1
->
Get
NumContours
();
icont1
++
)
for
(
int
icont1
=
0
;
icont1
<
poly1
->
Get
ContoursCount
();
icont1
++
)
{
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
...
...
@@ -692,7 +692,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
style1
=
poly1
->
GetSideStyle
(
ic1
);
for
(
int
icont2
=
0
;
icont2
<
poly2
->
Get
NumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
poly2
->
Get
ContoursCount
();
icont2
++
)
{
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
...
...
@@ -781,142 +781,84 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_
/**
* Function CombineAreas
*
If possible, combine 2 copper areas
*
Merge 2 copper areas (which are expected intersecting)
* @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo
* commands can be NULL
* @param area_ref = t
j
e main area (zone)
* @param area_ref = t
h
e main area (zone)
* @param area_to_combine = the zone that can be merged with area_ref
* area_ref must be BEFORE area_to_combine
* area_to_combine will be deleted, if areas are combined
* @return : 0 if no intersection
* 1 if intersection
* 2 if arcs intersect
* 2 if arcs intersect
(Currently not supported)
*/
int
BOARD
::
CombineAreas
(
PICKED_ITEMS_LIST
*
aDeletedList
,
ZONE_CONTAINER
*
area_ref
,
ZONE_CONTAINER
*
area_to_combine
)
{
if
(
area_ref
==
area_to_combine
)
{
wxASSERT
(
0
);
return
0
;
}
// polygons intersect, combine them
std
::
vector
<
CArc
>
arc_array1
;
std
::
vector
<
CArc
>
arc_array2
;
bool
keep_area_to_combine
=
false
;
Bool_Engine
*
booleng
=
new
Bool_Engine
();
ArmBoolEng
(
booleng
);
// std::vector<CArc> arc_array1;
// std::vector<CArc> arc_array2;
bool
keep_area_to_combine
=
false
;
// TODO test if areas intersect
KI_POLYGON_WITH_HOLES
areaRefPoly
;
KI_POLYGON_WITH_HOLES
areaToMergePoly
;
CopyPolysListToKiPolygonWithHole
(
area_ref
->
m_Poly
->
m_CornersList
,
areaRefPoly
);
CopyPolysListToKiPolygonWithHole
(
area_to_combine
->
m_Poly
->
m_CornersList
,
areaToMergePoly
);
KI_POLYGON_WITH_HOLES_SET
mergedOutlines
;
mergedOutlines
.
push_back
(
areaRefPoly
);
mergedOutlines
+=
areaToMergePoly
;
// We should have only one polygon with holes in mergedOutlines
// or the 2 initial outlines do not intersect
if
(
mergedOutlines
.
size
()
>
1
)
return
0
;
area_ref
->
m_Poly
->
AddPolygonsToBoolEng
(
booleng
,
GROUP_A
,
-
1
,
-
1
);
area_to_combine
->
m_Poly
->
AddPolygonsToBoolEng
(
booleng
,
GROUP_B
,
-
1
,
-
1
);
booleng
->
Do_Operation
(
BOOL_OR
);
areaRefPoly
=
mergedOutlines
[
0
];
area_ref
->
m_Poly
->
RemoveAllContours
();
KI_POLYGON_WITH_HOLES
::
iterator_type
corner
=
areaRefPoly
.
begin
();
// create area with external contour: Recreate only area edges, NOT holes
if
(
booleng
->
StartPolygonGet
()
)
{
if
(
booleng
->
GetPolygonPointEdgeType
()
==
KB_INSIDE_EDGE
)
{
DisplayError
(
NULL
,
wxT
(
"BOARD::CombineAreas() error: unexpected hole descriptor"
)
);
}
area_ref
->
m_Poly
->
RemoveAllContours
();
// foreach point in the polygon
bool
first
=
true
;
while
(
booleng
->
PolygonHasMorePoints
()
)
{
int
x
=
(
int
)
booleng
->
GetPolygonXPoint
();
int
y
=
(
int
)
booleng
->
GetPolygonYPoint
();
if
(
first
)
{
first
=
false
;
area_ref
->
m_Poly
->
Start
(
area_ref
->
GetLayer
(
),
x
,
y
,
area_ref
->
m_Poly
->
GetHatchStyle
()
);
}
else
{
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
}
}
booleng
->
EndPolygonGet
();
area_ref
->
m_Poly
->
Close
();
}
// Recreate the area_to_combine if a second polygon exists
// if not exists , the first poly contains the 2 initial polygons
#if 0 // TestAreaIntersection must be called before combine areas, so
// 2 intersecting areas are expected, and only one outline contour after combining areas
else
area_ref
->
m_Poly
->
Start
(
area_ref
->
GetLayer
(),
corner
->
x
(),
corner
->
y
(),
area_ref
->
m_Poly
->
GetHatchStyle
()
);
while
(
++
corner
!=
areaRefPoly
.
end
()
)
{
area_to_combine->m_Poly->RemoveAllContours();
keep_area_to_combine = true;
// create area with external contour: Recreate only area edges, NOT holes (todo..)
{
// foreach point in the polygon
bool first = true;
while( booleng->PolygonHasMorePoints() )
{
int x = booleng->GetPolygonXPoint();
int y = booleng->GetPolygonYPoint();
if( first )
{
first = false;
area_to_combine->m_Poly->Start( area_ref->GetLayer(), x, y,
area_ref->m_Poly->GetHatchStyle() );
}
else
{
area_to_combine->m_Poly->AppendCorner( x, y );
}
}
booleng->EndPolygonGet();
area_to_combine->m_Poly->Close();
}
area_ref
->
m_Poly
->
AppendCorner
(
corner
->
x
(),
corner
->
y
()
);
}
#endif
// add holes
bool
show_error
=
true
;
area_ref
->
m_Poly
->
Close
();
while
(
booleng
->
StartPolygonGet
()
)
// add holes (set of polygons)
KI_POLYGON_WITH_HOLES
::
iterator_holes_type
hole
=
areaRefPoly
.
begin_holes
();
while
(
hole
!=
areaRefPoly
.
end_holes
()
)
{
// we expect all vertex are holes inside the main outline
if
(
booleng
->
GetPolygonPointEdgeType
()
!=
KB_INSIDE_EDGE
)
KI_POLYGON
::
iterator_type
hole_corner
=
hole
->
begin
();
// create area with external contour: Recreate only area edges, NOT holes
while
(
hole_corner
!=
hole
->
end
()
)
{
if
(
show_error
)
// show this error only once, if happens
DisplayError
(
NULL
,
wxT
(
"BOARD::CombineAreas() error: unexpected outside contour descriptor"
)
);
show_error
=
false
;
continue
;
area_ref
->
m_Poly
->
AppendCorner
(
hole_corner
->
x
(),
hole_corner
->
y
()
);
hole_corner
++
;
}
while
(
booleng
->
PolygonHasMorePoints
()
)
{
int
x
=
(
int
)
booleng
->
GetPolygonXPoint
();
int
y
=
(
int
)
booleng
->
GetPolygonYPoint
();
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
}
area_ref
->
m_Poly
->
Close
();
booleng
->
EndPolygonGet
()
;
hole
++
;
}
if
(
!
keep_area_to_combine
)
RemoveArea
(
aDeletedList
,
area_to_combine
);
area_ref
->
utility
=
1
;
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array1
);
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array2
);
//
area_ref->m_Poly->RestoreArcs( &arc_array1 );
//
area_ref->m_Poly->RestoreArcs( &arc_array2 );
area_ref
->
m_Poly
->
Hatch
();
delete
booleng
;
return
1
;
}
...
...
@@ -1024,7 +966,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
}
// now test spacing between areas
for
(
int
icont
=
0
;
icont
<
refSmoothedPoly
->
Get
NumContours
();
icont
++
)
for
(
int
icont
=
0
;
icont
<
refSmoothedPoly
->
Get
ContoursCount
();
icont
++
)
{
int
ic_start
=
refSmoothedPoly
->
GetContourStart
(
icont
);
int
ic_end
=
refSmoothedPoly
->
GetContourEnd
(
icont
);
...
...
@@ -1048,7 +990,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E
int
astyle
=
refSmoothedPoly
->
GetSideStyle
(
ic
);
for
(
int
icont2
=
0
;
icont2
<
testSmoothedPoly
->
Get
NumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
testSmoothedPoly
->
Get
ContoursCount
();
icont2
++
)
{
int
ic_start2
=
testSmoothedPoly
->
GetContourStart
(
icont2
);
int
ic_end2
=
testSmoothedPoly
->
GetContourEnd
(
icont2
);
...
...
@@ -1128,7 +1070,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
wxPoint
end
;
// Search the end point of the edge starting at aCornerIndex
if
(
aArea
->
m_Poly
->
corner
[
aCornerIndex
].
end_contour
==
false
if
(
aArea
->
m_Poly
->
m_CornersList
[
aCornerIndex
].
end_contour
==
false
&&
aCornerIndex
<
(
aArea
->
GetNumCorners
()
-
1
)
)
{
end
=
aArea
->
GetCornerPosition
(
aCornerIndex
+
1
);
...
...
@@ -1141,7 +1083,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
while
(
ii
>=
0
)
{
if
(
aArea
->
m_Poly
->
corner
[
ii
].
end_contour
)
if
(
aArea
->
m_Poly
->
m_CornersList
[
ii
].
end_contour
)
break
;
end
=
aArea
->
GetCornerPosition
(
ii
);
...
...
@@ -1189,7 +1131,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
int
ax2
=
end
.
x
;
int
ay2
=
end
.
y
;
for
(
int
icont2
=
0
;
icont2
<
area_to_test
->
m_Poly
->
Get
NumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
area_to_test
->
m_Poly
->
Get
ContoursCount
();
icont2
++
)
{
int
ic_start2
=
area_to_test
->
m_Poly
->
GetContourStart
(
icont2
);
int
ic_end2
=
area_to_test
->
m_Poly
->
GetContourEnd
(
icont2
);
...
...
polygon/PolyLine.cpp
View file @
1c9433fb
...
...
@@ -16,10 +16,10 @@
CPolyLine
::
CPolyLine
()
{
m_hatchStyle
=
NO_HATCH
;
m_hatchPitch
=
0
;
m_
Width
=
0
;
utility
=
0
;
m_hatchStyle
=
NO_HATCH
;
m_hatchPitch
=
0
;
m_
width
=
0
;
m_utility
=
0
;
m_Kbool_Poly_Engine
=
NULL
;
}
...
...
@@ -29,11 +29,23 @@ CPolyLine::CPolyLine()
CPolyLine
::~
CPolyLine
()
{
UnHatch
();
if
(
m_Kbool_Poly_Engine
)
delete
m_Kbool_Poly_Engine
;
}
/**
* Function armBoolEng
* Initialise parameters used in kbool
* @param aBooleng = pointer to the Bool_Engine to initialise
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
*/
static
void
armBoolEng
(
Bool_Engine
*
aBooleng
,
bool
aConvertHoles
=
false
);
/**
* Function NormalizeWithKbool
* Use the Kbool Library to clip contours: if outlines are crossing, the self-crossing polygon
...
...
@@ -46,11 +58,11 @@ CPolyLine::~CPolyLine()
* @param bRetainArcs == true, try to retain arcs in polys
* @return number of external contours, or -1 if error
*/
int
CPolyLine
::
NormalizeWithKbool
(
std
::
vector
<
CPolyLine
*>
*
aExtraPolyList
,
bool
bRetainArcs
)
int
CPolyLine
::
NormalizeWithKbool
(
std
::
vector
<
CPolyLine
*>*
aExtraPolyList
,
bool
bRetainArcs
)
{
std
::
vector
<
CArc
>
arc_array
;
std
::
vector
<
void
*>
hole_array
;
// list of holes
std
::
vector
<
int
>
*
hole
;
// used to store corners for a given hole
std
::
vector
<
int
>
*
hole
;
// used to store corners for a given hole
CPolyLine
*
polyline
;
int
n_ext_cont
=
0
;
// CPolyLine count
...
...
@@ -61,9 +73,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
* True holes are combined if possible
*/
if
(
bRetainArcs
)
MakeKboolPoly
(
-
1
,
-
1
,
&
arc_array
);
MakeKboolPoly
(
&
arc_array
);
else
MakeKboolPoly
(
-
1
,
-
1
,
NULL
);
MakeKboolPoly
(
NULL
);
UnHatch
();
...
...
@@ -82,10 +94,11 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
{
hole
=
new
std
::
vector
<
int
>
;
hole_array
.
push_back
(
hole
);
while
(
m_Kbool_Poly_Engine
->
PolygonHasMorePoints
()
)
// store hole
{
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
hole
->
push_back
(
x
);
hole
->
push_back
(
y
);
}
...
...
@@ -95,14 +108,16 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
else
if
(
n_ext_cont
==
0
)
{
// first external contour, replace this poly
corner
.
clear
();
side_s
tyle
.
clear
();
m_CornersList
.
clear
();
m_SideS
tyle
.
clear
();
bool
first
=
true
;
while
(
m_Kbool_Poly_Engine
->
PolygonHasMorePoints
()
)
{
// foreach point in the polygon
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
if
(
first
)
{
first
=
false
;
...
...
@@ -121,10 +136,12 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
polyline
=
new
CPolyLine
;
// create new poly
aExtraPolyList
->
push_back
(
polyline
);
// put it in array
bool
first
=
true
;
while
(
m_Kbool_Poly_Engine
->
PolygonHasMorePoints
()
)
// read next external contour
{
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
if
(
first
)
{
first
=
false
;
...
...
@@ -143,8 +160,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// now add cutouts to the corresponding CPolyLine(s)
for
(
unsigned
ii
=
0
;
ii
<
hole_array
.
size
();
ii
++
)
{
hole
=
(
std
::
vector
<
int
>
*
)
hole_array
[
ii
];
polyline
=
NULL
;
hole
=
(
std
::
vector
<
int
>*
)
hole_array
[
ii
];
polyline
=
NULL
;
if
(
n_ext_cont
==
1
)
{
polyline
=
this
;
...
...
@@ -154,8 +172,9 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// find the polygon that contains this hole
// testing one corner inside is enought because a hole is entirely inside the polygon
// so we test only the first corner
int
x
=
(
*
hole
)[
0
];
int
y
=
(
*
hole
)[
1
];
int
x
=
(
*
hole
)[
0
];
int
y
=
(
*
hole
)[
1
];
if
(
TestPointInside
(
x
,
y
)
)
polyline
=
this
;
else
if
(
aExtraPolyList
)
...
...
@@ -177,8 +196,8 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
{
for
(
unsigned
ii
=
0
;
ii
<
(
*
hole
).
size
();
ii
++
)
{
int
x
=
(
*
hole
)[
ii
];
ii
++
;
int
y
=
(
*
hole
)[
ii
];
int
x
=
(
*
hole
)[
ii
];
ii
++
;
int
y
=
(
*
hole
)[
ii
];
polyline
->
AppendCorner
(
x
,
y
,
STRAIGHT
,
false
);
}
...
...
@@ -194,76 +213,21 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
// free hole list
for
(
unsigned
ii
=
0
;
ii
<
hole_array
.
size
();
ii
++
)
delete
(
std
::
vector
<
int
>
*
)
hole_array
[
ii
];
delete
(
std
::
vector
<
int
>*
)
hole_array
[
ii
];
return
n_ext_cont
;
}
/**
* Function AddPolygonsToBoolEng
* Add a CPolyLine to a kbool engine, preparing a boolean op between polygons
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* @param arc_array: arc converted to poly segments (NULL if not exists)
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
*/
int
CPolyLine
::
AddPolygonsToBoolEng
(
Bool_Engine
*
aBooleng
,
GroupType
aGroup
,
int
aStart_contour
,
int
aEnd_contour
,
std
::
vector
<
CArc
>
*
arc_array
)
{
int
count
=
0
;
if
(
(
aGroup
!=
GROUP_A
)
&&
(
aGroup
!=
GROUP_B
)
)
return
0
;
//Error !
/* Convert the current polyline contour to a kbool polygon: */
MakeKboolPoly
(
aStart_contour
,
aEnd_contour
,
arc_array
);
/* add the resulting kbool set of polygons to the current kcool engine */
while
(
m_Kbool_Poly_Engine
->
StartPolygonGet
()
)
{
if
(
aBooleng
->
StartPolygonAdd
(
GROUP_A
)
)
{
while
(
m_Kbool_Poly_Engine
->
PolygonHasMorePoints
()
)
{
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
aBooleng
->
AddPoint
(
x
,
y
);
count
++
;
}
aBooleng
->
EndPolygonAdd
();
}
m_Kbool_Poly_Engine
->
EndPolygonGet
();
}
delete
m_Kbool_Poly_Engine
;
m_Kbool_Poly_Engine
=
NULL
;
return
count
;
}
/**
* Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour
* approximates arcs with multiple straight-line segments
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* combining intersecting contours if possible
* @param arc_array : return corners computed from arcs approximations in arc_array
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
* @return error: 0 if Ok, 1 if error
*/
int
CPolyLine
::
MakeKboolPoly
(
int
aStart_contour
,
int
aEnd_contour
,
std
::
vector
<
CArc
>
*
arc_array
,
bool
aConvertHoles
)
int
CPolyLine
::
MakeKboolPoly
(
std
::
vector
<
CArc
>*
arc_array
)
{
if
(
m_Kbool_Poly_Engine
)
{
...
...
@@ -271,65 +235,40 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
m_Kbool_Poly_Engine
=
NULL
;
}
int
polycount
=
GetNumContours
();
if
(
!
GetClosed
()
&&
(
aStart_contour
==
(
polycount
-
1
)
||
aStart_contour
==
-
1
)
)
if
(
!
GetClosed
()
)
return
1
;
// error
int
n_arcs
=
0
;
int
polycount
=
GetContoursCount
();
int
last_contour
=
polycount
-
1
;
int
first_contour
=
aStart_contour
;
int
last_contour
=
aEnd_contour
;
if
(
aStart_contour
==
-
1
)
{
first_contour
=
0
;
last_contour
=
polycount
-
1
;
}
if
(
aEnd_contour
==
-
1
)
{
last_contour
=
polycount
-
1
;
}
if
(
arc_array
)
arc_array
->
clear
();
int
iarc
=
0
;
for
(
int
icont
=
first_contour
;
icont
<=
last_contour
;
icont
++
)
for
(
int
icont
=
0
;
icont
<=
last_contour
;
icont
++
)
{
// Fill a kbool engine for this contour,
// and combine it with previous contours
Bool_Engine
*
booleng
=
new
Bool_Engine
();
ArmBoolEng
(
booleng
,
aConvertHoles
);
if
(
m_Kbool_Poly_Engine
)
// a previous contour exists. Put it in new engine
{
while
(
m_Kbool_Poly_Engine
->
StartPolygonGet
()
)
{
if
(
booleng
->
StartPolygonAdd
(
GROUP_A
)
)
{
while
(
m_Kbool_Poly_Engine
->
PolygonHasMorePoints
()
)
{
int
x
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonXPoint
();
int
y
=
(
int
)
m_Kbool_Poly_Engine
->
GetPolygonYPoint
();
booleng
->
AddPoint
(
x
,
y
);
}
booleng
->
EndPolygonAdd
();
}
m_Kbool_Poly_Engine
->
EndPolygonGet
();
}
}
armBoolEng
(
booleng
,
false
);
// first, calculate number of vertices in contour
int
n_vertices
=
0
;
int
ic_st
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
int
ic_st
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
if
(
!
booleng
->
StartPolygonAdd
(
GROUP_B
)
)
{
wxASSERT
(
0
);
return
1
;
//
error
return
1
;
//
error
}
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
{
int
style
=
side_style
[
ic
];
int
style
=
m_SideStyle
[
ic
];
if
(
style
==
STRAIGHT
)
n_vertices
++
;
else
...
...
@@ -343,22 +282,25 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
// now enter this contour to booleng
int
ivtx
=
0
;
for
(
int
ic
=
ic_st
;
ic
<=
ic_end
;
ic
++
)
{
int
style
=
side_s
tyle
[
ic
];
int
x1
=
corner
[
ic
].
x
;
int
y1
=
corner
[
ic
].
y
;
int
style
=
m_SideS
tyle
[
ic
];
int
x1
=
m_CornersList
[
ic
].
x
;
int
y1
=
m_CornersList
[
ic
].
y
;
int
x2
,
y2
;
if
(
ic
<
ic_end
)
{
x2
=
corner
[
ic
+
1
].
x
;
y2
=
corner
[
ic
+
1
].
y
;
x2
=
m_CornersList
[
ic
+
1
].
x
;
y2
=
m_CornersList
[
ic
+
1
].
y
;
}
else
{
x2
=
corner
[
ic_st
].
x
;
y2
=
corner
[
ic_st
].
y
;
x2
=
m_CornersList
[
ic_st
].
x
;
y2
=
m_CornersList
[
ic_st
].
y
;
}
if
(
style
==
STRAIGHT
)
{
booleng
->
AddPoint
(
x1
,
y1
);
...
...
@@ -367,44 +309,45 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
else
{
// style is arc_cw or arc_ccw
int
n
;
// number of steps for arcs
int
n
;
// number of steps for arcs
n
=
CArc
::
ARC_STEPS
;
double
xo
,
yo
,
theta1
,
theta2
,
a
,
b
;
a
=
fabs
(
(
double
)
(
x1
-
x2
)
);
b
=
fabs
(
(
double
)
(
y1
-
y2
)
);
double
xo
,
yo
,
theta1
,
theta2
,
a
,
b
;
a
=
fabs
(
(
double
)
(
x1
-
x2
)
);
b
=
fabs
(
(
double
)
(
y1
-
y2
)
);
if
(
style
==
CPolyLine
::
ARC_CW
)
{
// clockwise arc (ie.quadrant of ellipse)
if
(
x2
>
x1
&&
y2
>
y1
)
{
// first quadrant, draw second quadrant of ellipse
xo
=
x2
;
yo
=
y1
;
theta1
=
M_PI
;
theta2
=
M_PI
/
2.0
;
xo
=
x2
;
yo
=
y1
;
theta1
=
M_PI
;
theta2
=
M_PI
/
2.0
;
}
else
if
(
x2
<
x1
&&
y2
>
y1
)
{
// second quadrant, draw third quadrant of ellipse
xo
=
x1
;
yo
=
y2
;
theta1
=
3.0
*
M_PI
/
2.0
;
theta2
=
M_PI
;
xo
=
x1
;
yo
=
y2
;
theta1
=
3.0
*
M_PI
/
2.0
;
theta2
=
M_PI
;
}
else
if
(
x2
<
x1
&&
y2
<
y1
)
{
// third quadrant, draw fourth quadrant of ellipse
xo
=
x2
;
yo
=
y1
;
theta1
=
2.0
*
M_PI
;
theta2
=
3.0
*
M_PI
/
2.0
;
xo
=
x2
;
yo
=
y1
;
theta1
=
2.0
*
M_PI
;
theta2
=
3.0
*
M_PI
/
2.0
;
}
else
{
xo
=
x1
;
// fourth quadrant, draw first quadrant of ellipse
yo
=
y2
;
theta1
=
M_PI
/
2.0
;
theta2
=
0.0
;
xo
=
x1
;
// fourth quadrant, draw first quadrant of ellipse
yo
=
y2
;
theta1
=
M_PI
/
2.0
;
theta2
=
0.0
;
}
}
else
...
...
@@ -412,31 +355,31 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
// counter-clockwise arc
if
(
x2
>
x1
&&
y2
>
y1
)
{
xo
=
x1
;
// first quadrant, draw fourth quadrant of ellipse
yo
=
y2
;
theta1
=
3.0
*
M_PI
/
2.0
;
theta2
=
2.0
*
M_PI
;
xo
=
x1
;
// first quadrant, draw fourth quadrant of ellipse
yo
=
y2
;
theta1
=
3.0
*
M_PI
/
2.0
;
theta2
=
2.0
*
M_PI
;
}
else
if
(
x2
<
x1
&&
y2
>
y1
)
{
xo
=
x2
;
// second quadrant
yo
=
y1
;
theta1
=
0.0
;
theta2
=
M_PI
/
2.0
;
xo
=
x2
;
// second quadrant
yo
=
y1
;
theta1
=
0.0
;
theta2
=
M_PI
/
2.0
;
}
else
if
(
x2
<
x1
&&
y2
<
y1
)
{
xo
=
x1
;
// third quadrant
yo
=
y2
;
theta1
=
M_PI
/
2.0
;
theta2
=
M_PI
;
xo
=
x1
;
// third quadrant
yo
=
y2
;
theta1
=
M_PI
/
2.0
;
theta2
=
M_PI
;
}
else
{
xo
=
x2
;
// fourth quadrant
yo
=
y1
;
theta1
=
M_PI
;
theta2
=
3.0
*
M_PI
/
2.0
;
xo
=
x2
;
// fourth quadrant
yo
=
y1
;
theta1
=
M_PI
;
theta2
=
3.0
*
M_PI
/
2.0
;
}
}
...
...
@@ -446,23 +389,26 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
CArc
new_arc
;
new_arc
.
style
=
style
;
new_arc
.
n_steps
=
n
;
new_arc
.
xi
=
x1
;
new_arc
.
yi
=
y1
;
new_arc
.
xf
=
x2
;
new_arc
.
yf
=
y2
;
new_arc
.
xi
=
x1
;
new_arc
.
yi
=
y1
;
new_arc
.
xf
=
x2
;
new_arc
.
yf
=
y2
;
arc_array
->
push_back
(
new_arc
);
iarc
++
;
}
for
(
int
is
=
0
;
is
<
n
;
is
++
)
{
double
theta
=
theta1
+
(
(
theta2
-
theta1
)
*
(
double
)
is
)
/
n
;
double
x
=
xo
+
a
*
cos
(
theta
);
double
y
=
yo
+
b
*
sin
(
theta
);
double
theta
=
theta1
+
(
(
theta2
-
theta1
)
*
(
double
)
is
)
/
n
;
double
x
=
xo
+
a
*
cos
(
theta
);
double
y
=
yo
+
b
*
sin
(
theta
);
if
(
is
==
0
)
{
x
=
x1
;
y
=
y1
;
x
=
x1
;
y
=
y1
;
}
booleng
->
AddPoint
(
x
,
y
);
ivtx
++
;
}
...
...
@@ -474,7 +420,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
wxASSERT
(
0
);
}
//
close list added to the bool engine
// close list added to the bool engine
booleng
->
EndPolygonAdd
();
/* now combine polygon to the previous polygons.
...
...
@@ -484,7 +430,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
* Others polygons are substract to the outline and corners will be ordered counter clockwise
* by the kbool engine
*/
if
(
aStart_contour
<=
0
&&
icont
!=
0
)
// substract hole to outside ( if the outline contour is take in account)
if
(
icont
!=
0
)
// substract hole to outside ( if the outline contour is take in account)
{
booleng
->
Do_Operation
(
BOOL_A_SUB_B
);
}
...
...
@@ -496,6 +442,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
// now use result as new polygon (delete the old one if exists)
if
(
m_Kbool_Poly_Engine
)
delete
m_Kbool_Poly_Engine
;
m_Kbool_Poly_Engine
=
booleng
;
}
...
...
@@ -504,69 +451,70 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector<
/**
* Function
A
rmBoolEng
* Function
a
rmBoolEng
* Initialise parameters used in kbool
* @param aBooleng = pointer to the Bool_Engine to initialise
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: in resulting polygon, holes are linked into outer contours by double overlapping segments
* false: in resulting polygons, holes are not linked: they are separate polygons
*/
void
A
rmBoolEng
(
Bool_Engine
*
aBooleng
,
bool
aConvertHoles
)
void
a
rmBoolEng
(
Bool_Engine
*
aBooleng
,
bool
aConvertHoles
)
{
// set some global vals to arm the boolean engine
// input points are scaled up with GetDGrid() * GetGrid()
// DGRID is only meant to make fractional parts of input data which
/*
The input data scaled up with DGrid is related to the accuracy the user has in his input data.
User data with a minimum accuracy of 0.001, means set the DGrid to 1000.
The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid
everything smaller than 1/DGrid is rounded.
DGRID is only meant to make fractional parts of input data which can be
doubles, part of the integers used in vertexes within the boolean algorithm.
And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy.
Within the algorithm all input data is multiplied with DGRID, and the result
is rounded to an integer.
*/
double
DGRID
=
1000.0
;
// round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// kbool uses DGRID to convert float user units to integer
// kbool unit = (int)(user unit * DGRID)
// Note: in kicad, coordinates are already integer so DGRID could be set to 1
// we can choose 1.0,
// but choose DGRID = 1000.0 solves some filling problems
//
(perhaps because this allows a better precision in kbool internal calculations
double
MARGE
=
1.0
/
DGRID
;
// snap with in this range points to lines in the intersection routines
// should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
// this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 )
// For kicad we choose MARGE = 1/DGRID
/*
*
The input data scaled up with DGrid is related to the accuracy the user has in his input data.
*
User data with a minimum accuracy of 0.001, means set the DGrid to 1000.
*
The input data may contain data with a minimum accuracy much smaller, but by setting the DGrid
*
everything smaller than 1/DGrid is rounded.
*
*
DGRID is only meant to make fractional parts of input data which can be
*
doubles, part of the integers used in vertexes within the boolean algorithm.
*
And therefore DGRID bigger than 1 is not usefull, you would only loose accuracy.
*
Within the algorithm all input data is multiplied with DGRID, and the result
*
is rounded to an integer.
*/
double
DGRID
=
1000.0
;
// round coordinate X or Y value in calculations to this (initial value = 1000.0 in kbool example)
// kbool uses DGRID to convert float user units to integer
// kbool unit = (int)(user unit * DGRID)
// Note: in kicad, coordinates are already integer so DGRID could be set to 1
// we can choose 1.0,
// but choose DGRID = 1000.0 solves some filling problems
// (perhaps because this allows a better precision in kbool internal calculations
double
MARGE
=
1.0
/
DGRID
;
// snap with in this range points to lines in the intersection routines
// should always be >= 1/DGRID a MARGE >= 10/DGRID is ok
// this is also used to remove small segments and to decide when
// two segments are in line. ( initial value = 0.001 )
// For kicad we choose MARGE = 1/DGRID
double
CORRECTIONFACTOR
=
0.0
;
// correct the polygons by this number: used in BOOL_CORRECTION operation
// this operation shrinks a polygon if CORRECTIONFACTOR < 0
// or stretch it if CORRECTIONFACTOR > 0
// the size change is CORRECTIONFACTOR (holes are correctly handled)
double
CORRECTIONABER
=
1.0
;
// the accuracy for the rounded shapes used in correction
double
ROUNDFACTOR
=
1.5
;
// when will we round the correction shape to a circle
double
SMOOTHABER
=
10.0
;
// accuracy when smoothing a polygon
double
MAXLINEMERGE
=
1000.0
;
// leave as is, segments of this length in smoothen
/*
Grid makes sure that the integer data used within the algorithm has room for extra intersections
smaller than the smallest number within the input data.
The input data scaled up with DGrid is related to the accuracy the user has in his input data.
Another scaling with Grid is applied on top of it to create space in the integer number for
even smaller numbers.
*/
int
GRID
=
(
int
)
(
10000.0
/
DGRID
);
// initial value = 10000 in kbool example but we use
// 10000/DGRID because the scaling is made by DGRID
// on integer pcbnew units and the global scaling
// ( GRID*DGRID) must be < 30000 to avoid overflow
// in calculations (made in long long in kbool)
if
(
GRID
<=
1
)
// Cannot be null!
double
CORRECTIONABER
=
1.0
;
// the accuracy for the rounded shapes used in correction
double
ROUNDFACTOR
=
1.5
;
// when will we round the correction shape to a circle
double
SMOOTHABER
=
10.0
;
// accuracy when smoothing a polygon
double
MAXLINEMERGE
=
1000.0
;
// leave as is, segments of this length in smoothen
/*
* Grid makes sure that the integer data used within the algorithm has room for extra intersections
* smaller than the smallest number within the input data.
* The input data scaled up with DGrid is related to the accuracy the user has in his input data.
* Another scaling with Grid is applied on top of it to create space in the integer number for
* even smaller numbers.
*/
int
GRID
=
(
int
)
(
10000.0
/
DGRID
);
// initial value = 10000 in kbool example but we use
// 10000/DGRID because the scaling is made by DGRID
// on integer pcbnew units and the global scaling
// ( GRID*DGRID) must be < 30000 to avoid overflow
// in calculations (made in long long in kbool)
if
(
GRID
<=
1
)
// Cannot be null!
GRID
=
1
;
aBooleng
->
SetMarge
(
MARGE
);
...
...
@@ -581,9 +529,9 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
if
(
aConvertHoles
)
{
#if 1 // Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions
// SetAllowNonTopHoleLinking() exists only in kbool >= 2.1
aBooleng
->
SetAllowNonTopHoleLinking
(
false
);
// Default = true, but i have problems (filling errors) when true
#if 1
// Can be set to 1 for kbool version >= 2.1, must be set to 0 for previous versions
// SetAllowNonTopHoleLinking() exists only in kbool >= 2.1
aBooleng
->
SetAllowNonTopHoleLinking
(
false
);
// Default = true, but i have problems (filling errors) when true
#endif
aBooleng
->
SetLinkHoles
(
true
);
// holes will be connected by double overlapping segments
aBooleng
->
SetOrientationEntryMode
(
false
);
// all polygons are contours, not holes
...
...
@@ -596,7 +544,7 @@ void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles )
}
int
CPolyLine
::
NormalizeAreaOutlines
(
std
::
vector
<
CPolyLine
*>
*
pa
,
bool
bRetainArcs
)
int
CPolyLine
::
NormalizeAreaOutlines
(
std
::
vector
<
CPolyLine
*>*
pa
,
bool
bRetainArcs
)
{
return
NormalizeWithKbool
(
pa
,
bRetainArcs
);
}
...
...
@@ -605,33 +553,37 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*> * pa, bool bRetain
// Restore arcs to a polygon where they were replaced with steps
// If pa != NULL, also use polygons in pa array
//
int
CPolyLine
::
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
)
int
CPolyLine
::
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
)
{
// get poly info
int
n_polys
=
1
;
if
(
pa
)
n_polys
+=
pa
->
size
();
CPolyLine
*
poly
;
// undraw polys and clear utility flag for all corners
// undraw polys and clear
m_
utility flag for all corners
for
(
int
ip
=
0
;
ip
<
n_polys
;
ip
++
)
{
if
(
ip
==
0
)
poly
=
this
;
else
poly
=
(
*
pa
)[
ip
-
1
];
poly
->
UnHatch
();
for
(
int
ic
=
0
;
ic
<
poly
->
GetNumCorners
();
ic
++
)
poly
->
SetUtility
(
ic
,
0
);
// clear utility flag
// clear
m_
utility flag
}
// find arcs and replace them
bool
bFound
;
int
arc_start
=
0
;
int
arc_end
=
0
;
bool
bFound
;
int
arc_start
=
0
;
int
arc_end
=
0
;
for
(
unsigned
iarc
=
0
;
iarc
<
arc_array
->
size
();
iarc
++
)
{
int
arc_xi
=
(
*
arc_array
)[
iarc
].
xi
;
...
...
@@ -649,62 +601,77 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly
=
this
;
else
poly
=
(
*
pa
)[
ip
-
1
];
int
polycount
=
poly
->
GetNumContours
();
int
polycount
=
poly
->
GetContoursCount
();
for
(
int
icont
=
0
;
icont
<
polycount
;
icont
++
)
{
int
ic_start
=
poly
->
GetContourStart
(
icont
);
int
ic_end
=
poly
->
GetContourEnd
(
icont
);
int
ic_start
=
poly
->
GetContourStart
(
icont
);
int
ic_end
=
poly
->
GetContourEnd
(
icont
);
if
(
(
ic_end
-
ic_start
)
>
n_steps
)
{
for
(
int
ic
=
ic_start
;
ic
<=
ic_end
;
ic
++
)
{
int
ic_next
=
ic
+
1
;
if
(
ic_next
>
ic_end
)
ic_next
=
ic_start
;
int
xi
=
poly
->
GetX
(
ic
);
int
yi
=
poly
->
GetY
(
ic
);
int
xi
=
poly
->
GetX
(
ic
);
int
yi
=
poly
->
GetY
(
ic
);
if
(
xi
==
arc_xi
&&
yi
==
arc_yi
)
{
// test for forward arc
int
ic2
=
ic
+
n_steps
;
if
(
ic2
>
ic_end
)
ic2
=
ic2
-
ic_end
+
ic_start
-
1
;
int
xf
=
poly
->
GetX
(
ic2
);
int
yf
=
poly
->
GetY
(
ic2
);
int
xf
=
poly
->
GetX
(
ic2
);
int
yf
=
poly
->
GetY
(
ic2
);
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
{
// arc from ic to ic2
bFound
=
true
;
arc_start
=
ic
;
arc_end
=
ic2
;
bFound
=
true
;
arc_start
=
ic
;
arc_end
=
ic2
;
}
else
{
// try reverse arc
ic2
=
ic
-
n_steps
;
if
(
ic2
<
ic_start
)
ic2
=
ic2
-
ic_start
+
ic_end
+
1
;
xf
=
poly
->
GetX
(
ic2
);
yf
=
poly
->
GetY
(
ic2
);
xf
=
poly
->
GetX
(
ic2
);
yf
=
poly
->
GetY
(
ic2
);
if
(
xf
==
arc_xf
&&
yf
==
arc_yf
)
{
// arc from ic2 to ic
bFound
=
true
;
arc_start
=
ic2
;
arc_end
=
ic
;
style
=
3
-
style
;
bFound
=
true
;
arc_start
=
ic2
;
arc_end
=
ic
;
style
=
3
-
style
;
}
}
if
(
bFound
)
{
poly
->
side_s
tyle
[
arc_start
]
=
style
;
poly
->
m_SideS
tyle
[
arc_start
]
=
style
;
// mark corners for deletion from arc_start+1 to arc_end-1
for
(
int
i
=
arc_start
+
1
;
i
!=
arc_end
;
)
{
if
(
i
>
ic_end
)
i
=
ic_start
;
poly
->
SetUtility
(
i
,
1
);
if
(
i
==
ic_end
)
i
=
ic_start
;
else
...
...
@@ -714,10 +681,12 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
break
;
}
}
if
(
bFound
)
break
;
}
}
if
(
bFound
)
break
;
}
...
...
@@ -734,6 +703,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly
=
this
;
else
poly
=
(
*
pa
)[
ip
-
1
];
for
(
int
ic
=
poly
->
GetNumCorners
()
-
1
;
ic
>=
0
;
ic
--
)
{
if
(
poly
->
GetUtility
(
ic
)
)
...
...
@@ -751,26 +721,26 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
// if sel_box = 0, don't create selection elements at all
//
// if polyline is board outline, enter with:
//
id.type = ID_BOARD
//
id.st = ID_BOARD_OUTLINE
//
id.i = 0
//
ptr = NULL
//
id.type = ID_BOARD
//
id.st = ID_BOARD_OUTLINE
//
id.i = 0
//
ptr = NULL
//
// if polyline is copper area, enter with:
//
id.type = ID_NET;
//
id.st = ID_AREA
//
id.i = index to area
//
ptr = pointer to net
//
id.type = ID_NET;
//
id.st = ID_AREA
//
id.i = index to area
//
ptr = pointer to net
//
void
CPolyLine
::
Start
(
int
layer
,
int
x
,
int
y
,
int
hatch
)
{
m_layer
=
layer
;
m_layer
=
layer
;
SetHatchStyle
(
(
enum
hatch_style
)
hatch
);
CPolyPt
poly_pt
(
x
,
y
);
poly_pt
.
end_contour
=
false
;
corner
.
push_back
(
poly_pt
);
side_s
tyle
.
push_back
(
0
);
m_CornersList
.
push_back
(
poly_pt
);
m_SideS
tyle
.
push_back
(
0
);
}
...
...
@@ -783,10 +753,12 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
poly_pt
.
end_contour
=
false
;
// add entries for new corner and side
corner
.
push_back
(
poly_pt
);
side_style
.
push_back
(
style
);
if
(
corner
.
size
()
>
0
&&
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
side_style
[
corner
.
size
()
-
1
]
=
style
;
m_CornersList
.
push_back
(
poly_pt
);
m_SideStyle
.
push_back
(
style
);
if
(
m_CornersList
.
size
()
>
0
&&
!
m_CornersList
[
m_CornersList
.
size
()
-
1
].
end_contour
)
m_SideStyle
[
m_CornersList
.
size
()
-
1
]
=
style
;
if
(
bDraw
)
Hatch
();
}
...
...
@@ -800,9 +772,11 @@ void CPolyLine::Close( int style, bool bDraw )
{
wxASSERT
(
0
);
}
UnHatch
();
side_style
[
corner
.
size
()
-
1
]
=
style
;
corner
[
corner
.
size
()
-
1
].
end_contour
=
true
;
m_SideStyle
[
m_CornersList
.
size
()
-
1
]
=
style
;
m_CornersList
[
m_CornersList
.
size
()
-
1
].
end_contour
=
true
;
if
(
bDraw
)
Hatch
();
}
...
...
@@ -813,8 +787,8 @@ void CPolyLine::Close( int style, bool bDraw )
void
CPolyLine
::
MoveCorner
(
int
ic
,
int
x
,
int
y
)
{
UnHatch
();
corner
[
ic
].
x
=
x
;
corner
[
ic
].
y
=
y
;
m_CornersList
[
ic
].
x
=
x
;
m_CornersList
[
ic
].
y
=
y
;
Hatch
();
}
...
...
@@ -824,32 +798,35 @@ void CPolyLine::MoveCorner( int ic, int x, int y )
void
CPolyLine
::
DeleteCorner
(
int
ic
,
bool
bDraw
)
{
UnHatch
();
int
icont
=
GetContour
(
ic
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
bool
bClosed
=
icont
<
GetNumContours
()
-
1
||
GetClosed
();
int
icont
=
GetContour
(
ic
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
bool
bClosed
=
icont
<
GetContoursCount
()
-
1
||
GetClosed
();
if
(
!
bClosed
)
{
// open contour, must be last contour
corner
.
erase
(
corner
.
begin
()
+
ic
);
m_CornersList
.
erase
(
m_CornersList
.
begin
()
+
ic
);
if
(
ic
!=
istart
)
side_style
.
erase
(
side_s
tyle
.
begin
()
+
ic
-
1
);
m_SideStyle
.
erase
(
m_SideS
tyle
.
begin
()
+
ic
-
1
);
}
else
{
// closed contour
corner
.
erase
(
corner
.
begin
()
+
ic
);
side_style
.
erase
(
side_style
.
begin
()
+
ic
);
m_CornersList
.
erase
(
m_CornersList
.
begin
()
+
ic
);
m_SideStyle
.
erase
(
m_SideStyle
.
begin
()
+
ic
);
if
(
ic
==
iend
)
corner
[
ic
-
1
].
end_contour
=
true
;
m_CornersList
[
ic
-
1
].
end_contour
=
true
;
}
if
(
bClosed
&&
GetContourSize
(
icont
)
<
3
)
{
// delete the entire contour
RemoveContour
(
icont
);
}
if
(
bDraw
)
Hatch
();
}
...
...
@@ -866,10 +843,11 @@ void CPolyLine::RemoveContour( int icont )
*/
{
UnHatch
();
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
polycount
=
GetContoursCount
();
int
polycount
=
GetNumContours
();
if
(
icont
==
0
&&
polycount
==
1
)
{
// remove the only contour
...
...
@@ -878,18 +856,19 @@ void CPolyLine::RemoveContour( int icont )
else
if
(
icont
==
polycount
-
1
)
{
// remove last contour
corner
.
erase
(
corner
.
begin
()
+
istart
,
corner
.
end
()
);
side_style
.
erase
(
side_style
.
begin
()
+
istart
,
side_s
tyle
.
end
()
);
m_CornersList
.
erase
(
m_CornersList
.
begin
()
+
istart
,
m_CornersList
.
end
()
);
m_SideStyle
.
erase
(
m_SideStyle
.
begin
()
+
istart
,
m_SideS
tyle
.
end
()
);
}
else
{
// remove closed contour
for
(
int
ic
=
iend
;
ic
>=
istart
;
ic
--
)
{
corner
.
erase
(
corner
.
begin
()
+
ic
);
side_style
.
erase
(
side_s
tyle
.
begin
()
+
ic
);
m_CornersList
.
erase
(
m_CornersList
.
begin
()
+
ic
);
m_SideStyle
.
erase
(
m_SideS
tyle
.
begin
()
+
ic
);
}
}
Hatch
();
}
...
...
@@ -904,65 +883,67 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance )
return
newPoly
;
}
int
polycount
=
GetNumContours
();
int
polycount
=
GetContoursCount
();
for
(
int
contour
=
0
;
contour
<
polycount
;
contour
++
)
{
unsigned
int
startIndex
=
GetContourStart
(
contour
);
unsigned
int
endIndex
=
GetContourEnd
(
contour
);
unsigned
int
startIndex
=
GetContourStart
(
contour
);
unsigned
int
endIndex
=
GetContourEnd
(
contour
);
for
(
unsigned
int
index
=
startIndex
;
index
<=
endIndex
;
index
++
)
{
int
x1
,
y1
,
nx
,
ny
;
long
long
xa
,
ya
,
xb
,
yb
;
int
x1
,
y1
,
nx
,
ny
;
long
long
xa
,
ya
,
xb
,
yb
;
x1
=
corner
[
index
].
x
;
y1
=
corner
[
index
].
y
;
x1
=
m_CornersList
[
index
].
x
;
y1
=
m_CornersList
[
index
].
y
;
if
(
index
==
startIndex
)
{
xa
=
corner
[
endIndex
].
x
-
x1
;
ya
=
corner
[
endIndex
].
y
-
y1
;
xa
=
m_CornersList
[
endIndex
].
x
-
x1
;
ya
=
m_CornersList
[
endIndex
].
y
-
y1
;
}
else
{
xa
=
corner
[
index
-
1
].
x
-
x1
;
ya
=
corner
[
index
-
1
].
y
-
y1
;
xa
=
m_CornersList
[
index
-
1
].
x
-
x1
;
ya
=
m_CornersList
[
index
-
1
].
y
-
y1
;
}
if
(
index
==
endIndex
)
{
xb
=
corner
[
startIndex
].
x
-
x1
;
yb
=
corner
[
startIndex
].
y
-
y1
;
xb
=
m_CornersList
[
startIndex
].
x
-
x1
;
yb
=
m_CornersList
[
startIndex
].
y
-
y1
;
}
else
{
xb
=
corner
[
index
+
1
].
x
-
x1
;
yb
=
corner
[
index
+
1
].
y
-
y1
;
xb
=
m_CornersList
[
index
+
1
].
x
-
x1
;
yb
=
m_CornersList
[
index
+
1
].
y
-
y1
;
}
unsigned
int
lena
=
(
unsigned
int
)
sqrt
(
(
double
)(
xa
*
xa
+
ya
*
ya
)
);
unsigned
int
lenb
=
(
unsigned
int
)
sqrt
(
(
double
)(
xb
*
xb
+
yb
*
yb
)
);
unsigned
int
distance
=
aDistance
;
unsigned
int
lena
=
(
unsigned
int
)
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
);
unsigned
int
lenb
=
(
unsigned
int
)
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
);
unsigned
int
distance
=
aDistance
;
// Chamfer one half of an edge at most
if
(
0.5
*
lena
<
distance
)
distance
=
(
unsigned
int
)
(
0.5
*
(
double
)
lena
);
if
(
0.5
*
lena
<
distance
)
distance
=
(
unsigned
int
)
(
0.5
*
(
double
)
lena
);
if
(
0.5
*
lenb
<
distance
)
distance
=
(
unsigned
int
)
(
0.5
*
(
double
)
lenb
);
if
(
0.5
*
lenb
<
distance
)
distance
=
(
unsigned
int
)
(
0.5
*
(
double
)
lenb
);
nx
=
(
int
)
(
(
double
)
(
distance
*
xa
)
/
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
)
);
ny
=
(
int
)
(
(
double
)
(
distance
*
ya
)
/
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
)
);
nx
=
(
int
)
(
(
double
)
(
distance
*
xa
)
/
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
)
);
ny
=
(
int
)
(
(
double
)
(
distance
*
ya
)
/
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
)
);
if
(
index
==
startIndex
)
newPoly
->
Start
(
GetLayer
(),
x1
+
nx
,
y1
+
ny
,
GetHatchStyle
()
);
else
newPoly
->
AppendCorner
(
x1
+
nx
,
y1
+
ny
);
nx
=
(
int
)
(
(
double
)
(
distance
*
xb
)
/
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
)
);
ny
=
(
int
)
(
(
double
)
(
distance
*
yb
)
/
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
)
);
nx
=
(
int
)
(
(
double
)
(
distance
*
xb
)
/
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
)
);
ny
=
(
int
)
(
(
double
)
(
distance
*
yb
)
/
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
)
);
newPoly
->
AppendCorner
(
x1
+
nx
,
y1
+
ny
);
}
newPoly
->
Close
();
}
...
...
@@ -980,115 +961,120 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments )
return
newPoly
;
}
int
polycount
=
GetNumContours
();
int
polycount
=
GetContoursCount
();
for
(
int
contour
=
0
;
contour
<
polycount
;
contour
++
)
{
unsigned
int
startIndex
=
GetContourStart
(
contour
);
unsigned
int
endIndex
=
GetContourEnd
(
contour
);
unsigned
int
startIndex
=
GetContourStart
(
contour
);
unsigned
int
endIndex
=
GetContourEnd
(
contour
);
for
(
unsigned
int
index
=
startIndex
;
index
<=
endIndex
;
index
++
)
{
int
x1
,
y1
;
// Current vertex
long
long
xa
,
ya
;
// Previous vertex
long
long
xb
,
yb
;
// Next vertex
double
nx
,
ny
;
int
x1
,
y1
;
// Current vertex
long
long
xa
,
ya
;
// Previous vertex
long
long
xb
,
yb
;
// Next vertex
double
nx
,
ny
;
x1
=
corner
[
index
].
x
;
y1
=
corner
[
index
].
y
;
x1
=
m_CornersList
[
index
].
x
;
y1
=
m_CornersList
[
index
].
y
;
if
(
index
==
startIndex
)
{
xa
=
corner
[
endIndex
].
x
-
x1
;
ya
=
corner
[
endIndex
].
y
-
y1
;
xa
=
m_CornersList
[
endIndex
].
x
-
x1
;
ya
=
m_CornersList
[
endIndex
].
y
-
y1
;
}
else
{
xa
=
corner
[
index
-
1
].
x
-
x1
;
ya
=
corner
[
index
-
1
].
y
-
y1
;
xa
=
m_CornersList
[
index
-
1
].
x
-
x1
;
ya
=
m_CornersList
[
index
-
1
].
y
-
y1
;
}
if
(
index
==
endIndex
)
{
xb
=
corner
[
startIndex
].
x
-
x1
;
yb
=
corner
[
startIndex
].
y
-
y1
;
xb
=
m_CornersList
[
startIndex
].
x
-
x1
;
yb
=
m_CornersList
[
startIndex
].
y
-
y1
;
}
else
{
xb
=
corner
[
index
+
1
].
x
-
x1
;
yb
=
corner
[
index
+
1
].
y
-
y1
;
xb
=
m_CornersList
[
index
+
1
].
x
-
x1
;
yb
=
m_CornersList
[
index
+
1
].
y
-
y1
;
}
double
lena
=
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
);
double
lenb
=
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
);
double
cosine
=
(
xa
*
xb
+
ya
*
yb
)
/
(
lena
*
lenb
);
double
lena
=
sqrt
(
(
double
)
(
xa
*
xa
+
ya
*
ya
)
);
double
lenb
=
sqrt
(
(
double
)
(
xb
*
xb
+
yb
*
yb
)
);
double
cosine
=
(
xa
*
xb
+
ya
*
yb
)
/
(
lena
*
lenb
);
unsigned
int
radius
=
aRadius
;
double
denom
=
sqrt
(
2.0
/
(
1
+
cosine
)
-
1
);
unsigned
int
radius
=
aRadius
;
double
denom
=
sqrt
(
2.0
/
(
1
+
cosine
)
-
1
);
// Limit rounding distance to one half of an edge
if
(
0.5
*
lena
*
denom
<
radius
)
radius
=
(
unsigned
int
)
(
0.5
*
lena
*
denom
);
if
(
0.5
*
lena
*
denom
<
radius
)
radius
=
(
unsigned
int
)
(
0.5
*
lena
*
denom
);
if
(
0.5
*
lenb
*
denom
<
radius
)
radius
=
(
unsigned
int
)
(
0.5
*
lenb
*
denom
);
if
(
0.5
*
lenb
*
denom
<
radius
)
radius
=
(
unsigned
int
)
(
0.5
*
lenb
*
denom
);
// Calculate fillet arc absolute center point (xc, yx)
double
k
=
radius
/
sqrt
(
.5
*
(
1
-
cosine
)
);
double
lenab
=
sqrt
(
(
xa
/
lena
+
xb
/
lenb
)
*
(
xa
/
lena
+
xb
/
lenb
)
+
(
ya
/
lena
+
yb
/
lenb
)
*
(
ya
/
lena
+
yb
/
lenb
)
);
double
xc
=
x1
+
k
*
(
xa
/
lena
+
xb
/
lenb
)
/
lenab
;
double
yc
=
y1
+
k
*
(
ya
/
lena
+
yb
/
lenb
)
/
lenab
;
double
k
=
radius
/
sqrt
(
.5
*
(
1
-
cosine
)
);
double
lenab
=
sqrt
(
(
xa
/
lena
+
xb
/
lenb
)
*
(
xa
/
lena
+
xb
/
lenb
)
+
(
ya
/
lena
+
yb
/
lenb
)
*
(
ya
/
lena
+
yb
/
lenb
)
);
double
xc
=
x1
+
k
*
(
xa
/
lena
+
xb
/
lenb
)
/
lenab
;
double
yc
=
y1
+
k
*
(
ya
/
lena
+
yb
/
lenb
)
/
lenab
;
// Calculate arc start and end vectors
k
=
radius
/
sqrt
(
2
/
(
1
+
cosine
)
-
1
);
double
xs
=
x1
+
k
*
xa
/
lena
-
xc
;
double
ys
=
y1
+
k
*
ya
/
lena
-
yc
;
double
xe
=
x1
+
k
*
xb
/
lenb
-
xc
;
double
ye
=
y1
+
k
*
yb
/
lenb
-
yc
;
k
=
radius
/
sqrt
(
2
/
(
1
+
cosine
)
-
1
);
double
xs
=
x1
+
k
*
xa
/
lena
-
xc
;
double
ys
=
y1
+
k
*
ya
/
lena
-
yc
;
double
xe
=
x1
+
k
*
xb
/
lenb
-
xc
;
double
ye
=
y1
+
k
*
yb
/
lenb
-
yc
;
// Cosine of arc angle
double
argument
=
(
xs
*
xe
+
ys
*
ye
)
/
(
radius
*
radius
);
double
argument
=
(
xs
*
xe
+
ys
*
ye
)
/
(
radius
*
radius
);
if
(
argument
<
-
1
)
// Just in case...
argument
=
-
1
;
else
if
(
argument
>
1
)
argument
=
1
;
double
arcAngle
=
acos
(
argument
);
double
arcAngle
=
acos
(
argument
);
// Calculate the number of segments
double
tempSegments
=
(
double
)
aSegments
*
(
arcAngle
/
(
2
*
M_PI
)
);
double
tempSegments
=
(
double
)
aSegments
*
(
arcAngle
/
(
2
*
M_PI
)
);
if
(
tempSegments
-
(
int
)
tempSegments
>
0
)
if
(
tempSegments
-
(
int
)
tempSegments
>
0
)
tempSegments
++
;
unsigned
int
segments
=
(
unsigned
int
)
tempSegments
;
double
deltaAngle
=
arcAngle
/
segments
;
double
startAngle
=
atan2
(
-
ys
,
xs
);
unsigned
int
segments
=
(
unsigned
int
)
tempSegments
;
double
deltaAngle
=
arcAngle
/
segments
;
double
startAngle
=
atan2
(
-
ys
,
xs
);
// Flip arc for inner corners
if
(
xa
*
yb
-
ya
*
xb
<=
0
)
if
(
xa
*
yb
-
ya
*
xb
<=
0
)
deltaAngle
*=
-
1
;
nx
=
xc
+
xs
+
0.5
;
ny
=
yc
+
ys
+
0.5
;
nx
=
xc
+
xs
+
0.5
;
ny
=
yc
+
ys
+
0.5
;
if
(
index
==
startIndex
)
newPoly
->
Start
(
GetLayer
(),
(
int
)
nx
,
(
int
)
ny
,
GetHatchStyle
()
);
newPoly
->
Start
(
GetLayer
(),
(
int
)
nx
,
(
int
)
ny
,
GetHatchStyle
()
);
else
newPoly
->
AppendCorner
(
(
int
)
nx
,
(
int
)
ny
);
newPoly
->
AppendCorner
(
(
int
)
nx
,
(
int
)
ny
);
unsigned
int
nVertices
=
0
;
for
(
unsigned
int
j
=
0
;
j
<
segments
;
j
++
)
{
nx
=
xc
+
cos
(
startAngle
+
(
j
+
1
)
*
deltaAngle
)
*
radius
+
0.5
;
ny
=
yc
-
sin
(
startAngle
+
(
j
+
1
)
*
deltaAngle
)
*
radius
+
0.5
;
newPoly
->
AppendCorner
(
(
int
)
nx
,
(
int
)
ny
);
nx
=
xc
+
cos
(
startAngle
+
(
j
+
1
)
*
deltaAngle
)
*
radius
+
0.5
;
ny
=
yc
-
sin
(
startAngle
+
(
j
+
1
)
*
deltaAngle
)
*
radius
+
0.5
;
newPoly
->
AppendCorner
(
(
int
)
nx
,
(
int
)
ny
);
nVertices
++
;
}
}
newPoly
->
Close
();
}
return
newPoly
;
}
...
...
@@ -1103,8 +1089,8 @@ void CPolyLine::RemoveAllContours( void )
* Others params are not chnaged
*/
{
corner
.
clear
();
side_s
tyle
.
clear
();
m_CornersList
.
clear
();
m_SideS
tyle
.
clear
();
}
...
...
@@ -1117,25 +1103,27 @@ void CPolyLine::RemoveAllContours( void )
void
CPolyLine
::
InsertCorner
(
int
ic
,
int
x
,
int
y
)
{
UnHatch
();
if
(
(
unsigned
)
(
ic
)
>=
corner
.
size
()
)
if
(
(
unsigned
)
(
ic
)
>=
m_CornersList
.
size
()
)
{
corner
.
push_back
(
CPolyPt
(
x
,
y
)
);
side_s
tyle
.
push_back
(
STRAIGHT
);
m_CornersList
.
push_back
(
CPolyPt
(
x
,
y
)
);
m_SideS
tyle
.
push_back
(
STRAIGHT
);
}
else
{
corner
.
insert
(
corner
.
begin
()
+
ic
+
1
,
CPolyPt
(
x
,
y
)
);
side_style
.
insert
(
side_s
tyle
.
begin
()
+
ic
+
1
,
STRAIGHT
);
m_CornersList
.
insert
(
m_CornersList
.
begin
()
+
ic
+
1
,
CPolyPt
(
x
,
y
)
);
m_SideStyle
.
insert
(
m_SideS
tyle
.
begin
()
+
ic
+
1
,
STRAIGHT
);
}
if
(
(
unsigned
)
(
ic
+
1
)
<
corner
.
size
()
)
if
(
(
unsigned
)
(
ic
+
1
)
<
m_CornersList
.
size
()
)
{
if
(
corner
[
ic
].
end_contour
)
if
(
m_CornersList
[
ic
].
end_contour
)
{
corner
[
ic
+
1
].
end_contour
=
true
;
corner
[
ic
].
end_contour
=
false
;
m_CornersList
[
ic
+
1
].
end_contour
=
true
;
m_CornersList
[
ic
].
end_contour
=
false
;
}
}
Hatch
();
}
...
...
@@ -1150,7 +1138,7 @@ void CPolyLine::UnHatch()
int
CPolyLine
::
GetEndContour
(
int
ic
)
{
return
corner
[
ic
].
end_contour
;
return
m_CornersList
[
ic
].
end_contour
;
}
...
...
@@ -1158,10 +1146,10 @@ CRect CPolyLine::GetBounds()
{
CRect
r
=
GetCornerBounds
();
r
.
left
-=
m_W
idth
/
2
;
r
.
right
+=
m_W
idth
/
2
;
r
.
bottom
-=
m_W
idth
/
2
;
r
.
top
+=
m_W
idth
/
2
;
r
.
left
-=
m_w
idth
/
2
;
r
.
right
+=
m_w
idth
/
2
;
r
.
bottom
-=
m_w
idth
/
2
;
r
.
top
+=
m_w
idth
/
2
;
return
r
;
}
...
...
@@ -1172,12 +1160,13 @@ CRect CPolyLine::GetCornerBounds()
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
right
=
r
.
top
=
INT_MIN
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_CornersList
.
size
();
i
++
)
{
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
r
.
left
=
min
(
r
.
left
,
m_CornersList
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
m_CornersList
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
m_CornersList
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
m_CornersList
[
i
].
y
);
}
return
r
;
...
...
@@ -1190,14 +1179,15 @@ CRect CPolyLine::GetCornerBounds( int icont )
r
.
left
=
r
.
bottom
=
INT_MAX
;
r
.
right
=
r
.
top
=
INT_MIN
;
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
for
(
int
i
=
istart
;
i
<=
iend
;
i
++
)
{
r
.
left
=
min
(
r
.
left
,
corner
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
corner
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
corner
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
corner
[
i
].
y
);
r
.
left
=
min
(
r
.
left
,
m_CornersList
[
i
].
x
);
r
.
right
=
max
(
r
.
right
,
m_CornersList
[
i
].
x
);
r
.
bottom
=
min
(
r
.
bottom
,
m_CornersList
[
i
].
y
);
r
.
top
=
max
(
r
.
top
,
m_CornersList
[
i
].
y
);
}
return
r
;
...
...
@@ -1206,32 +1196,35 @@ CRect CPolyLine::GetCornerBounds( int icont )
int
CPolyLine
::
GetNumCorners
()
{
return
corner
.
size
();
return
m_CornersList
.
size
();
}
int
CPolyLine
::
GetNumSides
()
{
if
(
GetClosed
()
)
return
corner
.
size
();
return
m_CornersList
.
size
();
else
return
corner
.
size
()
-
1
;
return
m_CornersList
.
size
()
-
1
;
}
int
CPolyLine
::
Get
NumContours
()
int
CPolyLine
::
Get
ContoursCount
()
{
int
ncont
=
0
;
if
(
!
corner
.
size
()
)
if
(
!
m_CornersList
.
size
()
)
return
0
;
for
(
unsigned
ic
=
0
;
ic
<
corner
.
size
();
ic
++
)
if
(
corner
[
ic
].
end_contour
)
for
(
unsigned
ic
=
0
;
ic
<
m_CornersList
.
size
();
ic
++
)
if
(
m_CornersList
[
ic
].
end_contour
)
ncont
++
;
if
(
!
corner
[
corner
.
size
()
-
1
].
end_contour
)
if
(
!
m_CornersList
[
m_CornersList
.
size
()
-
1
].
end_contour
)
ncont
++
;
return
ncont
;
}
...
...
@@ -1242,7 +1235,7 @@ int CPolyLine::GetContour( int ic )
for
(
int
i
=
0
;
i
<
ic
;
i
++
)
{
if
(
corner
[
i
].
end_contour
)
if
(
m_CornersList
[
i
].
end_contour
)
ncont
++
;
}
...
...
@@ -1256,11 +1249,13 @@ int CPolyLine::GetContourStart( int icont )
return
0
;
int
ncont
=
0
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_CornersList
.
size
();
i
++
)
{
if
(
corner
[
i
].
end_contour
)
if
(
m_CornersList
[
i
].
end_contour
)
{
ncont
++
;
if
(
ncont
==
icont
)
return
i
+
1
;
}
...
...
@@ -1276,16 +1271,18 @@ int CPolyLine::GetContourEnd( int icont )
if
(
icont
<
0
)
return
0
;
if
(
icont
==
Get
NumContours
()
-
1
)
return
corner
.
size
()
-
1
;
if
(
icont
==
Get
ContoursCount
()
-
1
)
return
m_CornersList
.
size
()
-
1
;
int
ncont
=
0
;
for
(
unsigned
i
=
0
;
i
<
corner
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_CornersList
.
size
();
i
++
)
{
if
(
corner
[
i
].
end_contour
)
if
(
m_CornersList
[
i
].
end_contour
)
{
if
(
ncont
==
icont
)
return
i
;
ncont
++
;
}
}
...
...
@@ -1305,50 +1302,55 @@ void CPolyLine::SetSideStyle( int is, int style )
{
UnHatch
();
wxPoint
p1
,
p2
;
if
(
is
==
(
int
)
(
corner
.
size
()
-
1
)
)
if
(
is
==
(
int
)
(
m_CornersList
.
size
()
-
1
)
)
{
p1
.
x
=
corner
[
corner
.
size
()
-
1
].
x
;
p1
.
y
=
corner
[
corner
.
size
()
-
1
].
y
;
p2
.
x
=
corner
[
0
].
x
;
p2
.
y
=
corner
[
0
].
y
;
p1
.
x
=
m_CornersList
[
m_CornersList
.
size
()
-
1
].
x
;
p1
.
y
=
m_CornersList
[
m_CornersList
.
size
()
-
1
].
y
;
p2
.
x
=
m_CornersList
[
0
].
x
;
p2
.
y
=
m_CornersList
[
0
].
y
;
}
else
{
p1
.
x
=
corner
[
is
].
x
;
p1
.
y
=
corner
[
is
].
y
;
p2
.
x
=
corner
[
is
+
1
].
x
;
p2
.
y
=
corner
[
is
+
1
].
y
;
p1
.
x
=
m_CornersList
[
is
].
x
;
p1
.
y
=
m_CornersList
[
is
].
y
;
p2
.
x
=
m_CornersList
[
is
+
1
].
x
;
p2
.
y
=
m_CornersList
[
is
+
1
].
y
;
}
if
(
p1
.
x
==
p2
.
x
||
p1
.
y
==
p2
.
y
)
side_s
tyle
[
is
]
=
STRAIGHT
;
m_SideS
tyle
[
is
]
=
STRAIGHT
;
else
side_style
[
is
]
=
style
;
m_SideStyle
[
is
]
=
style
;
Hatch
();
}
int
CPolyLine
::
GetSideStyle
(
int
is
)
{
return
side_s
tyle
[
is
];
return
m_SideS
tyle
[
is
];
}
int
CPolyLine
::
GetClosed
()
{
if
(
corner
.
size
()
==
0
)
if
(
m_CornersList
.
size
()
==
0
)
return
0
;
else
return
corner
[
corner
.
size
()
-
1
].
end_contour
;
return
m_CornersList
[
m_CornersList
.
size
()
-
1
].
end_contour
;
}
// Creates hatch lines inside the outline of the complex polygon
//
// sort function used in ::Hatch to sort points by descending wxPoint.x values
bool
sort_ends_by_descending_X
(
const
wxPoint
&
ref
,
const
wxPoint
&
tst
)
bool
sort_ends_by_descending_X
(
const
wxPoint
&
ref
,
const
wxPoint
&
tst
)
{
return
tst
.
x
<
ref
.
x
;
}
void
CPolyLine
::
Hatch
()
{
m_HatchLines
.
clear
();
...
...
@@ -1356,51 +1358,58 @@ void CPolyLine::Hatch()
if
(
m_hatchStyle
==
NO_HATCH
||
m_hatchPitch
==
0
)
return
;
if
(
!
GetClosed
()
)
// If not closed, the poly is beeing created and not finalised. Not not hatch
if
(
!
GetClosed
()
)
// If not closed, the poly is beeing created and not finalised. Not not hatch
return
;
// define range for hatch lines
int
min_x
=
corner
[
0
].
x
;
int
max_x
=
corner
[
0
].
x
;
int
min_y
=
corner
[
0
].
y
;
int
max_y
=
corner
[
0
].
y
;
for
(
unsigned
ic
=
1
;
ic
<
corner
.
size
();
ic
++
)
int
min_x
=
m_CornersList
[
0
].
x
;
int
max_x
=
m_CornersList
[
0
].
x
;
int
min_y
=
m_CornersList
[
0
].
y
;
int
max_y
=
m_CornersList
[
0
].
y
;
for
(
unsigned
ic
=
1
;
ic
<
m_CornersList
.
size
();
ic
++
)
{
if
(
corner
[
ic
].
x
<
min_x
)
min_x
=
corner
[
ic
].
x
;
if
(
corner
[
ic
].
x
>
max_x
)
max_x
=
corner
[
ic
].
x
;
if
(
corner
[
ic
].
y
<
min_y
)
min_y
=
corner
[
ic
].
y
;
if
(
corner
[
ic
].
y
>
max_y
)
max_y
=
corner
[
ic
].
y
;
if
(
m_CornersList
[
ic
].
x
<
min_x
)
min_x
=
m_CornersList
[
ic
].
x
;
if
(
m_CornersList
[
ic
].
x
>
max_x
)
max_x
=
m_CornersList
[
ic
].
x
;
if
(
m_CornersList
[
ic
].
y
<
min_y
)
min_y
=
m_CornersList
[
ic
].
y
;
if
(
m_CornersList
[
ic
].
y
>
max_y
)
max_y
=
m_CornersList
[
ic
].
y
;
}
// Calculate spacing betwwen 2 hatch lines
int
spacing
;
int
spacing
;
if
(
m_hatchStyle
==
DIAGONAL_EDGE
)
spacing
=
m_hatchPitch
;
else
spacing
=
m_hatchPitch
*
2
;
// set the "lenght" of hatch lines (the lenght on horizontal axis)
double
hatch_line_len
=
m_hatchPitch
;
double
hatch_line_len
=
m_hatchPitch
;
// To have a better look, give a slope depending on the layer
int
layer
=
GetLayer
();
int
slope_flag
=
(
layer
&
1
)
?
1
:
-
1
;
// 1 or -1
double
slope
=
0.707106
*
slope_flag
;
// 45 degrees slope
int
max_a
,
min_a
;
int
layer
=
GetLayer
();
int
slope_flag
=
(
layer
&
1
)
?
1
:
-
1
;
// 1 or -1
double
slope
=
0.707106
*
slope_flag
;
// 45 degrees slope
int
max_a
,
min_a
;
if
(
slope_flag
==
1
)
{
max_a
=
(
int
)
(
max_y
-
slope
*
min_x
);
min_a
=
(
int
)
(
min_y
-
slope
*
max_x
);
max_a
=
(
int
)
(
max_y
-
slope
*
min_x
);
min_a
=
(
int
)
(
min_y
-
slope
*
max_x
);
}
else
{
max_a
=
(
int
)
(
max_y
-
slope
*
max_x
);
min_a
=
(
int
)
(
min_y
-
slope
*
min_x
);
max_a
=
(
int
)
(
max_y
-
slope
*
max_x
);
min_a
=
(
int
)
(
min_y
-
slope
*
min_x
);
}
min_a
=
(
min_a
/
spacing
)
*
spacing
;
// calculate an offset depending on layer number,
...
...
@@ -1409,7 +1418,7 @@ void CPolyLine::Hatch()
min_a
+=
offset
;
// now calculate and draw hatch lines
int
nc
=
corner
.
size
();
int
nc
=
m_CornersList
.
size
();
// loop through hatch lines
#define MAXPTS 200 // Usually we store only few values per one hatch line
...
...
@@ -1417,7 +1426,7 @@ void CPolyLine::Hatch()
static
std
::
vector
<
wxPoint
>
pointbuffer
;
pointbuffer
.
clear
();
pointbuffer
.
reserve
(
MAXPTS
+
2
);
pointbuffer
.
reserve
(
MAXPTS
+
2
);
for
(
int
a
=
min_a
;
a
<
max_a
;
a
+=
spacing
)
{
...
...
@@ -1429,38 +1438,43 @@ void CPolyLine::Hatch()
// we skip this line (should not occur)
pointbuffer
.
clear
();
int
i_start_contour
=
0
;
for
(
int
ic
=
0
;
ic
<
nc
;
ic
++
)
{
double
x
,
y
,
x2
,
y2
;
int
ok
;
if
(
corner
[
ic
].
end_contour
||
(
ic
==
(
int
)
(
corner
.
size
()
-
1
)
)
)
double
x
,
y
,
x2
,
y2
;
int
ok
;
if
(
m_CornersList
[
ic
].
end_contour
||
(
ic
==
(
int
)
(
m_CornersList
.
size
()
-
1
)
)
)
{
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
i_start_contour
].
x
,
corner
[
i_start_contour
].
y
,
side_s
tyle
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
m_CornersList
[
ic
].
x
,
m_CornersList
[
ic
].
y
,
m_CornersList
[
i_start_contour
].
x
,
m_CornersList
[
i_start_contour
].
y
,
m_SideS
tyle
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
i_start_contour
=
ic
+
1
;
}
else
{
ok
=
FindLineSegmentIntersection
(
a
,
slope
,
corner
[
ic
].
x
,
corner
[
ic
].
y
,
corner
[
ic
+
1
].
x
,
corner
[
ic
+
1
].
y
,
side_s
tyle
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
m_CornersList
[
ic
].
x
,
m_CornersList
[
ic
].
y
,
m_CornersList
[
ic
+
1
].
x
,
m_CornersList
[
ic
+
1
].
y
,
m_SideS
tyle
[
ic
],
&
x
,
&
y
,
&
x2
,
&
y2
);
}
if
(
ok
)
{
wxPoint
point
(
(
int
)
x
,
(
int
)
y
);
wxPoint
point
(
(
int
)
x
,
(
int
)
y
);
pointbuffer
.
push_back
(
point
);
}
if
(
ok
==
2
)
{
wxPoint
point
(
(
int
)
x2
,
(
int
)
y2
);
wxPoint
point
(
(
int
)
x2
,
(
int
)
y2
);
pointbuffer
.
push_back
(
point
);
}
if
(
pointbuffer
.
size
()
>=
MAXPTS
)
// overflow
{
wxASSERT
(
0
);
...
...
@@ -1485,6 +1499,7 @@ void CPolyLine::Hatch()
for
(
unsigned
ip
=
0
;
ip
<
pointbuffer
.
size
();
ip
+=
2
)
{
double
dx
=
pointbuffer
[
ip
+
1
].
x
-
pointbuffer
[
ip
].
x
;
// Push only one line for diagonal hatch,
// or for small lines < twice the line len
// else push 2 small lines
...
...
@@ -1494,18 +1509,18 @@ void CPolyLine::Hatch()
}
else
{
double
dy
=
pointbuffer
[
ip
+
1
].
y
-
pointbuffer
[
ip
].
y
;
double
slope
=
dy
/
dx
;
double
dy
=
pointbuffer
[
ip
+
1
].
y
-
pointbuffer
[
ip
].
y
;
double
slope
=
dy
/
dx
;
if
(
dx
>
0
)
dx
=
hatch_line_len
;
else
dx
=
-
hatch_line_len
;
double
x1
=
pointbuffer
[
ip
].
x
+
dx
;
double
x2
=
pointbuffer
[
ip
+
1
].
x
-
dx
;
double
y1
=
pointbuffer
[
ip
].
y
+
dx
*
slope
;
double
y2
=
pointbuffer
[
ip
+
1
].
y
-
dx
*
slope
;
double
x1
=
pointbuffer
[
ip
].
x
+
dx
;
double
x2
=
pointbuffer
[
ip
+
1
].
x
-
dx
;
double
y1
=
pointbuffer
[
ip
].
y
+
dx
*
slope
;
double
y2
=
pointbuffer
[
ip
+
1
].
y
-
dx
*
slope
;
m_HatchLines
.
push_back
(
CSegment
(
pointbuffer
[
ip
].
x
,
pointbuffer
[
ip
].
y
,
...
...
@@ -1534,32 +1549,34 @@ bool CPolyLine::TestPointInside( int px, int py )
// if the tested point is inside only one contour, it is inside the whole polygon
// (in fact inside the main outline, and outside all holes).
// if inside 2 contours (the main outline + an hole), it is outside the poly.
int
polycount
=
GetNumContours
();
bool
inside
=
false
;
int
polycount
=
GetContoursCount
();
bool
inside
=
false
;
for
(
int
icont
=
0
;
icont
<
polycount
;
icont
++
)
{
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
int
istart
=
GetContourStart
(
icont
);
int
iend
=
GetContourEnd
(
icont
);
// Test this polygon:
if
(
TestPointInsidePolygon
(
corner
,
istart
,
iend
,
px
,
py
)
)
// test point inside the current polygon
if
(
TestPointInsidePolygon
(
m_CornersList
,
istart
,
iend
,
px
,
py
)
)
// test point inside the current polygon
inside
=
not
inside
;
}
return
inside
;
}
// copy data from another poly, but don't draw it
//
void
CPolyLine
::
Copy
(
CPolyLine
*
src
)
{
UnHatch
();
m_hatchStyle
=
src
->
m_hatchStyle
;
m_hatchPitch
=
src
->
m_hatchPitch
;
m_hatchStyle
=
src
->
m_hatchStyle
;
m_hatchPitch
=
src
->
m_hatchPitch
;
// copy corners, using vector copy
corner
=
src
->
corner
;
m_CornersList
=
src
->
m_CornersList
;
// copy side styles, using vector copy
side_style
=
src
->
side_s
tyle
;
m_SideStyle
=
src
->
m_SideS
tyle
;
}
...
...
@@ -1573,8 +1590,9 @@ bool CPolyLine::IsCutoutContour( int icont )
{
int
ncont
=
GetContour
(
icont
);
if
(
ncont
==
0
)
// the first contour is the main outline, not an hole
if
(
ncont
==
0
)
// the first contour is the main outline, not an hole
return
false
;
return
true
;
}
...
...
@@ -1582,6 +1600,7 @@ bool CPolyLine::IsCutoutContour( int icont )
void
CPolyLine
::
MoveOrigin
(
int
x_off
,
int
y_off
)
{
UnHatch
();
for
(
int
ic
=
0
;
ic
<
GetNumCorners
();
ic
++
)
{
SetX
(
ic
,
GetX
(
ic
)
+
x_off
);
...
...
@@ -1593,43 +1612,43 @@ void CPolyLine::MoveOrigin( int x_off, int y_off )
// Set various parameters:
//
the calling function should UnHatch() before calling them,
//
and Draw() after
// the calling function should UnHatch() before calling them,
// and Draw() after
//
void
CPolyLine
::
SetX
(
int
ic
,
int
x
)
{
corner
[
ic
].
x
=
x
;
m_CornersList
[
ic
].
x
=
x
;
}
void
CPolyLine
::
SetY
(
int
ic
,
int
y
)
{
corner
[
ic
].
y
=
y
;
m_CornersList
[
ic
].
y
=
y
;
}
void
CPolyLine
::
SetEndContour
(
int
ic
,
bool
end_contour
)
{
corner
[
ic
].
end_contour
=
end_contour
;
m_CornersList
[
ic
].
end_contour
=
end_contour
;
}
void
CPolyLine
::
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
)
{
// get radius
double
r
=
sqrt
(
(
double
)
(
xi
-
xc
)
*
(
xi
-
xc
)
+
(
double
)
(
yi
-
yc
)
*
(
yi
-
yc
)
);
double
r
=
sqrt
(
(
double
)
(
xi
-
xc
)
*
(
xi
-
xc
)
+
(
double
)
(
yi
-
yc
)
*
(
yi
-
yc
)
);
// get angles of start and finish
double
th_i
=
atan2
(
(
double
)
(
yi
-
yc
),
(
double
)
(
xi
-
xc
)
);
double
th_f
=
atan2
(
(
double
)
(
yf
-
yc
),
(
double
)
(
xf
-
xc
)
);
double
th_d
=
(
th_f
-
th_i
)
/
(
num
-
1
);
double
theta
=
th_i
;
double
th_i
=
atan2
(
(
double
)
(
yi
-
yc
),
(
double
)
(
xi
-
xc
)
);
double
th_f
=
atan2
(
(
double
)
(
yf
-
yc
),
(
double
)
(
xf
-
xc
)
);
double
th_d
=
(
th_f
-
th_i
)
/
(
num
-
1
);
double
theta
=
th_i
;
// generate arc
for
(
int
ic
=
0
;
ic
<
num
;
ic
++
)
{
int
x
=
KiROUND
(
xc
+
r
*
cos
(
theta
)
);
int
y
=
KiROUND
(
yc
+
r
*
sin
(
theta
)
);
int
x
=
KiROUND
(
xc
+
r
*
cos
(
theta
)
);
int
y
=
KiROUND
(
yc
+
r
*
sin
(
theta
)
);
AppendCorner
(
x
,
y
,
STRAIGHT
,
0
);
theta
+=
th_d
;
}
...
...
@@ -1637,23 +1656,27 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
Close
(
STRAIGHT
);
}
// Bezier Support
void
CPolyLine
::
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
)
void
CPolyLine
::
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
)
{
std
::
vector
<
wxPoint
>
bezier_points
;
bezier_points
=
Bezier2Poly
(
x1
,
y1
,
x2
,
y2
,
x3
,
y3
);
for
(
unsigned
int
i
=
0
;
i
<
bezier_points
.
size
()
;
i
++
)
AppendCorner
(
bezier_points
[
i
].
x
,
bezier_points
[
i
].
y
);
bezier_points
=
Bezier2Poly
(
x1
,
y1
,
x2
,
y2
,
x3
,
y3
);
for
(
unsigned
int
i
=
0
;
i
<
bezier_points
.
size
();
i
++
)
AppendCorner
(
bezier_points
[
i
].
x
,
bezier_points
[
i
].
y
);
}
void
CPolyLine
::
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
,
int
x4
,
int
y4
)
void
CPolyLine
::
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
,
int
x4
,
int
y4
)
{
std
::
vector
<
wxPoint
>
bezier_points
;
bezier_points
=
Bezier2Poly
(
x1
,
y1
,
x2
,
y2
,
x3
,
y3
,
x4
,
y4
);
for
(
unsigned
int
i
=
0
;
i
<
bezier_points
.
size
()
;
i
++
)
AppendCorner
(
bezier_points
[
i
].
x
,
bezier_points
[
i
].
y
);
bezier_points
=
Bezier2Poly
(
x1
,
y1
,
x2
,
y2
,
x3
,
y3
,
x4
,
y4
);
for
(
unsigned
int
i
=
0
;
i
<
bezier_points
.
size
();
i
++
)
AppendCorner
(
bezier_points
[
i
].
x
,
bezier_points
[
i
].
y
);
}
...
...
@@ -1675,13 +1698,13 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
if
(
TestPointInside
(
aStart
.
x
,
aStart
.
y
)
)
return
0
;
int
distance
=
INT_MAX
;
int
polycount
=
GetNumContours
();
int
distance
=
INT_MAX
;
int
polycount
=
GetContoursCount
();
for
(
int
icont
=
0
;
icont
<
polycount
;
icont
++
)
{
int
ic_start
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
int
ic_start
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
// now test spacing between area outline and segment
for
(
int
ic2
=
ic_start
;
ic2
<=
ic_end
;
ic2
++
)
...
...
@@ -1705,10 +1728,12 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
int
d
=
GetClearanceBetweenSegments
(
bx1
,
by1
,
bx2
,
by2
,
bstyle
,
0
,
aStart
.
x
,
aStart
.
y
,
aEnd
.
x
,
aEnd
.
y
,
CPolyLine
::
STRAIGHT
,
aWidth
,
1
,
// min clearance, should be > 0
1
,
// min clearance, should be > 0
NULL
,
NULL
);
if
(
distance
>
d
)
distance
=
d
;
if
(
distance
<=
0
)
return
0
;
}
...
...
@@ -1717,6 +1742,7 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth )
return
distance
;
}
/*
* Function Distance
* Calculates the distance between a point and polygon (with holes):
...
...
@@ -1731,13 +1757,13 @@ int CPolyLine::Distance( const wxPoint& aPoint )
if
(
TestPointInside
(
aPoint
.
x
,
aPoint
.
y
)
)
return
0
;
int
distance
=
INT_MAX
;
int
polycount
=
GetNumContours
();
int
distance
=
INT_MAX
;
int
polycount
=
GetContoursCount
();
for
(
int
icont
=
0
;
icont
<
polycount
;
icont
++
)
{
int
ic_start
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
int
ic_start
=
GetContourStart
(
icont
);
int
ic_end
=
GetContourEnd
(
icont
);
// now test spacing between area outline and segment
for
(
int
ic2
=
ic_start
;
ic2
<=
ic_end
;
ic2
++
)
...
...
@@ -1760,11 +1786,12 @@ int CPolyLine::Distance( const wxPoint& aPoint )
// Here we expect only straight lines for vertices
// (no arcs, not yet supported in Pcbnew)
int
d
=
KiROUND
(
GetPointToLineSegmentDistance
(
aPoint
.
x
,
aPoint
.
y
,
bx1
,
by1
,
bx2
,
by2
)
);
bx1
,
by1
,
bx2
,
by2
)
);
if
(
distance
>
d
)
distance
=
d
;
if
(
distance
<=
0
)
return
0
;
}
...
...
@@ -1772,3 +1799,152 @@ int CPolyLine::Distance( const wxPoint& aPoint )
return
distance
;
}
/**
* Function CopyPolysListToKiPolygonWithHole
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
*
* @param aPolysList = the list of corners of contours
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
*/
void
CopyPolysListToKiPolygonWithHole
(
const
std
::
vector
<
CPolyPt
>&
aPolysList
,
KI_POLYGON_WITH_HOLES
&
aPolygoneWithHole
)
{
unsigned
corners_count
=
aPolysList
.
size
();
std
::
vector
<
KI_POLY_POINT
>
cornerslist
;
KI_POLYGON
poly
;
// Enter main outline: this is the first contour
unsigned
ic
=
0
;
while
(
ic
<
corners_count
)
{
const
CPolyPt
&
corner
=
aPolysList
[
ic
++
];
cornerslist
.
push_back
(
KI_POLY_POINT
(
corner
.
x
,
corner
.
y
)
);
if
(
corner
.
end_contour
)
break
;
}
aPolygoneWithHole
.
set
(
cornerslist
.
begin
(),
cornerslist
.
end
()
);
// Enter holes: they are next contours (when exist)
if
(
ic
<
corners_count
)
{
KI_POLYGON_SET
holePolyList
;
while
(
ic
<
corners_count
)
{
cornerslist
.
clear
();
while
(
ic
<
corners_count
)
{
const
CPolyPt
&
corner
=
aPolysList
[
ic
++
];
cornerslist
.
push_back
(
KI_POLY_POINT
(
corner
.
x
,
corner
.
y
)
);
if
(
corner
.
end_contour
)
break
;
}
bpl
::
set_points
(
poly
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
holePolyList
.
push_back
(
poly
);
}
aPolygoneWithHole
.
set_holes
(
holePolyList
.
begin
(),
holePolyList
.
end
()
);
}
}
/**
* Function ConvertPolysListWithHolesToOnePolygon
* converts the outline contours aPolysListWithHoles with holes to one polygon
* with no holes (only one contour)
* holes are linked to main outlines by overlap segments, to give only one polygon
*
* @param aPolysListWithHoles = the list of corners of contours (haing holes
* @param aOnePolyList = a polygon with no holes
*/
void
ConvertPolysListWithHolesToOnePolygon
(
const
std
::
vector
<
CPolyPt
>&
aPolysListWithHoles
,
std
::
vector
<
CPolyPt
>&
aOnePolyList
)
{
unsigned
corners_count
=
aPolysListWithHoles
.
size
();
int
polycount
=
0
;
for
(
unsigned
ii
=
0
;
ii
<
corners_count
;
ii
++
)
{
const
CPolyPt
&
corner
=
aPolysListWithHoles
[
ii
];
if
(
corner
.
end_contour
)
polycount
++
;
}
// If polycount<= 1, there is no holes found.
if
(
polycount
<=
1
)
{
aOnePolyList
=
aPolysListWithHoles
;
return
;
}
// Holes are found: convert them to only one polygon with overlap segments
KI_POLYGON_SET
polysholes
;
KI_POLYGON_SET
mainpoly
;
KI_POLYGON
poly_tmp
;
std
::
vector
<
KI_POLY_POINT
>
cornerslist
;
corners_count
=
aPolysListWithHoles
.
size
();
unsigned
ic
=
0
;
// enter main outline
while
(
ic
<
corners_count
)
{
const
CPolyPt
&
corner
=
aPolysListWithHoles
[
ic
++
];
cornerslist
.
push_back
(
KI_POLY_POINT
(
corner
.
x
,
corner
.
y
)
);
if
(
corner
.
end_contour
)
break
;
}
bpl
::
set_points
(
poly_tmp
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
mainpoly
.
push_back
(
poly_tmp
);
while
(
ic
<
corners_count
)
{
cornerslist
.
clear
();
{
while
(
ic
<
corners_count
)
{
const
CPolyPt
&
corner
=
aPolysListWithHoles
[
ic
++
];
cornerslist
.
push_back
(
KI_POLY_POINT
(
corner
.
x
,
corner
.
y
)
);
if
(
corner
.
end_contour
)
break
;
}
bpl
::
set_points
(
poly_tmp
,
cornerslist
.
begin
(),
cornerslist
.
end
()
);
polysholes
.
push_back
(
poly_tmp
);
}
}
mainpoly
-=
polysholes
;
// copy polygon with no holes to destination
// 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
.
push_back
(
corner
);
}
corner
.
end_contour
=
true
;
aOnePolyList
.
pop_back
();
aOnePolyList
.
push_back
(
corner
);
}
}
polygon/PolyLine.h
View file @
1c9433fb
...
...
@@ -19,11 +19,12 @@
#include <kbool/include/kbool/booleng.h>
#include <pad_shapes.h>
#include <wx/gdicmn.h>
#include <wx/gdicmn.h> // for wxPoint definition
#include <polygons_defs.h>
// inflection modes for DS_LINE and DS_LINE_VERTEX, used in math_for_graphics.cpp
enum
{
enum
{
IM_NONE
=
0
,
IM_90_45
,
IM_45_90
,
...
...
@@ -31,18 +32,6 @@ enum
};
/**
* Function ArmBoolEng
* Initialise parameters used in kbool
* @param aBooleng = pointer to the Bool_Engine to initialise
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
*/
void
ArmBoolEng
(
Bool_Engine
*
aBooleng
,
bool
aConvertHoles
=
false
);
class
CRect
{
public
:
...
...
@@ -56,15 +45,16 @@ public:
wxPoint
m_End
;
CSegment
()
{
};
CSegment
(
const
wxPoint
&
aStart
,
const
wxPoint
&
aEnd
)
CSegment
(
const
wxPoint
&
aStart
,
const
wxPoint
&
aEnd
)
{
m_Start
=
aStart
;
m_End
=
aEnd
;
m_End
=
aEnd
;
}
CSegment
(
int
x0
,
int
y0
,
int
x1
,
int
y1
)
{
m_Start
.
x
=
x0
;
m_Start
.
y
=
y0
;
m_End
.
x
=
x1
;
m_End
.
y
=
y1
;
m_Start
.
x
=
x0
;
m_Start
.
y
=
y0
;
m_End
.
x
=
x1
;
m_End
.
y
=
y1
;
}
};
...
...
@@ -75,10 +65,10 @@ class CArc
{
public
:
enum
{
ARC_STEPS
=
16
};
// arc approximation step is 16 segm / 90 degres
int
style
;
int
xi
,
yi
,
xf
,
yf
;
int
n_steps
;
// number of straight-line segments in gpc_poly
bool
bFound
;
int
style
;
int
xi
,
yi
,
xf
,
yf
;
int
n_steps
;
// number of straight-line segments in gpc_poly
bool
bFound
;
};
...
...
@@ -86,27 +76,27 @@ class CPolyPt : public wxPoint
{
public
:
CPolyPt
(
int
aX
=
0
,
int
aY
=
0
,
bool
aEnd
=
false
,
int
aUtility
=
0
)
:
wxPoint
(
aX
,
aY
),
end_contour
(
aEnd
),
utility
(
aUtility
)
wxPoint
(
aX
,
aY
),
end_contour
(
aEnd
),
m_
utility
(
aUtility
)
{}
/// Pure copy constructor is here to dis-ambiguate from the
/// specialized CPolyPt( const wxPoint& ) constructor version below.
//
/ Pure copy constructor is here to dis-ambiguate from the
//
/ specialized CPolyPt( const wxPoint& ) constructor version below.
CPolyPt
(
const
CPolyPt
&
aPt
)
:
wxPoint
(
aPt
.
x
,
aPt
.
y
),
end_contour
(
aPt
.
end_contour
),
utility
(
aPt
.
utility
)
wxPoint
(
aPt
.
x
,
aPt
.
y
),
end_contour
(
aPt
.
end_contour
),
m_utility
(
aPt
.
m_
utility
)
{}
CPolyPt
(
const
wxPoint
&
aPoint
)
:
wxPoint
(
aPoint
),
end_contour
(
false
),
utility
(
0
)
wxPoint
(
aPoint
),
end_contour
(
false
),
m_
utility
(
0
)
{}
bool
end_contour
;
int
utility
;
bool
end_contour
;
int
m_
utility
;
bool
operator
==
(
const
CPolyPt
&
cpt2
)
const
bool
operator
==
(
const
CPolyPt
&
cpt2
)
const
{
return
(
x
==
cpt2
.
x
)
&&
(
y
==
cpt2
.
y
)
&&
(
end_contour
==
cpt2
.
end_contour
);
}
bool
operator
!=
(
CPolyPt
&
cpt2
)
const
bool
operator
!=
(
CPolyPt
&
cpt2
)
const
{
return
(
x
!=
cpt2
.
x
)
||
(
y
!=
cpt2
.
y
)
||
(
end_contour
!=
cpt2
.
end_contour
);
}
};
...
...
@@ -116,7 +106,7 @@ public:
class
CPolyLine
{
public
:
enum
side_s
tyle
{
STRAIGHT
,
ARC_CW
,
ARC_CCW
};
// side styles
enum
m_SideS
tyle
{
STRAIGHT
,
ARC_CW
,
ARC_CCW
};
// side styles
enum
hatch_style
{
NO_HATCH
,
DIAGONAL_FULL
,
DIAGONAL_EDGE
};
// hatch styles
// constructors/destructor
...
...
@@ -124,13 +114,13 @@ public:
~
CPolyLine
();
// functions for modifying polyline
void
Start
(
int
layer
,
int
x
,
int
y
,
int
hatch
);
void
AppendCorner
(
int
x
,
int
y
,
int
style
=
STRAIGHT
,
bool
bDraw
=
false
);
void
InsertCorner
(
int
ic
,
int
x
,
int
y
);
void
DeleteCorner
(
int
ic
,
bool
bDraw
=
false
);
void
MoveCorner
(
int
ic
,
int
x
,
int
y
);
void
Close
(
int
style
=
STRAIGHT
,
bool
bDraw
=
false
);
void
RemoveContour
(
int
icont
);
void
Start
(
int
layer
,
int
x
,
int
y
,
int
hatch
);
void
AppendCorner
(
int
x
,
int
y
,
int
style
=
STRAIGHT
,
bool
bDraw
=
false
);
void
InsertCorner
(
int
ic
,
int
x
,
int
y
);
void
DeleteCorner
(
int
ic
,
bool
bDraw
=
false
);
void
MoveCorner
(
int
ic
,
int
x
,
int
y
);
void
Close
(
int
style
=
STRAIGHT
,
bool
bDraw
=
false
);
void
RemoveContour
(
int
icont
);
/**
* Function Chamfer
...
...
@@ -138,7 +128,7 @@ public:
* @param aDistance is the chamfering distance.
* @return CPolyLine* - Pointer to new polygon.
*/
CPolyLine
*
Chamfer
(
unsigned
int
aDistance
);
CPolyLine
*
Chamfer
(
unsigned
int
aDistance
);
/**
* Function Fillet
...
...
@@ -147,108 +137,88 @@ public:
* @param aSegments is the number of segments / fillet.
* @return CPolyLine* - Pointer to new polygon.
*/
CPolyLine
*
Fillet
(
unsigned
int
aRadius
,
unsigned
int
aSegments
);
CPolyLine
*
Fillet
(
unsigned
int
aRadius
,
unsigned
int
aSegments
);
void
RemoveAllContours
(
void
);
void
RemoveAllContours
(
void
);
// Remove or create hatch
void
UnHatch
();
void
Hatch
();
void
UnHatch
();
void
Hatch
();
// Transform functions
void
MoveOrigin
(
int
x_off
,
int
y_off
);
void
MoveOrigin
(
int
x_off
,
int
y_off
);
// misc. functions
CRect
GetBounds
();
CRect
GetCornerBounds
();
CRect
GetCornerBounds
(
int
icont
);
void
Copy
(
CPolyLine
*
src
);
bool
TestPointInside
(
int
x
,
int
y
);
bool
IsCutoutContour
(
int
icont
);
void
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
);
CRect
GetBounds
();
CRect
GetCornerBounds
();
CRect
GetCornerBounds
(
int
icont
);
void
Copy
(
CPolyLine
*
src
);
bool
TestPointInside
(
int
x
,
int
y
);
bool
IsCutoutContour
(
int
icont
);
void
AppendArc
(
int
xi
,
int
yi
,
int
xf
,
int
yf
,
int
xc
,
int
yc
,
int
num
);
// access functions
void
SetLayer
(
int
aLayer
)
{
m_layer
=
aLayer
;
}
int
GetLayer
()
{
return
m_layer
;
}
int
GetNumCorners
();
int
GetNumSides
();
int
GetClosed
();
int
GetNumContours
();
int
GetContour
(
int
ic
);
int
GetContourStart
(
int
icont
);
int
GetContourEnd
(
int
icont
);
int
GetContourSize
(
int
icont
);
int
GetNumCorners
();
int
GetNumSides
();
int
GetClosed
();
int
GetContoursCount
();
int
GetContour
(
int
ic
);
int
GetContourStart
(
int
icont
);
int
GetContourEnd
(
int
icont
);
int
GetContourSize
(
int
icont
);
int
GetX
(
int
ic
)
const
{
return
m_CornersList
[
ic
].
x
;
}
int
GetY
(
int
ic
)
const
{
return
m_CornersList
[
ic
].
y
;
}
int
GetX
(
int
ic
)
const
{
return
corner
[
ic
].
x
;
}
int
GetY
(
int
ic
)
const
{
return
corner
[
ic
].
y
;
}
const
wxPoint
&
GetPos
(
int
ic
)
const
{
return
m_CornersList
[
ic
];
}
const
wxPoint
&
GetPos
(
int
ic
)
const
{
return
corner
[
ic
];
}
int
GetEndContour
(
int
ic
);
int
GetEndContour
(
int
ic
);
int
GetUtility
(
int
ic
)
{
return
m_CornersList
[
ic
].
m_utility
;
};
void
SetUtility
(
int
ic
,
int
utility
)
{
m_CornersList
[
ic
].
m_utility
=
utility
;
};
int
GetSideStyle
(
int
is
);
int
GetUtility
(
int
ic
)
{
return
corner
[
ic
].
utility
;
};
void
SetUtility
(
int
ic
,
int
utility
)
{
corner
[
ic
].
utility
=
utility
;
};
int
GetSideStyle
(
int
is
);
int
GetHatchPitch
()
{
return
m_hatchPitch
;
}
int
GetDefaultHatchPitchMils
()
{
return
20
;
}
// default hatch pitch value in mils
int
GetDefaultHatchPitchMils
()
{
return
20
;
}
// default hatch pitch value in mils
enum
hatch_style
GetHatchStyle
()
{
return
m_hatchStyle
;
}
void
SetHatch
(
int
hatch
,
int
pitch
)
{
SetHatchPitch
(
pitch
);
m_hatchStyle
=
(
enum
hatch_style
)
hatch
;
Hatch
();
}
void
SetX
(
int
ic
,
int
x
);
void
SetY
(
int
ic
,
int
y
);
void
SetEndContour
(
int
ic
,
bool
end_contour
);
void
SetSideStyle
(
int
is
,
int
style
);
{
SetHatchPitch
(
pitch
);
m_hatchStyle
=
(
enum
hatch_style
)
hatch
;
Hatch
();
}
void
SetX
(
int
ic
,
int
x
);
void
SetY
(
int
ic
,
int
y
);
void
SetEndContour
(
int
ic
,
bool
end_contour
);
void
SetSideStyle
(
int
is
,
int
style
);
void
SetHatchStyle
(
enum
hatch_style
style
)
{
m_hatchStyle
=
style
;
}
{
m_hatchStyle
=
style
;
}
void
SetHatchPitch
(
int
pitch
)
{
m_hatchPitch
=
pitch
;
}
int
RestoreArcs
(
std
::
vector
<
CArc
>
*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
);
int
RestoreArcs
(
std
::
vector
<
CArc
>*
arc_array
,
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
);
int
NormalizeAreaOutlines
(
std
::
vector
<
CPolyLine
*>
*
pa
=
NULL
,
bool
bRetainArcs
=
false
);
int
NormalizeAreaOutlines
(
std
::
vector
<
CPolyLine
*>*
pa
=
NULL
,
bool
bRetainArcs
=
false
);
// KBOOL functions
/**
* Function AddPolygonsToBoolEng
* and edges contours to a kbool engine, preparing a boolean op between polygons
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* @param arc_array: arc connverted to poly (NULL if not exists)
* @param aBooleng : pointer on a bool engine (handle a set of polygons)
* @param aGroup : group to fill (aGroup = GROUP_A or GROUP_B) operations are made between GROUP_A and GROUP_B
*/
int
AddPolygonsToBoolEng
(
Bool_Engine
*
aBooleng
,
GroupType
aGroup
,
int
aStart_contour
=
-
1
,
int
aEnd_contour
=
-
1
,
std
::
vector
<
CArc
>
*
arc_array
=
NULL
);
/**
* Function MakeKboolPoly
* fill a kbool engine with a closed polyline contour
* approximates arcs with multiple straight-line segments
* @param aStart_contour: starting contour number (-1 = all, 0 is the outlines of zone, > 1 = holes in zone
* @param aEnd_contour: ending contour number (-1 = all after aStart_contour)
* combining intersecting contours if possible
* @param arc_array : return data on arcs in arc_array
* @param aConvertHoles = mode for holes when a boolean operation is made
* true: holes are linked into outer contours by double overlapping segments
* false: holes are not linked: in this mode contours are added clockwise
* and polygons added counter clockwise are holes (default)
* @return error: 0 if Ok, 1 if error
*/
int
MakeKboolPoly
(
int
aStart_contour
=
-
1
,
int
aEnd_contour
=
-
1
,
std
::
vector
<
CArc
>
*
arc_array
=
NULL
,
bool
aConvertHoles
=
false
);
int
MakeKboolPoly
(
std
::
vector
<
CArc
>*
arc_array
=
NULL
);
/**
* Function NormalizeWithKbool
...
...
@@ -262,22 +232,11 @@ public:
* @param bRetainArcs == false, try to retain arcs in polys
* @return number of external contours, or -1 if error
*/
int
NormalizeWithKbool
(
std
::
vector
<
CPolyLine
*>
*
aExtraPolyList
,
bool
bRetainArcs
);
/**
* Function GetKboolEngine
* @return the current used Kbool Engine (after normalization using kbool)
*/
Bool_Engine
*
GetKboolEngine
(
)
{
return
m_Kbool_Poly_Engine
;
}
/**
* Function FreeKboolEngine
* delete the current used Kbool Engine (free memory after normalization using kbool)
*/
void
FreeKboolEngine
(
)
{
delete
m_Kbool_Poly_Engine
;
m_Kbool_Poly_Engine
=
NULL
;
}
int
NormalizeWithKbool
(
std
::
vector
<
CPolyLine
*>*
aExtraPolyList
,
bool
bRetainArcs
);
// Bezier Support
void
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
);
void
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
,
int
x4
,
int
y4
);
void
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
);
void
AppendBezier
(
int
x1
,
int
y1
,
int
x2
,
int
y2
,
int
x3
,
int
y3
,
int
x4
,
int
y4
);
/**
* Function Distance
...
...
@@ -286,7 +245,7 @@ public:
* @return int = distance between the point and outline.
* 0 if the point is inside
*/
int
Distance
(
const
wxPoint
&
aPoint
);
int
Distance
(
const
wxPoint
&
aPoint
);
/**
* Function Distance
...
...
@@ -297,22 +256,44 @@ public:
* @return int = distance between the segment and outline.
* 0 if segment intersects or is inside
*/
int
Distance
(
wxPoint
aStart
,
wxPoint
aEnd
,
int
aWidth
);
int
Distance
(
wxPoint
aStart
,
wxPoint
aEnd
,
int
aWidth
);
private
:
int
m_layer
;
// layer to draw on
int
m_Width
;
// lines width when drawing. Provided but not really used
enum
hatch_style
m_hatchStyle
;
// hatch style, see enum above
int
m_hatchPitch
;
// for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
// and the len of eacvh segment
// for DIAGONAL_FULL, the pitch is twice this value
int
utility
;
Bool_Engine
*
m_Kbool_Poly_Engine
;
// polygons set in kbool engine data
int
m_layer
;
// layer to draw on
int
m_width
;
// lines width when drawing. Provided but not really used
enum
hatch_style
m_hatchStyle
;
// hatch style, see enum above
int
m_hatchPitch
;
// for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
// and the len of eacvh segment
// for DIAGONAL_FULL, the pitch is twice this value
int
m_utility
;
// a flag used in some calculations
Bool_Engine
*
m_Kbool_Poly_Engine
;
// polygons set in kbool engine data
public
:
std
::
vector
<
CPolyPt
>
corner
;
// array of points for corners
std
::
vector
<
int
>
side_style
;
// array of styles for sides
std
::
vector
<
CSegment
>
m_HatchLines
;
// hatch lines
std
::
vector
<
CPolyPt
>
m_CornersList
;
// array of points for corners
std
::
vector
<
int
>
m_SideStyle
;
// array of styles for sides
std
::
vector
<
CSegment
>
m_HatchLines
;
// hatch lines showing the polygon area
};
#endif // #ifndef POLYLINE_H
/**
* Function CopyPolysListToKiPolygonWithHole
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
*
* @param aPolysList = the list of corners of contours
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
*/
void
CopyPolysListToKiPolygonWithHole
(
const
std
::
vector
<
CPolyPt
>&
aPolysList
,
KI_POLYGON_WITH_HOLES
&
aPolygoneWithHole
);
/**
* Function ConvertPolysListWithHolesToOnePolygon
* converts the outline contours aPolysListWithHoles with holes to one polygon
* with no holes (only one contour)
* holes are linked to main outlines by overlap segments, to give only one polygon
*
* @param aPolysListWithHoles = the list of corners of contours (haing holes
* @param aOnePolyList = a polygon with no holes
*/
void
ConvertPolysListWithHolesToOnePolygon
(
const
std
::
vector
<
CPolyPt
>&
aPolysListWithHoles
,
std
::
vector
<
CPolyPt
>&
aOnePolyList
);
#endif // #ifndef POLYLINE_H
polygon/polygons_defs.h
0 → 100644
View file @
1c9433fb
/*
* file polygons_defs.h
* definitions to use boost::polygon in KiCad.
*/
#ifndef _POLYGONS_DEFS_H_
#define _POLYGONS_DEFS_H_
#include <boost/polygon/polygon.hpp>
// Define some types used here from boost::polygon
namespace
bpl
=
boost
::
polygon
;
// bpl = boost polygon library
using
namespace
bpl
::
operators
;
// +, -, =, ...
// Definitions needed by boost::polygon
typedef
int
coordinate_type
;
/**
* KI_POLYGON defines a single polygon ( boost::polygon_data type.
* When holes are created in a KPolygon, they are
* linked to main outline by overlapping segments,
* so there is always one polygon and one list of corners
* coordinates are int
*/
typedef
bpl
::
polygon_data
<
int
>
KI_POLYGON
;
/**
* KI_POLYGON_SET defines a set of single KI_POLYGON.
* A KI_POLYGON_SET is used to store a set of polygons
* when performing operations between 2 polygons
* or 2 sets of polygons
* The result of operations like and, xor... between 2 polygons
* is always stored in a KI_POLYGON_SET, because these operations
* can create many polygons
*/
typedef
std
::
vector
<
KI_POLYGON
>
KI_POLYGON_SET
;
/**
* KI_POLY_POINT defines a point for boost::polygon.
* KI_POLY_POINT store x and y coordinates (int)
*/
typedef
bpl
::
point_data
<
int
>
KI_POLY_POINT
;
/**
* KI_POLYGON_WITH_HOLES defines a single polygon with holes
* When holes are created in a KI_POLYGON_WITH_HOLES, they are
* stored as separate single polygons,
* KI_POLYGON_WITH_HOLES store always one polygon for the external outline
* and one list of polygons (holes) which can be empty
*/
typedef
bpl
::
polygon_with_holes_data
<
int
>
KI_POLYGON_WITH_HOLES
;
/**
* KI_POLYGON_WITH_HOLES_SET defines a set of KI_POLYGON_WITH_HOLES.
* A KI_POLYGON_WITH_HOLES_SET is used to store a set of polygons with holes
* when performing operations between 2 polygons
* or 2 sets of polygons with holes
* The result of operations like and, xor... between 2 polygons with holes
* is always stored in a KI_POLYGON_WITH_HOLES_SET, because these operations
* can create many separate polygons with holespolygons
*/
typedef
std
::
vector
<
KI_POLYGON_WITH_HOLES
>
KI_POLYGON_WITH_HOLES_SET
;
#endif // #ifndef _POLYGONS_DEFS_H_
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