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
f63492f5
Commit
f63492f5
authored
Jan 04, 2008
by
raburton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
set eol-style native on new file
parent
ffd3a713
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
975 additions
and
975 deletions
+975
-975
zones_test_and_combine_areas.cpp
pcbnew/zones_test_and_combine_areas.cpp
+975
-975
No files found.
pcbnew/zones_test_and_combine_areas.cpp
View file @
f63492f5
/****************************************************************************/
/****************************************************************************/
/* functions to test, merges and cut polygons used as copper areas outlines */
/* functions to test, merges and cut polygons used as copper areas outlines */
/****************************************************************************/
/****************************************************************************/
#include <vector>
#include <vector>
#include "fctsys.h"
#include "fctsys.h"
#include "common.h"
#include "common.h"
#include "pcbnew.h"
#include "pcbnew.h"
using
namespace
std
;
using
namespace
std
;
#undef ASSERT
#undef ASSERT
#define ASSERT wxASSERT
#define ASSERT wxASSERT
bool
bDontShowSelfIntersectionArcsWarning
;
bool
bDontShowSelfIntersectionArcsWarning
;
bool
bDontShowSelfIntersectionWarning
;
bool
bDontShowSelfIntersectionWarning
;
bool
bDontShowIntersectionArcsWarning
;
bool
bDontShowIntersectionArcsWarning
;
bool
bDontShowIntersectionWarning
;
bool
bDontShowIntersectionWarning
;
#define poly m_Poly
#define poly m_Poly
// carea: describes a copper area
// carea: describes a copper area
#define carea ZONE_CONTAINER
#define carea ZONE_CONTAINER
/**
/**
* Function AddArea
* Function AddArea
* add empty copper area to net
* add empty copper area to net
* @return pointer to the new area
* @return pointer to the new area
*/
*/
ZONE_CONTAINER
*
BOARD
::
AddArea
(
int
netcode
,
int
layer
,
int
x
,
int
y
,
int
hatch
)
ZONE_CONTAINER
*
BOARD
::
AddArea
(
int
netcode
,
int
layer
,
int
x
,
int
y
,
int
hatch
)
{
{
ZONE_CONTAINER
*
new_area
=
InsertArea
(
netcode
,
m_ZoneDescriptorList
.
size
(
ZONE_CONTAINER
*
new_area
=
InsertArea
(
netcode
,
m_ZoneDescriptorList
.
size
(
)
-
1
,
layer
,
x
,
y
,
hatch
);
)
-
1
,
layer
,
x
,
y
,
hatch
);
return
new_area
;
return
new_area
;
}
}
/**
/**
* remove copper area from net
* remove copper area from net
* @param area = area to remove
* @param area = area to remove
* @return 0
* @return 0
*/
*/
int
BOARD
::
RemoveArea
(
ZONE_CONTAINER
*
area_to_remove
)
int
BOARD
::
RemoveArea
(
ZONE_CONTAINER
*
area_to_remove
)
{
{
Delete
(
area_to_remove
);
Delete
(
area_to_remove
);
return
0
;
return
0
;
}
}
/**
/**
* Function InsertArea
* Function InsertArea
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
* @return pointer to the new area
* @return pointer to the new area
*/
*/
ZONE_CONTAINER
*
BOARD
::
InsertArea
(
int
netcode
,
int
iarea
,
int
layer
,
int
x
,
int
y
,
int
hatch
)
ZONE_CONTAINER
*
BOARD
::
InsertArea
(
int
netcode
,
int
iarea
,
int
layer
,
int
x
,
int
y
,
int
hatch
)
{
{
ZONE_CONTAINER
*
new_area
=
new
ZONE_CONTAINER
(
this
);
ZONE_CONTAINER
*
new_area
=
new
ZONE_CONTAINER
(
this
);
new_area
->
SetNet
(
netcode
);
new_area
->
SetNet
(
netcode
);
new_area
->
SetLayer
(
layer
);
new_area
->
SetLayer
(
layer
);
new_area
->
m_TimeStamp
=
GetTimeStamp
();
new_area
->
m_TimeStamp
=
GetTimeStamp
();
if
(
iarea
<
(
int
)
(
m_ZoneDescriptorList
.
size
()
-
1
)
)
if
(
iarea
<
(
int
)
(
m_ZoneDescriptorList
.
size
()
-
1
)
)
m_ZoneDescriptorList
.
insert
(
m_ZoneDescriptorList
.
begin
()
+
iarea
+
1
,
new_area
);
m_ZoneDescriptorList
.
insert
(
m_ZoneDescriptorList
.
begin
()
+
iarea
+
1
,
new_area
);
else
else
m_ZoneDescriptorList
.
push_back
(
new_area
);
m_ZoneDescriptorList
.
push_back
(
new_area
);
new_area
->
poly
->
Start
(
layer
,
1
,
10
*
NM_PER_MIL
,
x
,
y
,
new_area
->
poly
->
Start
(
layer
,
1
,
10
*
NM_PER_MIL
,
x
,
y
,
hatch
);
hatch
);
return
new_area
;
return
new_area
;
}
}
/**
/**
* Function CompleteArea
* Function CompleteArea
* complete copper area contour by adding a line from last to first corner
* complete copper area contour by adding a line from last to first corner
* if there is only 1 or 2 corners, remove (delete) the area
* if there is only 1 or 2 corners, remove (delete) the area
* @param area_to_complete = area to complete or remove
* @param area_to_complete = area to complete or remove
* @param style = style of last corner
* @param style = style of last corner
* @return 1 if Ok, 0 if area removed
* @return 1 if Ok, 0 if area removed
*/
*/
int
BOARD
::
CompleteArea
(
ZONE_CONTAINER
*
area_to_complete
,
int
style
)
int
BOARD
::
CompleteArea
(
ZONE_CONTAINER
*
area_to_complete
,
int
style
)
{
{
if
(
area_to_complete
->
poly
->
GetNumCorners
()
>
2
)
if
(
area_to_complete
->
poly
->
GetNumCorners
()
>
2
)
{
{
area_to_complete
->
poly
->
Close
(
style
);
area_to_complete
->
poly
->
Close
(
style
);
return
1
;
return
1
;
}
}
else
else
{
{
RemoveArea
(
area_to_complete
);
RemoveArea
(
area_to_complete
);
}
}
return
0
;
return
0
;
}
}
/**
/**
* Function TestAreaPolygon
* Function TestAreaPolygon
* Test an area for self-intersection.
* Test an area for self-intersection.
*
*
* @param CurrArea = copper area to test
* @param CurrArea = copper area to test
* @return :
* @return :
* -1 if arcs intersect other sides
* -1 if arcs intersect other sides
* 0 if no intersecting sides
* 0 if no intersecting sides
* 1 if intersecting sides, but no intersecting arcs
* 1 if intersecting sides, but no intersecting arcs
* Also sets utility2 flag of area with return value
* Also sets utility2 flag of area with return value
*/
*/
int
BOARD
::
TestAreaPolygon
(
ZONE_CONTAINER
*
CurrArea
)
int
BOARD
::
TestAreaPolygon
(
ZONE_CONTAINER
*
CurrArea
)
{
{
CPolyLine
*
p
=
CurrArea
->
poly
;
CPolyLine
*
p
=
CurrArea
->
poly
;
// first, check for sides intersecting other sides, especially arcs
// first, check for sides intersecting other sides, especially arcs
bool
bInt
=
false
;
bool
bInt
=
false
;
bool
bArcInt
=
false
;
bool
bArcInt
=
false
;
int
n_cont
=
p
->
GetNumContours
();
int
n_cont
=
p
->
GetNumContours
();
// make bounding rect for each contour
// make bounding rect for each contour
std
::
vector
<
CRect
>
cr
;
std
::
vector
<
CRect
>
cr
;
cr
.
reserve
(
n_cont
);
cr
.
reserve
(
n_cont
);
for
(
int
icont
=
0
;
icont
<
n_cont
;
icont
++
)
for
(
int
icont
=
0
;
icont
<
n_cont
;
icont
++
)
cr
.
push_back
(
p
->
GetCornerBounds
(
icont
)
);
cr
.
push_back
(
p
->
GetCornerBounds
(
icont
)
);
for
(
int
icont
=
0
;
icont
<
n_cont
;
icont
++
)
for
(
int
icont
=
0
;
icont
<
n_cont
;
icont
++
)
{
{
int
is_start
=
p
->
GetContourStart
(
icont
);
int
is_start
=
p
->
GetContourStart
(
icont
);
int
is_end
=
p
->
GetContourEnd
(
icont
);
int
is_end
=
p
->
GetContourEnd
(
icont
);
for
(
int
is
=
is_start
;
is
<=
is_end
;
is
++
)
for
(
int
is
=
is_start
;
is
<=
is_end
;
is
++
)
{
{
int
is_prev
=
is
-
1
;
int
is_prev
=
is
-
1
;
if
(
is_prev
<
is_start
)
if
(
is_prev
<
is_start
)
is_prev
=
is_end
;
is_prev
=
is_end
;
int
is_next
=
is
+
1
;
int
is_next
=
is
+
1
;
if
(
is_next
>
is_end
)
if
(
is_next
>
is_end
)
is_next
=
is_start
;
is_next
=
is_start
;
int
style
=
p
->
GetSideStyle
(
is
);
int
style
=
p
->
GetSideStyle
(
is
);
int
x1i
=
p
->
GetX
(
is
);
int
x1i
=
p
->
GetX
(
is
);
int
y1i
=
p
->
GetY
(
is
);
int
y1i
=
p
->
GetY
(
is
);
int
x1f
=
p
->
GetX
(
is_next
);
int
x1f
=
p
->
GetX
(
is_next
);
int
y1f
=
p
->
GetY
(
is_next
);
int
y1f
=
p
->
GetY
(
is_next
);
// check for intersection with any other sides
// check for intersection with any other sides
for
(
int
icont2
=
icont
;
icont2
<
n_cont
;
icont2
++
)
for
(
int
icont2
=
icont
;
icont2
<
n_cont
;
icont2
++
)
{
{
if
(
cr
[
icont
].
left
>
cr
[
icont2
].
right
if
(
cr
[
icont
].
left
>
cr
[
icont2
].
right
||
cr
[
icont
].
bottom
>
cr
[
icont2
].
top
||
cr
[
icont
].
bottom
>
cr
[
icont2
].
top
||
cr
[
icont2
].
left
>
cr
[
icont
].
right
||
cr
[
icont2
].
left
>
cr
[
icont
].
right
||
cr
[
icont2
].
bottom
>
cr
[
icont
].
top
)
||
cr
[
icont2
].
bottom
>
cr
[
icont
].
top
)
{
{
// rectangles don't overlap, do nothing
// rectangles don't overlap, do nothing
}
}
else
else
{
{
int
is2_start
=
p
->
GetContourStart
(
icont2
);
int
is2_start
=
p
->
GetContourStart
(
icont2
);
int
is2_end
=
p
->
GetContourEnd
(
icont2
);
int
is2_end
=
p
->
GetContourEnd
(
icont2
);
for
(
int
is2
=
is2_start
;
is2
<=
is2_end
;
is2
++
)
for
(
int
is2
=
is2_start
;
is2
<=
is2_end
;
is2
++
)
{
{
int
is2_prev
=
is2
-
1
;
int
is2_prev
=
is2
-
1
;
if
(
is2_prev
<
is2_start
)
if
(
is2_prev
<
is2_start
)
is2_prev
=
is2_end
;
is2_prev
=
is2_end
;
int
is2_next
=
is2
+
1
;
int
is2_next
=
is2
+
1
;
if
(
is2_next
>
is2_end
)
if
(
is2_next
>
is2_end
)
is2_next
=
is2_start
;
is2_next
=
is2_start
;
if
(
icont
!=
icont2
if
(
icont
!=
icont2
||
(
is2
!=
is
&&
is2
!=
is_prev
&&
is2
!=
is_next
&&
is
!=
is2_prev
||
(
is2
!=
is
&&
is2
!=
is_prev
&&
is2
!=
is_next
&&
is
!=
is2_prev
&&
is
!=
&&
is
!=
is2_next
)
)
is2_next
)
)
{
{
int
style2
=
p
->
GetSideStyle
(
is2
);
int
style2
=
p
->
GetSideStyle
(
is2
);
int
x2i
=
p
->
GetX
(
is2
);
int
x2i
=
p
->
GetX
(
is2
);
int
y2i
=
p
->
GetY
(
is2
);
int
y2i
=
p
->
GetY
(
is2
);
int
x2f
=
p
->
GetX
(
is2_next
);
int
x2f
=
p
->
GetX
(
is2_next
);
int
y2f
=
p
->
GetY
(
is2_next
);
int
y2f
=
p
->
GetY
(
is2_next
);
int
ret
=
FindSegmentIntersections
(
x1i
,
int
ret
=
FindSegmentIntersections
(
x1i
,
y1i
,
y1i
,
x1f
,
x1f
,
y1f
,
y1f
,
style
,
style
,
x2i
,
x2i
,
y2i
,
y2i
,
x2f
,
x2f
,
y2f
,
y2f
,
style2
);
style2
);
if
(
ret
)
if
(
ret
)
{
{
// intersection between non-adjacent sides
// intersection between non-adjacent sides
bInt
=
TRUE
;
bInt
=
TRUE
;
if
(
style
!=
CPolyLine
::
STRAIGHT
||
style2
!=
CPolyLine
::
STRAIGHT
)
if
(
style
!=
CPolyLine
::
STRAIGHT
||
style2
!=
CPolyLine
::
STRAIGHT
)
{
{
bArcInt
=
TRUE
;
bArcInt
=
TRUE
;
break
;
break
;
}
}
}
}
}
}
}
}
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
bArcInt
)
if
(
bArcInt
)
CurrArea
->
utility2
=
-
1
;
CurrArea
->
utility2
=
-
1
;
else
if
(
bInt
)
else
if
(
bInt
)
CurrArea
->
utility2
=
1
;
CurrArea
->
utility2
=
1
;
else
else
CurrArea
->
utility2
=
0
;
CurrArea
->
utility2
=
0
;
return
CurrArea
->
utility2
;
return
CurrArea
->
utility2
;
}
}
/**
/**
* Function ClipAreaPolygon
* Function ClipAreaPolygon
* Process an area that has been modified, by clipping its polygon against itself.
* Process an area that has been modified, by clipping its polygon against itself.
* This may change the number and order of copper areas in the net.
* This may change the number and order of copper areas in the net.
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
* @param bMessageBoxInt == TRUE, shows message when clipping occurs.
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
* @param bMessageBoxArc == TRUE, shows message when clipping can't be done due to arcs.
* @return:
* @return:
* -1 if arcs intersect other sides, so polygon can't be clipped
* -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides
* 0 if no intersecting sides
* 1 if intersecting sides
* 1 if intersecting sides
* Also sets areas->utility1 flags if areas are modified
* Also sets areas->utility1 flags if areas are modified
*/
*/
int
BOARD
::
ClipAreaPolygon
(
ZONE_CONTAINER
*
CurrArea
,
int
BOARD
::
ClipAreaPolygon
(
ZONE_CONTAINER
*
CurrArea
,
bool
bMessageBoxArc
,
bool
bMessageBoxInt
,
bool
bRetainArcs
)
bool
bMessageBoxArc
,
bool
bMessageBoxInt
,
bool
bRetainArcs
)
{
{
CPolyLine
*
p
=
CurrArea
->
poly
;
CPolyLine
*
p
=
CurrArea
->
poly
;
int
test
=
TestAreaPolygon
(
CurrArea
);
// this sets utility2 flag
int
test
=
TestAreaPolygon
(
CurrArea
);
// this sets utility2 flag
if
(
test
==
-
1
&&
!
bRetainArcs
)
if
(
test
==
-
1
&&
!
bRetainArcs
)
test
=
1
;
test
=
1
;
if
(
test
==
-
1
)
if
(
test
==
-
1
)
{
{
// arc intersections, don't clip unless bRetainArcs == false
// arc intersections, don't clip unless bRetainArcs == false
if
(
bMessageBoxArc
&&
bDontShowSelfIntersectionArcsWarning
==
false
)
if
(
bMessageBoxArc
&&
bDontShowSelfIntersectionArcsWarning
==
false
)
{
{
wxString
str
;
wxString
str
;
str
.
Printf
(
wxT
(
"Area %X of net
\"
%s
\"
has arcs intersecting other sides.
\n
"
),
str
.
Printf
(
wxT
(
"Area %X of net
\"
%s
\"
has arcs intersecting other sides.
\n
"
),
CurrArea
->
m_TimeStamp
,
CurrArea
->
m_Netname
.
GetData
()
);
CurrArea
->
m_TimeStamp
,
CurrArea
->
m_Netname
.
GetData
()
);
str
+=
wxT
(
"This may cause problems with other editing operations,
\n
"
);
str
+=
wxT
(
"This may cause problems with other editing operations,
\n
"
);
str
+=
wxT
(
"such as adding cutouts. It can't be fixed automatically.
\n
"
);
str
+=
wxT
(
"such as adding cutouts. It can't be fixed automatically.
\n
"
);
str
+=
wxT
(
"Manual correction is recommended."
);
str
+=
wxT
(
"Manual correction is recommended."
);
wxMessageBox
(
str
);
wxMessageBox
(
str
);
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
// bDontShowSelfIntersectionArcsWarning = dlg.bDontShowBoxState;
}
}
return
-
1
;
// arcs intersect with other sides, error
return
-
1
;
// arcs intersect with other sides, error
}
}
// mark all areas as unmodified except this one
// mark all areas as unmodified except this one
for
(
unsigned
ia
=
0
;
ia
<
m_ZoneDescriptorList
.
size
();
ia
++
)
for
(
unsigned
ia
=
0
;
ia
<
m_ZoneDescriptorList
.
size
();
ia
++
)
m_ZoneDescriptorList
[
ia
]
->
utility
=
0
;
m_ZoneDescriptorList
[
ia
]
->
utility
=
0
;
CurrArea
->
utility
=
1
;
CurrArea
->
utility
=
1
;
if
(
test
==
1
)
if
(
test
==
1
)
{
{
// non-arc intersections, clip the polygon
// non-arc intersections, clip the polygon
if
(
bMessageBoxInt
&&
bDontShowSelfIntersectionWarning
==
false
)
if
(
bMessageBoxInt
&&
bDontShowSelfIntersectionWarning
==
false
)
{
{
wxString
str
;
wxString
str
;
str
.
Printf
(
wxT
(
"Area %d of net
\"
%s
\"
is self-intersecting and will be clipped.
\n
"
),
str
.
Printf
(
wxT
(
"Area %d of net
\"
%s
\"
is self-intersecting and will be clipped.
\n
"
),
CurrArea
->
m_TimeStamp
,
CurrArea
->
m_Netname
.
GetData
()
);
CurrArea
->
m_TimeStamp
,
CurrArea
->
m_Netname
.
GetData
()
);
str
+=
wxT
(
"This may result in splitting the area.
\n
"
);
str
+=
wxT
(
"This may result in splitting the area.
\n
"
);
str
+=
wxT
(
"If the area is complex, this may take a few seconds."
);
str
+=
wxT
(
"If the area is complex, this may take a few seconds."
);
wxMessageBox
(
str
);
wxMessageBox
(
str
);
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
// bDontShowSelfIntersectionWarning = dlg.bDontShowBoxState;
}
}
}
}
//** TODO test for cutouts outside of area
//** TODO test for cutouts outside of area
//** if( test == 1 )
//** if( test == 1 )
{
{
std
::
vector
<
CPolyLine
*>
*
pa
=
new
std
::
vector
<
CPolyLine
*>
;
std
::
vector
<
CPolyLine
*>
*
pa
=
new
std
::
vector
<
CPolyLine
*>
;
p
->
Undraw
();
p
->
Undraw
();
int
n_poly
=
CurrArea
->
poly
->
NormalizeWithGpc
(
pa
,
bRetainArcs
);
int
n_poly
=
CurrArea
->
poly
->
NormalizeWithGpc
(
pa
,
bRetainArcs
);
if
(
n_poly
>
1
)
// i.e if clippinf has created some polygons, we must add these new copper areas
if
(
n_poly
>
1
)
// i.e if clippinf has created some polygons, we must add these new copper areas
{
{
for
(
int
ip
=
1
;
ip
<
n_poly
;
ip
++
)
for
(
int
ip
=
1
;
ip
<
n_poly
;
ip
++
)
{
{
// create new copper area and copy poly into it
// create new copper area and copy poly into it
CPolyLine
*
new_p
=
(
*
pa
)[
ip
-
1
];
CPolyLine
*
new_p
=
(
*
pa
)[
ip
-
1
];
CurrArea
=
AddArea
(
CurrArea
->
GetNet
(),
CurrArea
->
GetLayer
(),
0
,
0
,
0
);
CurrArea
=
AddArea
(
CurrArea
->
GetNet
(),
CurrArea
->
GetLayer
(),
0
,
0
,
0
);
// remove the poly that was automatically created for the new area
// remove the poly that was automatically created for the new area
// and replace it with a poly from NormalizeWithGpc
// and replace it with a poly from NormalizeWithGpc
delete
CurrArea
->
poly
;
delete
CurrArea
->
poly
;
CurrArea
->
poly
=
new_p
;
CurrArea
->
poly
=
new_p
;
CurrArea
->
poly
->
Draw
();
CurrArea
->
poly
->
Draw
();
CurrArea
->
utility
=
1
;
CurrArea
->
utility
=
1
;
}
}
}
}
p
->
Draw
();
p
->
Draw
();
delete
pa
;
delete
pa
;
}
}
return
test
;
return
test
;
}
}
/**
/**
* Process an area that has been modified, by clipping its polygon against
* Process an area that has been modified, by clipping its polygon against
* itself and the polygons for any other areas on the same net.
* itself and the polygons for any other areas on the same net.
* This may change the number and order of copper areas in the net.
* This may change the number and order of copper areas in the net.
* @param modified_area = area to test
* @param modified_area = area to test
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
* @param bMessageBox : if TRUE, shows message boxes when clipping occurs.
* @return :
* @return :
* -1 if arcs intersect other sides, so polygon can't be clipped
* -1 if arcs intersect other sides, so polygon can't be clipped
* 0 if no intersecting sides
* 0 if no intersecting sides
* 1 if intersecting sides, polygon clipped
* 1 if intersecting sides, polygon clipped
*/
*/
int
BOARD
::
AreaPolygonModified
(
ZONE_CONTAINER
*
modified_area
,
int
BOARD
::
AreaPolygonModified
(
ZONE_CONTAINER
*
modified_area
,
bool
bMessageBoxArc
,
bool
bMessageBoxArc
,
bool
bMessageBoxInt
)
bool
bMessageBoxInt
)
{
{
// clip polygon against itself
// clip polygon against itself
int
test
=
ClipAreaPolygon
(
modified_area
,
bMessageBoxArc
,
bMessageBoxInt
);
int
test
=
ClipAreaPolygon
(
modified_area
,
bMessageBoxArc
,
bMessageBoxInt
);
if
(
test
==
-
1
)
if
(
test
==
-
1
)
return
test
;
return
test
;
// now see if we need to clip against other areas
// now see if we need to clip against other areas
bool
bCheckAllAreas
=
false
;
bool
bCheckAllAreas
=
false
;
if
(
test
==
1
)
if
(
test
==
1
)
bCheckAllAreas
=
TRUE
;
bCheckAllAreas
=
TRUE
;
else
else
bCheckAllAreas
=
TestAreaIntersections
(
modified_area
);
bCheckAllAreas
=
TestAreaIntersections
(
modified_area
);
if
(
bCheckAllAreas
)
if
(
bCheckAllAreas
)
CombineAllAreasInNet
(
modified_area
->
GetNet
(),
bMessageBoxInt
,
TRUE
);
CombineAllAreasInNet
(
modified_area
->
GetNet
(),
bMessageBoxInt
,
TRUE
);
return
test
;
return
test
;
}
}
/**
/**
* Function CombineAllAreasInNet
* Function CombineAllAreasInNet
* Checks all copper areas in net for intersections, combining them if found
* Checks all copper areas in net for intersections, combining them if found
* @param aNetCode = net to consider
* @param aNetCode = net to consider
* @param bMessageBox : if true display warning message box
* @param bMessageBox : if true display warning message box
* @param bUseUtility : if true, don't check areas if both utility flags are 0
* @param bUseUtility : if true, don't check areas if both utility flags are 0
* Sets utility flag = 1 for any areas modified
* Sets utility flag = 1 for any areas modified
* If an area has self-intersecting arcs, doesn't try to combine it
* If an area has self-intersecting arcs, doesn't try to combine it
*/
*/
int
BOARD
::
CombineAllAreasInNet
(
int
aNetCode
,
bool
bMessageBox
,
bool
bUseUtility
)
int
BOARD
::
CombineAllAreasInNet
(
int
aNetCode
,
bool
bMessageBox
,
bool
bUseUtility
)
{
{
if
(
m_ZoneDescriptorList
.
size
()
>
1
)
if
(
m_ZoneDescriptorList
.
size
()
>
1
)
{
{
// start by testing all area polygons to set utility2 flags
// start by testing all area polygons to set utility2 flags
for
(
unsigned
ia
=
0
;
ia
<
m_ZoneDescriptorList
.
size
();
ia
++
)
for
(
unsigned
ia
=
0
;
ia
<
m_ZoneDescriptorList
.
size
();
ia
++
)
if
(
m_ZoneDescriptorList
[
ia
]
->
GetNet
()
==
aNetCode
)
if
(
m_ZoneDescriptorList
[
ia
]
->
GetNet
()
==
aNetCode
)
TestAreaPolygon
(
m_ZoneDescriptorList
[
ia
]
);
TestAreaPolygon
(
m_ZoneDescriptorList
[
ia
]
);
// now loop through all combinations
// now loop through all combinations
for
(
unsigned
ia1
=
0
;
ia1
<
m_ZoneDescriptorList
.
size
()
-
1
;
ia1
++
)
for
(
unsigned
ia1
=
0
;
ia1
<
m_ZoneDescriptorList
.
size
()
-
1
;
ia1
++
)
{
{
ZONE_CONTAINER
*
curr_area
=
m_ZoneDescriptorList
[
ia1
];
ZONE_CONTAINER
*
curr_area
=
m_ZoneDescriptorList
[
ia1
];
if
(
curr_area
->
GetNet
()
!=
aNetCode
)
if
(
curr_area
->
GetNet
()
!=
aNetCode
)
continue
;
continue
;
// legal polygon
// legal polygon
CRect
b1
=
curr_area
->
poly
->
GetCornerBounds
();
CRect
b1
=
curr_area
->
poly
->
GetCornerBounds
();
bool
mod_ia1
=
false
;
bool
mod_ia1
=
false
;
for
(
unsigned
ia2
=
m_ZoneDescriptorList
.
size
()
-
1
;
ia2
>
ia1
;
ia2
--
)
for
(
unsigned
ia2
=
m_ZoneDescriptorList
.
size
()
-
1
;
ia2
>
ia1
;
ia2
--
)
{
{
ZONE_CONTAINER
*
area2
=
m_ZoneDescriptorList
[
ia2
];
ZONE_CONTAINER
*
area2
=
m_ZoneDescriptorList
[
ia2
];
if
(
curr_area
->
poly
->
GetLayer
()
==
area2
->
poly
->
GetLayer
()
if
(
curr_area
->
poly
->
GetLayer
()
==
area2
->
poly
->
GetLayer
()
&&
curr_area
->
utility2
!=
-
1
&&
area2
->
utility2
!=
-
1
)
&&
curr_area
->
utility2
!=
-
1
&&
area2
->
utility2
!=
-
1
)
{
{
CRect
b2
=
area2
->
poly
->
GetCornerBounds
();
CRect
b2
=
area2
->
poly
->
GetCornerBounds
();
if
(
!
(
b1
.
left
>
b2
.
right
||
b1
.
right
<
b2
.
left
if
(
!
(
b1
.
left
>
b2
.
right
||
b1
.
right
<
b2
.
left
||
b1
.
bottom
>
b2
.
top
||
b1
.
top
<
b2
.
bottom
)
)
||
b1
.
bottom
>
b2
.
top
||
b1
.
top
<
b2
.
bottom
)
)
{
{
// check ia2 against 1a1
// check ia2 against 1a1
if
(
curr_area
->
utility
||
area2
->
utility
||
bUseUtility
==
if
(
curr_area
->
utility
||
area2
->
utility
||
bUseUtility
==
false
)
false
)
{
{
int
ret
=
TestAreaIntersection
(
curr_area
,
area2
);
int
ret
=
TestAreaIntersection
(
curr_area
,
area2
);
if
(
ret
==
1
)
if
(
ret
==
1
)
ret
=
CombineAreas
(
curr_area
,
area2
);
ret
=
CombineAreas
(
curr_area
,
area2
);
if
(
ret
==
1
)
if
(
ret
==
1
)
{
{
if
(
bMessageBox
&&
bDontShowIntersectionWarning
==
false
)
if
(
bMessageBox
&&
bDontShowIntersectionWarning
==
false
)
{
{
wxString
str
;
wxString
str
;
str
.
Printf
(
str
.
Printf
(
wxT
(
wxT
(
"Areas %d and %d of net
\"
%s
\"
intersect and will be combined.
\n
"
),
"Areas %d and %d of net
\"
%s
\"
intersect and will be combined.
\n
"
),
ia1
+
1
,
ia1
+
1
,
ia2
+
1
,
ia2
+
1
,
curr_area
->
m_Netname
.
GetData
()
);
curr_area
->
m_Netname
.
GetData
()
);
str
+=
wxT
(
str
+=
wxT
(
"If they are complex, this may take a few seconds."
);
"If they are complex, this may take a few seconds."
);
wxMessageBox
(
str
);
wxMessageBox
(
str
);
// bDontShowIntersectionWarning = dlg.bDontShowBoxState;
// bDontShowIntersectionWarning = dlg.bDontShowBoxState;
}
}
mod_ia1
=
TRUE
;
mod_ia1
=
TRUE
;
}
}
else
if
(
ret
==
2
)
else
if
(
ret
==
2
)
{
{
if
(
bMessageBox
&&
bDontShowIntersectionArcsWarning
==
false
)
if
(
bMessageBox
&&
bDontShowIntersectionArcsWarning
==
false
)
{
{
wxString
str
;
wxString
str
;
str
.
Printf
(
str
.
Printf
(
wxT
(
wxT
(
"Areas %d and %d of net
\"
%s
\"
intersect, but some of the intersecting sides are arcs.
\n
"
),
"Areas %d and %d of net
\"
%s
\"
intersect, but some of the intersecting sides are arcs.
\n
"
),
ia1
+
1
,
ia1
+
1
,
ia2
+
1
,
ia2
+
1
,
curr_area
->
m_Netname
.
GetData
()
);
curr_area
->
m_Netname
.
GetData
()
);
str
+=
wxT
(
"Therefore, these areas can't be combined."
);
str
+=
wxT
(
"Therefore, these areas can't be combined."
);
wxMessageBox
(
str
);
wxMessageBox
(
str
);
// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState;
// bDontShowIntersectionArcsWarning = dlg.bDontShowBoxState;
}
}
}
}
}
}
}
}
}
}
}
}
if
(
mod_ia1
)
if
(
mod_ia1
)
ia1
--
;
// if modified, we need to check it again
ia1
--
;
// if modified, we need to check it again
}
}
}
}
return
0
;
return
0
;
}
}
/**
/**
* Function TestAreaIntersections
* Function TestAreaIntersections
* Check for intersection of a given copper area with other areas in same net
* Check for intersection of a given copper area with other areas in same net
* @param area_to_test = area to compare to all other areas in the same net
* @param area_to_test = area to compare to all other areas in the same net
*/
*/
bool
BOARD
::
TestAreaIntersections
(
ZONE_CONTAINER
*
area_to_test
)
bool
BOARD
::
TestAreaIntersections
(
ZONE_CONTAINER
*
area_to_test
)
{
{
CPolyLine
*
poly1
=
area_to_test
->
poly
;
CPolyLine
*
poly1
=
area_to_test
->
poly
;
for
(
unsigned
ia2
=
0
;
ia2
<
m_ZoneDescriptorList
.
size
();
ia2
++
)
for
(
unsigned
ia2
=
0
;
ia2
<
m_ZoneDescriptorList
.
size
();
ia2
++
)
{
{
ZONE_CONTAINER
*
area2
=
m_ZoneDescriptorList
[
ia2
];
ZONE_CONTAINER
*
area2
=
m_ZoneDescriptorList
[
ia2
];
if
(
area_to_test
->
GetNet
()
!=
area_to_test
->
GetNet
()
)
if
(
area_to_test
->
GetNet
()
!=
area_to_test
->
GetNet
()
)
continue
;
continue
;
if
(
area_to_test
!=
area2
)
if
(
area_to_test
!=
area2
)
{
{
// see if areas are on same layer
// see if areas are on same layer
if
(
area_to_test
->
GetLayer
()
!=
area2
->
GetLayer
()
)
if
(
area_to_test
->
GetLayer
()
!=
area2
->
GetLayer
()
)
continue
;
continue
;
CPolyLine
*
poly2
=
area2
->
poly
;
CPolyLine
*
poly2
=
area2
->
poly
;
// test bounding rects
// test bounding rects
CRect
b1
=
poly1
->
GetCornerBounds
();
CRect
b1
=
poly1
->
GetCornerBounds
();
CRect
b2
=
poly2
->
GetCornerBounds
();
CRect
b2
=
poly2
->
GetCornerBounds
();
if
(
b1
.
bottom
>
b2
.
top
if
(
b1
.
bottom
>
b2
.
top
||
b1
.
top
<
b2
.
bottom
||
b1
.
top
<
b2
.
bottom
||
b1
.
left
>
b2
.
right
||
b1
.
left
>
b2
.
right
||
b1
.
right
<
b2
.
left
)
||
b1
.
right
<
b2
.
left
)
continue
;
continue
;
// test for intersecting segments
// test for intersecting segments
for
(
int
icont1
=
0
;
icont1
<
poly1
->
GetNumContours
();
icont1
++
)
for
(
int
icont1
=
0
;
icont1
<
poly1
->
GetNumContours
();
icont1
++
)
{
{
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
for
(
int
ic1
=
is1
;
ic1
<=
ie1
;
ic1
++
)
for
(
int
ic1
=
is1
;
ic1
<=
ie1
;
ic1
++
)
{
{
int
xi1
=
poly1
->
GetX
(
ic1
);
int
xi1
=
poly1
->
GetX
(
ic1
);
int
yi1
=
poly1
->
GetY
(
ic1
);
int
yi1
=
poly1
->
GetY
(
ic1
);
int
xf1
,
yf1
,
style1
;
int
xf1
,
yf1
,
style1
;
if
(
ic1
<
ie1
)
if
(
ic1
<
ie1
)
{
{
xf1
=
poly1
->
GetX
(
ic1
+
1
);
xf1
=
poly1
->
GetX
(
ic1
+
1
);
yf1
=
poly1
->
GetY
(
ic1
+
1
);
yf1
=
poly1
->
GetY
(
ic1
+
1
);
}
}
else
else
{
{
xf1
=
poly1
->
GetX
(
is1
);
xf1
=
poly1
->
GetX
(
is1
);
yf1
=
poly1
->
GetY
(
is1
);
yf1
=
poly1
->
GetY
(
is1
);
}
}
style1
=
poly1
->
GetSideStyle
(
ic1
);
style1
=
poly1
->
GetSideStyle
(
ic1
);
for
(
int
icont2
=
0
;
icont2
<
poly2
->
GetNumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
poly2
->
GetNumContours
();
icont2
++
)
{
{
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
for
(
int
ic2
=
is2
;
ic2
<=
ie2
;
ic2
++
)
for
(
int
ic2
=
is2
;
ic2
<=
ie2
;
ic2
++
)
{
{
int
xi2
=
poly2
->
GetX
(
ic2
);
int
xi2
=
poly2
->
GetX
(
ic2
);
int
yi2
=
poly2
->
GetY
(
ic2
);
int
yi2
=
poly2
->
GetY
(
ic2
);
int
xf2
,
yf2
,
style2
;
int
xf2
,
yf2
,
style2
;
if
(
ic2
<
ie2
)
if
(
ic2
<
ie2
)
{
{
xf2
=
poly2
->
GetX
(
ic2
+
1
);
xf2
=
poly2
->
GetX
(
ic2
+
1
);
yf2
=
poly2
->
GetY
(
ic2
+
1
);
yf2
=
poly2
->
GetY
(
ic2
+
1
);
}
}
else
else
{
{
xf2
=
poly2
->
GetX
(
is2
);
xf2
=
poly2
->
GetX
(
is2
);
yf2
=
poly2
->
GetY
(
is2
);
yf2
=
poly2
->
GetY
(
is2
);
}
}
style2
=
poly2
->
GetSideStyle
(
ic2
);
style2
=
poly2
->
GetSideStyle
(
ic2
);
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
style1
,
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
style1
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
);
xi2
,
yi2
,
xf2
,
yf2
,
style2
);
if
(
n_int
)
if
(
n_int
)
return
TRUE
;
return
TRUE
;
}
}
}
}
}
}
}
}
}
}
}
}
return
false
;
return
false
;
}
}
/**
/**
* Function TestAreaIntersection
* Function TestAreaIntersection
* Test for intersection of 2 copper areas
* Test for intersection of 2 copper areas
* area_to_test must be after area_ref in m_ZoneDescriptorList
* area_to_test must be after area_ref in m_ZoneDescriptorList
* @param area_ref = area reference
* @param area_ref = area reference
* @param area_to_test = area to compare for intersection calculations
* @param area_to_test = area to compare for intersection calculations
* @return : 0 if no intersection
* @return : 0 if no intersection
* 1 if intersection
* 1 if intersection
* 2 if arcs intersect
* 2 if arcs intersect
*/
*/
int
BOARD
::
TestAreaIntersection
(
ZONE_CONTAINER
*
area_ref
,
ZONE_CONTAINER
*
area_to_test
)
int
BOARD
::
TestAreaIntersection
(
ZONE_CONTAINER
*
area_ref
,
ZONE_CONTAINER
*
area_to_test
)
{
{
// see if areas are on same layer
// see if areas are on same layer
if
(
area_ref
->
GetLayer
()
!=
area_to_test
->
GetLayer
()
)
if
(
area_ref
->
GetLayer
()
!=
area_to_test
->
GetLayer
()
)
return
0
;
return
0
;
CPolyLine
*
poly1
=
area_ref
->
poly
;
CPolyLine
*
poly1
=
area_ref
->
poly
;
CPolyLine
*
poly2
=
area_to_test
->
poly
;
CPolyLine
*
poly2
=
area_to_test
->
poly
;
// test bounding rects
// test bounding rects
CRect
b1
=
poly1
->
GetCornerBounds
();
CRect
b1
=
poly1
->
GetCornerBounds
();
CRect
b2
=
poly2
->
GetCornerBounds
();
CRect
b2
=
poly2
->
GetCornerBounds
();
if
(
b1
.
bottom
>
b2
.
top
if
(
b1
.
bottom
>
b2
.
top
||
b1
.
top
<
b2
.
bottom
||
b1
.
top
<
b2
.
bottom
||
b1
.
left
>
b2
.
right
||
b1
.
left
>
b2
.
right
||
b1
.
right
<
b2
.
left
)
||
b1
.
right
<
b2
.
left
)
return
0
;
return
0
;
// now test for intersecting segments
// now test for intersecting segments
bool
bInt
=
false
;
bool
bInt
=
false
;
bool
bArcInt
=
false
;
bool
bArcInt
=
false
;
for
(
int
icont1
=
0
;
icont1
<
poly1
->
GetNumContours
();
icont1
++
)
for
(
int
icont1
=
0
;
icont1
<
poly1
->
GetNumContours
();
icont1
++
)
{
{
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
is1
=
poly1
->
GetContourStart
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
int
ie1
=
poly1
->
GetContourEnd
(
icont1
);
for
(
int
ic1
=
is1
;
ic1
<=
ie1
;
ic1
++
)
for
(
int
ic1
=
is1
;
ic1
<=
ie1
;
ic1
++
)
{
{
int
xi1
=
poly1
->
GetX
(
ic1
);
int
xi1
=
poly1
->
GetX
(
ic1
);
int
yi1
=
poly1
->
GetY
(
ic1
);
int
yi1
=
poly1
->
GetY
(
ic1
);
int
xf1
,
yf1
,
style1
;
int
xf1
,
yf1
,
style1
;
if
(
ic1
<
ie1
)
if
(
ic1
<
ie1
)
{
{
xf1
=
poly1
->
GetX
(
ic1
+
1
);
xf1
=
poly1
->
GetX
(
ic1
+
1
);
yf1
=
poly1
->
GetY
(
ic1
+
1
);
yf1
=
poly1
->
GetY
(
ic1
+
1
);
}
}
else
else
{
{
xf1
=
poly1
->
GetX
(
is1
);
xf1
=
poly1
->
GetX
(
is1
);
yf1
=
poly1
->
GetY
(
is1
);
yf1
=
poly1
->
GetY
(
is1
);
}
}
style1
=
poly1
->
GetSideStyle
(
ic1
);
style1
=
poly1
->
GetSideStyle
(
ic1
);
for
(
int
icont2
=
0
;
icont2
<
poly2
->
GetNumContours
();
icont2
++
)
for
(
int
icont2
=
0
;
icont2
<
poly2
->
GetNumContours
();
icont2
++
)
{
{
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
is2
=
poly2
->
GetContourStart
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
int
ie2
=
poly2
->
GetContourEnd
(
icont2
);
for
(
int
ic2
=
is2
;
ic2
<=
ie2
;
ic2
++
)
for
(
int
ic2
=
is2
;
ic2
<=
ie2
;
ic2
++
)
{
{
int
xi2
=
poly2
->
GetX
(
ic2
);
int
xi2
=
poly2
->
GetX
(
ic2
);
int
yi2
=
poly2
->
GetY
(
ic2
);
int
yi2
=
poly2
->
GetY
(
ic2
);
int
xf2
,
yf2
,
style2
;
int
xf2
,
yf2
,
style2
;
if
(
ic2
<
ie2
)
if
(
ic2
<
ie2
)
{
{
xf2
=
poly2
->
GetX
(
ic2
+
1
);
xf2
=
poly2
->
GetX
(
ic2
+
1
);
yf2
=
poly2
->
GetY
(
ic2
+
1
);
yf2
=
poly2
->
GetY
(
ic2
+
1
);
}
}
else
else
{
{
xf2
=
poly2
->
GetX
(
is2
);
xf2
=
poly2
->
GetX
(
is2
);
yf2
=
poly2
->
GetY
(
is2
);
yf2
=
poly2
->
GetY
(
is2
);
}
}
style2
=
poly2
->
GetSideStyle
(
ic2
);
style2
=
poly2
->
GetSideStyle
(
ic2
);
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
style1
,
int
n_int
=
FindSegmentIntersections
(
xi1
,
yi1
,
xf1
,
yf1
,
style1
,
xi2
,
yi2
,
xf2
,
yf2
,
style2
);
xi2
,
yi2
,
xf2
,
yf2
,
style2
);
if
(
n_int
)
if
(
n_int
)
{
{
bInt
=
TRUE
;
bInt
=
TRUE
;
if
(
style1
!=
CPolyLine
::
STRAIGHT
||
style2
!=
CPolyLine
::
STRAIGHT
)
if
(
style1
!=
CPolyLine
::
STRAIGHT
||
style2
!=
CPolyLine
::
STRAIGHT
)
bArcInt
=
TRUE
;
bArcInt
=
TRUE
;
break
;
break
;
}
}
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
bArcInt
)
if
(
bArcInt
)
break
;
break
;
}
}
if
(
!
bInt
)
if
(
!
bInt
)
return
0
;
return
0
;
if
(
bArcInt
)
if
(
bArcInt
)
return
2
;
return
2
;
return
1
;
return
1
;
}
}
/**
/**
* Function CombineAreas
* Function CombineAreas
* If possible, combine 2 copper areas
* If possible, combine 2 copper areas
* area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList
* area_ref must be BEFORE area_to_combine in m_ZoneDescriptorList
* area_to_combine will be deleted, if areas are combined
* area_to_combine will be deleted, if areas are combined
* @return : 0 if no intersection
* @return : 0 if no intersection
* 1 if intersection
* 1 if intersection
* 2 if arcs intersect
* 2 if arcs intersect
*/
*/
int
BOARD
::
CombineAreas
(
ZONE_CONTAINER
*
area_ref
,
ZONE_CONTAINER
*
area_to_combine
)
int
BOARD
::
CombineAreas
(
ZONE_CONTAINER
*
area_ref
,
ZONE_CONTAINER
*
area_to_combine
)
{
{
if
(
area_ref
==
area_to_combine
)
if
(
area_ref
==
area_to_combine
)
ASSERT
(
0
);
ASSERT
(
0
);
#if 0
#if 0
// test for intersection
// test for intersection
int test = TestAreaIntersection( area_ref, area_to_combine );
int test = TestAreaIntersection( area_ref, area_to_combine );
if( test != 1 )
if( test != 1 )
return test; // no intersection
return test; // no intersection
#endif
#endif
// polygons intersect, combine them
// polygons intersect, combine them
CPolyLine
*
poly1
=
area_ref
->
poly
;
CPolyLine
*
poly1
=
area_ref
->
poly
;
CPolyLine
*
poly2
=
area_to_combine
->
poly
;
CPolyLine
*
poly2
=
area_to_combine
->
poly
;
std
::
vector
<
CArc
>
arc_array1
;
std
::
vector
<
CArc
>
arc_array1
;
std
::
vector
<
CArc
>
arc_array2
;
std
::
vector
<
CArc
>
arc_array2
;
poly1
->
MakeGpcPoly
(
-
1
,
&
arc_array1
);
poly1
->
MakeGpcPoly
(
-
1
,
&
arc_array1
);
poly2
->
MakeGpcPoly
(
-
1
,
&
arc_array2
);
poly2
->
MakeGpcPoly
(
-
1
,
&
arc_array2
);
int
n_ext_cont1
=
0
;
int
n_ext_cont1
=
0
;
for
(
int
ic
=
0
;
ic
<
poly1
->
GetGpcPoly
()
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
poly1
->
GetGpcPoly
()
->
num_contours
;
ic
++
)
if
(
!
(
(
poly1
->
GetGpcPoly
()
->
hole
)[
ic
]
)
)
if
(
!
(
(
poly1
->
GetGpcPoly
()
->
hole
)[
ic
]
)
)
n_ext_cont1
++
;
n_ext_cont1
++
;
int
n_ext_cont2
=
0
;
int
n_ext_cont2
=
0
;
for
(
int
ic
=
0
;
ic
<
poly2
->
GetGpcPoly
()
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
poly2
->
GetGpcPoly
()
->
num_contours
;
ic
++
)
if
(
!
(
(
poly2
->
GetGpcPoly
()
->
hole
)[
ic
]
)
)
if
(
!
(
(
poly2
->
GetGpcPoly
()
->
hole
)[
ic
]
)
)
n_ext_cont2
++
;
n_ext_cont2
++
;
gpc_polygon
*
union_gpc
=
new
gpc_polygon
;
gpc_polygon
*
union_gpc
=
new
gpc_polygon
;
gpc_polygon_clip
(
GPC_UNION
,
poly1
->
GetGpcPoly
(),
poly2
->
GetGpcPoly
(),
union_gpc
);
gpc_polygon_clip
(
GPC_UNION
,
poly1
->
GetGpcPoly
(),
poly2
->
GetGpcPoly
(),
union_gpc
);
// get number of outside contours
// get number of outside contours
int
n_union_ext_cont
=
0
;
int
n_union_ext_cont
=
0
;
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
if
(
!
(
(
union_gpc
->
hole
)[
ic
]
)
)
if
(
!
(
(
union_gpc
->
hole
)[
ic
]
)
)
n_union_ext_cont
++
;
n_union_ext_cont
++
;
// if no intersection, free new gpc and return
// if no intersection, free new gpc and return
if
(
n_union_ext_cont
==
n_ext_cont1
+
n_ext_cont2
)
if
(
n_union_ext_cont
==
n_ext_cont1
+
n_ext_cont2
)
{
{
gpc_free_polygon
(
union_gpc
);
gpc_free_polygon
(
union_gpc
);
delete
union_gpc
;
delete
union_gpc
;
return
0
;
return
0
;
}
}
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
// intersection, replace area_ref->m_Poly with combined areas and remove area_to_combine
RemoveArea
(
area_to_combine
);
RemoveArea
(
area_to_combine
);
area_ref
->
m_Poly
->
RemoveAllContours
();
area_ref
->
m_Poly
->
RemoveAllContours
();
// create area with external contour
// create area with external contour
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
{
{
if
(
!
(
union_gpc
->
hole
)[
ic
]
)
if
(
!
(
union_gpc
->
hole
)[
ic
]
)
{
{
// external contour, replace this poly
// external contour, replace this poly
for
(
int
i
=
0
;
i
<
union_gpc
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
union_gpc
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
x
;
int
x
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
x
;
int
y
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
y
;
int
y
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
y
;
if
(
i
==
0
)
if
(
i
==
0
)
{
{
area_ref
->
m_Poly
->
Start
(
area_ref
->
GetLayer
(),
0
,
0
,
x
,
y
,
area_ref
->
m_Poly
->
GetHatchStyle
()
);
area_ref
->
m_Poly
->
Start
(
area_ref
->
GetLayer
(),
0
,
0
,
x
,
y
,
area_ref
->
m_Poly
->
GetHatchStyle
()
);
}
}
else
else
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
}
}
area_ref
->
m_Poly
->
Close
();
area_ref
->
m_Poly
->
Close
();
}
}
}
}
// add holes
// add holes
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
for
(
int
ic
=
0
;
ic
<
union_gpc
->
num_contours
;
ic
++
)
{
{
if
(
(
union_gpc
->
hole
)[
ic
]
)
if
(
(
union_gpc
->
hole
)[
ic
]
)
{
{
// hole
// hole
for
(
int
i
=
0
;
i
<
union_gpc
->
contour
[
ic
].
num_vertices
;
i
++
)
for
(
int
i
=
0
;
i
<
union_gpc
->
contour
[
ic
].
num_vertices
;
i
++
)
{
{
int
x
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
x
;
int
x
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
x
;
int
y
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
y
;
int
y
=
(
(
union_gpc
->
contour
)[
ic
].
vertex
)[
i
].
y
;
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
area_ref
->
m_Poly
->
AppendCorner
(
x
,
y
);
}
}
area_ref
->
m_Poly
->
Close
();
area_ref
->
m_Poly
->
Close
();
}
}
}
}
area_ref
->
utility
=
1
;
area_ref
->
utility
=
1
;
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array1
);
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array1
);
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array2
);
area_ref
->
m_Poly
->
RestoreArcs
(
&
arc_array2
);
area_ref
->
m_Poly
->
Draw
();
area_ref
->
m_Poly
->
Draw
();
gpc_free_polygon
(
union_gpc
);
gpc_free_polygon
(
union_gpc
);
delete
union_gpc
;
delete
union_gpc
;
return
1
;
return
1
;
}
}
#if 0
#if 0
void dra_areas( CDlgLog* log, int copper_layers,
void dra_areas( CDlgLog* log, int copper_layers,
int units, BOOL check_unrouted,
int units, BOOL check_unrouted,
CArray<CPolyLine> * board_outline,
CArray<CPolyLine> * board_outline,
DesignRules* dr, DRErrorList* drelist )
DesignRules* dr, DRErrorList* drelist )
{
{
CString d_str, x_str, y_str;
CString d_str, x_str, y_str;
CString str;
CString str;
CString str2;
CString str2;
long nerrors = 0;
long nerrors = 0;
// now iterate through all areas
// now iterate through all areas
for( int ia = 0; ia<net->nareas; ia++ )
for( int ia = 0; ia<net->nareas; ia++ )
{
{
carea* a = &net->area[ia];
carea* a = &net->area[ia];
// iterate through all nets again
// iterate through all nets again
POSITION pos2 = pos;
POSITION pos2 = pos;
void* ptr2;
void* ptr2;
CString name2;
CString name2;
while( pos2 != NULL )
while( pos2 != NULL )
{
{
m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 );
m_nlist->m_map.GetNextAssoc( pos2, name2, ptr2 );
cnet* net2 = (cnet*) ptr2;
cnet* net2 = (cnet*) ptr2;
for( int ia2 = 0; ia2<net2->nareas; ia2++ )
for( int ia2 = 0; ia2<net2->nareas; ia2++ )
{
{
carea* a2 = &net2->area[ia2];
carea* a2 = &net2->area[ia2];
// test for same layer
// test for same layer
if( a->poly->GetLayer() == a2->poly->GetLayer() )
if( a->poly->GetLayer() == a2->poly->GetLayer() )
{
{
// test for points inside one another
// test for points inside one another
for( int ic = 0; ic<a->poly->GetNumCorners(); ic++ )
for( int ic = 0; ic<a->poly->GetNumCorners(); ic++ )
{
{
int x = a->poly->GetX( ic );
int x = a->poly->GetX( ic );
int y = a->poly->GetY( ic );
int y = a->poly->GetY( ic );
if( a2->poly->TestPointInside( x, y ) )
if( a2->poly->TestPointInside( x, y ) )
{
{
// COPPERAREA_COPPERAREA error
// COPPERAREA_COPPERAREA error
id id_a = net->id;
id id_a = net->id;
id_a.st = ID_AREA;
id_a.st = ID_AREA;
id_a.i = ia;
id_a.i = ia;
id_a.sst = ID_SEL_CORNER;
id_a.sst = ID_SEL_CORNER;
id_a.ii = ic;
id_a.ii = ic;
str.Format(
str.Format(
"%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n",
"%ld: \"%s\" copper area inside \"%s\" inside copper area\r\n",
nerrors + 1,
nerrors + 1,
net->name,
net->name,
net2->name );
net2->name );
DRError* dre = drelist->Add( nerrors,
DRError* dre = drelist->Add( nerrors,
DRError::COPPERAREA_INSIDE_COPPERAREA,
DRError::COPPERAREA_INSIDE_COPPERAREA,
&str,
&str,
&net->name,
&net->name,
&net2->name,
&net2->name,
id_a,
id_a,
id_a,
id_a,
x,
x,
y,
y,
x,
x,
y,
y,
0,
0,
0 );
0 );
if( dre )
if( dre )
{
{
nerrors++;
nerrors++;
if( log )
if( log )
log->AddLine( str );
log->AddLine( str );
}
}
}
}
}
}
for( int ic2 = 0; ic2<a2->poly->GetNumCorners(); ic2++ )
for( int ic2 = 0; ic2<a2->poly->GetNumCorners(); ic2++ )
{
{
int x = a2->poly->GetX( ic2 );
int x = a2->poly->GetX( ic2 );
int y = a2->poly->GetY( ic2 );
int y = a2->poly->GetY( ic2 );
if( a->poly->TestPointInside( x, y ) )
if( a->poly->TestPointInside( x, y ) )
{
{
// COPPERAREA_COPPERAREA error
// COPPERAREA_COPPERAREA error
id id_a = net2->id;
id id_a = net2->id;
id_a.st = ID_AREA;
id_a.st = ID_AREA;
id_a.i = ia2;
id_a.i = ia2;
id_a.sst = ID_SEL_CORNER;
id_a.sst = ID_SEL_CORNER;
id_a.ii = ic2;
id_a.ii = ic2;
str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n",
str.Format( "%ld: \"%s\" copper area inside \"%s\" copper area\r\n",
nerrors + 1, net2->name, net->name );
nerrors + 1, net2->name, net->name );
DRError* dre = drelist->Add( nerrors,
DRError* dre = drelist->Add( nerrors,
DRError::COPPERAREA_INSIDE_COPPERAREA,
DRError::COPPERAREA_INSIDE_COPPERAREA,
&str,
&str,
&net2->name,
&net2->name,
&net->name,
&net->name,
id_a,
id_a,
id_a,
id_a,
x,
x,
y,
y,
x,
x,
y,
y,
0,
0,
0 );
0 );
if( dre )
if( dre )
{
{
nerrors++;
nerrors++;
if( log )
if( log )
log->AddLine( str );
log->AddLine( str );
}
}
}
}
}
}
// now test spacing between areas
// now test spacing between areas
for( int icont = 0; icont<a->poly->GetNumContours(); icont++ )
for( int icont = 0; icont<a->poly->GetNumContours(); icont++ )
{
{
int ic_start = a->poly->GetContourStart( icont );
int ic_start = a->poly->GetContourStart( icont );
int ic_end = a->poly->GetContourEnd( icont );
int ic_end = a->poly->GetContourEnd( icont );
for( int ic = ic_start; ic<=ic_end; ic++ )
for( int ic = ic_start; ic<=ic_end; ic++ )
{
{
id id_a = net->id;
id id_a = net->id;
id_a.st = ID_AREA;
id_a.st = ID_AREA;
id_a.i = ia;
id_a.i = ia;
id_a.sst = ID_SIDE;
id_a.sst = ID_SIDE;
id_a.ii = ic;
id_a.ii = ic;
int ax1 = a->poly->GetX( ic );
int ax1 = a->poly->GetX( ic );
int ay1 = a->poly->GetY( ic );
int ay1 = a->poly->GetY( ic );
int ax2, ay2;
int ax2, ay2;
if( ic == ic_end )
if( ic == ic_end )
{
{
ax2 = a->poly->GetX( ic_start );
ax2 = a->poly->GetX( ic_start );
ay2 = a->poly->GetY( ic_start );
ay2 = a->poly->GetY( ic_start );
}
}
else
else
{
{
ax2 = a->poly->GetX( ic + 1 );
ax2 = a->poly->GetX( ic + 1 );
ay2 = a->poly->GetY( ic + 1 );
ay2 = a->poly->GetY( ic + 1 );
}
}
int astyle = a->poly->GetSideStyle( ic );
int astyle = a->poly->GetSideStyle( ic );
for( int icont2 = 0; icont2<a2->poly->GetNumContours(); icont2++ )
for( int icont2 = 0; icont2<a2->poly->GetNumContours(); icont2++ )
{
{
int ic_start2 = a2->poly->GetContourStart( icont2 );
int ic_start2 = a2->poly->GetContourStart( icont2 );
int ic_end2 = a2->poly->GetContourEnd( icont2 );
int ic_end2 = a2->poly->GetContourEnd( icont2 );
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
for( int ic2 = ic_start2; ic2<=ic_end2; ic2++ )
{
{
id id_b = net2->id;
id id_b = net2->id;
id_b.st = ID_AREA;
id_b.st = ID_AREA;
id_b.i = ia2;
id_b.i = ia2;
id_b.sst = ID_SIDE;
id_b.sst = ID_SIDE;
id_b.ii = ic2;
id_b.ii = ic2;
int bx1 = a2->poly->GetX( ic2 );
int bx1 = a2->poly->GetX( ic2 );
int by1 = a2->poly->GetY( ic2 );
int by1 = a2->poly->GetY( ic2 );
int bx2, by2;
int bx2, by2;
if( ic2 == ic_end2 )
if( ic2 == ic_end2 )
{
{
bx2 = a2->poly->GetX( ic_start2 );
bx2 = a2->poly->GetX( ic_start2 );
by2 = a2->poly->GetY( ic_start2 );
by2 = a2->poly->GetY( ic_start2 );
}
}
else
else
{
{
bx2 = a2->poly->GetX( ic2 + 1 );
bx2 = a2->poly->GetX( ic2 + 1 );
by2 = a2->poly->GetY( ic2 + 1 );
by2 = a2->poly->GetY( ic2 + 1 );
}
}
int bstyle = a2->poly->GetSideStyle( ic2 );
int bstyle = a2->poly->GetSideStyle( ic2 );
int x, y;
int x, y;
int d = ::GetClearanceBetweenSegments( bx1,
int d = ::GetClearanceBetweenSegments( bx1,
by1,
by1,
bx2,
bx2,
by2,
by2,
bstyle,
bstyle,
0,
0,
ax1,
ax1,
ay1,
ay1,
ax2,
ax2,
ay2,
ay2,
astyle,
astyle,
0,
0,
dr->copper_copper,
dr->copper_copper,
&x,
&x,
&y );
&y );
if( d < dr->copper_copper )
if( d < dr->copper_copper )
{
{
// COPPERAREA_COPPERAREA error
// COPPERAREA_COPPERAREA error
::MakeCStringFromDimension( &d_str,
::MakeCStringFromDimension( &d_str,
d,
d,
units,
units,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
TRUE,
1 );
1 );
::MakeCStringFromDimension( &x_str,
::MakeCStringFromDimension( &x_str,
x,
x,
units,
units,
FALSE,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
1 );
1 );
::MakeCStringFromDimension( &y_str,
::MakeCStringFromDimension( &y_str,
y,
y,
units,
units,
FALSE,
FALSE,
TRUE,
TRUE,
TRUE,
TRUE,
1 );
1 );
str.Format(
str.Format(
"%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n",
"%ld: \"%s\" copper area to \"%s\" copper area = %s, x=%s, y=%s\r\n",
nerrors + 1,
nerrors + 1,
net->name,
net->name,
net2->name,
net2->name,
d_str,
d_str,
x_str,
x_str,
y_str );
y_str );
DRError* dre = drelist->Add(
DRError* dre = drelist->Add(
nerrors,
nerrors,
DRError::
DRError::
COPPERAREA_COPPERAREA,
COPPERAREA_COPPERAREA,
&str,
&str,
&net->name,
&net->name,
&net2->name,
&net2->name,
id_a,
id_a,
id_b,
id_b,
x,
x,
y,
y,
x,
x,
y,
y,
0,
0,
0 );
0 );
if( dre )
if( dre )
{
{
nerrors++;
nerrors++;
if( log )
if( log )
log->AddLine( str );
log->AddLine( str );
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
#endif
#endif
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