Finish arc implementation of m_ThirdPoint for EDGE_MODULEs.
Fixes https://gitlab.com/kicad/code/kicad/issues/5191
This commit is contained in:
parent
7342532276
commit
6c74658a98
|
@ -262,6 +262,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
array_pad_name_provider.cpp
|
||||
build_BOM_from_board.cpp
|
||||
cleanup_item.cpp
|
||||
convert_drawsegment_list_to_polygon.cpp
|
||||
cross-probing.cpp
|
||||
edit.cpp
|
||||
edit_track_width.cpp
|
||||
|
|
|
@ -187,9 +187,10 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
|
|||
case S_ARC:
|
||||
case S_SEGMENT:
|
||||
case S_CIRCLE:
|
||||
// these can all be done by just rotating the start and end points
|
||||
// these can all be done by just rotating the constituent points
|
||||
RotatePoint( &m_Start, aRotCentre, aAngle );
|
||||
RotatePoint( &m_End, aRotCentre, aAngle );
|
||||
RotatePoint( &m_ThirdPoint, aRotCentre, aAngle );
|
||||
break;
|
||||
|
||||
case S_RECT:
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
* sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
|
||||
* @param aAngle is tenths of degrees, but will soon be degrees.
|
||||
*/
|
||||
void SetAngle( double aAngle ); // encapsulates the transition to degrees
|
||||
virtual void SetAngle( double aAngle ); // encapsulates the transition to degrees
|
||||
double GetAngle() const { return m_Angle; }
|
||||
|
||||
void SetType( int aType ) { m_Type = aType; }
|
||||
|
@ -200,14 +200,18 @@ public:
|
|||
* to initialize one point of the cicumference
|
||||
*/
|
||||
void SetArcStart( const wxPoint& aArcStartPoint )
|
||||
{ m_End = aArcStartPoint; }
|
||||
{
|
||||
m_End = aArcStartPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the start arc point. can be used for circles
|
||||
* Initialize the end arc point. can be used for circles
|
||||
* to initialize one point of the cicumference
|
||||
*/
|
||||
void SetArcEnd( const wxPoint& aArcEndPoint )
|
||||
{ m_ThirdPoint = aArcEndPoint; }
|
||||
{
|
||||
m_ThirdPoint = aArcEndPoint;
|
||||
}
|
||||
|
||||
/** For arcs and circles:
|
||||
*/
|
||||
|
|
|
@ -58,6 +58,7 @@ void EDGE_MODULE::SetLocalCoord()
|
|||
{
|
||||
m_Start0 = m_Start;
|
||||
m_End0 = m_End;
|
||||
m_ThirdPoint0 = m_ThirdPoint;
|
||||
m_Bezier0_C1 = m_BezierC1;
|
||||
m_Bezier0_C2 = m_BezierC2;
|
||||
return;
|
||||
|
@ -65,11 +66,13 @@ void EDGE_MODULE::SetLocalCoord()
|
|||
|
||||
m_Start0 = m_Start - module->GetPosition();
|
||||
m_End0 = m_End - module->GetPosition();
|
||||
m_ThirdPoint0 = m_ThirdPoint - module->GetPosition();
|
||||
m_Bezier0_C1 = m_BezierC1 - module->GetPosition();
|
||||
m_Bezier0_C2 = m_BezierC2 - module->GetPosition();
|
||||
double angle = module->GetOrientation();
|
||||
RotatePoint( &m_Start0.x, &m_Start0.y, -angle );
|
||||
RotatePoint( &m_End0.x, &m_End0.y, -angle );
|
||||
RotatePoint( &m_ThirdPoint0.x, &m_ThirdPoint0.y, -angle );
|
||||
RotatePoint( &m_Bezier0_C1.x, &m_Bezier0_C1.y, -angle );
|
||||
RotatePoint( &m_Bezier0_C2.x, &m_Bezier0_C2.y, -angle );
|
||||
}
|
||||
|
@ -81,6 +84,7 @@ void EDGE_MODULE::SetDrawCoord()
|
|||
|
||||
m_Start = m_Start0;
|
||||
m_End = m_End0;
|
||||
m_ThirdPoint = m_ThirdPoint0;
|
||||
m_BezierC1 = m_Bezier0_C1;
|
||||
m_BezierC2 = m_Bezier0_C2;
|
||||
|
||||
|
@ -88,11 +92,13 @@ void EDGE_MODULE::SetDrawCoord()
|
|||
{
|
||||
RotatePoint( &m_Start.x, &m_Start.y, module->GetOrientation() );
|
||||
RotatePoint( &m_End.x, &m_End.y, module->GetOrientation() );
|
||||
RotatePoint( &m_ThirdPoint.x, &m_ThirdPoint.y, module->GetOrientation() );
|
||||
RotatePoint( &m_BezierC1.x, &m_BezierC1.y, module->GetOrientation() );
|
||||
RotatePoint( &m_BezierC2.x, &m_BezierC2.y, module->GetOrientation() );
|
||||
|
||||
m_Start += module->GetPosition();
|
||||
m_End += module->GetPosition();
|
||||
m_ThirdPoint += module->GetPosition();
|
||||
m_BezierC1 += module->GetPosition();
|
||||
m_BezierC2 += module->GetPosition();
|
||||
}
|
||||
|
@ -144,6 +150,17 @@ EDA_ITEM* EDGE_MODULE::Clone() const
|
|||
}
|
||||
|
||||
|
||||
void EDGE_MODULE::SetAngle( double aAngle )
|
||||
{
|
||||
// Mark as depreciated.
|
||||
// m_Angle does not define the arc anymore
|
||||
// m_Angle must be >= -360 and <= +360 degrees
|
||||
m_Angle = NormalizeAngle360Max( aAngle );
|
||||
m_ThirdPoint0 = m_End0;
|
||||
RotatePoint( &m_ThirdPoint0, m_Start0, -m_Angle );
|
||||
}
|
||||
|
||||
|
||||
void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
wxPoint pt( 0, 0 );
|
||||
|
@ -166,10 +183,12 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
|||
{
|
||||
MIRROR( m_Start.x, aCentre.x );
|
||||
MIRROR( m_End.x, aCentre.x );
|
||||
MIRROR( m_ThirdPoint.y, aCentre.x );
|
||||
MIRROR( m_BezierC1.x, aCentre.x );
|
||||
MIRROR( m_BezierC2.x, aCentre.x );
|
||||
MIRROR( m_Start0.x, pt.x );
|
||||
MIRROR( m_End0.x, pt.x );
|
||||
MIRROR( m_ThirdPoint0.x, pt.x );
|
||||
MIRROR( m_Bezier0_C1.x, pt.x );
|
||||
MIRROR( m_Bezier0_C2.x, pt.x );
|
||||
}
|
||||
|
@ -177,10 +196,12 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
|
|||
{
|
||||
MIRROR( m_Start.y, aCentre.y );
|
||||
MIRROR( m_End.y, aCentre.y );
|
||||
MIRROR( m_ThirdPoint.y, aCentre.y );
|
||||
MIRROR( m_BezierC1.y, aCentre.y );
|
||||
MIRROR( m_BezierC2.y, aCentre.y );
|
||||
MIRROR( m_Start0.y, pt.y );
|
||||
MIRROR( m_End0.y, pt.y );
|
||||
MIRROR( m_ThirdPoint0.y, pt.y );
|
||||
MIRROR( m_Bezier0_C1.y, pt.y );
|
||||
MIRROR( m_Bezier0_C2.y, pt.y );
|
||||
}
|
||||
|
@ -272,6 +293,7 @@ void EDGE_MODULE::Move( const wxPoint& aMoveVector )
|
|||
// This is a footprint shape modification.
|
||||
m_Start0 += aMoveVector;
|
||||
m_End0 += aMoveVector;
|
||||
m_ThirdPoint0 += aMoveVector;
|
||||
m_Bezier0_C1 += aMoveVector;
|
||||
m_Bezier0_C2 += aMoveVector;
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
void SetAngle( double aAngle ) override;
|
||||
|
||||
/**
|
||||
* Move an edge of the footprint.
|
||||
* This is a footprint shape modification.
|
||||
|
@ -111,6 +113,9 @@ public:
|
|||
void SetEnd0( const wxPoint& aPoint ) { m_End0 = aPoint; }
|
||||
const wxPoint& GetEnd0() const { return m_End0; }
|
||||
|
||||
void SetThirdPoint0( const wxPoint& aPoint ){ m_ThirdPoint0 = aPoint; }
|
||||
const wxPoint& GetThirdPoint0() const { return m_ThirdPoint0; }
|
||||
|
||||
void SetBezier0_C1( const wxPoint& aPoint ) { m_Bezier0_C1 = aPoint; }
|
||||
const wxPoint& GetBezier0_C1() const { return m_Bezier0_C1; }
|
||||
|
||||
|
@ -151,6 +156,7 @@ public:
|
|||
|
||||
wxPoint m_Start0; ///< Start point or center, relative to module origin, orient 0.
|
||||
wxPoint m_End0; ///< End point, relative to module origin, orient 0.
|
||||
wxPoint m_ThirdPoint0; ///< End point for an arc.
|
||||
wxPoint m_Bezier0_C1; ///< Bezier Control Point 1, relative to module origin, orient 0.
|
||||
wxPoint m_Bezier0_C2; ///< Bezier Control Point 2, relative to module origin, orient 0.
|
||||
};
|
||||
|
|
|
@ -178,12 +178,14 @@ static DRAWSEGMENT* findPoint( const wxPoint& aPoint, std::vector< DRAWSEGMENT*
|
|||
* These closed inner outlines are considered as holes in the main outline
|
||||
* @param aSegList the initial list of drawsegments (only lines, circles and arcs).
|
||||
* @param aPolygons will contain the complex polygon.
|
||||
* @param aTolerance is the max distance between points that is still accepted as connected (internal units)
|
||||
* @param aTolerance is the max distance between points that is still accepted as connected
|
||||
* (internal units)
|
||||
* @param aErrorText is a wxString to return error message.
|
||||
* @param aErrorLocation is the optional position of the error in the outline
|
||||
*/
|
||||
bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
|
||||
wxString* aErrorText, unsigned int aTolerance, wxPoint* aErrorLocation )
|
||||
wxString* aErrorText, unsigned int aTolerance,
|
||||
wxPoint* aErrorLocation )
|
||||
{
|
||||
if( aSegList.size() == 0 )
|
||||
return true;
|
||||
|
@ -225,15 +227,12 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
break;
|
||||
|
||||
case S_ARC:
|
||||
// Freerouter does not yet understand arcs, so approximate
|
||||
// an arc with a series of short lines and put those
|
||||
// line segments into the !same! PATH.
|
||||
{
|
||||
wxPoint pstart = graphic->GetArcStart();
|
||||
wxPoint center = graphic->GetCenter();
|
||||
double angle = -graphic->GetAngle();
|
||||
double radius = graphic->GetRadius();
|
||||
int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 );
|
||||
int steps = GetArcToSegmentCount( radius, aTolerance, angle / 10.0 );
|
||||
wxPoint pt;
|
||||
|
||||
for( int step = 1; step<=steps; ++step )
|
||||
|
@ -273,10 +272,8 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
{
|
||||
graphic->RebuildBezierToSegmentsPointsList( graphic->GetWidth() );
|
||||
|
||||
for( unsigned int jj = 0; jj < graphic->GetBezierPoints().size(); jj++ )
|
||||
for( const wxPoint& pt : graphic->GetBezierPoints())
|
||||
{
|
||||
wxPoint pt = graphic->GetBezierPoints()[jj];
|
||||
|
||||
if( pt.x < xmin.x )
|
||||
{
|
||||
xmin = pt;
|
||||
|
@ -288,14 +285,14 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
|
||||
case S_POLYGON:
|
||||
{
|
||||
const auto poly = graphic->GetPolyShape();
|
||||
const SHAPE_POLY_SET poly = graphic->GetPolyShape();
|
||||
MODULE* module = aSegList[0]->GetParentModule();
|
||||
double orientation = module ? module->GetOrientation() : 0.0;
|
||||
VECTOR2I offset = module ? module->GetPosition() : VECTOR2I( 0, 0 );
|
||||
|
||||
for( auto iter = poly.CIterate(); iter; iter++ )
|
||||
{
|
||||
auto pt = *iter;
|
||||
VECTOR2I pt = *iter;
|
||||
RotatePoint( pt, orientation );
|
||||
pt += offset;
|
||||
|
||||
|
@ -308,6 +305,7 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -358,8 +356,10 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
// Polygon start point. Arbitrarily chosen end of the
|
||||
// segment and build the poly from here.
|
||||
|
||||
wxPoint startPt = wxPoint( graphic->GetEnd() );
|
||||
prevPt = graphic->GetEnd();
|
||||
wxPoint startPt = graphic->GetShape() == S_ARC ? graphic->GetArcEnd()
|
||||
: graphic->GetEnd();
|
||||
|
||||
prevPt = startPt;
|
||||
aPolygons.NewOutline();
|
||||
aPolygons.Append( prevPt );
|
||||
|
||||
|
@ -374,9 +374,8 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
{
|
||||
wxPoint nextPt;
|
||||
|
||||
// Use the line segment end point furthest away from
|
||||
// prevPt as we assume the other end to be ON prevPt or
|
||||
// very close to it.
|
||||
// Use the line segment end point furthest away from prevPt as we assume
|
||||
// the other end to be ON prevPt or very close to it.
|
||||
|
||||
if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) )
|
||||
nextPt = graphic->GetEnd();
|
||||
|
@ -389,9 +388,8 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
break;
|
||||
|
||||
case S_ARC:
|
||||
// We do not support arcs in polygons, so approximate
|
||||
// an arc with a series of short lines and put those
|
||||
// line segments into the !same! PATH.
|
||||
// We do not support arcs in polygons, so approximate an arc with a series of
|
||||
// short lines and put those line segments into the !same! PATH.
|
||||
{
|
||||
wxPoint pstart = graphic->GetArcStart();
|
||||
wxPoint pend = graphic->GetArcEnd();
|
||||
|
@ -424,9 +422,8 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
break;
|
||||
|
||||
case S_CURVE:
|
||||
// We do not support Bezier curves in polygons, so approximate
|
||||
// with a series of short lines and put those
|
||||
// line segments into the !same! PATH.
|
||||
// We do not support Bezier curves in polygons, so approximate with a series
|
||||
// of short lines and put those line segments into the !same! PATH.
|
||||
{
|
||||
wxPoint nextPt;
|
||||
bool reverse = false;
|
||||
|
@ -584,13 +581,9 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
// very close to it.
|
||||
|
||||
if( close_st( prevPt, graphic->GetStart(), graphic->GetEnd() ) )
|
||||
{
|
||||
nextPt = graphic->GetEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
nextPt = graphic->GetStart();
|
||||
}
|
||||
|
||||
prevPt = nextPt;
|
||||
aPolygons.Append( prevPt, -1, hole );
|
||||
|
@ -660,8 +653,8 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
}
|
||||
else
|
||||
{
|
||||
for( size_t jj = 0; jj < graphic->GetBezierPoints().size(); jj++ )
|
||||
aPolygons.Append( graphic->GetBezierPoints()[jj], -1, hole );
|
||||
for( const wxPoint& pt : graphic->GetBezierPoints())
|
||||
aPolygons.Append( pt, -1, hole );
|
||||
}
|
||||
|
||||
prevPt = nextPt;
|
||||
|
@ -742,7 +735,7 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
|
|||
return false;
|
||||
}
|
||||
|
||||
if( auto pt = seg1.Get().Intersect( seg2.Get(), true ) )
|
||||
if( boost::optional<VECTOR2I> pt = seg1.Get().Intersect( seg2.Get(), true ) )
|
||||
{
|
||||
if( aErrorLocation )
|
||||
{
|
||||
|
|
|
@ -1678,9 +1678,12 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
|
|||
width = biuParse( data, &data );
|
||||
layer = layerParse( data );
|
||||
|
||||
dwg->SetAngle( angle );
|
||||
dwg->m_Start0 = wxPoint( start0_x, start0_y );
|
||||
dwg->m_End0 = wxPoint( end0_x, end0_y );
|
||||
|
||||
// Setting angle will set m_ThirdPoint0, so must be done after setting
|
||||
// m_Start0 and m_End0
|
||||
dwg->SetAngle( angle );
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -163,10 +163,13 @@ void PCB_ARC::AddToModule( MODULE* aModule )
|
|||
EDGE_MODULE* arc = new EDGE_MODULE( aModule, ( IsCircle() ? S_CIRCLE : S_ARC ) );
|
||||
aModule->Add( arc );
|
||||
|
||||
arc->SetAngle( -m_angle );
|
||||
arc->m_Start0 = wxPoint( m_positionX, m_positionY );
|
||||
arc->m_End0 = wxPoint( m_startX, m_startY );
|
||||
|
||||
// Setting angle will set m_ThirdPoint0, so must be done after setting
|
||||
// m_Start0 and m_End0
|
||||
arc->SetAngle( -m_angle );
|
||||
|
||||
arc->SetWidth( m_width );
|
||||
arc->SetLayer( m_KiCadLayer );
|
||||
|
||||
|
|
|
@ -2960,6 +2960,8 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
|
|||
if( token != T_angle )
|
||||
Expecting( T_angle );
|
||||
|
||||
// Setting angle will set m_ThirdPoint0, so must be done after setting
|
||||
// m_Start0 and m_End0
|
||||
segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue