From 889408c96a0d8af204bc7712b04256cde4e5d8e3 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 29 Nov 2020 14:00:39 +0000 Subject: [PATCH] More improvements to new selection disambiguation. Also a rationalization of text polygon generators, with the "standard" version inherited from BOARD_ITEM now giving the bounding box. This requires callers who want the (much) more expensive stroke-based one to call it explicitly (and brings PCB_TEXT in line with the was FP_TEXT already was. Fixes https://gitlab.com/kicad/code/kicad/issues/6525 --- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 2 +- 3d-viewer/3d_canvas/create_layer_items.cpp | 72 +++++++----- ...board_items_to_polygon_shape_transform.cpp | 57 ++++++--- pcbnew/footprint.cpp | 109 ++++++++++-------- pcbnew/footprint.h | 2 +- pcbnew/fp_text.h | 4 + pcbnew/pcb_text.h | 14 ++- pcbnew/tools/pad_tool.cpp | 10 +- pcbnew/tools/selection_tool.cpp | 14 ++- pcbnew/zone_filler.cpp | 28 ++--- .../polygon_generator/polygon_generator.cpp | 12 +- 11 files changed, 195 insertions(+), 129 deletions(-) diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index efd79c38e4..d271ddebb0 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -82,7 +82,7 @@ void addTextSegmToContainer( int x0, int y0, int xf, int yf, void* aData ) // Based on -// void PCB_TEXT::TransformShapeWithClearanceToPolygon +// void PCB_TEXT::TransformTextShapeWithClearanceToPolygon // board_items_to_polygon_shape_transform.cpp void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const PCB_TEXT* aText, CGENERICCONTAINER2D *aDstContainer, diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index 23eba48f8a..afc4aaa67f 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -631,7 +631,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) CBVHCONTAINER2D *layerContainer = m_layers_container2D[curr_layer_id]; // Add graphic items on copper layers (texts and other graphics) - for( auto item : m_board->Drawings() ) + for( BOARD_ITEM* item : m_board->Drawings() ) { if( !item->IsOnLayer( curr_layer_id ) ) continue; @@ -683,11 +683,19 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) switch( item->Type() ) { case PCB_SHAPE_T: - case PCB_TEXT_T: item->TransformShapeWithClearanceToPolygon( *layerPoly, cur_layer_id, 0, ARC_HIGH_DEF, ERROR_INSIDE ); break; + case PCB_TEXT_T: + { + PCB_TEXT* text = static_cast( item ); + + text->TransformTextShapeWithClearanceToPolygon( *layerPoly, cur_layer_id, 0, + ARC_HIGH_DEF, ERROR_INSIDE ); + } + break; + default: wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), item->Type() ); @@ -781,7 +789,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) if( m_F_Cu_PlatedPads_poly && ( m_layers_poly.find( F_Cu ) != m_layers_poly.end() ) ) { SHAPE_POLY_SET *layerPoly_F_Cu = m_layers_poly[F_Cu]; - layerPoly_F_Cu->BooleanSubtract( *m_F_Cu_PlatedPads_poly, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST ); + layerPoly_F_Cu->BooleanSubtract( *m_F_Cu_PlatedPads_poly, SHAPE_POLY_SET::PM_FAST ); m_F_Cu_PlatedPads_poly->Simplify( SHAPE_POLY_SET::PM_FAST ); } @@ -789,7 +797,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) if( m_B_Cu_PlatedPads_poly && ( m_layers_poly.find( B_Cu ) != m_layers_poly.end() ) ) { SHAPE_POLY_SET *layerPoly_B_Cu = m_layers_poly[B_Cu]; - layerPoly_B_Cu->BooleanSubtract( *m_B_Cu_PlatedPads_poly, SHAPE_POLY_SET::POLYGON_MODE::PM_FAST ); + layerPoly_B_Cu->BooleanSubtract( *m_B_Cu_PlatedPads_poly, SHAPE_POLY_SET::PM_FAST ); m_B_Cu_PlatedPads_poly->Simplify( SHAPE_POLY_SET::PM_FAST ); } @@ -822,23 +830,25 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) size_t parallelThreadCount = std::min( std::max( std::thread::hardware_concurrency(), 2 ), selected_layer_id.size() ); + for( size_t ii = 0; ii < parallelThreadCount; ++ii ) { - std::thread t = std::thread( [&nextItem, &threadsFinished, &selected_layer_id, this]() - { - for( size_t i = nextItem.fetch_add( 1 ); - i < selected_layer_id.size(); - i = nextItem.fetch_add( 1 ) ) - { - auto layerPoly = m_layers_poly.find( selected_layer_id[i] ); + std::thread t = std::thread( + [&nextItem, &threadsFinished, &selected_layer_id, this]() + { + for( size_t i = nextItem.fetch_add( 1 ); + i < selected_layer_id.size(); + i = nextItem.fetch_add( 1 ) ) + { + auto layerPoly = m_layers_poly.find( selected_layer_id[i] ); - if( layerPoly != m_layers_poly.end() ) - // This will make a union of all added contours - layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST ); - } + if( layerPoly != m_layers_poly.end() ) + // This will make a union of all added contours + layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST ); + } - threadsFinished++; - } ); + threadsFinished++; + } ); t.detach(); } @@ -927,27 +937,21 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) switch( item->Type() ) { case PCB_SHAPE_T: - AddShapeWithClearanceToContainer( (PCB_SHAPE*) item, - layerContainer, - curr_layer_id, - 0 ); + AddShapeWithClearanceToContainer( static_cast( item ), layerContainer, + curr_layer_id, 0 ); break; case PCB_TEXT_T: - AddShapeWithClearanceToContainer( (PCB_TEXT*) item, - layerContainer, - curr_layer_id, - 0 ); + AddShapeWithClearanceToContainer( static_cast( item ), layerContainer, + curr_layer_id, 0 ); break; case PCB_DIM_ALIGNED_T: case PCB_DIM_CENTER_T: case PCB_DIM_ORTHOGONAL_T: case PCB_DIM_LEADER_T: - AddShapeWithClearanceToContainer( (DIMENSION_BASE*) item, - layerContainer, - curr_layer_id, - 0 ); + AddShapeWithClearanceToContainer( static_cast( item ), + layerContainer, curr_layer_id, 0 ); break; default: @@ -965,11 +969,19 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) switch( item->Type() ) { case PCB_SHAPE_T: - case PCB_TEXT_T: item->TransformShapeWithClearanceToPolygon( *layerPoly, curr_layer_id, 0, ARC_HIGH_DEF, ERROR_INSIDE ); break; + case PCB_TEXT_T: + { + PCB_TEXT* text = static_cast( item ); + + text->TransformTextShapeWithClearanceToPolygon( *layerPoly, curr_layer_id, 0, + ARC_HIGH_DEF, ERROR_INSIDE ); + } + break; + default: break; } diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index cac4866240..0ad73060d3 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -67,7 +67,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_ int maxError = GetDesignSettings().m_MaxError; // convert tracks and vias: - for( auto track : m_tracks ) + for( TRACK* track : m_tracks ) { if( !track->IsOnLayer( aLayer ) ) continue; @@ -76,7 +76,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_ ERROR_INSIDE ); } - // convert pads + // convert pads and other copper items in footprints for( FOOTPRINT* footprint : m_footprints ) { footprint->TransformPadsWithClearanceToPolygon( aOutlines, aLayer, 0, maxError, @@ -84,7 +84,15 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_ // Micro-wave footprints may have items on copper layers footprint->TransformFPShapesWithClearanceToPolygon( aOutlines, aLayer, 0, maxError, - ERROR_INSIDE ); + ERROR_INSIDE, + true, /* include text */ + true /* include shapes */ ); + + for( ZONE* zone : footprint->Zones() ) + { + if( zone->GetLayerSet().test( aLayer ) ) + zone->TransformSolidAreasShapesToPolygon( aLayer, aOutlines ); + } } // convert copper zones @@ -113,8 +121,8 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_ case PCB_TEXT_T: { PCB_TEXT* text = static_cast( item ); - text->TransformShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError, - ERROR_INSIDE ); + text->TransformTextShapeWithClearanceToPolygon( aOutlines, aLayer, 0, maxError, + ERROR_INSIDE ); } break; @@ -270,10 +278,16 @@ void FOOTPRINT::TransformFPShapesWithClearanceToPolygon( SHAPE_POLY_SET& aCorner } +/** + * Function TransformTextShapeWithClearanceToPolygon + * Convert the text to a polygonSet describing the actual character strokes (one per segment). + * @aCornerBuffer = SHAPE_POLY_SET to store the polygon corners + * @aClearanceValue = the clearance around the text + * @aError = the maximum error to allow when approximating curves + */ void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, - enum PCB_LAYER_ID aLayer, - int aClearance, int aError, - ERROR_LOC aErrorLoc ) const + PCB_LAYER_ID aLayer, int aClearance, + int aError, ERROR_LOC aErrorLoc ) const { bool forceBold = true; int penWidth = 0; // force max width for bold text @@ -291,6 +305,15 @@ void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB } +void FP_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, + PCB_LAYER_ID aLayer, int aClearance, + int aError, ERROR_LOC aErrorLoc, + bool aIgnoreLineWidth ) const +{ + EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance ); +} + + void ZONE::TransformSolidAreasShapesToPolygon( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aCornerBuffer, int aError ) const { @@ -354,16 +377,15 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( SHAPE_POLY_SET* aCorn /** - * Function TransformShapeWithClearanceToPolygon - * Convert the text shape to a set of polygons (one per segment). + * Function TransformTextShapeWithClearanceToPolygon + * Convert the text to a polygonSet describing the actual character strokes (one per segment). * @aCornerBuffer = SHAPE_POLY_SET to store the polygon corners * @aClearanceValue = the clearance around the text * @aError = the maximum error to allow when approximating curves */ -void PCB_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, +void PCB_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, - int aError, ERROR_LOC aErrorLoc, - bool aIgnoreLineWidth ) const + int aError, ERROR_LOC aErrorLoc ) const { wxSize size = GetTextSize(); @@ -401,6 +423,15 @@ void PCB_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuff } +void PCB_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, + PCB_LAYER_ID aLayer, int aClearance, + int aError, ERROR_LOC aErrorLoc, + bool aIgnoreLineWidth ) const +{ + EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &aCornerBuffer, aClearance ); +} + + void PCB_SHAPE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 225f74306e..21f60d98bd 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -34,12 +34,13 @@ #include #include #include +#include #include #include #include #include #include - +#include FOOTPRINT::FOOTPRINT( BOARD* parent ) : BOARD_ITEM_CONTAINER((BOARD_ITEM*) parent, PCB_FOOTPRINT_T ), @@ -675,51 +676,51 @@ const EDA_RECT FOOTPRINT::GetBoundingBox( bool aIncludeInvisibleText ) const } -/** - * This is a bit hacky right now for performance reasons. - * - * We assume that most footprints will have features aligned to the axes in - * the zero-rotation state. Therefore, if the footprint is rotated, we - * temporarily rotate back to zero, get the bounding box (excluding reference - * and value text) and then rotate the resulting poly back to the correct - * orientation. - * - * This is more accurate than using the AABB when most footprints are rotated - * off of the axes, but less accurate than computing some kind of bounding hull. - * We should consider doing that instead at some point in the future if we can - * use a performant algorithm and cache the result to avoid extra computing. - */ -SHAPE_POLY_SET FOOTPRINT::GetBoundingPoly() const +SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const { - SHAPE_POLY_SET poly; - double orientation = GetOrientationRadians(); - FOOTPRINT temp = *this; + SHAPE_POLY_SET rawPolys; - temp.SetOrientation( 0.0 ); - BOX2I area = temp.GetFootprintRect(); - - poly.NewOutline(); - - VECTOR2I p = area.GetPosition(); - poly.Append( p ); - p.x = area.GetRight(); - poly.Append( p ); - p.y = area.GetBottom(); - poly.Append( p ); - p.x = area.GetX(); - poly.Append( p ); - - BOARD* board = GetBoard(); - if( board ) + for( BOARD_ITEM* item : m_drawings ) { - int biggest_clearance = board->GetDesignSettings().GetBiggestClearanceValue(); - poly.Inflate( biggest_clearance, 4 ); + if( item->Type() == PCB_FP_SHAPE_T ) + { + item->TransformShapeWithClearanceToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF, + ERROR_OUTSIDE ); + } + + // We intentionally exclude footprint text from the bounding hull. } - poly.Inflate( Millimeter2iu( 0.01 ), 4 ); - poly.Rotate( -orientation, m_pos ); + for( PAD* pad : m_pads ) + { + pad->TransformShapeWithClearanceToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF, + ERROR_OUTSIDE ); + } - return poly; + for( FP_ZONE* zone : m_fp_zones ) + { + for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) + { + SHAPE_POLY_SET layerPoly = zone->GetFilledPolysList( layer ); + + for( int ii = 0; ii < layerPoly.OutlineCount(); ii++ ) + { + const SHAPE_LINE_CHAIN& poly = layerPoly.COutline( ii ); + rawPolys.AddOutline( poly ); + } + } + } + + std::vector convex_hull; + BuildConvexHull( convex_hull, rawPolys ); + + SHAPE_POLY_SET hullPoly; + hullPoly.NewOutline(); + + for( const wxPoint& pt : convex_hull ) + hullPoly.Append( pt ); + + return hullPoly; } @@ -823,7 +824,7 @@ bool FOOTPRINT::HitTest( const wxPoint& aPosition, int aAccuracy ) const bool FOOTPRINT::HitTestAccurate( const wxPoint& aPosition, int aAccuracy ) const { - return GetBoundingPoly().Collide( aPosition, aAccuracy ); + return GetBoundingHull().Collide( aPosition, aAccuracy ); } @@ -1633,11 +1634,19 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC int textMargin = KiROUND( 5 * aCollector.GetGuide()->OnePixelInIU() ); SHAPE_POLY_SET poly; - if( aItem->Type() == PCB_FOOTPRINT_T ) + if( aItem->Type() == PCB_MARKER_T ) + { + const PCB_MARKER* marker = static_cast( aItem ); + SHAPE_LINE_CHAIN markerShape; + + marker->ShapeToPolygon( markerShape ); + return markerShape.Area(); + } + else if( aItem->Type() == PCB_FOOTPRINT_T ) { const FOOTPRINT* footprint = static_cast( aItem ); - return footprint->GetFootprintRect().GetArea(); + poly = footprint->GetBoundingHull(); } else if( aItem->Type() == PCB_FP_TEXT_T ) { @@ -1662,7 +1671,7 @@ double FOOTPRINT::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const { int textMargin = KiROUND( 5 * aCollector.GetGuide()->OnePixelInIU() ); - SHAPE_POLY_SET footprintRegion( GetBoundingPoly() ); + SHAPE_POLY_SET footprintRegion( GetBoundingHull() ); SHAPE_POLY_SET coveredRegion; TransformPadsWithClearanceToPolygon( coveredRegion, UNDEFINED_LAYER, 0, ARC_LOW_DEF, @@ -1683,7 +1692,7 @@ double FOOTPRINT::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const case PCB_FP_SHAPE_T: if( item->GetParent() != this ) { - item->TransformShapeWithClearanceToPolygon( coveredRegion, UNDEFINED_LAYER, 1, + item->TransformShapeWithClearanceToPolygon( coveredRegion, UNDEFINED_LAYER, 0, ARC_LOW_DEF, ERROR_OUTSIDE ); } break; @@ -1693,10 +1702,18 @@ double FOOTPRINT::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const case PCB_TRACE_T: case PCB_ARC_T: case PCB_VIA_T: - item->TransformShapeWithClearanceToPolygon( coveredRegion, UNDEFINED_LAYER, 1, + item->TransformShapeWithClearanceToPolygon( coveredRegion, UNDEFINED_LAYER, 0, ARC_LOW_DEF, ERROR_OUTSIDE ); break; + case PCB_FOOTPRINT_T: + if( item != this ) + { + const FOOTPRINT* footprint = static_cast( item ); + coveredRegion.AddOutline( footprint->GetBoundingHull().Outline( 0 ) ); + } + break; + default: break; } diff --git a/pcbnew/footprint.h b/pcbnew/footprint.h index f63aac7f05..6b66cf2a95 100644 --- a/pcbnew/footprint.h +++ b/pcbnew/footprint.h @@ -173,7 +173,7 @@ public: * Returns a bounding polygon for the shapes and pads in the footprint * This operation is slower but more accurate than calculating a bounding box */ - SHAPE_POLY_SET GetBoundingPoly() const; + SHAPE_POLY_SET GetBoundingHull() const; // Virtual function const EDA_RECT GetBoundingBox() const override; diff --git a/pcbnew/fp_text.h b/pcbnew/fp_text.h index 47e2c021e2..35781d9cba 100644 --- a/pcbnew/fp_text.h +++ b/pcbnew/fp_text.h @@ -198,6 +198,10 @@ public: return TextHitTest( aRect, aContained, aAccuracy ); } + void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, + int aClearance, int aError, ERROR_LOC aErrorLoc, + bool aIgnoreLineWidth ) const override; + void TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc ) const; diff --git a/pcbnew/pcb_text.h b/pcbnew/pcb_text.h index dbcb7e45df..b284b93856 100644 --- a/pcbnew/pcb_text.h +++ b/pcbnew/pcb_text.h @@ -111,14 +111,18 @@ public: } /** - * Function TransformShapeWithClearanceToPolygon - * Convert the text shape to a set of polygons (one by segment) + * Function TransformTextShapeWithClearanceToPolygon + * Convert the text to a polygonSet describing the actual character strokes (one per segment). * Used in 3D viewer * Circles and arcs are approximated by segments - * @param aCornerBuffer = a buffer to store the polygon - * @param aClearanceValue = the clearance around the text - * @param aError = deviation from true arc position to segment approx + * @aCornerBuffer = SHAPE_POLY_SET to store the polygon corners + * @aClearanceValue = the clearance around the text + * @aError = the maximum error to allow when approximating curves */ + void TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, + PCB_LAYER_ID aLayer, int aClearanceValue, + int aError, ERROR_LOC aErrorLoc ) const; + void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, PCB_LAYER_ID aLayer, int aClearanceValue, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth = false ) const override; diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index c297bd798c..13a5941c65 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -623,17 +623,17 @@ void PAD_TOOL::recombinePad( PAD* aPad ) for( BOARD_ITEM* item : board()->GetFirstFootprint()->GraphicalItems() ) { - PCB_SHAPE* draw = dynamic_cast( item ); + PCB_SHAPE* shape = dynamic_cast( item ); - if( !draw || ( draw->GetEditFlags() & STRUCT_DELETED ) ) + if( !shape || ( shape->GetEditFlags() & STRUCT_DELETED ) ) continue; - if( draw->GetLayer() != aLayer ) + if( shape->GetLayer() != aLayer ) continue; SHAPE_POLY_SET drawPoly; - draw->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError, - ERROR_INSIDE ); + shape->TransformShapeWithClearanceToPolygon( drawPoly, aLayer, 0, maxError, + ERROR_INSIDE ); drawPoly.BooleanIntersection( padPoly, SHAPE_POLY_SET::PM_FAST ); if( !drawPoly.IsEmpty() ) diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 3232847e07..f97b34cda2 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -34,6 +34,7 @@ using namespace std::placeholders; #include #include #include +#include #include #include #include @@ -2265,7 +2266,7 @@ void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector, { FOOTPRINT* footprint = static_cast( item ); - footprint->GetBoundingPoly().Collide( loc, maxSlop * pixel, &actualSlop ); + footprint->GetBoundingHull().Collide( loc, maxSlop * pixel, &actualSlop ); // Consider footprints larger than the viewport only as a last resort if( item->ViewBBox().GetHeight() > viewport.GetHeight() @@ -2276,6 +2277,17 @@ void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector, } break; + case PCB_MARKER_T: + { + PCB_MARKER* marker = static_cast( item ); + SHAPE_LINE_CHAIN polygon; + + marker->ShapeToPolygon( polygon ); + polygon.Move( marker->GetPos() ); + polygon.Collide( loc, maxSlop * pixel, &actualSlop ); + } + break; + default: item->GetEffectiveShape()->Collide( loc, maxSlop * pixel, &actualSlop ); break; diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 2cd22bd29f..ac03ae029e 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -572,34 +572,24 @@ void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap, switch( aItem->Type() ) { case PCB_SHAPE_T: - { - PCB_SHAPE* shape = (PCB_SHAPE*) aItem; - shape->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, - ERROR_OUTSIDE, aIgnoreLineWidth ); - break; - } case PCB_TEXT_T: - { - PCB_TEXT* text = (PCB_TEXT*) aItem; - text->TransformBoundingBoxWithClearanceToPolygon( &aHoles, aGap ); - break; - } case PCB_FP_SHAPE_T: - { - FP_SHAPE* shape = (FP_SHAPE*) aItem; - shape->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, + aItem->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, ERROR_OUTSIDE, aIgnoreLineWidth ); break; - } + case PCB_FP_TEXT_T: { - FP_TEXT* text = (FP_TEXT*) aItem; + FP_TEXT* text = static_cast( aItem ); if( text->IsVisible() ) - text->TransformBoundingBoxWithClearanceToPolygon( &aHoles, aGap ); - - break; + { + text->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError, + ERROR_OUTSIDE, aIgnoreLineWidth ); + } } + break; + default: break; } diff --git a/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.cpp b/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.cpp index 109c097aee..790758e383 100644 --- a/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.cpp +++ b/qa/pcbnew_tools/tools/polygon_generator/polygon_generator.cpp @@ -61,9 +61,7 @@ enum POLY_GEN_RET_CODES int polygon_gererator_main( int argc, char* argv[] ) { if( argc < 2 ) - { return KI_TEST::RET_CODES::BAD_CMDLINE; - } std::string filename; @@ -73,22 +71,20 @@ int polygon_gererator_main( int argc, char* argv[] ) auto brd = KI_TEST::ReadBoardFromFileOrStream( filename ); if( !brd ) - { return POLY_GEN_RET_CODES::LOAD_FAILED; - } for( unsigned net = 0; net < brd->GetNetCount(); net++ ) { - for( auto track : brd->Tracks() ) + for( TRACK* track : brd->Tracks() ) process( track, net ); - for( auto mod : brd->Footprints() ) + for( FOOTPRINT* fp : brd->Footprints() ) { - for( auto pad : mod->Pads() ) + for( PAD* pad : fp->Pads() ) process( pad, net ); } - for( auto zone : brd->Zones() ) + for( ZONE* zone : brd->Zones() ) process( zone, net ); }