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
This commit is contained in:
parent
37178e3751
commit
889408c96a
|
@ -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,
|
||||
|
|
|
@ -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<PCB_TEXT*>( 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<size_t>(
|
||||
std::max<size_t>( 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<PCB_SHAPE*>( item ), layerContainer,
|
||||
curr_layer_id, 0 );
|
||||
break;
|
||||
|
||||
case PCB_TEXT_T:
|
||||
AddShapeWithClearanceToContainer( (PCB_TEXT*) item,
|
||||
layerContainer,
|
||||
curr_layer_id,
|
||||
0 );
|
||||
AddShapeWithClearanceToContainer( static_cast<PCB_TEXT*>( 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<DIMENSION_BASE*>( 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<PCB_TEXT*>( item );
|
||||
|
||||
text->TransformTextShapeWithClearanceToPolygon( *layerPoly, curr_layer_id, 0,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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<PCB_TEXT*>( 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,
|
||||
|
|
|
@ -34,12 +34,13 @@
|
|||
#include <board.h>
|
||||
#include <fp_shape.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_marker.h>
|
||||
#include <footprint.h>
|
||||
#include <view/view.h>
|
||||
#include <geometry/shape_null.h>
|
||||
#include <i18n_utility.h>
|
||||
#include <convert_drawsegment_list_to_polygon.h>
|
||||
|
||||
#include <geometry/convex_hull.h>
|
||||
|
||||
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<wxPoint> 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<const PCB_MARKER*>( aItem );
|
||||
SHAPE_LINE_CHAIN markerShape;
|
||||
|
||||
marker->ShapeToPolygon( markerShape );
|
||||
return markerShape.Area();
|
||||
}
|
||||
else if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
const FOOTPRINT* footprint = static_cast<const FOOTPRINT*>( 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<const FOOTPRINT*>( item );
|
||||
coveredRegion.AddOutline( footprint->GetBoundingHull().Outline( 0 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -623,17 +623,17 @@ void PAD_TOOL::recombinePad( PAD* aPad )
|
|||
|
||||
for( BOARD_ITEM* item : board()->GetFirstFootprint()->GraphicalItems() )
|
||||
{
|
||||
PCB_SHAPE* draw = dynamic_cast<PCB_SHAPE*>( item );
|
||||
PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( 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() )
|
||||
|
|
|
@ -34,6 +34,7 @@ using namespace std::placeholders;
|
|||
#include <footprint.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_marker.h>
|
||||
#include <zone.h>
|
||||
#include <collectors.h>
|
||||
#include <confirm.h>
|
||||
|
@ -2265,7 +2266,7 @@ void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector,
|
|||
{
|
||||
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( 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<PCB_MARKER*>( 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;
|
||||
|
|
|
@ -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<FP_TEXT*>( aItem );
|
||||
|
||||
if( text->IsVisible() )
|
||||
text->TransformBoundingBoxWithClearanceToPolygon( &aHoles, aGap );
|
||||
|
||||
break;
|
||||
{
|
||||
text->TransformShapeWithClearanceToPolygon( aHoles, aLayer, aGap, m_maxError,
|
||||
ERROR_OUTSIDE, aIgnoreLineWidth );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue