More work on CPOLYGONS_LIST class.
This commit is contained in:
parent
6fcd9eb8a6
commit
2e6969fe96
|
@ -91,8 +91,8 @@ static void BuildPadShapeThickOutlineAsPolygon( D_PAD* aPad,
|
||||||
for( unsigned ii = 0, jj = corners.size() - 1; ii < corners.size(); jj = ii, ii++ )
|
for( unsigned ii = 0, jj = corners.size() - 1; ii < corners.size(); jj = ii, ii++ )
|
||||||
{
|
{
|
||||||
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
|
||||||
wxPoint( corners[jj].x, corners[jj].y ),
|
corners.GetPos( jj ),
|
||||||
wxPoint( corners[ii].x, corners[ii].y ),
|
corners.GetPos( ii ),
|
||||||
aCircleToSegmentsCount, aWidth );
|
aCircleToSegmentsCount, aWidth );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,14 +289,13 @@ void EDA_3D_CANVAS::BuildBoard3DView()
|
||||||
KI_POLYGON_SET polysetHoles;
|
KI_POLYGON_SET polysetHoles;
|
||||||
|
|
||||||
// Add polygons, without holes
|
// Add polygons, without holes
|
||||||
AddPolygonCornersToKiPolygonList( bufferPolys, currLayerPolyset );
|
bufferPolys.ExportTo( currLayerPolyset );
|
||||||
|
|
||||||
// Add holes in polygon list
|
// Add holes in polygon list
|
||||||
currLayerHoles.insert( currLayerHoles.begin(),
|
currLayerHoles.Append( allLayerHoles );
|
||||||
allLayerHoles.begin(), allLayerHoles.end() );
|
|
||||||
|
|
||||||
if( currLayerHoles.size() > 0 )
|
if( currLayerHoles.size() > 0 )
|
||||||
AddPolygonCornersToKiPolygonList( currLayerHoles, polysetHoles );
|
currLayerHoles.ExportTo( polysetHoles );
|
||||||
|
|
||||||
// Merge polygons, remove holes
|
// Merge polygons, remove holes
|
||||||
currLayerPolyset -= polysetHoles;
|
currLayerPolyset -= polysetHoles;
|
||||||
|
@ -309,7 +308,7 @@ void EDA_3D_CANVAS::BuildBoard3DView()
|
||||||
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
||||||
|
|
||||||
bufferPolys.clear();
|
bufferPolys.clear();
|
||||||
CopyPolygonsFromKiPolygonListToPolysList( currLayerPolyset, bufferPolys );
|
bufferPolys.ImportFrom( currLayerPolyset );
|
||||||
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
|
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
|
||||||
thickness,
|
thickness,
|
||||||
g_Parm_3D_Visu.m_BiuTo3Dunits );
|
g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||||
|
@ -410,7 +409,7 @@ void EDA_3D_CANVAS::BuildBoard3DView()
|
||||||
|
|
||||||
KI_POLYGON_SET currLayerPolyset;
|
KI_POLYGON_SET currLayerPolyset;
|
||||||
KI_POLYGON_SET polyset;
|
KI_POLYGON_SET polyset;
|
||||||
AddPolygonCornersToKiPolygonList( bufferPolys, polyset );
|
bufferPolys.ExportTo( polyset );
|
||||||
// merge polys:
|
// merge polys:
|
||||||
currLayerPolyset += polyset;
|
currLayerPolyset += polyset;
|
||||||
|
|
||||||
|
@ -430,7 +429,7 @@ void EDA_3D_CANVAS::BuildBoard3DView()
|
||||||
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) );
|
||||||
|
|
||||||
bufferPolys.clear();
|
bufferPolys.clear();
|
||||||
CopyPolygonsFromKiPolygonListToPolysList( currLayerPolyset, bufferPolys );
|
bufferPolys.ImportFrom( currLayerPolyset );
|
||||||
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
|
Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos,
|
||||||
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
thickness, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ static inline void SetNormalZneg()
|
||||||
* from Z position = aZpos to aZpos + aHeight
|
* from Z position = aZpos to aZpos + aHeight
|
||||||
* Used to create the vertical sides of 3D horizontal shapes with thickness.
|
* Used to create the vertical sides of 3D horizontal shapes with thickness.
|
||||||
*/
|
*/
|
||||||
static void Draw3D_VerticalPolygonalCylinder( const std::vector<CPolyPt>& aPolysList,
|
static void Draw3D_VerticalPolygonalCylinder( const CPOLYGONS_LIST& aPolysList,
|
||||||
int aHeight, int aZpos,
|
int aHeight, int aZpos,
|
||||||
bool aInside, double aBiuTo3DUnits )
|
bool aInside, double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
|
@ -100,19 +100,19 @@ static void Draw3D_VerticalPolygonalCylinder( const std::vector<CPolyPt>& aPolys
|
||||||
{
|
{
|
||||||
unsigned jj = ii + 1;
|
unsigned jj = ii + 1;
|
||||||
|
|
||||||
if( aPolysList[ii].end_contour || jj >= aPolysList.size() )
|
if( aPolysList.IsEndContour( ii ) || jj >= aPolysList.size() )
|
||||||
{
|
{
|
||||||
jj = startContour;
|
jj = startContour;
|
||||||
startContour = ii + 1;
|
startContour = ii + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the 4 vertices of each GL_QUAD
|
// Build the 4 vertices of each GL_QUAD
|
||||||
coords[0].x = aPolysList[ii].x;
|
coords[0].x = aPolysList.GetX( ii );
|
||||||
coords[0].y = -aPolysList[ii].y;
|
coords[0].y = -aPolysList.GetY( ii );
|
||||||
coords[1].x = coords[0].x;
|
coords[1].x = coords[0].x;
|
||||||
coords[1].y = coords[0].y; // only z change
|
coords[1].y = coords[0].y; // only z change
|
||||||
coords[2].x = aPolysList[jj].x;
|
coords[2].x = aPolysList.GetX( jj );
|
||||||
coords[2].y = -aPolysList[jj].y;
|
coords[2].y = -aPolysList.GetY( jj );
|
||||||
coords[3].x = coords[2].x;
|
coords[3].x = coords[2].x;
|
||||||
coords[3].y = coords[2].y; // only z change
|
coords[3].y = coords[2].y; // only z change
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ void SetGLColor( EDA_COLOR_T color )
|
||||||
* The top side is located at aZpos + aThickness / 2
|
* The top side is located at aZpos + aThickness / 2
|
||||||
* The bottom side is located at aZpos - aThickness / 2
|
* The bottom side is located at aZpos - aThickness / 2
|
||||||
*/
|
*/
|
||||||
void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList,
|
void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList,
|
||||||
int aZpos, int aThickness, double aBiuTo3DUnits )
|
int aZpos, int aThickness, double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
GLUtesselator* tess = gluNewTess();
|
GLUtesselator* tess = gluNewTess();
|
||||||
|
@ -164,7 +164,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList,
|
||||||
// gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
|
// gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
|
||||||
|
|
||||||
// Draw solid areas contained in this list
|
// Draw solid areas contained in this list
|
||||||
std::vector<CPolyPt> polylist = aPolysList; // temporary copy for gluTessVertex
|
CPOLYGONS_LIST polylist = aPolysList; // temporary copy for gluTessVertex
|
||||||
|
|
||||||
for( int side = 0; side < 2; side++ )
|
for( int side = 0; side < 2; side++ )
|
||||||
{
|
{
|
||||||
|
@ -179,15 +179,15 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList,
|
||||||
startContour = 0;
|
startContour = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
v_data[0] = polylist[ii].x * aBiuTo3DUnits;
|
v_data[0] = polylist.GetX( ii ) * aBiuTo3DUnits;
|
||||||
v_data[1] = -polylist[ii].y * aBiuTo3DUnits;
|
v_data[1] = -polylist.GetY( ii ) * aBiuTo3DUnits;
|
||||||
// gluTessVertex store pointers on data, not data, so do not store
|
// gluTessVertex store pointers on data, not data, so do not store
|
||||||
// different corners values in a temporary variable
|
// different corners values in a temporary variable
|
||||||
// but send pointer on each CPolyPt value in polylist
|
// but send pointer on each CPolyPt value in polylist
|
||||||
// before calling gluDeleteTess
|
// before calling gluDeleteTess
|
||||||
gluTessVertex( tess, v_data, &polylist[ii] );
|
gluTessVertex( tess, v_data, &polylist[ii] );
|
||||||
|
|
||||||
if( polylist[ii].end_contour == 1 )
|
if( polylist.IsEndContour( ii ) )
|
||||||
{
|
{
|
||||||
gluTessEndContour( tess );
|
gluTessEndContour( tess );
|
||||||
gluTessEndPolygon( tess );
|
gluTessEndPolygon( tess );
|
||||||
|
@ -220,11 +220,11 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector<CPolyPt>& aPolysList,
|
||||||
* The first polygon is the main polygon, others are holes
|
* The first polygon is the main polygon, others are holes
|
||||||
* See Draw3D_SolidHorizontalPolyPolygons for more info
|
* See Draw3D_SolidHorizontalPolyPolygons for more info
|
||||||
*/
|
*/
|
||||||
void Draw3D_SolidHorizontalPolygonWithHoles( const std::vector<CPolyPt>& aPolysList,
|
void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList,
|
||||||
int aZpos, int aThickness,
|
int aZpos, int aThickness,
|
||||||
double aBiuTo3DUnits )
|
double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
std::vector<CPolyPt> polygon;
|
CPOLYGONS_LIST polygon;
|
||||||
|
|
||||||
ConvertPolysListWithHolesToOnePolygon( aPolysList, polygon );
|
ConvertPolysListWithHolesToOnePolygon( aPolysList, polygon );
|
||||||
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits );
|
Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits );
|
||||||
|
@ -241,7 +241,7 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
|
||||||
int aZpos, double aBiuTo3DUnits )
|
int aZpos, double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
const int slice = SEGM_PER_CIRCLE;
|
const int slice = SEGM_PER_CIRCLE;
|
||||||
std::vector <CPolyPt> outer_cornerBuffer;
|
CPOLYGONS_LIST outer_cornerBuffer;
|
||||||
|
|
||||||
TransformCircleToPolygon( outer_cornerBuffer, aCenterPos,
|
TransformCircleToPolygon( outer_cornerBuffer, aCenterPos,
|
||||||
aRadius + (aThickness / 2), slice );
|
aRadius + (aThickness / 2), slice );
|
||||||
|
@ -249,7 +249,7 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
|
||||||
std::vector<S3D_VERTEX> coords;
|
std::vector<S3D_VERTEX> coords;
|
||||||
coords.resize( 4 );
|
coords.resize( 4 );
|
||||||
|
|
||||||
std::vector <CPolyPt> inner_cornerBuffer;
|
CPOLYGONS_LIST inner_cornerBuffer;
|
||||||
if( aThickness ) // build the the vertical inner polygon (hole)
|
if( aThickness ) // build the the vertical inner polygon (hole)
|
||||||
TransformCircleToPolygon( inner_cornerBuffer, aCenterPos,
|
TransformCircleToPolygon( inner_cornerBuffer, aCenterPos,
|
||||||
aRadius - (aThickness / 2), slice );
|
aRadius - (aThickness / 2), slice );
|
||||||
|
@ -269,9 +269,8 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius,
|
||||||
{
|
{
|
||||||
// draw top (front) and bottom (back) horizontal sides (rings)
|
// draw top (front) and bottom (back) horizontal sides (rings)
|
||||||
SetNormalZpos();
|
SetNormalZpos();
|
||||||
outer_cornerBuffer.insert( outer_cornerBuffer.end(),
|
outer_cornerBuffer.Append( inner_cornerBuffer );
|
||||||
inner_cornerBuffer.begin(), inner_cornerBuffer.end() );
|
CPOLYGONS_LIST polygon;
|
||||||
std::vector<CPolyPt> polygon;
|
|
||||||
|
|
||||||
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
|
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
|
||||||
// draw top (front) horizontal ring
|
// draw top (front) horizontal ring
|
||||||
|
@ -303,7 +302,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
||||||
const int slice = SEGM_PER_CIRCLE;
|
const int slice = SEGM_PER_CIRCLE;
|
||||||
|
|
||||||
// Build the points to approximate oblong cylinder by segments
|
// Build the points to approximate oblong cylinder by segments
|
||||||
std::vector <CPolyPt> outer_cornerBuffer;
|
CPOLYGONS_LIST outer_cornerBuffer;
|
||||||
|
|
||||||
int segm_width = (aRadius * 2) + aThickness;
|
int segm_width = (aRadius * 2) + aThickness;
|
||||||
TransformRoundedEndsSegmentToPolygon( outer_cornerBuffer, aAxis1Pos,
|
TransformRoundedEndsSegmentToPolygon( outer_cornerBuffer, aAxis1Pos,
|
||||||
|
@ -316,7 +315,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
||||||
|
|
||||||
if( aThickness )
|
if( aThickness )
|
||||||
{
|
{
|
||||||
std::vector <CPolyPt> inner_cornerBuffer;
|
CPOLYGONS_LIST inner_cornerBuffer;
|
||||||
segm_width = aRadius * 2;
|
segm_width = aRadius * 2;
|
||||||
TransformRoundedEndsSegmentToPolygon( inner_cornerBuffer, aAxis1Pos,
|
TransformRoundedEndsSegmentToPolygon( inner_cornerBuffer, aAxis1Pos,
|
||||||
aAxis2Pos, slice, segm_width );
|
aAxis2Pos, slice, segm_width );
|
||||||
|
@ -328,11 +327,9 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
||||||
|
|
||||||
// Build the horizontal full polygon shape
|
// Build the horizontal full polygon shape
|
||||||
// (outer polygon shape - inner polygon shape)
|
// (outer polygon shape - inner polygon shape)
|
||||||
outer_cornerBuffer.insert( outer_cornerBuffer.end(),
|
outer_cornerBuffer.Append( inner_cornerBuffer );
|
||||||
inner_cornerBuffer.begin(),
|
|
||||||
inner_cornerBuffer.end() );
|
|
||||||
|
|
||||||
std::vector<CPolyPt> polygon;
|
CPOLYGONS_LIST polygon;
|
||||||
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
|
ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon );
|
||||||
|
|
||||||
// draw top (front) horizontal side (ring)
|
// draw top (front) horizontal side (ring)
|
||||||
|
@ -360,7 +357,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos,
|
||||||
void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
|
void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd,
|
||||||
int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits )
|
int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits )
|
||||||
{
|
{
|
||||||
std::vector <CPolyPt> cornerBuffer;
|
CPOLYGONS_LIST cornerBuffer;
|
||||||
const int slice = SEGM_PER_CIRCLE;
|
const int slice = SEGM_PER_CIRCLE;
|
||||||
|
|
||||||
TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth );
|
TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth );
|
||||||
|
@ -375,7 +372,7 @@ void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint,
|
||||||
{
|
{
|
||||||
const int slice = SEGM_PER_CIRCLE;
|
const int slice = SEGM_PER_CIRCLE;
|
||||||
|
|
||||||
std::vector <CPolyPt> cornerBuffer;
|
CPOLYGONS_LIST cornerBuffer;
|
||||||
TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle,
|
TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle,
|
||||||
slice, aWidth );
|
slice, aWidth );
|
||||||
|
|
||||||
|
|
|
@ -32,82 +32,6 @@
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
|
|
||||||
/* Helper functions:
|
|
||||||
* We are using a lots polygons in calculations.
|
|
||||||
* and we are using 2 descriptions,
|
|
||||||
* one easy to use with boost::polygon (KI_POLYGON_SET)
|
|
||||||
* one easy to use in zones and in draw functions (CPOLYGONS_LIST)
|
|
||||||
* Copy polygons from a KI_POLYGON_SET set of polygons to
|
|
||||||
* a CPOLYGONS_LIST polygon list
|
|
||||||
* Therefore we need conversion functions between these 2 descriptions
|
|
||||||
*/
|
|
||||||
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
|
|
||||||
CPOLYGONS_LIST& aPolysList )
|
|
||||||
{
|
|
||||||
for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ )
|
|
||||||
{
|
|
||||||
KI_POLYGON& poly = aKiPolyList[ii];
|
|
||||||
CPolyPt corner( 0, 0, false );
|
|
||||||
|
|
||||||
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
|
||||||
{
|
|
||||||
KI_POLY_POINT point = *(poly.begin() + jj);
|
|
||||||
corner.x = point.x();
|
|
||||||
corner.y = point.y();
|
|
||||||
corner.end_contour = false;
|
|
||||||
aPolysList.push_back( corner );
|
|
||||||
}
|
|
||||||
|
|
||||||
aPolysList.back().end_contour = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function AddPolygonCornersToKiPolygonList
|
|
||||||
* This function adds a KI_POLYGON_SET description to a
|
|
||||||
* CPOLYGONS_LIST description
|
|
||||||
* @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
|
|
||||||
* @param aPolysList = destination (set of polygons)
|
|
||||||
*/
|
|
||||||
void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer,
|
|
||||||
KI_POLYGON_SET& aKiPolyList )
|
|
||||||
{
|
|
||||||
std::vector<KI_POLY_POINT> cornerslist;
|
|
||||||
unsigned corners_count = aCornersBuffer.size();
|
|
||||||
|
|
||||||
// Count the number of polygons in aCornersBuffer
|
|
||||||
int polycount = 0;
|
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < corners_count; ii++ )
|
|
||||||
{
|
|
||||||
if( aCornersBuffer[ii].end_contour )
|
|
||||||
polycount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
aKiPolyList.reserve( polycount );
|
|
||||||
|
|
||||||
for( unsigned icnt = 0; icnt < corners_count; )
|
|
||||||
{
|
|
||||||
KI_POLYGON poly;
|
|
||||||
cornerslist.clear();
|
|
||||||
|
|
||||||
unsigned ii;
|
|
||||||
|
|
||||||
for( ii = icnt; ii < aCornersBuffer.size(); ii++ )
|
|
||||||
{
|
|
||||||
cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) );
|
|
||||||
|
|
||||||
if( aCornersBuffer[ii].end_contour )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
|
||||||
aKiPolyList.push_back( poly );
|
|
||||||
icnt = ii + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformCircleToPolygon
|
* Function TransformCircleToPolygon
|
||||||
|
|
|
@ -35,33 +35,6 @@
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <PolyLine.h>
|
#include <PolyLine.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function CopyPolygonsFromKiPolygonListToPolysList
|
|
||||||
* We are using a lots polygons in calculations.
|
|
||||||
* and we are using 2 descriptions,
|
|
||||||
* one easy to use with boost::polygon (KI_POLYGON_SET)
|
|
||||||
* one easy to use in zones and in draw functions (CPOLYGONS_LIST)
|
|
||||||
* Copy polygons from a KI_POLYGON_SET set of polygons to
|
|
||||||
* a CPOLYGONS_LIST corner polygon list
|
|
||||||
* Therefore we need conversion functions between these 2 descriptions
|
|
||||||
* This function converts a KI_POLYGON_SET description to a
|
|
||||||
* CPOLYGONS_LIST description
|
|
||||||
* @param aKiPolyList = source (set of polygons)
|
|
||||||
* @param aPolysList = destination (set of polygons using CPolyPt corners descr)
|
|
||||||
*/
|
|
||||||
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
|
|
||||||
CPOLYGONS_LIST& aPolysList );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function AddPolygonCornersToKiPolygonList
|
|
||||||
* This function adds a KI_POLYGON_SET description to a
|
|
||||||
* CPOLYGONS_LIST description
|
|
||||||
* @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
|
|
||||||
* @param aPolysList = destination (set of polygons)
|
|
||||||
*/
|
|
||||||
void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer,
|
|
||||||
KI_POLYGON_SET& aKiPolyList );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TransformCircleToPolygon
|
* Function TransformCircleToPolygon
|
||||||
* convert a circle to a polygon, using multiple straight lines
|
* convert a circle to a polygon, using multiple straight lines
|
||||||
|
|
|
@ -177,8 +177,7 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// add filled areas polygons
|
// add filled areas polygons
|
||||||
aCornerBuffer.insert( aCornerBuffer.end(), m_FilledPolysList.begin(),
|
aCornerBuffer.Append( m_FilledPolysList );
|
||||||
m_FilledPolysList.end() );
|
|
||||||
|
|
||||||
// add filled areas outlines, which are drawn with thich lines
|
// add filled areas outlines, which are drawn with thich lines
|
||||||
wxPoint seg_start, seg_end;
|
wxPoint seg_start, seg_end;
|
||||||
|
|
|
@ -202,7 +202,7 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod
|
||||||
{
|
{
|
||||||
seg_start = GetCornerPosition( ic ) + offset;
|
seg_start = GetCornerPosition( ic ) + offset;
|
||||||
|
|
||||||
if( m_Poly->m_CornersList[ic].end_contour == false && ic < GetNumCorners() - 1 )
|
if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < GetNumCorners() - 1 )
|
||||||
{
|
{
|
||||||
seg_end = GetCornerPosition( ic + 1 ) + offset;
|
seg_end = GetCornerPosition( ic + 1 ) + offset;
|
||||||
}
|
}
|
||||||
|
@ -283,16 +283,13 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
|
||||||
|
|
||||||
for( int ic = 0; ic <= imax; ic++ )
|
for( int ic = 0; ic <= imax; ic++ )
|
||||||
{
|
{
|
||||||
CPolyPt* corner = &m_FilledPolysList[ic];
|
const CPolyPt& corner = m_FilledPolysList.GetCorner( ic );
|
||||||
|
wxPoint coord( corner.x + offset.x, corner.y + offset.y );
|
||||||
wxPoint coord( corner->x + offset.x, corner->y + offset.y );
|
|
||||||
|
|
||||||
CornersBuffer.push_back( coord );
|
CornersBuffer.push_back( coord );
|
||||||
|
CornersTypeBuffer.push_back( (char) corner.m_utility );
|
||||||
CornersTypeBuffer.push_back( (char) corner->m_utility );
|
|
||||||
|
|
||||||
// the last corner of a filled area is found: draw it
|
// the last corner of a filled area is found: draw it
|
||||||
if( (corner->end_contour) || (ic == imax) )
|
if( (corner.end_contour) || (ic == imax) )
|
||||||
{
|
{
|
||||||
/* Draw the current filled area: draw segments outline first
|
/* Draw the current filled area: draw segments outline first
|
||||||
* Curiously, draw segments outline first and after draw filled polygons
|
* Curiously, draw segments outline first and after draw filled polygons
|
||||||
|
@ -418,13 +415,13 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||||
int yi = GetCornerPosition( ic ).y;
|
int yi = GetCornerPosition( ic ).y;
|
||||||
int xf, yf;
|
int xf, yf;
|
||||||
|
|
||||||
if( m_Poly->m_CornersList[ic].end_contour == false && ic < icmax )
|
if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < icmax )
|
||||||
{
|
{
|
||||||
is_close_segment = false;
|
is_close_segment = false;
|
||||||
xf = GetCornerPosition( ic + 1 ).x;
|
xf = GetCornerPosition( ic + 1 ).x;
|
||||||
yf = GetCornerPosition( ic + 1 ).y;
|
yf = GetCornerPosition( ic + 1 ).y;
|
||||||
|
|
||||||
if( (m_Poly->m_CornersList[ic + 1].end_contour) || (ic == icmax - 1) )
|
if( m_Poly->m_CornersList.IsEndContour( ic + 1 ) || (ic == icmax - 1) )
|
||||||
current_gr_mode = GR_XOR;
|
current_gr_mode = GR_XOR;
|
||||||
else
|
else
|
||||||
current_gr_mode = draw_mode;
|
current_gr_mode = draw_mode;
|
||||||
|
@ -497,8 +494,8 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos )
|
||||||
|
|
||||||
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
|
for( unsigned item_pos = 0; item_pos < lim; item_pos++ )
|
||||||
{
|
{
|
||||||
delta.x = refPos.x - m_Poly->m_CornersList[item_pos].x;
|
delta.x = refPos.x - m_Poly->m_CornersList.GetX( item_pos );
|
||||||
delta.y = refPos.y - m_Poly->m_CornersList[item_pos].y;
|
delta.y = refPos.y - m_Poly->m_CornersList.GetY( item_pos );
|
||||||
|
|
||||||
// Calculate a distance:
|
// Calculate a distance:
|
||||||
int dist = std::max( abs( delta.x ), abs( delta.y ) );
|
int dist = std::max( abs( delta.x ), abs( delta.y ) );
|
||||||
|
@ -533,7 +530,7 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||||
* the last segment of the current outline starts at current corner, and ends
|
* the last segment of the current outline starts at current corner, and ends
|
||||||
* at the first corner of the outline
|
* at the first corner of the outline
|
||||||
*/
|
*/
|
||||||
if( m_Poly->m_CornersList[item_pos].end_contour || end_segm >= lim )
|
if( m_Poly->m_CornersList.IsEndContour ( item_pos ) || end_segm >= lim )
|
||||||
{
|
{
|
||||||
unsigned tmp = first_corner_pos;
|
unsigned tmp = first_corner_pos;
|
||||||
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
|
first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline
|
||||||
|
@ -541,13 +538,12 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos )
|
||||||
}
|
}
|
||||||
|
|
||||||
// test the dist between segment and ref point
|
// test the dist between segment and ref point
|
||||||
int dist = KiROUND( GetPointToLineSegmentDistance(
|
int dist = KiROUND( GetPointToLineSegmentDistance(
|
||||||
refPos.x,
|
refPos.x, refPos.y,
|
||||||
refPos.y,
|
m_Poly->m_CornersList.GetX( item_pos ),
|
||||||
m_Poly->m_CornersList[item_pos].x,
|
m_Poly->m_CornersList.GetY( item_pos ),
|
||||||
m_Poly->m_CornersList[item_pos].y,
|
m_Poly->m_CornersList.GetX( end_segm ),
|
||||||
m_Poly->m_CornersList[end_segm].x,
|
m_Poly->m_CornersList.GetY( end_segm ) ) );
|
||||||
m_Poly->m_CornersList[end_segm].y ) );
|
|
||||||
|
|
||||||
if( dist < min_dist )
|
if( dist < min_dist )
|
||||||
{
|
{
|
||||||
|
@ -616,10 +612,10 @@ bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
|
||||||
|
|
||||||
for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ )
|
for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ )
|
||||||
{
|
{
|
||||||
if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found
|
if( m_FilledPolysList.IsEndContour( indexend ) ) // end of a filled sub-area found
|
||||||
{
|
{
|
||||||
if( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, aRefPos.x,
|
if( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend,
|
||||||
aRefPos.y ) )
|
aRefPos.x, aRefPos.y ) )
|
||||||
{
|
{
|
||||||
inside = true;
|
inside = true;
|
||||||
break;
|
break;
|
||||||
|
@ -742,9 +738,8 @@ void ZONE_CONTAINER::Move( const wxPoint& offset )
|
||||||
/* move filled areas: */
|
/* move filled areas: */
|
||||||
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
||||||
{
|
{
|
||||||
CPolyPt* corner = &m_FilledPolysList[ic];
|
m_FilledPolysList.SetX( ic, m_FilledPolysList.GetX( ic ) + offset.x );
|
||||||
corner->x += offset.x;
|
m_FilledPolysList.SetY( ic, m_FilledPolysList.GetX( ic ) + offset.y );
|
||||||
corner->y += offset.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
||||||
|
@ -763,7 +758,7 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset )
|
||||||
SetCornerPosition( ii, GetCornerPosition( ii ) + offset );
|
SetCornerPosition( ii, GetCornerPosition( ii ) + offset );
|
||||||
|
|
||||||
// Move the end point of the selected edge:
|
// Move the end point of the selected edge:
|
||||||
if( m_Poly->m_CornersList[ii].end_contour || ii == GetNumCorners() - 1 )
|
if( m_Poly->m_CornersList.IsEndContour( ii ) || ii == GetNumCorners() - 1 )
|
||||||
{
|
{
|
||||||
int icont = m_Poly->GetContour( ii );
|
int icont = m_Poly->GetContour( ii );
|
||||||
ii = m_Poly->GetContourStart( icont );
|
ii = m_Poly->GetContourStart( icont );
|
||||||
|
@ -783,13 +778,12 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
|
||||||
{
|
{
|
||||||
wxPoint pos;
|
wxPoint pos;
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ )
|
for( unsigned ic = 0; ic < m_Poly->m_CornersList.size(); ic++ )
|
||||||
{
|
{
|
||||||
pos.x = m_Poly->m_CornersList[ii].x;
|
pos = m_Poly->m_CornersList.GetPos( ic );
|
||||||
pos.y = m_Poly->m_CornersList[ii].y;
|
|
||||||
RotatePoint( &pos, centre, angle );
|
RotatePoint( &pos, centre, angle );
|
||||||
m_Poly->m_CornersList[ii].x = pos.x;
|
m_Poly->SetX( ic, pos.x );
|
||||||
m_Poly->m_CornersList[ii].y = pos.y;
|
m_Poly->SetY( ic, pos.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Poly->Hatch();
|
m_Poly->Hatch();
|
||||||
|
@ -797,12 +791,10 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle )
|
||||||
/* rotate filled areas: */
|
/* rotate filled areas: */
|
||||||
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
||||||
{
|
{
|
||||||
CPolyPt* corner = &m_FilledPolysList[ic];
|
pos = m_FilledPolysList.GetPos( ic );
|
||||||
pos.x = corner->x;
|
|
||||||
pos.y = corner->y;
|
|
||||||
RotatePoint( &pos, centre, angle );
|
RotatePoint( &pos, centre, angle );
|
||||||
corner->x = pos.x;
|
m_FilledPolysList.SetX( ic, pos.x );
|
||||||
corner->y = pos.y;
|
m_FilledPolysList.SetY( ic, pos.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
||||||
|
@ -822,11 +814,11 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre )
|
||||||
|
|
||||||
void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
|
void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
|
||||||
{
|
{
|
||||||
for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ )
|
for( unsigned ic = 0; ic < m_Poly->m_CornersList.size(); ic++ )
|
||||||
{
|
{
|
||||||
m_Poly->m_CornersList[ii].y -= mirror_ref.y;
|
int py = m_Poly->m_CornersList.GetY( ic ) - mirror_ref.y;
|
||||||
NEGATE( m_Poly->m_CornersList[ii].y );
|
NEGATE( py );
|
||||||
m_Poly->m_CornersList[ii].y += mirror_ref.y;
|
m_Poly->m_CornersList.SetY( ic, py + mirror_ref.y );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Poly->Hatch();
|
m_Poly->Hatch();
|
||||||
|
@ -834,10 +826,9 @@ void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
|
||||||
/* mirror filled areas: */
|
/* mirror filled areas: */
|
||||||
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ )
|
||||||
{
|
{
|
||||||
CPolyPt* corner = &m_FilledPolysList[ic];
|
int py = m_FilledPolysList.GetY( ic ) - mirror_ref.y;
|
||||||
corner->y -= mirror_ref.y;
|
NEGATE( py );
|
||||||
NEGATE( corner->y );
|
m_FilledPolysList.SetY( ic, py + mirror_ref.y );
|
||||||
corner->y += mirror_ref.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
|
||||||
|
|
|
@ -551,7 +551,7 @@ public:
|
||||||
|
|
||||||
void AddFilledPolygon( CPOLYGONS_LIST& aPolygon )
|
void AddFilledPolygon( CPOLYGONS_LIST& aPolygon )
|
||||||
{
|
{
|
||||||
m_FilledPolysList.insert( m_FilledPolysList.end(), aPolygon.begin(), aPolygon.end() );
|
m_FilledPolysList.Append( aPolygon );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddFillSegments( std::vector< SEGMENT >& aSegments )
|
void AddFillSegments( std::vector< SEGMENT >& aSegments )
|
||||||
|
|
|
@ -1403,14 +1403,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
|
||||||
m_out->Print( aNestLevel+1, "(polygon\n");
|
m_out->Print( aNestLevel+1, "(polygon\n");
|
||||||
m_out->Print( aNestLevel+2, "(pts\n" );
|
m_out->Print( aNestLevel+2, "(pts\n" );
|
||||||
|
|
||||||
for( CPOLYGONS_LIST::const_iterator it = cv.begin(); it != cv.end(); ++it )
|
for( unsigned it = 0; it < cv.size(); ++it )
|
||||||
{
|
{
|
||||||
if( newLine == 0 )
|
if( newLine == 0 )
|
||||||
m_out->Print( aNestLevel+3, "(xy %s %s)",
|
m_out->Print( aNestLevel+3, "(xy %s %s)",
|
||||||
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
|
FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() );
|
||||||
else
|
else
|
||||||
m_out->Print( 0, " (xy %s %s)",
|
m_out->Print( 0, " (xy %s %s)",
|
||||||
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
|
FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() );
|
||||||
|
|
||||||
if( newLine < 4 )
|
if( newLine < 4 )
|
||||||
{
|
{
|
||||||
|
@ -1422,14 +1422,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( it->end_contour )
|
if( cv.IsEndContour( it ) )
|
||||||
{
|
{
|
||||||
if( newLine != 0 )
|
if( newLine != 0 )
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
|
|
||||||
m_out->Print( aNestLevel+2, ")\n" );
|
m_out->Print( aNestLevel+2, ")\n" );
|
||||||
|
|
||||||
if( it+1 != cv.end() )
|
if( it+1 != cv.size() )
|
||||||
{
|
{
|
||||||
newLine = 0;
|
newLine = 0;
|
||||||
m_out->Print( aNestLevel+1, ")\n" );
|
m_out->Print( aNestLevel+1, ")\n" );
|
||||||
|
@ -1451,14 +1451,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
|
||||||
m_out->Print( aNestLevel+1, "(filled_polygon\n" );
|
m_out->Print( aNestLevel+1, "(filled_polygon\n" );
|
||||||
m_out->Print( aNestLevel+2, "(pts\n" );
|
m_out->Print( aNestLevel+2, "(pts\n" );
|
||||||
|
|
||||||
for( CPOLYGONS_LIST::const_iterator it = fv.begin(); it != fv.end(); ++it )
|
for( unsigned it = 0; it < fv.size(); ++it )
|
||||||
{
|
{
|
||||||
if( newLine == 0 )
|
if( newLine == 0 )
|
||||||
m_out->Print( aNestLevel+3, "(xy %s %s)",
|
m_out->Print( aNestLevel+3, "(xy %s %s)",
|
||||||
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
|
FMT_IU( fv.GetX( it ) ).c_str(), FMT_IU( fv.GetY( it ) ).c_str() );
|
||||||
else
|
else
|
||||||
m_out->Print( 0, " (xy %s %s)",
|
m_out->Print( 0, " (xy %s %s)",
|
||||||
FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() );
|
FMT_IU( fv.GetX( it ) ).c_str(), FMT_IU( fv.GetY( it ) ).c_str() );
|
||||||
|
|
||||||
if( newLine < 4 )
|
if( newLine < 4 )
|
||||||
{
|
{
|
||||||
|
@ -1470,14 +1470,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( it->end_contour )
|
if( fv.IsEndContour( it ) )
|
||||||
{
|
{
|
||||||
if( newLine != 0 )
|
if( newLine != 0 )
|
||||||
m_out->Print( 0, "\n" );
|
m_out->Print( 0, "\n" );
|
||||||
|
|
||||||
m_out->Print( aNestLevel+2, ")\n" );
|
m_out->Print( aNestLevel+2, ")\n" );
|
||||||
|
|
||||||
if( it+1 != fv.end() )
|
if( it+1 != fv.size() )
|
||||||
{
|
{
|
||||||
newLine = 0;
|
newLine = 0;
|
||||||
m_out->Print( aNestLevel+1, ")\n" );
|
m_out->Print( aNestLevel+1, ")\n" );
|
||||||
|
|
|
@ -3693,11 +3693,11 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
|
||||||
// Save the corner list
|
// Save the corner list
|
||||||
const CPOLYGONS_LIST& cv = me->Outline()->m_CornersList;
|
const CPOLYGONS_LIST& cv = me->Outline()->m_CornersList;
|
||||||
|
|
||||||
for( CPOLYGONS_LIST::const_iterator it = cv.begin(); it != cv.end(); ++it )
|
for( unsigned it = 0; it < cv.size(); ++it )
|
||||||
{
|
{
|
||||||
fprintf( m_fp, "ZCorner %s %d\n",
|
fprintf( m_fp, "ZCorner %s %d\n",
|
||||||
fmtBIUPair( it->x, it->y ).c_str(),
|
fmtBIUPair( cv.GetX( it ), cv.GetY( it ) ).c_str(),
|
||||||
it->end_contour );
|
cv.IsEndContour( it ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the PolysList
|
// Save the PolysList
|
||||||
|
@ -3706,12 +3706,12 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const
|
||||||
{
|
{
|
||||||
fprintf( m_fp, "$POLYSCORNERS\n" );
|
fprintf( m_fp, "$POLYSCORNERS\n" );
|
||||||
|
|
||||||
for( CPOLYGONS_LIST::const_iterator it = fv.begin(); it != fv.end(); ++it )
|
for( unsigned it = 0; it < fv.size(); ++it )
|
||||||
{
|
{
|
||||||
fprintf( m_fp, "%s %d %d\n",
|
fprintf( m_fp, "%s %d %d\n",
|
||||||
fmtBIUPair( it->x, it->y ).c_str(),
|
fmtBIUPair( fv.GetX( it ), fv.GetY( it ) ).c_str(),
|
||||||
it->end_contour,
|
fv.IsEndContour( it ),
|
||||||
it->m_utility );
|
fv.GetUtility( it ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( m_fp, "$endPOLYSCORNERS\n" );
|
fprintf( m_fp, "$endPOLYSCORNERS\n" );
|
||||||
|
|
|
@ -52,9 +52,6 @@
|
||||||
#include <pcbnew.h>
|
#include <pcbnew.h>
|
||||||
#include <pcbplot.h>
|
#include <pcbplot.h>
|
||||||
|
|
||||||
// Imported function
|
|
||||||
extern void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer,
|
|
||||||
KI_POLYGON_SET& aKiPolyList );
|
|
||||||
// Local
|
// Local
|
||||||
/* Plot a solder mask layer.
|
/* Plot a solder mask layer.
|
||||||
* Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
|
* Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
|
||||||
|
@ -581,9 +578,9 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
// having a thickness < aMinThickness
|
// having a thickness < aMinThickness
|
||||||
// 2 - deflate resulting areas by aMinThickness/2
|
// 2 - deflate resulting areas by aMinThickness/2
|
||||||
KI_POLYGON_SET areasToMerge;
|
KI_POLYGON_SET areasToMerge;
|
||||||
AddPolygonCornersToKiPolygonList( bufferPolys, areasToMerge );
|
bufferPolys.ExportTo( areasToMerge );
|
||||||
KI_POLYGON_SET initialAreas;
|
KI_POLYGON_SET initialAreas;
|
||||||
AddPolygonCornersToKiPolygonList( initialPolys, initialAreas );
|
initialPolys.ExportTo( initialAreas );
|
||||||
|
|
||||||
// Merge polygons: because each shape was created with an extra margin
|
// Merge polygons: because each shape was created with an extra margin
|
||||||
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
||||||
|
|
|
@ -528,10 +528,10 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
|
||||||
*/
|
*/
|
||||||
for( unsigned ic = 0; ic < imax; ic++ )
|
for( unsigned ic = 0; ic < imax; ic++ )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = polysList[ic];
|
wxPoint pos = polysList.GetPos( ic );
|
||||||
cornerList.push_back( wxPoint( corner.x, corner.y) );
|
cornerList.push_back( pos );
|
||||||
|
|
||||||
if( corner.end_contour ) // Plot the current filled area outline
|
if( polysList.IsEndContour( ic ) ) // Plot the current filled area outline
|
||||||
{
|
{
|
||||||
// First, close the outline
|
// First, close the outline
|
||||||
if( cornerList[0] != cornerList[cornerList.size() - 1] )
|
if( cornerList[0] != cornerList[cornerList.size() - 1] )
|
||||||
|
|
|
@ -417,7 +417,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
if( cornerBufferPolysToSubstract.size() > 0 )
|
if( cornerBufferPolysToSubstract.size() > 0 )
|
||||||
{
|
{
|
||||||
KI_POLYGON_SET polyset_holes;
|
KI_POLYGON_SET polyset_holes;
|
||||||
AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes );
|
cornerBufferPolysToSubstract.ExportTo( polyset_holes );
|
||||||
// Remove holes from initial area.:
|
// Remove holes from initial area.:
|
||||||
polyset_zone_solid_areas -= polyset_holes;
|
polyset_zone_solid_areas -= polyset_holes;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
if( cornerBufferPolysToSubstract.size() )
|
if( cornerBufferPolysToSubstract.size() )
|
||||||
{
|
{
|
||||||
KI_POLYGON_SET polyset_holes;
|
KI_POLYGON_SET polyset_holes;
|
||||||
AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes );
|
cornerBufferPolysToSubstract.ExportTo( polyset_holes );
|
||||||
|
|
||||||
// Remove unconnected stubs
|
// Remove unconnected stubs
|
||||||
polyset_zone_solid_areas -= polyset_holes;
|
polyset_zone_solid_areas -= polyset_holes;
|
||||||
|
@ -463,11 +463,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
void ZONE_CONTAINER::CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList )
|
void ZONE_CONTAINER::CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList )
|
||||||
{
|
{
|
||||||
m_FilledPolysList.clear();
|
m_FilledPolysList.clear();
|
||||||
CopyPolygonsFromKiPolygonListToPolysList( aKiPolyList, m_FilledPolysList );
|
m_FilledPolysList.ImportFrom( aKiPolyList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ZONE_CONTAINER::CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList )
|
void ZONE_CONTAINER::CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList )
|
||||||
{
|
{
|
||||||
AddPolygonCornersToKiPolygonList( m_FilledPolysList, aKiPolyList );
|
m_FilledPolysList.ExportTo( aKiPolyList );
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,9 +107,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
aCornerBuffer.push_back( corner );
|
aCornerBuffer.push_back( corner );
|
||||||
}
|
}
|
||||||
|
|
||||||
corner.end_contour = true;
|
aCornerBuffer.back().end_contour = true;
|
||||||
aCornerBuffer.pop_back();
|
|
||||||
aCornerBuffer.push_back( corner );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,8 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare )
|
||||||
wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
|
wxASSERT( m_Poly ); // m_Poly == NULL Should never happen
|
||||||
wxASSERT( aZoneToCompare.Outline() );
|
wxASSERT( aZoneToCompare.Outline() );
|
||||||
|
|
||||||
if( Outline()->m_CornersList != aZoneToCompare.Outline()->m_CornersList ) // Compare vector
|
if( Outline()->m_CornersList.GetList() !=
|
||||||
|
aZoneToCompare.Outline()->m_CornersList.GetList() ) // Compare vector
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -108,9 +108,7 @@ void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb )
|
||||||
}
|
}
|
||||||
else // Not connected: remove this polygon
|
else // Not connected: remove this polygon
|
||||||
{
|
{
|
||||||
m_FilledPolysList.erase( m_FilledPolysList.begin() + indexstart,
|
m_FilledPolysList.DeleteCorners( indexstart, indexend );
|
||||||
m_FilledPolysList.begin() + indexend + 1 );
|
|
||||||
|
|
||||||
indexend = indexstart; /* indexstart points the first point of the next polygon
|
indexend = indexstart; /* indexstart points the first point of the next polygon
|
||||||
* because the current poly is removed */
|
* because the current poly is removed */
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
|
||||||
for( indexend = 0; indexend < polysList.size(); indexend++ )
|
for( indexend = 0; indexend < polysList.size(); indexend++ )
|
||||||
{
|
{
|
||||||
// end of a filled sub-area found
|
// end of a filled sub-area found
|
||||||
if( polysList[indexend].end_contour )
|
if( polysList.IsEndContour( indexend ) )
|
||||||
{
|
{
|
||||||
subnet++;
|
subnet++;
|
||||||
EDA_RECT bbox = curr_zone->CalculateSubAreaBoundaryBox( indexstart, indexend );
|
EDA_RECT bbox = curr_zone->CalculateSubAreaBoundaryBox( indexstart, indexend );
|
||||||
|
|
|
@ -295,8 +295,8 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_
|
||||||
// polygons intersect, combine them
|
// polygons intersect, combine them
|
||||||
KI_POLYGON_WITH_HOLES areaRefPoly;
|
KI_POLYGON_WITH_HOLES areaRefPoly;
|
||||||
KI_POLYGON_WITH_HOLES areaToMergePoly;
|
KI_POLYGON_WITH_HOLES areaToMergePoly;
|
||||||
CopyPolysListToKiPolygonWithHole( area_ref->Outline()->m_CornersList, areaRefPoly );
|
area_ref->Outline()->m_CornersList.ExportTo( areaRefPoly );
|
||||||
CopyPolysListToKiPolygonWithHole( area_to_combine->Outline()->m_CornersList, areaToMergePoly );
|
area_to_combine->Outline()->m_CornersList.ExportTo( areaToMergePoly );
|
||||||
|
|
||||||
KI_POLYGON_WITH_HOLES_SET mergedOutlines;
|
KI_POLYGON_WITH_HOLES_SET mergedOutlines;
|
||||||
mergedOutlines.push_back( areaRefPoly );
|
mergedOutlines.push_back( areaRefPoly );
|
||||||
|
|
|
@ -111,7 +111,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
|
||||||
ClipperLib::Polygon& polygon = normalized_polygons[ii];
|
ClipperLib::Polygon& polygon = normalized_polygons[ii];
|
||||||
cornerslist.clear();
|
cornerslist.clear();
|
||||||
for( unsigned jj = 0; jj < polygon.size(); jj++ )
|
for( unsigned jj = 0; jj < polygon.size(); jj++ )
|
||||||
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
|
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
|
||||||
KiROUND( polygon[jj].Y ) ) );
|
KiROUND( polygon[jj].Y ) ) );
|
||||||
mainpoly.set( cornerslist.begin(), cornerslist.end() );
|
mainpoly.set( cornerslist.begin(), cornerslist.end() );
|
||||||
all_contours.push_back( mainpoly );
|
all_contours.push_back( mainpoly );
|
||||||
|
@ -138,7 +138,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList )
|
||||||
ClipperLib::Polygon& polygon = normalized_polygons[ii];
|
ClipperLib::Polygon& polygon = normalized_polygons[ii];
|
||||||
cornerslist.clear();
|
cornerslist.clear();
|
||||||
for( unsigned jj = 0; jj < polygon.size(); jj++ )
|
for( unsigned jj = 0; jj < polygon.size(); jj++ )
|
||||||
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
|
cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ),
|
||||||
KiROUND( polygon[jj].Y ) ) );
|
KiROUND( polygon[jj].Y ) ) );
|
||||||
bpl::set_points( poly_tmp, cornerslist.begin(), cornerslist.end() );
|
bpl::set_points( poly_tmp, cornerslist.begin(), cornerslist.end() );
|
||||||
polysholes.push_back( poly_tmp );
|
polysholes.push_back( poly_tmp );
|
||||||
|
@ -232,15 +232,6 @@ void CPolyLine::AppendCorner( int x, int y )
|
||||||
m_CornersList.push_back( poly_pt );
|
m_CornersList.push_back( poly_pt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// close last polyline contour
|
|
||||||
//
|
|
||||||
void CPolyLine::CloseLastContour()
|
|
||||||
{
|
|
||||||
m_CornersList[m_CornersList.size() - 1].end_contour = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// move corner of polyline
|
// move corner of polyline
|
||||||
//
|
//
|
||||||
void CPolyLine::MoveCorner( int ic, int x, int y )
|
void CPolyLine::MoveCorner( int ic, int x, int y )
|
||||||
|
@ -264,12 +255,12 @@ void CPolyLine::DeleteCorner( int ic )
|
||||||
if( !closed )
|
if( !closed )
|
||||||
{
|
{
|
||||||
// open contour, must be last contour
|
// open contour, must be last contour
|
||||||
m_CornersList.erase( m_CornersList.begin() + ic );
|
m_CornersList.DeleteCorner( ic );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// closed contour
|
// closed contour
|
||||||
m_CornersList.erase( m_CornersList.begin() + ic );
|
m_CornersList.DeleteCorner( ic );
|
||||||
|
|
||||||
if( ic == iend )
|
if( ic == iend )
|
||||||
m_CornersList[ic - 1].end_contour = true;
|
m_CornersList[ic - 1].end_contour = true;
|
||||||
|
@ -304,17 +295,12 @@ void CPolyLine::RemoveContour( int icont )
|
||||||
// remove the only contour
|
// remove the only contour
|
||||||
wxASSERT( 0 );
|
wxASSERT( 0 );
|
||||||
}
|
}
|
||||||
else if( icont == polycount - 1 )
|
|
||||||
{
|
|
||||||
// remove last contour
|
|
||||||
m_CornersList.erase( m_CornersList.begin() + istart, m_CornersList.end() );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// remove closed contour
|
// remove closed contour
|
||||||
for( int ic = iend; ic>=istart; ic-- )
|
for( int ic = iend; ic>=istart; ic-- )
|
||||||
{
|
{
|
||||||
m_CornersList.erase( m_CornersList.begin() + ic );
|
m_CornersList.DeleteCorner( ic );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,7 +541,7 @@ void CPolyLine::InsertCorner( int ic, int x, int y )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_CornersList.insert( m_CornersList.begin() + ic + 1, CPolyPt( x, y ) );
|
m_CornersList.InsertCorner(ic, CPolyPt( x, y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (unsigned) (ic + 1) < m_CornersList.size() )
|
if( (unsigned) (ic + 1) < m_CornersList.size() )
|
||||||
|
@ -632,21 +618,12 @@ CRect CPolyLine::GetCornerBounds( int icont )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CPolyLine::GetNumCorners()
|
int CPolyLine::GetNumCorners() const
|
||||||
{
|
{
|
||||||
return m_CornersList.size();
|
return m_CornersList.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CPolyLine::GetNumSides()
|
|
||||||
{
|
|
||||||
if( GetClosed() )
|
|
||||||
return m_CornersList.size();
|
|
||||||
else
|
|
||||||
return m_CornersList.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CPolyLine::GetContoursCount()
|
int CPolyLine::GetContoursCount()
|
||||||
{
|
{
|
||||||
int ncont = 0;
|
int ncont = 0;
|
||||||
|
@ -958,8 +935,8 @@ bool CPolyLine::TestPointInside( int px, int py )
|
||||||
int istart = GetContourStart( icont );
|
int istart = GetContourStart( icont );
|
||||||
int iend = GetContourEnd( icont );
|
int iend = GetContourEnd( icont );
|
||||||
|
|
||||||
// Test this polygon:
|
// test point inside the current polygon
|
||||||
if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) ) // test point inside the current polygon
|
if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) )
|
||||||
inside = not inside;
|
inside = not inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,28 +986,6 @@ void CPolyLine::MoveOrigin( int x_off, int y_off )
|
||||||
Hatch();
|
Hatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set various parameters:
|
|
||||||
// the calling function should UnHatch() before calling them,
|
|
||||||
// and Draw() after
|
|
||||||
//
|
|
||||||
void CPolyLine::SetX( int ic, int x )
|
|
||||||
{
|
|
||||||
m_CornersList[ic].x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CPolyLine::SetY( int ic, int y )
|
|
||||||
{
|
|
||||||
m_CornersList[ic].y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CPolyLine::SetEndContour( int ic, bool end_contour )
|
|
||||||
{
|
|
||||||
m_CornersList[ic].end_contour = end_contour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AppendArc:
|
* AppendArc:
|
||||||
* adds segments to current contour to approximate the given arc
|
* adds segments to current contour to approximate the given arc
|
||||||
|
@ -1040,7 +995,7 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n
|
||||||
// get radius
|
// get radius
|
||||||
double radius = ::Distance( xi, yi, xf, yf );
|
double radius = ::Distance( xi, yi, xf, yf );
|
||||||
|
|
||||||
// get angles of start and finish
|
// get angles of start pint and end point
|
||||||
double th_i = atan2( (double) (yi - yc), (double) (xi - xc) );
|
double th_i = atan2( (double) (yi - yc), (double) (xi - xc) );
|
||||||
double th_f = atan2( (double) (yf - yc), (double) (xf - xc) );
|
double th_f = atan2( (double) (yf - yc), (double) (xf - xc) );
|
||||||
double th_d = (th_f - th_i) / (num - 1);
|
double th_d = (th_f - th_i) / (num - 1);
|
||||||
|
@ -1199,17 +1154,13 @@ int CPolyLine::Distance( const wxPoint& aPoint )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Function CopyPolysListToKiPolygonWithHole
|
* Copy the contours to a KI_POLYGON_WITH_HOLES
|
||||||
* converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES
|
* The first contour is the main outline, others are holes
|
||||||
*
|
|
||||||
* @param aPolysList = the list of corners of contours
|
|
||||||
* @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate
|
|
||||||
*/
|
*/
|
||||||
void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList,
|
void CPOLYGONS_LIST::ExportTo( KI_POLYGON_WITH_HOLES& aPolygoneWithHole )
|
||||||
KI_POLYGON_WITH_HOLES& aPolygoneWithHole )
|
|
||||||
{
|
{
|
||||||
unsigned corners_count = aPolysList.size();
|
unsigned corners_count = m_cornersList.size();
|
||||||
|
|
||||||
std::vector<KI_POLY_POINT> cornerslist;
|
std::vector<KI_POLY_POINT> cornerslist;
|
||||||
KI_POLYGON poly;
|
KI_POLYGON poly;
|
||||||
|
@ -1219,7 +1170,7 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList,
|
||||||
|
|
||||||
while( ic < corners_count )
|
while( ic < corners_count )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = aPolysList[ic++];
|
const CPolyPt& corner = GetCorner( ic++ );
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
||||||
|
|
||||||
if( corner.end_contour )
|
if( corner.end_contour )
|
||||||
|
@ -1239,10 +1190,9 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList,
|
||||||
|
|
||||||
while( ic < corners_count )
|
while( ic < corners_count )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = aPolysList[ic++];
|
cornerslist.push_back( KI_POLY_POINT( GetX( ic ), GetY( ic ) ) );
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
|
||||||
|
|
||||||
if( corner.end_contour )
|
if( IsEndContour( ic ) )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,6 +1204,74 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy all contours to a KI_POLYGON_SET aPolygons
|
||||||
|
* Each contour is copied into a KI_POLYGON, and each KI_POLYGON
|
||||||
|
* is append to aPolygons
|
||||||
|
*/
|
||||||
|
void CPOLYGONS_LIST::ExportTo( KI_POLYGON_SET& aPolygons )
|
||||||
|
{
|
||||||
|
std::vector<KI_POLY_POINT> cornerslist;
|
||||||
|
unsigned corners_count = GetCornersCount();
|
||||||
|
|
||||||
|
// Count the number of polygons in aCornersBuffer
|
||||||
|
int polycount = 0;
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < corners_count; ii++ )
|
||||||
|
{
|
||||||
|
if( IsEndContour( ii ) )
|
||||||
|
polycount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
aPolygons.reserve( polycount );
|
||||||
|
|
||||||
|
for( unsigned icnt = 0; icnt < corners_count; )
|
||||||
|
{
|
||||||
|
KI_POLYGON poly;
|
||||||
|
cornerslist.clear();
|
||||||
|
|
||||||
|
unsigned ii;
|
||||||
|
|
||||||
|
for( ii = icnt; ii < corners_count; ii++ )
|
||||||
|
{
|
||||||
|
cornerslist.push_back( KI_POLY_POINT( GetX( ii ), GetY( ii ) ) );
|
||||||
|
|
||||||
|
if( IsEndContour( ii ) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
|
||||||
|
aPolygons.push_back( poly );
|
||||||
|
icnt = ii + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Imports all polygons found in a KI_POLYGON_SET in list
|
||||||
|
*/
|
||||||
|
void CPOLYGONS_LIST::ImportFrom( KI_POLYGON_SET& aPolygons )
|
||||||
|
{
|
||||||
|
CPolyPt corner;
|
||||||
|
|
||||||
|
for( unsigned ii = 0; ii < aPolygons.size(); ii++ )
|
||||||
|
{
|
||||||
|
KI_POLYGON& poly = aPolygons[ii];
|
||||||
|
|
||||||
|
for( unsigned jj = 0; jj < poly.size(); jj++ )
|
||||||
|
{
|
||||||
|
KI_POLY_POINT point = *(poly.begin() + jj);
|
||||||
|
corner.x = point.x();
|
||||||
|
corner.y = point.y();
|
||||||
|
corner.end_contour = false;
|
||||||
|
AddCorner( corner );
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseLastContour();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ConvertPolysListWithHolesToOnePolygon
|
* Function ConvertPolysListWithHolesToOnePolygon
|
||||||
* converts the outline contours aPolysListWithHoles with holes to one polygon
|
* converts the outline contours aPolysListWithHoles with holes to one polygon
|
||||||
|
@ -1271,9 +1289,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith
|
||||||
int polycount = 0;
|
int polycount = 0;
|
||||||
for( unsigned ii = 0; ii < corners_count; ii++ )
|
for( unsigned ii = 0; ii < corners_count; ii++ )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = aPolysListWithHoles[ii];
|
if( aPolysListWithHoles.IsEndContour( ii ) )
|
||||||
|
|
||||||
if( corner.end_contour )
|
|
||||||
polycount++;
|
polycount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,7 +1311,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith
|
||||||
// enter main outline
|
// enter main outline
|
||||||
while( ic < corners_count )
|
while( ic < corners_count )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = aPolysListWithHoles[ic++];
|
const CPolyPt& corner = aPolysListWithHoles.GetCorner( ic++ );
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
||||||
|
|
||||||
if( corner.end_contour )
|
if( corner.end_contour )
|
||||||
|
@ -1310,7 +1326,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith
|
||||||
{
|
{
|
||||||
while( ic < corners_count )
|
while( ic < corners_count )
|
||||||
{
|
{
|
||||||
const CPolyPt& corner = aPolysListWithHoles[ic++];
|
const CPolyPt& corner = aPolysListWithHoles.GetCorner( ic++ );
|
||||||
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) );
|
||||||
|
|
||||||
if( corner.end_contour )
|
if( corner.end_contour )
|
||||||
|
@ -1337,10 +1353,10 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith
|
||||||
corner.x = point.x();
|
corner.x = point.x();
|
||||||
corner.y = point.y();
|
corner.y = point.y();
|
||||||
corner.end_contour = false;
|
corner.end_contour = false;
|
||||||
aOnePolyList.push_back( corner );
|
aOnePolyList.AddCorner( corner );
|
||||||
}
|
}
|
||||||
|
|
||||||
aOnePolyList.back().end_contour = true;
|
aOnePolyList.CloseLastContour();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -77,13 +77,129 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPOLYGONS_LIST handle a list of contours.
|
* CPOLYGONS_LIST handle a list of contours (polygons corners).
|
||||||
* Each contour is a polygon, i.e. a list of corners.
|
|
||||||
* Each corner is a CPolyPt item.
|
* Each corner is a CPolyPt item.
|
||||||
* The last cornet of each contour has its end_contour member = true
|
* The last cornet of each contour has its end_contour member = true
|
||||||
*/
|
*/
|
||||||
typedef std::vector<CPolyPt> CPOLYGONS_LIST;
|
class CPOLYGONS_LIST
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::vector <CPolyPt> m_cornersList; // array of points for corners
|
||||||
|
public:
|
||||||
|
CPOLYGONS_LIST() {};
|
||||||
|
|
||||||
|
CPolyPt& operator [](int aIdx) {return m_cornersList[aIdx]; }
|
||||||
|
|
||||||
|
// Accessor:
|
||||||
|
const std::vector <CPolyPt>& GetList() const {return m_cornersList;}
|
||||||
|
int GetX( int ic ) const { return m_cornersList[ic].x; }
|
||||||
|
void SetX( int ic, int aValue ) { m_cornersList[ic].x = aValue; }
|
||||||
|
int GetY( int ic ) const { return m_cornersList[ic].y; }
|
||||||
|
void SetY( int ic, int aValue ) { m_cornersList[ic].y = aValue; }
|
||||||
|
int GetUtility( int ic ) const { return m_cornersList[ic].m_utility; }
|
||||||
|
void SetFlag( int ic, int aFlag )
|
||||||
|
{
|
||||||
|
m_cornersList[ic].m_utility = aFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEndContour( int ic ) const
|
||||||
|
{
|
||||||
|
return m_cornersList[ic].end_contour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEndContour( int ic, bool end_contour )
|
||||||
|
{
|
||||||
|
m_cornersList[ic].end_contour = end_contour;
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxPoint& GetPos( int ic ) const { return m_cornersList[ic]; }
|
||||||
|
const CPolyPt& GetCorner( int ic ) const { return m_cornersList[ic]; }
|
||||||
|
|
||||||
|
// vector <> methods
|
||||||
|
void reserve( int aSize ) { m_cornersList.reserve( aSize ); }
|
||||||
|
void clear() { m_cornersList.clear(); }
|
||||||
|
unsigned size() const { return m_cornersList.size(); }
|
||||||
|
void push_back( const CPolyPt& aItem ) { m_cornersList.push_back( aItem ); }
|
||||||
|
CPolyPt& back() { return m_cornersList.back(); }
|
||||||
|
|
||||||
|
unsigned GetCornersCount() const { return m_cornersList.size(); }
|
||||||
|
|
||||||
|
void DeleteCorner( int aIdx )
|
||||||
|
{
|
||||||
|
m_cornersList.erase( m_cornersList.begin() + aIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteCorners( int aIdFirstCorner, int aIdLastCorner )
|
||||||
|
{
|
||||||
|
m_cornersList.erase( m_cornersList.begin() + aIdFirstCorner,
|
||||||
|
m_cornersList.begin() + aIdLastCorner + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append( const CPOLYGONS_LIST& aList )
|
||||||
|
{
|
||||||
|
m_cornersList.insert( m_cornersList.end(),
|
||||||
|
aList.m_cornersList.begin(),
|
||||||
|
aList.m_cornersList.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append( const CPolyPt& aItem )
|
||||||
|
{
|
||||||
|
m_cornersList.push_back( aItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append( const wxPoint& aItem )
|
||||||
|
{
|
||||||
|
CPolyPt item( aItem );
|
||||||
|
|
||||||
|
m_cornersList.push_back( aItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertCorner( int aPosition, const CPolyPt& aItem )
|
||||||
|
{
|
||||||
|
m_cornersList.insert( m_cornersList.begin() + aPosition + 1, aItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ExportTo
|
||||||
|
* Copy all contours to a KI_POLYGON_SET
|
||||||
|
* @param aPolygons = the KI_POLYGON_WITH_HOLES to populate
|
||||||
|
*/
|
||||||
|
void ExportTo( KI_POLYGON_SET& aPolygons );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ExportTo
|
||||||
|
* Copy the contours to a KI_POLYGON_WITH_HOLES
|
||||||
|
* The first contour is the main outline, others are holes
|
||||||
|
* @param aPolygoneWithHole = the KI_POLYGON_WITH_HOLES to populate
|
||||||
|
*/
|
||||||
|
void ExportTo( KI_POLYGON_WITH_HOLES& aPolygoneWithHole );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function ImportFrom
|
||||||
|
* Copy all polygons from a KI_POLYGON_SET in list
|
||||||
|
* @param aPolygons = the KI_POLYGON_SET to import
|
||||||
|
*/
|
||||||
|
void ImportFrom( KI_POLYGON_SET& aPolygons );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function AddCorner
|
||||||
|
* add a corner to the list
|
||||||
|
*/
|
||||||
|
void AddCorner( const CPolyPt& aCorner )
|
||||||
|
{
|
||||||
|
m_cornersList.push_back( aCorner );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function CloseLastContour
|
||||||
|
* Set the .end_contour member of the last corner in list to true
|
||||||
|
*/
|
||||||
|
void CloseLastContour()
|
||||||
|
{
|
||||||
|
if( m_cornersList.size() > 0 )
|
||||||
|
m_cornersList.back().end_contour = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CPolyLine
|
class CPolyLine
|
||||||
{
|
{
|
||||||
|
@ -99,7 +215,7 @@ public:
|
||||||
* Copy settings (layer, hatch styles) from aPoly
|
* Copy settings (layer, hatch styles) from aPoly
|
||||||
* @param aPoly is the CPolyLine to import settings
|
* @param aPoly is the CPolyLine to import settings
|
||||||
*/
|
*/
|
||||||
void ImportSettings( const CPolyLine * aPoly );
|
void ImportSettings( const CPolyLine* aPoly );
|
||||||
|
|
||||||
// functions for modifying the CPolyLine contours
|
// functions for modifying the CPolyLine contours
|
||||||
|
|
||||||
|
@ -117,9 +233,19 @@ public:
|
||||||
* keep the controur closed by modifying the previous corner
|
* keep the controur closed by modifying the previous corner
|
||||||
* @param ic = the index of the corner to delete
|
* @param ic = the index of the corner to delete
|
||||||
*/
|
*/
|
||||||
void DeleteCorner ( int ic );
|
void DeleteCorner( int ic );
|
||||||
void MoveCorner( int ic, int x, int y );
|
void MoveCorner( int ic, int x, int y );
|
||||||
void CloseLastContour();
|
|
||||||
|
/**
|
||||||
|
* function CloseLastContour
|
||||||
|
* Set the .end_contour member of the last corner
|
||||||
|
* of the last contour to true
|
||||||
|
*/
|
||||||
|
void CloseLastContour()
|
||||||
|
{
|
||||||
|
m_CornersList.CloseLastContour();
|
||||||
|
}
|
||||||
|
|
||||||
void RemoveContour( int icont );
|
void RemoveContour( int icont );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,7 +258,7 @@ public:
|
||||||
* When a CPolyLine is self intersectic, it need to be normalized.
|
* When a CPolyLine is self intersectic, it need to be normalized.
|
||||||
* (converted to non intersecting polygons)
|
* (converted to non intersecting polygons)
|
||||||
*/
|
*/
|
||||||
bool IsPolygonSelfIntersecting();
|
bool IsPolygonSelfIntersecting();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Chamfer
|
* Function Chamfer
|
||||||
|
@ -157,7 +283,7 @@ public:
|
||||||
* (i.e. when 2 successive corners are at the same location)
|
* (i.e. when 2 successive corners are at the same location)
|
||||||
* @return the count of removed corners.
|
* @return the count of removed corners.
|
||||||
*/
|
*/
|
||||||
int RemoveNullSegments();
|
int RemoveNullSegments();
|
||||||
|
|
||||||
void RemoveAllContours( void );
|
void RemoveAllContours( void );
|
||||||
|
|
||||||
|
@ -185,24 +311,25 @@ public:
|
||||||
// access functions
|
// access functions
|
||||||
void SetLayer( LAYER_NUM aLayer ) { m_layer = aLayer; }
|
void SetLayer( LAYER_NUM aLayer ) { m_layer = aLayer; }
|
||||||
LAYER_NUM GetLayer() const { return m_layer; }
|
LAYER_NUM GetLayer() const { return m_layer; }
|
||||||
int GetNumCorners();
|
int GetNumCorners() const;
|
||||||
int GetNumSides();
|
int GetClosed();
|
||||||
int GetClosed();
|
int GetContoursCount();
|
||||||
int GetContoursCount();
|
int GetContour( int ic );
|
||||||
int GetContour( int ic );
|
int GetContourStart( int icont );
|
||||||
int GetContourStart( int icont );
|
int GetContourEnd( int icont );
|
||||||
int GetContourEnd( int icont );
|
int GetContourSize( int icont );
|
||||||
int GetContourSize( int icont );
|
|
||||||
|
|
||||||
int GetX( int ic ) const { return m_CornersList[ic].x; }
|
int GetX( int ic ) const { return m_CornersList.GetX( ic ); }
|
||||||
int GetY( int ic ) const { return m_CornersList[ic].y; }
|
int GetY( int ic ) const { return m_CornersList.GetY( ic ); }
|
||||||
|
bool IsEndContour( int ic ) const
|
||||||
|
{ return m_CornersList.IsEndContour( ic ); }
|
||||||
|
|
||||||
const wxPoint& GetPos( int ic ) const { return m_CornersList[ic]; }
|
const wxPoint& GetPos( int ic ) const { return m_CornersList.GetPos( ic ); }
|
||||||
|
|
||||||
int GetEndContour( int ic );
|
int GetEndContour( int ic );
|
||||||
|
|
||||||
int GetUtility( int ic ) const { return m_CornersList[ic].m_utility; };
|
int GetUtility( int ic ) const { return m_CornersList.GetUtility( ic ); };
|
||||||
void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; };
|
void SetUtility( int ic, int aFlag ) { m_CornersList.SetFlag( ic, aFlag ); };
|
||||||
|
|
||||||
int GetHatchPitch() const { return m_hatchPitch; }
|
int GetHatchPitch() const { return m_hatchPitch; }
|
||||||
static int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
|
static int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils
|
||||||
|
@ -212,13 +339,25 @@ public:
|
||||||
{
|
{
|
||||||
SetHatchPitch( aHatchPitch );
|
SetHatchPitch( aHatchPitch );
|
||||||
m_hatchStyle = (enum HATCH_STYLE) aHatchStyle;
|
m_hatchStyle = (enum HATCH_STYLE) aHatchStyle;
|
||||||
|
|
||||||
if( aRebuildHatch )
|
if( aRebuildHatch )
|
||||||
Hatch();
|
Hatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetX( int ic, int x );
|
void SetX( int ic, int x )
|
||||||
void SetY( int ic, int y );
|
{
|
||||||
void SetEndContour( int ic, bool end_contour );
|
m_CornersList.SetX( ic, x );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetY( int ic, int y )
|
||||||
|
{
|
||||||
|
m_CornersList.SetY( ic, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEndContour( int ic, bool end_contour )
|
||||||
|
{
|
||||||
|
m_CornersList.SetEndContour( ic, end_contour );
|
||||||
|
}
|
||||||
|
|
||||||
void SetHatchStyle( enum HATCH_STYLE style )
|
void SetHatchStyle( enum HATCH_STYLE style )
|
||||||
{
|
{
|
||||||
|
@ -235,7 +374,7 @@ public:
|
||||||
* @return the polygon count (always >= 1, because there is at least one polygon)
|
* @return the polygon count (always >= 1, because there is at least one polygon)
|
||||||
* There are new polygons only if the polygon count is > 1
|
* There are new polygons only if the polygon count is > 1
|
||||||
*/
|
*/
|
||||||
int NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList );
|
int NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList );
|
||||||
|
|
||||||
// Bezier Support
|
// 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 );
|
||||||
|
@ -262,39 +401,28 @@ public:
|
||||||
int Distance( wxPoint aStart, wxPoint aEnd, int aWidth );
|
int Distance( wxPoint aStart, wxPoint aEnd, int aWidth );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LAYER_NUM m_layer; // layer to draw on
|
LAYER_NUM m_layer; // layer to draw on
|
||||||
enum HATCH_STYLE m_hatchStyle; // hatch style, see enum above
|
enum HATCH_STYLE m_hatchStyle; // hatch style, see enum above
|
||||||
int m_hatchPitch; // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
|
int m_hatchPitch; // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
|
||||||
// and the len of eacvh segment
|
// and the len of eacvh segment
|
||||||
// for DIAGONAL_FULL, the pitch is twice this value
|
// for DIAGONAL_FULL, the pitch is twice this value
|
||||||
int m_utility; // a flag used in some calculations
|
int m_utility; // a flag used in some calculations
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPOLYGONS_LIST m_CornersList; // array of points for corners
|
CPOLYGONS_LIST m_CornersList; // array of points for corners
|
||||||
std::vector <CSegment> m_HatchLines; // hatch lines showing the polygon area
|
std::vector <CSegment> m_HatchLines; // hatch lines showing the polygon area
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 CPOLYGONS_LIST& aPolysList,
|
|
||||||
KI_POLYGON_WITH_HOLES& aPolygoneWithHole );
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ConvertPolysListWithHolesToOnePolygon
|
* Function ConvertPolysListWithHolesToOnePolygon
|
||||||
* converts the outline contours aPolysListWithHoles with holes to one polygon
|
* converts the outline contours aPolysListWithHoles with holes to one polygon
|
||||||
* with no holes (only one contour)
|
* with no holes (only one contour)
|
||||||
* holes are linked to main outlines by overlap segments, to give only one polygon
|
* 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 aPolysListWithHoles = the list of corners of contours
|
||||||
|
* (main outline and holes)
|
||||||
* @param aOnePolyList = a polygon with no holes
|
* @param aOnePolyList = a polygon with no holes
|
||||||
*/
|
*/
|
||||||
void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWithHoles,
|
void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWithHoles,
|
||||||
CPOLYGONS_LIST& aOnePolyList );
|
CPOLYGONS_LIST& aOnePolyList );
|
||||||
|
|
||||||
#endif // #ifndef POLYLINE_H
|
#endif // #ifndef POLYLINE_H
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
#define OUTSIDE false
|
#define OUTSIDE false
|
||||||
#define INSIDE true
|
#define INSIDE true
|
||||||
|
|
||||||
bool TestPointInsidePolygon( CPOLYGONS_LIST aPolysList,
|
bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList,
|
||||||
int aIdxstart,
|
int aIdxstart,
|
||||||
int aIdxend,
|
int aIdxend,
|
||||||
int aRefx,
|
int aRefx,
|
||||||
int aRefy)
|
int aRefy)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function TestPointInsidePolygon
|
* Function TestPointInsidePolygon
|
||||||
|
@ -50,10 +50,10 @@ bool TestPointInsidePolygon( CPOLYGONS_LIST aPolysList,
|
||||||
// find all intersection points of line with polyline sides
|
// find all intersection points of line with polyline sides
|
||||||
for( ics = aIdxstart, ice = aIdxend; ics <= aIdxend; ice = ics++ )
|
for( ics = aIdxstart, ice = aIdxend; ics <= aIdxend; ice = ics++ )
|
||||||
{
|
{
|
||||||
int seg_startX = aPolysList[ics].x;
|
int seg_startX = aPolysList.GetX( ics );
|
||||||
int seg_startY = aPolysList[ics].y;
|
int seg_startY = aPolysList.GetY( ics );
|
||||||
int seg_endX = aPolysList[ice].x;
|
int seg_endX = aPolysList.GetX( ice );
|
||||||
int seg_endY = aPolysList[ice].y;
|
int seg_endY = aPolysList.GetY( ice );
|
||||||
|
|
||||||
/* Trivial cases: skip if ref above or below the segment to test */
|
/* Trivial cases: skip if ref above or below the segment to test */
|
||||||
if( ( seg_startY > aRefy ) && (seg_endY > aRefy ) )
|
if( ( seg_startY > aRefy ) && (seg_endY > aRefy ) )
|
||||||
|
|
|
@ -19,11 +19,11 @@ public:
|
||||||
* @param aRefx, aRefy: the point coordinate to test
|
* @param aRefx, aRefy: the point coordinate to test
|
||||||
* @return true if the point is inside, false for outside
|
* @return true if the point is inside, false for outside
|
||||||
*/
|
*/
|
||||||
bool TestPointInsidePolygon( std::vector <CPolyPt> aPolysList,
|
bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList,
|
||||||
int aIdxstart,
|
int aIdxstart,
|
||||||
int aIdxend,
|
int aIdxend,
|
||||||
int aRefx,
|
int aRefx,
|
||||||
int aRefy);
|
int aRefy);
|
||||||
/**
|
/**
|
||||||
* Function TestPointInsidePolygon (overlaid)
|
* Function TestPointInsidePolygon (overlaid)
|
||||||
* same as previous, but mainly use wxPoint
|
* same as previous, but mainly use wxPoint
|
||||||
|
|
Loading…
Reference in New Issue