diff --git a/common/geometry/shape_line_chain.cpp b/common/geometry/shape_line_chain.cpp index 006b7b9e62..3a4c0eeaa5 100644 --- a/common/geometry/shape_line_chain.cpp +++ b/common/geometry/shape_line_chain.cpp @@ -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 - // *exactly* on the edge -- which saves us considerable processing time - return inside && ( aAccuracy > 0 || !PointOnEdge( aPt ) ); + // If accuracy is 0 then we need to make sure the point isn't actually on the edge. + // If accuracy is 1 then we don't really care whether or not the point is *exactly* on the + // 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 ); } diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp index 2af996c1b1..bb3aea3f62 100644 --- a/common/geometry/shape_poly_set.cpp +++ b/common/geometry/shape_poly_set.cpp @@ -1191,28 +1191,18 @@ bool SHAPE_POLY_SET::PointOnEdge( const VECTOR2I& aP ) const bool SHAPE_POLY_SET::Collide( const SEG& aSeg, int aClearance ) const { - - SHAPE_POLY_SET polySet = SHAPE_POLY_SET( *this ); - - // Inflate the polygon if necessary. - if( aClearance > 0 ) - { - // 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 ) ) + // 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. Use an accuracy of "1" to + // indicate that a collision with the edge should be treated the same as inside. + if( Collide( aSeg.A, 1 ) ) 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; } @@ -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 { - SHAPE_POLY_SET polySet = SHAPE_POLY_SET( *this ); - - // 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 ); + return Contains( aP, -1, aClearance ); } @@ -1403,20 +1383,20 @@ void SHAPE_POLY_SET::BuildBBoxCaches() } -bool SHAPE_POLY_SET::Contains( const VECTOR2I& aP, int aSubpolyIndex, bool aIgnoreHoles, - bool aIgnoreEdges, bool aUseBBoxCaches ) const +bool SHAPE_POLY_SET::Contains( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy, + bool aUseBBoxCaches ) const { - if( m_polys.size() == 0 ) // empty set? + if( m_polys.empty() ) return false; // If there is a polygon specified, check the condition against that polygon 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 for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ ) { - if( containsSingle( aP, polygonIdx, aIgnoreHoles, aIgnoreEdges, aUseBBoxCaches ) ) + if( containsSingle( aP, polygonIdx, aAccuracy, aUseBBoxCaches ) ) 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 aIgnoreEdges, bool aUseBBoxCaches ) const +bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy, + bool aUseBBoxCaches ) const { // 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 - for( int holeIdx = 0; holeIdx < HoleCount( aSubpolyIndex ); holeIdx++ ) - { - const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx ); + const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx ); - // If the point is inside a hole (and not on its edge), - // it is outside of the polygon - if( pointInPolygon( aP, hole, aIgnoreEdges, aUseBBoxCaches ) ) - return false; - } + // If the point is inside a hole it is outside of the polygon. Do not use aAccuracy + // here as it's meaning would be inverted. + if( hole.PointInside( aP, 1, aUseBBoxCaches ) ) + return false; } 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 ) { 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 ) { - // We calculate the min dist between the segment and each outline segment - // However, if the segment to test is inside the outline, and does not cross - // any edge, it can be seen outside the polygon. - // Therefore test if a segment end is inside ( testing only one end is enough ) - if( containsSingle( aPoint, aPolygonIndex ) ) + // We calculate the min dist between the segment and each outline segment. However, if the + // segment to test is inside the outline, and does not cross any edge, it can be seen outside + // the polygon. 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, 1 ) ) return 0; 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 - // However, if the segment to test is inside the outline, and does not cross - // any edge, it can be seen outside the polygon. - // Therefore test if a segment end is inside ( testing only one end is enough ) - if( containsSingle( aSegment.A, aPolygonIndex ) ) + // We calculate the min dist between the segment and each outline segment. However, if the + // segment to test is inside the outline, and does not cross any edge, it can be seen outside + // the polygon. 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, 1 ) ) return 0; SEGMENT_ITERATOR iterator = IterateSegmentsWithHoles( aPolygonIndex ); diff --git a/common/page_layout/ws_draw_item.cpp b/common/page_layout/ws_draw_item.cpp index 5e778fceff..4c046a2292 100644 --- a/common/page_layout/ws_draw_item.cpp +++ b/common/page_layout/ws_draw_item.cpp @@ -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 { - return m_Polygons.Contains( aPosition ); + return m_Polygons.Collide( aPosition, aAccuracy ); } diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp index 959449b794..e6263d46e5 100644 --- a/gerbview/gerber_draw_item.cpp +++ b/gerbview/gerber_draw_item.cpp @@ -776,12 +776,12 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const { case GBR_POLYGON: poly = m_Polygon; - return poly.Contains( VECTOR2I( ref_pos ), 0 ); + return poly.Contains( VECTOR2I( ref_pos ), 0, aAccuracy ); case GBR_SPOT_POLY: poly = GetDcodeDescr()->m_Polygon; poly.Move( m_Start ); - return poly.Contains( VECTOR2I( ref_pos ), 0 ); + return poly.Contains( VECTOR2I( ref_pos ), 0, aAccuracy ); case GBR_SPOT_RECT: return GetBoundingBox().Contains( aRefPos ); @@ -828,12 +828,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const case GBR_SPOT_MACRO: // Aperture macro polygons are already in absolute coordinates auto p = GetDcodeDescr()->GetMacro()->GetApertureMacroShape( this, m_Start ); - for( int i = 0; i < p->OutlineCount(); ++i ) - { - if( p->Contains( VECTOR2I( aRefPos ), i ) ) - return true; - } - return false; + return p->Contains( VECTOR2I( aRefPos ), -1, aAccuracy ); } // TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items) diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h index dba5c8df4f..d9a6c1853c 100644 --- a/include/geometry/shape_poly_set.h +++ b/include/geometry/shape_poly_set.h @@ -844,11 +844,6 @@ class SHAPE_POLY_SET : public SHAPE */ 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 ) { 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. */ bool CollideVertex( const VECTOR2I& aPoint, VERTEX_INDEX& aClosestVertex, - int aClearance = 0 ); + int aClearance = 0 ); /** * 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. */ 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 @@ -987,16 +982,13 @@ class SHAPE_POLY_SET : public SHAPE * * @param aP is the point to check * @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 * editing in between, but the caller MUST cache the bbox caches * before calling (via BuildBBoxCaches(), above) * @return true if the polygon contains the point */ - bool Contains( const VECTOR2I& aP, int aSubpolyIndex = -1, bool aIgnoreHoles = false, - bool aIgnoreEdges = false, bool aUseBBoxCaches = false ) const; + bool Contains( const VECTOR2I& aP, int aSubpolyIndex = -1, int aAccuracy = 0, + bool aUseBBoxCaches = false ) const; ///> Returns true if the set is empty (no polygons at all) 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 * distance is zero. */ - int DistanceToPolygon( SEG aSegment, int aIndex, int aSegmentWidth = 0 ); + int DistanceToPolygon( const SEG& aSegment, int aIndex, int aSegmentWidth = 0 ); /** * Function DistanceToPolygon @@ -1153,9 +1145,6 @@ class SHAPE_POLY_SET : public SHAPE void booleanOp( ClipperLib::ClipType aType, const SHAPE_POLY_SET& aShape, 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 * 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. * @param aSubpolyIndex is an integer specifying which polygon in the set has to be * checked. - * @param aIgnoreHoles can be set to true to ignore internal holes in the polygon - * @param aIgnoreEdges can be set to true to skip checking whether or not the point - * lies directly on the edge + * @param aAccuracy accuracy in internal units * @param aUseBBoxCaches gives faster performance when multiple calls are made with no * editing in between, but the caller MUST cache the bbox caches * before calling (via BuildBBoxCaches(), above) * @return bool - true if aP is inside aSubpolyIndex-th polygon; false in any other * case. */ - bool containsSingle( const VECTOR2I& aP, int aSubpolyIndex, bool aIgnoreHoles = false, - bool aIgnoreEdges = false, bool aUseBBoxCaches = false ) const; + bool containsSingle( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy, + bool aUseBBoxCaches = false ) const; /** * Operations ChamferPolygon and FilletPolygon are computed under the private chamferFillet diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index 88a308ab42..741d74c86d 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -448,7 +448,7 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& { 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). wxDateTime date( static_cast( m_LastEditTime ) ); @@ -459,18 +459,18 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& else 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 - 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 - aList.push_back( MSG_PANEL_ITEM( _( "Board Side" ), - IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) ); + aList.emplace_back( MSG_PANEL_ITEM( _( "Board Side" ), + IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) ); 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( ".." ); @@ -480,10 +480,10 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& if( m_ModuleStatus & MODULE_is_PLACED ) 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() ); - 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 switch( m_Attributs & 255 ) @@ -505,8 +505,8 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& break; } - aList.push_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( _( "Attributes" ), msg, BROWN ) ); + aList.emplace_back( MSG_PANEL_ITEM( _( "Footprint" ), FROM_UTF8( m_fpid.Format().c_str() ), BLUE ) ); if( m_3D_Drawings.empty() ) 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 - aList.push_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) ); + aList.emplace_back( MSG_PANEL_ITEM( _( "3D-Shape" ), msg, RED ) ); wxString doc, keyword; - doc.Printf( _( "Doc: %s" ), GetChars( m_Doc ) ); - keyword.Printf( _( "Key Words: %s" ), GetChars( m_KeyWord ) ); - aList.push_back( MSG_PANEL_ITEM( doc, keyword, BLACK ) ); + doc.Printf( _( "Doc: %s" ), m_Doc ); + keyword.Printf( _( "Key Words: %s" ), m_KeyWord ); + 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 { - SHAPE_POLY_SET shape = GetBoundingPoly(); - - shape.Inflate( aAccuracy, 4 ); - return shape.Contains( aPosition, -1, true ); + return GetBoundingPoly().Collide( aPosition, aAccuracy ); } diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 89749f362a..c8eb69c957 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -1198,9 +1198,10 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const * Convert the zone filled areas polygons to polygons * inflated (optional) by max( aClearanceValue, the zone clearance) * and copy them in aCornerBuffer - * param aClearanceValue = the clearance around polygons - * param aAddClearance = true to add a clearance area to the polygon - * false to create the outline polygon. + * @param aMinClearanceValue the min clearance around outlines + * @param aUseNetClearance true to use a clearance which is the max value between + * aMinClearanceValue and the net clearance + * false to use aMinClearanceValue only */ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aMinClearanceValue, bool aUseNetClearance ) const @@ -1215,6 +1216,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( if( aUseNetClearance && IsOnCopperLayer() ) { clearance = GetClearance(); + if( aMinClearanceValue > clearance ) clearance = aMinClearanceValue; } @@ -1223,7 +1225,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( // holes are linked to the main outline, so only one polygon is created. if( clearance ) { - auto board = GetBoard(); + BOARD* board = GetBoard(); int maxError = ARC_HIGH_DEF; if( board ) @@ -1232,6 +1234,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( int segCount = std::max( GetArcToSegmentCount( clearance, maxError, 360.0 ), 3 ); polybuffer.Inflate( clearance, segCount ); } + polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST ); aCornerBuffer.Append( polybuffer ); } diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index e42af26374..75a48d8dc9 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -247,18 +247,6 @@ public: */ 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 * tests if the given wxPoint is within the bounds of a filled area of this zone. @@ -575,8 +563,7 @@ public: /** * Function GetSmoothedPoly - * returns a pointer to the corner-smoothed version of - * m_Poly if it exists, otherwise it returns m_Poly. + * returns a pointer to the corner-smoothed version of m_Poly. * @return SHAPE_POLY_SET* - pointer to the polygon. */ bool BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const; diff --git a/pcbnew/eagle_plugin.cpp b/pcbnew/eagle_plugin.cpp index bc260c9a2e..72539bc2ab 100644 --- a/pcbnew/eagle_plugin.cpp +++ b/pcbnew/eagle_plugin.cpp @@ -1186,7 +1186,7 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode ) // We trace the zone such that the copper is completely inside. 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 ); } diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 9a9f0ba7f0..2457391eac 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -852,10 +852,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, int zone_margin = 0; #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 ) continue; diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index fbe0c81415..e3dbbc675b 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -111,9 +111,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck bool filledPolyWithOutline = not m_board->GetDesignSettings().m_ZoneUseNoOutlineInFill; if( ADVANCED_CFG::GetCfg().m_forceThickOutlinesInZones ) - { filledPolyWithOutline = true; - } std::unique_lock 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 ); // 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 ); 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 * ( 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; - /* 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 * this zone */