Setting custom pad shape to be outline for PNS

Changes SHAPE_CONVEX to SHAPE_SIMPLE to better reflect the limitations.
Changes SHAPE_LINE_CHAIN::PointInside calculation to allow points
strictly inside a line chain

Fixes: lp:1768862
* https://bugs.launchpad.net/kicad/+bug/1768862
This commit is contained in:
Seth Hillbrand 2018-05-03 10:52:42 -07:00
parent 93c7f65d96
commit b2c4519c2c
11 changed files with 78 additions and 80 deletions

View File

@ -30,7 +30,7 @@
#include <geometry/shape_circle.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_convex.h>
#include "../../include/geometry/shape_simple.h"
typedef VECTOR2I::extended_type ecoord;
@ -178,7 +178,7 @@ static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_LINE_CHAIN& aB,
}
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_CONVEX& aB, int aClearance,
static inline bool Collide( const SHAPE_CIRCLE& aA, const SHAPE_SIMPLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
bool found;
@ -228,14 +228,14 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_LINE_CHAIN&
}
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_CONVEX& aB, int aClearance,
static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SIMPLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
return Collide( aA, aB.Vertices(), aClearance, aNeedMTV, aMTV );
}
static inline bool Collide( const SHAPE_CONVEX& aA, const SHAPE_CONVEX& aB, int aClearance,
static inline bool Collide( const SHAPE_SIMPLE& aA, const SHAPE_SIMPLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
return Collide( aA.Vertices(), aB.Vertices(), aClearance, aNeedMTV, aMTV );
@ -257,7 +257,7 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in
}
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_CONVEX& aB, int aClearance,
static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_SIMPLE& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
return Collide( aA, aB.Vertices(), aClearance, aNeedMTV, aMTV );
@ -288,7 +288,7 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& aA, const SHAPE_SEGMENT& aB,
}
static inline bool Collide( const SHAPE_CONVEX& aA, const SHAPE_SEGMENT& aB, int aClearance,
static inline bool Collide( const SHAPE_SIMPLE& aA, const SHAPE_SEGMENT& aB, int aClearance,
bool aNeedMTV, VECTOR2I& aMTV )
{
return Collide( aA.Vertices(), aB, aClearance, aNeedMTV, aMTV );
@ -340,8 +340,8 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SEGMENT:
return CollCase<SHAPE_RECT, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CONVEX:
return CollCase<SHAPE_RECT, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
default:
break;
@ -363,8 +363,8 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SEGMENT:
return CollCase<SHAPE_CIRCLE, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CONVEX:
return CollCase<SHAPE_CIRCLE, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
default:
break;
@ -386,8 +386,8 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SEGMENT:
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CONVEX:
return CollCase<SHAPE_LINE_CHAIN, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
default:
break;
@ -409,31 +409,31 @@ bool CollideShapes( const SHAPE* aA, const SHAPE* aB, int aClearance, bool aNeed
case SH_SEGMENT:
return CollCase<SHAPE_SEGMENT, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CONVEX:
return CollCase<SHAPE_CONVEX, SHAPE_SEGMENT>( aB, aA, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aB, aA, aClearance, aNeedMTV, aMTV );
default:
break;
}
break;
case SH_CONVEX:
case SH_SIMPLE:
switch( aB->Type() )
{
case SH_RECT:
return CollCase<SHAPE_RECT, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
return CollCase<SHAPE_RECT, SHAPE_SIMPLE>( aB, aA, aClearance, aNeedMTV, aMTV );
case SH_CIRCLE:
return CollCase<SHAPE_CIRCLE, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
return CollCase<SHAPE_CIRCLE, SHAPE_SIMPLE>( aB, aA, aClearance, aNeedMTV, aMTV );
case SH_LINE_CHAIN:
return CollCase<SHAPE_LINE_CHAIN, SHAPE_CONVEX>( aB, aA, aClearance, aNeedMTV, aMTV );
return CollCase<SHAPE_LINE_CHAIN, SHAPE_SIMPLE>( aB, aA, aClearance, aNeedMTV, aMTV );
case SH_SEGMENT:
return CollCase<SHAPE_CONVEX, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
return CollCase<SHAPE_SIMPLE, SHAPE_SEGMENT>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_CONVEX:
return CollCase<SHAPE_CONVEX, SHAPE_CONVEX>( aA, aB, aClearance, aNeedMTV, aMTV );
case SH_SIMPLE:
return CollCase<SHAPE_SIMPLE, SHAPE_SIMPLE>( aA, aB, aClearance, aNeedMTV, aMTV );
default:
break;

View File

@ -334,23 +334,26 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const
if( !m_closed || SegmentCount() < 3 )
return false;
int cur = CSegment( 0 ).Side( aP );
bool inside = false;
if( cur == 0 )
return false;
for( int i = 1; i < SegmentCount(); i++ )
/**
* To check for interior points, we draw a line in the positive x direction from
* the point. If it intersects an even number of segments, the point is outside the
* line chain (it had to first enter and then exit). Otherwise, it is inside the chain.
*
* Note: slope might be denormal here in the case of a horizontal line but we require our
* y to move from above to below the point (or vice versa)
*/
for( int i = 0; i < SegmentCount(); i++ )
{
const SEG s = CSegment( i );
if( aP == s.A || aP == s.B ) // edge does not belong to the interior!
return false;
if( s.Side( aP ) != cur )
return false;
double inv_slope = ( ( double ) s.B.x - s.A.x ) / (s.B.y - s.A.y );
if( ( ( s.A.y > aP.y ) != ( s.B.y > aP.y ) ) &&
( aP.x - s.A.x < inv_slope * ( aP.y - s.A.y ) ) )
inside = !inside;
}
return true;
return inside;
}

View File

@ -44,7 +44,7 @@ enum SHAPE_TYPE
SH_SEGMENT, ///> line segment
SH_LINE_CHAIN, ///> line chain (polyline)
SH_CIRCLE, ///> circle
SH_CONVEX, ///> convex polygon
SH_SIMPLE, ///> simple polygon
SH_POLY_SET, ///> set of polygons (with holes, etc.)
SH_COMPOUND, ///> compound shape, consisting of multiple simple shapes
SH_ARC ///> circular arc

View File

@ -21,8 +21,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __SHAPE_CONVEX_H
#define __SHAPE_CONVEX_H
#ifndef __SHAPE_SIMPLE_H
#define __SHAPE_SIMPLE_H
#include <vector>
@ -31,34 +31,34 @@
#include <geometry/shape_line_chain.h>
/**
* Class SHAPE_CONVEX
* Class SHAPE_SIMPLE
*
* Represents a convex polygon consisting of a zero-thickness closed chain of
* Represents a simple polygon consisting of a zero-thickness closed chain of
* connected line segments.
*
* Internally the vertices are held in a SHAPE_LINE_CHAIN, please note that
* there is a "virtual" line segment between the last and first vertex.
*/
class SHAPE_CONVEX : public SHAPE
class SHAPE_SIMPLE : public SHAPE
{
public:
/**
* Constructor
* Creates an empty polygon
*/
SHAPE_CONVEX() :
SHAPE( SH_CONVEX )
SHAPE_SIMPLE() :
SHAPE( SH_SIMPLE )
{
m_points.SetClosed( true );
}
SHAPE_CONVEX( const SHAPE_CONVEX& aOther ) :
SHAPE( SH_CONVEX ), m_points( aOther.m_points )
SHAPE_SIMPLE( const SHAPE_SIMPLE& aOther ) :
SHAPE( SH_SIMPLE ), m_points( aOther.m_points )
{}
SHAPE* Clone() const override
{
return new SHAPE_CONVEX( *this );
return new SHAPE_SIMPLE( *this );
}
/**
@ -132,9 +132,9 @@ public:
/**
* Function Vertices()
*
* Returns the list of vertices defining this convex polygon.
* Returns the list of vertices defining this simple polygon.
*
* @return the list of vertices defining this convex polygon
* @return the list of vertices defining this simple polygon
*/
const SHAPE_LINE_CHAIN& Vertices() const
{
@ -186,4 +186,4 @@ private:
SHAPE_LINE_CHAIN m_points;
};
#endif // __SHAPE_CONVEX_H
#endif // __SHAPE_SIMPLE_H

View File

@ -42,13 +42,14 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_convex.h>
#include <geometry/shape_arc.h>
#include <geometry/convex_hull.h>
#include "tools/pcb_tool.h"
#include "pns_kicad_iface.h"
#include "../../include/geometry/shape_simple.h"
#include "pns_routing_settings.h"
#include "pns_sizes_settings.h"
#include "pns_item.h"
@ -575,15 +576,10 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
outline.Append( aPad->GetCustomShapeAsPolygon() );
aPad->CustomShapeAsPolygonToBoardPosition( &outline, wx_c, aPad->GetOrientation() );
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
// We use the convex hull of the pad shape, because PnS knows
// only convex shapes.
std::vector<wxPoint> convex_hull;
BuildConvexHull( convex_hull, outline );
for( unsigned ii = 0; ii < convex_hull.size(); ii++ )
shape->Append( convex_hull[ii] );
for( auto iter = outline.CIterate( 0 ); iter; iter++ )
shape->Append( *iter );
solid->SetShape( shape );
}
@ -622,7 +618,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
{
wxPoint coords[4];
aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
for( int ii = 0; ii < 4; ii++ )
{
@ -642,7 +638,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
for( int ii = 0; ii < poly.PointCount(); ++ii )
{
@ -673,7 +669,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
wxPoint end;
wxPoint corner;
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );
@ -719,7 +715,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
wxPoint coords[4];
aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
for( int ii = 0; ii < 4; ii++ )
{
shape->Append( wx_c + coords[ii] );
@ -738,7 +734,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
SHAPE_CONVEX* shape = new SHAPE_CONVEX();
SHAPE_SIMPLE* shape = new SHAPE_SIMPLE();
for( int ii = 0; ii < poly.PointCount(); ++ii )
{
@ -837,7 +833,7 @@ bool PNS_KICAD_IFACE::syncZone( PNS::NODE* aWorld, ZONE_CONTAINER* aZone )
{
VECTOR2I a, b, c;
tri->GetTriangle( i, a, b, c );
auto triShape = new SHAPE_CONVEX;
auto triShape = new SHAPE_SIMPLE;
triShape->Append( a );
triShape->Append( b );

View File

@ -30,7 +30,7 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_convex.h>
#include "../../include/geometry/shape_simple.h"
namespace PNS {
@ -177,9 +177,9 @@ void LOGGER::dumpShape( const SHAPE* aSh )
break;
}
case SH_CONVEX:
case SH_SIMPLE:
{
const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) aSh;
const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) aSh;
m_theLog << "convex " << c->PointCount() << " ";
for( int i = 0; i < c->PointCount(); i++ )

View File

@ -21,8 +21,6 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_convex.h>
#include <cmath>
#include "pns_line.h"
@ -30,6 +28,8 @@
#include "pns_node.h"
#include "pns_solid.h"
#include "pns_optimizer.h"
#include "../../include/geometry/shape_simple.h"
#include "pns_utils.h"
#include "pns_router.h"
@ -669,7 +669,7 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::convexBreakouts( int aWidth,
const SHAPE* aShape, bool aPermitDiagonal ) const
{
BREAKOUT_LIST breakouts;
const SHAPE_CONVEX* convex = static_cast<const SHAPE_CONVEX*>( aShape );
const SHAPE_SIMPLE* convex = static_cast<const SHAPE_SIMPLE*>( aShape );
BOX2I bbox = convex->BBox( 0 );
VECTOR2I p0 = bbox.Centre();
@ -791,7 +791,7 @@ OPTIMIZER::BREAKOUT_LIST OPTIMIZER::computeBreakouts( int aWidth,
case SH_CIRCLE:
return circleBreakouts( aWidth, shape, aPermitDiagonal );
case SH_CONVEX:
case SH_SIMPLE:
return convexBreakouts( aWidth, shape, aPermitDiagonal );
default:

View File

@ -25,9 +25,9 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_convex.h>
#include "pns_solid.h"
#include "../../include/geometry/shape_simple.h"
#include "pns_utils.h"
namespace PNS {
@ -58,9 +58,9 @@ const SHAPE_LINE_CHAIN SOLID::Hull( int aClearance, int aWalkaroundThickness ) c
return SegmentHull( *seg, aClearance, aWalkaroundThickness );
}
case SH_CONVEX:
case SH_SIMPLE:
{
SHAPE_CONVEX* convex = static_cast<SHAPE_CONVEX*>( m_shape );
SHAPE_SIMPLE* convex = static_cast<SHAPE_SIMPLE*>( m_shape );
return ConvexHull( *convex, cl );
}

View File

@ -98,7 +98,7 @@ static void MoveDiagonal( SEG& aDiagonal, const SHAPE_LINE_CHAIN& aVertices, int
}
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& aConvex, int aClearance )
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_SIMPLE& aConvex, int aClearance )
{
// this defines the horizontal and vertical lines in the hull octagon
BOX2I box = aConvex.BBox( aClearance + HULL_MARGIN );

View File

@ -27,7 +27,7 @@
#include <geometry/shape_line_chain.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_convex.h>
#include "../../include/geometry/shape_simple.h"
namespace PNS {
@ -52,7 +52,7 @@ const SHAPE_LINE_CHAIN SegmentHull( const SHAPE_SEGMENT& aSeg, int aClearance,
* @param aClearance The minimum distance between polygon and hull.
* @return A closed line chain describing the octagon.
*/
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_CONVEX& aConvex, int aClearance );
const SHAPE_LINE_CHAIN ConvexHull( const SHAPE_SIMPLE& aConvex, int aClearance );
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );

View File

@ -24,13 +24,12 @@
#include <view/view.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_convex.h>
#include "class_track.h"
#include <pcb_painter.h>
#include "router_preview_item.h"
#include "../../include/geometry/shape_simple.h"
#include "pns_line.h"
#include "pns_segment.h"
#include "pns_via.h"
@ -245,9 +244,9 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
break;
}
case SH_CONVEX:
case SH_SIMPLE:
{
const SHAPE_CONVEX* c = (const SHAPE_CONVEX*) m_shape;
const SHAPE_SIMPLE* c = (const SHAPE_SIMPLE*) m_shape;
std::deque<VECTOR2D> polygon = std::deque<VECTOR2D>();
for( int i = 0; i < c->PointCount(); i++ )
{