Prepare rounded rect and custom shaped pads: add plot functions. It fixes also a pcbnew crash in HPGL mode when plotting trapezoidal pads.

This commit is contained in:
jean-pierre charras 2016-02-10 17:02:40 +01:00
parent a319c34188
commit 5658ed9c8e
11 changed files with 480 additions and 241 deletions

View File

@ -5,7 +5,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -617,6 +617,43 @@ void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
FinishTo( wxPoint( ox, oy ) );
}
void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, segmentToCircleCount );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
for( int ii = 1; ii < poly.PointCount(); ++ii )
LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
FinishTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
}
void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
{
for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
{
SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
for( int ii = 1; ii < poly.PointCount(); ++ii )
LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
FinishTo(wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) );
}
}
/**
* DXF trapezoidal pad: only sketch mode is supported

View File

@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -36,6 +36,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
#include <convert_basic_shapes_to_polygon.h>
#include <build_version.h>
@ -479,8 +480,9 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
if( trace_mode == FILLED )
{
/* XXX to do: use an aperture macro to declare the rotated pad */
/* The pad is reduced to an oval with dy > dx */
// TODO: use an aperture macro to declare the rotated pad
//
// The pad is reduced to an segment with dy > dx
delta = size.y - size.x;
x0 = 0;
y0 = -delta / 2;
@ -559,12 +561,71 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
}
}
void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
{
// Currently, a Pad RoundRect is plotted as polygon.
// TODO: use Aperture macro and flash it
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundRectToPolygon( outline, aPadPos, aSize, aOrient,
aCornerRadius, segmentToCircleCount );
std::vector< wxPoint > cornerList;
cornerList.reserve( segmentToCircleCount + 5 );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL );
}
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
{
// A Pad custom is plotted as polygon.
#if 1
// A flashed circle @aPadPos is added (anchor pad)
// However, because the anchor pad can be circle or rect, we use only
// a circle not bigger tahn the rect.
// the main purpose is to show a flashed DCode as pad anchor
FlashPadCircle( aPadPos, std::min( aSize.x, aSize.x ), aTraceMode );
#endif
std::vector< wxPoint > cornerList;
for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
{
SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
cornerList.clear();
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL );
}
}
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
{
// XXX to do: use an aperture macro to declare the pad
// Currently, a Pad Trapezoid is plotted as polygon.
// TODO: use Aperture macro and flash it
// polygon corners list
std::vector< wxPoint > cornerList;

View File

@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -25,7 +25,6 @@
/**
* @file common_plotHPGL_functions.cpp
* @brief KiCad: Common plot HPGL Routines
* Filled primitive are not supported, but some could be using HPGL/2
* Since this plot engine is mostly intended for import in external programs,
* sadly HPGL/2 isn't supported a lot... some of the primitives use overlapped
* strokes to fill the shape
@ -113,6 +112,12 @@
* but the outputs and feedrates are affected.
* PD {x, y};
*
* PM Polygon mode
* associated commands:
* PM2 End polygon mode
* FP Fill polygon
* EP Draw polygon outline
*
* PR (Plot Relative): Moves to the relative position specified and sets relative mode
* for future PU and PD commands.
* If no arguments follow the command, only relative mode is set.
@ -179,7 +184,7 @@
* VS (Velocity Select):
* VS {v {, n}};
* v [1 .. 40]
* n [1 .. 8, je nach Ausstattung]
* n [1 .. 8]
*
* XT (X Tick):
* XT;
@ -197,6 +202,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
#include <convert_basic_shapes_to_polygon.h>
// HPGL scale factor (1 PLU = 1/40mm = 25 micrometers)
static const double PLUsPERDECIMIL = 0.102041;
@ -223,8 +229,6 @@ void HPGL_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
paperSize.y *= 10.0 * aIusPerDecimil;
SetDefaultLineWidth( 0 ); // HPGL has pen sizes instead
m_plotMirror = aMirror;
penOverlap = 0;
penDiameter = 0;
}
@ -284,8 +288,9 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill,
/**
* HPGL polygon: fill not supported (but closed, at least)
* HPGL polygon:
*/
void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
FILL_T aFill, int aWidth )
{
@ -293,19 +298,38 @@ void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
return;
SetCurrentLineWidth( aWidth );
MoveTo( aCornerList[0] );
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
LineTo( aCornerList[ii] );
// Close polygon if filled.
if( aFill )
if( aFill == FILLED_SHAPE )
{
// Draw the filled area
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
fprintf( outputFile, "PM 0;\n" ); // Start polygon
for( unsigned ii = 1; ii < aCornerList.size(); ++ii )
LineTo( aCornerList[ii] );
int ii = aCornerList.size() - 1;
if( aCornerList[ii] != aCornerList[0] )
LineTo( aCornerList[0] );
fprintf( outputFile, "PM 2; FP; EP;\n" ); // Close, fill polygon and draw outlines
}
else
{
// Plot only the polygon outline.
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
LineTo( aCornerList[ii] );
// Always close polygon if filled.
if( aFill )
{
int ii = aCornerList.size() - 1;
if( aCornerList[ii] != aCornerList[0] )
LineTo( aCornerList[0] );
}
}
PenFinish();
@ -455,7 +479,7 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
int deltaxy, cx, cy;
wxSize size( aSize );
/* The pad is reduced to an oval with size.y > size.x
/* The pad will be drawn as an oblong shape with size.y > size.x
* (Oval vertical orientation 0)
*/
if( size.x > size.y )
@ -477,7 +501,7 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
RotatePoint( &cx, &cy, orient );
FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode );
}
else // Plot in SKETCH mode.
else // Plot in outline mode.
{
sketchOval( pos, size, orient, KiROUND( penDiameter ) );
}
@ -492,28 +516,34 @@ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
wxASSERT( outputFile );
DPOINT pos_dev = userToDeviceCoordinates( pos );
int delta = KiROUND( penDiameter - penOverlap );
int radius = ( diametre - KiROUND( penDiameter ) ) / 2;
int radius = diametre / 2;
if( trace_mode == FILLED )
{
// if filled mode, the pen diameter is removed from diameter
// to keep the pad size
radius -= KiROUND( penDiameter ) / 2;
}
if( radius < 0 )
radius = 0;
double rsize = userToDeviceSize( radius );
fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n",
pos_dev.x, pos_dev.y, rsize );
if( trace_mode == FILLED ) // Plot in filled mode.
{
if( delta > 0 )
{
while( (radius -= delta ) >= 0 )
{
rsize = userToDeviceSize( radius );
fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n",
// A filled polygon uses always the current point to start the polygon.
// Gives a correct current starting point for the circle
MoveTo( wxPoint( pos.x+radius, pos.y ) );
// Plot filled area and its outline
fprintf( outputFile, "PM 0; PA %.0f,%.0f;CI %.0f; PM 2; FP; EP;\n",
pos_dev.x, pos_dev.y, rsize );
}
}
}
else
{
// Draw outline only:
fprintf( outputFile, "PA %.0f,%.0f;CI %.0f;\n",
pos_dev.x, pos_dev.y, rsize );
}
PenFinish();
@ -523,113 +553,92 @@ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
double orient, EDA_DRAW_MODE_T trace_mode )
{
wxASSERT( outputFile );
wxSize size;
int delta;
int ox, oy, fx, fy;
// Build rect polygon:
std::vector<wxPoint> corners;
size.x = padsize.x / 2;
size.y = padsize.y / 2;
size.x = (padsize.x - (int) penDiameter) / 2;
size.y = (padsize.y - (int) penDiameter) / 2;
if( size.x < 0 )
size.x = 0;
if( size.y < 0 )
size.y = 0;
// If a dimension is zero, the trace is reduced to 1 line.
if( size.x == 0 )
{
ox = pos.x;
oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
fx = pos.x;
fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
MoveTo( wxPoint( ox, oy ) );
FinishTo( wxPoint( fx, fy ) );
return;
}
if( size.y == 0 )
{
ox = pos.x - size.x;
oy = pos.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
fx = pos.x + size.x;
fy = pos.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
MoveTo( wxPoint( ox, oy ) );
FinishTo( wxPoint( fx, fy ) );
return;
}
ox = pos.x - size.x;
oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
MoveTo( wxPoint( ox, oy ) );
fx = pos.x - size.x;
fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
fx = pos.x + size.x;
fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
fx = pos.x + size.x;
fy = pos.y - size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
FinishTo( wxPoint( ox, oy ) );
int dx = padsize.x / 2;
int dy = padsize.y / 2;
if( trace_mode == FILLED )
{
// Plot in filled mode.
delta = (int) (penDiameter - penOverlap);
if( delta > 0 )
while( (size.x > 0) && (size.y > 0) )
{
size.x -= delta;
size.y -= delta;
if( size.x < 0 )
size.x = 0;
if( size.y < 0 )
size.y = 0;
ox = pos.x - size.x;
oy = pos.y - size.y;
RotatePoint( &ox, &oy, pos.x, pos.y, orient );
MoveTo( wxPoint( ox, oy ) );
fx = pos.x - size.x;
fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
fx = pos.x + size.x;
fy = pos.y + size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
fx = pos.x + size.x;
fy = pos.y - size.y;
RotatePoint( &fx, &fy, pos.x, pos.y, orient );
LineTo( wxPoint( fx, fy ) );
FinishTo( wxPoint( ox, oy ) );
}
// in filled mode, the pen diameter is removed from size
// to compensate the extra size due to this pen size
dx -= KiROUND( penDiameter ) / 2;
dx = std::max( dx, 0);
dy -= KiROUND( penDiameter ) / 2;
dy = std::max( dy, 0);
}
corners.push_back( wxPoint( - dx, - dy ) );
corners.push_back( wxPoint( - dx, + dy ) );
corners.push_back( wxPoint( + dx, + dy ) );
corners.push_back( wxPoint( + dx, - dy ) );
for( unsigned ii = 0; ii < corners.size(); ii++ )
{
RotatePoint( &corners[ii], orient );
corners[ii] += pos;
}
PlotPoly( corners, trace_mode == FILLED ? FILLED_SHAPE : NO_FILL );
}
void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 32;
wxSize size = aSize;
if( aTraceMode == FILLED )
{
// in filled mode, the pen diameter is removed from size
// to keep the pad size
size.x -= KiROUND( penDiameter ) / 2;
size.x = std::max( size.x, 0);
size.y -= KiROUND( penDiameter ) / 2;
size.y = std::max( size.y, 0);
// keep aCornerRadius to a value < min size x,y < 2:
aCornerRadius = std::min( aCornerRadius, std::min( size.x, size.y ) /2 );
}
TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, segmentToCircleCount );
// TransformRoundRectToPolygon creates only one convex polygon
std::vector< wxPoint > cornerList;
cornerList.reserve( segmentToCircleCount + 4 );
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL );
}
void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
{
std::vector< wxPoint > cornerList;
for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
{
SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
cornerList.clear();
cornerList.reserve( poly.PointCount() );
for( int ii = 1; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL );
}
}
@ -637,105 +646,16 @@ void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
{
wxASSERT( outputFile );
wxPoint polygone[4]; // coordinates of corners relatives to the pad
wxPoint coord[4]; // absolute coordinates of corners (coordinates in plotter space)
int move;
move = KiROUND( penDiameter );
std::vector< wxPoint > cornerList;
cornerList.reserve( 4 );
for( int ii = 0; ii < 4; ii++ )
polygone[ii] = aCorners[ii];
// polygone[0] is assumed the lower left
// polygone[1] is assumed the upper left
// polygone[2] is assumed the upper right
// polygone[3] is assumed the lower right
// Plot the outline:
for( int ii = 0; ii < 4; ii++ )
{
coord[ii] = polygone[ii];
RotatePoint( &coord[ii], aPadOrient );
coord[ii] += aPadPos;
wxPoint coord( aCorners[ii] );
RotatePoint( &coord, aPadOrient );
coord += aPadPos;
cornerList.push_back( coord );
}
MoveTo( coord[0] );
LineTo( coord[1] );
LineTo( coord[2] );
LineTo( coord[3] );
FinishTo( coord[0] );
// Fill shape:
if( aTrace_Mode == FILLED )
{
// TODO: replace this par the HPGL plot polygon.
int jj;
// Fill the shape
move = KiROUND( penDiameter - penOverlap );
// Calculate fill height.
if( polygone[0].y == polygone[3].y ) // Horizontal
{
jj = polygone[3].y - (int) ( penDiameter + ( 2 * penOverlap ) );
}
else // vertical
{
jj = polygone[3].x - (int) ( penDiameter + ( 2 * penOverlap ) );
}
// Calculation of dd = number of segments was traced to fill.
jj = jj / (int) ( penDiameter - penOverlap );
// Trace the outline.
for( ; jj > 0; jj-- )
{
polygone[0].x += move;
polygone[0].y -= move;
polygone[1].x += move;
polygone[1].y += move;
polygone[2].x -= move;
polygone[2].y += move;
polygone[3].x -= move;
polygone[3].y -= move;
// Test for crossed vertexes.
if( polygone[0].x > polygone[3].x ) /* X axis intersection on
* vertexes 0 and 3 */
{
polygone[0].x = polygone[3].x = 0;
}
if( polygone[1].x > polygone[2].x ) /* X axis intersection on
* vertexes 1 and 2 */
{
polygone[1].x = polygone[2].x = 0;
}
if( polygone[1].y > polygone[0].y ) /* Y axis intersection on
* vertexes 0 and 1 */
{
polygone[0].y = polygone[1].y = 0;
}
if( polygone[2].y > polygone[3].y ) /* Y axis intersection on
* vertexes 2 and 3 */
{
polygone[2].y = polygone[3].y = 0;
}
for( int ii = 0; ii < 4; ii++ )
{
coord[ii] = polygone[ii];
RotatePoint( &coord[ii], aPadOrient );
coord[ii] += aPadPos;
}
MoveTo( coord[0] );
LineTo( coord[1] );
LineTo( coord[2] );
LineTo( coord[3] );
FinishTo( coord[0] );
}
}
PlotPoly( cornerList, aTrace_Mode == FILLED ? FILLED_SHAPE : NO_FILL );
}

View File

@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -35,6 +35,7 @@
#include <plot_common.h>
#include <macros.h>
#include <kicad_string.h>
#include <convert_basic_shapes_to_polygon.h>
/* Forward declaration of the font width metrics
(yes extern! this is the way to forward declare variables */
@ -188,6 +189,76 @@ void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
GetCurrentLineWidth() );
}
void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
{
wxSize size( aSize );
if( aTraceMode == FILLED )
SetCurrentLineWidth( 0 );
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
size.x -= GetCurrentLineWidth();
size.y -= GetCurrentLineWidth();
aCornerRadius -= GetCurrentLineWidth()/2;
}
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
TransformRoundRectToPolygon( outline, aPadPos, size, aOrient,
aCornerRadius, segmentToCircleCount );
std::vector< wxPoint > cornerList;
cornerList.reserve( segmentToCircleCount + 5 );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
GetCurrentLineWidth() );
}
void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
{
wxSize size( aSize );
if( aTraceMode == FILLED )
SetCurrentLineWidth( 0 );
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
size.x -= GetCurrentLineWidth();
size.y -= GetCurrentLineWidth();
}
std::vector< wxPoint > cornerList;
for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
{
SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
cornerList.clear();
for( int ii = 0; ii < poly.PointCount(); ++ii )
cornerList.push_back( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) );
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL,
GetCurrentLineWidth() );
}
}
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode )

View File

@ -64,6 +64,71 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
}
/* Returns the centers of the rounded corners of a rect.
*/
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
const wxPoint& aPosition, const wxSize& aSize, double aRotation )
{
wxSize size( aSize/2 );
size.x -= aRadius;
size.y -= aRadius;
aCenters[0].x = -size.x;
aCenters[0].y = size.y;
aCenters[1].x = size.x;
aCenters[1].y = size.y;
aCenters[2].x = size.x;
aCenters[2].y = -size.y;
aCenters[3].x = -size.x;
aCenters[3].y = -size.y;
// Rotate the polygon
if( aRotation )
{
for( int ii = 0; ii < 4; ii++ )
RotatePoint( &aCenters[ii], aRotation );
}
// move the polygon to the position
for( int ii = 0; ii < 4; ii++ )
aCenters[ii] += aPosition;
}
/**
* Function TransformRoundRectToPolygon
* convert a rectangle with rounded corners to a polygon
* Convert arcs to multiple straight lines
* @param aCornerBuffer = a buffer to store the polygon
* @param aPosition = the coordinate of the center of the rectangle
* @param aSize = the size of the rectangle
* @param aRadius = radius of rounded corners
* @param aRotation = rotation in 0.1 degrees of the rectangle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
*/
void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
int aCircleToSegmentsCount )
{
wxPoint corners[4];
GetRoundRectCornerCenters( corners, aCornerRadius, aPosition, aSize, aRotation );
SHAPE_POLY_SET outline;
outline.NewOutline();
for( int ii = 0; ii < 4; ++ii )
outline.Append( corners[ii].x, corners[ii].y );
outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
// Add the outline:
aCornerBuffer.Append( outline );
}
/**
* Function TransformRoundedEndsSegmentToPolygon

View File

@ -50,6 +50,34 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint aCenter, int aRadius,
int aCircleToSegmentsCount );
/**
* Helper function GetRoundRectCornerCenters
* Has meaning only for rounded rect
* Returns the centers of the rounded corners.
* @param aPosition = position of the round rect
* @param aSize = size of the of the round rect.
* @param aRotation = rotation of the of the round rect
* @param aCenters a buffer to store the 4 coordinates.
*/
void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
const wxPoint& aPosition, const wxSize& aSize, double aRotation );
/**
* Function TransformRoundRectToPolygon
* convert a rectangle with rounded corners to a polygon
* Convert arcs to multiple straight lines
* @param aCornerBuffer = a buffer to store the polygon
* @param aPosition = the coordinate of the center of the rectangle
* @param aSize = the size of the rectangle
* @param aCornerRadius = radius of rounded corners
* @param aRotation = rotation in 0.1 degrees of the rectangle
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
*/
void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
const wxPoint& aPosition, const wxSize& aSize,
double aRotation, int aCornerRadius,
int aCircleToSegmentsCount );
/**
* Function TransformRoundedEndsSegmentToPolygon
* convert a segment with rounded ends to a polygon

View File

@ -38,6 +38,8 @@
#include <class_page_info.h>
#include <eda_text.h> // FILL_T
class SHAPE_POLY_SET;
/**
* Enum PlotFormat
* is the set of supported output plot formats. They should be kept in order
@ -280,6 +282,29 @@ public:
virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode ) = 0;
/**
* virtual function FlashPadRoundRect
* @param aPadPos Position of the shape (center of the rectangle
* @param aSize = size of rounded rect
* @param cornerRadius Radius of the rounded corners
* @param aOrient The rotation of the shape
* @param aTraceMode FILLED or SKETCH
*/
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode ) = 0;
/**
* virtual function FlashPadCustom
* @param aPadPos Position of the shape (center of the rectangle
* @param aSize = size of round reference pad
* @param aPolygons the shape as polygon set
* @param aTraceMode FILLED or SKETCH
*/
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode ) = 0;
/** virtual function FlashPadTrapez
* flash a trapezoidal pad
* @param aPadPos = the position of the shape
@ -534,6 +559,12 @@ public:
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@ -586,6 +617,12 @@ public:
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@ -942,14 +979,28 @@ public:
EDA_DRAW_MODE_T trace_mode );
/**
* Filled rect flashes are handled as aperture in the 90 degree positions only
* Filled rect flashes are handled as aperture in the 0 90 180 or 270 degree orientation only
* and as polygon for other orientations
* TODO: always use flashed shapes (aperture macros)
*/
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
/**
* Roundrect pad at the moment are not handled as aperture, since
* they require aperture macros
* TODO: always use flashed shapes (aperture macros)
*/
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
/**
* Trapezoidal pad at the moment are *never* handled as aperture, since
* they require aperture macros
* TODO: always use flashed shapes (aperture macros)
*/
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
@ -1069,6 +1120,12 @@ public:
EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );

View File

@ -136,8 +136,6 @@ public:
void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
#endif
//protected: @todo: is it just me?
wxPoint m_Start0; // Start point or center, relative to module origin, orient 0.
wxPoint m_End0; // End point, relative to module origin, orient 0.
};

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 8 2012)
// C++ code generated with wxFormBuilder (version Jan 1 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -198,7 +198,7 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxEXPAND, 5 );
bSizerMain->Add( m_sdbSizer, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
this->SetSizer( bSizerMain );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="11" />
<FileVersion major="1" minor="13" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -20,8 +20,10 @@
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
@ -1025,7 +1027,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 8 2012)
// C++ code generated with wxFormBuilder (version Jan 1 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!