Move pad-outline plotting to plot_brditems_plotter.cpp.

This commit is contained in:
Jeff Young 2025-05-10 12:41:20 +01:00
parent c452fe9686
commit c78ce373fd
7 changed files with 92 additions and 50 deletions

View File

@ -732,7 +732,7 @@ void DXF_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
orient += ANGLE_90;
}
sketchOval( aPos, size, orient, USE_DEFAULT_LINE_WIDTH );
ThickOval( aPos, size, orient, USE_DEFAULT_LINE_WIDTH, aData );
}

View File

@ -1198,8 +1198,7 @@ void GERBER_PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, i
}
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
segmentAsOval( start, end, GetCurrentLineWidth(), tracemode );
PLOTTER::ThickSegment( start, end, width, tracemode, aData );
}
}
@ -1383,17 +1382,7 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
}
else // Non filled shape: plot outlines:
{
if( size.x > size.y )
{
std::swap( size.x, size.y );
if( orient < ANGLE_270 )
orient += ANGLE_90;
else
orient -= ANGLE_270;
}
sketchOval( aPos, size, orient, USE_DEFAULT_LINE_WIDTH );
ThickOval( aPos, size, orient, USE_DEFAULT_LINE_WIDTH, aData );
}
}
}

View File

@ -115,7 +115,7 @@ void PSLIKE_PLOTTER::FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSiz
if( aTraceMode == FILLED )
ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr );
else
sketchOval( aPadPos, size, orient, USE_DEFAULT_LINE_WIDTH );
ThickOval( aPadPos, size, orient, USE_DEFAULT_LINE_WIDTH, nullptr );
}

View File

@ -29,7 +29,6 @@
* with different plot formats.
*
* There are currently engines for:
* HPGL
* POSTSCRIPT
* GERBER
* DXF
@ -43,6 +42,7 @@
#include <bezier_curves.h>
#include <callback_gal.h>
#include <math/util.h> // for KiROUND
#include <convert_basic_shapes_to_polygon.h>
PLOTTER::PLOTTER( const PROJECT* aProject ) :
m_project( aProject )
@ -482,25 +482,10 @@ void PLOTTER::Marker( const VECTOR2I& position, int diametre, unsigned aShapeId
}
void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int aWidth,
OUTLINE_MODE aTraceMode )
void PLOTTER::ThickOval( const VECTOR2I& aPos, const VECTOR2I& aSize, const EDA_ANGLE& aOrient,
int aWidth, void* aData )
{
VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 );
VECTOR2I size( end.x - start.x, end.y - start.y );
EDA_ANGLE orient( size );
orient = -orient; // this is due to our Y axis orientation
size.x = size.EuclideanNorm() + aWidth;
size.y = aWidth;
FlashPadOval( center, size, orient, aTraceMode, nullptr );
}
void PLOTTER::sketchOval( const VECTOR2I& aPos, const VECTOR2I& aSize, const EDA_ANGLE& aOrient,
int aWidth )
{
SetCurrentLineWidth( aWidth );
SetCurrentLineWidth( aWidth, aData );
EDA_ANGLE orient( aOrient );
VECTOR2I size( aSize );
@ -568,8 +553,21 @@ void PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int widt
}
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
segmentAsOval( start, end, width, tracemode );
std::vector<VECTOR2I> cornerList;
SHAPE_POLY_SET outlineBuffer;
TransformOvalToPolygon( outlineBuffer, start, end, width, GetPlotterArcHighDef(), ERROR_INSIDE );
const SHAPE_LINE_CHAIN& path = outlineBuffer.COutline( 0 );
cornerList.reserve( path.PointCount() );
for( int jj = 0; jj < path.PointCount(); jj++ )
cornerList.emplace_back( path.CPoint( jj ).x, path.CPoint( jj ).y );
// Ensure the polygon is closed
if( cornerList[0] != cornerList[cornerList.size() - 1] )
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, FILL_T::NO_FILL, USE_DEFAULT_LINE_WIDTH, aData );
}
}
@ -673,6 +671,12 @@ void PLOTTER::FilledCircle( const VECTOR2I& pos, int diametre, OUTLINE_MODE trac
}
void PLOTTER::ThickPoly( const SHAPE_POLY_SET& aPoly, int aWidth, void* aData )
{
PlotPoly( aPoly.COutline( 0 ), FILL_T::NO_FILL, aWidth, aData );
}
void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth, void* aData )
{
std::vector<VECTOR2I> cornerList;

View File

@ -319,6 +319,10 @@ public:
virtual void FilledCircle( const VECTOR2I& pos, int diametre, OUTLINE_MODE tracemode,
void* aData );
virtual void ThickOval( const VECTOR2I& aPos, const VECTOR2I& aSize, const EDA_ANGLE& aOrient,
int aWidth, void* aData );
virtual void ThickPoly( const SHAPE_POLY_SET& aPoly, int aWidth, void* aData );
// Flash primitives

View File

@ -853,6 +853,8 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask
BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
itemplotter.SetLayerSet( aLayerMask );
int smallDrill = pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize );
SHAPE_POLY_SET outlines;
for( PCB_LAYER_ID layer : aLayerMask.Seq( aLayerMask.SeqStackupForPlotting() ) )
@ -874,36 +876,36 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, const LSET& aLayerMask
const SHAPE_LINE_CHAIN& path = ( kk == 0 ) ? outlines.COutline( ii )
: outlines.CHole( ii, kk - 1 );
aPlotter->PlotPoly( path, FILL_T::NO_FILL );
aPlotter->PlotPoly( path, FILL_T::NO_FILL, PLOTTER::USE_DEFAULT_LINE_WIDTH, nullptr );
}
}
// Plot pad holes
if( aPlotOpt.GetDrillMarksType() != DRILL_MARKS::NO_DRILL_SHAPE )
{
int smallDrill = ( aPlotOpt.GetDrillMarksType() == DRILL_MARKS::SMALL_DRILL_SHAPE )
? pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize )
: INT_MAX;
for( FOOTPRINT* footprint : aBoard->Footprints() )
{
for( PAD* pad : footprint->Pads() )
{
if( pad->HasHole() )
{
std::shared_ptr<SHAPE_SEGMENT> slot = pad->GetEffectiveHoleShape();
if( slot->GetSeg().A == slot->GetSeg().B ) // circular hole
if( pad->GetDrillSizeX() == pad->GetDrillSizeY() )
{
int drill = std::min( smallDrill, slot->GetWidth() );
aPlotter->Circle( pad->GetPosition(), drill, FILL_T::NO_FILL,
PLOTTER::USE_DEFAULT_LINE_WIDTH );
int drill = pad->GetDrillSizeX();
if( aPlotOpt.GetDrillMarksType() == DRILL_MARKS::SMALL_DRILL_SHAPE )
drill = std::min( smallDrill, drill );
aPlotter->ThickCircle( pad->ShapePos( layer ), drill,
PLOTTER::USE_DEFAULT_LINE_WIDTH, FILLED, nullptr );
}
else
{
// Note: small drill marks have no significance when applied to slots
aPlotter->ThickSegment( slot->GetSeg().A, slot->GetSeg().B,
slot->GetWidth(), SKETCH, nullptr );
aPlotter->ThickOval( pad->ShapePos( layer ), pad->GetSize( layer ),
pad->GetOrientation(), PLOTTER::USE_DEFAULT_LINE_WIDTH,
nullptr );
}
}
}

View File

@ -277,7 +277,50 @@ void BRDITEMS_PLOTTER::PlotPad( const PAD* aPad, PCB_LAYER_ID aLayer, const COLO
m_plotter->SetColor( aColor != WHITE ? aColor : LIGHTGRAY );
if( aPlotMode == SKETCH )
m_plotter->SetCurrentLineWidth( GetSketchPadLineWidth(), &metadata );
{
switch( aPad->GetShape( aLayer ) )
{
case PAD_SHAPE::CIRCLE:
m_plotter->ThickCircle( shape_pos, aPad->GetSize( aLayer ).x, GetSketchPadLineWidth(),
FILLED, &metadata );
break;
case PAD_SHAPE::OVAL:
{
m_plotter->ThickOval( shape_pos, aPad->GetSize( aLayer ), aPad->GetOrientation(),
GetSketchPadLineWidth(), &metadata );
break;
}
case PAD_SHAPE::RECTANGLE:
{
VECTOR2I size = aPad->GetSize( aLayer );
m_plotter->ThickRect( VECTOR2I( shape_pos.x - ( size.x / 2 ), shape_pos.y - (size.y / 2 ) ),
VECTOR2I( shape_pos.x + ( size.x / 2 ), shape_pos.y + (size.y / 2 ) ),
GetSketchPadLineWidth(), FILLED, &metadata );
break;
}
case PAD_SHAPE::ROUNDRECT:
case PAD_SHAPE::TRAPEZOID:
case PAD_SHAPE::CHAMFERED_RECT:
case PAD_SHAPE::CUSTOM:
{
SHAPE_POLY_SET outline;
aPad->TransformShapeToPolygon( outline, aLayer, 0, m_plotter->GetPlotterArcHighDef(),
ERROR_INSIDE, true );
m_plotter->ThickPoly( outline, GetSketchPadLineWidth(), &metadata );
break;
}
default:
UNIMPLEMENTED_FOR( aPad->ShowPadShape( PADSTACK::ALL_LAYERS ) );
}
return;
}
switch( aPad->GetShape( aLayer ) )
{