Improve performance, commenting and API of some polygon classes.
This commit is contained in:
parent
560fda70a2
commit
1a7cef2950
|
@ -392,9 +392,16 @@ bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aPt, int aAccuracy, bool aUs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If aAccuracy is > 0 then by definition we don't care whether or not the point is
|
// If accuracy is 0 then we need to make sure the point isn't actually on the edge.
|
||||||
// *exactly* on the edge -- which saves us considerable processing time
|
// If accuracy is 1 then we don't really care whether or not the point is *exactly* on the
|
||||||
return inside && ( aAccuracy > 0 || !PointOnEdge( aPt ) );
|
// edge, so we skip edge processing for performance.
|
||||||
|
// If accuracy is > 1, then we use "OnEdge(accuracy-1)" as a proxy for "Inside(accuracy)".
|
||||||
|
if( aAccuracy == 0 )
|
||||||
|
return inside && !PointOnEdge( aPt );
|
||||||
|
else if( aAccuracy == 1 )
|
||||||
|
return inside;
|
||||||
|
else
|
||||||
|
return inside || PointOnEdge( aPt, aAccuracy - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1191,28 +1191,18 @@ bool SHAPE_POLY_SET::PointOnEdge( const VECTOR2I& aP ) const
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::Collide( const SEG& aSeg, int aClearance ) const
|
bool SHAPE_POLY_SET::Collide( const SEG& aSeg, int aClearance ) const
|
||||||
{
|
{
|
||||||
|
// We are going to check to see if the segment crosses an external boundary. However, if
|
||||||
SHAPE_POLY_SET polySet = SHAPE_POLY_SET( *this );
|
// the full segment is inside the polyset, this will not be true. So we first test to see
|
||||||
|
// if one of the points is inside. If true, then we collide. Use an accuracy of "1" to
|
||||||
// Inflate the polygon if necessary.
|
// indicate that a collision with the edge should be treated the same as inside.
|
||||||
if( aClearance > 0 )
|
if( Collide( aSeg.A, 1 ) )
|
||||||
{
|
|
||||||
// fixme: the number of arc segments should not be hardcoded
|
|
||||||
polySet.Inflate( aClearance, 8 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are going to check to see if the segment crosses an external
|
|
||||||
// boundary. However, if the full segment is inside the polyset, this
|
|
||||||
// will not be true. So we first test to see if one of the points is
|
|
||||||
// inside. If true, then we collide
|
|
||||||
if( polySet.Contains( aSeg.A ) )
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for( SEGMENT_ITERATOR iterator = polySet.IterateSegmentsWithHoles(); iterator; iterator++ )
|
for( SEGMENT_ITERATOR it = ( (SHAPE_POLY_SET*) this )->IterateSegmentsWithHoles(); it; it++ )
|
||||||
{
|
{
|
||||||
SEG polygonEdge = *iterator;
|
SEG polygonEdge = *it;
|
||||||
|
|
||||||
if( polygonEdge.Intersect( aSeg, true ) )
|
if( polygonEdge.Collide( aSeg, aClearance ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,17 +1212,7 @@ bool SHAPE_POLY_SET::Collide( const SEG& aSeg, int aClearance ) const
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::Collide( const VECTOR2I& aP, int aClearance ) const
|
bool SHAPE_POLY_SET::Collide( const VECTOR2I& aP, int aClearance ) const
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET polySet = SHAPE_POLY_SET( *this );
|
return Contains( aP, -1, aClearance );
|
||||||
|
|
||||||
// Inflate the polygon if necessary.
|
|
||||||
if( aClearance > 0 )
|
|
||||||
{
|
|
||||||
// fixme: the number of arc segments should not be hardcoded
|
|
||||||
polySet.Inflate( aClearance, 8 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is a collision if and only if the point is inside of the polygon.
|
|
||||||
return polySet.Contains( aP );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1403,20 +1383,20 @@ void SHAPE_POLY_SET::BuildBBoxCaches()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::Contains( const VECTOR2I& aP, int aSubpolyIndex, bool aIgnoreHoles,
|
bool SHAPE_POLY_SET::Contains( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy,
|
||||||
bool aIgnoreEdges, bool aUseBBoxCaches ) const
|
bool aUseBBoxCaches ) const
|
||||||
{
|
{
|
||||||
if( m_polys.size() == 0 ) // empty set?
|
if( m_polys.empty() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If there is a polygon specified, check the condition against that polygon
|
// If there is a polygon specified, check the condition against that polygon
|
||||||
if( aSubpolyIndex >= 0 )
|
if( aSubpolyIndex >= 0 )
|
||||||
return containsSingle( aP, aSubpolyIndex, aIgnoreHoles, aIgnoreEdges, aUseBBoxCaches );
|
return containsSingle( aP, aSubpolyIndex, aAccuracy, aUseBBoxCaches );
|
||||||
|
|
||||||
// In any other case, check it against all polygons in the set
|
// In any other case, check it against all polygons in the set
|
||||||
for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
|
for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
|
||||||
{
|
{
|
||||||
if( containsSingle( aP, polygonIdx, aIgnoreHoles, aIgnoreEdges, aUseBBoxCaches ) )
|
if( containsSingle( aP, polygonIdx, aAccuracy, aUseBBoxCaches ) )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1442,24 +1422,21 @@ void SHAPE_POLY_SET::RemoveVertex( VERTEX_INDEX aIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex, bool aIgnoreHoles,
|
bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy,
|
||||||
bool aIgnoreEdges, bool aUseBBoxCaches ) const
|
bool aUseBBoxCaches ) const
|
||||||
{
|
{
|
||||||
// Check that the point is inside the outline
|
// Check that the point is inside the outline
|
||||||
if( pointInPolygon( aP, m_polys[aSubpolyIndex][0], aIgnoreEdges ) )
|
if( m_polys[aSubpolyIndex][0].PointInside( aP, aAccuracy ) )
|
||||||
{
|
{
|
||||||
if( !aIgnoreHoles )
|
// Check that the point is not in any of the holes
|
||||||
|
for( int holeIdx = 0; holeIdx < HoleCount( aSubpolyIndex ); holeIdx++ )
|
||||||
{
|
{
|
||||||
// Check that the point is not in any of the holes
|
const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx );
|
||||||
for( int holeIdx = 0; holeIdx < HoleCount( aSubpolyIndex ); holeIdx++ )
|
|
||||||
{
|
|
||||||
const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx );
|
|
||||||
|
|
||||||
// If the point is inside a hole (and not on its edge),
|
// If the point is inside a hole it is outside of the polygon. Do not use aAccuracy
|
||||||
// it is outside of the polygon
|
// here as it's meaning would be inverted.
|
||||||
if( pointInPolygon( aP, hole, aIgnoreEdges, aUseBBoxCaches ) )
|
if( hole.PointInside( aP, 1, aUseBBoxCaches ) )
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1469,13 +1446,6 @@ bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_POLY_SET::pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath,
|
|
||||||
bool aIgnoreEdges, bool aUseBBoxCaches ) const
|
|
||||||
{
|
|
||||||
return aPath.PointInside( aP, aIgnoreEdges ? 1 : 0, aUseBBoxCaches );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::Move( const VECTOR2I& aVector )
|
void SHAPE_POLY_SET::Move( const VECTOR2I& aVector )
|
||||||
{
|
{
|
||||||
for( POLYGON& poly : m_polys )
|
for( POLYGON& poly : m_polys )
|
||||||
|
@ -1526,11 +1496,11 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::FilletPolygon( unsigned int aRadius,
|
||||||
|
|
||||||
int SHAPE_POLY_SET::DistanceToPolygon( VECTOR2I aPoint, int aPolygonIndex )
|
int SHAPE_POLY_SET::DistanceToPolygon( VECTOR2I aPoint, int aPolygonIndex )
|
||||||
{
|
{
|
||||||
// We calculate the min dist between the segment and each outline segment
|
// We calculate the min dist between the segment and each outline segment. However, if the
|
||||||
// However, if the segment to test is inside the outline, and does not cross
|
// segment to test is inside the outline, and does not cross any edge, it can be seen outside
|
||||||
// any edge, it can be seen outside the polygon.
|
// the polygon. Therefore test if a segment end is inside (testing only one end is enough).
|
||||||
// Therefore test if a segment end is inside ( testing only one end is enough )
|
// Use an accuracy of "1" to say that we don't care if it's exactly on the edge or not.
|
||||||
if( containsSingle( aPoint, aPolygonIndex ) )
|
if( containsSingle( aPoint, aPolygonIndex, 1 ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SEGMENT_ITERATOR iterator = IterateSegmentsWithHoles( aPolygonIndex );
|
SEGMENT_ITERATOR iterator = IterateSegmentsWithHoles( aPolygonIndex );
|
||||||
|
@ -1552,13 +1522,13 @@ int SHAPE_POLY_SET::DistanceToPolygon( VECTOR2I aPoint, int aPolygonIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SHAPE_POLY_SET::DistanceToPolygon( SEG aSegment, int aPolygonIndex, int aSegmentWidth )
|
int SHAPE_POLY_SET::DistanceToPolygon( const SEG& aSegment, int aPolygonIndex, int aSegmentWidth )
|
||||||
{
|
{
|
||||||
// We calculate the min dist between the segment and each outline segment
|
// We calculate the min dist between the segment and each outline segment. However, if the
|
||||||
// However, if the segment to test is inside the outline, and does not cross
|
// segment to test is inside the outline, and does not cross any edge, it can be seen outside
|
||||||
// any edge, it can be seen outside the polygon.
|
// the polygon. Therefore test if a segment end is inside (testing only one end is enough).
|
||||||
// Therefore test if a segment end is inside ( testing only one end is enough )
|
// Use an accuracy of "1" to say that we don't care if it's exactly on the edge or not.
|
||||||
if( containsSingle( aSegment.A, aPolygonIndex ) )
|
if( containsSingle( aSegment.A, aPolygonIndex, 1 ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SEGMENT_ITERATOR iterator = IterateSegmentsWithHoles( aPolygonIndex );
|
SEGMENT_ITERATOR iterator = IterateSegmentsWithHoles( aPolygonIndex );
|
||||||
|
|
|
@ -236,7 +236,7 @@ const EDA_RECT WS_DRAW_ITEM_POLYPOLYGONS::GetBoundingBox() const
|
||||||
|
|
||||||
bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
bool WS_DRAW_ITEM_POLYPOLYGONS::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
return m_Polygons.Contains( aPosition );
|
return m_Polygons.Collide( aPosition, aAccuracy );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -776,12 +776,12 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
case GBR_POLYGON:
|
case GBR_POLYGON:
|
||||||
poly = m_Polygon;
|
poly = m_Polygon;
|
||||||
return poly.Contains( VECTOR2I( ref_pos ), 0 );
|
return poly.Contains( VECTOR2I( ref_pos ), 0, aAccuracy );
|
||||||
|
|
||||||
case GBR_SPOT_POLY:
|
case GBR_SPOT_POLY:
|
||||||
poly = GetDcodeDescr()->m_Polygon;
|
poly = GetDcodeDescr()->m_Polygon;
|
||||||
poly.Move( m_Start );
|
poly.Move( m_Start );
|
||||||
return poly.Contains( VECTOR2I( ref_pos ), 0 );
|
return poly.Contains( VECTOR2I( ref_pos ), 0, aAccuracy );
|
||||||
|
|
||||||
case GBR_SPOT_RECT:
|
case GBR_SPOT_RECT:
|
||||||
return GetBoundingBox().Contains( aRefPos );
|
return GetBoundingBox().Contains( aRefPos );
|
||||||
|
@ -828,12 +828,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const
|
||||||
case GBR_SPOT_MACRO:
|
case GBR_SPOT_MACRO:
|
||||||
// Aperture macro polygons are already in absolute coordinates
|
// Aperture macro polygons are already in absolute coordinates
|
||||||
auto p = GetDcodeDescr()->GetMacro()->GetApertureMacroShape( this, m_Start );
|
auto p = GetDcodeDescr()->GetMacro()->GetApertureMacroShape( this, m_Start );
|
||||||
for( int i = 0; i < p->OutlineCount(); ++i )
|
return p->Contains( VECTOR2I( aRefPos ), -1, aAccuracy );
|
||||||
{
|
|
||||||
if( p->Contains( VECTOR2I( aRefPos ), i ) )
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items)
|
// TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items)
|
||||||
|
|
|
@ -844,11 +844,6 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
*/
|
*/
|
||||||
void Inflate( int aFactor, int aCircleSegmentsCount, bool aPreserveCorners = false );
|
void Inflate( int aFactor, int aCircleSegmentsCount, bool aPreserveCorners = false );
|
||||||
|
|
||||||
void Inflate( int aFactor, bool aPreserveCorners )
|
|
||||||
{
|
|
||||||
Inflate( aFactor, 32, aPreserveCorners );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Deflate( int aFactor, int aCircleSegmentsCount, bool aPreserveCorners = false )
|
void Deflate( int aFactor, int aCircleSegmentsCount, bool aPreserveCorners = false )
|
||||||
{
|
{
|
||||||
Inflate( -aFactor, aPreserveCorners, aPreserveCorners );
|
Inflate( -aFactor, aPreserveCorners, aPreserveCorners );
|
||||||
|
@ -961,7 +956,7 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
* @return bool - true if there is a collision, false in any other case.
|
* @return bool - true if there is a collision, false in any other case.
|
||||||
*/
|
*/
|
||||||
bool CollideVertex( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
bool CollideVertex( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
||||||
int aClearance = 0 );
|
int aClearance = 0 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function CollideEdge
|
* Function CollideEdge
|
||||||
|
@ -974,7 +969,7 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
* @return bool - true if there is a collision, false in any other case.
|
* @return bool - true if there is a collision, false in any other case.
|
||||||
*/
|
*/
|
||||||
bool CollideEdge( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
bool CollideEdge( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex,
|
||||||
int aClearance = 0 );
|
int aClearance = 0 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs BBoxCaches for Contains(), below. These caches MUST be built before a
|
* Constructs BBoxCaches for Contains(), below. These caches MUST be built before a
|
||||||
|
@ -987,16 +982,13 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
*
|
*
|
||||||
* @param aP is the point to check
|
* @param aP is the point to check
|
||||||
* @param aSubpolyIndex is the subpolygon to check, or -1 to check all
|
* @param aSubpolyIndex is the subpolygon to check, or -1 to check all
|
||||||
* @param aIgnoreHoles controls whether or not internal holes are considered
|
|
||||||
* @param aIgnoreEdges controls whether or not a check for the point lying exactly on
|
|
||||||
* the polygon edge is made
|
|
||||||
* @param aUseBBoxCaches gives faster performance when multiple calls are made with no
|
* @param aUseBBoxCaches gives faster performance when multiple calls are made with no
|
||||||
* editing in between, but the caller MUST cache the bbox caches
|
* editing in between, but the caller MUST cache the bbox caches
|
||||||
* before calling (via BuildBBoxCaches(), above)
|
* before calling (via BuildBBoxCaches(), above)
|
||||||
* @return true if the polygon contains the point
|
* @return true if the polygon contains the point
|
||||||
*/
|
*/
|
||||||
bool Contains( const VECTOR2I& aP, int aSubpolyIndex = -1, bool aIgnoreHoles = false,
|
bool Contains( const VECTOR2I& aP, int aSubpolyIndex = -1, int aAccuracy = 0,
|
||||||
bool aIgnoreEdges = false, bool aUseBBoxCaches = false ) const;
|
bool aUseBBoxCaches = false ) const;
|
||||||
|
|
||||||
///> Returns true if the set is empty (no polygons at all)
|
///> Returns true if the set is empty (no polygons at all)
|
||||||
bool IsEmpty() const
|
bool IsEmpty() const
|
||||||
|
@ -1102,7 +1094,7 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
* aIndex-th polygon. If the point is contained in the polygon, the
|
* aIndex-th polygon. If the point is contained in the polygon, the
|
||||||
* distance is zero.
|
* distance is zero.
|
||||||
*/
|
*/
|
||||||
int DistanceToPolygon( SEG aSegment, int aIndex, int aSegmentWidth = 0 );
|
int DistanceToPolygon( const SEG& aSegment, int aIndex, int aSegmentWidth = 0 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DistanceToPolygon
|
* Function DistanceToPolygon
|
||||||
|
@ -1153,9 +1145,6 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape,
|
||||||
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode );
|
const SHAPE_POLY_SET& aOtherShape, POLYGON_MODE aFastMode );
|
||||||
|
|
||||||
bool pointInPolygon( const VECTOR2I& aP, const SHAPE_LINE_CHAIN& aPath,
|
|
||||||
bool aIgnoreEdges, bool aUseBBoxCaches = false ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* containsSingle function
|
* containsSingle function
|
||||||
* Checks whether the point aP is inside the aSubpolyIndex-th polygon of the polyset. If
|
* Checks whether the point aP is inside the aSubpolyIndex-th polygon of the polyset. If
|
||||||
|
@ -1164,17 +1153,15 @@ class SHAPE_POLY_SET : public SHAPE
|
||||||
* the aSubpolyIndex-th polygon will be tested.
|
* the aSubpolyIndex-th polygon will be tested.
|
||||||
* @param aSubpolyIndex is an integer specifying which polygon in the set has to be
|
* @param aSubpolyIndex is an integer specifying which polygon in the set has to be
|
||||||
* checked.
|
* checked.
|
||||||
* @param aIgnoreHoles can be set to true to ignore internal holes in the polygon
|
* @param aAccuracy accuracy in internal units
|
||||||
* @param aIgnoreEdges can be set to true to skip checking whether or not the point
|
|
||||||
* lies directly on the edge
|
|
||||||
* @param aUseBBoxCaches gives faster performance when multiple calls are made with no
|
* @param aUseBBoxCaches gives faster performance when multiple calls are made with no
|
||||||
* editing in between, but the caller MUST cache the bbox caches
|
* editing in between, but the caller MUST cache the bbox caches
|
||||||
* before calling (via BuildBBoxCaches(), above)
|
* before calling (via BuildBBoxCaches(), above)
|
||||||
* @return bool - true if aP is inside aSubpolyIndex-th polygon; false in any other
|
* @return bool - true if aP is inside aSubpolyIndex-th polygon; false in any other
|
||||||
* case.
|
* case.
|
||||||
*/
|
*/
|
||||||
bool containsSingle( const VECTOR2I& aP, int aSubpolyIndex, bool aIgnoreHoles = false,
|
bool containsSingle( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy,
|
||||||
bool aIgnoreEdges = false, bool aUseBBoxCaches = false ) const;
|
bool aUseBBoxCaches = false ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Operations ChamferPolygon and FilletPolygon are computed under the private chamferFillet
|
* Operations ChamferPolygon and FilletPolygon are computed under the private chamferFillet
|
||||||
|
|
|
@ -448,7 +448,7 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
|
aList.emplace_back( MSG_PANEL_ITEM( m_Reference->GetShownText(), m_Value->GetShownText(), DARKCYAN ) );
|
||||||
|
|
||||||
// Display last date the component was edited (useful in Module Editor).
|
// Display last date the component was edited (useful in Module Editor).
|
||||||
wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
|
wxDateTime date( static_cast<time_t>( m_LastEditTime ) );
|
||||||
|
@ -459,18 +459,18 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||||
else
|
else
|
||||||
msg = _( "Unknown" );
|
msg = _( "Unknown" );
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
|
||||||
|
|
||||||
// display schematic path
|
// display schematic path
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
|
||||||
|
|
||||||
// display the board side placement
|
// display the board side placement
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Board Side" ),
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Board Side" ),
|
||||||
IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
|
IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
|
||||||
|
|
||||||
|
|
||||||
msg.Printf( wxT( "%zu" ), m_pads.size() );
|
msg.Printf( wxT( "%zu" ), m_pads.size() );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
|
||||||
|
|
||||||
msg = wxT( ".." );
|
msg = wxT( ".." );
|
||||||
|
|
||||||
|
@ -480,10 +480,10 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||||
if( m_ModuleStatus & MODULE_is_PLACED )
|
if( m_ModuleStatus & MODULE_is_PLACED )
|
||||||
msg[1] = 'P';
|
msg[1] = 'P';
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Status" ), msg, MAGENTA ) );
|
||||||
|
|
||||||
msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
|
msg.Printf( wxT( "%.1f" ), GetOrientationDegrees() );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BROWN ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BROWN ) );
|
||||||
|
|
||||||
// Controls on right side of the dialog
|
// Controls on right side of the dialog
|
||||||
switch( m_Attributs & 255 )
|
switch( m_Attributs & 255 )
|
||||||
|
@ -505,8 +505,8 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Attributes" ), msg, BROWN ) );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) );
|
||||||
|
|
||||||
if( m_3D_Drawings.empty() )
|
if( m_3D_Drawings.empty() )
|
||||||
msg = _( "No 3D shape" );
|
msg = _( "No 3D shape" );
|
||||||
|
@ -515,12 +515,12 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >&
|
||||||
|
|
||||||
// Search the first active 3D shape in list
|
// Search the first active 3D shape in list
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
|
aList.emplace_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) );
|
||||||
|
|
||||||
wxString doc, keyword;
|
wxString doc, keyword;
|
||||||
doc.Printf( _( "Doc: %s" ), GetChars( m_Doc ) );
|
doc.Printf( _( "Doc: %s" ), m_Doc );
|
||||||
keyword.Printf( _( "Key Words: %s" ), GetChars( m_KeyWord ) );
|
keyword.Printf( _( "Key Words: %s" ), m_KeyWord );
|
||||||
aList.push_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
|
aList.emplace_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -533,10 +533,7 @@ bool MODULE::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||||
|
|
||||||
bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
|
bool MODULE::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET shape = GetBoundingPoly();
|
return GetBoundingPoly().Collide( aPosition, aAccuracy );
|
||||||
|
|
||||||
shape.Inflate( aAccuracy, 4 );
|
|
||||||
return shape.Contains( aPosition, -1, true );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1198,9 +1198,10 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const
|
||||||
* Convert the zone filled areas polygons to polygons
|
* Convert the zone filled areas polygons to polygons
|
||||||
* inflated (optional) by max( aClearanceValue, the zone clearance)
|
* inflated (optional) by max( aClearanceValue, the zone clearance)
|
||||||
* and copy them in aCornerBuffer
|
* and copy them in aCornerBuffer
|
||||||
* param aClearanceValue = the clearance around polygons
|
* @param aMinClearanceValue the min clearance around outlines
|
||||||
* param aAddClearance = true to add a clearance area to the polygon
|
* @param aUseNetClearance true to use a clearance which is the max value between
|
||||||
* false to create the outline polygon.
|
* aMinClearanceValue and the net clearance
|
||||||
|
* false to use aMinClearanceValue only
|
||||||
*/
|
*/
|
||||||
void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
SHAPE_POLY_SET& aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance ) const
|
SHAPE_POLY_SET& aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance ) const
|
||||||
|
@ -1215,6 +1216,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
if( aUseNetClearance && IsOnCopperLayer() )
|
if( aUseNetClearance && IsOnCopperLayer() )
|
||||||
{
|
{
|
||||||
clearance = GetClearance();
|
clearance = GetClearance();
|
||||||
|
|
||||||
if( aMinClearanceValue > clearance )
|
if( aMinClearanceValue > clearance )
|
||||||
clearance = aMinClearanceValue;
|
clearance = aMinClearanceValue;
|
||||||
}
|
}
|
||||||
|
@ -1223,7 +1225,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
// holes are linked to the main outline, so only one polygon is created.
|
// holes are linked to the main outline, so only one polygon is created.
|
||||||
if( clearance )
|
if( clearance )
|
||||||
{
|
{
|
||||||
auto board = GetBoard();
|
BOARD* board = GetBoard();
|
||||||
int maxError = ARC_HIGH_DEF;
|
int maxError = ARC_HIGH_DEF;
|
||||||
|
|
||||||
if( board )
|
if( board )
|
||||||
|
@ -1232,6 +1234,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
|
||||||
int segCount = std::max( GetArcToSegmentCount( clearance, maxError, 360.0 ), 3 );
|
int segCount = std::max( GetArcToSegmentCount( clearance, maxError, 360.0 ), 3 );
|
||||||
polybuffer.Inflate( clearance, segCount );
|
polybuffer.Inflate( clearance, segCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
aCornerBuffer.Append( polybuffer );
|
aCornerBuffer.Append( polybuffer );
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,18 +247,6 @@ public:
|
||||||
*/
|
*/
|
||||||
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
|
bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Function HitTest
|
|
||||||
* tests if a point is inside the zone area, i.e. inside the main outline
|
|
||||||
* and outside holes.
|
|
||||||
* @param aPosition : the wxPoint to test
|
|
||||||
* @return bool - true if a hit, else false
|
|
||||||
*/
|
|
||||||
bool HitTestInsideZone( const wxPoint& aPosition ) const
|
|
||||||
{
|
|
||||||
return m_Poly->Contains( VECTOR2I( aPosition ), 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function HitTestFilledArea
|
* Function HitTestFilledArea
|
||||||
* tests if the given wxPoint is within the bounds of a filled area of this zone.
|
* tests if the given wxPoint is within the bounds of a filled area of this zone.
|
||||||
|
@ -575,8 +563,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetSmoothedPoly
|
* Function GetSmoothedPoly
|
||||||
* returns a pointer to the corner-smoothed version of
|
* returns a pointer to the corner-smoothed version of m_Poly.
|
||||||
* m_Poly if it exists, otherwise it returns m_Poly.
|
|
||||||
* @return SHAPE_POLY_SET* - pointer to the polygon.
|
* @return SHAPE_POLY_SET* - pointer to the polygon.
|
||||||
*/
|
*/
|
||||||
bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const;
|
bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const;
|
||||||
|
|
|
@ -1186,7 +1186,7 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
|
||||||
// We trace the zone such that the copper is completely inside.
|
// We trace the zone such that the copper is completely inside.
|
||||||
if( p.width.ToPcbUnits() > 0 )
|
if( p.width.ToPcbUnits() > 0 )
|
||||||
{
|
{
|
||||||
polygon.Inflate( p.width.ToPcbUnits() / 2, true );
|
polygon.Inflate( p.width.ToPcbUnits() / 2, 32, true );
|
||||||
polygon.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
polygon.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -852,10 +852,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||||
int zone_margin = 0;
|
int zone_margin = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
|
for( ZONE_CONTAINER* zone : aBoard->Zones() )
|
||||||
{
|
{
|
||||||
ZONE_CONTAINER* zone = aBoard->GetArea( ii );
|
|
||||||
|
|
||||||
if( zone->GetLayer() != layer )
|
if( zone->GetLayer() != layer )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
|
||||||
bool filledPolyWithOutline = not m_board->GetDesignSettings().m_ZoneUseNoOutlineInFill;
|
bool filledPolyWithOutline = not m_board->GetDesignSettings().m_ZoneUseNoOutlineInFill;
|
||||||
|
|
||||||
if( ADVANCED_CFG::GetCfg().m_forceThickOutlinesInZones )
|
if( ADVANCED_CFG::GetCfg().m_forceThickOutlinesInZones )
|
||||||
{
|
|
||||||
filledPolyWithOutline = true;
|
filledPolyWithOutline = true;
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock( connectivity->GetLock(), std::try_to_lock );
|
std::unique_lock<std::mutex> lock( connectivity->GetLock(), std::try_to_lock );
|
||||||
|
|
||||||
|
@ -722,7 +720,7 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone,
|
||||||
const VECTOR2I& testPt = spoke.CPoint( 3 );
|
const VECTOR2I& testPt = spoke.CPoint( 3 );
|
||||||
|
|
||||||
// Hit-test against zone body
|
// Hit-test against zone body
|
||||||
if( testAreas.Contains( testPt, -1, false, true, USE_BBOX_CACHES ) )
|
if( testAreas.Contains( testPt, -1, 1, USE_BBOX_CACHES ) )
|
||||||
{
|
{
|
||||||
aRawPolys.AddOutline( spoke );
|
aRawPolys.AddOutline( spoke );
|
||||||
continue;
|
continue;
|
||||||
|
@ -782,7 +780,8 @@ void ZONE_FILLER::computeRawFilledArea( const ZONE_CONTAINER* aZone,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Build the filled solid areas data from real outlines (stored in m_Poly)
|
/*
|
||||||
|
* Build the filled solid areas data from real outlines (stored in m_Poly)
|
||||||
* The solid areas can be more than one on copper layers, and do not have holes
|
* The solid areas can be more than one on copper layers, and do not have holes
|
||||||
* ( holes are linked by overlapping segments to the main outline)
|
* ( holes are linked by overlapping segments to the main outline)
|
||||||
*/
|
*/
|
||||||
|
@ -791,7 +790,8 @@ bool ZONE_FILLER::fillSingleZone( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& aRawPol
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET smoothedPoly;
|
SHAPE_POLY_SET smoothedPoly;
|
||||||
|
|
||||||
/* convert outlines + holes to outlines without holes (adding extra segments if necessary)
|
/*
|
||||||
|
* convert outlines + holes to outlines without holes (adding extra segments if necessary)
|
||||||
* m_Poly data is expected normalized, i.e. NormalizeAreaOutlines was used after building
|
* m_Poly data is expected normalized, i.e. NormalizeAreaOutlines was used after building
|
||||||
* this zone
|
* this zone
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue