Gerbview: support for plot lines (currently: not arcs) with a rectangular pen (Yes, it exists!). pcbnew: try to fix an issue when exporting arcs in gencad.
This commit is contained in:
parent
1206177ce0
commit
f0364c9da6
|
@ -88,8 +88,7 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
|
|||
m_mirrorA = aSource.m_mirrorA;
|
||||
m_mirrorB = aSource.m_mirrorB;
|
||||
m_layerOffset = aSource.m_layerOffset;
|
||||
m_drawScale.x = aSource.m_drawScale.x;
|
||||
m_drawScale.y = aSource.m_drawScale.y;
|
||||
m_drawScale = aSource.m_drawScale;
|
||||
m_lyrRotation = aSource.m_lyrRotation;
|
||||
}
|
||||
|
||||
|
@ -222,7 +221,13 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape()
|
|||
return wxT( "polygon" );
|
||||
|
||||
case GBR_SPOT_MACRO:
|
||||
return wxT( "apt_macro" ); // TODO: add aperture macro name
|
||||
{
|
||||
wxString name = wxT( "apt_macro" );
|
||||
D_CODE* dcode = GetDcodeDescr();
|
||||
if( dcode && dcode->GetMacro() )
|
||||
name << wxT(" ") << dcode->GetMacro()->name;
|
||||
return name;
|
||||
}
|
||||
|
||||
default:
|
||||
return wxT( "??" );
|
||||
|
@ -363,8 +368,8 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
|
|||
break;
|
||||
|
||||
case GBR_CIRCLE:
|
||||
radius = (int) hypot( (double) ( m_End.x - m_Start.x ),
|
||||
(double) ( m_End.y - m_Start.y ) );
|
||||
radius = wxRound(hypot( (double) ( m_End.x - m_Start.x ),
|
||||
(double) ( m_End.y - m_Start.y ) ));
|
||||
|
||||
halfPenWidth = m_Size.x >> 1;
|
||||
|
||||
|
@ -384,6 +389,8 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
|
|||
break;
|
||||
|
||||
case GBR_ARC:
|
||||
// Currently, arcs plotted witha rectangular aperture are not supported.
|
||||
// a round pen only is expected.
|
||||
#if 0 // for arc debug only
|
||||
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
|
||||
GetABPosition( m_ArcCentre ), 0, color );
|
||||
|
@ -415,12 +422,30 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
|
|||
break;
|
||||
|
||||
case GBR_SEGMENT:
|
||||
if( !isFilled )
|
||||
GRCSegm( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
|
||||
GetABPosition( m_End ), m_Size.x, color );
|
||||
/* Plot a line from m_Start to m_End.
|
||||
* Usually, a round pen is used, but some gerber files use a rectangular pen
|
||||
* In fact, any aperture can be used to plot a line.
|
||||
* currently: only a square pen is handled (I believe using a polygon gives a strange plot).
|
||||
*/
|
||||
if( d_codeDescr->m_Shape == APT_RECT )
|
||||
{
|
||||
if( m_PolyCorners.size() == 0 )
|
||||
ConvertSegmentToPolygon( );
|
||||
DrawGbrPoly( &aPanel->m_ClipBox, aDC, color, aOffset, isFilled );
|
||||
}
|
||||
else
|
||||
GRFilledSegment( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
|
||||
{
|
||||
if( !isFilled )
|
||||
{
|
||||
GRCSegm( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
|
||||
GetABPosition( m_End ), m_Size.x, color );
|
||||
}
|
||||
else
|
||||
{
|
||||
GRFilledSegment( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
|
||||
GetABPosition( m_End ), m_Size.x, color );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -433,9 +458,71 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
|
|||
}
|
||||
}
|
||||
|
||||
/** function ConvertSegmentToPolygon
|
||||
* convert a line to an equivalent polygon.
|
||||
* Useful when a line is plotted using a rectangular pen.
|
||||
* In this case, the usual segment plot cannot be used
|
||||
* The equivalent polygon is the area paint by the rectancular pen
|
||||
* from m_Start to m_End.
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
|
||||
{
|
||||
m_PolyCorners.clear();
|
||||
m_PolyCorners.reserve(6);
|
||||
|
||||
wxPoint start = m_Start;
|
||||
wxPoint end = m_End;
|
||||
// make calculations more easy if ensure start.x < end.x
|
||||
// (only 2 quadrants to consider)
|
||||
if( start.x > end.x )
|
||||
EXCHG( start, end );
|
||||
|
||||
// calculate values relative to start point:
|
||||
wxPoint delta = end - start;
|
||||
// calculate corners for the first quadrant only (delta.x and delta.y > 0 )
|
||||
// currently, delta.x already is > 0.
|
||||
// make delta.y > 0
|
||||
bool change = delta.y < 0;
|
||||
if( change )
|
||||
NEGATE( delta.y);
|
||||
// Now create the full polygon.
|
||||
// Due to previous chnages, the shape is always something like
|
||||
// 3 4
|
||||
// 2 5
|
||||
// 1 6
|
||||
wxPoint corner;
|
||||
corner.x -= m_Size.x/2;
|
||||
corner.y -= m_Size.y/2;
|
||||
m_PolyCorners.push_back( corner ); // Lower left corner, start point (1)
|
||||
corner.y += m_Size.y;
|
||||
m_PolyCorners.push_back( corner ); // upper left corner, start point (2)
|
||||
if( delta.x || delta.y)
|
||||
{
|
||||
corner += delta;
|
||||
m_PolyCorners.push_back( corner ); // upper left corner, end point (3)
|
||||
}
|
||||
corner.x += m_Size.x;
|
||||
m_PolyCorners.push_back( corner ); // upper right corner, end point (4)
|
||||
corner.y -= m_Size.y;
|
||||
m_PolyCorners.push_back( corner ); // lower right corner, end point (5)
|
||||
if( delta.x || delta.y )
|
||||
{
|
||||
corner -= delta;
|
||||
m_PolyCorners.push_back( corner ); // lower left corner, start point (6)
|
||||
}
|
||||
|
||||
// Create final polygon:
|
||||
for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
|
||||
{
|
||||
if( change )
|
||||
NEGATE( m_PolyCorners[ii].y);
|
||||
m_PolyCorners[ii] += start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** function DrawGbrPoly
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* a helper function used id ::Draw to draw the polygon stored in m_PolyCorners
|
||||
* Draw filled polygons
|
||||
*/
|
||||
void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect* aClipBox,
|
||||
|
|
|
@ -194,8 +194,15 @@ public:
|
|||
int aDrawMode,
|
||||
const wxPoint& aOffset = ZeroOffset );
|
||||
|
||||
/** function ConvertSegmentToPolygon
|
||||
* convert a line to an equivalent polygon.
|
||||
* Useful when a line is plotted using a rectangular pen.
|
||||
* In this case, the usual segment plot function cannot be used
|
||||
*/
|
||||
void ConvertSegmentToPolygon( );
|
||||
|
||||
/** function DrawGbrPoly
|
||||
* a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
|
||||
* a helper function used id ::Draw to draw the polygon stored in m_PolyCorners
|
||||
*/
|
||||
void DrawGbrPoly( EDA_Rect* aClipBox,
|
||||
wxDC* aDC, int aColor,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
*
|
||||
%FSLAX23Y23*%
|
||||
%MOIN*%
|
||||
%ADD10R,0.025X0.025*%
|
||||
%ADD11R,0.03X0.06*%
|
||||
%IPPOS*%
|
||||
%LNtest_rect.gbr*%
|
||||
%LPD*%
|
||||
G75*
|
||||
G54D10*
|
||||
X04000Y00100D02*
|
||||
X04400Y00140D01*
|
||||
G54D11*
|
||||
X03000Y00100D02*
|
||||
X02400Y-00340D01*
|
||||
M02*
|
|
@ -137,23 +137,23 @@ static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
* @param aGbrItem The GERBER_DRAW_ITEM to fill in.
|
||||
* @param Dcode_index The DCODE value, like D14
|
||||
* @param aLayer The layer index to set into the GBRITEM
|
||||
* @param aPos The center point of the flash
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aStart The starting point of the line
|
||||
* @param aEnd The ending point of the line
|
||||
* @param aPenSize The size of the flash. Note rectangular shapes are legal.
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
||||
int Dcode_index,
|
||||
int aLayer,
|
||||
const wxPoint& aStart,
|
||||
const wxPoint& aEnd,
|
||||
int aWidth,
|
||||
wxSize aPenSize,
|
||||
bool aLayerNegative )
|
||||
{
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
aGbrItem->m_Size = aPenSize;
|
||||
|
||||
aGbrItem->m_Start = aStart;
|
||||
aGbrItem->m_End = aEnd;
|
||||
|
@ -188,13 +188,12 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
|
|||
* must be calculated from the previously given constraint: arc only in the
|
||||
* same quadrant.
|
||||
* @param aDiameter The diameter of the round flash
|
||||
* @param aWidth is the pen width.
|
||||
* @param aPenSize The size of the flash. Note rectangular shapes are legal.
|
||||
* @param aLayerNegative = true if the current layer is negative
|
||||
* @param aImageNegative = true if the current image is negative
|
||||
*/
|
||||
static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
|
||||
const wxPoint& aStart, const wxPoint& aEnd,
|
||||
const wxPoint& aRelCenter, int aWidth,
|
||||
const wxPoint& aRelCenter, wxSize aPenSize,
|
||||
bool aClockwise, bool aMultiquadrant,
|
||||
bool aLayerNegative )
|
||||
{
|
||||
|
@ -202,7 +201,7 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
|
|||
|
||||
aGbrItem->m_Shape = GBR_ARC;
|
||||
aGbrItem->SetLayer( aLayer );
|
||||
aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
|
||||
aGbrItem->m_Size = aPenSize;
|
||||
aGbrItem->m_Flashed = false;
|
||||
|
||||
|
||||
|
@ -333,7 +332,7 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
|
|||
aGbrItem->SetLayerPolarity( aLayerNegative );
|
||||
|
||||
fillArcGBRITEM( &dummyGbrItem, 0, 0,
|
||||
aStart, aEnd, rel_center, 0,
|
||||
aStart, aEnd, rel_center, wxSize(0, 0),
|
||||
clockwise, multiquadrant, aLayerNegative );
|
||||
|
||||
wxPoint center;
|
||||
|
@ -688,7 +687,7 @@ bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
|
|||
// m_PreviousPos.x, m_PreviousPos.y,
|
||||
// m_CurrentPos.x, m_CurrentPos.y ); )
|
||||
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, size.x, GetLayerParams().m_LayerNegative );
|
||||
m_CurrentPos, size, GetLayerParams().m_LayerNegative );
|
||||
StepAndRepeatItem( *gbritem );
|
||||
break;
|
||||
|
||||
|
@ -708,7 +707,7 @@ bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
|
|||
// m_CurrentPos.y, m_IJPos.x,
|
||||
// m_IJPos.y, m_Iterpolation, m_360Arc_enbl ); )
|
||||
fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
|
||||
m_CurrentPos, m_IJPos, size.x,
|
||||
m_CurrentPos, m_IJPos, size,
|
||||
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
|
||||
false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
|
||||
StepAndRepeatItem( *gbritem );
|
||||
|
|
|
@ -245,9 +245,11 @@ void DRAWSEGMENT::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
|
|||
GRSetDrawMode( DC, draw_mode );
|
||||
l_piste = m_Width >> 1; /* half trace width */
|
||||
|
||||
// Line start point or Circle and Arc center
|
||||
ux0 = m_Start.x;
|
||||
uy0 = m_Start.y;
|
||||
|
||||
// Line end point or circle and arc start point
|
||||
dx = m_End.x;
|
||||
dy = m_End.y;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ class DRAWSEGMENT : public BOARD_ITEM
|
|||
{
|
||||
public:
|
||||
int m_Width; // thickness of lines ...
|
||||
wxPoint m_Start; // Line start point
|
||||
wxPoint m_End; // Line end point
|
||||
wxPoint m_Start; // Line start point or Circle and Arc center
|
||||
wxPoint m_End; // Line end point or circle and arc start point
|
||||
|
||||
int m_Shape; // Shape: line, Circle, Arc
|
||||
int m_Type; // Used in complex associations ( Dimensions.. )
|
||||
|
|
|
@ -421,6 +421,7 @@ int EDGE_MODULE::ReadDescr( char* Line, FILE* File,
|
|||
&m_Start0.x, &m_Start0.y,
|
||||
&m_End0.x, &m_End0.y,
|
||||
&m_Angle, &m_Width, &m_Layer );
|
||||
NORMALIZE_ANGLE( m_Angle );
|
||||
break;
|
||||
|
||||
case S_SEGMENT:
|
||||
|
|
|
@ -818,9 +818,9 @@ void CreateTracksInfoData( FILE* file, BOARD* pcb )
|
|||
*/
|
||||
void FootprintWriteShape( FILE* file, MODULE* module )
|
||||
{
|
||||
EDGE_MODULE* PtEdge;
|
||||
EDA_BaseStruct* PtStruct;
|
||||
int Yaxis_sign = -1; // Control Y axis change sign (as normal
|
||||
EDGE_MODULE* edge;
|
||||
EDA_BaseStruct* item;
|
||||
int y_axis_sign = -1; // Control Y axis change sign (as normal
|
||||
// module / mirror axis and conventions)
|
||||
|
||||
/* creates header: */
|
||||
|
@ -840,46 +840,53 @@ void FootprintWriteShape( FILE* file, MODULE* module )
|
|||
}
|
||||
|
||||
/* creates Drawing */
|
||||
PtStruct = module->m_Drawings;
|
||||
for( ; PtStruct != NULL; PtStruct = PtStruct->Next() )
|
||||
item = module->m_Drawings;
|
||||
for( ; item != NULL; item = item->Next() )
|
||||
{
|
||||
switch( PtStruct->Type() )
|
||||
switch( item->Type() )
|
||||
{
|
||||
case TYPE_TEXTE_MODULE:
|
||||
break;
|
||||
|
||||
case TYPE_EDGE_MODULE:
|
||||
PtEdge = (EDGE_MODULE*) PtStruct;
|
||||
edge = (EDGE_MODULE*) item;
|
||||
|
||||
switch( PtEdge->m_Shape )
|
||||
switch( edge->m_Shape )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
fprintf( file, "LINE %d %d %d %d\n",
|
||||
PtEdge->m_Start0.x, Yaxis_sign * PtEdge->m_Start0.y,
|
||||
PtEdge->m_End0.x, Yaxis_sign * PtEdge->m_End0.y );
|
||||
edge->m_Start0.x, y_axis_sign * edge->m_Start0.y,
|
||||
edge->m_End0.x, y_axis_sign * edge->m_End0.y );
|
||||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int rayon = (int) hypot(
|
||||
(double) ( PtEdge->m_End0.x - PtEdge->m_Start0.x ),
|
||||
(double) ( PtEdge->m_End0.y - PtEdge->m_Start0.y ) );
|
||||
(double) ( edge->m_End0.x - edge->m_Start0.x ),
|
||||
(double) ( edge->m_End0.y - edge->m_Start0.y ) );
|
||||
fprintf( file, "CIRCLE %d %d %d\n",
|
||||
PtEdge->m_Start0.x, Yaxis_sign * PtEdge->m_Start0.y,
|
||||
edge->m_Start0.x, y_axis_sign * edge->m_Start0.y,
|
||||
rayon );
|
||||
break;
|
||||
}
|
||||
|
||||
case S_ARC: /* print ARC x,y start x,y end x,y center */
|
||||
{
|
||||
int arcendx, arcendy;
|
||||
arcendx = PtEdge->m_Start0.x;
|
||||
arcendy = PtEdge->m_Start0.y;
|
||||
RotatePoint( &arcendx, &arcendy, PtEdge->m_Angle );
|
||||
{ // Arcs are defined counter clockwise (positive trigonometric)
|
||||
// from the start point to the end point (0 to 360 degrees)
|
||||
wxPoint arcStart, arcEnd;
|
||||
// edge->m_Start0 is the arc center relative to the shape position
|
||||
// edge->m_End0 is the arc start point relative to the shape position
|
||||
arcStart = edge->m_End0;
|
||||
// calculate arcEnd arc end point relative to the shape position, in pcbnew coordinates
|
||||
arcEnd = arcStart;
|
||||
RotatePoint( &arcEnd, edge->m_Start0, -edge->m_Angle );
|
||||
// due to difference between pcbnew and gencad, swap arc start and arc end
|
||||
EXCHG(arcEnd, arcStart);
|
||||
// print arc shape:
|
||||
fprintf( file, "ARC %d %d %d %d %d %d\n",
|
||||
PtEdge->m_End0.x, Yaxis_sign * PtEdge->m_End0.y,
|
||||
arcendx, Yaxis_sign * arcendy,
|
||||
PtEdge->m_Start0.x, Yaxis_sign * PtEdge->m_Start0.y );
|
||||
arcStart.x, y_axis_sign * arcStart.y, // Start point
|
||||
arcEnd.x, y_axis_sign * arcEnd.y, // End point
|
||||
edge->m_Start0.x, y_axis_sign * edge->m_Start0.y );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue